- added GC support to the events. OF_Fixed is not recommended because it can seriously impede the GC's functionality if just being used as a lazy means to avoid collection.

This commit is contained in:
Christoph Oelckers 2017-02-09 14:35:45 +01:00
parent fd615713d5
commit c6a5e74c75
3 changed files with 32 additions and 4 deletions

View file

@ -78,6 +78,7 @@
#include "menu/menu.h" #include "menu/menu.h"
#include "intermission/intermission.h" #include "intermission/intermission.h"
#include "g_levellocals.h" #include "g_levellocals.h"
#include "events.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -331,6 +332,8 @@ static void MarkRoot()
DThinker::MarkRoots(); DThinker::MarkRoots();
FCanvasTextureInfo::Mark(); FCanvasTextureInfo::Mark();
Mark(DACSThinker::ActiveThinker); Mark(DACSThinker::ActiveThinker);
Mark(E_FirstEventHandler);
Mark(E_LastEventHandler);
for (auto &s : level.sectorPortals) for (auto &s : level.sectorPortals)
{ {
Mark(s.mSkybox); Mark(s.mSkybox);

View file

@ -37,32 +37,42 @@ bool E_RegisterHandler(DStaticEventHandler* handler)
// 2. MyHandler3->2: // 2. MyHandler3->2:
// E_FirstEventHandler = MyHandler2, E_LastEventHandler = MyHandler3 // E_FirstEventHandler = MyHandler2, E_LastEventHandler = MyHandler3
// (Yes, all those write barriers here are really needed!)
if (before != nullptr) if (before != nullptr)
{ {
// if before is not null, link it before the existing handler. // if before is not null, link it before the existing handler.
// note that before can be first handler, check for this. // note that before can be first handler, check for this.
handler->next = before; handler->next = before;
GC::WriteBarrier(handler, before);
handler->prev = before->prev; handler->prev = before->prev;
GC::WriteBarrier(handler, before->prev);
before->prev = handler; before->prev = handler;
GC::WriteBarrier(before, handler);
if (before == E_FirstEventHandler) if (before == E_FirstEventHandler)
{
E_FirstEventHandler = handler; E_FirstEventHandler = handler;
GC::WriteBarrier(handler);
}
} }
else else
{ {
// so if before is null, it means add last. // so if before is null, it means add last.
// it can also mean that we have no handlers at all yet. // it can also mean that we have no handlers at all yet.
handler->prev = E_LastEventHandler; handler->prev = E_LastEventHandler;
GC::WriteBarrier(handler, E_LastEventHandler);
handler->next = nullptr; handler->next = nullptr;
if (E_FirstEventHandler == nullptr) if (E_FirstEventHandler == nullptr) E_FirstEventHandler = handler;
E_FirstEventHandler = handler;
E_LastEventHandler = handler; E_LastEventHandler = handler;
GC::WriteBarrier(handler);
if (handler->prev != nullptr) if (handler->prev != nullptr)
{
handler->prev->next = handler; handler->prev->next = handler;
GC::WriteBarrier(handler->prev, handler);
}
} }
if (handler->IsStatic()) if (handler->IsStatic())
{ {
handler->ObjectFlags |= OF_Fixed;
handler->ObjectFlags |= OF_Transient; handler->ObjectFlags |= OF_Transient;
} }
@ -80,16 +90,28 @@ bool E_UnregisterHandler(DStaticEventHandler* handler)
// link out of normal list // link out of normal list
if (handler->prev) if (handler->prev)
{
handler->prev->next = handler->next; handler->prev->next = handler->next;
GC::WriteBarrier(handler->prev, handler->next);
}
if (handler->next) if (handler->next)
{
handler->next->prev = handler->prev; handler->next->prev = handler->prev;
GC::WriteBarrier(handler->next, handler->prev);
}
if (handler == E_FirstEventHandler) if (handler == E_FirstEventHandler)
{
E_FirstEventHandler = handler->next; E_FirstEventHandler = handler->next;
GC::WriteBarrier(handler->next);
}
if (handler == E_LastEventHandler) if (handler == E_LastEventHandler)
{
E_LastEventHandler = handler->prev; E_LastEventHandler = handler->prev;
GC::WriteBarrier(handler->prev);
}
if (handler->IsStatic()) if (handler->IsStatic())
{ {
handler->ObjectFlags &= ~(OF_Fixed|OF_Transient); handler->ObjectFlags &= ~OF_Transient;
handler->Destroy(); handler->Destroy();
} }
return true; return true;

View file

@ -77,6 +77,7 @@ void E_SerializeEvents(FSerializer& arc);
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)
HAS_OBJECT_POINTERS
public: public:
DStaticEventHandler() DStaticEventHandler()
{ {
@ -99,6 +100,7 @@ public:
void Serialize(FSerializer& arc) override void Serialize(FSerializer& arc) override
{ {
Super::Serialize(arc); Super::Serialize(arc);
/*
if (arc.isReading()) if (arc.isReading())
{ {
Printf("DStaticEventHandler::Serialize: reading object %s\n", GetClass()->TypeName.GetChars()); Printf("DStaticEventHandler::Serialize: reading object %s\n", GetClass()->TypeName.GetChars());
@ -107,6 +109,7 @@ public:
{ {
Printf("DStaticEventHandler::Serialize: store object %s\n", GetClass()->TypeName.GetChars()); Printf("DStaticEventHandler::Serialize: store object %s\n", GetClass()->TypeName.GetChars());
} }
*/
arc("Order", Order); arc("Order", Order);
arc("IsUiProcessor", IsUiProcessor); arc("IsUiProcessor", IsUiProcessor);