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