1
0
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:
Gymnasiast
2021-09-12 21:25:22 +02:00
parent 37821ce25e
commit bdab3219cb
52 changed files with 707 additions and 500 deletions

View File

@@ -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);