TilesetsGenerator.java 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package squidpony.tileset;
  2. import java.io.FileNotFoundException;
  3. import java.io.InputStream;
  4. import java.io.PrintWriter;
  5. import java.lang.reflect.Field;
  6. import com.google.gson.Gson;
  7. import squidpony.squidgrid.mapping.styled.Tile;
  8. import squidpony.squidgrid.mapping.styled.Tileset;
  9. /**
  10. * Class that generates the other {@code .java} files in this package. This is
  11. * required to be compatible with GWT (for libgdx's html5 backend) as it avoids
  12. * to load .js files from disk in {@code DungeonBoneGen} (this is impossible in
  13. * GWT, because Gson isn't GWT-compatible). As a side effect, it removes
  14. * SquidLib's runtime dependency on Gson. Gson is only required to run this
  15. * class.
  16. *
  17. * <p>
  18. * In Eclipse, I execute this class by right-clicking on this class and
  19. * selecting 'Run as > Java Application'. It works without further setup.
  20. * Generated .java files are put in the adequate location, i.e. close to this
  21. * file.
  22. * </p>
  23. *
  24. * </p>
  25. *
  26. * @author smelC
  27. */
  28. public class TilesetsGenerator {
  29. private static final String EOL = System.getProperty("line.separator");
  30. public static void main(String[] args) {
  31. final String[] jss = {"etc/caves_limit_connectivity.js", "etc/caves_tiny_corridors.js", "etc/corner_caves.js",
  32. "etc/default_dungeon.js", "etc/horizontal_corridors_v1.js", "etc/horizontal_corridors_v2.js",
  33. "etc/horizontal_corridors_v3.js", "etc/limit_connectivity_fat.js", "etc/limited_connectivity.js",
  34. "etc/maze_2_wide.js", "etc/maze_plus_2_wide.js", "etc/open_areas.js", "etc/ref2_corner_caves.js",
  35. "etc/rooms_and_corridors_2_wide_diagonal_bias.js", "etc/rooms_and_corridors.js",
  36. "etc/rooms_limit_connectivity.js", "etc/round_rooms_diagonal_corridors.js", "etc/simple_caves_2_wide.js",
  37. "etc/square_rooms_with_random_rects.js"};
  38. main0(jss);
  39. }
  40. /**
  41. * @param args
  42. * The {@code .js} files containing {@link Tileset}s.
  43. */
  44. private static void main0(String[] args) {
  45. final Gson gson = new Gson();
  46. for (String arg : args) {
  47. if (!arg.endsWith(".js")) {
  48. errLog("File " + arg
  49. + " doesn't look like a gson file (expected extension: .js). Skipping it.");
  50. continue;
  51. }
  52. final int slashIdx = arg.lastIndexOf('.');
  53. final String gsonFileName = slashIdx < 0 ? arg : arg.substring(0, slashIdx);
  54. generate(gson, TilesetsGenerator.class.getResourceAsStream("/" + arg),
  55. gsonFileNametoJavaFileName(gsonFileName));
  56. }
  57. }
  58. /**
  59. * @param is
  60. * A stream to a gson file. Closed by this method.
  61. * @param javaClassName
  62. * The name of the class to generate
  63. */
  64. private static void generate(Gson gson, InputStream is, String javaClassName) {
  65. /* This closes 'is' */
  66. final String content = stringifyStream(is);
  67. final Tileset ts = gson.fromJson(content, Tileset.class);
  68. /* Now dump 'ts' as a Java class */
  69. final StringBuilder java = new StringBuilder();
  70. appendln(java,
  71. "/* File generated automatically by TilesetsGenerator.java. Do not edit. This file is committed for convenience. */");
  72. appendln(java, "package squidpony.tileset;");
  73. appendln(java, "");
  74. appendln(java, "import squidpony.squidgrid.mapping.styled.*;");
  75. appendln(java, "");
  76. final String javaFileName = javaClassName + ".java";
  77. appendln(java, "/** @author TilesetsGenerator.java */");
  78. appendln(java, "public class " + javaClassName + " {");
  79. appendln(java, "");
  80. appendln(java, " public static final Tileset INSTANCE = new Tileset();");
  81. appendln(java, "");
  82. appendln(java, " static {");
  83. appendln(java, 4, "/* Initialize #INSTANCE */ ");
  84. try {
  85. initalizeTopLevel(java, "config", ts.config, ts);
  86. initalizeTopLevel(java, "max_tiles", ts.max_tiles, ts);
  87. } catch (Throwable e) {
  88. errLog("Could not write " + javaFileName, e);
  89. return;
  90. }
  91. appendln(java, 4, "Tile t = null;");
  92. appendln(java, 4, "String[] data = null;");
  93. initializeTileArray(java, "h_tiles", ts.h_tiles, ts);
  94. initializeTileArray(java, "v_tiles", ts.v_tiles, ts);
  95. appendln(java, " }");
  96. appendln(java, "");
  97. java.append("}");
  98. writeToDisk(java, javaClassName + ".java");
  99. }
  100. private static void initializeTileArray(StringBuilder java, String fieldName, Tile[] ts_tiles,
  101. Tileset ts) {
  102. final int len = ts_tiles.length;
  103. /* Initialize array */
  104. appendln(java, 4, "INSTANCE." + fieldName + " = new Tile[" + len + "];");
  105. for (int i = 0; i < len; i++) {
  106. final Tile source = ts_tiles[i];
  107. /* Fill temporary variable to copy Tile.data */
  108. appendln(java, " /* Build " + fieldName + " #" + i + " */");
  109. appendln(java, 4, "data = new String[" + source.data.length + "];");
  110. for (int j = 0; j < source.data.length; j++) {
  111. appendln(java, 4, "data[" + j + "] = \"" + source.data[j] + "\";");
  112. }
  113. /* Build new Tile */
  114. java.append(" t = new Tile(");
  115. java.append(source.a_constraint);
  116. java.append(", ");
  117. java.append(source.b_constraint);
  118. java.append(", ");
  119. java.append(source.c_constraint);
  120. java.append(", ");
  121. java.append(source.d_constraint);
  122. java.append(", ");
  123. java.append(source.e_constraint);
  124. java.append(", ");
  125. java.append(source.f_constraint);
  126. appendln(java, ", data);");
  127. appendln(java, 4, "INSTANCE." + fieldName + "[" + i + "] = t;");
  128. }
  129. }
  130. private static void initalizeTopLevel(StringBuilder java, String fieldName, Object c, Tileset ts)
  131. throws IllegalArgumentException, IllegalAccessException {
  132. for (Field field : c.getClass().getFields())
  133. appendln(java, 4, "INSTANCE." + fieldName + "." + field.getName() + "=" + field.get(c) + ";");
  134. }
  135. private static void writeToDisk(StringBuilder java, String filename) {
  136. final String dest = "squidlib-util/src/main/java/squidpony/tileset/" + filename;
  137. final PrintWriter pw;
  138. try {
  139. pw = new PrintWriter(dest);
  140. } catch (FileNotFoundException e) {
  141. errLog("Cannot write " + filename + " to disk", e);
  142. return;
  143. }
  144. pw.append(java);
  145. pw.flush();
  146. pw.close();
  147. infoLog("Written " + dest);
  148. }
  149. /**
  150. * @param s
  151. * An extension less filename.
  152. */
  153. private static String gsonFileNametoJavaFileName(String s) {
  154. String result = "";
  155. final int bound = s.length();
  156. boolean upperNext = false;
  157. for (int i = 0; i < bound; i++) {
  158. final char c = s.charAt(i);
  159. if (c == '_')
  160. upperNext = true;
  161. else {
  162. result += (i == 0 || upperNext) ? Character.toUpperCase(c) : c;
  163. upperNext = false;
  164. }
  165. }
  166. return result;
  167. }
  168. /* A Tommy Ettinger © trick coming from DungeonBoneGen. Handy! */
  169. /**
  170. * @param is
  171. * @return The content of {@©ode is} as a {@link String}.
  172. */
  173. private static String stringifyStream(InputStream is) {
  174. java.util.Scanner s = new java.util.Scanner(is);
  175. s.useDelimiter("\\A");
  176. String nx = s.hasNext() ? s.next() : "";
  177. s.close();
  178. return nx;
  179. }
  180. private static StringBuilder appendln(StringBuilder buf, int indent, String s) {
  181. for (int i = 0; i < indent; i++)
  182. buf.append(' ');
  183. appendln(buf, s);
  184. return buf;
  185. }
  186. private static StringBuilder appendln(StringBuilder buf, String s) {
  187. buf.append(s);
  188. buf.append(EOL);
  189. return buf;
  190. }
  191. private static void errLog(String msg, Throwable e) {
  192. if (msg != null)
  193. System.err.println(msg);
  194. e.printStackTrace(System.err);
  195. }
  196. private static void errLog(String msg) {
  197. System.err.println(msg);
  198. }
  199. private static void infoLog(String msg) {
  200. System.out.println(msg);
  201. }
  202. }