Engine
Raylib based game framework
Loading...
Searching...
No Matches
LuaManager.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Lua/MyLua.hpp"
4
5#include "entt/entt.hpp"
6
7#include <functional>
8#include <mutex>
9#include <optional>
10#include <queue>
11#include <string>
12#include <unordered_map>
13
18
23{
25 sol::environment environment;
26
28 std::string directory;
29
31 bool enabled = true;
32};
33
45class LuaManager
46{
47public:
48
59 template <typename Event>
60 void RegisterReceiveEvent(entt::dispatcher& dispatcher)
61 {
62 if (!Lua::TypeExists<Event>(lua))
63 {
64 Event event;
65 event.LuaRegister(lua);
66 }
67
68 dispatcher.sink<Event>().template connect<&LuaManager::OnEvent<Event>>(this);
69 }
70
82 template <typename Event>
83 void RegisterSendEvent(entt::dispatcher& dispatcher)
84 {
85 if (!Lua::TypeExists<Event>(lua))
86 {
87 Event event;
88 event.LuaRegister(lua);
89 };
90
91 std::string functionName = "Trigger" + DemangleWithoutNamespace<Event>() + "Event";
92
93 if (!Lua::FunctionExists(lua, functionName.c_str()))
94 {
95 Lua::RegisterFunction(lua, functionName.c_str(), [this, &dispatcher](Event event)
96 {
97 std::unique_lock lock(m_mutex);
98 m_pendingEvents.push([&dispatcher, e = std::move(event)]() mutable
99 {
100 dispatcher.trigger<Event>(std::move(e));
101 });
102 });
103 }
104 }
105
115 bool LoadScript(const std::string& path);
116
124 void RemoveScript(const std::string& path);
125
132 bool IsScriptLoaded(const std::string& path);
133
141 void EnableScript(const std::string& path);
142
151 void DisableScript(const std::string& path);
152
161 std::optional<sol::environment> GetScriptEnvironment(const std::string& path);
162
169 void ReloadScripts();
170
172 sol::state lua;
173
174private:
175
176 LuaManager();
177
185 void Update(const float deltaT);
186
196 template <typename Event>
197 void OnEvent(const Event& event)
198 {
199 // Copy event and queue the dispatch so we don't call into Lua while holding
200 // the mutex — avoids deadlock if a script triggers another event.
201 std::unique_lock lock(m_mutex);
202
203 for (auto& [path, script] : m_scripts)
204 {
205 if (script.enabled)
206 {
207 std::string functionName = "On" + DemangleWithoutNamespace<Event>() + "Event";
208 Event copy = event;
209 m_pendingEvents.push([&script, functionName, copy]()
210 {
211 Lua::CallFunction<false>(script.environment, functionName.c_str(), copy);
212 });
213 }
214 }
215 }
216
217 std::mutex m_mutex;
218
219 std::unordered_map<std::string, LuaScript> m_scripts;
220
221 std::queue<std::function<void()>> m_pendingEvents;
222
223 friend class Engine;
224};
Core engine.
Definition Engine.hpp:90
void RegisterReceiveEvent(entt::dispatcher &dispatcher)
Connects the dispatcher so all loaded scripts receive events of type Event.
Definition LuaManager.hpp:60
sol::state lua
The shared Lua state; all scripts execute within this state.
Definition LuaManager.hpp:172
void RegisterSendEvent(entt::dispatcher &dispatcher)
Exposes a global Lua function that fires an event on the dispatcher.
Definition LuaManager.hpp:83
Holds the runtime state of a single Lua script.
Definition LuaManager.hpp:23
bool enabled
When false the script's Update function is not called each frame.
Definition LuaManager.hpp:31
std::string directory
Directory the script was loaded from; used to resolve sandboxed requires.
Definition LuaManager.hpp:28
sol::environment environment
Isolated Lua environment; each script gets its own globals table.
Definition LuaManager.hpp:25