| 459 | } |
| 460 | |
| 461 | void ScriptsContainer::load(const ESM::LuaScripts& data) |
| 462 | { |
| 463 | removeAllScripts(); |
| 464 | const ScriptsConfiguration& cfg = mLua.getConfiguration(); |
| 465 | |
| 466 | std::map<int, ScriptInfo> scripts; |
| 467 | for (const auto& [scriptId, initData] : mAutoStartScripts) |
| 468 | scripts[scriptId] = { initData, nullptr }; |
| 469 | for (const ESM::LuaScript& s : data.mScripts) |
| 470 | { |
| 471 | std::optional<int> scriptId = cfg.mapId(s.mScriptId); |
| 472 | if (!scriptId) |
| 473 | { |
| 474 | Log(Debug::Verbose) << "Ignoring " << mNamePrefix << "[" << s.mScriptId << "]; script not registered"; |
| 475 | continue; |
| 476 | } |
| 477 | auto it = scripts.find(*scriptId); |
| 478 | if (it != scripts.end()) |
| 479 | it->second.mSavedData = &s; |
| 480 | else if (cfg.isCustomScript(*scriptId)) |
| 481 | scripts[*scriptId] = { cfg[*scriptId].mInitializationData, &s }; |
| 482 | else |
| 483 | Log(Debug::Verbose) << "Ignoring " << mNamePrefix << "[" << cfg[*scriptId].mScriptPath |
| 484 | << "]; this script is not allowed here"; |
| 485 | } |
| 486 | |
| 487 | mLua.protectedCall([&](LuaView& view) { |
| 488 | UnloadedData& container = ensureUnloaded(view); |
| 489 | |
| 490 | for (const auto& [scriptId, scriptInfo] : scripts) |
| 491 | { |
| 492 | if (scriptInfo.mSavedData == nullptr) |
| 493 | continue; |
| 494 | ESM::LuaScript& script = container.mScripts.emplace_back(*scriptInfo.mSavedData); |
| 495 | script.mScriptId = scriptId; |
| 496 | if (!script.mData.empty()) |
| 497 | { |
| 498 | try |
| 499 | { |
| 500 | sol::object state = deserialize(view.sol(), script.mData, mSavedDataDeserializer); |
| 501 | script.mData = serialize(state, mSerializer); |
| 502 | } |
| 503 | catch (std::exception& e) |
| 504 | { |
| 505 | printError(scriptId, "onLoad failed", e); |
| 506 | script.mData.clear(); |
| 507 | } |
| 508 | } |
| 509 | for (auto it = script.mTimers.begin(); it != script.mTimers.end();) |
| 510 | { |
| 511 | try |
| 512 | { |
| 513 | sol::object arg = deserialize(view.sol(), it->mCallbackArgument, mSavedDataDeserializer); |
| 514 | // It is important if the order of content files was changed. The deserialize-serialize |
| 515 | // procedure updates refnums, so timer.mSerializedArg may be not equal to |
| 516 | // savedTimer.mCallbackArgument. |
| 517 | it->mCallbackArgument = serialize(arg, mSerializer); |
| 518 | ++it; |
nothing calls this directly
no test coverage detected