mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-18 18:05:05 +01:00
Enable script in big world (#884)
* add docs for tower * fix: LEAK: ByteBuf.release() was not called * enableScriptInBigWorld * not print log when loaded scripts from cache * revert the change of server tick * revert the change of server tick * fix * optimize the performance: lazy load & cache * fix the refresh group * fix NPE Co-authored-by: Melledy <52122272+Melledy@users.noreply.github.com>
This commit is contained in:
@@ -1,32 +1,27 @@
|
||||
package emu.grasscutter.scripts;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.script.Compilable;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.OneArgFunction;
|
||||
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
||||
import org.luaj.vm2.script.LuajContext;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.scripts.constants.EventType;
|
||||
import emu.grasscutter.scripts.constants.ScriptGadgetState;
|
||||
import emu.grasscutter.scripts.constants.ScriptRegionShape;
|
||||
import emu.grasscutter.scripts.data.SceneMeta;
|
||||
import emu.grasscutter.scripts.serializer.LuaSerializer;
|
||||
import emu.grasscutter.scripts.serializer.Serializer;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.OneArgFunction;
|
||||
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
||||
import org.luaj.vm2.script.LuajContext;
|
||||
|
||||
import javax.script.*;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ScriptLoader {
|
||||
private static ScriptEngineManager sm;
|
||||
@@ -34,9 +29,15 @@ public class ScriptLoader {
|
||||
private static ScriptEngineFactory factory;
|
||||
private static String fileType;
|
||||
private static Serializer serializer;
|
||||
|
||||
private static Map<String, CompiledScript> scripts = new HashMap<>();
|
||||
|
||||
/**
|
||||
* suggest GC to remove it if the memory is less
|
||||
*/
|
||||
private static Map<String, SoftReference<CompiledScript>> scriptsCache = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* sceneId - SceneMeta
|
||||
*/
|
||||
private static Map<Integer, SoftReference<SceneMeta>> sceneMetaCache = new ConcurrentHashMap<>();
|
||||
|
||||
public synchronized static void init() throws Exception {
|
||||
if (sm != null) {
|
||||
throw new Exception("Script loader already initialized");
|
||||
@@ -81,25 +82,42 @@ public class ScriptLoader {
|
||||
return serializer;
|
||||
}
|
||||
|
||||
public static CompiledScript getScriptByPath(String path) {
|
||||
CompiledScript sc = scripts.get(path);
|
||||
|
||||
Grasscutter.getLogger().info("Loaded " + path);
|
||||
|
||||
if (sc == null) {
|
||||
File file = new File(path);
|
||||
|
||||
if (!file.exists()) return null;
|
||||
|
||||
try (FileReader fr = new FileReader(file)) {
|
||||
sc = ((Compilable) getEngine()).compile(fr);
|
||||
scripts.put(path, sc);
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
public static <T> Optional<T> tryGet(SoftReference<T> softReference){
|
||||
try{
|
||||
return Optional.ofNullable(softReference.get());
|
||||
}catch (NullPointerException npe){
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
public static CompiledScript getScriptByPath(String path) {
|
||||
var sc = tryGet(scriptsCache.get(path));
|
||||
if (sc.isPresent()) {
|
||||
return sc.get();
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().info("Loaded Script" + path);
|
||||
|
||||
File file = new File(path);
|
||||
|
||||
if (!file.exists()) return null;
|
||||
|
||||
try (FileReader fr = new FileReader(file)) {
|
||||
var script = ((Compilable) getEngine()).compile(fr);
|
||||
scriptsCache.put(path, new SoftReference<>(script));
|
||||
return script;
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Loaded Script {} failed!", path, e);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static SceneMeta getSceneMeta(int sceneId) {
|
||||
return tryGet(sceneMetaCache.get(sceneId)).orElseGet(() -> {
|
||||
var instance = SceneMeta.of(sceneId);
|
||||
sceneMetaCache.put(sceneId, new SoftReference<>(instance));
|
||||
return instance;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user