Added WorldEventHandler with WorldThingSpawned. WorldThingDestroyed is not implemented because you already can attach an object that would check master's state.

This commit is contained in:
ZZYZX 2017-01-30 08:47:15 +02:00
parent fd282d3001
commit 0598c18ad8
4 changed files with 122 additions and 12 deletions

View file

@ -203,12 +203,12 @@ void E_WorldLoaded()
} }
} }
void E_WorldUnloading() void E_WorldUnloaded()
{ {
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
{ {
if (handler->IsStatic() && !handler->isMapScope) continue; if (handler->IsStatic() && !handler->isMapScope) continue;
handler->WorldUnloading(); handler->WorldUnloaded();
} }
} }
@ -221,22 +221,31 @@ void E_WorldLoadedUnsafe()
} }
} }
void E_WorldUnloadingUnsafe() void E_WorldUnloadedUnsafe()
{ {
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
{ {
if (!handler->IsStatic() || handler->isMapScope) continue; if (!handler->IsStatic() || handler->isMapScope) continue;
handler->WorldUnloading(); handler->WorldUnloaded();
} }
} }
void E_WorldThingSpawned(AActor* actor)
{
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
handler->WorldThingSpawned(actor);
}
// normal event loopers (non-special, argument-less)
DEFINE_EVENT_LOOPER(RenderFrame) DEFINE_EVENT_LOOPER(RenderFrame)
// declarations // declarations
IMPLEMENT_CLASS(DStaticEventHandler, false, false); IMPLEMENT_CLASS(DStaticEventHandler, false, false);
IMPLEMENT_CLASS(DStaticRenderEventHandler, false, false); IMPLEMENT_CLASS(DStaticRenderEventHandler, false, false);
IMPLEMENT_CLASS(DStaticWorldEventHandler, false, false);
IMPLEMENT_CLASS(DEventHandler, false, false); IMPLEMENT_CLASS(DEventHandler, false, false);
IMPLEMENT_CLASS(DRenderEventHandler, false, false); IMPLEMENT_CLASS(DRenderEventHandler, false, false);
IMPLEMENT_CLASS(DWorldEventHandler, false, false);
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewPos); DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewPos);
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewAngle); DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewAngle);
@ -245,6 +254,9 @@ DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, ViewRoll);
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, FracTic); DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, FracTic);
DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, Camera); DEFINE_FIELD_X(StaticRenderEventHandler, DStaticRenderEventHandler, Camera);
DEFINE_FIELD_X(StaticWorldEventHandler, DStaticWorldEventHandler, IsSaveGame);
DEFINE_FIELD_X(StaticWorldEventHandler, DStaticWorldEventHandler, Thing);
DEFINE_ACTION_FUNCTION(DEventHandler, Create) DEFINE_ACTION_FUNCTION(DEventHandler, Create)
{ {
@ -321,7 +333,8 @@ void cls::funcname(args) \
} }
DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldLoaded,) DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldLoaded,)
DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldUnloading,) DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldUnloaded,)
DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldThingSpawned, AActor*)
DEFINE_EVENT_HANDLER(DStaticEventHandler, RenderFrame, ) DEFINE_EVENT_HANDLER(DStaticEventHandler, RenderFrame, )
// //
@ -346,3 +359,28 @@ void DStaticRenderEventHandler::RenderFrame()
Setup(); Setup();
Super::RenderFrame(); Super::RenderFrame();
} }
void DStaticWorldEventHandler::Setup()
{
IsSaveGame = savegamerestore;
Thing = nullptr;
}
void DStaticWorldEventHandler::WorldLoaded()
{
Setup();
Super::WorldLoaded();
}
void DStaticWorldEventHandler::WorldUnloaded()
{
Setup();
Super::WorldUnloaded();
}
void DStaticWorldEventHandler::WorldThingSpawned(AActor* actor)
{
Setup();
Thing = actor;
Super::WorldThingSpawned(actor);
}

View file

@ -20,17 +20,25 @@ void E_InitStaticHandlers(bool map);
// called right after the map has loaded (approximately same time as OPEN ACS scripts) // called right after the map has loaded (approximately same time as OPEN ACS scripts)
void E_WorldLoaded(); void E_WorldLoaded();
// called when the map is about to unload (approximately same time as UNLOADING ACS scripts) // called when the map is about to unload (approximately same time as UNLOADING ACS scripts)
void E_WorldUnloading(); void E_WorldUnloaded();
// called right after the map has loaded (every time, UNSAFE VERSION) // called right after the map has loaded (every time, UNSAFE VERSION)
void E_WorldLoadedUnsafe(); void E_WorldLoadedUnsafe();
// called right before the map is unloaded (every time, UNSAFE VERSION) // called right before the map is unloaded (every time, UNSAFE VERSION)
void E_WorldUnloadingUnsafe(); void E_WorldUnloadedUnsafe();
// called around PostBeginPlay of each actor.
void E_WorldThingSpawned(AActor* actor);
// called on each render frame once. // called on each render frame once.
void E_RenderFrame(); void E_RenderFrame();
// serialization stuff // serialization stuff
void E_SerializeEvents(FSerializer& arc); void E_SerializeEvents(FSerializer& arc);
// ==============================================
//
// EventHandler - base class
//
// ==============================================
class DStaticEventHandler : public DObject // make it a part of normal GC process class DStaticEventHandler : public DObject // make it a part of normal GC process
{ {
DECLARE_CLASS(DStaticEventHandler, DObject) DECLARE_CLASS(DStaticEventHandler, DObject)
@ -67,7 +75,8 @@ public:
void OnDestroy() override; void OnDestroy() override;
virtual void WorldLoaded(); virtual void WorldLoaded();
virtual void WorldUnloading(); virtual void WorldUnloaded();
virtual void WorldThingSpawned(AActor*);
virtual void RenderFrame(); virtual void RenderFrame();
}; };
class DEventHandler : public DStaticEventHandler class DEventHandler : public DStaticEventHandler
@ -78,6 +87,13 @@ public:
}; };
extern DStaticEventHandler* E_FirstEventHandler; extern DStaticEventHandler* E_FirstEventHandler;
// ==============================================
//
// RenderEventHandler - for renderer events
//
// ==============================================
class DStaticRenderEventHandler : public DStaticEventHandler class DStaticRenderEventHandler : public DStaticEventHandler
{ {
DECLARE_CLASS(DStaticRenderEventHandler, DStaticEventHandler) DECLARE_CLASS(DStaticRenderEventHandler, DStaticEventHandler)
@ -90,6 +106,12 @@ public:
double FracTic; // 0..1 value that describes where we are inside the current gametic, render-wise. double FracTic; // 0..1 value that describes where we are inside the current gametic, render-wise.
AActor* Camera; AActor* Camera;
DStaticRenderEventHandler()
{
FracTic = 0;
Camera = nullptr;
}
// serialization handler for our local stuff // serialization handler for our local stuff
void Serialize(FSerializer& arc) override void Serialize(FSerializer& arc) override
{ {
@ -114,4 +136,46 @@ public:
bool IsStatic() override { return false; } bool IsStatic() override { return false; }
}; };
// ==============================================
//
// WorldEventHandler - for world events
//
// ==============================================
class DStaticWorldEventHandler : public DStaticEventHandler
{
DECLARE_CLASS(DStaticWorldEventHandler, DStaticEventHandler)
public:
// for WorldLoaded, WorldUnloaded.
bool IsSaveGame; // this will be true if world event was triggered during savegame loading.
// for WorldThingSpawned
AActor* Thing;
DStaticWorldEventHandler()
{
IsSaveGame = false;
Thing = nullptr;
}
void Serialize(FSerializer& arc) override
{
Super::Serialize(arc);
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 #endif

View file

@ -409,7 +409,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
// did we have any level before? // did we have any level before?
if (level.info != nullptr) if (level.info != nullptr)
E_WorldUnloadingUnsafe(); E_WorldUnloadedUnsafe();
if (!savegamerestore) if (!savegamerestore)
{ {
@ -661,9 +661,9 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
unloading = true; unloading = true;
FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true); FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true);
// [ZZ] safe world unload // [ZZ] safe world unload
E_WorldUnloading(); E_WorldUnloaded();
// [ZZ] unsafe world unload (changemap != map) // [ZZ] unsafe world unload (changemap != map)
E_WorldUnloadingUnsafe(); E_WorldUnloadedUnsafe();
unloading = false; unloading = false;
STAT_ChangeLevel(nextlevel); STAT_ChangeLevel(nextlevel);

View file

@ -1,7 +1,8 @@
class StaticEventHandler : Object native class StaticEventHandler : Object native
{ {
virtual native void WorldLoaded(); virtual native void WorldLoaded();
virtual native void WorldUnloading(); virtual native void WorldUnloaded();
virtual native void WorldThingSpawned();
virtual native void RenderFrame(); virtual native void RenderFrame();
} }
@ -17,6 +18,13 @@ class StaticRenderEventHandler : StaticEventHandler native
native readonly Actor Camera; 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
}
class EventHandler : StaticEventHandler native class EventHandler : StaticEventHandler native
{ {
static native StaticEventHandler Create(class<StaticEventHandler> type); static native StaticEventHandler Create(class<StaticEventHandler> type);