Skip to content

Commit

Permalink
NativeEvents can now be used from any script type, can be added/remov…
Browse files Browse the repository at this point in the history
…ed/reloaded at runtime. Also added optional priority as first param. Removed NativeModEvents, it now decides based on class automatically
  • Loading branch information
LatvianModder committed Jun 25, 2024
1 parent f98a525 commit 8387f54
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 47 deletions.
11 changes: 1 addition & 10 deletions src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.ToolAction;
import net.neoforged.neoforge.common.crafting.SizedIngredient;
import net.neoforged.neoforge.fluids.FluidStack;
Expand Down Expand Up @@ -450,15 +449,7 @@ public void registerBindings(BindingRegistry bindings) {

bindings.add("BlockProperties", BlockStateProperties.class);

if (bindings.type().isStartup()) {
bindings.add("NativeEvents", new NativeEventWrapper("NativeEvents", NeoForge.EVENT_BUS));

var modBus = KubeJS.thisMod.getEventBus();

if (modBus != null) {
bindings.add("NativeModEvents", new NativeEventWrapper("NativeModEvents", modBus));
}
}
bindings.add("NativeEvents", NativeEventWrapper.class);
}

@Override
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/dev/latvian/mods/kubejs/KubeJS.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public static ResourceLocation id(String path) {
return ResourceLocation.fromNamespaceAndPath(MOD_ID, path);
}

public static IEventBus modEventBus;
public static ModContainer thisMod;

public static KubeJSCommon PROXY = new KubeJSCommon();
Expand All @@ -98,6 +99,7 @@ public static ScriptManager getClientScriptManager() {
}

public KubeJS(IEventBus bus, Dist dist, ModContainer mod) throws Throwable {
modEventBus = bus;
thisMod = mod;
VERSION = mod.getModInfo().getVersion().toString();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public class ButtonBlockBuilder extends ShapedBlockBuilder {

public transient BlockSetType behaviour;
public transient int ticksToStayPressed;
public transient boolean arrowsCanPress;

public ButtonBlockBuilder(ResourceLocation i) {
super(i, "_button");
Expand All @@ -27,7 +26,6 @@ public ButtonBlockBuilder(ResourceLocation i) {
// tagBoth(BlockTags.WOODEN_BUTTONS.location());
behaviour = BlockSetType.OAK;
ticksToStayPressed = 30;
arrowsCanPress = true;
}

public ButtonBlockBuilder behaviour(BlockSetType wt) {
Expand All @@ -40,12 +38,6 @@ public ButtonBlockBuilder ticksToStayPressed(int t) {
return this;
}

// TODO: this is now determined by the BlockSetType
public ButtonBlockBuilder arrowsCanPress(boolean b) {
arrowsCanPress = b;
return this;
}

@Override
public Block createObject() {
return new ButtonBlock(behaviour, ticksToStayPressed, createProperties());
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dev.latvian.mods.kubejs.neoforge;

import dev.latvian.mods.rhino.type.TypeInfo;
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.EventPriority;

import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;

public class NativeEventListeners implements Consumer<Event> {
public static final TypeInfo EVENT_CONSUMER_TYPE = TypeInfo.RAW_CONSUMER.withParams(TypeInfo.of(Event.class));

public record Key(Class<?> eventClass, EventPriority priority) {
@Override
public boolean equals(Object o) {
return o == this || o instanceof Key k && k.eventClass == eventClass && k.priority == priority;
}
}

public final List<Consumer<Event>> listeners;

public NativeEventListeners() {
this.listeners = new LinkedList<>();
}

@Override
public void accept(Event event) {
for (var listener : listeners) {
listener.accept(event);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
package dev.latvian.mods.kubejs.neoforge;

import dev.latvian.mods.kubejs.script.ConsoleJS;
import dev.latvian.mods.kubejs.KubeJS;
import dev.latvian.mods.kubejs.script.KubeJSContext;
import dev.latvian.mods.rhino.Context;
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.event.IModBusEvent;
import net.neoforged.neoforge.common.NeoForge;

public record NativeEventWrapper(String name, IEventBus eventBus) {
public Object onEvent(Context cx, Object eventClass, NativeEventConsumer consumer) {
if (!((KubeJSContext) cx).getType().isStartup()) {
throw new RuntimeException("Native event wrappers are only allowed in startup scripts!");
} else if (!(eventClass instanceof CharSequence || eventClass instanceof Class)) {
throw new RuntimeException("Invalid syntax! " + name + ".onEvent(eventType, function) requires event class and handler");
} else if (!((KubeJSContext) cx).kjsFactory.manager.firstLoad) {
ConsoleJS.STARTUP.warn(name + ".onEvent() can't be reloaded! You will have to restart the game for changes to take effect.");
return null;
import java.util.function.Consumer;

public interface NativeEventWrapper {
static void onEvent(Context cx, Class<?> eventClass, Consumer<Event> consumer) {
onEvent(cx, EventPriority.NORMAL, eventClass, consumer);
}

static void onEvent(Context cx, EventPriority priority, Class<?> eventClass, Consumer<Event> consumer) {
if (!Event.class.isAssignableFrom(eventClass)) {
throw new IllegalArgumentException("Event class must extend net.neoforged.bus.api.Event!");
}

try {
Class type = eventClass instanceof Class<?> c ? c : Class.forName(eventClass.toString());
eventBus.addListener(EventPriority.NORMAL, false, type, consumer);
} catch (Exception ex) {
throw new RuntimeException(ex);
var scriptType = ((KubeJSContext) cx).kjsFactory.manager.scriptType;
var key = new NativeEventListeners.Key(eventClass, priority == null ? EventPriority.NORMAL : priority);

var listeners = scriptType.nativeEventListeners.get(key);

if (listeners == null) {
listeners = new NativeEventListeners();
scriptType.nativeEventListeners.put(key, listeners);

IEventBus bus;

if (IModBusEvent.class.isAssignableFrom(eventClass)) {
bus = KubeJS.modEventBus;
} else {
bus = NeoForge.EVENT_BUS;
}

bus.addListener(priority, false, (Class) eventClass, listeners);
}

return null;
listeners.listeners.add((Consumer<Event>) cx.jsToJava(consumer, NativeEventListeners.EVENT_CONSUMER_TYPE));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ public class ScriptManager {
public final ScriptType scriptType;
public final Map<String, ScriptPack> packs;
private final ClassFilter classFilter;
public boolean firstLoad;
public KubeJSContextFactory contextFactory;
public boolean canListenEvents;

public ScriptManager(ScriptType t) {
scriptType = t;
packs = new LinkedHashMap<>();
firstLoad = true;
classFilter = KubeJSPlugins.createClassFilter(scriptType);
}

Expand Down Expand Up @@ -121,7 +119,6 @@ public void load() {
scriptType.console.contextFactory = new WeakReference<>(contextFactory);

if (PlatformWrapper.isGeneratingData()) {
firstLoad = false;
scriptType.console.info("Skipping KubeJS script loading (DataGen)");
return;
}
Expand Down Expand Up @@ -158,7 +155,6 @@ public void load() {
}

scriptType.console.info("Loaded " + i + "/" + t + " KubeJS " + scriptType.name + " scripts in " + (System.currentTimeMillis() - startAll) / 1000D + " s with " + scriptType.console.errors.size() + " errors and " + scriptType.console.warnings.size() + " warnings");
firstLoad = false;
canListenEvents = false;
}
}
9 changes: 9 additions & 0 deletions src/main/java/dev/latvian/mods/kubejs/script/ScriptType.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import dev.latvian.mods.kubejs.KubeJSPaths;
import dev.latvian.mods.kubejs.event.EventGroups;
import dev.latvian.mods.kubejs.neoforge.NativeEventListeners;
import dev.latvian.mods.kubejs.plugin.ClassFilter;
import dev.latvian.mods.kubejs.plugin.KubeJSPlugins;
import dev.latvian.mods.kubejs.util.Lazy;
Expand All @@ -12,7 +13,9 @@

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

public enum ScriptType implements ScriptTypePredicate, ScriptTypeHolder {
Expand All @@ -34,6 +37,7 @@ public enum ScriptType implements ScriptTypePredicate, ScriptTypeHolder {
public final String nameStrip;
public transient Executor executor;
public final Lazy<ClassFilter> classFilter;
public final Map<NativeEventListeners.Key, NativeEventListeners> nativeEventListeners;

ScriptType(String n, String cname, Path path) {
this.name = n;
Expand All @@ -42,6 +46,7 @@ public enum ScriptType implements ScriptTypePredicate, ScriptTypeHolder {
this.nameStrip = name + "_scripts:";
this.executor = Runnable::run;
this.classFilter = Lazy.of(() -> KubeJSPlugins.createClassFilter(this));
this.nativeEventListeners = new HashMap<>(0);
}

public Path getLogFile() {
Expand Down Expand Up @@ -90,6 +95,10 @@ public void unload() {
handler.clear(this);
}
}

for (var listener : nativeEventListeners.values()) {
listener.listeners.clear();
}
}

@Override
Expand Down

0 comments on commit 8387f54

Please sign in to comment.