Line data Source code
1 : /*
2 : * Copyright (c) 2014-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Martin Rupp
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef LUA_PARSING_H_
34 : #define LUA_PARSING_H_
35 :
36 : #ifdef USE_LUAJIT
37 : #include <lua.h>
38 : #else
39 : #include "externals/lua/lua.h"
40 : #endif
41 :
42 : #include "bindings_lua.h"
43 : #include "bindings/lua/lua_function_handle.h"
44 : #include "bindings/lua/lua_table_handle.h"
45 :
46 : namespace ug{
47 : namespace bridge{
48 : namespace lua{
49 :
50 : template <typename T>
51 : struct LuaParsing;
52 :
53 : template <>
54 : struct LuaParsing<bool>{
55 : static bool check(lua_State* L, int index){
56 0 : return lua_isboolean(L, index);
57 : }
58 : static bool get(lua_State* L, int index){
59 0 : return lua_toboolean(L, index);
60 : }
61 : static void push(lua_State* L, bool data){
62 0 : lua_pushboolean(L, (data ? 1 : 0));
63 0 : }
64 : };
65 :
66 : template <>
67 : struct LuaParsing<int>{
68 : static bool check(lua_State* L, int index){
69 0 : return lua_isnumber(L, index);
70 : }
71 : static int get(lua_State* L, int index){
72 0 : return (int)lua_tointeger(L, index);
73 : }
74 : static void push(lua_State* L, int data){
75 0 : lua_pushnumber(L, data);
76 0 : }
77 : };
78 :
79 : template <>
80 : struct LuaParsing<size_t>{
81 : static bool check(lua_State* L, int index){
82 0 : return lua_isnumber(L, index);
83 : }
84 : static size_t get(lua_State* L, int index){
85 0 : return lua_tointeger(L, index);
86 : }
87 : static void push(lua_State* L, size_t data){
88 0 : lua_pushnumber(L, (lua_Number)data);
89 0 : }
90 : };
91 :
92 : template <>
93 : struct LuaParsing<float>{
94 : static bool check(lua_State* L, int index){
95 0 : return lua_isnumber(L, index);
96 : }
97 : static float get(lua_State* L, int index){
98 0 : return (float)lua_tonumber(L, index);
99 : }
100 : static void push(lua_State* L, float data){
101 0 : lua_pushnumber(L, data);
102 0 : }
103 : };
104 :
105 : template <>
106 : struct LuaParsing<double>{
107 : static bool check(lua_State* L, int index){
108 0 : return lua_isnumber(L, index);
109 : }
110 : static double get(lua_State* L, int index){
111 0 : return lua_tonumber(L, index);
112 : }
113 : static void push(lua_State* L, double data){
114 0 : lua_pushnumber(L, data);
115 0 : }
116 : };
117 :
118 : template <>
119 : struct LuaParsing<const char*>{
120 : static bool check(lua_State* L, int index){
121 0 : return lua_isstring(L, index);
122 : }
123 : static const char* get(lua_State* L, int index){
124 0 : return lua_tostring(L, index);
125 : }
126 : static void push(lua_State* L, const char* data){
127 0 : lua_pushstring(L, data);
128 0 : }
129 : };
130 :
131 : template <>
132 : struct LuaParsing<std::string>{
133 : static bool check(lua_State* L, int index){
134 0 : return lua_isstring(L, index);
135 : }
136 : static std::string get(lua_State* L, int index){
137 0 : return std::string(lua_tostring(L, index));
138 : }
139 : static void push(lua_State* L, std::string data){
140 0 : lua_pushstring(L, data.c_str());
141 0 : }
142 : };
143 :
144 : template <>
145 : struct LuaParsing<const std::string&>{
146 : static bool check(lua_State* L, int index){
147 : return lua_isstring(L, index);
148 : }
149 : static void push(lua_State* L, const std::string& data){
150 : lua_pushstring(L, data.c_str());
151 : }
152 : };
153 :
154 : #ifdef UG_FOR_LUA
155 : template <>
156 : struct LuaParsing<LuaFunctionHandle>{
157 : static bool check(lua_State* L, int index){
158 0 : return lua_isfunction(L, index);
159 : }
160 : static LuaFunctionHandle get(lua_State* L, int index){
161 : LuaFunctionHandle tmp;
162 0 : lua_pushvalue(L, index);
163 0 : tmp.ref = luaL_ref(L, LUA_REGISTRYINDEX);
164 : return tmp;
165 : }
166 : static void push(lua_State* L, LuaFunctionHandle data){
167 : UG_THROW("Return value of type LuaFunctionHandle not implemented.");
168 : }
169 : };
170 :
171 : template <>
172 : struct LuaParsing<LuaTableHandle>{
173 : static bool check(lua_State* L, int index){
174 0 : return lua_istable(L, index);
175 : }
176 0 : static LuaTableHandle get(lua_State* L, int index){
177 0 : LuaTableHandle tmp(L, index);
178 0 : untested();
179 0 : return tmp;
180 0 : }
181 : static void push(lua_State* L, LuaTableHandle data){
182 : UG_THROW("Return value of type LuaTableHandle not implemented.");
183 : }
184 : };
185 : #endif
186 :
187 : template <>
188 : struct LuaParsing<void*>{
189 0 : static bool checkAndGet(std::pair<void*, const ClassNameNode*>& res,
190 : lua_State* L, int index, const char* baseClassName){
191 0 : if(!lua_isuserdata(L, index)) return false;
192 :
193 : UserDataWrapper* udata =
194 0 : reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
195 :
196 0 : if(udata->is_const()) return false;
197 :
198 : // extract the pointer to the object.
199 : // udata is either a RawUserData or a SmartUserDataWrapper
200 : void* obj = NULL;
201 0 : if(udata->is_raw_ptr())
202 0 : obj = static_cast<RawUserDataWrapper*>(udata)->obj;
203 0 : else if(udata->is_smart_ptr() && IMLPICIT_SMART_PTR_TO_PTR_CONVERSION)
204 : obj = static_cast<SmartUserDataWrapper*>(udata)->smartPtr.get();
205 : else return false;
206 :
207 : // get the object and its metatable. Make sure that obj can be cast to
208 : // the type that is expected by the paramsTemplate.
209 0 : if(lua_getmetatable(L, index) == 0) return false;
210 :
211 0 : lua_pushstring(L, "class_name_node");
212 0 : lua_rawget(L, -2);
213 0 : const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
214 0 : lua_pop(L, 2);
215 :
216 0 : if(!classNameNode) return false;
217 0 : if(classNameNode->empty()) return false;
218 0 : if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
219 :
220 0 : res.first = obj;
221 0 : res.second = classNameNode;
222 :
223 0 : return true;
224 : }
225 :
226 : static void push(lua_State* L, void* data, const char* className){
227 0 : CreateNewUserData(L, data, className, NULL, false);
228 0 : }
229 : };
230 :
231 : template <>
232 : struct LuaParsing<const void*>{
233 0 : static bool checkAndGet(std::pair<const void*, const ClassNameNode*>& res,
234 : lua_State* L, int index, const char* baseClassName){
235 0 : if(!lua_isuserdata(L, index)) return false;
236 :
237 : UserDataWrapper* udata =
238 0 : reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
239 :
240 : // extract the pointer to the object.
241 : // udata is either a RawUserData or a SmartUserDataWrapper
242 : const void* obj = NULL;
243 :
244 0 : if(udata->is_raw_ptr())
245 0 : obj = static_cast<RawUserDataWrapper*>(udata)->obj;
246 0 : else if(udata->is_smart_ptr() && IMLPICIT_SMART_PTR_TO_PTR_CONVERSION){
247 : // we have to distinguish between const and non-const smart pointers.
248 0 : if(udata->is_const())
249 : obj = static_cast<ConstSmartUserDataWrapper*>(udata)->smartPtr.get();
250 : else
251 : obj = static_cast<SmartUserDataWrapper*>(udata)->smartPtr.get();
252 : }
253 : else return false;
254 :
255 : // get the object and its metatable. Make sure that obj can be cast to
256 : // the type that is expected by the paramsTemplate.
257 0 : if(lua_getmetatable(L, index) == 0) return false;
258 :
259 0 : lua_pushstring(L, "class_name_node");
260 0 : lua_rawget(L, -2);
261 0 : const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
262 0 : lua_pop(L, 2);
263 :
264 0 : if(!classNameNode) return false;
265 0 : if(classNameNode->empty()) return false;
266 0 : if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
267 :
268 0 : res.first = obj;
269 0 : res.second = classNameNode;
270 :
271 0 : return true;
272 : }
273 :
274 : static void push(lua_State* L, const void* data, const char* className){
275 : // we're removing const with a cast. However, it was made sure that
276 : // obj is treated as a const value.
277 0 : CreateNewUserData(L, (void*)data, className, NULL, true);
278 0 : }
279 : };
280 :
281 : template <>
282 : struct LuaParsing<SmartPtr<void> >{
283 0 : static bool checkAndGet(std::pair<SmartPtr<void>, const ClassNameNode*>& res,
284 : lua_State* L, int index, const char* baseClassName){
285 0 : if(!lua_isuserdata(L, index)) return false;
286 :
287 : UserDataWrapper* udata =
288 0 : reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
289 :
290 0 : if(!udata->is_smart_ptr()) return false;
291 0 : if(udata->is_const()) return false;
292 :
293 0 : SmartPtr<void>& obj = ((SmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
294 :
295 0 : if(lua_getmetatable(L, index) == 0) return false;
296 0 : lua_pushstring(L, "class_name_node");
297 0 : lua_rawget(L, -2);
298 0 : const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
299 0 : lua_pop(L, 2);
300 :
301 0 : if(!classNameNode) return false;
302 0 : if(classNameNode->empty()) return false;
303 0 : if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
304 :
305 0 : res.first = obj;
306 0 : res.second = classNameNode;
307 :
308 0 : return true;
309 : }
310 :
311 : static void push(lua_State* L, SmartPtr<void> data, const char* className){
312 0 : CreateNewUserData(L, data, className);
313 0 : }
314 : };
315 :
316 : template <>
317 : struct LuaParsing<ConstSmartPtr<void> >{
318 0 : static bool checkAndGet(std::pair<ConstSmartPtr<void>, const ClassNameNode*>& res,
319 : lua_State* L, int index, const char* baseClassName){
320 0 : if(!lua_isuserdata(L, index)) return false;
321 :
322 : UserDataWrapper* udata =
323 0 : reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
324 :
325 0 : if(!udata->is_smart_ptr()) return false;
326 :
327 : ConstSmartPtr<void> obj;
328 0 : if(((UserDataWrapper*)lua_touserdata(L, index))->is_const())
329 0 : obj = ((ConstSmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
330 : else
331 0 : obj = ((SmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
332 :
333 0 : if(lua_getmetatable(L, index) == 0) return false;
334 0 : lua_pushstring(L, "class_name_node");
335 0 : lua_rawget(L, -2);
336 0 : const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
337 0 : lua_pop(L, 2);
338 :
339 0 : if(!classNameNode) return false;
340 0 : if(classNameNode->empty()) return false;
341 0 : if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
342 :
343 0 : res.first = obj;
344 0 : res.second = classNameNode;
345 :
346 0 : return true;
347 : }
348 :
349 : static void push(lua_State* L, ConstSmartPtr<void> data, const char* className){
350 0 : CreateNewUserData(L, data, className);
351 0 : }
352 : };
353 :
354 :
355 : }
356 : }
357 : }
358 : #endif /* LUA_PARSING_H_ */
359 :
|