mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-17 12:03:07 +01:00
Merge pull request #15335 from ZehMatt/refactor/object-load
Fix ownership of loaded object data
This commit is contained in:
@@ -36,7 +36,8 @@ class ObjectManager final : public IObjectManager
|
||||
{
|
||||
private:
|
||||
IObjectRepository& _objectRepository;
|
||||
std::vector<std::unique_ptr<Object>> _loadedObjects;
|
||||
|
||||
std::vector<Object*> _loadedObjects;
|
||||
std::array<std::vector<ObjectEntryIndex>, RIDE_TYPE_COUNT> _rideTypeToObjectMap;
|
||||
|
||||
// Used to return a safe empty vector back from GetAllRideEntries, can be removed when std::span is available
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return _loadedObjects[index].get();
|
||||
return _loadedObjects[index];
|
||||
}
|
||||
|
||||
Object* GetLoadedObject(ObjectType objectType, size_t index) override
|
||||
@@ -82,13 +83,11 @@ public:
|
||||
|
||||
Object* GetLoadedObject(const ObjectEntryDescriptor& entry) override
|
||||
{
|
||||
Object* loadedObject = nullptr;
|
||||
const ObjectRepositoryItem* ori = _objectRepository.FindObject(entry);
|
||||
if (ori != nullptr)
|
||||
{
|
||||
loadedObject = ori->LoadedObject;
|
||||
}
|
||||
return loadedObject;
|
||||
if (ori == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return ori->LoadedObject.get();
|
||||
}
|
||||
|
||||
ObjectEntryIndex GetLoadedObjectEntryIndex(std::string_view identifier) override
|
||||
@@ -140,14 +139,14 @@ public:
|
||||
auto requiredObjects = GetRequiredObjects(entries, count);
|
||||
|
||||
// Load the required objects
|
||||
size_t numNewLoadedObjects = 0;
|
||||
auto loadedObjects = LoadObjects(requiredObjects, &numNewLoadedObjects);
|
||||
LoadObjects(requiredObjects);
|
||||
|
||||
SetNewLoadedObjectList(std::move(loadedObjects));
|
||||
// Load defaults.
|
||||
LoadDefaultObjects();
|
||||
|
||||
// Update indices.
|
||||
UpdateSceneryGroupIndexes();
|
||||
ResetTypeToRideEntryIndexMap();
|
||||
log_verbose("%u / %u new objects loaded", numNewLoadedObjects, requiredObjects.size());
|
||||
}
|
||||
|
||||
void UnloadObjects(const std::vector<rct_object_entry>& entries) override
|
||||
@@ -162,7 +161,7 @@ public:
|
||||
const ObjectRepositoryItem* ori = _objectRepository.FindObject(&entry);
|
||||
if (ori != nullptr)
|
||||
{
|
||||
Object* loadedObject = ori->LoadedObject;
|
||||
Object* loadedObject = ori->LoadedObject.get();
|
||||
if (loadedObject != nullptr)
|
||||
{
|
||||
UnloadObject(loadedObject);
|
||||
@@ -180,9 +179,9 @@ public:
|
||||
|
||||
void UnloadAll() override
|
||||
{
|
||||
for (auto& object : _loadedObjects)
|
||||
for (auto* object : _loadedObjects)
|
||||
{
|
||||
UnloadObject(object.get());
|
||||
UnloadObject(object);
|
||||
}
|
||||
UpdateSceneryGroupIndexes();
|
||||
ResetTypeToRideEntryIndexMap();
|
||||
@@ -353,42 +352,42 @@ private:
|
||||
|
||||
Object* RepositoryItemToObject(const ObjectRepositoryItem* ori, std::optional<int32_t> slot = {})
|
||||
{
|
||||
Object* loadedObject = nullptr;
|
||||
if (ori != nullptr)
|
||||
if (ori == nullptr)
|
||||
return nullptr;
|
||||
|
||||
Object* loadedObject = ori->LoadedObject.get();
|
||||
if (loadedObject != nullptr)
|
||||
return loadedObject;
|
||||
|
||||
ObjectType objectType = ori->ObjectEntry.GetType();
|
||||
if (slot)
|
||||
{
|
||||
loadedObject = ori->LoadedObject;
|
||||
if (loadedObject == nullptr)
|
||||
if (_loadedObjects.size() > static_cast<size_t>(*slot) && _loadedObjects[*slot] != nullptr)
|
||||
{
|
||||
ObjectType objectType = ori->ObjectEntry.GetType();
|
||||
if (slot)
|
||||
{
|
||||
if (_loadedObjects.size() > static_cast<size_t>(*slot) && _loadedObjects[*slot] != nullptr)
|
||||
{
|
||||
// Slot already taken
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
slot = FindSpareSlot(objectType);
|
||||
}
|
||||
if (slot)
|
||||
{
|
||||
auto object = GetOrLoadObject(ori);
|
||||
if (object != nullptr)
|
||||
{
|
||||
if (_loadedObjects.size() <= static_cast<size_t>(*slot))
|
||||
{
|
||||
_loadedObjects.resize(*slot + 1);
|
||||
}
|
||||
loadedObject = object.get();
|
||||
_loadedObjects[*slot] = std::move(object);
|
||||
UpdateSceneryGroupIndexes();
|
||||
ResetTypeToRideEntryIndexMap();
|
||||
}
|
||||
}
|
||||
// Slot already taken
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
slot = FindSpareSlot(objectType);
|
||||
}
|
||||
if (slot)
|
||||
{
|
||||
auto* object = GetOrLoadObject(ori);
|
||||
if (object != nullptr)
|
||||
{
|
||||
if (_loadedObjects.size() <= static_cast<size_t>(*slot))
|
||||
{
|
||||
_loadedObjects.resize(*slot + 1);
|
||||
}
|
||||
loadedObject = object;
|
||||
_loadedObjects[*slot] = object;
|
||||
UpdateSceneryGroupIndexes();
|
||||
ResetTypeToRideEntryIndexMap();
|
||||
}
|
||||
}
|
||||
|
||||
return loadedObject;
|
||||
}
|
||||
|
||||
@@ -416,8 +415,7 @@ private:
|
||||
Guard::ArgumentNotNull(object, GUARD_LINE);
|
||||
|
||||
auto result = std::numeric_limits<size_t>().max();
|
||||
auto it = std::find_if(
|
||||
_loadedObjects.begin(), _loadedObjects.end(), [object](auto& obj) { return obj.get() == object; });
|
||||
auto it = std::find(_loadedObjects.begin(), _loadedObjects.end(), object);
|
||||
if (it != _loadedObjects.end())
|
||||
{
|
||||
result = std::distance(_loadedObjects.begin(), it);
|
||||
@@ -425,45 +423,26 @@ private:
|
||||
return result;
|
||||
}
|
||||
|
||||
void SetNewLoadedObjectList(std::vector<std::unique_ptr<Object>>&& newLoadedObjects)
|
||||
{
|
||||
if (newLoadedObjects.empty())
|
||||
{
|
||||
UnloadAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
UnloadObjectsExcept(newLoadedObjects);
|
||||
}
|
||||
_loadedObjects = std::move(newLoadedObjects);
|
||||
}
|
||||
|
||||
void UnloadObject(Object* object)
|
||||
{
|
||||
if (object != nullptr)
|
||||
if (object == nullptr)
|
||||
return;
|
||||
|
||||
object->Unload();
|
||||
|
||||
// TODO try to prevent doing a repository search
|
||||
const ObjectRepositoryItem* ori = _objectRepository.FindObject(object->GetObjectEntry());
|
||||
if (ori != nullptr)
|
||||
{
|
||||
object->Unload();
|
||||
|
||||
// TODO try to prevent doing a repository search
|
||||
const ObjectRepositoryItem* ori = _objectRepository.FindObject(object->GetObjectEntry());
|
||||
if (ori != nullptr)
|
||||
{
|
||||
_objectRepository.UnregisterLoadedObject(ori, object);
|
||||
}
|
||||
|
||||
// Because it's possible to have the same loaded object for multiple
|
||||
// slots, we have to make sure find and set all of them to nullptr
|
||||
for (auto& obj : _loadedObjects)
|
||||
{
|
||||
if (obj.get() == object)
|
||||
{
|
||||
obj = nullptr;
|
||||
}
|
||||
}
|
||||
_objectRepository.UnregisterLoadedObject(ori, object);
|
||||
}
|
||||
|
||||
// Because it's possible to have the same loaded object for multiple
|
||||
// slots, we have to make sure find and set all of them to nullptr
|
||||
std::replace(_loadedObjects.begin(), _loadedObjects.end(), object, static_cast<Object*>(nullptr));
|
||||
}
|
||||
|
||||
void UnloadObjectsExcept(const std::vector<std::unique_ptr<Object>>& newLoadedObjects)
|
||||
void UnloadObjectsExcept(const std::vector<Object*>& newLoadedObjects)
|
||||
{
|
||||
// Build a hash set for quick checking
|
||||
auto exceptSet = std::unordered_set<Object*>();
|
||||
@@ -471,77 +450,69 @@ private:
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
exceptSet.insert(object.get());
|
||||
exceptSet.insert(object);
|
||||
}
|
||||
}
|
||||
|
||||
// Unload objects that are not in the hash set
|
||||
size_t totalObjectsLoaded = 0;
|
||||
size_t numObjectsUnloaded = 0;
|
||||
for (auto& object : _loadedObjects)
|
||||
for (auto* object : _loadedObjects)
|
||||
{
|
||||
if (object != nullptr)
|
||||
if (object == nullptr)
|
||||
continue;
|
||||
|
||||
totalObjectsLoaded++;
|
||||
if (exceptSet.find(object) == exceptSet.end())
|
||||
{
|
||||
totalObjectsLoaded++;
|
||||
if (exceptSet.find(object.get()) == exceptSet.end())
|
||||
{
|
||||
UnloadObject(object.get());
|
||||
numObjectsUnloaded++;
|
||||
}
|
||||
UnloadObject(object);
|
||||
numObjectsUnloaded++;
|
||||
}
|
||||
}
|
||||
|
||||
log_verbose("%u / %u objects unloaded", numObjectsUnloaded, totalObjectsLoaded);
|
||||
}
|
||||
|
||||
template<typename T> void UpdateSceneryGroupIndexes(Object* object)
|
||||
{
|
||||
auto* sceneryEntry = static_cast<T*>(object->GetLegacyData());
|
||||
sceneryEntry->scenery_tab_id = GetPrimarySceneryGroupEntryIndex(object);
|
||||
}
|
||||
|
||||
void UpdateSceneryGroupIndexes()
|
||||
{
|
||||
for (auto& loadedObject : _loadedObjects)
|
||||
for (auto* loadedObject : _loadedObjects)
|
||||
{
|
||||
if (loadedObject != nullptr)
|
||||
// The list can contain unused slots, skip them.
|
||||
if (loadedObject == nullptr)
|
||||
continue;
|
||||
|
||||
switch (loadedObject->GetObjectType())
|
||||
{
|
||||
switch (loadedObject->GetObjectType())
|
||||
case ObjectType::SmallScenery:
|
||||
UpdateSceneryGroupIndexes<SmallSceneryEntry>(loadedObject);
|
||||
break;
|
||||
case ObjectType::LargeScenery:
|
||||
UpdateSceneryGroupIndexes<LargeSceneryEntry>(loadedObject);
|
||||
break;
|
||||
case ObjectType::Walls:
|
||||
UpdateSceneryGroupIndexes<WallSceneryEntry>(loadedObject);
|
||||
break;
|
||||
case ObjectType::Banners:
|
||||
UpdateSceneryGroupIndexes<BannerSceneryEntry>(loadedObject);
|
||||
break;
|
||||
case ObjectType::PathBits:
|
||||
UpdateSceneryGroupIndexes<PathBitEntry>(loadedObject);
|
||||
break;
|
||||
case ObjectType::SceneryGroup:
|
||||
{
|
||||
case ObjectType::SmallScenery:
|
||||
{
|
||||
auto* sceneryEntry = static_cast<SmallSceneryEntry*>(loadedObject->GetLegacyData());
|
||||
sceneryEntry->scenery_tab_id = GetPrimarySceneryGroupEntryIndex(loadedObject.get());
|
||||
break;
|
||||
}
|
||||
case ObjectType::LargeScenery:
|
||||
{
|
||||
auto* sceneryEntry = static_cast<LargeSceneryEntry*>(loadedObject->GetLegacyData());
|
||||
sceneryEntry->scenery_tab_id = GetPrimarySceneryGroupEntryIndex(loadedObject.get());
|
||||
break;
|
||||
}
|
||||
case ObjectType::Walls:
|
||||
{
|
||||
auto* wallEntry = static_cast<WallSceneryEntry*>(loadedObject->GetLegacyData());
|
||||
wallEntry->scenery_tab_id = GetPrimarySceneryGroupEntryIndex(loadedObject.get());
|
||||
break;
|
||||
}
|
||||
case ObjectType::Banners:
|
||||
{
|
||||
auto* bannerEntry = static_cast<BannerSceneryEntry*>(loadedObject->GetLegacyData());
|
||||
bannerEntry->scenery_tab_id = GetPrimarySceneryGroupEntryIndex(loadedObject.get());
|
||||
break;
|
||||
}
|
||||
case ObjectType::PathBits:
|
||||
{
|
||||
auto* pathBitEntry = static_cast<PathBitEntry*>(loadedObject->GetLegacyData());
|
||||
pathBitEntry->scenery_tab_id = GetPrimarySceneryGroupEntryIndex(loadedObject.get());
|
||||
break;
|
||||
}
|
||||
case ObjectType::SceneryGroup:
|
||||
{
|
||||
auto sgObject = dynamic_cast<SceneryGroupObject*>(loadedObject.get());
|
||||
sgObject->UpdateEntryIndexes();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// This switch only handles scenery ObjectTypes.
|
||||
break;
|
||||
auto sgObject = dynamic_cast<SceneryGroupObject*>(loadedObject);
|
||||
sgObject->UpdateEntryIndexes();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// This switch only handles scenery ObjectTypes.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,7 +523,7 @@ private:
|
||||
|
||||
ObjectEntryIndex GetPrimarySceneryGroupEntryIndex(Object* loadedObject)
|
||||
{
|
||||
auto sceneryObject = dynamic_cast<SceneryObject*>(loadedObject);
|
||||
auto* sceneryObject = dynamic_cast<SceneryObject*>(loadedObject);
|
||||
const auto& primarySGEntry = sceneryObject->GetPrimarySceneryGroup();
|
||||
Object* sgObject = GetLoadedObject(primarySGEntry);
|
||||
|
||||
@@ -564,60 +535,6 @@ private:
|
||||
return entryIndex;
|
||||
}
|
||||
|
||||
rct_object_entry* DuplicateObjectEntry(const rct_object_entry* original)
|
||||
{
|
||||
rct_object_entry* duplicate = Memory::Allocate<rct_object_entry>(sizeof(rct_object_entry));
|
||||
duplicate->checksum = original->checksum;
|
||||
strncpy(duplicate->name, original->name, 8);
|
||||
duplicate->flags = original->flags;
|
||||
return duplicate;
|
||||
}
|
||||
|
||||
std::vector<rct_object_entry> GetInvalidObjects(const rct_object_entry* entries) override
|
||||
{
|
||||
std::vector<rct_object_entry> invalidEntries;
|
||||
invalidEntries.reserve(OBJECT_ENTRY_COUNT);
|
||||
for (int32_t i = 0; i < OBJECT_ENTRY_COUNT; i++)
|
||||
{
|
||||
auto entry = entries[i];
|
||||
const ObjectRepositoryItem* ori = nullptr;
|
||||
if (object_entry_is_empty(&entry))
|
||||
{
|
||||
entry = {};
|
||||
continue;
|
||||
}
|
||||
|
||||
ori = _objectRepository.FindObject(&entry);
|
||||
if (ori == nullptr)
|
||||
{
|
||||
if (entry.GetType() != ObjectType::ScenarioText)
|
||||
{
|
||||
invalidEntries.push_back(entry);
|
||||
ReportMissingObject(&entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = {};
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto loadedObject = ori->LoadedObject;
|
||||
if (loadedObject == nullptr)
|
||||
{
|
||||
auto object = _objectRepository.LoadObject(ori);
|
||||
if (object == nullptr)
|
||||
{
|
||||
invalidEntries.push_back(entry);
|
||||
ReportObjectLoadProblem(&entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return invalidEntries;
|
||||
}
|
||||
|
||||
std::vector<const ObjectRepositoryItem*> GetRequiredObjects(const rct_object_entry* entries, size_t count)
|
||||
{
|
||||
std::vector<const ObjectRepositoryItem*> requiredObjects;
|
||||
@@ -671,61 +588,51 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Object>> LoadObjects(
|
||||
std::vector<const ObjectRepositoryItem*>& requiredObjects, size_t* outNewObjectsLoaded)
|
||||
void LoadObjects(std::vector<const ObjectRepositoryItem*>& requiredObjects)
|
||||
{
|
||||
std::vector<std::unique_ptr<Object>> objects;
|
||||
std::vector<Object*> loadedObjects;
|
||||
std::vector<Object*> objects;
|
||||
std::vector<Object*> newLoadedObjects;
|
||||
std::vector<rct_object_entry> badObjects;
|
||||
objects.resize(OBJECT_ENTRY_COUNT);
|
||||
loadedObjects.reserve(OBJECT_ENTRY_COUNT);
|
||||
newLoadedObjects.reserve(OBJECT_ENTRY_COUNT);
|
||||
|
||||
// Read objects
|
||||
std::mutex commonMutex;
|
||||
ParallelFor(requiredObjects, [this, &commonMutex, requiredObjects, &objects, &badObjects, &loadedObjects](size_t i) {
|
||||
auto requiredObject = requiredObjects[i];
|
||||
std::unique_ptr<Object> object;
|
||||
ParallelFor(requiredObjects, [this, &commonMutex, requiredObjects, &objects, &badObjects, &newLoadedObjects](size_t i) {
|
||||
auto* requiredObject = requiredObjects[i];
|
||||
Object* object = nullptr;
|
||||
if (requiredObject != nullptr)
|
||||
{
|
||||
auto loadedObject = requiredObject->LoadedObject;
|
||||
auto* loadedObject = requiredObject->LoadedObject.get();
|
||||
if (loadedObject == nullptr)
|
||||
{
|
||||
// Object requires to be loaded, if the object successfully loads it will register it
|
||||
// as a loaded object otherwise placed into the badObjects list.
|
||||
object = _objectRepository.LoadObject(requiredObject);
|
||||
auto newObject = _objectRepository.LoadObject(requiredObject);
|
||||
std::lock_guard<std::mutex> guard(commonMutex);
|
||||
if (object == nullptr)
|
||||
if (newObject == nullptr)
|
||||
{
|
||||
badObjects.push_back(requiredObject->ObjectEntry);
|
||||
ReportObjectLoadProblem(&requiredObject->ObjectEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
loadedObjects.push_back(object.get());
|
||||
object = newObject.get();
|
||||
newLoadedObjects.push_back(object);
|
||||
// Connect the ori to the registered object
|
||||
_objectRepository.RegisterLoadedObject(requiredObject, object.get());
|
||||
_objectRepository.RegisterLoadedObject(requiredObject, std::move(newObject));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The object is already loaded, given that the new list will be used as the next loaded object list,
|
||||
// we can move the element out safely. This is required as the resulting list must contain all loaded
|
||||
// objects and not just the newly loaded ones.
|
||||
std::lock_guard<std::mutex> guard(commonMutex);
|
||||
auto it = std::find_if(_loadedObjects.begin(), _loadedObjects.end(), [loadedObject](const auto& obj) {
|
||||
return obj.get() == loadedObject;
|
||||
});
|
||||
if (it != _loadedObjects.end())
|
||||
{
|
||||
object = std::move(*it);
|
||||
}
|
||||
object = loadedObject;
|
||||
}
|
||||
}
|
||||
objects[i] = std::move(object);
|
||||
objects[i] = object;
|
||||
});
|
||||
|
||||
// Load objects
|
||||
for (auto obj : loadedObjects)
|
||||
for (auto* obj : newLoadedObjects)
|
||||
{
|
||||
obj->Load();
|
||||
}
|
||||
@@ -733,37 +640,47 @@ private:
|
||||
if (!badObjects.empty())
|
||||
{
|
||||
// Unload all the new objects we loaded
|
||||
for (auto object : loadedObjects)
|
||||
for (auto* object : newLoadedObjects)
|
||||
{
|
||||
UnloadObject(object);
|
||||
}
|
||||
throw ObjectLoadException(std::move(badObjects));
|
||||
}
|
||||
|
||||
if (outNewObjectsLoaded != nullptr)
|
||||
// Unload objects which are not in the required list.
|
||||
if (objects.empty())
|
||||
{
|
||||
*outNewObjectsLoaded = loadedObjects.size();
|
||||
UnloadAll();
|
||||
}
|
||||
return objects;
|
||||
else
|
||||
{
|
||||
UnloadObjectsExcept(objects);
|
||||
}
|
||||
|
||||
_loadedObjects = std::move(objects);
|
||||
|
||||
log_verbose("%u / %u new objects loaded", newLoadedObjects.size(), requiredObjects.size());
|
||||
}
|
||||
|
||||
std::unique_ptr<Object> GetOrLoadObject(const ObjectRepositoryItem* ori)
|
||||
Object* GetOrLoadObject(const ObjectRepositoryItem* ori)
|
||||
{
|
||||
std::unique_ptr<Object> object;
|
||||
auto loadedObject = ori->LoadedObject;
|
||||
if (loadedObject == nullptr)
|
||||
{
|
||||
// Try to load object
|
||||
object = _objectRepository.LoadObject(ori);
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->Load();
|
||||
auto* loadedObject = ori->LoadedObject.get();
|
||||
if (loadedObject != nullptr)
|
||||
return loadedObject;
|
||||
|
||||
// Connect the ori to the registered object
|
||||
_objectRepository.RegisterLoadedObject(ori, object.get());
|
||||
}
|
||||
// Try to load object
|
||||
auto object = _objectRepository.LoadObject(ori);
|
||||
if (object != nullptr)
|
||||
{
|
||||
loadedObject = object.get();
|
||||
|
||||
object->Load();
|
||||
|
||||
// Connect the ori to the registered object
|
||||
_objectRepository.RegisterLoadedObject(ori, std::move(object));
|
||||
}
|
||||
return object;
|
||||
|
||||
return loadedObject;
|
||||
}
|
||||
|
||||
void ResetTypeToRideEntryIndexMap()
|
||||
@@ -775,23 +692,23 @@ private:
|
||||
}
|
||||
|
||||
// Build object lists
|
||||
auto maxRideObjects = static_cast<size_t>(object_entry_group_counts[EnumValue(ObjectType::Ride)]);
|
||||
const auto maxRideObjects = static_cast<size_t>(object_entry_group_counts[EnumValue(ObjectType::Ride)]);
|
||||
for (size_t i = 0; i < maxRideObjects; i++)
|
||||
{
|
||||
auto rideObject = static_cast<RideObject*>(GetLoadedObject(ObjectType::Ride, i));
|
||||
if (rideObject != nullptr)
|
||||
auto* rideObject = static_cast<RideObject*>(GetLoadedObject(ObjectType::Ride, i));
|
||||
if (rideObject == nullptr)
|
||||
continue;
|
||||
|
||||
const auto* entry = static_cast<rct_ride_entry*>(rideObject->GetLegacyData());
|
||||
if (entry == nullptr)
|
||||
continue;
|
||||
|
||||
for (auto rideType : entry->ride_type)
|
||||
{
|
||||
const auto entry = static_cast<rct_ride_entry*>(rideObject->GetLegacyData());
|
||||
if (entry != nullptr)
|
||||
if (rideType < _rideTypeToObjectMap.size())
|
||||
{
|
||||
for (auto rideType : entry->ride_type)
|
||||
{
|
||||
if (rideType < _rideTypeToObjectMap.size())
|
||||
{
|
||||
auto& v = _rideTypeToObjectMap[rideType];
|
||||
v.push_back(static_cast<ObjectEntryIndex>(i));
|
||||
}
|
||||
}
|
||||
auto& v = _rideTypeToObjectMap[rideType];
|
||||
v.push_back(static_cast<ObjectEntryIndex>(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -828,13 +745,6 @@ std::unique_ptr<IObjectManager> CreateObjectManager(IObjectRepository& objectRep
|
||||
return std::make_unique<ObjectManager>(objectRepository);
|
||||
}
|
||||
|
||||
Object* object_manager_get_loaded_object_by_index(size_t index)
|
||||
{
|
||||
auto& objectManager = OpenRCT2::GetContext()->GetObjectManager();
|
||||
Object* loadedObject = objectManager.GetLoadedObject(index);
|
||||
return loadedObject;
|
||||
}
|
||||
|
||||
Object* object_manager_get_loaded_object(const ObjectEntryDescriptor& entry)
|
||||
{
|
||||
auto& objectManager = OpenRCT2::GetContext()->GetObjectManager();
|
||||
|
||||
@@ -30,7 +30,6 @@ struct IObjectManager
|
||||
virtual ObjectEntryIndex GetLoadedObjectEntryIndex(std::string_view identifier) abstract;
|
||||
virtual ObjectEntryIndex GetLoadedObjectEntryIndex(const ObjectEntryDescriptor& descriptor) abstract;
|
||||
virtual ObjectEntryIndex GetLoadedObjectEntryIndex(const Object* object) abstract;
|
||||
virtual std::vector<rct_object_entry> GetInvalidObjects(const rct_object_entry* entries) abstract;
|
||||
|
||||
virtual Object* LoadObject(std::string_view identifier) abstract;
|
||||
virtual Object* LoadObject(const rct_object_entry* entry) abstract;
|
||||
@@ -47,7 +46,6 @@ struct IObjectManager
|
||||
|
||||
[[nodiscard]] std::unique_ptr<IObjectManager> CreateObjectManager(IObjectRepository& objectRepository);
|
||||
|
||||
[[nodiscard]] Object* object_manager_get_loaded_object_by_index(size_t index);
|
||||
[[nodiscard]] Object* object_manager_get_loaded_object(const ObjectEntryDescriptor& entry);
|
||||
[[nodiscard]] ObjectEntryIndex object_manager_get_loaded_object_entry_index(const Object* loadedObject);
|
||||
[[nodiscard]] ObjectEntryIndex object_manager_get_loaded_object_entry_index(const ObjectEntryDescriptor& entry);
|
||||
|
||||
@@ -266,18 +266,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterLoadedObject(const ObjectRepositoryItem* ori, Object* object) override
|
||||
void RegisterLoadedObject(const ObjectRepositoryItem* ori, std::unique_ptr<Object>&& object) override
|
||||
{
|
||||
ObjectRepositoryItem* item = &_items[ori->Id];
|
||||
|
||||
Guard::Assert(item->LoadedObject == nullptr, GUARD_LINE);
|
||||
item->LoadedObject = object;
|
||||
item->LoadedObject = std::move(object);
|
||||
}
|
||||
|
||||
void UnregisterLoadedObject(const ObjectRepositoryItem* ori, Object* object) override
|
||||
{
|
||||
ObjectRepositoryItem* item = &_items[ori->Id];
|
||||
if (item->LoadedObject == object)
|
||||
if (item->LoadedObject.get() == object)
|
||||
{
|
||||
item->LoadedObject = nullptr;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ struct ObjectRepositoryItem
|
||||
std::string Name;
|
||||
std::vector<std::string> Authors;
|
||||
std::vector<ObjectSourceGame> Sources;
|
||||
Object* LoadedObject{};
|
||||
std::shared_ptr<Object> LoadedObject{};
|
||||
struct
|
||||
{
|
||||
uint8_t RideFlags;
|
||||
@@ -82,7 +82,7 @@ struct IObjectRepository
|
||||
[[nodiscard]] virtual const ObjectRepositoryItem* FindObject(const ObjectEntryDescriptor& oed) const abstract;
|
||||
|
||||
[[nodiscard]] virtual std::unique_ptr<Object> LoadObject(const ObjectRepositoryItem* ori) abstract;
|
||||
virtual void RegisterLoadedObject(const ObjectRepositoryItem* ori, Object* object) abstract;
|
||||
virtual void RegisterLoadedObject(const ObjectRepositoryItem* ori, std::unique_ptr<Object>&& object) abstract;
|
||||
virtual void UnregisterLoadedObject(const ObjectRepositoryItem* ori, Object* object) abstract;
|
||||
|
||||
virtual void AddObject(const rct_object_entry* objectEntry, const void* data, size_t dataSize) abstract;
|
||||
|
||||
@@ -81,7 +81,7 @@ void SceneryGroupObject::UpdateEntryIndexes()
|
||||
if (ori->LoadedObject == nullptr)
|
||||
continue;
|
||||
|
||||
auto entryIndex = objectManager.GetLoadedObjectEntryIndex(ori->LoadedObject);
|
||||
auto entryIndex = objectManager.GetLoadedObjectEntryIndex(ori->LoadedObject.get());
|
||||
Guard::Assert(entryIndex != OBJECT_ENTRY_INDEX_NULL, GUARD_LINE);
|
||||
|
||||
auto sceneryType = ori->ObjectEntry.GetSceneryType();
|
||||
|
||||
Reference in New Issue
Block a user