Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 29 additions & 31 deletions src/main/java/com/tkisor/nekojs/api/event/EventGroup.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.tkisor.nekojs.api.event;

import com.tkisor.nekojs.script.ScriptType;
import com.tkisor.nekojs.script.WithScriptType;
import com.tkisor.nekojs.utils.event.dispatch.DispatchKey;

import java.util.Collections;
Expand All @@ -16,27 +17,24 @@ public static EventGroup of(String name) {
return new EventGroup(name);
}

final String name;
final Map<String, EventBusJS<?, ?>> buses;
final Map<String, ScriptType> targetScriptType;
private final String name;
private final Map<String, RegisteredBus> buses;

private EventGroup(String name) {
this.name = Objects.requireNonNull(name);
this.buses = new HashMap<>();
this.targetScriptType = new HashMap<>();
}

public String name() {
return name;
}

public Map<String, EventBusJS<?, ?>> viewBuses() {
public Map<String, BusHolder> viewBuses() {
return Collections.unmodifiableMap(buses);
}

public boolean isHandlerValidFor(String busName, ScriptType type) {
var scriptType = targetScriptType.get(busName);
return scriptType != null && (scriptType == ScriptType.COMMON || scriptType == type);
public BusHolder getBusHolder(String busName) {
return this.buses.get(busName);
}

public <E> EventBusJS<E, Void> server(String name, Class<E> type) {
Expand Down Expand Up @@ -72,44 +70,31 @@ public <E, K> EventBusJS<E, K> common(String name, Class<E> type, DispatchKey<E,
}

public <BUS extends EventBusJS<?, ?>> BUS add(String name, ScriptType scriptType, BUS bus) {
if (name == null) {
throw new IllegalArgumentException("name == null");
} else if (this.buses.containsKey(name)) {
Objects.requireNonNull(name, "name == null");
Objects.requireNonNull(scriptType, "scriptType == null");
Objects.requireNonNull(bus, "bus == null");
if (this.buses.containsKey(name)) {
throw new IllegalArgumentException(String.format("A bus with name '%s' has already been registered", name));
} else if (scriptType == null) {
throw new IllegalArgumentException("scriptType == null");
}
this.buses.put(name, bus);
this.targetScriptType.put(name, scriptType);

this.buses.put(name, new RegisteredBus(bus, scriptType));
return bus;
}

public void merge(EventGroup other) {
if (!this.name.equals(other.name)) {
return;
}
other.buses.forEach((busName, bus) -> {
ScriptType type = other.targetScriptType.get(busName);
this.add(busName, type, bus);
});
}

public void clearListeners() {
for (var busJS : buses.values()) {
clearBus(busJS);
}
other.buses.forEach((busName, registered) -> this.add(busName, registered.scriptType, registered.bus));
}

// 清理指定类型的监听器,用于reload scripts,但由于新的eventbus还未熟悉,也许后续会需要调整
public void clearListeners(ScriptType type) {
for (var entry : buses.entrySet()) {
String busName = entry.getKey();
EventBusJS<?, ?> busJS = entry.getValue();

ScriptType busType = targetScriptType.get(busName);
var registered = entry.getValue();

if (busType == type || type == ScriptType.COMMON) {
clearBus(busJS);
if (registered.canApplyOn(type)) {
clearBus(registered.bus);
}
}
}
Expand All @@ -120,4 +105,17 @@ private static <E> void clearBus(EventBusJS<E, ?> bus) {
bus.bus().unregister(token);
}
}

public interface BusHolder extends WithScriptType {

EventBusJS<?, ?> getBus(ScriptType targetEnv);
}

private record RegisteredBus(EventBusJS<?, ?> bus, ScriptType scriptType) implements BusHolder {

@Override
public EventBusJS<?, ?> getBus(ScriptType targetEnv) {
return canApplyOn(targetEnv) ? bus : null;
}
}
}
19 changes: 13 additions & 6 deletions src/main/java/com/tkisor/nekojs/api/event/EventGroupJS.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,46 @@
import graal.graalvm.polyglot.Value;
import graal.graalvm.polyglot.proxy.ProxyObject;

import java.util.Map;

/**
* @author ZZZank
*/
public class EventGroupJS implements ProxyObject {
private final EventGroup group;
private final ScriptType currentEnv;
private final Map<String, EventGroup.BusHolder> busView;

public EventGroupJS(EventGroup group, ScriptType currentEnv) {
this.group = group;
this.currentEnv = currentEnv;
this.busView = group.viewBuses();
}

@Override
public Object getMember(String key) {
var handler = group.buses.get(key);
if (handler == null) {
var busHolder = group.getBusHolder(key);
if (busHolder == null) {
throw new IllegalArgumentException(String.format("No such event bus: %s.%s", group.name(), key));
}
if (!group.isHandlerValidFor(key, currentEnv)) {

var bus = busHolder.getBus(this.currentEnv);
if (bus == null) {
throw new IllegalArgumentException(String.format("Event '%s.%s' not available in %s", group.name(), key, currentEnv));
}

return handler;
return bus;
}

@Override
public Object getMemberKeys() {
return group.buses.keySet().toArray();
return busView.keySet().toArray();
}

@Override
public boolean hasMember(String key) {
return group.buses.containsKey(key);
var holder = busView.get(key);
return holder != null && holder.canApplyOn(currentEnv);
}

@Override
Expand Down
Loading