Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Reloading vehicle now reloads everything (both ZIP and dir) #2709

Merged
merged 3 commits into from
Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion source/main/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 12 additions & 18 deletions source/main/GameContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,27 +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);
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));
}
}

Expand Down
8 changes: 2 additions & 6 deletions source/main/gui/panels/GUI_MainSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
27 changes: 27 additions & 0 deletions source/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<CacheEntry*>(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:;
}

Expand Down
14 changes: 8 additions & 6 deletions source/main/physics/SimData.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
42 changes: 40 additions & 2 deletions source/main/resources/CacheSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1102,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
}

Expand Down
2 changes: 2 additions & 0 deletions source/main/resources/CacheSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<CacheEntry> &GetEntries() const { return m_entries; }
const CategoryIdNameMap &GetCategories() const { return m_categories; }
Expand All @@ -211,6 +212,7 @@ class CacheSystem : public ZeroedMemoryAllocator

CacheEntry *GetEntry(int modid);
Ogre::String GetPrettyName(Ogre::String fname);
std::string ActorTypeToName(ActorType driveable);

private:

Expand Down