First take at serialization

This commit is contained in:
ZZYZX 2017-01-24 00:17:12 +02:00
parent 23c9386add
commit 3e093a20ff
8 changed files with 128 additions and 43 deletions

View file

@ -69,6 +69,8 @@
#include "c_consolebuffer.h" #include "c_consolebuffer.h"
#include "g_levellocals.h" #include "g_levellocals.h"
FString FStringFormat(VM_ARGS); // extern from thingdef_data.cpp
#include "gi.h" #include "gi.h"
#define LEFTMARGIN 8 #define LEFTMARGIN 8
@ -1332,6 +1334,14 @@ DEFINE_ACTION_FUNCTION(_Console, HideConsole)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(_Console, Printf)
{
PARAM_PROLOGUE;
FString s = FStringFormat(param, defaultparam, numparam, ret, numret);
Printf("%s", s);
return 0;
}
static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
{ {
int data1 = ev->data1; int data1 = ev->data1;

View file

@ -61,6 +61,53 @@ bool E_IsStaticType(PClass* type)
void E_SerializeEvents(FSerializer& arc) void E_SerializeEvents(FSerializer& arc)
{ {
// todo : stuff // todo : stuff
if (arc.BeginArray("eventhandlers"))
{
int numlocalhandlers = 0;
TArray<DStaticEventHandler*> handlers;
if (arc.isReading())
{
numlocalhandlers = arc.ArraySize();
// delete all current local handlers, if any
for (DStaticEventHandler* lhandler = E_FirstEventHandler; lhandler; lhandler = lhandler->next)
if (!lhandler->IsStatic()) lhandler->Destroy();
}
else
{
for (DStaticEventHandler* lhandler = E_FirstEventHandler; lhandler; lhandler = lhandler->next)
{
if (lhandler->IsStatic()) continue;
numlocalhandlers++;
handlers.Push(lhandler);
}
}
for (int i = 0; i < numlocalhandlers; i++)
{
// serialize the object properly.
if (arc.isReading())
{
// get object and put it into the array
DStaticEventHandler* lhandler;
arc(nullptr, lhandler);
if (lhandler != nullptr)
handlers.Push(lhandler);
}
else
{
::Serialize<DStaticEventHandler>(arc, nullptr, handlers[i], nullptr);
}
}
if (arc.isReading())
{
// add all newly deserialized handlers into the list
for (int i = 0; i < numlocalhandlers; i++)
E_RegisterHandler(handlers[i]);
}
arc.EndArray();
}
} }
static void E_InitStaticHandler(PClass* type, FString typestring, bool map) static void E_InitStaticHandler(PClass* type, FString typestring, bool map)
@ -124,23 +171,17 @@ void E_InitStaticHandlers(bool map)
} }
} }
void E_MapLoaded() #define DEFINE_EVENT_LOOPER(name) void E_##name() \
{ { \
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) \
handler->MapLoaded(); handler->name(); \
} }
void E_MapUnloading() DEFINE_EVENT_LOOPER(WorldLoaded)
{ DEFINE_EVENT_LOOPER(WorldUnloading)
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) DEFINE_EVENT_LOOPER(WorldLoadedUnsafe)
handler->MapUnloading(); DEFINE_EVENT_LOOPER(WorldUnloadingUnsafe)
} DEFINE_EVENT_LOOPER(RenderFrame)
void E_RenderFrame()
{
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
handler->RenderFrame();
}
// declarations // declarations
IMPLEMENT_CLASS(DStaticEventHandler, false, false); IMPLEMENT_CLASS(DStaticEventHandler, false, false);
@ -230,15 +271,17 @@ void cls::funcname(args) \
} \ } \
} }
DEFINE_EVENT_HANDLER(DStaticEventHandler, MapLoaded,) DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldLoaded,)
DEFINE_EVENT_HANDLER(DStaticEventHandler, MapUnloading,) DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldUnloading,)
DEFINE_EVENT_HANDLER(DStaticEventHandler, RenderFrame,) DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldLoadedUnsafe, )
DEFINE_EVENT_HANDLER(DStaticEventHandler, WorldUnloadingUnsafe, )
DEFINE_EVENT_HANDLER(DStaticEventHandler, RenderFrame, )
// //
void DStaticEventHandler::OnDestroy() void DStaticEventHandler::OnDestroy()
{ {
E_UnregisterHandler(this); E_UnregisterHandler(this);
DObject::OnDestroy(); Super::OnDestroy();
} }
void DStaticRenderEventHandler::Setup() void DStaticRenderEventHandler::Setup()
@ -254,6 +297,5 @@ void DStaticRenderEventHandler::Setup()
void DStaticRenderEventHandler::RenderFrame() void DStaticRenderEventHandler::RenderFrame()
{ {
Setup(); Setup();
DStaticEventHandler::RenderFrame(); Super::RenderFrame();
} }

View file

@ -18,9 +18,13 @@ bool E_IsStaticType(PClass* type);
void E_InitStaticHandlers(bool map); 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_MapLoaded(); 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_MapUnloading(); void E_WorldUnloading();
// called right after the map has loaded (every time, UNSAFE VERSION)
void E_WorldLoadedUnsafe();
// called right before the map is unloaded (every time, UNSAFE VERSION)
void E_WorldUnloadingUnsafe();
// called on each render frame once. // called on each render frame once.
void E_RenderFrame(); void E_RenderFrame();
@ -38,17 +42,28 @@ public:
bool isMapScope; // this is only used with IsStatic=true bool isMapScope; // this is only used with IsStatic=true
virtual bool IsStatic() { return true; } virtual bool IsStatic() { return true; }
// serialization handler. let's keep it here so that I don't get lost in serialized/not serialized fields
void Serialize(FSerializer& arc) override
{
Super::Serialize(arc);
if (arc.isReading())
{
Printf("DStaticEventHandler::Serialize: reading object %s\n", GetClass()->TypeName.GetChars());
}
else
{
Printf("DStaticEventHandler::Serialize: store object %s\n", GetClass()->TypeName.GetChars());
}
/* do nothing */
}
// destroy handler. this unlinks EventHandler from the list automatically. // destroy handler. this unlinks EventHandler from the list automatically.
void OnDestroy() override; void OnDestroy() override;
// this checks if we are /actually/ static, using DObject dynamic typing system. virtual void WorldLoaded();
static bool IsActuallyStatic(PClass* type); virtual void WorldUnloading();
virtual void WorldLoadedUnsafe();
// called right after the map has loaded (approximately same time as OPEN ACS scripts) virtual void WorldUnloadingUnsafe();
virtual void MapLoaded();
// called when the map is about to unload (approximately same time as UNLOADING ACS scripts)
virtual void MapUnloading();
// called on each render frame once.
virtual void RenderFrame(); virtual void RenderFrame();
}; };
class DEventHandler : public DStaticEventHandler class DEventHandler : public DStaticEventHandler
@ -71,6 +86,18 @@ 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;
// serialization handler for our local stuff
void Serialize(FSerializer& arc) override
{
Super::Serialize(arc);
arc("ViewPos", ViewPos);
arc("ViewAngle", ViewAngle);
arc("ViewPitch", ViewPitch);
arc("ViewRoll", ViewRoll);
arc("FracTic", FracTic);
arc("Camera", Camera);
}
void RenderFrame() override; void RenderFrame() override;
private: private:

View file

@ -407,6 +407,10 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
bool wantFast; bool wantFast;
int i; int i;
// did we have any level before?
if (level.info != nullptr)
E_WorldUnloadingUnsafe();
if (!savegamerestore) if (!savegamerestore)
{ {
G_ClearHubInfo(); G_ClearHubInfo();
@ -656,7 +660,10 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
// [RH] Give scripts a chance to do something // [RH] Give scripts a chance to do something
unloading = true; unloading = true;
FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true); FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true);
E_MapUnloading(); // [ZZ] safe world unload
E_WorldUnloading();
// [ZZ] unsafe world unload (changemap != map)
E_WorldUnloadingUnsafe();
unloading = false; unloading = false;
STAT_ChangeLevel(nextlevel); STAT_ChangeLevel(nextlevel);
@ -1068,8 +1075,8 @@ void G_DoLoadLevel (int position, bool autosave)
StatusBar->AttachToPlayer (&players[consoleplayer]); StatusBar->AttachToPlayer (&players[consoleplayer]);
// [ZZ] init per-map static handlers // [ZZ] init per-map static handlers
E_InitStaticHandlers(true); E_InitStaticHandlers(true);
// call map load hook // unsafe world load
E_MapLoaded(); E_WorldLoadedUnsafe();
P_DoDeferedScripts (); // [RH] Do script actions that were triggered on another map. P_DoDeferedScripts (); // [RH] Do script actions that were triggered on another map.
if (demoplayback || oldgs == GS_STARTUP || oldgs == GS_TITLELEVEL) if (demoplayback || oldgs == GS_STARTUP || oldgs == GS_TITLELEVEL)

View file

@ -1443,6 +1443,8 @@ void P_SpawnSpecials (void)
break; break;
} }
} }
// [ZZ] safe world load
E_WorldLoaded();
// [RH] Start running any open scripts on this map // [RH] Start running any open scripts on this map
FBehavior::StaticStartTypedScripts (SCRIPT_Open, NULL, false); FBehavior::StaticStartTypedScripts (SCRIPT_Open, NULL, false);
} }

View file

@ -945,7 +945,7 @@ DEFINE_ACTION_FUNCTION(FStringStruct, Replace)
return 0; return 0;
} }
static FString FStringFormat(VM_ARGS) FString FStringFormat(VM_ARGS)
{ {
assert(param[0].Type == REGT_STRING); assert(param[0].Type == REGT_STRING);
FString fmtstring = param[0].s().GetChars(); FString fmtstring = param[0].s().GetChars();

View file

@ -41,6 +41,7 @@ struct Console native
{ {
native static void HideConsole(); native static void HideConsole();
native static void MidPrint(string fontname, string textlabel, bool bold = false); // always uses the stringtable. native static void MidPrint(string fontname, string textlabel, bool bold = false); // always uses the stringtable.
native static vararg void Printf(string fmt, ...);
} }
struct DamageTypeDefinition native struct DamageTypeDefinition native

View file

@ -1,12 +1,11 @@
class StaticEventHandler : Object native class StaticEventHandler : Object native
{ {
virtual native void MapLoaded(); virtual native void WorldLoaded();
virtual native void MapUnloading(); virtual native void WorldLoadedUnsafe();
virtual native void WorldUnloading();
virtual native void WorldUnloadingUnsafe();
virtual native void RenderFrame(); virtual native void RenderFrame();
virtual native void RenderCamera();
virtual native void RenderBeforeThing();
virtual native void RenderAfterThing();
} }
class StaticRenderEventHandler : StaticEventHandler native class StaticRenderEventHandler : StaticEventHandler native
@ -17,10 +16,7 @@ class StaticRenderEventHandler : StaticEventHandler native
native readonly double ViewPitch; native readonly double ViewPitch;
native readonly double ViewRoll; native readonly double ViewRoll;
native readonly double FracTic; native readonly double FracTic;
// for camera
native readonly Actor Camera; native readonly Actor Camera;
// for thing
native readonly Actor CurrentThing;
} }
class EventHandler : StaticEventHandler native class EventHandler : StaticEventHandler native