- Changed DObject's pointer substitution so that the pointers inside an

object are handled by a virtual function. This allows subclasses to
  implement their own handling if they need it.


SVN r797 (trunk)
This commit is contained in:
Christoph Oelckers 2008-03-12 16:27:47 +00:00
parent f609f43187
commit 07e795e656
6 changed files with 32 additions and 23 deletions

View file

@ -1,4 +1,7 @@
March 12, 2008 (Changes by Graf Zahl)
- Changed DObject's pointer substitution so that the pointers inside an
object are handled by a virtual function. This allows subclasses to
implement their own handling if they need it.
- Bumped the minimum savegame version because the current version crashes
each time an old savegame is loaded.

View file

@ -379,7 +379,7 @@ DObject::~DObject ()
}
// Find all pointers that reference this object and NULL them.
PointerSubstitution(this, NULL);
StaticPointerSubstitution(this, NULL);
// Now unlink this object from the GC list.
for (probe = &GC::Root; *probe != NULL; probe = &((*probe)->ObjNext))
@ -433,6 +433,25 @@ size_t DObject::PropagateMark()
}
void DObject::PointerSubstitution (DObject *old, DObject *notOld)
{
const PClass *info = GetClass();
const size_t *offsets = info->FlatPointers;
if (offsets == NULL)
{
const_cast<PClass *>(info)->BuildFlatPointers();
offsets = info->FlatPointers;
}
while (*offsets != ~(size_t)0)
{
if (*(DObject **)((BYTE *)this + *offsets) == old)
{
*(DObject **)((BYTE *)this + *offsets) = notOld;
}
offsets++;
}
}
void DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
{
DObject *probe;
int i;
@ -440,21 +459,7 @@ void DObject::PointerSubstitution (DObject *old, DObject *notOld)
// Go through all objects.
for (probe = GC::Root; probe != NULL; probe = probe->ObjNext)
{
const PClass *info = probe->GetClass();
const size_t *offsets = info->FlatPointers;
if (offsets == NULL)
{
const_cast<PClass *>(info)->BuildFlatPointers();
offsets = info->FlatPointers;
}
while (*offsets != ~(size_t)0)
{
if (*(DObject **)((BYTE *)probe + *offsets) == old)
{
*(DObject **)((BYTE *)probe + *offsets) = notOld;
}
offsets++;
}
probe->PointerSubstitution(old, notOld);
}
// Go through the bodyque.

View file

@ -446,7 +446,8 @@ public:
// If you need to replace one object with another and want to
// change any pointers from the old object to the new object,
// use this method.
static void PointerSubstitution (DObject *old, DObject *notOld);
virtual void PointerSubstitution (DObject *old, DObject *notOld);
static void StaticPointerSubstitution (DObject *old, DObject *notOld);
PClass *GetClass() const
{

View file

@ -2299,7 +2299,7 @@ void G_FinishTravel ()
pawn->target = NULL;
pawn->lastenemy = NULL;
pawn->player->mo = pawn;
DObject::PointerSubstitution (oldpawn, pawn);
DObject::StaticPointerSubstitution (oldpawn, pawn);
oldpawn->Destroy();
pawndup->Destroy ();
pawn->LinkToWorld ();

View file

@ -58,7 +58,7 @@ bool P_MorphPlayer (player_t *p, const PClass *spawntype)
}
morphed = static_cast<APlayerPawn *>(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE));
DObject::PointerSubstitution (actor, morphed);
DObject::StaticPointerSubstitution (actor, morphed);
morphed->angle = actor->angle;
morphed->target = actor->target;
morphed->tracer = actor;
@ -151,7 +151,7 @@ bool P_UndoPlayerMorph (player_t *player, bool force)
pmo->player = NULL;
mo->ObtainInventory (pmo);
DObject::PointerSubstitution (pmo, mo);
DObject::StaticPointerSubstitution (pmo, mo);
mo->angle = pmo->angle;
mo->player = player;
mo->reactiontime = 18;
@ -234,7 +234,7 @@ bool P_MorphMonster (AActor *actor, const PClass *spawntype)
}
morphed = static_cast<AMorphedMonster *>(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE));
DObject::PointerSubstitution (actor, morphed);
DObject::StaticPointerSubstitution (actor, morphed);
morphed->tid = actor->tid;
morphed->angle = actor->angle;
morphed->UnmorphedMe = actor;
@ -311,7 +311,7 @@ bool P_UpdateMorphedMonster (AMorphedMonster *beast)
memcpy (actor->args, beast->args, sizeof(actor->args));
actor->AddToHash ();
beast->UnmorphedMe = NULL;
DObject::PointerSubstitution (beast, actor);
DObject::StaticPointerSubstitution (beast, actor);
beast->Destroy ();
Spawn<ATeleportFog> (beast->x, beast->y, beast->z + TELEFOGHEIGHT, ALLOW_REPLACE);
return true;

View file

@ -3671,7 +3671,7 @@ void P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer)
}
DObject::PointerSubstitution (oldactor, p->mo);
DObject::StaticPointerSubstitution (oldactor, p->mo);
// PointerSubstitution() will also affect the bodyque, so undo that now.
for (int ii=0; ii < BODYQUESIZE; ++ii)
if (bodyque[ii] == p->mo)