Continue Lua Rewrite

This commit is contained in:
Lion Kortlepel
2021-09-16 03:21:00 +02:00
parent c309fa28c6
commit ba0678dade
12 changed files with 215 additions and 39 deletions

View File

@@ -2,6 +2,8 @@
#include "Common.h"
#include "Compat.h"
#include "TLuaEngine.h"
#include <ctime>
#include <sstream>
@@ -55,13 +57,8 @@ TConsole::TConsole() {
Application::GracefullyShutdown();
} else if (cmd == "clear" || cmd == "cls") {
// TODO: clear screen
mLuaEngine.EnqueueScript(mStateId, std::make_shared<std::string>(cmd));
} else {
/*if (mLuaConsole) {
mLuaConsole->Execute(cmd);
} else {
error("Lua subsystem not yet initialized, please wait a few seconds and try again");
} BROKEN
*/
}
};
}
@@ -71,11 +68,11 @@ void TConsole::Write(const std::string& str) {
mCommandline.write(ToWrite);
// TODO write to logfile, too
}
/* BROKEN
void TConsole::InitializeLuaConsole(TLuaEngine& Engine) {
mLuaConsole = std::make_unique<TLuaFile>(Engine, true);
}
*/
void TConsole::WriteRaw(const std::string& str) {
mCommandline.write(str);
}
void TConsole::InitializeLuaConsole(TLuaEngine& Engine) {
Engine.EnsureStateExists(mStateId, "<>");
}

View File

@@ -1,5 +1,16 @@
#include "TLuaEngine.h"
#include "CustomAssert.h"
#include "TLuaPlugin.h"
#include <chrono>
#include <random>
static std::mt19937_64 MTGen64;
static TLuaStateId GenerateUniqueStateId() {
auto Time = std::chrono::high_resolution_clock::now().time_since_epoch();
return std::to_string(MTGen64()) + std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(Time).count());
}
TLuaEngine::TLuaEngine(TServer& Server, TNetwork& Network)
: mNetwork(Network)
@@ -18,27 +29,114 @@ TLuaEngine::TLuaEngine(TServer& Server, TNetwork& Network)
mThread.join();
}
});
Start();
}
void TLuaEngine::operator()() {
RegisterThread("LuaEngine");
// lua engine main thread
CollectPlugins();
while (!mShutdown) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void TLuaEngine::EnqueueScript(TLuaStateId StateID, const std::shared_ptr<std::string>& Script) {
std::unique_lock Lock(mLuaStatesMutex);
mLuaStates.at(StateID)->EnqueueScript(Script);
}
void TLuaEngine::CollectPlugins() {
for (const auto& dir : fs::directory_iterator(mResourceServerPath)) {
auto path = dir.path();
path = fs::relative(path);
if (!dir.is_directory()) {
beammp_error("\"" + dir.path().string() + "\" is not a directory, skipping");
for (const auto& Dir : fs::directory_iterator(mResourceServerPath)) {
auto Path = Dir.path();
Path = fs::relative(Path);
if (!Dir.is_directory()) {
beammp_error("\"" + Dir.path().string() + "\" is not a directory, skipping");
} else {
beammp_debug("found plugin directory: " + path.string());
beammp_debug("found plugin directory: " + Path.string());
TLuaPluginConfig Config { GenerateUniqueStateId() };
FindAndParseConfig(Path, Config);
InitializePlugin(Path, Config);
}
}
}
void TLuaEngine::InitializePlugin(const fs::path& folder) {
beammp_assert(fs::exists(folder));
beammp_assert(fs::is_directory(folder));
void TLuaEngine::InitializePlugin(const fs::path& Folder, const TLuaPluginConfig& Config) {
beammp_assert(fs::exists(Folder));
beammp_assert(fs::is_directory(Folder));
TLuaPlugin Plugin(*this, Config);
std::unique_lock Lock(mLuaStatesMutex);
EnsureStateExists(Config.StateId, Folder.stem().string());
}
void TLuaEngine::FindAndParseConfig(const fs::path& Folder, TLuaPluginConfig& Config) {
auto ConfigFile = Folder / TLuaPluginConfig::FileName;
if (fs::exists(ConfigFile) && fs::is_regular_file(ConfigFile)) {
beammp_debug("\"" + ConfigFile.string() + "\" found");
// TODO use toml11 here to parse it
try {
auto Data = toml::parse(ConfigFile);
if (Data.contains("LuaStateID")) {
auto ID = toml::find<std::string>(Data, "LuaStateID");
if (!ID.empty()) {
beammp_debug("Plugin \"" + Folder.string() + "\" specified it wants LuaStateID \"" + ID + "\"");
Config.StateId = ID;
} else {
beammp_debug("LuaStateID empty, using randomized state ID");
}
}
} catch (const std::exception& e) {
beammp_error(Folder.string() + ": " + e.what());
}
}
}
void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name) {
if (mLuaStates.find(StateId) == mLuaStates.end()) {
beammp_debug("Creating lua state for state id \"" + StateId + "\"");
auto DataPtr = std::make_unique<StateThreadData>(Name, mShutdown);
mLuaStates[StateId] = std::move(DataPtr);
}
}
TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomic_bool& Shutdown)
: mName(Name)
, mShutdown(Shutdown) {
mState.open_libraries(sol::lib::base);
Start();
}
void TLuaEngine::StateThreadData::EnqueueScript(const std::shared_ptr<std::string>& Script) {
beammp_debug("enqueuing script into \"" + mName + "\"");
std::unique_lock Lock(mStateExecuteQueueMutex);
mStateExecuteQueue.push(Script);
}
void TLuaEngine::StateThreadData::operator()() {
RegisterThreadAuto();
while (!mShutdown) {
std::unique_lock Lock(mStateExecuteQueueMutex);
if (mStateExecuteQueue.empty()) {
Lock.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
} else {
auto S = mStateExecuteQueue.front();
mStateExecuteQueue.pop();
Lock.unlock();
mState.do_string(*S);
}
}
}
TLuaEngine::StateThreadData::~StateThreadData() {
if (mThread.joinable()) {
mThread.join();
}
}
// AHHH
std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr<TLuaArg> arg, bool Wait) {
}
void TLuaArg::PushArgs(lua_State* State) {
}

View File

@@ -0,0 +1,10 @@
#include "TLuaPlugin.h"
#include <chrono>
#include <functional>
#include <random>
#include <utility>
TLuaPlugin::TLuaPlugin(TLuaEngine& Engine, const TLuaPluginConfig& Config)
: mConfig(Config)
, mEngine(Engine) {
}

View File

@@ -2,6 +2,7 @@
#include "Client.h"
#include <CustomAssert.h>
#include <Http.h>
#include <TLuaPlugin.h>
#include <array>
#include <cstring>
@@ -43,7 +44,7 @@ void TNetwork::UDPServerMain() {
#ifdef WIN32
WSADATA data;
if (WSAStartup(514, &data)) {
error(("Can't start Winsock!"));
beammp_error(("Can't start Winsock!"));
//return;
}
#endif // WIN32
@@ -104,7 +105,7 @@ void TNetwork::TCPServerMain() {
#ifdef WIN32
WSADATA wsaData;
if (WSAStartup(514, &wsaData)) {
error("Can't start Winsock!");
beammp_error("Can't start Winsock!");
return;
}
#endif // WIN32
@@ -621,7 +622,7 @@ void TNetwork::SyncResources(TClient& c) {
}
#ifndef DEBUG
} catch (std::exception& e) {
error("Exception! : " + std::string(e.what()));
beammp_error("Exception! : " + std::string(e.what()));
c.SetStatus(-1);
}
#endif

View File

@@ -3,7 +3,7 @@
#include "Common.h"
#include "TNetwork.h"
#include "TPPSMonitor.h"
#include <TLuaFile.h>
#include <TLuaPlugin.h>
#include <any>
#include <sstream>

View File

@@ -66,7 +66,7 @@ int main(int argc, char** argv) {
TNetwork Network(Server, PPSMonitor, ResourceManager);
TLuaEngine LuaEngine(Server, Network);
PPSMonitor.SetNetwork(Network);
Application::Console().InitializeLuaConsole(LuaEngine);
// BROKEN Application::Console().InitializeLuaConsole(LuaEngine);
// TODO: replace
while (!Shutdown) {