mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 12:32:34 +00:00
Replaced specialized event handlers with Event structure passed to a method; returned the check for virtual implementation to make sure that we don't waste time initializing the event data.
This commit is contained in:
parent
5751f84350
commit
27c8140c46
3 changed files with 145 additions and 97 deletions
122
src/events.cpp
122
src/events.cpp
|
@ -58,8 +58,7 @@ bool E_CheckHandler(DStaticEventHandler* handler)
|
|||
bool E_IsStaticType(PClass* type)
|
||||
{
|
||||
return (type->IsDescendantOf(RUNTIME_CLASS(DStaticEventHandler)) && // make sure it's from our hierarchy at all.
|
||||
!type->IsDescendantOf(RUNTIME_CLASS(DEventHandler)) &&
|
||||
!type->IsDescendantOf(RUNTIME_CLASS(DRenderEventHandler)));
|
||||
!type->IsDescendantOf(RUNTIME_CLASS(DEventHandler)));
|
||||
}
|
||||
|
||||
void E_SerializeEvents(FSerializer& arc)
|
||||
|
@ -245,21 +244,20 @@ DEFINE_EVENT_LOOPER(RenderFrame)
|
|||
|
||||
// declarations
|
||||
IMPLEMENT_CLASS(DStaticEventHandler, false, false);
|
||||
IMPLEMENT_CLASS(DStaticRenderEventHandler, false, false);
|
||||
IMPLEMENT_CLASS(DStaticWorldEventHandler, false, false);
|
||||
IMPLEMENT_CLASS(DEventHandler, false, false);
|
||||
IMPLEMENT_CLASS(DRenderEventHandler, false, false);
|
||||
IMPLEMENT_CLASS(DWorldEventHandler, false, false);
|
||||
IMPLEMENT_CLASS(DBaseEvent, false, false)
|
||||
IMPLEMENT_CLASS(DRenderEvent, false, false)
|
||||
IMPLEMENT_CLASS(DWorldEvent, false, false)
|
||||
|
||||
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewPos);
|
||||
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewAngle);
|
||||
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewPitch);
|
||||
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewRoll);
|
||||
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, FracTic);
|
||||
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, Camera);
|
||||
DEFINE_FIELD_X(RenderEvent, DRenderEvent, ViewPos);
|
||||
DEFINE_FIELD_X(RenderEvent, DRenderEvent, ViewAngle);
|
||||
DEFINE_FIELD_X(RenderEvent, DRenderEvent, ViewPitch);
|
||||
DEFINE_FIELD_X(RenderEvent, DRenderEvent, ViewRoll);
|
||||
DEFINE_FIELD_X(RenderEvent, DRenderEvent, FracTic);
|
||||
DEFINE_FIELD_X(RenderEvent, DRenderEvent, Camera);
|
||||
|
||||
DEFINE_FIELD_X(StaticWorldEventHandler, DStaticWorldEventHandler, IsSaveGame);
|
||||
DEFINE_FIELD_X(StaticWorldEventHandler, DStaticWorldEventHandler, Thing);
|
||||
DEFINE_FIELD_X(WorldEvent, DWorldEvent, IsSaveGame);
|
||||
DEFINE_FIELD_X(WorldEvent, DWorldEvent, Thing);
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DEventHandler, Create)
|
||||
|
@ -368,19 +366,91 @@ DEFINE_ACTION_FUNCTION(DStaticEventHandler, Unregister)
|
|||
ACTION_RETURN_BOOL(E_UnregisterHandler(handler));
|
||||
}
|
||||
|
||||
#define DEFINE_EVENT_HANDLER(cls, funcname, args) void cls::funcname(args) \
|
||||
#define DEFINE_EMPTY_HANDLER(cls, funcname) DEFINE_ACTION_FUNCTION(cls, funcname) \
|
||||
{ \
|
||||
IFVIRTUAL(cls, funcname) \
|
||||
{ \
|
||||
VMValue params[1] = { (cls*)this }; \
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); \
|
||||
} \
|
||||
PARAM_SELF_PROLOGUE(cls); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldLoaded,)
|
||||
DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldUnloaded,)
|
||||
DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldThingSpawned, AActor*)
|
||||
DEFINE_EVENT_HANDLER(DStaticEventHandler, RenderFrame, )
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLoaded)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldUnloaded)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingSpawned)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderFrame)
|
||||
|
||||
static DWorldEvent* E_SetupWorldEvent()
|
||||
{
|
||||
static DWorldEvent* e = nullptr;
|
||||
if (!e) e = (DWorldEvent*)RUNTIME_CLASS(DWorldEvent)->CreateNew();
|
||||
e->IsSaveGame = savegamerestore;
|
||||
e->Thing = nullptr;
|
||||
return e;
|
||||
}
|
||||
|
||||
void DStaticEventHandler::WorldLoaded()
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, WorldLoaded)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (func == DStaticEventHandler_WorldLoaded_VMPtr)
|
||||
return;
|
||||
DWorldEvent* e = E_SetupWorldEvent();
|
||||
VMValue params[2] = { (DStaticEventHandler*)this, e };
|
||||
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void DStaticEventHandler::WorldUnloaded()
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, WorldUnloaded)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (func == DStaticEventHandler_WorldUnloaded_VMPtr)
|
||||
return;
|
||||
DWorldEvent* e = E_SetupWorldEvent();
|
||||
VMValue params[2] = { (DStaticEventHandler*)this, e };
|
||||
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void DStaticEventHandler::WorldThingSpawned(AActor* actor)
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, WorldThingSpawned)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (func == DStaticEventHandler_WorldThingSpawned_VMPtr)
|
||||
return;
|
||||
DWorldEvent* e = E_SetupWorldEvent();
|
||||
e->Thing = actor;
|
||||
VMValue params[2] = { (DStaticEventHandler*)this, e };
|
||||
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static DRenderEvent* E_SetupRenderEvent()
|
||||
{
|
||||
static DRenderEvent* e = nullptr;
|
||||
if (!e) e = (DRenderEvent*)RUNTIME_CLASS(DRenderEvent)->CreateNew();
|
||||
e->ViewPos = ::ViewPos;
|
||||
e->ViewAngle = ::ViewAngle;
|
||||
e->ViewPitch = ::ViewPitch;
|
||||
e->ViewRoll = ::ViewRoll;
|
||||
e->FracTic = ::r_TicFracF;
|
||||
e->Camera = ::camera;
|
||||
return e;
|
||||
}
|
||||
|
||||
void DStaticEventHandler::RenderFrame()
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, RenderFrame)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (func == DStaticEventHandler_RenderFrame_VMPtr)
|
||||
return;
|
||||
DRenderEvent* e = E_SetupRenderEvent();
|
||||
VMValue params[2] = { (DStaticEventHandler*)this, e };
|
||||
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DStaticEventHandler::OnDestroy()
|
||||
|
@ -388,7 +458,7 @@ void DStaticEventHandler::OnDestroy()
|
|||
E_UnregisterHandler(this);
|
||||
Super::OnDestroy();
|
||||
}
|
||||
|
||||
/*
|
||||
void DStaticRenderEventHandler::Setup()
|
||||
{
|
||||
ViewPos = ::ViewPos;
|
||||
|
@ -428,4 +498,4 @@ void DStaticWorldEventHandler::WorldThingSpawned(AActor* actor)
|
|||
Setup();
|
||||
Thing = actor;
|
||||
Super::WorldThingSpawned(actor);
|
||||
}
|
||||
}*/
|
70
src/events.h
70
src/events.h
|
@ -87,16 +87,24 @@ public:
|
|||
};
|
||||
extern DStaticEventHandler* E_FirstEventHandler;
|
||||
|
||||
|
||||
// ==============================================
|
||||
//
|
||||
// RenderEventHandler - for renderer events
|
||||
//
|
||||
// ==============================================
|
||||
|
||||
class DStaticRenderEventHandler : public DStaticEventHandler
|
||||
// we cannot call this DEvent because in ZScript, 'event' is a keyword
|
||||
class DBaseEvent : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DStaticRenderEventHandler, DStaticEventHandler)
|
||||
DECLARE_CLASS(DBaseEvent, DObject)
|
||||
public:
|
||||
|
||||
DBaseEvent()
|
||||
{
|
||||
// each type of event is created only once to avoid new/delete hell
|
||||
// since from what I remember object creation and deletion results in a lot of GC processing
|
||||
// (and we aren't supposed to pass event objects around anyway)
|
||||
this->ObjectFlags |= OF_Fixed;
|
||||
}
|
||||
};
|
||||
|
||||
class DRenderEvent : public DBaseEvent
|
||||
{
|
||||
DECLARE_CLASS(DRenderEvent, DBaseEvent)
|
||||
public:
|
||||
// these are for all render events
|
||||
DVector3 ViewPos;
|
||||
|
@ -106,7 +114,7 @@ public:
|
|||
double FracTic; // 0..1 value that describes where we are inside the current gametic, render-wise.
|
||||
AActor* Camera;
|
||||
|
||||
DStaticRenderEventHandler()
|
||||
DRenderEvent()
|
||||
{
|
||||
FracTic = 0;
|
||||
Camera = nullptr;
|
||||
|
@ -123,34 +131,18 @@ public:
|
|||
arc("FracTic", FracTic);
|
||||
arc("Camera", Camera);
|
||||
}
|
||||
|
||||
void RenderFrame() override;
|
||||
|
||||
private:
|
||||
void Setup();
|
||||
};
|
||||
class DRenderEventHandler : public DStaticRenderEventHandler
|
||||
{
|
||||
DECLARE_CLASS(DRenderEventHandler, DStaticRenderEventHandler) // TODO: make sure this does not horribly break anythings
|
||||
public:
|
||||
bool IsStatic() override { return false; }
|
||||
};
|
||||
|
||||
// ==============================================
|
||||
//
|
||||
// WorldEventHandler - for world events
|
||||
//
|
||||
// ==============================================
|
||||
class DStaticWorldEventHandler : public DStaticEventHandler
|
||||
class DWorldEvent : public DBaseEvent
|
||||
{
|
||||
DECLARE_CLASS(DStaticWorldEventHandler, DStaticEventHandler)
|
||||
DECLARE_CLASS(DWorldEvent, DBaseEvent)
|
||||
public:
|
||||
// for WorldLoaded, WorldUnloaded.
|
||||
bool IsSaveGame; // this will be true if world event was triggered during savegame loading.
|
||||
// for WorldThingSpawned
|
||||
// for loaded/unloaded
|
||||
bool IsSaveGame;
|
||||
// for thingspawned, thingdied, thingdestroyed
|
||||
AActor* Thing;
|
||||
|
||||
DStaticWorldEventHandler()
|
||||
DWorldEvent()
|
||||
{
|
||||
IsSaveGame = false;
|
||||
Thing = nullptr;
|
||||
|
@ -162,20 +154,6 @@ public:
|
|||
arc("IsSaveGame", IsSaveGame);
|
||||
arc("Thing", Thing);
|
||||
}
|
||||
|
||||
void WorldLoaded() override;
|
||||
void WorldUnloaded() override;
|
||||
void WorldThingSpawned(AActor*) override;
|
||||
|
||||
private:
|
||||
void Setup();
|
||||
};
|
||||
// not sure if anyone wants non-static world handler, but here it is, just in case.
|
||||
class DWorldEventHandler : public DStaticWorldEventHandler
|
||||
{
|
||||
DECLARE_CLASS(DWorldEventHandler, DStaticWorldEventHandler)
|
||||
public:
|
||||
bool IsStatic() override { return false; }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,3 +1,23 @@
|
|||
class BaseEvent native { } // just a base class. it doesn't inherit from Object on the scripting side so you can't call Destroy() on it and break everything.
|
||||
|
||||
class RenderEvent : BaseEvent native
|
||||
{
|
||||
native readonly Vector3 ViewPos;
|
||||
native readonly double ViewAngle;
|
||||
native readonly double ViewPitch;
|
||||
native readonly double ViewRoll;
|
||||
native readonly double FracTic;
|
||||
native readonly Actor Camera;
|
||||
}
|
||||
|
||||
class WorldEvent : BaseEvent native
|
||||
{
|
||||
// for loaded/unloaded
|
||||
native readonly bool IsSaveGame;
|
||||
// for thingspawned/thingdied/thingdestroyed
|
||||
native readonly Actor Thing;
|
||||
}
|
||||
|
||||
class StaticEventHandler : Object native
|
||||
{
|
||||
// static event handlers CAN register other static event handlers.
|
||||
|
@ -9,30 +29,12 @@ class StaticEventHandler : Object native
|
|||
protected static native bool Register(StaticEventHandler handler);
|
||||
protected static native bool Unregister(StaticEventHandler handler);
|
||||
|
||||
// world stuff
|
||||
virtual void WorldLoaded() {}
|
||||
virtual void WorldUnloaded() {}
|
||||
virtual void WorldThingSpawned() {}
|
||||
// render stuff
|
||||
virtual void RenderFrame() {}
|
||||
}
|
||||
// actual handlers are here
|
||||
virtual native void WorldLoaded(WorldEvent e);
|
||||
virtual native void WorldUnloaded(WorldEvent e);
|
||||
virtual native void WorldThingSpawned(WorldEvent e);
|
||||
|
||||
class StaticRenderEventHandler : StaticEventHandler native
|
||||
{
|
||||
// for frame and camera
|
||||
native readonly Vector3 ViewPos;
|
||||
native readonly double ViewAngle;
|
||||
native readonly double ViewPitch;
|
||||
native readonly double ViewRoll;
|
||||
native readonly double FracTic;
|
||||
native readonly Actor Camera;
|
||||
}
|
||||
|
||||
class StaticWorldEventHandler : StaticEventHandler native
|
||||
{
|
||||
// for world
|
||||
native readonly bool IsSaveGame; // this is set to true if static WorldLoaded was triggered during savegame loading.
|
||||
native readonly Actor Thing; // this is for WorldThingSpawned
|
||||
virtual native void RenderFrame(RenderEvent e);
|
||||
}
|
||||
|
||||
class EventHandler : StaticEventHandler native
|
||||
|
@ -44,5 +46,3 @@ class EventHandler : StaticEventHandler native
|
|||
static native bool Register(StaticEventHandler handler);
|
||||
static native bool Unregister(StaticEventHandler handler);
|
||||
}
|
||||
|
||||
class RenderEventHandler : StaticRenderEventHandler native { }
|
||||
|
|
Loading…
Reference in a new issue