Simple Lua
A Simple C++ Lua Wrapper
Loading...
Searching...
No Matches
Runtime.hpp
1#pragma once
2
3#include <filesystem>
4
5#include "Lib.hpp"
6#include "TypeMap.hpp"
7
8#define LUA_HOT_RELOAD
9
10namespace SL
11{
12
16 struct Runtime
17 {
18 enum class ErrorCode
19 {
20 None,
21 TypeMismatch,
22 VariableDoesntExist,
23 NotFunction,
24 FunctionError
25 };
26
27 template<typename T>
29
34 SL_SYMBOL Runtime(const std::string& filename);
35
36 SL_SYMBOL Runtime(Runtime&& r);
37 Runtime(const Runtime&) = delete;
38
39 SL_SYMBOL ~Runtime();
40
47 template<typename... Libraries>
48 static Runtime create(const std::string& filename);
49
57 SL_SYMBOL Result<void>
59 const std::string& table_name,
60 const std::string& func_name,
61 SL::Function function);
62
69 template<typename T>
70 SL_SYMBOL Result<T>
71 getGlobal(const std::string& name);
72
73 // TODO: Need to load globals in datastructure so that the file can be hot-reloaded
74 // when the lua state is reloaded, the globals that have been loaded in need to be
75 // transferred
76
84 template<typename T>
85 SL_SYMBOL Result<void>
86 setGlobal(const std::string& name, const T& value);
87
96 template<typename... Return, typename... Args>
97 inline Result<std::tuple<Return...>>
99 const std::string& name,
100 Args&&... args);
101
102 SL_SYMBOL bool good() const;
103 SL_SYMBOL operator bool() const;
104
105
106 const auto& filename() const { return _filename; }
107
108 private:
109 SL_SYMBOL void _pop(std::size_t n = 1) const;
110 SL_SYMBOL int _call_func(uint32_t args, uint32_t ret) const;
111
112 State L;
113 bool _good;
114 std::string _filename;
115
116# ifdef LUA_HOT_RELOAD
117 std::filesystem::file_time_type _last_modified;
118# endif
119 };
120
121 template<typename... Libraries>
122 Runtime Runtime::create(const std::string& filename)
123 {
124 using namespace Util::CompileTime;
125
126 Runtime runtime(filename);
127
128 static_for<sizeof...(Libraries)>([&](auto n)
129 {
130 const std::size_t i = n;
131 using Library = NthType<i, Libraries...>;
132 static_assert(std::is_base_of_v<SL::Lib::Base, Library>);
133 Library().registerFunctions(runtime);
134 });
135
136 return runtime;
137 }
138
139 template<typename... Return, typename... Args>
140 Runtime::Result<std::tuple<Return...>>
142 const std::string& name,
143 Args&&... args)
144 {
145 const auto glob_res = getGlobal<SL::Function>(name);
146 if (!glob_res)
147 {
148 _pop();
149 if (glob_res.error().code() == Runtime::ErrorCode::TypeMismatch) return { Runtime::ErrorCode::NotFunction };
150 else return { glob_res.error() };
151 }
152
153 auto args_set = std::tuple(std::forward<Args>(args)...);
154 Util::CompileTime::static_for<sizeof...(args)>([&](auto n){
155 constexpr std::size_t I = n;
156 using Type = std::remove_reference_t<Util::CompileTime::NthType<I, Args...>>;
157 CompileTime::TypeMap<Type>::push(L, std::get<I>(args_set));
158 });
159
160 if (_call_func(sizeof...(Args), sizeof...(Return)) != 0) return { { ErrorCode::FunctionError, CompileTime::TypeMap<SL::String>::construct(L) } };
161
162 bool err = false;
163 auto left = sizeof...(Return);
164 auto return_vals = std::tuple<Return...>();
165 Util::CompileTime::static_for<sizeof...(Return)>([&](auto n) {
166 constexpr std::size_t I = n;
167 using Type = Util::CompileTime::NthType<I, Return...>;
169
170 if (!err)
171 {
172 if (Map::check(L))
173 {
174 std::get<I>(return_vals) = Map::construct(L);
175 left--;
176 }
177 else err = true;
178 }
179 });
180
181 SL_ASSERT(!left, "Still arguments left.");
182 if (err)
183 {
184 _pop(left);
185 return { ErrorCode::TypeMismatch };
186 }
187
188 return { std::move(return_vals) };
189 }
190
191} // SL
Definition TypeMap.hpp:19
Represents a single Lua runtime.
Definition Runtime.hpp:17
Result< std::tuple< Return... > > runFunction(const std::string &name, Args &&... args)
Invokes a Lua function from this environment.
Definition Runtime.hpp:141
static Runtime create(const std::string &filename)
Creates a runtime with the given Libraries loaded into it.
Definition Runtime.hpp:122
SL_SYMBOL Runtime(const std::string &filename)
Construct a Lua runtime from a script.
SL_SYMBOL Result< void > registerFunction(const std::string &table_name, const std::string &func_name, SL::Function function)
Registers a C++ function for use in the Lua runtime.
SL_SYMBOL Result< void > setGlobal(const std::string &name, const T &value)
Set a global variable from a value to a name.
SL_SYMBOL Result< T > getGlobal(const std::string &name)
Get a global variable by name from runtime.
Basic way to return a value or an error.
Definition Result.hpp:37