Skip to content

Commit ad309ad

Browse files
committed
Fixes to UniqueID loading
1 parent f2ab8b1 commit ad309ad

File tree

6 files changed

+34
-41
lines changed

6 files changed

+34
-41
lines changed

Source/Entities/MovableObject.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,9 @@ int MovableObject::Create(const MovableObject& reference) {
266266
m_NumberValueMap = reference.m_NumberValueMap;
267267
m_ObjectValueMap = reference.m_ObjectValueMap;
268268

269-
// If we have a -1 unique ID, then we're currently performing a game save or load
270-
// In this case, we actually want to persist our existing IDs
269+
// If we're currently performing a game save or load we want to persist our existing IDs
271270
if (g_MovableMan.ShouldPersistUniqueIDs()) {
272-
m_UniqueID = reference.m_UniqueID;
271+
m_UniqueID = reference.m_UniqueID == 0 ? g_MovableMan.GetNextUniqueID() : reference.m_UniqueID;
273272
m_AgeTimer = reference.m_AgeTimer;
274273
} else {
275274
// Otherwise we're copying from a preset normally and ought to create a new object
@@ -384,11 +383,7 @@ int MovableObject::ReadProperty(const std::string_view& propName, Reader& reader
384383
MatchProperty("SimUpdatesBetweenScriptedUpdates", { reader >> m_SimUpdatesBetweenScriptedUpdates; });
385384
MatchProperty("AddCustomValue", { ReadCustomValueProperty(reader); });
386385
MatchProperty("ForceIntoMasterLuaState", { reader >> m_ForceIntoMasterLuaState; });
387-
MatchProperty("SpecialBehaviour_SetUniqueID", {
388-
long oldID = m_UniqueID;
389-
reader >> m_UniqueID;
390-
g_MovableMan.ReregisterObjectIfApplicable(this, oldID);
391-
});
386+
MatchProperty("SpecialBehaviour_SetUniqueID", { reader >> m_UniqueID; });
392387

393388
EndPropertyList;
394389
}

Source/Entities/MovableObject.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,9 @@ namespace RTE {
979979
/// @param newRestThreshold New rest threshold value
980980
void SetRestThreshold(int newRestThreshold) { m_RestThreshold = newRestThreshold; }
981981

982+
/// Resets this MO's unique persistent ID. Unsafe, only for internal use!
983+
void ResetUniqueID() { m_UniqueID = 0; }
984+
982985
/// Returns this MO's unique persistent ID
983986
/// @return Returns this MO's unique persistent ID
984987
long GetUniqueID() const { return m_UniqueID; }

Source/Entities/Scene.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,12 +1167,12 @@ void Scene::SaveSceneObject(Writer& writer, const SceneObject* sceneObjectToSave
11671167
}
11681168

11691169
if (const MovableObject* movableObjectToSave = dynamic_cast<const MovableObject*>(sceneObjectToSave); movableObjectToSave && saveFullData) {
1170+
writer.NewPropertyWithValue("SpecialBehaviour_SetUniqueID", movableObjectToSave->GetUniqueID());
11701171
writer.NewPropertyWithValue("HUDVisible", movableObjectToSave->GetHUDVisible());
11711172
writer.NewPropertyWithValue("Velocity", movableObjectToSave->GetVel());
11721173
writer.NewPropertyWithValue("LifeTime", movableObjectToSave->GetLifetime());
11731174
writer.NewPropertyWithValue("Age", movableObjectToSave->GetAge());
11741175
writer.NewPropertyWithValue("PinStrength", movableObjectToSave->GetPinStrength());
1175-
writer.NewPropertyWithValue("SpecialBehaviour_SetUniqueID", movableObjectToSave->GetUniqueID());
11761176
}
11771177

11781178
if (const MOSprite* moSpriteToSave = dynamic_cast<const MOSprite*>(sceneObjectToSave)) {

Source/Managers/ActivityMan.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,12 @@ bool ActivityMan::SaveCurrentGame(const std::string& fileName) {
128128
}
129129
}
130130

131+
writer->NewPropertyWithValue("MaxUniqueID", currentMaxID);
132+
writer->NewPropertyWithValue("CurrentSimTicks", g_TimerMan.GetSimTickCount());
131133
writer->NewPropertyWithValue("OriginalScenePresetName", scene->GetPresetName());
132134
writer->NewPropertyWithValue("PlaceObjectsIfSceneIsRestarted", g_SceneMan.GetPlaceObjectsOnLoad());
133135
writer->NewPropertyWithValue("PlaceUnitsIfSceneIsRestarted", g_SceneMan.GetPlaceUnitsOnLoad());
134136
writer->NewPropertyWithValue("Scene", modifiableScene.get());
135-
writer->NewPropertyWithValue("MaxUniqueID", currentMaxID);
136-
writer->NewPropertyWithValue("CurrentSimTicks", g_TimerMan.GetSimTickCount());
137137

138138
auto saveWriterData = [](Writer* writerToSave) {
139139
writerToSave->EndWrite();
@@ -170,14 +170,22 @@ bool ActivityMan::LoadAndLaunchGame(const std::string& fileName) {
170170
std::unique_ptr<Scene> scene(std::make_unique<Scene>());
171171
std::unique_ptr<GAScripted> activity(std::make_unique<GAScripted>());
172172

173-
long maxUniqueID = 0;
173+
g_MovableMan.ClearKnownObjects();
174+
175+
g_MovableMan.SetMaxUniqueID(std::numeric_limits<long>::min());
176+
177+
long maxUniqueID = 1;
174178
long long simTimeTicks = 0;
175179
std::string originalScenePresetName = fileName;
176180
bool placeObjectsIfSceneIsRestarted = true;
177181
bool placeUnitsIfSceneIsRestarted = true;
178182
while (reader.NextProperty()) {
179183
std::string propName = reader.ReadPropName();
180-
if (propName == "Activity") {
184+
if (propName == "MaxUniqueID") {
185+
reader >> maxUniqueID;
186+
} else if (propName == "CurrentSimTicks") {
187+
reader >> simTimeTicks;
188+
} else if (propName == "Activity") {
181189
reader >> activity.get();
182190
} else if (propName == "OriginalScenePresetName") {
183191
reader >> originalScenePresetName;
@@ -187,14 +195,11 @@ bool ActivityMan::LoadAndLaunchGame(const std::string& fileName) {
187195
reader >> placeUnitsIfSceneIsRestarted;
188196
} else if (propName == "Scene") {
189197
reader >> scene.get();
190-
} else if (propName == "MaxUniqueID") {
191-
reader >> maxUniqueID;
192-
g_MovableMan.SetShouldPersistUniqueIDs(true);
193-
} else if (propName == "CurrentSimTicks") {
194-
reader >> simTimeTicks;
195198
}
196199
}
197200

201+
g_MovableMan.SetShouldPersistUniqueIDs(true);
202+
198203
// SetSceneToLoad() doesn't Clone(), but when the Activity starts, it will eventually call LoadScene(), which does a Clone() of scene internally.
199204
g_SceneMan.SetSceneToLoad(scene.get(), true, true);
200205
// Saved Scenes get their presetname set to their filename to ensure they're separate from the preset Scene they're based off of.
@@ -203,18 +208,18 @@ bool ActivityMan::LoadAndLaunchGame(const std::string& fileName) {
203208
// For starting Activity, we need to directly clone the Activity we want to start.
204209
StartActivity(dynamic_cast<GAScripted*>(activity->Clone()));
205210

211+
g_MovableMan.SetShouldPersistUniqueIDs(false);
212+
206213
// Set the max unique ID to our loaded maximum so we don't stomp over any existing ones
207-
if (maxUniqueID != 0) {
208-
g_MovableMan.SetMaxUniqueID(maxUniqueID);
209-
}
214+
g_MovableMan.SetMaxUniqueID(maxUniqueID);
210215

211-
g_MovableMan.SetShouldPersistUniqueIDs(false);
212216
//g_TimerMan.SetSimTickCount(simTimeTicks); // Don't do for now... causes issues with negative times in places
213217

214218
// When this method exits, our Scene object will be destroyed, which will cause problems if you try to restart it. To avoid this, set the Scene to load to the preset object with the same name.
215219
g_SceneMan.SetSceneToLoad(originalScenePresetName, placeObjectsIfSceneIsRestarted, placeUnitsIfSceneIsRestarted);
216220

217221
g_ConsoleMan.PrintString("SYSTEM: Game \"" + fileName + "\" loaded!");
222+
218223
return true;
219224
}
220225

Source/Managers/MovableMan.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ MOID MovableMan::GetMOIDPixel(int pixelX, int pixelY, const std::vector<int>& mo
166166
}
167167

168168
void MovableMan::RegisterObject(MovableObject* mo) {
169-
if (!mo) {
169+
if (!mo || mo->GetUniqueID() <= 0) {
170170
return;
171171
}
172172

@@ -183,15 +183,12 @@ void MovableMan::UnregisterObject(MovableObject* mo) {
183183
m_KnownObjects.erase(mo->GetUniqueID());
184184
}
185185

186-
void MovableMan::ReregisterObjectIfApplicable(MovableObject* mo, long oldUniqueId) {
187-
if (mo == nullptr || m_KnownObjects.find(oldUniqueId) == m_KnownObjects.end()) {
188-
// Old ID was never registered, don't need to do anything
189-
return;
186+
void RTE::MovableMan::ClearKnownObjects() {
187+
for (auto& pair : m_KnownObjects) {
188+
pair.second->ResetUniqueID();
190189
}
191190

192-
std::lock_guard<std::mutex> guard(m_ObjectRegisteredMutex);
193-
m_KnownObjects[oldUniqueId] = nullptr;
194-
m_KnownObjects[mo->GetUniqueID()] = mo;
191+
m_KnownObjects.clear();
195192
}
196193

197194
const std::vector<MovableObject*>* MovableMan::GetMOsInBox(const Box& box, int ignoreTeam, bool getsHitByMOsOnly) const {

Source/Managers/MovableMan.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -482,19 +482,9 @@ namespace RTE {
482482
/// @param mo MO to remove.
483483
void UnregisterObject(MovableObject* mo);
484484

485-
/// Reregisters an object in a global Map collection to handle if it's unique ID changes
486-
/// @param mo MO to reregister if necessary.
487-
/// @param oldUniqueID The MO's old UniqueID.
488-
void ReregisterObjectIfApplicable(MovableObject* mo, long oldUniqueId);
489-
490485
/// Returns the next unique id for MO's and increments unique ID counter
491486
/// @return Returns the next unique id.
492-
long GetNextUniqueID() {
493-
if (m_ShouldPersistUniqueIDs) {
494-
return 0;
495-
}
496-
return ++m_UniqueIDCounter;
497-
}
487+
long GetNextUniqueID() { return ++m_UniqueIDCounter; }
498488

499489
/// Returns the max unique id for MO's
500490
/// @return Returns the current max unique id.
@@ -512,6 +502,9 @@ namespace RTE {
512502
/// @param newValue Whether we should be persisting uniqueIDs.
513503
void SetShouldPersistUniqueIDs(bool newValue) { m_ShouldPersistUniqueIDs = newValue; }
514504

505+
/// Clears all known objects. Should only be used for internal usage, it's unsafe!
506+
void ClearKnownObjects();
507+
515508
/// Uses a global lookup map to find an object by it's unique id.
516509
/// @param id Unique Id to look for.
517510
/// @return Object found or 0 if not found any.

0 commit comments

Comments
 (0)