Engine
Raylib based game framework
Loading...
Searching...
No Matches
MyLua.hpp
1#pragma once
2
3#define SOL_NO_EXCEPTIONS 1
4#include "sol/sol.hpp"
5
6#include "Log/Log.hpp"
7
8inline void SanitizeEnvironment(sol::state& lua, sol::environment& env)
9{
10 env["collectgarbage"] = sol::nil;
11 env["dofile"] = sol::nil;
12 env["loadfile"] = sol::nil;
13 env["module"] = sol::nil;
14 env["load"] = sol::nil;
15 // env["require"] = sol::nil;
16 // env["package"] = sol::nil;
17 env["getfenv"] = sol::nil;
18 env["setfenv"] = sol::nil;
19 env["newproxy"] = sol::nil;
20 env["rawset"] = sol::nil;
21 env["rawget"] = sol::nil;
22
23 sol::table metatable = lua.create_table();
24 metatable["__index"] = lua.globals();
25 metatable["__newindex"] = [](sol::table self, sol::object key, sol::object value)
26 {
27 self.raw_set(key, value);
28 };
29 metatable[sol::metatable_key] = sol::nil;
30 metatable["__metatable"] = "locked";
31
32 env[sol::metatable_key] = metatable;
33 env["_G"] = env;
34 env["_ENV"] = env;
35}
36
37namespace Lua
38{
39 inline sol::environment CreateEnvironment(sol::state& lua, const bool globals)
40 {
41 if (globals)
42 {
43 sol::environment env = sol::environment(lua, sol::create, lua.globals());
44
45 SanitizeEnvironment(lua, env);
46
47 return env;
48 }
49
50 sol::environment env(lua, sol::create);
51
52 SanitizeEnvironment(lua, env);
53
54 return env;
55 }
56
57 inline bool LoadFile(sol::state& lua, const char* name)
58 {
59 sol::protected_function_result result = lua.safe_script_file(name);
60
61 if (result.valid())
62 {
63 return true;
64 }
65
66 sol::error e = result;
67 LogColor(LOG_YELLOW, "Failed to load lua file ", name, " with error: ", e.what());
68
69 return false;
70 }
71
72 inline bool LoadFile(sol::state& lua, sol::environment& env, const char* name)
73 {
74 sol::protected_function_result result = lua.safe_script_file(name, env);
75
76 if (result.valid())
77 {
78 return true;
79 }
80
81 sol::error e = result;
82 LogColor(LOG_YELLOW, "Failed to load lua file ", name, " with error: ", e.what());
83
84 return false;
85 }
86
87 template <typename T>
88 std::optional<T> GetValue(sol::state& lua, const char* key)
89 {
90 sol::object object = lua[key];
91 if (object.is<T>())
92 {
93 return object.as<T>();
94 }
95
96 LogColor(LOG_YELLOW, "Type mismatch for: ", key, " expected ", Demangle<T>());
97
98 return std::nullopt;
99 }
100
101 template <typename T>
102 std::optional<T> GetValue(sol::environment& env, const char* key)
103 {
104 sol::object object = env[key];
105 if (object.is<T>())
106 {
107 return object.as<T>();
108 }
109
110 LogColor(LOG_YELLOW, "Type mismatch for: ", key, " expected ", Demangle<T>());
111
112 return std::nullopt;
113 }
114
115 template <typename O, typename T>
116 std::optional<T> GetValueObjectValue(sol::state& lua, const char* objectKey, const char* key)
117 {
118 sol::object object = lua[objectKey];
119 if (object.is<O>())
120 {
121 sol::object member = object.as<sol::table>()[key];
122 if (member.is<T>())
123 {
124 return member.as<T>();
125 }
126
127 LogColor(LOG_YELLOW, "Type mismatch for: ", key, " expected ", Demangle<T>());
128
129 return std::nullopt;
130 }
131
132 LogColor(LOG_YELLOW, "Type mismatch for: ", objectKey, " expected ", Demangle<O>());
133
134 return std::nullopt;
135 }
136
137 template <typename O, typename T>
138 std::optional<T> GetValueObjectValue(sol::environment& env, const char* objectKey, const char* key)
139 {
140 sol::object object = env[objectKey];
141 if (object.is<O>())
142 {
143 sol::object member = object.as<sol::table>()[key];
144 if (member.is<T>())
145 {
146 return member.as<T>();
147 }
148
149 LogColor(LOG_YELLOW, "Type mismatch for: ", key, " expected ", Demangle<T>());
150
151 return std::nullopt;
152 }
153
154 LogColor(LOG_YELLOW, "Type mismatch for: ", objectKey, " expected ", Demangle<O>());
155
156 return std::nullopt;
157 }
158
159 template <typename T>
160 bool TypeExists(sol::state& lua)
161 {
162 std::string typeName = DemangleWithoutNamespace<T>();
163
164 sol::object obj = lua[typeName];
165 return obj.valid();
166 }
167
168 template <typename T>
169 bool TypeExists(sol::environment& env)
170 {
171 std::string typeName = DemangleWithoutNamespace<T>();
172
173 sol::object obj = env[typeName];
174 return obj.valid();
175 }
176
177 inline bool ObjectExists(sol::state& lua, const char* key)
178 {
179 sol::object obj = lua[key];
180 return obj.valid();
181 }
182
183 inline bool ObjectExists(sol::environment& env, const char* key)
184 {
185 sol::object obj = env[key];
186 return obj.valid();
187 }
188
189 inline bool FunctionExists(sol::state& lua, const char* key)
190 {
191 sol::object obj = lua[key];
192 return obj.valid() && obj.is<sol::function>();
193 }
194
195 inline bool FunctionExists(sol::environment& env, const char* key)
196 {
197 sol::object obj = env[key];
198 return obj.valid() && obj.is<sol::function>();
199 }
200
201 template <bool log = true, typename... Args>
202 bool CallFunction(sol::state& lua, const char* key, Args&&... args)
203 {
204 sol::protected_function function = lua[key];
205 if (function)
206 {
207 sol::protected_function_result result = function(std::forward<Args>(args)...);
208 if (result.valid())
209 {
210 return true;
211 }
212
213 sol::error e = result;
214
215 LogColor(LOG_YELLOW, "Invalid call of function ", key, " with error: ", e.what());
216
217 return false;
218 }
219
220 if (log)
221 {
222 LogColor(LOG_YELLOW, "Function ", key, " does not exists");
223 }
224
225 return false;
226 }
227
228 template <bool log = true, typename... Args>
229 bool CallFunction(sol::environment& env, const char* key, Args&&... args)
230 {
231 sol::protected_function function = env[key];
232 if (function)
233 {
234 sol::protected_function_result result = function(std::forward<Args>(args)...);
235 if (result.valid())
236 {
237 return true;
238 }
239
240 sol::error e = result;
241
242 LogColor(LOG_YELLOW, "Invalid call of function ", key, " with error: ", e.what());
243
244 return false;
245 }
246
247 if (log)
248 {
249 LogColor(LOG_YELLOW, "Function ", key, " does not exists");
250 }
251
252 return false;
253 }
254
255 template <typename T, typename... Args>
256 std::optional<T> CallFunctionWithReturn(sol::state& lua, const char* key, Args&&... args)
257 {
258 sol::protected_function function = lua[key];
259 if (function)
260 {
261 sol::protected_function_result result = function(std::forward<Args>(args)...);
262 if (result.valid())
263 {
264 sol::object object = result.get<sol::object>();
265 if (object.is<T>())
266 {
267 return object.as<T>();
268 }
269
270 LogColor(LOG_YELLOW, "Type mismatch for: ", key, " expected: ", Demangle<T>());
271
272 return std::nullopt;
273 }
274
275 sol::error e = result;
276 LogColor(LOG_YELLOW, "Invalid call of function: ", key, " with error: ", e.what());
277
278 return std::nullopt;
279 }
280
281 LogColor(LOG_YELLOW, "Function ", key, " does not exists");
282
283 return std::nullopt;
284 }
285
286 template <typename T, typename... Args>
287 std::optional<T> CallFunctionWithReturn(sol::environment& env, const char* key, Args&&... args)
288 {
289 sol::protected_function function = env[key];
290 if (function)
291 {
292 sol::protected_function_result result = function(std::forward<Args>(args)...);
293 if (result.valid())
294 {
295 sol::object object = result.get<sol::object>();
296 if (object.is<T>())
297 {
298 return object.as<T>();
299 }
300
301 LogColor(LOG_YELLOW, "Type mismatch for: ", key, " expected: ", Demangle<T>());
302
303 return std::nullopt;
304 }
305
306 sol::error e = result;
307 LogColor(LOG_YELLOW, "Invalid call of function: ", key, " with error: ", e.what());
308
309 return std::nullopt;
310 }
311
312 LogColor(LOG_YELLOW, "Function ", key, " does not exists");
313
314 return std::nullopt;
315 }
316
317 template <typename T>
318 void RegisterFunction(sol::state& lua, const char* key, T function)
319 {
320 lua[key] = function;
321 }
322
323 template <typename T>
324 void RegisterFunction(sol::environment& env, const char* key, T function)
325 {
326 env[key] = function;
327 }
328
329 template <typename T, typename I, typename... Args>
330 void RegisterMethod(sol::state& lua, const char* key, I& instance, T (I::*method)(Args...))
331 {
332 lua.set_function(key, method, &instance);
333 }
334
335 template <typename T, typename I, typename... Args>
336 void RegisterMethod(sol::environment& env, const char* key, I& instance, T (I::*method)(Args...))
337 {
338 env.set_function(key, method, &instance);
339 }
340
341 template <typename T, typename... Args>
342 void RegisterType(sol::state& lua, const char* name, Args&&... args)
343 {
344 lua.new_usertype<T>(name, std::forward<Args>(args)...);
345 }
346
347 template <typename T, typename... Args>
348 void RegisterType(sol::environment& env, const char* name, Args&&... args)
349 {
350 env.new_usertype<T>(name, std::forward<Args>(args)...);
351 }
352
353 template <typename T>
354 void BindObject(sol::state& lua, const char* name, T object)
355 {
356 lua[name] = object;
357 }
358
359 template <typename T>
360 void BindObject(sol::environment& env, const char* name, T object)
361 {
362 env[name] = object;
363 }
364}