diff options
| author | Markus Mittendrein <git@maxmitti.tk> | 2017-01-02 19:31:53 +0100 |
|---|---|---|
| committer | Markus Mittendrein <git@maxmitti.tk> | 2017-01-02 19:31:53 +0100 |
| commit | 0908f1bd900dc53a12b7ceba89e61bbaf2a4f639 (patch) | |
| tree | 3a4bd02a22835f644aefc6450a09bc8a74631b6a /System.c4g/Global.c | |
| download | DTEvents.c4d-0908f1bd900dc53a12b7ceba89e61bbaf2a4f639.tar.gz DTEvents.c4d-0908f1bd900dc53a12b7ceba89e61bbaf2a4f639.zip | |
Initial
Diffstat (limited to 'System.c4g/Global.c')
| -rw-r--r-- | System.c4g/Global.c | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/System.c4g/Global.c b/System.c4g/Global.c new file mode 100644 index 0000000..d3b126c --- /dev/null +++ b/System.c4g/Global.c @@ -0,0 +1,419 @@ +#strict 2
+
+static Event_Stack;
+static Event_StackPos;
+static Event_Listeners;
+
+static const Event_Sender = 0;
+static const Event_Name = 1;
+static const Event_ReturnValue = 2;
+static const Event_Accepted = 3;
+static const Event_Prevented = 4;
+
+global func AddEventListener(eventName, array listener, int priority, customArgs)
+{
+ if(GetType(eventName) == C4V_Array)
+ {
+ for(var i = 0; i < GetLength(eventName); ++i)
+ {
+ if(GetType(customArgs) == C4V_Array)
+ {
+ AddEventListener(eventName[i], listener, priority, customArgs[i]);
+ }
+ else
+ {
+ AddEventListener(eventName[i], listener, priority, customArgs);
+ }
+ }
+ return;
+ }
+
+ if(GetType(customArgs) != C4V_Array)
+ {
+ customArgs = [customArgs];
+ }
+
+ var sender = this;
+ if(GetType(sender) == C4V_C4Object)
+ {
+ sender = ObjectNumber(sender);
+ }
+ if(GetLength(listener) == 3)
+ {
+ customArgs = listener[2];
+ listener = [listener[0], listener[1]];
+ }
+ var newListener = [listener, customArgs];
+ var listeners = GetEventListeners(sender, eventName);
+ var i;
+ for(i = 0; i < GetLength(listeners); ++i)
+ {
+ if(GetType(listeners[i]) != C4V_Array)
+ {
+ listeners[i] = [priority, [newListener]];
+ i = -1;
+ break;
+ }
+ else if(listeners[i][0] == priority)
+ {
+ listeners[i][1][GetLength(listeners[i][1])] = newListener;
+ i = -1;
+ break;
+ }
+ else if(listeners[i][0] > priority)
+ {
+ break;
+ }
+ }
+ if(i != -1)
+ {
+ var swap = listeners[i], swap2;
+ listeners[i] = [priority, [newListener]];
+ var length = GetLength(listeners);
+ for(; i < length; ++i)
+ {
+ swap2 = listeners[i + 1];
+ listeners[i + 1] = swap;
+ swap = swap2;
+ }
+ }
+ SetEventListeners(sender, eventName, listeners);
+}
+
+global func RemoveEventListener(sender, eventName, listener, customArgs)
+{
+ if(GetType(sender) == C4V_C4Object)
+ {
+ sender = ObjectNumber(sender);
+ }
+ if(sender == -1)
+ {
+ var i = 0;
+ for(var i = 0; i < GetLength(Event_Listeners); ++i)
+ {
+ if(GetType(Event_Listeners[i]) == C4V_Array)
+ {
+ RemoveEventListener(i, eventName, listener, customArgs);
+ }
+ }
+ }
+ else
+ {
+ if(eventName == -1)
+ {
+ for(var event in Event_Listeners[sender])
+ {
+ RemoveEventListener(sender, event[0], listener, customArgs);
+ }
+ }
+ else
+ {
+ var emptyPrios = 0;
+ var eventListeners = GetEventListeners(sender, eventName);
+ for(var i = 0; i < GetLength(eventListeners); ++i)
+ {
+ if(GetType(eventListeners[i]) != C4V_Array)
+ {
+ ++emptyPrios;
+ continue;
+ }
+ var listeners = eventListeners[i][1];
+ eventListeners[i][1] = [];
+ for(var eventListener in listeners)
+ {
+ if(!((listener == -1 || eventListener[0] == listener) && (customArgs == -1 || eventListener[1] == customArgs)))
+ {
+ eventListeners[i][1][GetLength(eventListeners[i][1])] = eventListener;
+ }
+ }
+ if(GetLength(eventListeners[i][1]) == 0)
+ {
+ ++emptyPrios;
+ }
+ }
+ if(emptyPrios == GetLength(eventListeners))
+ {
+ ClearEventListener(sender, eventName);
+ }
+ else
+ {
+ ClearEmptyPrios(eventListeners);
+ SetEventListeners(sender, eventName, eventListeners);
+ }
+ }
+ }
+}
+
+global func ClearEventListener(sender, eventName)
+{
+ var eventListeners = Event_Listeners[sender];
+ Event_Listeners[sender] = [];
+ for(var i = 0; i < GetLength(eventListeners); ++i)
+ {
+ if(eventListeners[i][0] != eventName)
+ {
+ Event_Listeners[sender][GetLength(Event_Listeners[sender])] = eventListeners[i];
+ }
+ }
+ if(GetLength(Event_Listeners[sender]) == 0)
+ {
+ Event_Listeners[sender] = 0;
+ }
+}
+
+global func ClearEmptyPrios(&prios)
+{
+ var oldPrios = prios;
+ prios = [];
+
+ for(var prio in oldPrios)
+ {
+ if(GetType(prio) == C4V_Array)
+ {
+ if(GetLength(prio[1]) != 0)
+ {
+ prios[GetLength(prios)] = prio;
+ }
+ }
+ }
+}
+
+global func GetEventListeners(sender, eventName)
+{
+ if(GetType(Event_Listeners) == C4V_Array && GetType(Event_Listeners[sender]))
+ {
+ for(var event in Event_Listeners[sender])
+ {
+ if(event[0] == eventName)
+ {
+ return event[1];
+ }
+ }
+ }
+ return [];
+}
+
+global func SetEventListeners(sender, eventName, listeners)
+{
+ if(GetType(Event_Listeners) != C4V_Array)
+ {
+ Event_Listeners = CreateArray(sender);
+ Event_Listeners[sender] = [[eventName, listeners]];
+ }
+ else
+ {
+ if(GetType(Event_Listeners[sender]) == C4V_Array)
+ {
+ for(var i = 0; i < GetLength(Event_Listeners[sender]); ++i)
+ {
+ if(Event_Listeners[sender][i][0] == eventName)
+ {
+ Event_Listeners[sender][i][1] = listeners;
+ return;
+ }
+ }
+ }
+ else
+ {
+ Event_Listeners[sender] = [];
+ }
+ Event_Listeners[sender][GetLength(Event_Listeners[sender])] = [eventName, listeners];
+ }
+}
+
+global func PushEvent(array event)
+{
+ if(GetType(Event_Stack) != C4V_Array)
+ {
+ /*Event_Stack = [0, 0]; // otherwise there is a really stupid operator "=" left side: got "any" but expected "&" error at this line in Event():
+ * // Event_Stack[Event_StackPos][Event_ReturnValue] = CallListener(listener[0], listener[1], args, event);
+ * Event_StackPos = 0;
+ * PopEvent();*/
+ Event_Stack = [];
+ Event_StackPos = -1;
+ }
+ Event_Stack[++Event_StackPos] = event;
+}
+
+global func PopEvent()
+{
+ if(Event_StackPos >= 0)
+ {
+ var event = Event_Stack[Event_StackPos];
+ SetLength(Event_Stack, Event_StackPos--);
+ return event;
+ }
+}
+
+global func Accept()
+{
+ Event_Stack[Event_StackPos][Event_Accepted] = true;
+}
+
+global func Prevent()
+{
+ Event_Stack[Event_StackPos][Event_Prevented] = true;
+}
+
+global func Accepted(array event)
+{
+ if(event)
+ {
+ return event[Event_Accepted];
+ }
+ else
+ {
+ return Event_Stack[Event_StackPos][Event_Accepted];
+ }
+}
+
+global func Prevented(array event)
+{
+ if(event)
+ {
+ return event[Event_Prevented];
+ }
+ else
+ {
+ return Event_Stack[Event_StackPos][Event_Prevented];
+ }
+}
+
+global func ReturnValue(array event)
+{
+ if(event)
+ {
+ return event[Event_ReturnValue];
+ }
+ else
+ {
+ return Event_Stack[Event_StackPos][Event_ReturnValue];
+ }
+}
+
+global func Event(string eventName, array args)
+{
+ var sender = this;
+ var event = [sender, eventName, 0, false, false];
+ PushEvent(event);
+
+ if(GetType(sender) == C4V_C4Object)
+ {
+ sender = ObjectNumber(sender);
+ }
+
+ var allListeners = [GetEventListeners(sender, eventName)];
+ if(sender != 0)
+ {
+ allListeners[1] = GetEventListeners(0, eventName);
+ }
+
+ for(var listeners in allListeners)
+ {
+ for(var listenerPrio in listeners)
+ {
+ if(GetType(listenerPrio) == C4V_Array)
+ {
+ for(var listener in listenerPrio[1])
+ {
+ var ret = CallListener(listener[0], listener[1], args, event);
+ var e = Event_Stack[Event_StackPos];
+ e[Event_ReturnValue] = ret;
+ Event_Stack[Event_StackPos] = e;
+
+ if(Accepted())
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ event = PopEvent();
+ return event;
+}
+
+global func CallListener(array listener, array customArgs, array args, array event)
+{
+ if(GetType(listener[0]) == C4V_Any)
+ {
+ return eval(Format("%s(%s, %s, %s)", listener[1], Serialize(event), Serialize(customArgs), Serialize(args)));
+ }
+ else if(GetType(listener[0]) == C4V_C4Object)
+ {
+ if(GetType(listener[1]) == C4V_String)
+ {
+ return eval(Format("%s->%s(%s, %s, %s)", Serialize(listener[0]), listener[1], Serialize(event), Serialize(customArgs), Serialize(args)));
+ }
+ else if(GetType(listener[1]) == C4V_Array)
+ {
+ return listener[0]->f(listener[1], [event, customArgs, args]);
+ }
+ }
+ else if(listener[0] == -1 && event[0] != 0)
+ {
+ if(GetType(listener[1]) == C4V_String)
+ {
+ return eval(Format("%s->%s(%s, %s, %s)", Serialize(event[0]), listener[1], Serialize(event), Serialize(customArgs), Serialize(args)));
+ }
+ else if(GetType(listener[1]) == C4V_Array)
+ {
+ return event[0]->f(listener[1], [event, customArgs, args]);
+ }
+ }
+ else if(GetType(listener[0]) == C4V_Array)
+ {
+ return f(listener, [event, customArgs, args]);
+ }
+}
+
+global func Event_Adapter(target, string function, passArgs)
+{
+ return [target, "Event_AdapterListener", [target, function, passArgs]];
+}
+
+global func Event_AdapterListener(array event, array customArgs, array args)
+{
+ if(customArgs[2] == -1)
+ {
+ args = [];
+ }
+ else if(GetType(customArgs[2]) == C4V_Array)
+ {
+ args = customArgs[2];
+ }
+
+ var argString = "";
+ for(var i = 0; i < GetLength(args) && i < 10; ++i)
+ {
+ if(i != 0)
+ {
+ argString = Format("%s, ", argString);
+ }
+
+ argString = Format("%s%s", argString, Serialize(args[i]));
+ }
+
+ if(GetType(customArgs[0]) == C4V_Any || customArgs[0] == -1)
+ {
+ return eval(Format("%s(%s)", customArgs[1], argString));
+ }
+ else if(GetType(customArgs[0]) == C4V_C4Object)
+ {
+ return eval(Format("%s->%s(%s)", Serialize(customArgs[0]), customArgs[1], argString));
+ }
+}
+
+global func GameCallEx(string function)
+{
+ var event = Event(Format("GameCallEx%s", function), CreateFilledArray(...));
+ if(Prevented(event))
+ {
+ return ReturnValue(event);
+ }
+ else
+ {
+ return _inherited(function, ...);
+ }
+}
|
