|
libFAUDES
Sections
Index
|
lbp_function.cppGo to the documentation of this file.00001 /** @file lbp_function.cpp luafaudes class to run scripts as rti functions */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2010 Thomas Moor 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2.1 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00020 00021 // my header 00022 #include "lbp_function.h" 00023 00024 // all lua headers, incl luafaudes 00025 #include "libluafaudes.h" 00026 00027 00028 00029 namespace faudes{ 00030 00031 /* 00032 ******************************************************************** 00033 ******************************************************************** 00034 ******************************************************************** 00035 00036 Implementation of class LuaFunctionDefinition 00037 00038 ******************************************************************** 00039 ******************************************************************** 00040 ******************************************************************** 00041 */ 00042 00043 // faudes type 00044 FAUDES_TYPE_IMPLEMENTATION(LuaFunctionDefinition,LuaFunctionDefinition,FunctionDefinition) 00045 00046 // construct 00047 LuaFunctionDefinition::LuaFunctionDefinition(const std::string& name) : 00048 FunctionDefinition(name) 00049 { 00050 Prototype(new LuaFunction(0)); 00051 FD_DLB("LuaFunctionDefinition::LuaFunctionDefinition("<<this<<"): name " << name); 00052 FD_DLB("LuaFunctionDefinition::LuaFunctionDefinition("<<this<<"): proto " << mpFunction); 00053 FD_DLB("LuaFunctionDefinition::LuaFunctionDefinition("<<this<<"): has def " << mpFunction->Definition()); 00054 } 00055 00056 // copy construct 00057 LuaFunctionDefinition::LuaFunctionDefinition(const LuaFunctionDefinition& rSrc) : 00058 FunctionDefinition(rSrc.Name()) 00059 { 00060 FD_DLB("LuaFunctionDefinition::LuaFunctionDefinition(copy)"); 00061 DoAssign(rSrc); 00062 } 00063 00064 // std faudes type 00065 void LuaFunctionDefinition::DoAssign(const LuaFunctionDefinition& rSrc) { 00066 FD_DLB("LuaFunctionDefinition::DoAssign()"); 00067 // assign base members 00068 FunctionDefinition::DoAssign(rSrc); 00069 // assign my members 00070 mLuaCode=rSrc.mLuaCode; 00071 mLuaFile=rSrc.mLuaFile; 00072 // special member 00073 pLuaFunction=dynamic_cast<LuaFunction*>(mpFunction); 00074 // report 00075 FD_DLB("LuaFunctionDefinition::DoAssign("<<this<<"): name " << mName); 00076 FD_DLB("LuaFunctionDefinition::DoAssign("<<this<<"): proto " << mpFunction); 00077 FD_DLB("LuaFunctionDefinition::DoAssign("<<this<<"): has def " << mpFunction->Definition()) 00078 } 00079 00080 // std faudes type 00081 bool LuaFunctionDefinition::DoEqual(const LuaFunctionDefinition& rOther) const { 00082 // test base members 00083 if(!FunctionDefinition::DoEqual(rOther)) return false; 00084 // test my members 00085 if(mLuaCode!=rOther.mLuaCode) return false; 00086 if(mLuaFile!=rOther.mLuaFile) return false; 00087 return true; 00088 } 00089 00090 // clear (all but prototype) 00091 void LuaFunctionDefinition::Clear(){ 00092 FD_DLB("LuaFunctionDefinition::Clear(): " << Name()); 00093 // call base 00094 FunctionDefinition::Clear(); 00095 // clear my data 00096 mLuaCode.clear(); 00097 } 00098 00099 00100 // set prototype object 00101 void LuaFunctionDefinition::Prototype(Function* pFunc){ 00102 FunctionDefinition::Prototype(pFunc); 00103 // set typed version 00104 pLuaFunction=dynamic_cast<LuaFunction*>(pFunc); 00105 } 00106 00107 00108 // get lua code 00109 const std::string& LuaFunctionDefinition::LuaCode(void) const { 00110 return mLuaCode; 00111 } 00112 00113 // set lua code 00114 void LuaFunctionDefinition::LuaCode(const std::string& rCode) { 00115 mLuaCode=rCode; 00116 } 00117 00118 00119 // test all variants 00120 std::string LuaFunctionDefinition::SyntaxCheck(void) { 00121 // trivial case ... ok 00122 if(VariantsSize()==0) { 00123 FD_DLB("LuaFunctionDefinition::SyntaxCheck(): no variants defined, fine"); 00124 return ""; 00125 } 00126 // allocate function 00127 faudes::LuaFunction* lfnct = pLuaFunction->New(); 00128 // iterate variants 00129 std::string err = ""; 00130 for(int i=0; i<lfnct->VariantsSize(); i++) { 00131 // select 00132 lfnct->Variant(i); 00133 FD_DLB("LuaFunctionDefinition::SyntaxCheck(): variant " << 00134 lfnct->Variant()->Name()); 00135 // allocate args (exception on unknown type, will lead to mem leak) 00136 try { 00137 lfnct->AllocateValues(); 00138 // let luafunction have a go 00139 if(err=="") try { 00140 lfnct->SyntaxCheck(); 00141 } catch(faudes::Exception ex) { 00142 err = ex.What(); 00143 } 00144 // free args 00145 lfnct->FreeValues(); 00146 // alloc err 00147 } catch(faudes::Exception ex) { 00148 err = "cannot allocate parameters for variant " + lfnct->Variant()->Name(); 00149 } 00150 } // iterate variants 00151 delete lfnct; 00152 // done 00153 return err; 00154 } 00155 00156 00157 // token io 00158 void LuaFunctionDefinition::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00159 FD_DLB("LuaFunctionDefinition::DoRead()"); 00160 // ignore 00161 (void) pContext; 00162 // label 00163 std::string label=rLabel; 00164 if(label=="") label="LuaFunctionDefinition"; 00165 // base can handle this 00166 FunctionDefinition::DoRead(rTr,label,pContext); 00167 // report 00168 FD_DLB("LuaFunctionDefinition::DoRead(): done " << mPlugIn << "::" << mName); 00169 } 00170 00171 00172 // token io 00173 void LuaFunctionDefinition::DoReadCore(TokenReader& rTr) { 00174 FD_DLB("LuaFunctionDefinition::DoReadCore()"); 00175 // call base 00176 FunctionDefinition::DoReadCore(rTr); 00177 // read my members 00178 Token token; 00179 rTr.Peek(token); 00180 // case a: embedded lua code 00181 if(token.IsBegin()) 00182 if(token.StringValue()=="LuaCode") { 00183 mLuaFile=""; 00184 rTr.ReadBegin("LuaCode"); 00185 mLuaCode=rTr.ReadString(); 00186 rTr.ReadEnd("LuaCode"); 00187 } 00188 // case b: lua file 00189 if(token.IsBegin()) 00190 if(token.StringValue()=="LuaFile") { 00191 rTr.ReadBegin("LuaFile"); 00192 std::string mLuaFile=rTr.ReadString(); 00193 // todo: read that file 00194 rTr.ReadEnd("LuaFile"); 00195 } 00196 } 00197 00198 00199 // token io 00200 void LuaFunctionDefinition::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00201 // label 00202 std::string label=rLabel; 00203 if(label=="") label="LuaFunctionDefinition"; 00204 // base can handle 00205 Documentation::DoWrite(rTw,label,pContext); 00206 } 00207 00208 // token io 00209 void LuaFunctionDefinition::DoWriteCore(TokenWriter& rTw) const { 00210 FD_DLB("LuaFunctionDefinition::DoWriteCore(): file " << rTw.FileName()); 00211 // call base core 00212 FunctionDefinition::DoWriteCore(rTw); 00213 // case a: embedded code 00214 if(mLuaFile=="") { 00215 rTw.WriteBegin("LuaCode"); 00216 rTw.WriteVerbatim(mLuaCode); 00217 rTw.WriteEnd("LuaCode"); 00218 } 00219 // case a: embedded code 00220 if(mLuaFile!="") { 00221 rTw.WriteBegin("LuaFile"); 00222 rTw.WriteString(mLuaFile); 00223 rTw.WriteEnd("LuaFile"); 00224 // todo: write that file 00225 } 00226 } 00227 00228 /* 00229 ******************************************************************** 00230 ******************************************************************** 00231 ******************************************************************** 00232 00233 Implementation of class LuaFunction 00234 00235 ******************************************************************** 00236 ******************************************************************** 00237 ******************************************************************** 00238 */ 00239 00240 // Constructor 00241 LuaFunction::LuaFunction(const LuaFunctionDefinition* fdef) : 00242 Function(fdef), 00243 pLuaFuncDef(fdef) 00244 { 00245 FD_DLB("LuaFunction::LuaFunction(): fdef " << pFuncDef); 00246 } 00247 00248 // new on heap 00249 LuaFunction* LuaFunction::New(void) const { 00250 return new LuaFunction(pLuaFuncDef); 00251 } 00252 00253 // set function definition 00254 void LuaFunction::Definition(const FunctionDefinition* fdef) { 00255 // cast and pass to base 00256 pLuaFuncDef = dynamic_cast<const LuaFunctionDefinition*>(fdef); 00257 Function::Definition(pLuaFuncDef); 00258 } 00259 00260 // get function definition 00261 const LuaFunctionDefinition* LuaFunction::Definition(void) const { 00262 return pLuaFuncDef; 00263 } 00264 00265 // implement typecheck 00266 bool LuaFunction::DoTypeCheck(int n) { 00267 FD_DLB("LuaFunction::DoTypeCheck("<< n << "): for " << Variant()->At(n).Type()); 00268 const Type* proto = TypeRegistry::G()->Prototype(Variant()->At(n).Type()); 00269 if(!proto) { 00270 FD_DLB("LuaFunction::DoTypeCheck("<< n << "): unknown type"); 00271 return false; 00272 } 00273 if(!proto->Cast(ParamValue(n))) { 00274 FD_DLB("LuaFunction::DoTypeCheck("<< n << "): could not cast param value"); 00275 return false; 00276 } 00277 return true; 00278 } 00279 00280 00281 // swigs version of user data (lua runtime version 4, swig 1.3.36) 00282 typedef void *(*swig_converter_func)(void *, int *); 00283 typedef struct swig_type_info *(*swig_dycast_func)(void **); 00284 typedef struct swig_cast_info { 00285 swig_type_info *type; /* pointer to type that is equivalent to this type */ 00286 swig_converter_func converter; /* function to cast the void pointers */ 00287 struct swig_cast_info *next; /* pointer to next cast in linked list */ 00288 struct swig_cast_info *prev; /* pointer to the previous cast */ 00289 } swig_cast_info; 00290 typedef struct swig_type_info { 00291 const char *name; /* mangled name of this type */ 00292 const char *str; /* human readable name of this type */ 00293 swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ 00294 struct swig_cast_info *cast; /* linked list of types that can cast into this type */ 00295 void *clientdata; /* language specific type data */ 00296 int owndata; /* flag if the structure owns the clientdata */ 00297 } swig_type_info; 00298 typedef struct { 00299 swig_type_info *type; 00300 int own; /* 1 <> owned by swig (garbadge collector wont destroy) */ 00301 void *ptr; 00302 } swig_lua_userdata; 00303 00304 00305 00306 /* Swig runtime sytem: dynamic cast of swig userdata pointers */ 00307 /* We need this to cast swig's userdata to the faudes base type */ 00308 /* faudes::Type. See SWIG runtime SWIG_ConvertPtr. */ 00309 void* SwigCastPtr(void* ptr, swig_type_info *from, swig_type_info *ty) { 00310 void* res=ptr; 00311 if(!ptr) return res; 00312 if(!from) return res; 00313 if(!ty) return res; 00314 swig_cast_info *iter = ty->cast; 00315 while(iter) { 00316 if(iter->type == from) { 00317 if(iter == ty->cast) break; 00318 iter->prev->next = iter->next; 00319 if(iter->next) 00320 iter->next->prev = iter->prev; 00321 iter->next = ty->cast; 00322 iter->prev = 0; 00323 if(ty->cast) ty->cast->prev = iter; 00324 ty->cast = iter; 00325 break; 00326 } 00327 iter = iter->next; 00328 } 00329 if(!iter) return res; 00330 if(!iter->converter) return res; 00331 int nm; 00332 res= (*iter->converter)(ptr,&nm); 00333 return res; 00334 } 00335 00336 // implement execute: run stages 00337 void LuaFunction::DoExecute(void) { 00338 FD_DLB("LuaFunction::DoExecute()"); 00339 /* 00340 for(int i=0; i< Variant()->Size(); i++) { 00341 FD_DLB("LuaFunction::DoExecute(): value at #" << i); 00342 ParamValue(i)->Write(); 00343 } 00344 */ 00345 // have a state 00346 mpL = lua_open(); 00347 // run stages 00348 DoExecuteA(); 00349 DoExecuteB(); 00350 DoExecuteC(); 00351 DoExecuteD(); 00352 // clean stack 00353 lua_pop(mpL, 1); // table from stage A 00354 // done 00355 lua_close(mpL); 00356 mpL=0; 00357 FD_DLB("LuaFunction::DoExecute(): done"); 00358 } 00359 00360 // implement execute: syntaxcheck 00361 void LuaFunction::SyntaxCheck(void) { 00362 FD_DLB("LuaFunction::SyntaxCheck()"); 00363 // have a state 00364 mpL = lua_open(); 00365 // run stages 00366 DoExecuteA(); 00367 DoExecuteB(); 00368 DoExecuteD(); 00369 // clean stack 00370 lua_pop(mpL, 1); // function from stage B 00371 lua_pop(mpL, 1); // table from stage A 00372 // done 00373 lua_close(mpL); 00374 mpL=0; 00375 } 00376 00377 // implement execute: get function on the stack 00378 void LuaFunction::DoExecuteA(void) { 00379 FD_DLB("LuaFunction::DoExecuteA()"); 00380 // prepare lua 00381 lua_gc(mpL, LUA_GCSTOP, 0); // stop collector during initialization 00382 luaL_openlibs(mpL); // open libraries 00383 luaopen_faudes_allplugins(mpL); // luafaudes: register 00384 //luafaudes_dotready(); // luafaudes: test dot 00385 lua_gc(mpL, LUA_GCRESTART, 0); // start garbage collector 00386 // load my script 00387 const char* script = pLuaFuncDef->LuaCode().c_str(); 00388 int script_len = pLuaFuncDef->LuaCode().size(); 00389 int errload=luaL_loadbuffer(mpL, script, script_len, "luafaudes"); 00390 if(errload!=0) { 00391 std::string lerr= std::string(lua_tostring(mpL, -1)); 00392 int c1 = lerr.find_first_of(':'); 00393 if(c1<0) c1=0; 00394 int c2 = lerr.find_first_of(':',c1+1); 00395 if(c2<0) c2=1; 00396 std::string line = lerr.substr(c1+1,c2-c1-1); 00397 if(c2>1) { 00398 lerr="error in Lua script: line " + line + ": " + lerr.substr(c2+2); 00399 } 00400 lua_close(mpL); 00401 mpL=0; 00402 throw Exception("LuaFunction::DoExecuteA()", lerr, 49); 00403 } 00404 // run the script 00405 int errrun=lua_pcall(mpL, 0, 0, 0); 00406 if(errrun!=0) { 00407 std::stringstream errstr; 00408 errstr << "failed to run script: "; 00409 errstr << std::string(lua_tostring(mpL, -1)); 00410 lua_close(mpL); 00411 mpL=0; 00412 throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49); 00413 } 00414 // get the swig generated table of faudes functions 00415 lua_getglobal(mpL,"faudes"); 00416 mFtable=lua_gettop(mpL); 00417 if(!lua_istable(mpL,-1)) { 00418 std::stringstream errstr; 00419 errstr << "failed to load faudes table"; 00420 lua_close(mpL); 00421 mpL=0; 00422 throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49); 00423 } 00424 // mangle my function name 00425 std::string fname = Variant()->Name(); 00426 unsigned int src=0; 00427 unsigned int dst=0; 00428 while(src<fname.length()) { 00429 if(isalnum(fname.at(src))) {fname[dst++]=fname[src++]; continue;} 00430 fname[dst++]='_'; 00431 for(;src<fname.length();src++) 00432 if(isalnum(fname.at(src))) break; 00433 } 00434 fname.resize(dst); 00435 // find my function 00436 lua_getglobal(mpL,fname.c_str()); 00437 if(!lua_isfunction(mpL,-1)) { 00438 std::stringstream errstr; 00439 errstr << "missing function \"" << fname << "\""; 00440 lua_close(mpL); 00441 mpL=0; 00442 throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49); 00443 } 00444 // construct a plain Type usrdata 00445 lua_pushstring(mpL,"Type"); 00446 lua_gettable(mpL,mFtable); 00447 if(!lua_isfunction(mpL,-1)) { 00448 std::stringstream errstr; 00449 errstr << "failed to load constructor for plain Type"; 00450 lua_close(mpL); 00451 mpL=0; 00452 throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49); 00453 } 00454 if(lua_pcall(mpL, 0, 1, 0) != 0) { 00455 std::stringstream errstr; 00456 errstr << "failed to construct plain Type (1)"; 00457 lua_close(mpL); 00458 mpL=0; 00459 throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49); 00460 } 00461 swig_lua_userdata* susr = (swig_lua_userdata*) lua_touserdata (mpL, -1); 00462 if(!susr) { 00463 std::stringstream errstr; 00464 errstr << "failed to construct plain Type (2)"; 00465 lua_close(mpL); 00466 mpL=0; 00467 throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49); 00468 } 00469 FD_DLB("LuaFunction::DoExecuteA(): plain type is " << susr->type->name); 00470 mFType=susr->type; 00471 lua_pop(mpL, 1); 00472 } 00473 00474 // implement execute: prepare parameters 00475 void LuaFunction::DoExecuteB(void) { 00476 FD_DLB("LuaFunction::DoExecuteB()"); 00477 // construct my parameters in lua 00478 for(int i=0; i< Variant()->Size(); i++) { 00479 const std::string& ftype= Variant()->At(i).Type(); 00480 // special case: int as lua number 00481 if(ftype=="Integer") { 00482 lua_pushnumber(mpL,((Integer*)ParamValue(i))->CValue()); 00483 FD_DLB("LuaFunction::DoExecuteB(): created ftype " << ftype); 00484 continue; 00485 } 00486 // special case: bool as lua bool 00487 if(ftype=="Boolean") { 00488 lua_pushboolean(mpL,((Boolean*)ParamValue(i))->CValue()); 00489 FD_DLB("LuaFunction::DoExecuteB(): created ftype " << ftype); 00490 continue; 00491 } 00492 // special case: str as lua string 00493 if(ftype=="String") { 00494 lua_pushstring(mpL,((String*)ParamValue(i))->CValue().c_str()); 00495 FD_DLB("LuaFunction::DoExecuteB(): created ftype " << ftype); 00496 continue; 00497 } 00498 // std case: faudes type: construct 1 00499 lua_pushstring(mpL,ftype.c_str()); 00500 lua_gettable(mpL,mFtable); 00501 if(!lua_isfunction(mpL,-1)) { 00502 std::stringstream errstr; 00503 errstr << "failed to load constructor for \"" << ftype << "\""; 00504 lua_close(mpL); 00505 mpL=0; 00506 throw Exception("LuaFunction::DoExecuteB()", errstr.str(), 49); 00507 } 00508 // std case: faudes type: construct 2 00509 if(lua_pcall(mpL, 0, 1, 0) != 0) { 00510 std::stringstream errstr; 00511 errstr << "failed to construct for \"" << ftype << "\" (1)"; 00512 lua_close(mpL); 00513 mpL=0; 00514 throw Exception("LuaFunction::DoExecuteB()", errstr.str(), 49); 00515 } 00516 // std case: test user data pointer 00517 swig_lua_userdata* susr = (swig_lua_userdata*) lua_touserdata (mpL, -1); 00518 if(!susr) { 00519 std::stringstream errstr; 00520 errstr << "failed to construct for\"" << ftype << "\" (2)"; 00521 lua_close(mpL); 00522 mpL=0; 00523 throw Exception("LuaFunction::DoExecuteB()", errstr.str(), 49); 00524 } 00525 // inspect stack 00526 FD_DLB("LuaFunction::DoExecuteB(): created stype " << susr->type->name << " for ftype " << ftype); 00527 FD_DLB("LuaFunction::DoExecuteB(): faudes parameter at " << ParamValue(i)); 00528 FD_DLB("LuaFunction::DoExecuteB(): swig usrdata ptr " << susr->ptr); 00529 void* fptr=SwigCastPtr(susr->ptr,susr->type,(swig_type_info*)mFType); 00530 FD_DLB("LuaFunction::DoExecuteB(): faudes::Type converted ptr " << fptr); 00531 // copy parameter value 00532 if(Variant()->At(i).Attribute()!=Parameter::Out) { 00533 FD_DLB("LuaFunction::DoExecuteB(): copy parameter value"); 00534 ((Type*)fptr)->Assign(*ParamValue(i)); 00535 } 00536 // note: the original idea did not work out .. 00537 // need to further investige how SWIG interacts with Lua 00538 // if(susr->own) free(susr->ptr); 00539 //susr->own=0; 00540 //susr->ptr = ParamValue(i); 00541 } 00542 } 00543 00544 // implement execute: execute the function 00545 void LuaFunction::DoExecuteC(void) { 00546 FD_DLB("LuaFunction::DoExecuteC()"); 00547 // run my function 00548 if(lua_pcall(mpL, Variant()->Size(), Variant()->Size(), 0) != 0) { 00549 FD_DLB("LuaFunction::DoExecuteC(): detect error"); 00550 std::string lerr= std::string(lua_tostring(mpL, -1)); 00551 // user request via loopback exception 00552 if(lerr.find("break on application request")!=std::string::npos) { 00553 lerr="break on application request"; 00554 } 00555 // user request via explicit exception 00556 else if(lerr.find("luafaudes script:")!=std::string::npos) { 00557 unsigned int c1=lerr.find("luafaudes script:"); 00558 lerr=lerr.substr(c1); 00559 } 00560 // have line number ? 00561 else if(lerr.size()>=2) { 00562 unsigned int c1 = lerr.find_first_of(':'); 00563 if(c1==std::string::npos) c1=0; 00564 if(c1+1>=lerr.size()) c1=0; 00565 unsigned int c2 = lerr.find_first_of(':',c1+1); 00566 if(c2==std::string::npos) c2=c1+1; 00567 if(c2>c1+1) { 00568 std::string line = lerr.substr(c1+1,c2-c1-1); 00569 lerr="error in Lua script: line " + line + ": " + lerr.substr(c2+2); 00570 } 00571 } 00572 // anyway: close lua 00573 lua_close(mpL); 00574 mpL=0; 00575 throw Exception("LuaFunction::DoExecuteC()", lerr, 49); 00576 } 00577 FD_DLB("LuaFunction::DoExecuteC():done "); 00578 } 00579 00580 // implement execute: retrieve results 00581 void LuaFunction::DoExecuteD(void) { 00582 FD_DLB("LuaFunction::DoExecuteD()"); 00583 // retrieve results from stack 00584 for(int i=Variant()->Size()-1; i>=0; i--) { 00585 const std::string& ftype= Variant()->At(i).Type(); 00586 // special case: int as lua number 00587 if(ftype=="Integer" && lua_isnumber(mpL,-1)) { 00588 FD_DLB("LuaFunction::DoExecuteD(): retrieve type " << ftype); 00589 ((Integer*)ParamValue(i))->CValue(lua_tonumber(mpL,-1)); 00590 lua_pop(mpL, 1); 00591 continue; 00592 } 00593 // special case: bool as lua bool 00594 if(ftype=="Boolean" && lua_isboolean(mpL,-1)) { 00595 ((Boolean*)ParamValue(i))->CValue(lua_toboolean(mpL,-1)); 00596 FD_DLB("LuaFunction::DoExecuteD(): retrieved type " << ftype); 00597 lua_pop(mpL, 1); 00598 continue; 00599 } 00600 // special case: str as lua string 00601 if(ftype=="String" && lua_isstring(mpL,-1)) { 00602 ((String*)ParamValue(i))->CValue(lua_tostring(mpL,-1)); 00603 FD_DLB("LuaFunction::DoExecuteD(): retrieved type " << ftype); 00604 lua_pop(mpL, 1); 00605 continue; 00606 } 00607 // std case: sould use references for faudes values anyway ... see ExecuteC 00608 if(lua_isuserdata(mpL,-1)) { 00609 FD_DLB("LuaFunction::DoExecuteD(): try to retrieve type " << ftype); 00610 swig_lua_userdata* susr = (swig_lua_userdata*) lua_touserdata(mpL, -1); 00611 if(susr) { 00612 FD_DLB("LuaFunction::DoExecuteD(): found swig type " << susr->type->name << " at " << susr->ptr); 00613 FD_DLB("LuaFunction::DoExecuteD(): usr data at " << susr->ptr); 00614 void* fptr=SwigCastPtr(susr->ptr,susr->type,(swig_type_info*)mFType); 00615 FD_DLB("LuaFunction::DoExecuteD(): faudes::Type converted ptr " << fptr); 00616 // copy parameter value 00617 if(Variant()->At(i).Attribute()!=Parameter::In) { 00618 FD_DLB("LuaFunction::DoExecuteD(): copy parameter value"); 00619 ParamValue(i)->Assign(*((Type*)fptr)); 00620 } 00621 // pop 00622 lua_pop(mpL, 1); 00623 continue; 00624 } 00625 } 00626 // report error 00627 std::stringstream errstr; 00628 errstr << "invalid return values in \"" << Variant()->Name() << "\""; 00629 lua_close(mpL); 00630 mpL=0; 00631 throw Exception("LuaFunction::DoExecuteD()", errstr.str(), 49); 00632 } 00633 } 00634 00635 00636 } // namespace 00637 |
libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3