Line data Source code
1 : /*
2 : * Copyright (c) 2014: 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 : /**
34 : * \file lua_serialization.cpp
35 : *
36 : * \author Martin Rupp
37 : *
38 : * \date 23.06.2014
39 : *
40 : * Goethe-Center for Scientific Computing 2014.
41 : *
42 : * Serialization stuff for lua.
43 : * not fully developed.
44 : * the idea is to call Serialize(obj, serializationObj) for all UserData-Objects, if this Serialize is registered in the registry.
45 : */
46 :
47 : #include <iomanip>
48 : #include "bindings/lua/lua_util.h"
49 : #include "bindings/lua/bindings_lua.h"
50 : #include "bridge/bridge.h"
51 : #include "bridge/util.h"
52 : #include "registry/class_helper.h"
53 : #include "common/util/sort_util.h"
54 : #include "common/util/string_util.h"
55 : #include "lua_stack_check.h"
56 : #include "registry/class_name_provider.h"
57 : #include "common/util/string_util.h"
58 :
59 : #include "common/util/stringify.h"
60 : //#include "bridge/misc_bridges/serialization.h"
61 : #include "bindings_lua.h"
62 : //#include "lua_parsing.h"
63 :
64 : #include "info_commands.h"
65 :
66 : using namespace std;
67 :
68 : namespace ug{
69 : size_t SerializerGetLastID();
70 :
71 : namespace bridge{
72 :
73 0 : string LUAStringEscape(string s)
74 : {
75 0 : s = ReplaceAll(s, "\\", "\\\\");
76 0 : s = ReplaceAll(s, "\"", "\\\"");
77 0 : s = ReplaceAll(s, "\n", "\\n");
78 0 : return s;
79 : }
80 :
81 :
82 : #if 0
83 : namespace lua{
84 : struct MyLuaParsing
85 : {
86 : static bool checkAndGet(std::pair<ConstSmartPtr<void>, const ClassNameNode*>& res,
87 : lua_State* L, int index, const char* baseClassName){
88 : if(!lua_isuserdata(L, index)) return false;
89 :
90 : UserDataWrapper* udata =
91 : reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
92 :
93 : if(!udata->is_smart_ptr()) return false;
94 :
95 : ConstSmartPtr<void> obj;
96 : if(((UserDataWrapper*)lua_touserdata(L, index))->is_const())
97 : obj = ((ConstSmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
98 : else
99 : obj = ((SmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
100 :
101 : if(lua_getmetatable(L, index) == 0) return false;
102 : lua_pushstring(L, "class_name_node");
103 : lua_rawget(L, -2);
104 : const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
105 : lua_pop(L, 2);
106 :
107 : if(!classNameNode) return false;
108 : if(classNameNode->empty()) return false;
109 : if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
110 :
111 : res.first = obj;
112 : res.second = classNameNode;
113 :
114 : return true;
115 : }
116 :
117 : static void push(lua_State* L, ConstSmartPtr<void> data, const char* className){
118 : CreateNewUserData(L, data, className);
119 : }
120 : };
121 : }
122 :
123 :
124 : template <typename T>
125 : static bool PushLuaStackPointerEntryToParamStack(ParameterStack& ps, lua_State* L,
126 : int index, const char* baseClassName,
127 : bool bIsVector)
128 : {
129 : typedef std::pair<T, const ClassNameNode*> result_type;
130 :
131 : result_type res;
132 : if(!bIsVector){
133 :
134 : UG_LOG(GetLuaTypeString(L, -1) << " " << baseClassName << "\n");
135 : if(lua::MyLuaParsing::checkAndGet(res, L, index, baseClassName)){
136 : ps.push(res.first, res.second);
137 : }
138 : else return false;
139 : }
140 : else {UG_THROW("ll");
141 : }
142 : return true;
143 : }
144 :
145 : const void *getPtr(lua::UserDataWrapper *self)
146 : {
147 : // raw pointer
148 : if(self->is_raw_ptr())
149 : {
150 : // cast to the needed base class
151 : return ((lua::RawUserDataWrapper*)self)->obj;
152 : }
153 : // smart pointer
154 : else if(self->is_smart_ptr())
155 : {
156 : if(self->is_const())
157 : // cast to the needed base class
158 : return (void*)((lua::ConstSmartUserDataWrapper*)self)->smartPtr.get();
159 : else
160 : return ((lua::SmartUserDataWrapper*)self)->smartPtr.get();
161 : }
162 : }
163 :
164 : TheSerializer theSerializer;
165 : #endif
166 :
167 0 : void WriteLUAObject2(lua_State* L, std::string name, std::ostream &s)
168 : {
169 : //UG_LOG(" " << lua_tostring(L, -1) << "\n");
170 0 : if(lua_isnil(L, -1))
171 0 : s << name << " = nil\n";
172 0 : else if(lua_isboolean(L, -1))
173 0 : s << name << " = " << (lua_toboolean(L, -1)==true ? "true" : "false") << "\n";
174 0 : else if(lua_isnumber(L, -1))
175 0 : s << name << " = " << lua_tostring(L, -1) << "\n";
176 0 : else if(lua_isstring(L, -1))
177 0 : s << name << " = \"" << LUAStringEscape(lua_tostring(L, -1)) << "\"\n";
178 0 : else if(lua_istable(L, -1))
179 : {
180 0 : lua_pushvalue(L, -1);
181 : /* table is in the stack at index 't' */
182 0 : s << name << " = " << name << " or {}\n";
183 : //UG_LOG(name << " = " << name << " or {}\n");
184 0 : lua_pushnil(L);
185 0 : while (lua_next(L, -2) != 0)
186 : {
187 : std::string nextname;
188 : // copy the key so that lua_tostring does not modify the original
189 0 : lua_pushvalue(L, -2);
190 0 : if(lua_type(L, -1) == LUA_TNUMBER)
191 0 : nextname = Stringify() << "\t" << name << "[" << lua_tostring(L, -1) << "]";
192 : else
193 0 : nextname = Stringify() << "\t" << name << "[\"" << lua_tostring(L, -1) << "\"]";
194 0 : lua_pop(L, 1);
195 :
196 : // also copy value
197 0 : lua_pushvalue(L, -1);
198 0 : WriteLUAObject2(L, nextname, s);
199 0 : lua_pop(L, 2);
200 : }
201 0 : lua_pop(L, 1);
202 :
203 : }
204 0 : else if(lua_isuserdata(L, -1))
205 : {
206 : #if 0
207 : const ClassNameNode& cnn = SerializeObject::class_name_node();
208 : lua::UserDataWrapper* self = (lua::UserDataWrapper*)lua_touserdata(L, 1);
209 : size_t id = theSerializer.is_serialized(self);
210 : if(id == 0)
211 : {
212 : const ExportedFunctionGroup* funcGrp = GetUGRegistry().get_exported_function_group("Serialize");
213 : if(funcGrp)
214 : {
215 : // we have to try each overload!
216 : for(size_t i = 0; i < funcGrp->num_overloads(); ++i){
217 : const ExportedFunction* func = funcGrp->get_overload(i);
218 :
219 : ParameterStack paramsIn;
220 : ParameterStack paramsOut;
221 : const ParameterInfo &psInfo = func->params_in();
222 :
223 : if(PushLuaStackPointerEntryToParamStack<ConstSmartPtr<void> >
224 : (paramsIn, L, -1, psInfo.class_name(0), false))
225 : {
226 : size_t id = theSerializer.create_id(self);
227 : SerializeObject so(theSerializer, id);
228 :
229 :
230 : paramsIn.push(&so, &cnn);
231 : func->execute(paramsIn, paramsOut);
232 :
233 : theSerializer.serialize(so.buffer(), id, psInfo.class_name(0));
234 : break;
235 : }
236 :
237 : }
238 : }
239 :
240 : }
241 :
242 :
243 : if(id == 0)
244 : s << name << " = nil -- no Serialize(" << GetLuaTypeString(L, -1) << ")\n";
245 : else
246 : s << name << " = SerializerGet(" << id << ")\n";
247 : #else
248 0 : s << name << " = nil -- Userdata serialize not yet supported\n";
249 : #endif
250 :
251 : }
252 : else
253 : {
254 0 : const char *p =lua_tostring(L, -1);
255 0 : s << "-- " << name << " = " << GetLuaTypeString(L, -1) << " ";
256 0 : if(p) s << p;
257 0 : s << "\n";
258 : }
259 :
260 0 : }
261 0 : void WriteLUAObject(lua_State* L, std::string name, std::ostream &s)
262 : {
263 0 : lua_getglobal(L, name.c_str());
264 0 : WriteLUAObject2(L, name, s);
265 0 : lua_pop(L, 1);
266 0 : }
267 :
268 : /*void LuaList_writeObjects(const char*filename)
269 : {
270 : fstream file(filename, ios::out);
271 : lua_State* L = script::GetDefaultLuaState();
272 : std::vector<std::string> luaObjects;
273 : GetLuaGlobal_luaObjects(luaObjects);
274 :
275 : if(luaObjects.empty()) return;
276 : int maxLength = (*max_element(luaObjects.begin(), luaObjects.end(), IsLonger)).size();
277 : for(size_t i=0; i<luaObjects.size(); i++)
278 : {
279 : if(luaObjects[i].compare("_G") == 0) continue;
280 : if(luaObjects[i].compare("package") == 0) continue;
281 : WriteLUAObject(L, luaObjects[i].c_str(), std::cout);
282 : }
283 : }*/
284 :
285 0 : void LuaWrite(const char *filename, const char* obj)
286 : {
287 0 : fstream file(filename, ios::out);
288 0 : file << "function LoadTheCheckpoint()\n";
289 0 : lua_State* L = script::GetDefaultLuaState();
290 0 : WriteLUAObject(L, obj, file);
291 0 : file << "return " << obj << "\n";
292 0 : file << "end\n";
293 0 : }
294 :
295 0 : void LuaWriteCout(const char* obj)
296 : {
297 0 : lua_State* L = script::GetDefaultLuaState();
298 0 : WriteLUAObject(L, obj, std::cout);
299 0 : }
300 :
301 :
302 1 : bool RegisterSerializationCommands(Registry ®, const char* parentGroup)
303 : {
304 1 : stringstream grpSS; grpSS << parentGroup << "/Serialization";
305 : std::string grp = grpSS.str();
306 :
307 : try
308 : {
309 : // reg.add_function("LuaList_writeObjects", &LuaList_writeObjects, grp.c_str());
310 2 : reg.add_function("LuaWrite", &LuaWrite, grp.c_str());
311 2 : reg.add_function("LuaWriteCout", &LuaWriteCout, grp.c_str());
312 : }
313 0 : UG_REGISTRY_CATCH_THROW(grp);
314 :
315 1 : return true;
316 1 : }
317 :
318 : }
319 : }
|