From c7e3ff235681419f7bd72cb9e0f17fdfcf5d1fbd Mon Sep 17 00:00:00 2001
From: ZZYZX <zzyzx@virtual>
Date: Mon, 30 Jan 2017 09:28:27 +0200
Subject: [PATCH] Static event handlers can create/register/unregister other
 static event handlers.

---
 src/events.cpp                   | 39 +++++++++++++++++++++++++++++++-
 wadsrc/static/zscript/events.txt |  8 +++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/events.cpp b/src/events.cpp
index e61dd019a..f296144d9 100755
--- a/src/events.cpp
+++ b/src/events.cpp
@@ -289,7 +289,30 @@ DEFINE_ACTION_FUNCTION(DEventHandler, CreateOnce)
 	// check if there are already registered handlers of this type.
 	for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
 		if (handler->GetClass() == t) // check precise class
-			ACTION_RETURN_OBJECT(nullptr);
+			ACTION_RETURN_OBJECT(handler);
+	// generate a new object of this type.
+	ACTION_RETURN_OBJECT(t->CreateNew());
+}
+
+// for static
+DEFINE_ACTION_FUNCTION(DStaticEventHandler, Create)
+{
+	PARAM_PROLOGUE;
+	PARAM_CLASS(t, DStaticEventHandler);
+	// static handlers can create any type of object.
+	// generate a new object of this type.
+	ACTION_RETURN_OBJECT(t->CreateNew());
+}
+
+DEFINE_ACTION_FUNCTION(DStaticEventHandler, CreateOnce)
+{
+	PARAM_PROLOGUE;
+	PARAM_CLASS(t, DStaticEventHandler);
+	// static handlers can create any type of object.
+	// check if there are already registered handlers of this type.
+	for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
+		if (handler->GetClass() == t) // check precise class
+			ACTION_RETURN_OBJECT(handler);
 	// generate a new object of this type.
 	ACTION_RETURN_OBJECT(t->CreateNew());
 }
@@ -320,6 +343,20 @@ DEFINE_ACTION_FUNCTION(DEventHandler, Unregister)
 	ACTION_RETURN_BOOL(E_UnregisterHandler(handler));
 }
 
+DEFINE_ACTION_FUNCTION(DStaticEventHandler, Register)
+{
+	PARAM_PROLOGUE;
+	PARAM_OBJECT(handler, DStaticEventHandler);
+	ACTION_RETURN_BOOL(E_RegisterHandler(handler));
+}
+
+DEFINE_ACTION_FUNCTION(DStaticEventHandler, Unregister)
+{
+	PARAM_PROLOGUE;
+	PARAM_OBJECT(handler, DStaticEventHandler);
+	ACTION_RETURN_BOOL(E_UnregisterHandler(handler));
+}
+
 #define DEFINE_EVENT_HANDLER(cls, funcname, args) DEFINE_ACTION_FUNCTION(cls, funcname) \
 { \
 	PARAM_SELF_PROLOGUE(cls); \
diff --git a/wadsrc/static/zscript/events.txt b/wadsrc/static/zscript/events.txt
index e3ee54025..85a662e3a 100755
--- a/wadsrc/static/zscript/events.txt
+++ b/wadsrc/static/zscript/events.txt
@@ -1,5 +1,13 @@
 class StaticEventHandler : Object native
 {
+    // static event handlers CAN register other static event handlers.
+    // unlike EventHandler.Create that will not create them.
+    protected static native StaticEventHandler Create(class<StaticEventHandler> type);
+    protected static native StaticEventHandler CreateOnce(class<StaticEventHandler> type);
+    
+    protected static native bool Register(StaticEventHandler handler);
+    protected static native bool Unregister(StaticEventHandler handler);
+
 	virtual native void WorldLoaded();
 	virtual native void WorldUnloaded();
     virtual native void WorldThingSpawned();