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:
ZZYZX 2017-01-31 01:28:47 +02:00
parent 5751f84350
commit 27c8140c46
3 changed files with 145 additions and 97 deletions

View file

@ -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);
}
}*/

View file

@ -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

View file

@ -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 { }