void DThinker::SerializeAll (FArchive &arc, bool hubLoad) { DThinker *thinker; if (arc.IsStoring ()) { thinker = FirstThinker; while (thinker) { arc << (BYTE)1; arc << thinker; thinker = thinker->m_Next; } arc << (BYTE)0; } else { if (hubLoad) DestroyMostThinkers (); else DestroyAllThinkers (); BYTE more; arc >> more; while (more) { DThinker *thinker; arc >> thinker; arc >> more; } // killough 3/26/98: Spawn icon landings: P_SpawnBrainTargets (); } }
void DThinker::SerializeAll (FArchive &arc, bool hubLoad, bool noStorePlayers) { DThinker *thinker; if (arc.IsStoring () && noStorePlayers) { thinker = FirstThinker; while (thinker) { // Don't store player mobjs. if (!(thinker->IsKindOf(RUNTIME_CLASS(AActor)) && static_cast<AActor *>(thinker)->type == MT_PLAYER)) { arc << (BYTE)1; arc << thinker; } thinker = thinker->m_Next; } arc << (BYTE)0; } else if (arc.IsStoring ()) { thinker = FirstThinker; while (thinker) { arc << (BYTE)1; arc << thinker; thinker = thinker->m_Next; } arc << (BYTE)0; } else { if (hubLoad || noStorePlayers) DestroyMostThinkers (); else DestroyAllThinkers (); BYTE more; arc >> more; while (more) { DThinker *thinker; arc >> thinker; arc >> more; } // killough 3/26/98: Spawn icon landings: P_SpawnBrainTargets (); } }
void DThinker::SerializeAll(FArchive &arc, bool hubLoad) { DThinker *thinker; BYTE stat; int statcount; int i; // Save lists of thinkers, but not by storing the first one and letting // the archiver catch the rest. (Which leads to buttloads of recursion // and makes the file larger.) Instead, we explicitly save each thinker // in sequence. When restoring an archive, we also have to maintain // the thinker lists here instead of relying on the archiver to do it // for us. if (arc.IsStoring()) { for (statcount = i = 0; i <= MAX_STATNUM; i++) { statcount += (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty()); } arc << statcount; for (i = 0; i <= MAX_STATNUM; i++) { if (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty()) { stat = i; arc << stat; SaveList(arc, Thinkers[i].GetHead()); SaveList(arc, FreshThinkers[i].GetHead()); thinker = NULL; arc << thinker; // Save a final NULL for this list } } } else { if (hubLoad) DestroyMostThinkers(); else DestroyAllThinkers(); // Prevent the constructor from inserting thinkers into a list. bSerialOverride = true; try { arc << statcount; while (statcount > 0) { arc << stat << thinker; while (thinker != NULL) { // This may be a player stored in their ancillary list. Remove // them first before inserting them into the new list. if (thinker->NextThinker != NULL) { thinker->Remove(); } // Thinkers with the OF_JustSpawned flag set go in the FreshThinkers // list. Anything else goes in the regular Thinkers list. if (thinker->ObjectFlags & OF_EuthanizeMe) { // This thinker was destroyed during the loading process. Do // not link it in to any list. } else if (thinker->ObjectFlags & OF_JustSpawned) { FreshThinkers[stat].AddTail(thinker); } else { Thinkers[stat].AddTail(thinker); } arc << thinker; } statcount--; } } catch (class CDoomError &err) { bSerialOverride = false; // DestroyAllThinkers cannot be called here. It will try to delete the corrupted // object table left behind by the serializer and crash. // Trying to continue is not an option here because the garbage collector will // crash the next time it runs. // Even making this a fatal error will crash but at least the message can be seen // before the crash - which is not the case with all other options. //DestroyAllThinkers(); I_FatalError("%s", err.GetMessage()); throw; } bSerialOverride = false; } }
void DThinker::SerializeAll(FArchive &arc, bool hubLoad) { DThinker *thinker; BYTE stat; int statcount; int i; // Save lists of thinkers, but not by storing the first one and letting // the archiver catch the rest. (Which leads to buttloads of recursion // and makes the file larger.) Instead, we explicitly save each thinker // in sequence. When restoring an archive, we also have to maintain // the thinker lists here instead of relying on the archiver to do it // for us. if (arc.IsStoring()) { for (statcount = i = 0; i <= MAX_STATNUM; i++) { statcount += (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty()); } arc << statcount; for (i = 0; i <= MAX_STATNUM; i++) { if (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty()) { stat = i; arc << stat; SaveList(arc, Thinkers[i].GetHead()); SaveList(arc, FreshThinkers[i].GetHead()); thinker = NULL; arc << thinker; // Save a final NULL for this list } } } else { if (hubLoad) DestroyMostThinkers(); else DestroyAllThinkers(); // Prevent the constructor from inserting thinkers into a list. bSerialOverride = true; try { arc << statcount; while (statcount > 0) { arc << stat << thinker; while (thinker != NULL) { // This may be a player stored in their ancillary list. Remove // them first before inserting them into the new list. if (thinker->NextThinker != NULL) { thinker->Remove(); } // Thinkers with the OF_JustSpawned flag set go in the FreshThinkers // list. Anything else goes in the regular Thinkers list. if (thinker->ObjectFlags & OF_EuthanizeMe) { // This thinker was destroyed during the loading process. Do // not link it in to any list. } else if (thinker->ObjectFlags & OF_JustSpawned) { FreshThinkers[stat].AddTail(thinker); } else { Thinkers[stat].AddTail(thinker); } arc << thinker; } statcount--; } } catch (class CDoomError &) { bSerialOverride = false; DestroyAllThinkers(); throw; } bSerialOverride = false; } }