Implement lazy loading of scripts when they enter a new block

This commit is contained in:
Melledy 2022-04-29 02:07:25 -07:00
parent 3af5d20473
commit 1a5d4cf466
3 changed files with 29 additions and 8 deletions

View File

@ -482,8 +482,8 @@ public class Scene {
for (SceneBlock block : visible) {
if (!this.getLoadedBlocks().contains(block)) {
this.getLoadedBlocks().add(block);
this.onLoadBlock(block);
this.getLoadedBlocks().add(block);
}
}
}
@ -491,11 +491,17 @@ public class Scene {
// TODO optimize
public void onLoadBlock(SceneBlock block) {
for (SceneGroup group : block.groups) {
// We load the script files for the groups here
if (!group.isLoaded()) {
this.getScriptManager().loadGroupFromScript(group);
}
group.triggers.forEach(getScriptManager()::registerTrigger);
}
// Spawn gadgets AFTER triggers are added
for (SceneGroup group : block.groups) {
this.getScriptManager().spawnGadgetsInGroup(block, group);
this.getScriptManager().spawnGadgetsInGroup(group);
}
}

View File

@ -145,7 +145,7 @@ public class SceneScriptManager {
SceneBlock block = blocks.get(0);
block.id = blockIds.get(i);
loadBlock(block);
loadBlockFromScript(block);
}
this.blocks = blocks;
@ -162,7 +162,7 @@ public class SceneScriptManager {
return isInit;
}
private void loadBlock(SceneBlock block) {
private void loadBlockFromScript(SceneBlock block) {
CompiledScript cs = ScriptLoader.getScriptByPath(
Grasscutter.getConfig().SCRIPTS_FOLDER + "Scene/" + getScene().getId() + "/scene" + getScene().getId() + "_block" + block.id + "." + ScriptLoader.getScriptType());
@ -176,13 +176,16 @@ public class SceneScriptManager {
// Set groups
block.groups = ScriptLoader.getSerializer().toList(SceneGroup.class, bindings.get("groups"));
block.groups.forEach(this::loadGroup);
block.groups.forEach(g -> g.block_id = block.id);
} catch (ScriptException e) {
Grasscutter.getLogger().error("Error loading block " + block.id + " in scene " + getScene().getId(), e);
}
}
private void loadGroup(SceneGroup group) {
public void loadGroupFromScript(SceneGroup group) {
// Set flag here so if there is no script, we dont call this function over and over again.
group.setLoaded(true);
CompiledScript cs = ScriptLoader.getScriptByPath(
Grasscutter.getConfig().SCRIPTS_FOLDER + "Scene/" + getScene().getId() + "/scene" + getScene().getId() + "_group" + group.id + "." + ScriptLoader.getScriptType());
@ -213,13 +216,13 @@ public class SceneScriptManager {
}
public void spawnGadgetsInGroup(SceneBlock block, SceneGroup group) {
public void spawnGadgetsInGroup(SceneGroup group) {
for (SceneGadget g : group.gadgets) {
EntityGadget entity = new EntityGadget(getScene(), g.gadget_id, g.pos);
if (entity.getGadgetData() == null) continue;
entity.setBlockId(block.id);
entity.setBlockId(group.block_id);
entity.setConfigId(g.config_id);
entity.setGroupId(group.id);
entity.getRotation().set(g.rot);

View File

@ -5,6 +5,8 @@ import java.util.List;
import emu.grasscutter.utils.Position;
public class SceneGroup {
public transient int block_id; // Not an actual variable in the scripts but we will keep it here for reference
public int id;
public int refresh_id;
public Position pos;
@ -14,4 +16,14 @@ public class SceneGroup {
public List<SceneTrigger> triggers;
public List<SceneSuite> suites;
public SceneInitConfig init_config;
private transient boolean isLoaded; // Not an actual variable in the scripts either
public boolean isLoaded() {
return isLoaded;
}
public boolean setLoaded(boolean loaded) {
return loaded;
}
}