From a534840f48af7bee9a13bded0e2cbe2677f1636b Mon Sep 17 00:00:00 2001 From: Petr Ohlidal Date: Sat, 13 Mar 2021 16:48:06 +0100 Subject: [PATCH 1/3] :bug: Fixed gibberish text in 'vehicle type' on Loader UI --- source/main/gui/panels/GUI_MainSelector.cpp | 8 ++------ source/main/physics/SimData.h | 14 ++++++++------ source/main/resources/CacheSystem.cpp | 14 ++++++++++++++ source/main/resources/CacheSystem.h | 1 + 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/source/main/gui/panels/GUI_MainSelector.cpp b/source/main/gui/panels/GUI_MainSelector.cpp index 71fe674631..6df9428c94 100644 --- a/source/main/gui/panels/GUI_MainSelector.cpp +++ b/source/main/gui/panels/GUI_MainSelector.cpp @@ -633,12 +633,8 @@ MainSelector::DisplayEntry::DisplayEntry(CacheEntry* entry): { sde_addtime_str = asctime(gmtime(&sde_entry->addtimestamp)); } - if (sde_entry->nodecount > 0) - { - static const char* str[] = - {_LC("MainSelector", "Non-Driveable"), _LC("MainSelector", "Truck"), _LC("MainSelector", "Airplane"), _LC("MainSelector", "Boat"), _LC("MainSelector", "Machine")}; - sde_driveable_str = str[sde_entry->driveable]; - } + + sde_driveable_str = App::GetCacheSystem()->ActorTypeToName(sde_entry->driveable); } MainSelector::DisplayCategory::DisplayCategory(int id, std::string const& name, size_t usage) diff --git a/source/main/physics/SimData.h b/source/main/physics/SimData.h index 24032706d7..d7b8b0d756 100644 --- a/source/main/physics/SimData.h +++ b/source/main/physics/SimData.h @@ -74,12 +74,14 @@ enum HookState enum ActorType //!< Aka 'Driveable' { - NOT_DRIVEABLE, //!< not drivable at all - TRUCK, //!< its a truck (or other land vehicle) - AIRPLANE, //!< its an airplane - BOAT, //!< its a boat - MACHINE, //!< its a machine - AI, //!< machine controlled by an Artificial Intelligence + // DO NOT MODIFY NUMBERS - serialized into cache file, see RoR::CacheEntry + + NOT_DRIVEABLE = 0, //!< not drivable at all + TRUCK = 1, //!< its a truck (or other land vehicle) + AIRPLANE = 2, //!< its an airplane + BOAT = 3, //!< its a boat + MACHINE = 4, //!< its a machine + AI = 5, //!< machine controlled by an Artificial Intelligence }; enum SpecialBeam: short diff --git a/source/main/resources/CacheSystem.cpp b/source/main/resources/CacheSystem.cpp index fc66cbc76c..228a666f89 100644 --- a/source/main/resources/CacheSystem.cpp +++ b/source/main/resources/CacheSystem.cpp @@ -428,6 +428,20 @@ String CacheSystem::GetPrettyName(String fname) return ""; } +std::string CacheSystem::ActorTypeToName(ActorType driveable) +{ + switch (driveable) + { + case ActorType::NOT_DRIVEABLE: return _LC("MainSelector", "Non-Driveable"); + case ActorType::TRUCK: return _LC("MainSelector", "Truck"); + case ActorType::AIRPLANE: return _LC("MainSelector", "Airplane"); + case ActorType::BOAT: return _LC("MainSelector", "Boat"); + case ActorType::MACHINE: return _LC("MainSelector", "Machine"); + case ActorType::AI: return _LC("MainSelector", "A.I."); + default: return ""; + }; +} + void CacheSystem::ExportEntryToJson(rapidjson::Value& j_entries, rapidjson::Document& j_doc, CacheEntry const & entry) { rapidjson::Value j_entry(rapidjson::kObjectType); diff --git a/source/main/resources/CacheSystem.h b/source/main/resources/CacheSystem.h index d0d1808ca5..186d56283c 100644 --- a/source/main/resources/CacheSystem.h +++ b/source/main/resources/CacheSystem.h @@ -211,6 +211,7 @@ class CacheSystem : public ZeroedMemoryAllocator CacheEntry *GetEntry(int modid); Ogre::String GetPrettyName(Ogre::String fname); + std::string ActorTypeToName(ActorType driveable); private: From b3c59b060079317c425c30b4e2475d432922f7d9 Mon Sep 17 00:00:00 2001 From: Petr Ohlidal Date: Sat, 13 Mar 2021 17:17:48 +0100 Subject: [PATCH 2/3] :bug: Fixed 'reload vehicle' not reloading the truck file. --- source/main/GameContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/main/GameContext.cpp b/source/main/GameContext.cpp index bc2e9caaa5..21d4b608e1 100644 --- a/source/main/GameContext.cpp +++ b/source/main/GameContext.cpp @@ -289,6 +289,7 @@ void GameContext::ModifyActor(ActorModifyRequest& rq) m_prev_player_actor = nullptr; this->DeleteActor(rq.amr_actor); + entry->actor_def = nullptr; App::GetCacheSystem()->ReLoadResource(*entry); ActorSpawnRequest* srq = new ActorSpawnRequest; From f4766438037ecdc27168c9394458ec53d9dc7ef2 Mon Sep 17 00:00:00 2001 From: Petr Ohlidal Date: Sat, 13 Mar 2021 18:39:04 +0100 Subject: [PATCH 3/3] :video_game: Reloading vehicle now reloads resources, too. Reloading vehicle will now reload all it's resources (materials, textures, everything). Works both for zipped and unzipped mods. The compromise is that all spawned actors using the same resource bundle must be deleted. --- source/main/Application.h | 3 ++- source/main/GameContext.cpp | 31 +++++++++++---------------- source/main/main.cpp | 27 +++++++++++++++++++++++ source/main/resources/CacheSystem.cpp | 28 ++++++++++++++++++++++-- source/main/resources/CacheSystem.h | 1 + 5 files changed, 68 insertions(+), 22 deletions(-) diff --git a/source/main/Application.h b/source/main/Application.h index 61379346c9..28aeff713d 100644 --- a/source/main/Application.h +++ b/source/main/Application.h @@ -91,12 +91,13 @@ enum MsgType // GUI MSG_GUI_OPEN_MENU_REQUESTED, MSG_GUI_CLOSE_MENU_REQUESTED, - MSG_GUI_OPEN_SELECTOR_REQUESTED, //!< Payload = LoaderType* (owner), Description = GUID | empty + MSG_GUI_OPEN_SELECTOR_REQUESTED, //!< Payload = LoaderType* (owner), Description = GUID | empty MSG_GUI_CLOSE_SELECTOR_REQUESTED, // Editing MSG_EDI_MODIFY_GROUNDMODEL_REQUESTED, //!< Payload = ground_model_t* (weak) MSG_EDI_ENTER_TERRN_EDITOR_REQUESTED, MSG_EDI_LEAVE_TERRN_EDITOR_REQUESTED, + MSG_EDI_RELOAD_BUNDLE_REQUESTED, //!< Payload = RoR::CacheEntry* (weak) }; enum class AppState diff --git a/source/main/GameContext.cpp b/source/main/GameContext.cpp index 21d4b608e1..c8ef9c65b1 100644 --- a/source/main/GameContext.cpp +++ b/source/main/GameContext.cpp @@ -279,28 +279,21 @@ void GameContext::ModifyActor(ActorModifyRequest& rq) return; } - auto reload_pos = rq.amr_actor->getPosition(); - auto reload_dir = Ogre::Quaternion(Ogre::Degree(270) - Ogre::Radian(m_player_actor->getRotation()), Ogre::Vector3::UNIT_Y); - auto debug_view = rq.amr_actor->GetGfxActor()->GetDebugView(); - auto asr_config = rq.amr_actor->GetSectionConfig(); - auto used_skin = rq.amr_actor->GetUsedSkin(); - - reload_pos.y = m_player_actor->GetMinHeight(); - - m_prev_player_actor = nullptr; - this->DeleteActor(rq.amr_actor); - entry->actor_def = nullptr; - App::GetCacheSystem()->ReLoadResource(*entry); - + // Create spawn request while actor still exists ActorSpawnRequest* srq = new ActorSpawnRequest; - srq->asr_position = reload_pos; - srq->asr_rotation = reload_dir; - srq->asr_config = asr_config; - srq->asr_skin_entry = used_skin; + srq->asr_position = Ogre::Vector3(rq.amr_actor->getPosition().x, rq.amr_actor->GetMinHeight(), rq.amr_actor->getPosition().z); + srq->asr_rotation = Ogre::Quaternion(Ogre::Degree(270) - Ogre::Radian(rq.amr_actor->getRotation()), Ogre::Vector3::UNIT_Y); + srq->asr_config = rq.amr_actor->GetSectionConfig(); + srq->asr_skin_entry = rq.amr_actor->GetUsedSkin(); srq->asr_cache_entry= entry; - srq->asr_debugview = (int)debug_view; + srq->asr_debugview = (int)rq.amr_actor->GetGfxActor()->GetDebugView(); srq->asr_origin = ActorSpawnRequest::Origin::USER; - this->PushMessage(Message(MSG_SIM_SPAWN_ACTOR_REQUESTED, (void*)srq)); + + // This deletes all actors using the resource bundle, including the one we're reloading. + this->PushMessage(Message(MSG_EDI_RELOAD_BUNDLE_REQUESTED, (void*)entry)); + + // Load our actor again, but only after all actors are deleted. + this->ChainMessage(Message(MSG_SIM_SPAWN_ACTOR_REQUESTED, (void*)srq)); } } diff --git a/source/main/main.cpp b/source/main/main.cpp index cfc625ebec..6c7f830ef2 100644 --- a/source/main/main.cpp +++ b/source/main/main.cpp @@ -672,6 +672,33 @@ int main(int argc, char *argv[]) } break; + case MSG_EDI_RELOAD_BUNDLE_REQUESTED: + { + // To reload the bundle, it's resource group must be destroyed and re-created. All actors using it must be deleted. + CacheEntry* entry = reinterpret_cast(m.payload); + bool all_clear = true; + for (Actor* actor: App::GetGameContext()->GetActorManager()->GetActors()) + { + if (actor->GetGfxActor()->GetResourceGroup() == entry->resource_group) + { + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, actor)); + all_clear = false; + } + } + + if (all_clear) + { + // Nobody uses the RG anymore -> destroy and re-create it. + App::GetCacheSystem()->ReLoadResource(*entry); + } + else + { + // Re-post the same message again so that it's message chain is executed later. + App::GetGameContext()->PushMessage(m); + failed_m = true; + } + } + default:; } diff --git a/source/main/resources/CacheSystem.cpp b/source/main/resources/CacheSystem.cpp index 228a666f89..9e7a7d509f 100644 --- a/source/main/resources/CacheSystem.cpp +++ b/source/main/resources/CacheSystem.cpp @@ -1116,8 +1116,32 @@ void CacheSystem::ReLoadResource(CacheEntry& t) return; // Not loaded - nothing to do } - Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(t.resource_group); - t.resource_group = ""; + // IMPORTANT! No actors must use the bundle while reloading, use RoR::MsgType::MSG_EDI_RELOAD_BUNDLE_REQUESTED + + this->UnLoadResource(t); + this->LoadResource(t); // Will create the same resource group again +} + +void CacheSystem::UnLoadResource(CacheEntry& t) +{ + if (t.resource_group == "") + { + return; // Not loaded - nothing to do + } + + // IMPORTANT! No actors must use the bundle after reloading, use RoR::MsgType::MSG_EDI_RELOAD_BUNDLE_REQUESTED + + std::string resource_group = t.resource_group; // Keep local copy, the CacheEntry will be blanked! + for (CacheEntry& i_entry: m_entries) + { + if (i_entry.resource_group == resource_group) + { + i_entry.actor_def = nullptr; // Delete cached truck file - force reload from disk + i_entry.resource_group = ""; // Mark as unloaded + } + } + + Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(resource_group); this->LoadResource(t); // Will create the same resource group again } diff --git a/source/main/resources/CacheSystem.h b/source/main/resources/CacheSystem.h index 186d56283c..6ed3ed5c28 100644 --- a/source/main/resources/CacheSystem.h +++ b/source/main/resources/CacheSystem.h @@ -203,6 +203,7 @@ class CacheSystem : public ZeroedMemoryAllocator bool CheckResourceLoaded(Ogre::String &in_out_filename); //!< Finds + loads the associated resource bundle if not already done. bool CheckResourceLoaded(Ogre::String &in_out_filename, Ogre::String &out_group); //!< Finds given resource, outputs group name. Also loads the associated resource bundle if not already done. void ReLoadResource(CacheEntry& t); //!< Forces reloading the associated bundle. + void UnLoadResource(CacheEntry& t); //!< Unloads associated bundle, destroying all spawned actors. const std::vector &GetEntries() const { return m_entries; } const CategoryIdNameMap &GetCategories() const { return m_categories; }