implement unloading arbitrary objects

This commit is contained in:
Ted John 2016-07-06 22:31:14 +01:00
parent 488da7942c
commit f59d6b7a00
5 changed files with 89 additions and 35 deletions

View File

@ -67,16 +67,10 @@ public:
uint8 GetLoadedObjectEntryIndex(const Object * object) override
{
uint8 result = UINT8_MAX;
if (_loadedObjects != nullptr)
size_t index = GetLoadedObjectIndex(object);
if (index != SIZE_MAX)
{
for (size_t i = 0; i < OBJECT_ENTRY_COUNT; i++)
{
if (_loadedObjects[i] == object)
{
get_type_entry_index(i, nullptr, &result);
break;
}
}
get_type_entry_index(index, nullptr, &result);
}
return result;
}
@ -141,6 +135,36 @@ public:
}
}
void UnloadObjects(const rct_object_entry * entries, size_t count) 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 (size_t i = 0; i < count; i++)
{
const rct_object_entry * entry = &entries[i];
const ObjectRepositoryItem * ori = _objectRepository->FindObject(entry);
if (ori != nullptr)
{
Object * loadedObject = ori->LoadedObject;
size_t index = GetLoadedObjectIndex(loadedObject);
UnloadObject(loadedObject);
_loadedObjects[index] = nullptr;
numObjectsUnloaded++;
}
}
if (numObjectsUnloaded > 0)
{
UpdateLegacyLoadedObjectList();
reset_type_to_ride_entry_index_map();
}
}
void UnloadAll() override
{
if (_loadedObjects != nullptr)
@ -173,6 +197,23 @@ private:
return -1;
}
size_t GetLoadedObjectIndex(const Object * object)
{
size_t result = SIZE_MAX;
if (_loadedObjects != nullptr)
{
for (size_t i = 0; i < OBJECT_ENTRY_COUNT; i++)
{
if (_loadedObjects[i] == object)
{
result = i;
break;
}
}
}
return result;
}
void SetNewLoadedObjectList(Object * * newLoadedObjects)
{
if (newLoadedObjects == nullptr)
@ -415,4 +456,10 @@ extern "C"
Object * loadedObject = objectManager->LoadObject(entry);
return (void *)loadedObject;
}
void object_manager_unload_objects(const rct_object_entry * entries, size_t count)
{
IObjectManager * objectManager = GetObjectManager();
objectManager->UnloadObjects(entries, count);
}
}

View File

@ -39,6 +39,7 @@ interface IObjectManager
virtual Object * LoadObject(const rct_object_entry * entry) abstract;
virtual bool LoadObjects(const rct_object_entry * entries, size_t count) abstract;
virtual void UnloadObjects(const rct_object_entry * entries, size_t count) abstract;
virtual void UnloadAll() abstract;
};
@ -49,5 +50,6 @@ IObjectManager * GetObjectManager();
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);
void object_manager_unload_objects(const rct_object_entry * entries, size_t count);
#endif

View File

@ -711,11 +711,6 @@ extern "C"
return (void *)object;
}
void object_repository_unload(size_t itemIndex)
{
// TODO
}
void object_unload_all()
{
IObjectManager * objectManager = GetObjectManager();

View File

@ -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_unload(size_t itemIndex);
void object_delete(void * object);
const utf8 * object_get_description(const void * object);

View File

@ -27,6 +27,7 @@
#include "../management/research.h"
#include "../object.h"
#include "../object_list.h"
#include "../object/ObjectManager.h"
#include "../object/ObjectRepository.h"
#include "../rct1.h"
#include "../ride/ride.h"
@ -714,12 +715,21 @@ void unload_unselected_objects()
{
int numItems = object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items();
size_t numObjectsToUnload = 0;
rct_object_entry * objectsToUnload = (rct_object_entry *)malloc(numItems * sizeof(rct_object_entry));
for (int i = 0; i < numItems; i++) {
if (!(_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED)) {
remove_selected_objects_from_research(&items[i].ObjectEntry);
object_repository_unload(i);
const rct_object_entry * entry = &items[i].ObjectEntry;
remove_selected_objects_from_research(entry);
objectsToUnload[numObjectsToUnload++] = *entry;
}
}
object_manager_unload_objects(objectsToUnload, numObjectsToUnload);
free(objectsToUnload);
}
/**
@ -1703,27 +1713,28 @@ static void window_editor_object_selection_manage_tracks()
*/
static void editor_load_selected_objects()
{
int numObjects = (int)object_repository_get_items_count();
int numItems = (int)object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = 0; i < numObjects; i++) {
for (int i = 0; i < numItems; i++) {
if (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED) {
uint8 entry_index, entry_type;
if (!find_object_in_entry_group(&items[i].ObjectEntry, &entry_type, &entry_index)) {
if (!object_load_chunk(-1, &items[i].ObjectEntry, NULL)) {
log_error("Failed to load entry %.8s", items->Name);
const ObjectRepositoryItem * item = &items[i];
const rct_object_entry * entry = &item->ObjectEntry;
void * loadedObject = object_manager_get_loaded_object(entry);
if (loadedObject == NULL) {
loadedObject = object_manager_load_object(entry);
if (loadedObject == NULL) {
log_error("Failed to load entry %.8s", entry->name);
}
// For in game use (cheat)
if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) {
// Defaults selected items to researched.
if (find_object_in_entry_group(&items[i].ObjectEntry, &entry_type, &entry_index)) {
if (entry_type == OBJECT_TYPE_RIDE) {
rct_ride_entry* rideType = get_ride_entry(entry_index);
research_insert(1, 0x10000 | (rideType->ride_type[0] << 8) | entry_index, rideType->category[0]);
}
else if (entry_type == OBJECT_TYPE_SCENERY_SETS) {
research_insert(1, entry_index, RESEARCH_CATEGORY_SCENERYSET);
}
else if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) {
// Defaults selected items to researched (if in-game)
uint8 objectType = entry->flags & 0x0F;
uint8 entryIndex = object_manager_get_loaded_object_entry_index(loadedObject);
if (objectType == OBJECT_TYPE_RIDE) {
rct_ride_entry *rideType = get_ride_entry(entryIndex);
research_insert(1, 0x10000 | (rideType->ride_type[0] << 8) | entryIndex, rideType->category[0]);
}
else if (objectType == OBJECT_TYPE_SCENERY_SETS) {
research_insert(1, entryIndex, RESEARCH_CATEGORY_SCENERYSET);
}
}
}