Intial commit
This commit is contained in:
parent
7329fb8dea
commit
73f201bdac
268 changed files with 11220 additions and 5 deletions
10
no2all-react/pom.xml
Normal file
10
no2all-react/pom.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>love.distributedrebirth.no2all</groupId>
|
||||
<artifactId>no2all</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>no2all-react</artifactId>
|
||||
<name>No2All-React</name>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package love.distributedrebirth.no2all.react;
|
||||
|
||||
public interface No2AllReact {
|
||||
|
||||
void claim(No2AllReactSlot slot);
|
||||
void claimIn(No2AllReactSlot slot, Class<?> eventType);
|
||||
void claimOut(No2AllReactSlot slot, Class<?> eventType);
|
||||
void requireSlot(No2AllReactSlot slot, No2AllReactSlot dep);
|
||||
void requireService(No2AllReactSlot slot, Class<?> serviceType);
|
||||
|
||||
void fire(No2AllReactSlot slot, Object event);
|
||||
void fireForEach(No2AllReactSlot slot, Object event);
|
||||
<T> void registrate(No2AllReactSlot slot, Class<T> eventType, No2AllReactListener<T> listener);
|
||||
|
||||
<T> T service(Class<T> serviceType);
|
||||
void release(No2AllReactSlot slot);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package love.distributedrebirth.no2all.react;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface No2AllReactListener<T> {
|
||||
|
||||
void onEvent(No2AllReactSlotSignal<T> signal);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package love.distributedrebirth.no2all.react;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class No2AllReactSlot {
|
||||
|
||||
private final No2AllReactSlot parent;
|
||||
private final String slotSlug;
|
||||
private final String slotPath;
|
||||
|
||||
private No2AllReactSlot(No2AllReactSlot parent, String slotSlug) {
|
||||
this.parent = parent;
|
||||
this.slotSlug = slotSlug;
|
||||
this.slotPath = createSlotPath();
|
||||
}
|
||||
|
||||
public No2AllReactSlot getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public String getSlotSlug() {
|
||||
return slotSlug;
|
||||
}
|
||||
|
||||
public String getSlotPath() {
|
||||
return slotPath;
|
||||
}
|
||||
|
||||
public String createSlotPath() {
|
||||
List<String> slugs = new ArrayList<>();
|
||||
No2AllReactSlot parentNode = this;
|
||||
while (parentNode != null) {
|
||||
slugs.add(parentNode.getSlotSlug());
|
||||
parentNode = parentNode.getParent();
|
||||
}
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i = slugs.size() - 1; i >= 0; i--) {
|
||||
buf.append(slugs.get(i));
|
||||
if (i > 0) {
|
||||
buf.append(',');
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(slotPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
No2AllReactSlot other = (No2AllReactSlot) obj;
|
||||
return Objects.equals(slotPath, other.slotPath);
|
||||
}
|
||||
|
||||
public static No2AllReactSlot ofClass(Class<?> scriptClz) {
|
||||
return new No2AllReactSlot(null, scriptClz.getPackageName() + ":type=" + scriptClz.getSimpleName());
|
||||
}
|
||||
|
||||
public static No2AllReactSlot of(No2AllReactSlot parent, String kvPair) {
|
||||
return new No2AllReactSlot(parent, kvPair);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package love.distributedrebirth.no2all.react;
|
||||
|
||||
public final class No2AllReactSlotLoad {
|
||||
|
||||
public No2AllReactSlotLoad() {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package love.distributedrebirth.no2all.react;
|
||||
|
||||
public final class No2AllReactSlotSignal<T> {
|
||||
|
||||
private final No2AllReactSlot target;
|
||||
private final T data;
|
||||
private final No2AllReact react;
|
||||
|
||||
public No2AllReactSlotSignal(No2AllReactSlot target, T data, No2AllReact react) {
|
||||
this.target = target;
|
||||
this.data = data;
|
||||
this.react = react;
|
||||
}
|
||||
|
||||
public No2AllReactSlot getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public No2AllReact getReact() {
|
||||
return react;
|
||||
}
|
||||
|
||||
// public T $() {
|
||||
// return getData();
|
||||
// }
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package love.distributedrebirth.no2all.react;
|
||||
|
||||
public interface No2AllReactTypeScript extends No2AllReactListener<No2AllReactSlotLoad> {
|
||||
|
||||
default void onRelease(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package love.distributedrebirth.no2all.react.warp;
|
||||
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlot;
|
||||
|
||||
public abstract class No2AllActAbstractSlot {
|
||||
|
||||
private final No2AllReactSlot slot;
|
||||
|
||||
public No2AllActAbstractSlot(No2AllReactSlot slot) {
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
public final No2AllReactSlot getSlot() {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package love.distributedrebirth.no2all.react.warp;
|
||||
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlot;
|
||||
|
||||
public final class No2AllArtWarpSlotAdd extends No2AllActAbstractSlot {
|
||||
|
||||
protected No2AllArtWarpSlotAdd(No2AllReactSlot slot) {
|
||||
super(slot);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package love.distributedrebirth.no2all.react.warp;
|
||||
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlot;
|
||||
|
||||
public final class No2AllArtWarpSlotRemove extends No2AllActAbstractSlot {
|
||||
|
||||
protected No2AllArtWarpSlotRemove(No2AllReactSlot slot) {
|
||||
super(slot);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package love.distributedrebirth.no2all.react.warp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlot;
|
||||
|
||||
public class No2AllReactSlotContract {
|
||||
|
||||
private final No2AllReactSlot slot;
|
||||
final List<Class<?>> slotTypesIn = new ArrayList<>();
|
||||
final List<Class<?>> slotTypesOut = new ArrayList<>();
|
||||
|
||||
public No2AllReactSlotContract(No2AllReactSlot slot) {
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
public No2AllReactSlot getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
public List<Class<?>> getSlotTypesIn() {
|
||||
return slotTypesIn;
|
||||
}
|
||||
|
||||
public List<Class<?>> getSlotTypesOut() {
|
||||
return slotTypesOut;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
package love.distributedrebirth.no2all.react.warp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
|
||||
import love.distributedrebirth.no2all.react.No2AllReact;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactListener;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlot;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
|
||||
|
||||
public class No2AllReactWarpCore implements No2AllReact {
|
||||
|
||||
public static final No2AllReactSlot DILITHIUM = No2AllReactSlot.ofClass(No2AllReactWarpCore.class);
|
||||
private final Map<No2AllReactSlot, No2AllReactWarpFuel> slots = new HashMap<>();
|
||||
private final Map<Class<?>, Object> services = new HashMap<>();
|
||||
private final List<BacklogEvent> backlog = new ArrayList<>();
|
||||
private Object currentEvent = null;
|
||||
|
||||
public No2AllReactWarpCore() {
|
||||
claim(DILITHIUM);
|
||||
toWarpFuel(DILITHIUM).registrateTypeIn(No2AllReactSlotLoad.class);
|
||||
toWarpFuel(DILITHIUM).registrateTypeOut(No2AllArtWarpSlotAdd.class);
|
||||
toWarpFuel(DILITHIUM).registrateTypeOut(No2AllArtWarpSlotRemove.class);
|
||||
}
|
||||
|
||||
public void load(No2AllReactTypeScript script) {
|
||||
Objects.requireNonNull(script).onEvent(new No2AllReactSlotSignal<>(DILITHIUM, new No2AllReactSlotLoad(), this));
|
||||
}
|
||||
|
||||
public No2AllReactSlotContract getSlotContract(No2AllReactSlot slot) {
|
||||
return toWarpFuel(slot).readContract();
|
||||
}
|
||||
|
||||
public List<No2AllReactSlot> listChilds(No2AllReactSlot slot) {
|
||||
Objects.requireNonNull(slot);
|
||||
List<No2AllReactSlot> result = new ArrayList<>();
|
||||
synchronized (slots) {
|
||||
for (No2AllReactSlot slug : slots.keySet()) {
|
||||
if (slot == null) {
|
||||
result.add(slug);
|
||||
continue;
|
||||
}
|
||||
if (slug.getParent() == null) {
|
||||
continue;
|
||||
}
|
||||
if (slug.getParent().getSlotPath().equals(slot.getSlotPath())) {
|
||||
result.add(slug);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireForEach(No2AllReactSlot slot, Object event) {
|
||||
for (No2AllReactSlot target : listChilds(slot)) {
|
||||
fire(target, event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fire(No2AllReactSlot slot, Object event) {
|
||||
Objects.requireNonNull(slot);
|
||||
Objects.requireNonNull(event);
|
||||
if (currentEvent != null) {
|
||||
backlog.add(new BacklogEvent(slot, event));
|
||||
return;
|
||||
}
|
||||
currentEvent = event;
|
||||
try {
|
||||
toWarpFuel(slot).fire(event, slot);
|
||||
|
||||
List<BacklogEvent> backlog2 = new ArrayList<>(backlog);
|
||||
backlog.clear();
|
||||
for (BacklogEvent next : backlog2) {
|
||||
toWarpFuel(next.slot).fire(next.event, next.slot);
|
||||
}
|
||||
} finally {
|
||||
currentEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
static class BacklogEvent {
|
||||
No2AllReactSlot slot;
|
||||
Object event;
|
||||
public BacklogEvent(No2AllReactSlot slot, Object event) {
|
||||
this.slot = slot;
|
||||
this.event = event;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> void registrate(No2AllReactSlot slot, Class<T> eventType, No2AllReactListener<T> listener) {
|
||||
No2AllReactListener<Object> listenerObj = (No2AllReactListener<Object>) listener;
|
||||
toWarpFuel(slot).registrateListener(eventType, listenerObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(No2AllReactSlot slot) {
|
||||
toWarpFuel(slot).removeAll();
|
||||
synchronized (slots) {
|
||||
slots.remove(slot);
|
||||
}
|
||||
fire(DILITHIUM, new No2AllArtWarpSlotRemove(slot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void claim(No2AllReactSlot slot) {
|
||||
Objects.requireNonNull(slot);
|
||||
synchronized (slots) {
|
||||
if (slots.keySet().contains(slot)) {
|
||||
throw new IllegalStateException("Slug already claimed: " + slot.getSlotPath());
|
||||
}
|
||||
slots.put(slot, new No2AllReactWarpFuel(this, slot));
|
||||
}
|
||||
fire(DILITHIUM, new No2AllArtWarpSlotAdd(slot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void claimOut(No2AllReactSlot slot, Class<?> eventType) {
|
||||
toWarpFuel(slot).registrateTypeOut(eventType);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void claimIn(No2AllReactSlot slot, Class<?> eventType) {
|
||||
toWarpFuel(slot).registrateTypeIn(eventType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireSlot(No2AllReactSlot slot, No2AllReactSlot dep) {
|
||||
if (!isClaimed(dep)) {
|
||||
throw new IllegalStateException("Script dependency missing: " + dep);
|
||||
}
|
||||
toWarpFuel(slot).addRequireSlot(dep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireService(No2AllReactSlot slot, Class<?> serviceType) {
|
||||
toWarpFuel(slot).addRequireService(serviceType);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T service(Class<T> serviceType) {
|
||||
Objects.requireNonNull(serviceType);
|
||||
synchronized (services) {
|
||||
return (T) services.get(serviceType);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void addService(Class<T> serviceType, T service) {
|
||||
Objects.requireNonNull(serviceType);
|
||||
Objects.requireNonNull(service);
|
||||
synchronized (services) {
|
||||
services.put(serviceType, service);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isClaimed(No2AllReactSlot slug) {
|
||||
Objects.requireNonNull(slug);
|
||||
synchronized (slots) {
|
||||
return slots.keySet().contains(slug);
|
||||
}
|
||||
}
|
||||
|
||||
protected No2AllReactWarpFuel toWarpFuel(No2AllReactSlot slot) {
|
||||
Objects.requireNonNull(slot);
|
||||
No2AllReactWarpFuel result;
|
||||
synchronized (slots) {
|
||||
result = slots.get(slot);
|
||||
if (result == null) {
|
||||
throw new IllegalStateException("Slot not claimed: " + slot.getSlotPath());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
package love.distributedrebirth.no2all.react.warp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import love.distributedrebirth.no2all.react.No2AllReactListener;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlot;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
|
||||
|
||||
public class No2AllReactWarpFuel {
|
||||
|
||||
private final No2AllReactWarpCore no2AllReactWarpCore;
|
||||
private final No2AllReactSlot containerSlot;
|
||||
private final Map<Class<?>, List<No2AllReactListener<Object>>> listeners = new HashMap<>();
|
||||
private final Set<Class<?>> claimTypesOut = new HashSet<>();
|
||||
private final Set<Class<?>> claimTypesIn = new HashSet<>();
|
||||
private final Set<Class<?>> requireServices = new HashSet<>();
|
||||
private final Set<No2AllReactSlot> requireSlots = new HashSet<>();
|
||||
|
||||
protected No2AllReactWarpFuel(No2AllReactWarpCore no2AllReactWarpCore, No2AllReactSlot containerSlot) {
|
||||
this.no2AllReactWarpCore = Objects.requireNonNull(no2AllReactWarpCore);
|
||||
this.containerSlot = Objects.requireNonNull(containerSlot);
|
||||
}
|
||||
|
||||
private List<No2AllReactListener<Object>> toViewOfListeners(Class<?> eventType) {
|
||||
List<No2AllReactListener<Object>> result = new ArrayList<>();
|
||||
synchronized (listeners) {
|
||||
List<No2AllReactListener<Object>> typeListeners = listeners.get(eventType);
|
||||
if (typeListeners == null) {
|
||||
return result;
|
||||
}
|
||||
result.addAll(typeListeners);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void fire(Object event, No2AllReactSlot slot) {
|
||||
for (No2AllReactListener<Object> listener : toViewOfListeners(event.getClass())) {
|
||||
listener.onEvent(new No2AllReactSlotSignal<>(slot, event, this.no2AllReactWarpCore));
|
||||
}
|
||||
}
|
||||
|
||||
public void registrateListener(Class<?> eventType, No2AllReactListener<Object> listener) {
|
||||
Objects.requireNonNull(eventType);
|
||||
Objects.requireNonNull(listener);
|
||||
synchronized (listeners) {
|
||||
List<No2AllReactListener<Object>> typeListeners = listeners.get(eventType);
|
||||
if (typeListeners == null) {
|
||||
typeListeners = new ArrayList<>();
|
||||
listeners.put(eventType, typeListeners);
|
||||
}
|
||||
typeListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void registrateTypeOut(Class<?> eventType) {
|
||||
Objects.requireNonNull(eventType);
|
||||
synchronized (claimTypesOut) {
|
||||
claimTypesOut.add(eventType);
|
||||
}
|
||||
}
|
||||
|
||||
public void registrateTypeIn(Class<?> eventType) {
|
||||
Objects.requireNonNull(eventType);
|
||||
synchronized (claimTypesIn) {
|
||||
claimTypesIn.add(eventType);
|
||||
}
|
||||
}
|
||||
|
||||
public No2AllReactSlotContract readContract() {
|
||||
No2AllReactSlotContract result = new No2AllReactSlotContract(containerSlot);
|
||||
synchronized (claimTypesIn) {
|
||||
result.slotTypesIn.addAll(claimTypesIn);
|
||||
}
|
||||
synchronized (claimTypesOut) {
|
||||
result.slotTypesOut.addAll(claimTypesOut);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addRequireService(Class<?> serviceType) {
|
||||
Objects.requireNonNull(serviceType);
|
||||
synchronized (requireServices) {
|
||||
requireServices.add(serviceType);
|
||||
}
|
||||
}
|
||||
|
||||
public void addRequireSlot(No2AllReactSlot dep) {
|
||||
Objects.requireNonNull(dep);
|
||||
synchronized (requireSlots) {
|
||||
requireSlots.add(dep);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAll() {
|
||||
synchronized (listeners) {
|
||||
for (Class<?> eventType : listeners.keySet()) {
|
||||
List<No2AllReactListener<Object>> typeListeners = listeners.get(eventType);
|
||||
typeListeners.clear();
|
||||
}
|
||||
}
|
||||
synchronized (claimTypesOut) {
|
||||
claimTypesOut.clear();
|
||||
}
|
||||
synchronized (claimTypesIn) {
|
||||
claimTypesIn.clear();
|
||||
}
|
||||
synchronized (requireServices) {
|
||||
requireServices.clear();
|
||||
}
|
||||
synchronized (requireSlots) {
|
||||
requireSlots.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package love.distributedrebirth.no2all.react.warp;
|
||||
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import love.distributedrebirth.no2all.react.No2AllReact;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlot;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
|
||||
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
|
||||
|
||||
public class No2AllRtsWarpSpeedMonitor implements No2AllReactTypeScript {
|
||||
|
||||
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(No2AllRtsWarpSpeedMonitor.class);
|
||||
private static final No2AllReactSlot API_DILITHIUM = No2AllReactWarpCore.DILITHIUM;
|
||||
private static final Logger LOG = Logger.getLogger(No2AllRtsWarpSpeedMonitor.class.getName());
|
||||
|
||||
@Override
|
||||
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
|
||||
No2AllReact react = signal.getReact();
|
||||
react.claim(API);
|
||||
react.requireSlot(API, API_DILITHIUM);
|
||||
react.registrate(API_DILITHIUM, No2AllArtWarpSlotAdd.class, v -> {
|
||||
LOG.fine("slot-add: " + v.getData().getSlot().getSlotPath());
|
||||
});
|
||||
react.registrate(API_DILITHIUM, No2AllArtWarpSlotRemove.class, v -> {
|
||||
LOG.fine("slot-remove: " + v.getData().getSlot().getSlotPath());
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue