From 5b9cb813e7f68a0ce8547c560f00a082cdae40f9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 5 Jul 2016 19:33:12 +0100 Subject: [PATCH] fix load_object cc --- src/interface/console.c | 10 +-- src/object/ObjectManager.cpp | 136 +++++++++++++++++++++++++++++--- src/object/ObjectManager.h | 17 +++- src/object/ObjectRepository.cpp | 14 ---- src/object/ObjectRepository.h | 1 - 5 files changed, 147 insertions(+), 31 deletions(-) diff --git a/src/interface/console.c b/src/interface/console.c index 1e4dc37ffa..c5b0fc7e0a 100644 --- a/src/interface/console.c +++ b/src/interface/console.c @@ -30,6 +30,7 @@ #include "../input.h" #include "../network/twitch.h" #include "../object.h" +#include "../object/ObjectManager.h" #include "../object/ObjectRepository.h" #include "../world/banner.h" #include "../world/climate.h" @@ -883,19 +884,18 @@ static int cc_load_object(const utf8 **argv, int argc) { } const rct_object_entry * entry = &ori->ObjectEntry; - void * loadedObject = object_repository_find_loaded_object(entry); + void * loadedObject = object_manager_get_loaded_object(entry); if (loadedObject != NULL) { console_writeline_error("Object is already in scenario."); return 1; } - int groupIndex; - if (!object_load_chunk(-1, entry, &groupIndex)) { + loadedObject = object_manager_load_object(entry); + if (loadedObject == NULL) { console_writeline_error("Unable to load object."); return 1; } - - reset_loaded_objects(); + int groupIndex = object_manager_get_loaded_object_entry_index(loadedObject); uint8 objectType = entry->flags & 0x0F; if (objectType == OBJECT_TYPE_RIDE) { diff --git a/src/object/ObjectManager.cpp b/src/object/ObjectManager.cpp index 7a6e2f0790..1daa07634d 100644 --- a/src/object/ObjectManager.cpp +++ b/src/object/ObjectManager.cpp @@ -53,6 +53,60 @@ public: return _loadedObjects[index]; } + Object * GetLoadedObject(const rct_object_entry * entry) override + { + Object * loadedObject = nullptr; + const ObjectRepositoryItem * ori = _objectRepository->FindObject(entry); + if (ori != nullptr) + { + loadedObject = ori->LoadedObject; + } + return loadedObject; + } + + uint8 GetLoadedObjectEntryIndex(const Object * object) override + { + uint8 result = UINT8_MAX; + if (_loadedObjects != nullptr) + { + for (size_t i = 0; i < OBJECT_ENTRY_COUNT; i++) + { + if (_loadedObjects[i] == object) + { + get_type_entry_index(i, nullptr, &result); + break; + } + } + } + return result; + } + + Object * LoadObject(const rct_object_entry * entry) override + { + Object * loadedObject = nullptr; + const ObjectRepositoryItem * ori = _objectRepository->FindObject(entry); + if (ori != nullptr) + { + loadedObject = ori->LoadedObject; + if (loadedObject == nullptr) + { + uint8 objectType = entry->flags & 0x0F; + sint32 slot = FindSpareSlot(objectType); + if (slot != -1) + { + loadedObject = GetOrLoadObject(ori); + if (loadedObject != nullptr) + { + _loadedObjects[slot] = loadedObject; + UpdateLegacyLoadedObjectList(); + reset_type_to_ride_entry_index_map(); + } + } + } + } + return loadedObject; + } + bool LoadObjects(const rct_object_entry * entries, size_t count) override { IObjectRepository * objectRepository = GetObjectRepository(); @@ -102,6 +156,23 @@ public: } private: + sint32 FindSpareSlot(uint8 objectType) + { + if (_loadedObjects != nullptr) + { + sint32 firstIndex = GetIndexFromTypeEntry(objectType, 0); + sint32 endIndex = firstIndex + object_entry_group_counts[objectType]; + for (sint32 i = firstIndex; i < endIndex; i++) + { + if (_loadedObjects[i] == nullptr) + { + return i; + } + } + } + return -1; + } + void SetNewLoadedObjectList(Object * * newLoadedObjects) { if (newLoadedObjects == nullptr) @@ -243,22 +314,15 @@ private: loadedObject = ori->LoadedObject; if (loadedObject == nullptr) { - // Try to load object - loadedObject = _objectRepository->LoadObject(ori); + loadedObject = GetOrLoadObject(ori); if (loadedObject == nullptr) { ReportObjectLoadProblem(&ori->ObjectEntry); Memory::Free(loadedObjects); return nullptr; - } - else - { - loadedObject->Load(); + } else { newObjectsLoaded++; } - - // Connect the ori to the registered object - _objectRepository->RegisterLoadedObject(ori, loadedObject); } } loadedObjects[i] = loadedObject; @@ -270,6 +334,24 @@ private: return loadedObjects; } + Object * GetOrLoadObject(const ObjectRepositoryItem * ori) + { + Object * loadedObject = ori->LoadedObject; + if (loadedObject == nullptr) + { + // Try to load object + loadedObject = _objectRepository->LoadObject(ori); + if (loadedObject != nullptr) + { + loadedObject->Load(); + + // Connect the ori to the registered object + _objectRepository->RegisterLoadedObject(ori, loadedObject); + } + } + return loadedObject; + } + static void ReportMissingObject(const rct_object_entry * entry) { utf8 objName[9] = { 0 }; @@ -285,6 +367,17 @@ private: Console::Error::WriteFormat("[%s]: Object could not be loaded.", objName); Console::Error::WriteLine(); } + + static sint32 GetIndexFromTypeEntry(uint8 objectType, uint8 entryIndex) + { + int result = 0; + for (uint8 i = 0; i < objectType; i++) + { + result += object_entry_group_counts[i]; + } + result += entryIndex; + return result; + } }; ObjectManager * _objectManager; @@ -298,3 +391,28 @@ IObjectManager * GetObjectManager() } return _objectManager; } + +extern "C" +{ + void * object_manager_get_loaded_object(const rct_object_entry * entry) + { + IObjectManager * objectManager = GetObjectManager(); + Object * loadedObject = objectManager->GetLoadedObject(entry); + return (void *)loadedObject; + } + + uint8 object_manager_get_loaded_object_entry_index(const void * loadedObject) + { + IObjectManager * objectManager = GetObjectManager(); + const Object * object = (const Object *)loadedObject; + uint8 entryIndex = objectManager->GetLoadedObjectEntryIndex(object); + return entryIndex; + } + + void * object_manager_load_object(const rct_object_entry * entry) + { + IObjectManager * objectManager = GetObjectManager(); + Object * loadedObject = objectManager->LoadObject(entry); + return (void *)loadedObject; + } +} diff --git a/src/object/ObjectManager.h b/src/object/ObjectManager.h index 4e09950fee..a2a2ad1ea4 100644 --- a/src/object/ObjectManager.h +++ b/src/object/ObjectManager.h @@ -27,14 +27,27 @@ extern "C" } #endif +#ifdef __cplusplus + interface IObjectManager { virtual ~IObjectManager() { } virtual Object * GetLoadedObject(size_t index) abstract; + virtual Object * GetLoadedObject(const rct_object_entry * entry) abstract; + virtual uint8 GetLoadedObjectEntryIndex(const Object * object) abstract; - virtual bool LoadObjects(const rct_object_entry * entries, size_t count) abstract; - virtual void UnloadAll() abstract; + virtual Object * LoadObject(const rct_object_entry * entry) abstract; + virtual bool LoadObjects(const rct_object_entry * entries, size_t count) abstract; + virtual void UnloadAll() abstract; }; IObjectManager * GetObjectManager(); + +#else + +void * object_manager_get_loaded_object(const rct_object_entry * entry); +uint8 object_manager_get_loaded_object_entry_index(const void * loadedObject); +void * object_manager_load_object(const rct_object_entry * entry); + +#endif diff --git a/src/object/ObjectRepository.cpp b/src/object/ObjectRepository.cpp index 04ca902f2d..18ae1ce8e5 100644 --- a/src/object/ObjectRepository.cpp +++ b/src/object/ObjectRepository.cpp @@ -711,20 +711,6 @@ extern "C" return (void *)object; } - void * object_repository_find_loaded_object(const rct_object_entry * objectEntry) - { - Object * object = nullptr; - - IObjectRepository * objectRepository = GetObjectRepository(); - const ObjectRepositoryItem * ori = objectRepository->FindObject(objectEntry); - if (ori != nullptr) - { - object = ori->LoadedObject; - } - - return (void *)object; - } - void * object_repository_get_loaded_object(uint8 objectType, uint8 entryIndex) { int index = GetObjectEntryIndex(objectType, entryIndex); diff --git a/src/object/ObjectRepository.h b/src/object/ObjectRepository.h index 77db1c82d4..1ee96967b4 100644 --- a/src/object/ObjectRepository.h +++ b/src/object/ObjectRepository.h @@ -86,7 +86,6 @@ const ObjectRepositoryItem * object_repository_get_items(); const ObjectRepositoryItem * object_repository_find_object_by_entry(const rct_object_entry * entry); const ObjectRepositoryItem * object_repository_find_object_by_name(const char * name); void * object_repository_load_object(const rct_object_entry * objectEntry); -void * object_repository_find_loaded_object(const rct_object_entry * objectEntry); void * object_repository_get_loaded_object(uint8 objectType, uint8 entryIndex); void object_repository_unload(size_t itemIndex);