From 59401d27ca13e84ad99a18182339eedd453a2f4e Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 29 Aug 2021 22:19:41 -0400 Subject: [PATCH] Snippets! --- .../com/volmit/iris/core/loader/IrisData.java | 101 +++++++++++++++++- .../iris/core/loader/IrisRegistrant.java | 6 ++ .../iris/core/loader/ResourceLoader.java | 12 ++- .../engine/object/annotations/Snippet.java | 31 ++++++ 4 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/object/annotations/Snippet.java diff --git a/src/main/java/com/volmit/iris/core/loader/IrisData.java b/src/main/java/com/volmit/iris/core/loader/IrisData.java index 662358455..0cf8fff7a 100644 --- a/src/main/java/com/volmit/iris/core/loader/IrisData.java +++ b/src/main/java/com/volmit/iris/core/loader/IrisData.java @@ -18,8 +18,15 @@ package com.volmit.iris.core.loader; +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; import com.volmit.iris.Iris; +import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.annotations.Snippet; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockData; import com.volmit.iris.engine.object.carving.IrisCave; @@ -41,14 +48,19 @@ import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.format.C; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.ChronoLatch; +import com.volmit.iris.util.scheduling.J; import lombok.Data; import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Type; import java.util.Objects; import java.util.function.Function; @Data -public class IrisData { +public class IrisData implements ExclusionStrategy, TypeAdapterFactory { private static final KMap dataLoaders = new KMap<>(); private ResourceLoader biomeLoader; private ResourceLoader lootLoader; @@ -67,6 +79,9 @@ public class IrisData { private ResourceLoader scriptLoader; private ResourceLoader caveLoader; private ResourceLoader ravineLoader; + private Gson gson; + private Gson snippetLoader; + private GsonBuilder builder; private KMap, ResourceLoader> loaders = new KMap<>(); private final File dataFolder; private Engine engine; @@ -174,7 +189,8 @@ public class IrisData { } else if (registrant.equals(IrisScript.class)) { r = (ResourceLoader) new ScriptResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName()); } else { - r = new ResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName(), registrant); + J.attempt(() -> registrant.getConstructor().newInstance().registerTypeAdapters(builder)); + r = new ResourceLoader<>(dataFolder, this, rr.getFolderName(), rr.getTypeName(), registrant); } loaders.put(registrant, r); @@ -189,6 +205,12 @@ public class IrisData { } public synchronized void hotloaded() { + builder = new GsonBuilder() + .addDeserializationExclusionStrategy(this) + .addSerializationExclusionStrategy(this) + .setLenient() + .registerTypeAdapterFactory(this) + .setPrettyPrinting(); loaders.clear(); File packs = dataFolder; packs.mkdirs(); @@ -209,6 +231,7 @@ public class IrisData { this.expressionLoader = registerLoader(IrisExpression.class); this.objectLoader = registerLoader(IrisObject.class); this.scriptLoader = registerLoader(IrisScript.class); + gson = builder.create(); } public void dump() { @@ -338,4 +361,78 @@ public class IrisData { return null; } + + @Override + public boolean shouldSkipField(FieldAttributes f) { + return false; + } + + @Override + public boolean shouldSkipClass(Class c) { + if(c.equals(AtomicCache.class)) + { + return true; + } + + else if(c.equals(ChronoLatch.class)) + { + return true; + } + + return false; + } + + @Override + public TypeAdapter create(Gson gson, TypeToken typeToken) { + if(!typeToken.getRawType().isAnnotationPresent(Snippet.class)) + { + return null; + } + + String snippetType = typeToken.getRawType().getDeclaredAnnotation(Snippet.class).value(); + + return new TypeAdapter<>() { + @Override + public void write(JsonWriter jsonWriter, T t) throws IOException { + gson.getDelegateAdapter(IrisData.this, typeToken).write(jsonWriter, t); + } + + @Override + public T read(JsonReader reader) throws IOException { + TypeAdapter adapter = gson.getDelegateAdapter(IrisData.this, typeToken); + + if (reader.peek().equals(JsonToken.STRING)) { + String r = reader.nextString(); + + if(r.startsWith("snippet/" + snippetType + "/")) + { + File f = new File(getDataFolder(), r); + + if(f.exists()) + { + try + { + JsonReader snippetReader = new JsonReader(new FileReader(f)); + return adapter.read(snippetReader); + } + + catch(Throwable e) + { + Iris.error("Couldn't read snippet " + r + " in " + reader.getPath() + " (" + e.getMessage() + ")"); + } + } + + else + { + Iris.error("Couldn't find snippet " + r + " in " + reader.getPath()); + } + } + + return null; + } + + return adapter.read(reader); + } + }; + } } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/core/loader/IrisRegistrant.java b/src/main/java/com/volmit/iris/core/loader/IrisRegistrant.java index 67775dcc2..47078b944 100644 --- a/src/main/java/com/volmit/iris/core/loader/IrisRegistrant.java +++ b/src/main/java/com/volmit/iris/core/loader/IrisRegistrant.java @@ -18,6 +18,7 @@ package com.volmit.iris.core.loader; +import com.google.gson.GsonBuilder; import com.volmit.iris.Iris; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; @@ -48,6 +49,11 @@ public abstract class IrisRegistrant { public abstract String getTypeName(); + public void registerTypeAdapters(GsonBuilder builder) + { + + } + public File openInVSCode() { try { Desktop.getDesktop().open(getLoadFile()); diff --git a/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java b/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java index ec4c10d87..dbf9d5e02 100644 --- a/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java +++ b/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java @@ -19,9 +19,13 @@ package com.volmit.iris.core.loader; import com.google.common.util.concurrent.AtomicDouble; +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.volmit.iris.Iris; import com.volmit.iris.core.project.SchemaBuilder; +import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; @@ -37,6 +41,7 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Data; import java.io.File; +import java.lang.reflect.Field; import java.util.Locale; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; @@ -176,7 +181,8 @@ public class ResourceLoader { protected T loadFile(File j, String key, String name) { try { PrecisionStopwatch p = PrecisionStopwatch.start(); - T t = new Gson().fromJson(IO.readAll(j), objectClass); + T t = getManager().getGson() + .fromJson(preprocess(new JSONObject(IO.readAll(j))).toString(0), objectClass); t.setLoadKey(name); t.setLoadFile(j); t.setLoader(manager); @@ -194,6 +200,10 @@ public class ResourceLoader { } } + protected JSONObject preprocess(JSONObject j) { + return j; + } + public Stream streamAll(Stream s) { return s.map(this::load); } diff --git a/src/main/java/com/volmit/iris/engine/object/annotations/Snippet.java b/src/main/java/com/volmit/iris/engine/object/annotations/Snippet.java new file mode 100644 index 000000000..aec442b0b --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/annotations/Snippet.java @@ -0,0 +1,31 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) +@Target({TYPE}) +public @interface Snippet { + String value(); +}