aboutsummaryrefslogtreecommitdiff
path: root/deep_test/deep_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--deep_test/deep_test.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/deep_test/deep_test.cpp b/deep_test/deep_test.cpp
new file mode 100644
index 0000000..3467939
--- /dev/null
+++ b/deep_test/deep_test.cpp
@@ -0,0 +1,259 @@
1#include "lanes/src/deep.h"
2#include "lanes/src/compat.h"
3
4#include <malloc.h>
5#include <memory.h>
6#include <assert.h>
7
8// ################################################################################################
9
10// a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code.
11struct MyDeepUserdata : public DeepPrelude // Deep userdata MUST start with a DeepPrelude
12{
13 lua_Integer val{ 0 };
14};
15
16// ################################################################################################
17
18[[nodiscard]] static void* deep_test_id(lua_State* L, DeepOp op_)
19{
20 switch( op_)
21 {
22 case DeepOp::New:
23 {
24 MyDeepUserdata* deep_test = new MyDeepUserdata;
25 return deep_test;
26 }
27
28 case DeepOp::Delete:
29 {
30 MyDeepUserdata* deep_test = static_cast<MyDeepUserdata*>(lua_touserdata( L, 1));
31 delete deep_test;
32 return nullptr;
33 }
34
35 case DeepOp::Metatable:
36 {
37 luaL_getmetatable( L, "deep"); // mt
38 return nullptr;
39 }
40
41 case DeepOp::Module:
42 return (void*)"deep_test";
43
44 default:
45 {
46 return nullptr;
47 }
48 }
49}
50
51// ################################################################################################
52
53[[nodiscard]] static int deep_set(lua_State* L)
54{
55 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
56 lua_Integer i = lua_tointeger( L, 2);
57 self->val = i;
58 return 0;
59}
60
61// ################################################################################################
62
63// won't actually do anything as deep userdata don't have uservalue slots
64[[nodiscard]] static int deep_setuv(lua_State* L)
65{
66 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
67 int uv = (int) luaL_optinteger(L, 2, 1);
68 lua_settop( L, 3);
69 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0);
70 return 1;
71}
72
73// ################################################################################################
74
75// won't actually do anything as deep userdata don't have uservalue slots
76[[nodiscard]] static int deep_getuv(lua_State* L)
77{
78 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
79 int uv = (int) luaL_optinteger(L, 2, 1);
80 lua_getiuservalue( L, 1, uv);
81 return 1;
82}
83
84// ################################################################################################
85
86[[nodiscard]] static int deep_tostring(lua_State* L)
87{
88 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
89 lua_pushfstring(L, "%p:deep(%d)", lua_topointer(L, 1), self->val);
90 return 1;
91}
92
93// ################################################################################################
94
95[[nodiscard]] static int deep_gc(lua_State* L)
96{
97 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
98 return 0;
99}
100
101// ################################################################################################
102
103static luaL_Reg const deep_mt[] =
104{
105 { "__tostring", deep_tostring},
106 { "__gc", deep_gc},
107 { "set", deep_set},
108 { "setuv", deep_setuv},
109 { "getuv", deep_getuv},
110 { nullptr, nullptr }
111};
112
113// ################################################################################################
114
115int luaD_new_deep( lua_State* L)
116{
117 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 0)) };
118 // no additional parameter to luaG_newdeepuserdata!
119 lua_settop(L, 0);
120 return luaG_newdeepuserdata(Dest{ L }, deep_test_id, nuv);
121}
122
123// ################################################################################################
124// ################################################################################################
125
126struct MyClonableUserdata
127{
128 lua_Integer val;
129};
130
131// ################################################################################################
132
133[[nodiscard]] static int clonable_set(lua_State* L)
134{
135 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
136 lua_Integer i = lua_tointeger(L, 2);
137 self->val = i;
138 return 0;
139}
140
141// ################################################################################################
142
143[[nodiscard]] static int clonable_setuv(lua_State* L)
144{
145 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
146 int uv = (int) luaL_optinteger(L, 2, 1);
147 lua_settop( L, 3);
148 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0);
149 return 1;
150}
151
152// ################################################################################################
153
154[[nodiscard]] static int clonable_getuv(lua_State* L)
155{
156 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
157 int uv = (int) luaL_optinteger(L, 2, 1);
158 lua_getiuservalue( L, 1, uv);
159 return 1;
160}
161
162// ################################################################################################
163
164[[nodiscard]] static int clonable_tostring(lua_State* L)
165{
166 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
167 lua_pushfstring(L, "%p:clonable(%d)", lua_topointer(L, 1), self->val);
168 return 1;
169}
170
171// ################################################################################################
172
173[[nodiscard]] static int clonable_gc(lua_State* L)
174{
175 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
176 return 0;
177}
178
179// ################################################################################################
180
181// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code.
182[[nodiscard]] static int clonable_lanesclone(lua_State* L)
183{
184 switch( lua_gettop( L))
185 {
186 case 3:
187 {
188 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
189 MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2));
190 size_t len = lua_tointeger( L, 3);
191 assert( len == sizeof(MyClonableUserdata));
192 *self = *from;
193 }
194 return 0;
195
196 default:
197 (void) luaL_error( L, "Lanes called clonable_lanesclone with unexpected parameters");
198 }
199 return 0;
200}
201
202// ################################################################################################
203
204static luaL_Reg const clonable_mt[] =
205{
206 { "__tostring", clonable_tostring},
207 { "__gc", clonable_gc},
208 { "__lanesclone", clonable_lanesclone},
209 { "set", clonable_set},
210 { "setuv", clonable_setuv},
211 { "getuv", clonable_getuv},
212 { nullptr, nullptr }
213};
214
215// ################################################################################################
216
217int luaD_new_clonable( lua_State* L)
218{
219 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 1)) };
220 lua_newuserdatauv( L, sizeof(MyClonableUserdata), nuv);
221 luaL_setmetatable( L, "clonable");
222 return 1;
223}
224
225// ################################################################################################
226// ################################################################################################
227
228static luaL_Reg const deep_module[] =
229{
230 { "new_deep", luaD_new_deep},
231 { "new_clonable", luaD_new_clonable},
232 { nullptr, nullptr }
233};
234
235// ################################################################################################
236
237LANES_API int luaopen_deep_test(lua_State* L)
238{
239 luaL_newlib( L, deep_module); // M
240
241 // preregister the metatables for the types we can instantiate so that Lanes can know about them
242 if( luaL_newmetatable( L, "clonable")) // M mt
243 {
244 luaL_setfuncs( L, clonable_mt, 0);
245 lua_pushvalue(L, -1); // M mt mt
246 lua_setfield(L, -2, "__index"); // M mt
247 }
248 lua_setfield(L, -2, "__clonableMT"); // M
249
250 if( luaL_newmetatable( L, "deep")) // mt
251 {
252 luaL_setfuncs( L, deep_mt, 0);
253 lua_pushvalue(L, -1); // mt mt
254 lua_setfield(L, -2, "__index"); // mt
255 }
256 lua_setfield(L, -2, "__deepMT"); // M
257
258 return 1;
259}