| 60 | } |
| 61 | |
| 62 | void ScriptModuleManager::Reload(const std::string& name, World* world) |
| 63 | { |
| 64 | auto it = m_Modules.find(name); |
| 65 | if (it == m_Modules.end()) { |
| 66 | TN_ERROR("Cannot reload '%s': not loaded.", name.c_str()); |
| 67 | return; |
| 68 | } |
| 69 | |
| 70 | LoadedModule& mod = it->second; |
| 71 | const std::string path = mod.path; |
| 72 | const std::vector<std::string> componentNames = mod.componentNames; |
| 73 | |
| 74 | // Step 1: Serialize affected component state while the old DLL is still live. |
| 75 | struct SavedComponent { |
| 76 | Actor* actor; |
| 77 | std::string type; |
| 78 | bool active; |
| 79 | nlohmann::json data; |
| 80 | }; |
| 81 | std::vector<SavedComponent> saved; |
| 82 | |
| 83 | if (world) { |
| 84 | for (auto& actorPtr : world->GetActors()) { |
| 85 | Actor* actor = actorPtr.get(); |
| 86 | for (Component* comp : actor->GetAllComponents()) { |
| 87 | std::string typeName = ComponentRegistry::Get().GetNameForType(typeid(*comp)); |
| 88 | bool isModuleComp = false; |
| 89 | for (const auto& n : componentNames) { |
| 90 | if (n == typeName) { isModuleComp = true; break; } |
| 91 | } |
| 92 | if (!isModuleComp) continue; |
| 93 | |
| 94 | SavedComponent sc; |
| 95 | sc.actor = actor; |
| 96 | sc.type = typeName; |
| 97 | sc.active = comp->IsActive(); |
| 98 | comp->Serialize(sc.data); |
| 99 | saved.push_back(std::move(sc)); |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | // Step 2a: Remove old instances while old DLL is open so vtables are still valid. |
| 104 | for (const auto& sc : saved) { |
| 105 | for (Component* comp : sc.actor->GetAllComponents()) { |
| 106 | if (ComponentRegistry::Get().GetNameForType(typeid(*comp)) == sc.type) { |
| 107 | sc.actor->RemoveComponentRaw(comp); |
| 108 | break; |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | // Step 2b: Unregister factories and unload old DLL. |
| 115 | void* unregSym = mod.dll->GetSymbol("UnregisterComponents"); |
| 116 | if (unregSym) |
| 117 | reinterpret_cast<void(*)()>(unregSym)(); |
| 118 | mod.dll.reset(); |
| 119 |
no test coverage detected