Removed BindingsGenerator, FontGenerator
This commit is contained in:
@@ -2,6 +2,7 @@ sourceSets.main.java.srcDirs = ["src/"]
|
|||||||
|
|
||||||
|
|
||||||
import arc.files.Fi
|
import arc.files.Fi
|
||||||
|
import arc.files.ZipFi
|
||||||
import arc.func.Func2
|
import arc.func.Func2
|
||||||
import arc.graphics.Color
|
import arc.graphics.Color
|
||||||
import arc.graphics.Pixmap
|
import arc.graphics.Pixmap
|
||||||
@@ -11,9 +12,12 @@ import arc.struct.IntMap
|
|||||||
import arc.struct.ObjectMap
|
import arc.struct.ObjectMap
|
||||||
import arc.struct.OrderedMap
|
import arc.struct.OrderedMap
|
||||||
import arc.struct.Seq
|
import arc.struct.Seq
|
||||||
|
import arc.util.Http
|
||||||
import arc.util.Log
|
import arc.util.Log
|
||||||
|
import arc.util.OS
|
||||||
import arc.util.async.Threads
|
import arc.util.async.Threads
|
||||||
import arc.util.io.PropertiesUtils
|
import arc.util.io.PropertiesUtils
|
||||||
|
import arc.util.io.Streams
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
@@ -260,10 +264,47 @@ task genSprites(dependsOn: classes, type: JavaExec){
|
|||||||
}
|
}
|
||||||
|
|
||||||
task fontgen(dependsOn: classes, type: JavaExec){
|
task fontgen(dependsOn: classes, type: JavaExec){
|
||||||
mainClass = "mindustry.tools.FontGenerator"
|
/* icon font pipeline:
|
||||||
classpath = sourceSets.main.runtimeClasspath
|
1. take set of pre-defined icons and SVGs
|
||||||
standardInput = System.in
|
2. use Fontello API to get a font with these
|
||||||
workingDir = "../"
|
3. combine fontello font and standard font, get output font
|
||||||
|
4. use json to generate a file with constants for every icon size+type (during annotation processing)
|
||||||
|
*/
|
||||||
|
doLast{
|
||||||
|
Fi folder = Fi.get("core/assets-raw/fontgen/out/");
|
||||||
|
folder.mkdirs();
|
||||||
|
|
||||||
|
Log.info("Session...");
|
||||||
|
|
||||||
|
OS.exec("curl", "--fail", "--output", "core/assets-raw/fontgen/out/session", "--form", "config=@core/assets-raw/fontgen/config.json", "https://fontello.com");
|
||||||
|
|
||||||
|
Log.info("Zip...");
|
||||||
|
|
||||||
|
String session = folder.child("session").readString();
|
||||||
|
|
||||||
|
Http.get("https://fontello.com/" + session + "/get").block(result -> {
|
||||||
|
Streams.copy(result.getResultAsStream(), folder.child("font.zip").write());
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.info("Icon font...");
|
||||||
|
|
||||||
|
ZipFi zip = new ZipFi(folder.child("font.zip"));
|
||||||
|
Fi dest = folder.child("font.woff");
|
||||||
|
zip.list()[0].child("font").child("fontello.ttf").copyTo(dest);
|
||||||
|
dest.copyTo(Fi.get("core/assets/fonts/icon.ttf"));
|
||||||
|
|
||||||
|
Log.info("Merge...");
|
||||||
|
|
||||||
|
//TODO this is broken
|
||||||
|
|
||||||
|
Log.info(OS.exec("fontforge", "-script",
|
||||||
|
Fi.get("core/assets-raw/fontgen/merge.pe").absolutePath(),
|
||||||
|
Fi.get("core/assets/fonts/font.woff").absolutePath(),
|
||||||
|
Fi.get("core/assets-raw/fontgen/out/font.woff").absolutePath())
|
||||||
|
);
|
||||||
|
|
||||||
|
Log.info("Done.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task icongen(dependsOn: classes, type: JavaExec){
|
task icongen(dependsOn: classes, type: JavaExec){
|
||||||
|
|||||||
@@ -1,227 +0,0 @@
|
|||||||
package mindustry.tools;
|
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.files.*;
|
|
||||||
import arc.func.*;
|
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.*;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.lang.reflect.*;
|
|
||||||
import java.nio.*;
|
|
||||||
import java.nio.charset.*;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static mindustry.tools.ScriptMainGenerator.*;
|
|
||||||
|
|
||||||
//experimental binding generator - used for Nim, but can be used for other languages as well, theoretically
|
|
||||||
public class BindingsGenerator{
|
|
||||||
//list of touchy class names that lead to conflicts or should not be referenced; all typedefs and procs containing these are ignored
|
|
||||||
static Seq<String> ignored = Seq.with(".Entry", ".MapIterator", "arc.freetype.FreeType.Glyph", "FrameBufferBuilder", "Spliterator",
|
|
||||||
"java.util.function", "java.util.stream", "ArrayList", "Constable", "Optional", "java.lang.reflect", "rhino.Context", "arc.graphics.GL20", "arc.graphics.GL30");
|
|
||||||
|
|
||||||
static ObjectSet<Class<?>> classSet = new ObjectSet<>();
|
|
||||||
static ObjectSet<String> keywords = ObjectSet.with("object", "string");
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception{
|
|
||||||
|
|
||||||
Seq<String> blacklist = Seq.with(
|
|
||||||
"mindustry.tools",
|
|
||||||
"arc.backend",
|
|
||||||
"arc.maps",
|
|
||||||
"arc.util.serialization.Xml",
|
|
||||||
"arc.fx",
|
|
||||||
"arc.net", "arc.Net",
|
|
||||||
"arc.freetype"
|
|
||||||
);
|
|
||||||
Seq<Class<?>> classes = Seq.withArrays(
|
|
||||||
getClasses("mindustry")
|
|
||||||
//getClasses("arc")
|
|
||||||
);
|
|
||||||
|
|
||||||
classes.removeAll(type -> type.isSynthetic() || type.isAnonymousClass() || type.getCanonicalName() == null || Modifier.isPrivate(type.getModifiers())
|
|
||||||
|| blacklist.contains(s -> type.getName().startsWith(s)));
|
|
||||||
|
|
||||||
classes.addAll(Enum.class, FloatBuffer.class, IntBuffer.class, ByteBuffer.class, StringBuilder.class,
|
|
||||||
Comparator.class, Comparable.class, Reader.class, Writer.class, PrintStream.class, PrintWriter.class, File.class, Charset.class,
|
|
||||||
ClassLoader.class, DoubleBuffer.class, CharBuffer.class, Locale.class,
|
|
||||||
LongBuffer.class, DataInputStream.class, DataOutputStream.class, Events.class, Cons.class
|
|
||||||
);
|
|
||||||
classes.distinct();
|
|
||||||
|
|
||||||
classes = sorted(classes);
|
|
||||||
classes.removeAll(BindingsGenerator::ignore);
|
|
||||||
classes.removeAll(c -> !Modifier.isPublic(c.getModifiers()));
|
|
||||||
|
|
||||||
ObjectMap<String, Seq<Class<?>>> similars = new ObjectMap<>();
|
|
||||||
classes.each(c -> similars.get(c.getSimpleName(), Seq::new).add(c));
|
|
||||||
similars.each((key, val) -> {
|
|
||||||
if(val.size > 1){
|
|
||||||
Log.info("\n" + key + ":\n" + val.toString("\n", v -> "- " + v.getCanonicalName()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
classSet = classes.asSet();
|
|
||||||
classSet.addAll(Object.class, Number.class, Integer.class, Double.class, Short.class, Float.class, Byte.class, Long.class, String.class, Boolean.class, Throwable.class, Exception.class, Class.class);
|
|
||||||
classSet.addAll(void.class, int.class, float.class, long.class, char.class, byte.class, boolean.class, double.class, short.class);
|
|
||||||
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
result.append("import jnim, jnim/java/lang\n\n{.push hint[ConvFromXtoItselfNotNeeded]: off.}\n\n");
|
|
||||||
|
|
||||||
for(Class<?> type : classes){
|
|
||||||
result.append("jclassDef ").append(type.getName()).append(" of `")
|
|
||||||
.append(repr(type.getSuperclass())).append("`\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
result.append("\n");
|
|
||||||
|
|
||||||
for(Class<?> type : classes){
|
|
||||||
|
|
||||||
Seq<Executable> exec = new Seq<>();
|
|
||||||
Seq<Method> methods = Seq.with(type.getDeclaredMethods());
|
|
||||||
|
|
||||||
methods.removeAll(m -> ignore(m.getReturnType()) || !discovered(m.getReturnType()));
|
|
||||||
|
|
||||||
exec.addAll(methods);
|
|
||||||
exec.addAll(type.getDeclaredConstructors());
|
|
||||||
|
|
||||||
exec.removeAll(e -> !Modifier.isPublic(e.getModifiers()) || keywords.contains(e.getName()));
|
|
||||||
exec.removeAll(e -> Structs.contains(e.getParameterTypes(), BindingsGenerator::ignore));
|
|
||||||
exec.removeAll(e -> Structs.contains(e.getParameterTypes(), p -> !discovered(p)));
|
|
||||||
|
|
||||||
Seq<Field> fields = Seq.select(type.getDeclaredFields(), f ->
|
|
||||||
Modifier.isPublic(f.getModifiers()) &&
|
|
||||||
!keywords.contains(f.getName()) &&
|
|
||||||
!ignore(f.getType()) && Modifier.isPublic(f.getType().getModifiers()) &&
|
|
||||||
!(f.getType().isArray() &&
|
|
||||||
f.getType().getComponentType().isArray()) &&
|
|
||||||
classSet.contains(f.getType())
|
|
||||||
);
|
|
||||||
|
|
||||||
if(exec.size + fields.size <= 0) continue;
|
|
||||||
|
|
||||||
result.append("jclassImpl ").append(type.getName()).append(" of `")
|
|
||||||
.append(repr(type.getSuperclass())).append("`").append(":").append("\n");
|
|
||||||
|
|
||||||
for(Field field : fields){
|
|
||||||
result.append(" proc `").append(field.getName()).append("`");
|
|
||||||
result.append(": ").append(str(field.getType()));
|
|
||||||
result.append(" {.prop");
|
|
||||||
if(Modifier.isStatic(field.getModifiers())) result.append(", `static`");
|
|
||||||
if(Modifier.isStatic(field.getModifiers())) result.append(", `final`");
|
|
||||||
result.append(".}\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Executable method : exec){
|
|
||||||
String mname = method.getName().equals("<init>") || method.getName().equals(type.getName()) ? "new" : method.getName();
|
|
||||||
|
|
||||||
if(method instanceof Method){
|
|
||||||
Method m = (Method)method;
|
|
||||||
|
|
||||||
//if a field by the same name exists, use it to prevent ambiguity
|
|
||||||
if(method.getParameterCount() == 0 && fields.contains(f -> f.getName().equals(method.getName()))){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//check if this is a less specific method that was overridden by another method
|
|
||||||
if(methods.contains(other ->
|
|
||||||
other != m &&
|
|
||||||
m.getName().equals(other.getName()) &&
|
|
||||||
m.getParameterCount() == other.getParameterCount() &&
|
|
||||||
Arrays.equals(m.getParameterTypes(), other.getParameterTypes()) &&
|
|
||||||
m.getReturnType().isAssignableFrom(other.getReturnType())
|
|
||||||
)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
result.append(" proc `").append(mname).append("`");
|
|
||||||
|
|
||||||
if(method.getParameterCount() > 0){
|
|
||||||
result.append("(");
|
|
||||||
|
|
||||||
for(int i = 0; i < method.getParameterCount(); i++){
|
|
||||||
Class p = method.getParameterTypes()[i];
|
|
||||||
|
|
||||||
result.append(method.getParameters()[i].getName()).append(": ").append(str(p));
|
|
||||||
|
|
||||||
if(i != method.getParameterCount() - 1){
|
|
||||||
result.append(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.append(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(method instanceof Method){
|
|
||||||
Method m = (Method)method;
|
|
||||||
if(!m.getReturnType().equals(void.class)){
|
|
||||||
result.append(": ").append(str(m.getReturnType()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Modifier.isStatic(method.getModifiers())){
|
|
||||||
result.append(" {.`static`.}");
|
|
||||||
}
|
|
||||||
result.append("\n");
|
|
||||||
}
|
|
||||||
result.append("\n");
|
|
||||||
}
|
|
||||||
result.append("{.pop.}\n");
|
|
||||||
|
|
||||||
//change directory as needed later
|
|
||||||
Fi.get("/home/anuke/Projects/Nimdustry-java/mindustry_bindings.nim").writeString(result.toString());
|
|
||||||
Log.info("Done. Classes found: @", classes.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean discovered(Class<?> type){
|
|
||||||
return classSet.contains(type) || (type.isArray() && discovered(type.getComponentType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean ignore(Class<?> type){
|
|
||||||
if(type == null) return false;
|
|
||||||
if(type.isArray() && type.getComponentType().isArray()) return true;
|
|
||||||
return ignored.contains(s -> type.getCanonicalName().contains(s)) || ignore(type.getSuperclass());
|
|
||||||
}
|
|
||||||
|
|
||||||
static Seq<Class<?>> sorted(Seq<Class<?>> classes){
|
|
||||||
ObjectSet<Class<?>> visited = new ObjectSet<>();
|
|
||||||
Seq<Class<?>> result = new Seq<>();
|
|
||||||
for(Class<?> c : classes){
|
|
||||||
if(!visited.contains(c)){
|
|
||||||
topoSort(c, result, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void topoSort(Class<?> c, Seq<Class<?>> stack, ObjectSet<Class<?>> visited){
|
|
||||||
visited.add(c);
|
|
||||||
for(Class<?> sup : c.getInterfaces()){
|
|
||||||
if(!visited.contains(sup)){
|
|
||||||
topoSort(sup, stack, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(c.getSuperclass() != null && !c.getSuperclass().equals(Object.class) && !visited.contains(c.getSuperclass())){
|
|
||||||
topoSort(c.getSuperclass(), stack, visited);
|
|
||||||
}
|
|
||||||
stack.add(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String repr(Class type){
|
|
||||||
if(type == null) return "JVMObject";
|
|
||||||
if(type.equals(Object.class)) return "Object";
|
|
||||||
if(type.equals(String.class)) return "string";
|
|
||||||
if(!Modifier.isPublic(type.getModifiers())) return "Object";
|
|
||||||
return type.getSimpleName();
|
|
||||||
}
|
|
||||||
|
|
||||||
static String str(Class type){
|
|
||||||
if(type.equals(Object.class)) return "Object";
|
|
||||||
if(type.equals(String.class)) return "string";
|
|
||||||
if(type.isArray()) return "seq[" + str(type.getComponentType()) + "]";
|
|
||||||
if(type.isPrimitive()) return "j" + type.getSimpleName();
|
|
||||||
return type.getSimpleName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package mindustry.tools;
|
|
||||||
|
|
||||||
import arc.files.*;
|
|
||||||
import arc.util.*;
|
|
||||||
import arc.util.io.*;
|
|
||||||
|
|
||||||
/* icon font pipeline:
|
|
||||||
1. take set of pre-defined icons and SVGs
|
|
||||||
2. use Fontello API to get a font with these
|
|
||||||
3. combine fontello font and standard font, get output font
|
|
||||||
4. use json to generate a file with constants for every icon size+type (during annotation processing)
|
|
||||||
*/
|
|
||||||
public class FontGenerator{
|
|
||||||
|
|
||||||
//E000 to F8FF
|
|
||||||
public static void main(String[] args){
|
|
||||||
Fi folder = Fi.get("core/assets-raw/fontgen/out/");
|
|
||||||
folder.mkdirs();
|
|
||||||
|
|
||||||
Log.info("Session...");
|
|
||||||
|
|
||||||
OS.exec("curl", "--fail", "--output", "core/assets-raw/fontgen/out/session", "--form", "config=@core/assets-raw/fontgen/config.json", "https://fontello.com");
|
|
||||||
|
|
||||||
Log.info("Zip...");
|
|
||||||
|
|
||||||
String session = folder.child("session").readString();
|
|
||||||
|
|
||||||
Http.get("https://fontello.com/" + session + "/get").block(result -> {
|
|
||||||
Streams.copy(result.getResultAsStream(), folder.child("font.zip").write());
|
|
||||||
});
|
|
||||||
|
|
||||||
Log.info("Icon font...");
|
|
||||||
|
|
||||||
ZipFi zip = new ZipFi(folder.child("font.zip"));
|
|
||||||
Fi dest = folder.child("font.woff");
|
|
||||||
zip.list()[0].child("font").child("fontello.ttf").copyTo(dest);
|
|
||||||
dest.copyTo(Fi.get("core/assets/fonts/icon.ttf"));
|
|
||||||
|
|
||||||
Log.info("Merge...");
|
|
||||||
|
|
||||||
//TODO this is broken
|
|
||||||
|
|
||||||
Log.info(OS.exec("fontforge", "-script",
|
|
||||||
Fi.get("core/assets-raw/fontgen/merge.pe").absolutePath(),
|
|
||||||
Fi.get("core/assets/fonts/font.woff").absolutePath(),
|
|
||||||
Fi.get("core/assets-raw/fontgen/out/font.woff").absolutePath())
|
|
||||||
);
|
|
||||||
|
|
||||||
Log.info("Done.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user