diff options
Diffstat (limited to 'deep_test/deep_test.cpp')
-rw-r--r-- | deep_test/deep_test.cpp | 260 |
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. | ||
11 | struct MyDeepUserdata | ||
12 | { | ||
13 | DeepPrelude prelude; // Deep userdata MUST start with this header | ||
14 | lua_Integer val{ 0 }; | ||
15 | }; | ||
16 | |||
17 | // ################################################################################################ | ||
18 | |||
19 | static 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 | |||
54 | static 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 | ||
65 | static 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 | ||
77 | static 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 | |||
87 | static 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 | |||
96 | static 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 | |||
104 | static 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 | |||
116 | int 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 | |||
127 | struct MyClonableUserdata | ||
128 | { | ||
129 | lua_Integer val; | ||
130 | }; | ||
131 | |||
132 | // ################################################################################################ | ||
133 | |||
134 | static 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 | |||
144 | static 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 | |||
155 | static 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 | |||
165 | static 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 | |||
174 | static 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. | ||
183 | static 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 | |||
205 | static 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 | |||
218 | int 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 | |||
229 | static 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 | |||
238 | LANES_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 | } | ||