mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
Added EventMeta data, EventRegistry
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.toop;
|
||||
|
||||
import org.toop.eventbus.EventRegistry;
|
||||
import org.toop.eventbus.Events;
|
||||
import org.toop.eventbus.GlobalEventBus;
|
||||
import org.toop.server.Server;
|
||||
@@ -7,6 +8,18 @@ import org.toop.server.Server;
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
|
||||
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.OnChangingServerBackend.class, e -> {
|
||||
System.out.println("Server backend has changed to -> " + e.backend());
|
||||
});
|
||||
|
||||
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.OnChangingServerIp.class, e -> {
|
||||
System.out.println("Server ip has changed to -> " + e.ip());
|
||||
});
|
||||
|
||||
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.OnChangingServerPort.class, e -> {
|
||||
System.out.println("Server port has changed to -> " + e.port());
|
||||
});
|
||||
|
||||
Server server = new Server(Server.ServerBackend.LOCAL, "127.0.0.1", "5000");
|
||||
server.setBackend(Server.ServerBackend.REMOTE);
|
||||
|
||||
@@ -17,15 +30,17 @@ public class Main {
|
||||
else if (e.command() == Server.Command.HELP) {
|
||||
System.out.println("HELP command -> " + String.join(" ", e.args()));
|
||||
}
|
||||
});
|
||||
|
||||
GlobalEventBus.subscribeAndRegister(Events.ServerEvents.OnChangingServerBackend.class, e -> {
|
||||
System.out.println("Server backend has changed to -> " + e.backend());
|
||||
else {
|
||||
System.out.println(e.command().toString());
|
||||
}
|
||||
});
|
||||
|
||||
Server.Message msg = server.sendCommand(Server.Command.LOGIN, "move");
|
||||
server.sendCommand(Server.Command.HELP, "test", "test2");
|
||||
server.sendCommand(Server.Command.BYE);
|
||||
|
||||
GlobalEventBus.post(new Events.ServerEvents.changeServerIp("127.1.1.1"));
|
||||
GlobalEventBus.post(new Events.ServerEvents.changeServerPort("5003"));
|
||||
server.setBackend(Server.ServerBackend.REMOTE);
|
||||
|
||||
System.out.println(msg);
|
||||
|
||||
41
src/main/java/org/toop/eventbus/EventMeta.java
Normal file
41
src/main/java/org/toop/eventbus/EventMeta.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package org.toop.eventbus;
|
||||
|
||||
/**
|
||||
* Wraps an event with its type and a ready flag.
|
||||
*/
|
||||
public class EventMeta<T> {
|
||||
private final Class<T> type;
|
||||
private final Object event;
|
||||
private boolean ready;
|
||||
|
||||
public EventMeta(Class<T> type, Object event) {
|
||||
this.type = type;
|
||||
this.event = event;
|
||||
this.ready = false; // default not ready
|
||||
}
|
||||
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Object getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return ready;
|
||||
}
|
||||
|
||||
public void setReady(boolean ready) {
|
||||
this.ready = ready;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ReadyEvent{" +
|
||||
"type=" + type.getSimpleName() +
|
||||
", event=" + event +
|
||||
", ready=" + ready +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
115
src/main/java/org/toop/eventbus/EventRegistry.java
Normal file
115
src/main/java/org/toop/eventbus/EventRegistry.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package org.toop.eventbus;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Thread-safe registry for storing events and tracking readiness of event types.
|
||||
*/
|
||||
public class EventRegistry {
|
||||
|
||||
private static final Map<Class<?>, CopyOnWriteArrayList<EventEntry<?>>> eventHistory =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
private static final Map<Class<?>, Boolean> readyStates = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Stores an event in the registry. Safe for concurrent use.
|
||||
*/
|
||||
public static <T> void storeEvent(EventMeta<T> eventMeta) {
|
||||
eventHistory
|
||||
.computeIfAbsent(eventMeta.getType(), k -> new CopyOnWriteArrayList<>())
|
||||
.add(new EventEntry<>(eventMeta));
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a specific event type as ready (safe to post).
|
||||
*/
|
||||
public static <T> void markReady(Class<T> type) {
|
||||
readyStates.put(type, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a specific event type as not ready (posting will fail).
|
||||
*/
|
||||
public static <T> void markNotReady(Class<T> type) {
|
||||
readyStates.put(type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this event type is marked ready.
|
||||
*/
|
||||
public static <T> boolean isReady(Class<T> type) {
|
||||
return readyStates.getOrDefault(type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all stored events of a given type.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<EventEntry<T>> getEvents(Class<T> type) {
|
||||
return (List<EventEntry<T>>) (List<?>) eventHistory
|
||||
.getOrDefault(type, new CopyOnWriteArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the most recent event of a given type, or null if none exist.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> EventEntry<T> getLastEvent(Class<T> type) {
|
||||
List<EventEntry<?>> entries = eventHistory.get(type);
|
||||
if (entries == null || entries.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return (EventEntry<T>) entries.get(entries.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the stored events for a given type.
|
||||
*/
|
||||
public static <T> void clearEvents(Class<T> type) {
|
||||
eventHistory.remove(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all events and resets readiness.
|
||||
*/
|
||||
public static void reset() {
|
||||
eventHistory.clear();
|
||||
readyStates.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for stored events, with a ready flag for per-event state.
|
||||
*/
|
||||
public static class EventEntry<T> {
|
||||
private final T event;
|
||||
private volatile boolean ready = false;
|
||||
|
||||
public EventEntry(T event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public T getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return ready;
|
||||
}
|
||||
|
||||
public void setReady(boolean ready) {
|
||||
this.ready = ready;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EventEntry{" +
|
||||
"event=" + event +
|
||||
", ready=" + ready +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import org.toop.server.Server;
|
||||
/**
|
||||
* Events that are used in the GlobalEventBus class.
|
||||
*/
|
||||
public class Events {
|
||||
public class Events implements IEvents {
|
||||
|
||||
public static class ServerEvents {
|
||||
/**
|
||||
|
||||
@@ -30,12 +30,13 @@ public enum GlobalEventBus {
|
||||
|
||||
/**
|
||||
* Wraps a Consumer into a Guava @Subscribe-compatible listener.
|
||||
* TODO
|
||||
*
|
||||
* @param type The event to be used. (e.g. Events.ServerCommand.class)
|
||||
* @param action The function, or lambda to run when fired.
|
||||
* @return Object to be used for registering an event.
|
||||
*/
|
||||
public static <T> Object subscribe(Class<T> type, Consumer<T> action) {
|
||||
private static <T> Object subscribe(Class<T> type, Consumer<T> action) {
|
||||
return new Object() {
|
||||
@Subscribe
|
||||
public void handle(T event) {
|
||||
@@ -51,7 +52,7 @@ public enum GlobalEventBus {
|
||||
* @param action The function, or lambda to run when fired.
|
||||
* @return Object to be used for registering an event.
|
||||
*/
|
||||
public static <T> Object subscribeAndRegister(Class<T> type, Consumer<T> action) {
|
||||
public static <T> EventMeta subscribeAndRegister(Class<T> type, Consumer<T> action) {
|
||||
Object listener = new Object() {
|
||||
@Subscribe
|
||||
public void handle(Object event) {
|
||||
@@ -60,30 +61,46 @@ public enum GlobalEventBus {
|
||||
}
|
||||
}
|
||||
};
|
||||
register(listener);
|
||||
return listener;
|
||||
var re = new EventMeta<>(type, listener);
|
||||
register(re);
|
||||
return re;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for registering a listener.
|
||||
*
|
||||
* @param listener The event listener to register.
|
||||
* @param event The ready event to add to register.
|
||||
*/
|
||||
public static void register(Object listener) {
|
||||
GlobalEventBus.INSTANCE.get().register(listener);
|
||||
public static <T> void register(EventMeta<T> event) {
|
||||
GlobalEventBus.INSTANCE.get().register(event.getEvent());
|
||||
event.setReady(true);
|
||||
EventRegistry.markReady(event.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for unregistering a listener.
|
||||
*
|
||||
* @param listener The event listener to unregister.
|
||||
* @param event The ready event to unregister.
|
||||
*/
|
||||
public static void unregister(Object listener) {
|
||||
GlobalEventBus.INSTANCE.get().unregister(listener);
|
||||
public static <T> void unregister(EventMeta<T> event) {
|
||||
EventRegistry.markNotReady(event.getType());
|
||||
event.setReady(false);
|
||||
GlobalEventBus.INSTANCE.get().unregister(event.getEvent());
|
||||
}
|
||||
|
||||
public static void post(Object event) {
|
||||
public static <T> void post(T event) {
|
||||
Class<T> type = (Class<T>) event.getClass();
|
||||
|
||||
if (!EventRegistry.isReady(type)) {
|
||||
throw new IllegalStateException("Event type not ready: " + type.getSimpleName());
|
||||
}
|
||||
|
||||
// store in registry
|
||||
EventMeta<T> eventMeta = new EventMeta<>(type, event);
|
||||
EventRegistry.storeEvent(eventMeta);
|
||||
|
||||
// post to Guava EventBus
|
||||
GlobalEventBus.INSTANCE.get().post(event);
|
||||
}
|
||||
|
||||
|
||||
3
src/main/java/org/toop/eventbus/IEvents.java
Normal file
3
src/main/java/org/toop/eventbus/IEvents.java
Normal file
@@ -0,0 +1,3 @@
|
||||
package org.toop.eventbus;
|
||||
|
||||
public interface IEvents {}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.toop.server;
|
||||
|
||||
import org.toop.eventbus.EventRegistry;
|
||||
import org.toop.eventbus.Events;
|
||||
import org.toop.eventbus.GlobalEventBus;
|
||||
import org.toop.server.backend.*;
|
||||
|
||||
Reference in New Issue
Block a user