nngn
Loading...
Searching...
No Matches
state.h
Go to the documentation of this file.
1
66#ifndef NNGN_LUA_STATE_H
67#define NNGN_LUA_STATE_H
68
69#include <tuple>
70#include <utility>
71#include <vector>
72
73#include "math/math.h"
74#include "utils/fixed_string.h"
75#include "utils/pp.h"
76#include "utils/utils.h"
77
78#include "lua.h"
79#include "utils.h"
80
81struct lua_State;
82
83namespace nngn::lua {
84
86struct alloc_info;
87
89public:
91 state_view(void) = default;
93 state_view(lua_State *L_) : L{L_} {}
95 operator lua_State*(void) const { return this->L; }
103 bool init(alloc_info *i = nullptr);
104 /* Disowns the current reference and returns a non-owning view to it. */
105 state_view release(void) { return std::exchange(this->L, {}); }
107 void destroy(void);
109 int top(void) const { return lua_gettop(*this); }
111 type get_type(int i) const;
113 template<typename T = lua_Integer> T len(int i) const;
115 std::pair<lua_Alloc, void*> allocator(void) const;
117 global_table globals(void) const;
119 void set_top(int i) const { lua_settop(*this, i); }
121 void set_meta_table(auto &&mt, int i);
123 void print_stack(void) const { nngn::lua::print_stack(*this); }
125 void print_traceback(void) const { nngn::lua::print_traceback(*this); }
130 bool doarg(std::string_view s) const;
132 bool dofile(std::string_view filename) const;
134 bool dostring(std::string_view src) const;
136 bool dofunction(std::string_view f) const;
138 template<typename T> T *new_user_data(int nv = 0) const;
140 template<typename T> table new_user_type(void) const;
142 table create_table(void) const;
144 table create_table(int narr, int nrec) const;
146 template<typename T = value_view> T get(int i) const;
148 template<typename T = value_view> T push(auto &&x) const;
150 void pop(int n = 1) const { lua_pop(*this, n); }
152 void remove(int i) const { lua_remove(*this, i); }
154 void call(auto &&f, auto &&...args) const;
156 int pcall(auto &&h, auto &&f, auto &&...args) const;
158 std::pair<value, std::string_view> to_string(int i) const;
160 bool heartbeat(void) const;
161protected:
162 lua_State *L = nullptr;
163};
164
169 state(void) = default;
171 explicit state(lua_State *L_) : state_view{L_} {}
173 state(state &&rhs) noexcept { *this = std::move(rhs); }
175 state &operator=(state &&rhs) noexcept;
177 ~state(void) { this->destroy(); }
178};
179
180template<typename T>
182 return stack_get<T>::get(L, i);
183}
184
185template<typename T = value_view>
187 [[maybe_unused]] const auto i = lua.top() + 1;
188 stack_push<>::push(lua, FWD(v));
189 if constexpr(!std::is_void_v<T>)
190 return lua.get<T>(i);
191}
192
193inline type state_view::get_type(int i) const {
194 const auto ret = static_cast<type>(lua_type(*this, i));
195 if constexpr(Platform::debug)
196 if(std::find(begin(types), end(types), ret) == end(types)) {
198 Log::l() << "invalid type at index " << i << '\n';
199 }
200 return ret;
201}
202
203template<typename T>
204T state_view::len(int i) const {
205 lua_len(*this, i);
207 return this->get<T>(this->top());
208}
209
210inline std::pair<lua_Alloc, void*> state_view::allocator(void) const {
211 void *p = nullptr;
212 auto *const f = lua_getallocf(*this, &p);
213 return {f, p};
214}
215
216void state_view::set_meta_table(auto &&mt, int i) {
217 this->push(FWD(mt));
218 lua_setmetatable(*this, i);
219}
220
221template<typename T>
223 return static_cast<T*>(
225 lua_newuserdatauv(*this, sizeof(T) + alignof(T), nv),
226 alignof(T)));
227}
228
229template<typename T>
230T state_view::get(int i) const {
231 return lua::get<T>(*this, i);
232}
233
234template<typename T>
235T state_view::push(auto &&x) const {
236 return lua::push<T>(*this, FWD(x));
237}
238
239void state_view::call(auto &&f, auto &&...args) const {
240 [[maybe_unused]] const int i = this->top() + 1;
241 if constexpr(Platform::debug)
242 lua_pushcfunction(*this, msgh);
243 lua::push(*this, FWD(f));
244 (..., lua::push(*this, FWD(args)));
245 constexpr auto n_args = static_cast<int>(sizeof...(args));
246 if constexpr(Platform::debug) {
247 lua_pcall(*this, n_args, LUA_MULTRET, i);
248 lua_remove(*this, i);
249 } else
250 lua_call(*this, n_args, LUA_MULTRET);
251}
252
253int state_view::pcall(auto &&h, auto &&f, auto &&...args) const {
254 const int h_idx = h.index();
255 assert(h_idx <= this->top());
256 lua::push(*this, FWD(f));
257 (..., lua::push(*this, FWD(args)));
258 constexpr auto n_args = static_cast<int>(sizeof...(args));
259 return lua_pcall(*this, n_args, LUA_MULTRET, h_idx);
260}
261
262inline state &state::operator=(state &&rhs) noexcept {
263 state_view::operator=(std::move(rhs).release());
264 return *this;
265}
266
267template<>
269 static state_view get(lua_State *L, int) { return L; }
270};
271
272}
273
274#endif
static std::ostream & l()
Definition: log.cpp:56
static void * align_ptr(void *p, std::size_t a)
Definition: math.h:559
Pops n values from the Lua stack at scope exit.
Definition: utils.h:24
Table interface to the global environment.
Definition: table.h:181
Definition: state.h:88
T push(auto &&x) const
Pushes a value onto the stack.
Definition: state.h:235
T get(int i) const
Reads a value from the stack.
Definition: state.h:230
void pop(int n=1) const
Definition: state.h:150
void call(auto &&f, auto &&...args) const
Function call, protected in debug mode.
Definition: state.h:239
lua_State * L
Definition: state.h:162
bool dostring(std::string_view src) const
Definition: state.cpp:83
table new_user_type(void) const
Registers a new user type and returns its meta table.
Definition: table.h:356
void set_top(int i) const
Definition: state.h:119
global_table globals(void) const
Definition: table.h:367
bool dofunction(std::string_view f) const
Executes the global function f.
Definition: state.cpp:95
T * new_user_data(int nv=0) const
Definition: state.h:222
void destroy(void)
Destroys the associated lua_State.
Definition: state.cpp:56
state_view release(void)
Definition: state.h:105
bool dofile(std::string_view filename) const
Definition: state.cpp:71
int top(void) const
Definition: state.h:109
std::pair< value, std::string_view > to_string(int i) const
Pushes a string representation of a value onto the stack.
Definition: value.h:94
bool doarg(std::string_view s) const
Calls dofile or dostring depending on s[0] == '@'.
Definition: state.cpp:67
bool init(alloc_info *i=nullptr)
Initializes a new state.
Definition: state.cpp:39
std::pair< lua_Alloc, void * > allocator(void) const
Get memory allocator data.
Definition: state.h:210
int pcall(auto &&h, auto &&f, auto &&...args) const
Protected function call with error handler.
Definition: state.h:253
void print_stack(void) const
Non-static version.
Definition: state.h:123
void set_meta_table(auto &&mt, int i)
Definition: state.h:216
void print_traceback(void) const
Non-static version.
Definition: state.h:125
state_view(void)=default
Empty state, must call init before any other function is called.
bool heartbeat(void) const
Execute the global heartbeat function.
Definition: state.cpp:106
T len(int i) const
Definition: state.h:204
type get_type(int i) const
Definition: state.h:193
table create_table(void) const
Creates a table and pushes it on the stack.
Definition: table.h:371
void remove(int i) const
Definition: state.h:152
state_view(lua_State *L_)
Wraps an existing luaState.
Definition: state.h:93
assert
Definition: debug.lua:3
end
Definition: entities.lua:9
#define NNGN_LOG_CONTEXT_CF(c)
Definition: log.h:11
nngn::lua::table_view alloc_info(nngn::lua::state_view lua)
Definition: lua_state.cpp:10
Definition: alloc.cpp:100
void print_stack(lua_State *L)
Logs the current data stack.
Definition: lua.cpp:26
int msgh(lua_State *L)
Default message handler for lua_pcall.
Definition: lua.cpp:15
T push(nngn::lua::state_view lua, auto &&v)
Definition: state.h:186
type
LUA_T* constants as a scoped enumeration.
Definition: lua.h:77
void print_traceback(lua_State *L)
Logs the current call stack.
Definition: lua.cpp:59
constexpr const R * begin(const T< R > &v)
Definition: vec.h:207
get
Definition: camera.lua:36
release
Definition: input.lua:33
function f()) end
v[1]
Definition: math.lua:19
mt
Definition: strict.lua:4
static constexpr bool debug
Definition: platform.h:26
Definition: types.h:32
Tracks state allocations.
Definition: alloc.h:29
static state_view get(lua_State *L, int)
Definition: state.h:269
Reads a value from the Lua stack.
Definition: lua.h:117
Pushes a value onto the Lua stack.
Definition: lua.h:119
Owning lua_State wrapper.
Definition: state.h:166
state(state &&rhs) noexcept
Transfers the lua_State from another object.
Definition: state.h:173
~state(void)
Destroys the associated lua_State.
Definition: state.h:177
state & operator=(state &&rhs) noexcept
Transfers the lua_State from another object.
Definition: state.h:262
Owning reference to a table on the stack, popped when destroyed.
Definition: table.h:172
std::chrono::seconds s
Definition: timing.cpp:6
#define NNGN_NO_COPY(x)
Definition: utils.h:35
#define FWD(...)
Definition: utils.h:18
#define NNGN_ANON_DECL(...)
Definition: utils.h:53