Lua: Set package.path and package.cpath before onInit is called

This commit is contained in:
Lion Kortlepel 2021-09-17 02:19:45 +02:00
parent e75e65815c
commit bac476ec34
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
2 changed files with 37 additions and 1 deletions

View File

@ -91,6 +91,7 @@ private:
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueScript(const std::shared_ptr<std::string>& Script); [[nodiscard]] std::shared_ptr<TLuaResult> EnqueueScript(const std::shared_ptr<std::string>& Script);
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueFunctionCall(const std::string& FunctionName, const std::initializer_list<std::any>& Args); [[nodiscard]] std::shared_ptr<TLuaResult> EnqueueFunctionCall(const std::string& FunctionName, const std::initializer_list<std::any>& Args);
void RegisterEvent(const std::string& EventName, const std::string& FunctionName); void RegisterEvent(const std::string& EventName, const std::string& FunctionName);
void AddPath(const fs::path& Path); // to be added to path and cpath
void operator()() override; void operator()() override;
private: private:
@ -110,6 +111,8 @@ private:
std::recursive_mutex mStateFunctionQueueMutex; std::recursive_mutex mStateFunctionQueueMutex;
TLuaEngine* mEngine; TLuaEngine* mEngine;
sol::state_view mStateView { mState }; sol::state_view mStateView { mState };
std::queue<fs::path> mPaths;
std::recursive_mutex mPathsMutex;
}; };
TNetwork* mNetwork; TNetwork* mNetwork;

View File

@ -42,7 +42,7 @@ void TLuaEngine::operator()() {
// now call all onInit's // now call all onInit's
for (const auto& Pair : mLuaStates) { for (const auto& Pair : mLuaStates) {
auto Res = EnqueueFunctionCall(Pair.first, "onInit", {}); auto Res = EnqueueFunctionCall(Pair.first, "onInit", {});
Res->WaitUntilReady(); Res->WaitUntilReady(); // FIXME this dumb, dont do this, this is smelly!
if (Res->Error && Res->ErrorMessage != TLuaEngine::BeamMPFnNotFoundError) { if (Res->Error && Res->ErrorMessage != TLuaEngine::BeamMPFnNotFoundError) {
beammp_lua_error("Calling \"onInit\" on \"" + Pair.first + "\" failed: " + Res->ErrorMessage); beammp_lua_error("Calling \"onInit\" on \"" + Pair.first + "\" failed: " + Res->ErrorMessage);
} }
@ -93,6 +93,7 @@ void TLuaEngine::InitializePlugin(const fs::path& Folder, const TLuaPluginConfig
beammp_assert(fs::is_directory(Folder)); beammp_assert(fs::is_directory(Folder));
std::unique_lock Lock(mLuaStatesMutex); std::unique_lock Lock(mLuaStatesMutex);
EnsureStateExists(Config.StateId, Folder.stem().string(), true); EnsureStateExists(Config.StateId, Folder.stem().string(), true);
mLuaStates[Config.StateId]->AddPath(Folder); // add to cpath + path
Lock.unlock(); Lock.unlock();
TLuaPlugin Plugin(*this, Config, Folder); TLuaPlugin Plugin(*this, Config, Folder);
} }
@ -315,6 +316,33 @@ void TLuaEngine::StateThreadData::operator()() {
auto S = mStateExecuteQueue.front(); auto S = mStateExecuteQueue.front();
mStateExecuteQueue.pop(); mStateExecuteQueue.pop();
Lock.unlock(); Lock.unlock();
{ // Paths Scope
std::unique_lock Lock(mPathsMutex);
if (!mPaths.empty()) {
std::stringstream PathAdditions;
std::stringstream CPathAdditions;
while (!mPaths.empty()) {
auto Path = mPaths.front();
mPaths.pop();
PathAdditions << ";" << (Path / "?.lua").string();
PathAdditions << ";" << (Path / "lua/?.lua").string();
#if WIN32
CPathAdditions << ";" << (Path / "?.dll").string();
CPathAdditions << ";" << (Path / "lib/?.dll").string();
#else // unix
CPathAdditions << ";" << (Path / "?.so").string();
CPathAdditions << ";" << (Path / "lib/?.so").string();
#endif
}
sol::state_view StateView(mState);
auto PackageTable = StateView.globals().get<sol::table>("package");
PackageTable["path"] = PackageTable.get<std::string>("path") + PathAdditions.str();
PackageTable["cpath"] = PackageTable.get<std::string>("cpath") + CPathAdditions.str();
StateView.globals()["package"] = PackageTable;
}
}
beammp_debug("Running script"); beammp_debug("Running script");
sol::state_view StateView(mState); sol::state_view StateView(mState);
auto Res = StateView.safe_script(*S.first, sol::script_pass_on_error); auto Res = StateView.safe_script(*S.first, sol::script_pass_on_error);
@ -365,6 +393,11 @@ void TLuaEngine::StateThreadData::operator()() {
} }
} }
void TLuaEngine::StateThreadData::AddPath(const fs::path& Path) {
std::unique_lock Lock(mPathsMutex);
mPaths.push(Path);
}
void TLuaResult::WaitUntilReady() { void TLuaResult::WaitUntilReady() {
while (!Ready) { while (!Ready) {
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));