mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
Added ordering for handlers - by int value returned by virtual function GetOrder(); Also, some handlers (WorldUnloaded and WorldThingDestroyed) are now executed in reverse order.
This commit is contained in:
parent
765bc2db39
commit
bc1194d03b
3 changed files with 86 additions and 8 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
|
|
||||||
DStaticEventHandler* E_FirstEventHandler = nullptr;
|
DStaticEventHandler* E_FirstEventHandler = nullptr;
|
||||||
|
DStaticEventHandler* E_LastEventHandler = nullptr;
|
||||||
|
|
||||||
bool E_RegisterHandler(DStaticEventHandler* handler)
|
bool E_RegisterHandler(DStaticEventHandler* handler)
|
||||||
{
|
{
|
||||||
|
@ -14,17 +15,53 @@ bool E_RegisterHandler(DStaticEventHandler* handler)
|
||||||
return false;
|
return false;
|
||||||
if (E_CheckHandler(handler))
|
if (E_CheckHandler(handler))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// link into normal list
|
// link into normal list
|
||||||
handler->prev = nullptr;
|
// update: link at specific position based on order.
|
||||||
handler->next = E_FirstEventHandler;
|
DStaticEventHandler* before = nullptr;
|
||||||
if (handler->next)
|
for (DStaticEventHandler* existinghandler = E_FirstEventHandler; existinghandler; existinghandler = existinghandler->next)
|
||||||
handler->next->prev = handler;
|
{
|
||||||
|
if (existinghandler->GetOrder() > handler->GetOrder())
|
||||||
|
{
|
||||||
|
before = existinghandler;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. MyHandler2->1:
|
||||||
|
// E_FirstEventHandler = MyHandler2, E_LastEventHandler = MyHandler2
|
||||||
|
// 2. MyHandler3->2:
|
||||||
|
// E_FirstEventHandler = MyHandler2, E_LastEventHandler = MyHandler3
|
||||||
|
|
||||||
|
if (before != nullptr)
|
||||||
|
{
|
||||||
|
// if before is not null, link it before the existing handler.
|
||||||
|
// note that before can be first handler, check for this.
|
||||||
|
handler->next = before;
|
||||||
|
handler->prev = before->prev;
|
||||||
|
before->prev = handler;
|
||||||
|
if (before == E_FirstEventHandler)
|
||||||
E_FirstEventHandler = handler;
|
E_FirstEventHandler = handler;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// so if before is null, it means add last.
|
||||||
|
// it can also mean that we have no handlers at all yet.
|
||||||
|
handler->prev = E_LastEventHandler;
|
||||||
|
handler->next = nullptr;
|
||||||
|
if (E_FirstEventHandler == nullptr)
|
||||||
|
E_FirstEventHandler = handler;
|
||||||
|
E_LastEventHandler = handler;
|
||||||
|
if (handler->prev != nullptr)
|
||||||
|
handler->prev->next = handler;
|
||||||
|
}
|
||||||
|
|
||||||
if (handler->IsStatic())
|
if (handler->IsStatic())
|
||||||
{
|
{
|
||||||
handler->ObjectFlags |= OF_Fixed;
|
handler->ObjectFlags |= OF_Fixed;
|
||||||
handler->ObjectFlags |= OF_Transient;
|
handler->ObjectFlags |= OF_Transient;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +78,8 @@ bool E_UnregisterHandler(DStaticEventHandler* handler)
|
||||||
handler->next->prev = handler->prev;
|
handler->next->prev = handler->prev;
|
||||||
if (handler == E_FirstEventHandler)
|
if (handler == E_FirstEventHandler)
|
||||||
E_FirstEventHandler = handler->next;
|
E_FirstEventHandler = handler->next;
|
||||||
|
if (handler == E_LastEventHandler)
|
||||||
|
E_LastEventHandler = handler->prev;
|
||||||
if (handler->IsStatic())
|
if (handler->IsStatic())
|
||||||
{
|
{
|
||||||
handler->ObjectFlags &= ~(OF_Fixed|OF_Transient);
|
handler->ObjectFlags &= ~(OF_Fixed|OF_Transient);
|
||||||
|
@ -224,7 +263,7 @@ void E_WorldLoaded()
|
||||||
|
|
||||||
void E_WorldUnloaded()
|
void E_WorldUnloaded()
|
||||||
{
|
{
|
||||||
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
|
for (DStaticEventHandler* handler = E_LastEventHandler; handler; handler = handler->prev)
|
||||||
{
|
{
|
||||||
if (handler->IsStatic()) continue;
|
if (handler->IsStatic()) continue;
|
||||||
handler->WorldUnloaded();
|
handler->WorldUnloaded();
|
||||||
|
@ -242,7 +281,7 @@ void E_WorldLoadedUnsafe()
|
||||||
|
|
||||||
void E_WorldUnloadedUnsafe()
|
void E_WorldUnloadedUnsafe()
|
||||||
{
|
{
|
||||||
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
|
for (DStaticEventHandler* handler = E_LastEventHandler; handler; handler = handler->prev)
|
||||||
{
|
{
|
||||||
if (!handler->IsStatic()) continue;
|
if (!handler->IsStatic()) continue;
|
||||||
handler->WorldUnloaded();
|
handler->WorldUnloaded();
|
||||||
|
@ -294,7 +333,7 @@ void E_WorldThingDestroyed(AActor* actor)
|
||||||
// this is because Destroyed should be reverse of Spawned. we don't want to catch random inventory give failures.
|
// this is because Destroyed should be reverse of Spawned. we don't want to catch random inventory give failures.
|
||||||
if (!(actor->ObjectFlags & OF_Spawned))
|
if (!(actor->ObjectFlags & OF_Spawned))
|
||||||
return;
|
return;
|
||||||
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
|
for (DStaticEventHandler* handler = E_LastEventHandler; handler; handler = handler->prev)
|
||||||
handler->WorldThingDestroyed(actor);
|
handler->WorldThingDestroyed(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,6 +488,12 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning)
|
||||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick)
|
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick)
|
||||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderFrame)
|
DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderFrame)
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DStaticEventHandler, GetOrder)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DStaticEventHandler);
|
||||||
|
ACTION_RETURN_INT(0);
|
||||||
|
}
|
||||||
|
|
||||||
// ===========================================
|
// ===========================================
|
||||||
//
|
//
|
||||||
// Event handlers
|
// Event handlers
|
||||||
|
@ -630,3 +675,22 @@ void DStaticEventHandler::OnDestroy()
|
||||||
E_UnregisterHandler(this);
|
E_UnregisterHandler(this);
|
||||||
Super::OnDestroy();
|
Super::OnDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int DStaticEventHandler::GetOrder()
|
||||||
|
{
|
||||||
|
// if we have cached order, return it.
|
||||||
|
// otherwise call VM.
|
||||||
|
if (haveorder)
|
||||||
|
return order;
|
||||||
|
|
||||||
|
IFVIRTUAL(DStaticEventHandler, GetOrder)
|
||||||
|
{
|
||||||
|
VMReturn results[1] = { &order };
|
||||||
|
VMValue params[1] = { (DStaticEventHandler*)this };
|
||||||
|
GlobalVMStack.Call(func, params, 1, results, 1, nullptr);
|
||||||
|
haveorder = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
|
@ -59,12 +59,18 @@ public:
|
||||||
{
|
{
|
||||||
prev = 0;
|
prev = 0;
|
||||||
next = 0;
|
next = 0;
|
||||||
|
order = 0;
|
||||||
|
haveorder = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DStaticEventHandler* prev;
|
DStaticEventHandler* prev;
|
||||||
DStaticEventHandler* next;
|
DStaticEventHandler* next;
|
||||||
virtual bool IsStatic() { return true; }
|
virtual bool IsStatic() { return true; }
|
||||||
|
|
||||||
|
// order is cached to avoid calling the VM for sorting too much
|
||||||
|
int order;
|
||||||
|
bool haveorder;
|
||||||
|
|
||||||
// serialization handler. let's keep it here so that I don't get lost in serialized/not serialized fields
|
// serialization handler. let's keep it here so that I don't get lost in serialized/not serialized fields
|
||||||
void Serialize(FSerializer& arc) override
|
void Serialize(FSerializer& arc) override
|
||||||
{
|
{
|
||||||
|
@ -93,6 +99,9 @@ public:
|
||||||
virtual void WorldLightning();
|
virtual void WorldLightning();
|
||||||
virtual void WorldTick();
|
virtual void WorldTick();
|
||||||
virtual void RenderFrame();
|
virtual void RenderFrame();
|
||||||
|
|
||||||
|
// gets the order of this item.
|
||||||
|
int GetOrder();
|
||||||
};
|
};
|
||||||
class DEventHandler : public DStaticEventHandler
|
class DEventHandler : public DStaticEventHandler
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,11 @@ class StaticEventHandler : Object native
|
||||||
virtual native void WorldTick(WorldEvent e);
|
virtual native void WorldTick(WorldEvent e);
|
||||||
|
|
||||||
virtual native void RenderFrame(RenderEvent e);
|
virtual native void RenderFrame(RenderEvent e);
|
||||||
|
|
||||||
|
// this function should return a value that will be queried on Register() to decide the relative order of this handler to every other.
|
||||||
|
// this is most useful in UI systems.
|
||||||
|
// default is 0.
|
||||||
|
virtual native int GetOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventHandler : StaticEventHandler native
|
class EventHandler : StaticEventHandler native
|
||||||
|
|
Loading…
Reference in a new issue