mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-18 04:23:20 +01:00
Modify object loading for JSON-only objects
This commit is contained in:
@@ -133,10 +133,16 @@ public:
|
||||
return RepositoryItemToObject(ori);
|
||||
}
|
||||
|
||||
void LoadObjects(const rct_object_entry* entries, size_t count) override
|
||||
Object* LoadObject(const ObjectEntryDescriptor& descriptor) override
|
||||
{
|
||||
const ObjectRepositoryItem* ori = _objectRepository.FindObject(descriptor);
|
||||
return RepositoryItemToObject(ori);
|
||||
}
|
||||
|
||||
void LoadObjects(const ObjectList& objectList) override
|
||||
{
|
||||
// Find all the required objects
|
||||
auto requiredObjects = GetRequiredObjects(entries, count);
|
||||
auto requiredObjects = GetRequiredObjects(objectList);
|
||||
|
||||
// Load the required objects
|
||||
LoadObjects(requiredObjects);
|
||||
@@ -149,19 +155,19 @@ public:
|
||||
ResetTypeToRideEntryIndexMap();
|
||||
}
|
||||
|
||||
void UnloadObjects(const std::vector<rct_object_entry>& entries) override
|
||||
void UnloadObjects(const std::vector<ObjectEntryDescriptor>& entries) override
|
||||
{
|
||||
// TODO there are two performance issues here:
|
||||
// - FindObject for every entry which is a dictionary lookup
|
||||
// - GetLoadedObjectIndex for every entry which enumerates _loadedList
|
||||
|
||||
size_t numObjectsUnloaded = 0;
|
||||
for (const auto& entry : entries)
|
||||
for (const auto& descriptor : entries)
|
||||
{
|
||||
const ObjectRepositoryItem* ori = _objectRepository.FindObject(&entry);
|
||||
const auto* ori = _objectRepository.FindObject(descriptor);
|
||||
if (ori != nullptr)
|
||||
{
|
||||
Object* loadedObject = ori->LoadedObject.get();
|
||||
auto* loadedObject = ori->LoadedObject.get();
|
||||
if (loadedObject != nullptr)
|
||||
{
|
||||
UnloadObject(loadedObject);
|
||||
@@ -209,7 +215,7 @@ public:
|
||||
{
|
||||
const ObjectRepositoryItem* item = &_objectRepository.GetObjects()[i];
|
||||
if (item->LoadedObject != nullptr && IsObjectCustom(item) && item->LoadedObject->GetLegacyData() != nullptr
|
||||
&& !item->LoadedObject->IsJsonObject())
|
||||
&& item->LoadedObject->GetGeneration() == ObjectGeneration::DAT)
|
||||
{
|
||||
objects.push_back(item);
|
||||
}
|
||||
@@ -352,42 +358,42 @@ private:
|
||||
|
||||
Object* RepositoryItemToObject(const ObjectRepositoryItem* ori, std::optional<int32_t> slot = {})
|
||||
{
|
||||
if (ori == nullptr)
|
||||
return nullptr;
|
||||
|
||||
Object* loadedObject = ori->LoadedObject.get();
|
||||
if (loadedObject != nullptr)
|
||||
return loadedObject;
|
||||
|
||||
ObjectType objectType = ori->ObjectEntry.GetType();
|
||||
if (slot)
|
||||
Object* loadedObject = nullptr;
|
||||
if (ori != nullptr)
|
||||
{
|
||||
if (_loadedObjects.size() > static_cast<size_t>(*slot) && _loadedObjects[*slot] != nullptr)
|
||||
loadedObject = ori->LoadedObject.get();
|
||||
if (loadedObject == nullptr)
|
||||
{
|
||||
// Slot already taken
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
slot = FindSpareSlot(objectType);
|
||||
}
|
||||
if (slot.has_value())
|
||||
{
|
||||
auto* object = GetOrLoadObject(ori);
|
||||
if (object != nullptr)
|
||||
{
|
||||
if (_loadedObjects.size() <= static_cast<size_t>(*slot))
|
||||
ObjectType objectType = ori->Type;
|
||||
if (slot)
|
||||
{
|
||||
_loadedObjects.resize(slot.value() + 1);
|
||||
if (_loadedObjects.size() > static_cast<size_t>(*slot) && _loadedObjects[*slot] != nullptr)
|
||||
{
|
||||
// Slot already taken
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
slot = FindSpareSlot(objectType);
|
||||
}
|
||||
if (slot.has_value())
|
||||
{
|
||||
auto object = GetOrLoadObject(ori);
|
||||
if (object != nullptr)
|
||||
{
|
||||
if (_loadedObjects.size() <= static_cast<size_t>(*slot))
|
||||
{
|
||||
_loadedObjects.resize(slot.value() + 1);
|
||||
}
|
||||
loadedObject = object;
|
||||
_loadedObjects[slot.value()] = std::move(object);
|
||||
UpdateSceneryGroupIndexes();
|
||||
ResetTypeToRideEntryIndexMap();
|
||||
}
|
||||
}
|
||||
loadedObject = object;
|
||||
_loadedObjects[slot.value()] = object;
|
||||
UpdateSceneryGroupIndexes();
|
||||
ResetTypeToRideEntryIndexMap();
|
||||
}
|
||||
}
|
||||
|
||||
return loadedObject;
|
||||
}
|
||||
|
||||
@@ -431,7 +437,7 @@ private:
|
||||
object->Unload();
|
||||
|
||||
// TODO try to prevent doing a repository search
|
||||
const ObjectRepositoryItem* ori = _objectRepository.FindObject(object->GetObjectEntry());
|
||||
const auto* ori = _objectRepository.FindObject(object->GetDescriptor());
|
||||
if (ori != nullptr)
|
||||
{
|
||||
_objectRepository.UnregisterLoadedObject(ori, object);
|
||||
@@ -535,25 +541,29 @@ private:
|
||||
return entryIndex;
|
||||
}
|
||||
|
||||
std::vector<const ObjectRepositoryItem*> GetRequiredObjects(const rct_object_entry* entries, size_t count)
|
||||
std::vector<const ObjectRepositoryItem*> GetRequiredObjects(const ObjectList& objectList)
|
||||
{
|
||||
std::vector<const ObjectRepositoryItem*> requiredObjects;
|
||||
std::vector<rct_object_entry> missingObjects;
|
||||
std::vector<ObjectEntryDescriptor> missingObjects;
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
for (auto objectType = ObjectType::Ride; objectType < ObjectType::Count; objectType++)
|
||||
{
|
||||
const rct_object_entry* entry = &entries[i];
|
||||
const ObjectRepositoryItem* ori = nullptr;
|
||||
if (!object_entry_is_empty(entry))
|
||||
auto maxObjectsOfType = static_cast<ObjectEntryIndex>(object_entry_group_counts[EnumValue(objectType)]);
|
||||
for (ObjectEntryIndex i = 0; i < maxObjectsOfType; i++)
|
||||
{
|
||||
ori = _objectRepository.FindObject(entry);
|
||||
if (ori == nullptr && entry->GetType() != ObjectType::ScenarioText)
|
||||
const ObjectRepositoryItem* ori = nullptr;
|
||||
const auto& entry = objectList.GetObject(objectType, i);
|
||||
if (entry.HasValue())
|
||||
{
|
||||
missingObjects.push_back(*entry);
|
||||
ReportMissingObject(entry);
|
||||
ori = _objectRepository.FindObject(entry);
|
||||
if (ori == nullptr && entry.GetType() != ObjectType::ScenarioText)
|
||||
{
|
||||
missingObjects.push_back(entry);
|
||||
ReportMissingObject(entry);
|
||||
}
|
||||
}
|
||||
requiredObjects.push_back(ori);
|
||||
}
|
||||
requiredObjects.push_back(ori);
|
||||
}
|
||||
|
||||
if (!missingObjects.empty())
|
||||
@@ -592,7 +602,7 @@ private:
|
||||
{
|
||||
std::vector<Object*> objects;
|
||||
std::vector<Object*> newLoadedObjects;
|
||||
std::vector<rct_object_entry> badObjects;
|
||||
std::vector<ObjectEntryDescriptor> badObjects;
|
||||
objects.resize(OBJECT_ENTRY_COUNT);
|
||||
newLoadedObjects.reserve(OBJECT_ENTRY_COUNT);
|
||||
|
||||
@@ -612,7 +622,7 @@ private:
|
||||
std::lock_guard<std::mutex> guard(commonMutex);
|
||||
if (newObject == nullptr)
|
||||
{
|
||||
badObjects.push_back(requiredObject->ObjectEntry);
|
||||
badObjects.push_back(ObjectEntryDescriptor(requiredObject->ObjectEntry));
|
||||
ReportObjectLoadProblem(&requiredObject->ObjectEntry);
|
||||
}
|
||||
else
|
||||
@@ -714,11 +724,10 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
static void ReportMissingObject(const rct_object_entry* entry)
|
||||
static void ReportMissingObject(const ObjectEntryDescriptor& entry)
|
||||
{
|
||||
utf8 objName[DAT_NAME_LENGTH + 1] = { 0 };
|
||||
std::copy_n(entry->name, DAT_NAME_LENGTH, objName);
|
||||
Console::Error::WriteLine("[%s] Object not found.", objName);
|
||||
std::string name(entry.GetName());
|
||||
Console::Error::WriteLine("[%s] Object not found.", name.c_str());
|
||||
}
|
||||
|
||||
void ReportObjectLoadProblem(const rct_object_entry* entry)
|
||||
@@ -771,7 +780,7 @@ Object* object_manager_load_object(const rct_object_entry* entry)
|
||||
return loadedObject;
|
||||
}
|
||||
|
||||
void object_manager_unload_objects(const std::vector<rct_object_entry>& entries)
|
||||
void object_manager_unload_objects(const std::vector<ObjectEntryDescriptor>& entries)
|
||||
{
|
||||
auto& objectManager = OpenRCT2::GetContext()->GetObjectManager();
|
||||
objectManager.UnloadObjects(entries);
|
||||
|
||||
Reference in New Issue
Block a user