lua++
|
00001 #include "luapp_state.hpp" 00002 #include "luapp_glues.hpp" 00003 #include "luapp_exception.hpp" 00004 #include "luapp_var.hpp" 00005 #include <utils_string.hpp> 00006 #include <utils_filesystem.hpp> 00007 #include <iostream> 00008 #include <deque> 00009 /*#include "frost_utils_eventmanager.h" 00010 #include "frost_utils_event.h"*/ 00011 00012 //#define DEBUG_STACK 00013 00014 namespace lua 00015 { 00016 const luaL_Reg lualibs[] = { 00017 {"", luaopen_base}, 00018 {LUA_LOADLIBNAME, luaopen_package}, 00019 {LUA_TABLIBNAME, luaopen_table}, 00020 {LUA_IOLIBNAME, luaopen_io}, 00021 {LUA_OSLIBNAME, luaopen_os}, 00022 {LUA_STRLIBNAME, luaopen_string}, 00023 {LUA_MATHLIBNAME, luaopen_math}, 00024 {LUA_DBLIBNAME, luaopen_debug}, 00025 {NULL, NULL} 00026 }; 00027 00028 std::map<lua_State*, state*> state::lLuaStateMap_; 00029 00030 void open_libs(lua_State* pLua_) 00031 { 00032 for (const luaL_Reg* lib = lualibs; lib->func; ++lib) 00033 { 00034 lua_pushcfunction(pLua_, lib->func); 00035 lua_pushstring(pLua_, lib->name); 00036 lua_call(pLua_, 1, 0); 00037 } 00038 } 00039 00040 int l_TreatError(lua_State*); 00041 00042 state::state() 00043 { 00044 pErrorFunction_ = &l_TreatError; 00045 00046 pLua_ = lua_open(); 00047 if (!pLua_) 00048 { 00049 throw exception("state", "Error while initializing Lua."); 00050 return; 00051 } 00052 00053 open_libs(pLua_); 00054 00055 reg("SendString", glue_send_string); 00056 reg("EmptyString", glue_empty_string); 00057 reg("ConcTable", glue_conc_table); 00058 00059 lLuaStateMap_[pLua_] = this; 00060 } 00061 00062 state::~state() 00063 { 00064 if (pLua_) 00065 lua_close(pLua_); 00066 00067 lLuaStateMap_.erase(pLua_); 00068 } 00069 00070 state* state::get_state(lua_State* pLua) 00071 { 00072 std::map<lua_State*, state*>::iterator iter = lLuaStateMap_.find(pLua); 00073 if (iter != lLuaStateMap_.end()) 00074 return iter->second; 00075 else 00076 return nullptr; 00077 } 00078 00079 lua_State* state::get_state() 00080 { 00081 return pLua_; 00082 } 00083 00084 std::string state::conc_table( const std::string& sTable ) 00085 { 00086 /* [#] This function converts a Lua table into a formated string. It is used 00087 * to save the content of the table in the SavedVariables. 00088 */ 00089 std::string s = "tbl = \"" + sTable + "\";\n" 00090 "temp = \"\";\n" 00091 "for k, v in pairs (" + sTable + ") do\n" 00092 "local s, t;\n" 00093 "if (type(k) == \"number\") then\ns = k;\nend\n" 00094 "if (type(k) == \"string\") then\ns = \"\\\"\"..k..\"\\\"\";\nend\n" 00095 "if (type(v) == \"number\") then\nt = v;\nend\n" 00096 "if (type(v) == \"string\") then\nt = \"\\\"\"..v..\"\\\"\";\nend\n" 00097 "if (type(v) == \"boolean\") then\nif v then\nt = \"'true'\";\nelse\nt = \"'false'\";\nend\nend\n" 00098 "if (type(v) == \"table\") then\n" 00099 "t = \"'table'\";\nSendString(s..\" \"..t..\" \");\nConcTable(temp, tbl..\"[\"..s..\"]\");\n" 00100 "else\n" 00101 "SendString(s..\" \"..t..\" \");\n" 00102 "end\n" 00103 "end\n" 00104 "SendString(\"'end' \");\n"; 00105 00106 luaL_dostring(pLua_, s.c_str()); 00107 00108 return sComString; 00109 } 00110 00111 void state::copy_table(state& mLua, const std::string& sSrcName, const std::string& sDestName) 00112 { 00113 #ifdef DEBUG_STACK 00114 Log("copy_table : "+get_top()); 00115 #endif 00116 std::string sNewName; 00117 if (sDestName == "") sNewName = sSrcName; 00118 else sNewName = sDestName; 00119 00120 sComString = ""; 00121 try 00122 { 00123 mLua.do_string("str = \"\";\nstr = ConcTable(str, \"" + sSrcName + "\");\n"); 00124 } 00125 catch (exception& e) 00126 { 00127 throw exception("state", "copy_table : "+e.get_description()); 00128 } 00129 00130 std::string s = sComString; 00131 00132 if (s != "") 00133 { 00134 std::string sTab = " "; 00135 std::string sTable; 00136 sTable = sNewName + " = {\n"; 00137 uint uiTableIndent = 1u; 00138 bool bTableended = false; 00139 uint uiLineNbr = 0u; 00140 while (!bTableended) 00141 { 00142 if (uiLineNbr > 1000u) 00143 break; 00144 00145 if (uiTableIndent == 0) 00146 { 00147 bTableended = true; 00148 } 00149 else 00150 { 00151 uint i = s.find(" "); 00152 std::string sKey = s.substr(0, i); 00153 ++i; 00154 s.erase(0, i); 00155 if (sKey == "'end'") 00156 { 00157 uiTableIndent--; 00158 sTab = sTab.substr(0, sTab.size() - 4u); 00159 if (uiTableIndent == 0) 00160 sTable += "}\n"; 00161 else 00162 sTable += sTab + "},\n"; 00163 } 00164 else 00165 { 00166 sKey = "[" + sKey + "]"; 00167 00168 i = s.find(" "); 00169 std::string sValue = s.substr(0, i); 00170 ++i; 00171 s.erase(0, i); 00172 00173 int iType; 00174 if (sValue == "'table'") 00175 iType = TYPE_TABLE; 00176 else 00177 { 00178 iType = TYPE_NUMBER; 00179 if (sValue.find("\"") != std::string::npos) 00180 { 00181 iType = TYPE_STRING; 00182 } 00183 else 00184 { 00185 if (sValue.find("'") != std::string::npos) 00186 { 00187 iType = TYPE_BOOLEAN; 00188 utils::trim(sValue, '\''); 00189 } 00190 } 00191 } 00192 00193 if (iType == TYPE_NUMBER) 00194 { 00195 sTable += sTab + sKey + " = " + sValue + ";\n"; 00196 } 00197 else if (iType == TYPE_NIL) 00198 { 00199 sTable += sTab + sKey + " = nil;\n"; 00200 } 00201 else if (iType == TYPE_BOOLEAN) 00202 { 00203 sTable += sTab + sKey + " = " + sValue + ";\n"; 00204 } 00205 else if (iType == TYPE_STRING) 00206 { 00207 sTable += sTab + sKey + " = " + sValue + ";\n"; 00208 } 00209 else if (iType == TYPE_TABLE) 00210 { 00211 sTable += sTab + sKey + " = {\n"; 00212 sTab += " "; 00213 } 00214 } 00215 } 00216 } 00217 00218 mLua.do_string(sTable); 00219 } 00220 else 00221 { 00222 mLua.new_table(); 00223 mLua.set_global(sNewName); 00224 } 00225 #ifdef DEBUG_STACK 00226 Log("~copy_table : "+get_top()); 00227 #endif 00228 } 00229 00230 int l_TreatError( lua_State* pLua ) 00231 { 00232 if (!lua_isstring(pLua, -1)) 00233 return 0; 00234 00235 lua_Debug d; 00236 00237 lua_getstack(pLua, 1, &d); 00238 lua_getinfo(pLua, "Sl", &d); 00239 00240 std::string sError = std::string(d.short_src) + ":" + utils::to_string(int(d.currentline)) + ": " + std::string(lua_tostring(pLua, -1)); 00241 lua_pushstring(pLua, sError.c_str()); 00242 00243 return 1; 00244 } 00245 00246 void default_print_function(const std::string& s) 00247 { 00248 std::cerr << s << std::endl; 00249 } 00250 00251 void state::do_file( const std::string& sFile ) 00252 { 00253 #ifdef DEBUG_STACK 00254 Log("do_file : "+get_top()+" "+sFile); 00255 #endif 00256 if (utils::file_exists(sFile)) 00257 { 00258 lua_pushcfunction(pLua_, pErrorFunction_); 00259 uint uiFuncPos = get_top(); 00260 00261 if (luaL_loadfile(pLua_, sFile.c_str()) != 0) 00262 { 00263 if (lua_isstring(pLua_, -1)) 00264 { 00265 std::string sError = lua_tostring(pLua_, -1); 00266 lua_pop(pLua_, 1); 00267 lua_remove(pLua_, uiFuncPos); 00268 throw exception(sError); 00269 } 00270 else 00271 { 00272 lua_remove(pLua_, uiFuncPos); 00273 throw exception("state", "Cannot load file : \""+sFile+"\""); 00274 } 00275 } 00276 00277 int iError = lua_pcall(pLua_, 0, LUA_MULTRET, -2); 00278 if (iError != 0) 00279 { 00280 if (lua_isstring(pLua_, -1)) 00281 { 00282 std::string sError = lua_tostring(pLua_, -1); 00283 lua_pop(pLua_, 1); 00284 lua_remove(pLua_, uiFuncPos); 00285 throw exception(sError); 00286 } 00287 else 00288 { 00289 lua_pop(pLua_, 1); 00290 lua_remove(pLua_, uiFuncPos); 00291 throw exception("state", "Unhandled error."); 00292 } 00293 } 00294 00295 lua_remove(pLua_, uiFuncPos); 00296 } 00297 else 00298 { 00299 throw exception("state", "do_file : cannot open \""+sFile+"\"."); 00300 } 00301 #ifdef DEBUG_STACK 00302 Log("~do_file : "+get_top()+" "+sFile); 00303 #endif 00304 } 00305 00306 void state::do_string( const std::string& sStr ) 00307 { 00308 #ifdef DEBUG_STACK 00309 Log("do_string : "+get_top()+" "+sStr); 00310 #endif 00311 lua_pushcfunction(pLua_, pErrorFunction_); 00312 uint uiFuncPos = get_top(); 00313 00314 if (luaL_loadstring(pLua_, sStr.c_str()) != 0) 00315 { 00316 if (lua_isstring(pLua_, -1)) 00317 { 00318 std::string sError = lua_tostring(pLua_, -1); 00319 lua_settop(pLua_, uiFuncPos-1); 00320 throw exception(sError); 00321 } 00322 else 00323 { 00324 lua_settop(pLua_, uiFuncPos-1); 00325 throw exception("state", "Unhandled error."); 00326 } 00327 } 00328 00329 int iError = lua_pcall(pLua_, 0, LUA_MULTRET, -2); 00330 if (iError != 0) 00331 { 00332 if (lua_isstring(pLua_, -1)) 00333 { 00334 std::string sError = lua_tostring(pLua_, -1); 00335 lua_settop(pLua_, uiFuncPos-1); 00336 throw exception(sError); 00337 } 00338 else 00339 { 00340 lua_settop(pLua_, uiFuncPos-1); 00341 throw exception("state", "Unhandled error."); 00342 } 00343 } 00344 00345 lua_remove(pLua_, uiFuncPos); 00346 #ifdef DEBUG_STACK 00347 Log("~do_string : "+get_top()+" "+sStr); 00348 #endif 00349 } 00350 00351 void state::call_function( const std::string& sfunctionName ) 00352 { 00353 #ifdef DEBUG_STACK 00354 Log("call_function : "+get_top()+" "+sfunctionName); 00355 #endif 00356 lua_pushcfunction(pLua_, pErrorFunction_); 00357 uint uiFuncPos = get_top(); 00358 00359 get_global(sfunctionName); 00360 00361 if (lua_isnil(pLua_, -1)) 00362 { 00363 lua_settop(pLua_, uiFuncPos-1); 00364 throw exception("state", "\""+sfunctionName+"\" doesn't exist."); 00365 } 00366 00367 if (!lua_isfunction(pLua_, -1)) 00368 { 00369 exception mExcept("state", "\""+sfunctionName+"\" is not a function ("+get_type_name(get_type())+" : "+get_value().to_string()+")."); 00370 lua_settop(pLua_, uiFuncPos-1); 00371 throw mExcept; 00372 } 00373 00374 int iError = lua_pcall(pLua_, 0, LUA_MULTRET, -2); 00375 if (iError != 0) 00376 { 00377 if (lua_isstring(pLua_, -1)) 00378 { 00379 std::string sError = lua_tostring(pLua_, -1); 00380 lua_settop(pLua_, uiFuncPos-1); 00381 throw exception(sError); 00382 } 00383 else 00384 { 00385 lua_settop(pLua_, uiFuncPos-1); 00386 throw exception("state", "Unhandled error."); 00387 } 00388 } 00389 00390 lua_remove(pLua_, uiFuncPos); 00391 #ifdef DEBUG_STACK 00392 Log("~call_function : "+get_top()+" "+sfunctionName); 00393 #endif 00394 } 00395 00396 void state::call_function(const std::string& sfunctionName, const std::vector<var>& lArgumentStack) 00397 { 00398 #ifdef DEBUG_STACK 00399 Log("call_function : "+get_top()+" "+sfunctionName+"(args)"); 00400 #endif 00401 lua_pushcfunction(pLua_, pErrorFunction_); 00402 uint uiFuncPos = get_top(); 00403 00404 get_global(sfunctionName); 00405 00406 if (lua_isnil(pLua_, -1)) 00407 { 00408 lua_settop(pLua_, uiFuncPos-1); 00409 throw exception("state", "\""+sfunctionName+"\" doesn't exist."); 00410 } 00411 00412 if (lua_isfunction(pLua_, -1)) 00413 { 00414 lua_settop(pLua_, uiFuncPos-1); 00415 throw exception("state", "\""+sfunctionName+"\" is not a function ("+get_type_name(get_type())+" : "+get_value().to_string()+")"); 00416 } 00417 00418 std::vector<var>::const_iterator iter; 00419 foreach (iter, lArgumentStack) 00420 push_var(*iter); 00421 00422 int iError = lua_pcall(pLua_, lArgumentStack.size(), LUA_MULTRET, -2-lArgumentStack.size()); 00423 if (iError != 0) 00424 { 00425 if (lua_isstring(pLua_, -1)) 00426 { 00427 std::string sError = lua_tostring(pLua_, -1); 00428 lua_settop(pLua_, uiFuncPos-1); 00429 throw exception(sError); 00430 } 00431 else 00432 { 00433 lua_settop(pLua_, uiFuncPos-1); 00434 throw exception("state", "Unhandled error."); 00435 } 00436 } 00437 00438 lua_remove(pLua_, uiFuncPos); 00439 #ifdef DEBUG_STACK 00440 Log("~call_function : "+get_top()+" "+sfunctionName+"(args)"); 00441 #endif 00442 } 00443 00444 void state::reg( const std::string& sfunctionName, c_function mFunction ) 00445 { 00446 lua_register(pLua_, sfunctionName.c_str(), mFunction); 00447 } 00448 00449 std::string state::format_error( const std::string& sError ) 00450 { 00451 push_string(sError); 00452 (*pErrorFunction_)(pLua_); 00453 std::string sResult = get_string(); 00454 pop(1); 00455 00456 return sResult; 00457 } 00458 00459 void state::print_error( const std::string& sError ) 00460 { 00461 (*pPrintFunction_)(format_error(sError)); 00462 } 00463 00464 void state::set_lua_error_function( c_function pFunc ) 00465 { 00466 if (pFunc != 0) 00467 pErrorFunction_ = pFunc; 00468 else 00469 pErrorFunction_ = &l_TreatError; 00470 } 00471 00472 void state::set_print_error_function( print_function pFunc ) 00473 { 00474 if (pFunc != 0) 00475 pPrintFunction_ = pFunc; 00476 else 00477 pPrintFunction_ = &default_print_function; 00478 } 00479 00480 bool state::is_serializable( int iIndex ) 00481 { 00482 if (lua_getmetatable(pLua_, iIndex)) 00483 { 00484 pop(); 00485 get_field("serialize", iIndex); 00486 if (get_type() == TYPE_FUNCTION) 00487 { 00488 pop(); 00489 return true; 00490 } 00491 pop(); 00492 } 00493 00494 type mType = get_type(iIndex); 00495 return (mType == TYPE_BOOLEAN) || (mType == TYPE_NUMBER) || 00496 (mType == TYPE_STRING) || (mType == TYPE_TABLE); 00497 } 00498 00499 std::string state::serialize_global( const std::string& sName ) 00500 { 00501 get_global(sName); 00502 00503 std::string sContent; 00504 if (is_serializable()) 00505 sContent = sName+" = "+serialize()+";"; 00506 00507 pop(); 00508 00509 return sContent; 00510 } 00511 00512 std::string state::serialize( const std::string& sTab, int iIndex ) 00513 { 00514 #ifdef DEBUG_STACK 00515 Log("serialize : "+get_top()+" "+sTab); 00516 #endif 00517 int iAbsoluteIndex = iIndex >= 0 ? iIndex : int(get_top()+1) + iIndex; 00518 std::string sResult; 00519 00520 if (lua_getmetatable(pLua_, iAbsoluteIndex)) 00521 { 00522 pop(); 00523 get_field("serialize", iAbsoluteIndex); 00524 if (get_type() == TYPE_FUNCTION) 00525 { 00526 pushValue(iAbsoluteIndex); 00527 push_string(sTab); 00528 int iError = lua_pcall(pLua_, 2, 1, 0); 00529 if (iError == 0) 00530 { 00531 sResult += get_string(); 00532 pop(); 00533 return sResult; 00534 } 00535 } 00536 else 00537 pop(); 00538 } 00539 00540 type mType = get_type(iIndex); 00541 switch (mType) 00542 { 00543 case TYPE_BOOLEAN : 00544 sResult += utils::to_string(get_bool(iIndex)); 00545 break; 00546 00547 case TYPE_NUMBER : 00548 sResult += utils::to_string(get_number(iIndex)); 00549 break; 00550 00551 case TYPE_STRING : 00552 sResult += "\""+get_string(iIndex)+"\""; 00553 break; 00554 00555 case TYPE_TABLE : 00556 { 00557 sResult += "{"; 00558 00559 std::string sContent = "\n"; 00560 pushValue(iIndex); 00561 push_nil(); 00562 while (lua_next(pLua_, -2) != 0) 00563 { 00564 if (is_serializable()) 00565 { 00566 sContent += sTab + " [" + serialize(sTab + " ", -2) + "] = " 00567 + serialize(sTab + " ", -1) + ",\n"; 00568 } 00569 pop(); 00570 } 00571 pop(); 00572 00573 if (sContent != "\n") 00574 sResult + sContent + sTab; 00575 00576 sResult += "}"; 00577 break; 00578 } 00579 00580 default : break; 00581 } 00582 00583 #ifdef DEBUG_STACK 00584 Log("~serialize : "+get_top()+" "+sTab); 00585 #endif 00586 00587 return sResult; 00588 } 00589 00590 void state::push_number( const double& dValue ) 00591 { 00592 lua_pushnumber(pLua_, dValue); 00593 } 00594 00595 void state::push_bool( bool bValue ) 00596 { 00597 lua_pushboolean(pLua_, bValue); 00598 } 00599 00600 void state::push_string( const std::string& sValue ) 00601 { 00602 lua_pushstring(pLua_, sValue.c_str()); 00603 } 00604 00605 void state::push_nil( uint uiNumber ) 00606 { 00607 for (uint ui = 0u; ui < uiNumber; ++ui) 00608 lua_pushnil(pLua_); 00609 } 00610 00611 void state::push_var( const var& vValue ) 00612 { 00613 const var_type& mType = vValue.get_type(); 00614 if (mType == var::VALUE_INT) push_number(vValue.get<int>()); 00615 else if (mType == var::VALUE_UINT) push_number(vValue.get<uint>()); 00616 else if (mType == var::VALUE_FLOAT) push_number(vValue.get<float>()); 00617 else if (mType == var::VALUE_DOUBLE) push_number(vValue.get<double>()); 00618 else if (mType == var::VALUE_STRING) push_string(vValue.get<std::string>()); 00619 else if (mType == var::VALUE_BOOL) push_bool(vValue.get<bool>()); 00620 else push_nil(); 00621 } 00622 00623 void state::pushValue( int iIndex ) 00624 { 00625 lua_pushvalue(pLua_, iIndex); 00626 } 00627 00628 void state::push_global( const std::string& sName ) 00629 { 00630 get_global(sName); 00631 } 00632 00633 void state::set_global( const std::string& sName ) 00634 { 00635 #ifdef DEBUG_STACK 00636 Log("set_global : "+get_top()+" "+sName); 00637 #endif 00638 std::deque<std::string> lDecomposedName; 00639 std::string sVarName; 00640 utils::string_vector lWords = utils::cut(sName, ":"); 00641 utils::string_vector::iterator iter1; 00642 foreach (iter1, lWords) 00643 { 00644 utils::string_vector lSubWords = utils::cut(*iter1, "."); 00645 utils::string_vector::iterator iter2; 00646 foreach (iter2, lSubWords) 00647 { 00648 lDecomposedName.push_back(*iter2); 00649 } 00650 } 00651 00652 // Start at 1 to pop the value the user has put on the stack. 00653 uint uiCounter = 1; 00654 00655 sVarName = lDecomposedName.back(); 00656 lDecomposedName.pop_back(); 00657 00658 if (lDecomposedName.size() >= 1) 00659 { 00660 lua_getglobal(pLua_, lDecomposedName.begin()->c_str()); 00661 lDecomposedName.pop_front(); 00662 ++uiCounter; 00663 00664 if (!lua_isnil(pLua_, -1)) 00665 { 00666 std::deque<std::string>::iterator iterWords; 00667 foreach (iterWords, lDecomposedName) 00668 { 00669 lua_getfield(pLua_, -1, iterWords->c_str()); 00670 ++uiCounter; 00671 if (lua_isnil(pLua_, -1)) 00672 { 00673 pop(uiCounter); 00674 return; 00675 } 00676 } 00677 } 00678 00679 lua_pushvalue(pLua_, (-uiCounter)); 00680 lua_setfield(pLua_, -2, sVarName.c_str()); 00681 pop(uiCounter); 00682 } 00683 else 00684 { 00685 lua_setglobal(pLua_, sName.c_str()); 00686 } 00687 #ifdef DEBUG_STACK 00688 Log("~set_global : "+get_top()+" "+sName); 00689 #endif 00690 } 00691 00692 void state::new_table() 00693 { 00694 #ifdef DEBUG_STACK 00695 Log("new_table : "+get_top()); 00696 #endif 00697 lua_newtable(pLua_); 00698 #ifdef DEBUG_STACK 00699 Log("~new_table : "+get_top()); 00700 #endif 00701 } 00702 00703 bool state::next( int iIndex ) 00704 { 00705 #ifdef DEBUG_STACK 00706 Log("next : "+get_top()); 00707 #endif 00708 int res = lua_next(pLua_, iIndex); 00709 #ifdef DEBUG_STACK 00710 Log("~next : "+get_top()); 00711 #endif 00712 return res != 0; 00713 } 00714 00715 void state::pop( uint uiNumber ) 00716 { 00717 #ifdef DEBUG_STACK 00718 Log("pop : "+get_top()+" "+uiNumber); 00719 #endif 00720 lua_pop(pLua_, static_cast<int>(uiNumber)); 00721 #ifdef DEBUG_STACK 00722 Log("~pop : "+get_top()+" "+uiNumber); 00723 #endif 00724 } 00725 00726 double state::get_number( int iIndex ) 00727 { 00728 return static_cast<float>(lua_tonumber(pLua_, iIndex)); 00729 } 00730 00731 bool state::get_bool( int iIndex ) 00732 { 00733 return lua_toboolean(pLua_, iIndex) != 0; 00734 } 00735 00736 std::string state::get_string( int iIndex ) 00737 { 00738 return lua_tostring(pLua_, iIndex); 00739 } 00740 00741 var state::get_value( int iIndex ) 00742 { 00743 int type = lua_type(pLua_, iIndex); 00744 switch (type) 00745 { 00746 case LUA_TBOOLEAN : return get_bool(iIndex); 00747 case LUA_TNUMBER : return get_number(iIndex); 00748 case LUA_TSTRING : return get_string(iIndex); 00749 default : return var(); 00750 } 00751 } 00752 00753 uint state::get_top() 00754 { 00755 return lua_gettop(pLua_); 00756 } 00757 00758 type state::get_type( int iIndex ) 00759 { 00760 int type = lua_type(pLua_, iIndex); 00761 switch (type) 00762 { 00763 case LUA_TBOOLEAN : return TYPE_BOOLEAN; 00764 case LUA_TFUNCTION : return TYPE_FUNCTION; 00765 case LUA_TLIGHTUSERDATA : return TYPE_LIGHTUSERDATA; 00766 case LUA_TNIL : return TYPE_NIL; 00767 case LUA_TNONE : return TYPE_NONE; 00768 case LUA_TNUMBER : return TYPE_NUMBER; 00769 case LUA_TSTRING : return TYPE_STRING; 00770 case LUA_TTABLE : return TYPE_TABLE; 00771 case LUA_TTHREAD : return TYPE_THREAD; 00772 case LUA_TUSERDATA : return TYPE_USERDATA; 00773 default : return TYPE_NONE; 00774 } 00775 } 00776 00777 std::string state::get_type_name( type mType ) 00778 { 00779 switch (mType) 00780 { 00781 case TYPE_BOOLEAN : return lua_typename(pLua_, LUA_TBOOLEAN); 00782 case TYPE_FUNCTION : return lua_typename(pLua_, LUA_TFUNCTION); 00783 case TYPE_LIGHTUSERDATA : return lua_typename(pLua_, LUA_TLIGHTUSERDATA); 00784 case TYPE_NIL : return lua_typename(pLua_, LUA_TNIL); 00785 case TYPE_NONE : return lua_typename(pLua_, LUA_TNONE); 00786 case TYPE_NUMBER : return lua_typename(pLua_, LUA_TNUMBER); 00787 case TYPE_STRING : return lua_typename(pLua_, LUA_TSTRING); 00788 case TYPE_TABLE : return lua_typename(pLua_, LUA_TTABLE); 00789 case TYPE_THREAD : return lua_typename(pLua_, LUA_TTHREAD); 00790 case TYPE_USERDATA : return lua_typename(pLua_, LUA_TUSERDATA); 00791 default : return ""; 00792 } 00793 } 00794 00795 void state::get_global( const std::string& sName ) 00796 { 00797 #ifdef DEBUG_STACK 00798 Log("get_global : "+get_top()+" "+sName); 00799 #endif 00800 std::deque<std::string> lDecomposedName; 00801 std::string sVarName; 00802 utils::string_vector lWords = utils::cut(sName, ":"); 00803 utils::string_vector::iterator iter1; 00804 foreach (iter1, lWords) 00805 { 00806 utils::string_vector lSubWords = utils::cut(*iter1, "."); 00807 utils::string_vector::iterator iter2; 00808 foreach (iter2, lSubWords) 00809 { 00810 lDecomposedName.push_back(*iter2); 00811 } 00812 } 00813 00814 lua_getglobal(pLua_, lDecomposedName.front().c_str()); 00815 00816 if (lDecomposedName.size() > 1) 00817 { 00818 if (lua_isnil(pLua_, -1)) 00819 return; 00820 00821 lDecomposedName.pop_front(); 00822 00823 std::deque<std::string>::iterator iterWords; 00824 foreach (iterWords, lDecomposedName) 00825 { 00826 lua_getfield(pLua_, -1, iterWords->c_str()); 00827 lua_remove(pLua_, -2); 00828 00829 if (lua_isnil(pLua_, -1)) 00830 return; 00831 00832 if (!lua_istable(pLua_, -1) && iterWords+1 != lDecomposedName.end()) 00833 { 00834 lua_pop(pLua_, 1); 00835 lua_pushnil(pLua_); 00836 return; 00837 } 00838 } 00839 } 00840 00841 #ifdef DEBUG_STACK 00842 Log("~get_global : "+get_top()+" "+sName); 00843 #endif 00844 } 00845 00846 int state::get_global_int( const std::string& sName, bool bCritical, int iDefaultValue ) 00847 { 00848 #ifdef DEBUG_STACK 00849 Log("get_global_int : "+get_top()+" "+sName); 00850 #endif 00851 int i; 00852 get_global(sName); 00853 if (lua_isnil(pLua_, -1)) 00854 { 00855 lua_pop(pLua_, 1); 00856 if (bCritical) 00857 { 00858 print_error("Missing " + sName + " attribute"); 00859 i = iDefaultValue; 00860 } 00861 else 00862 i = iDefaultValue; 00863 } 00864 else if (!lua_isnumber(pLua_, -1)) 00865 { 00866 lua_pop(pLua_, 1); 00867 print_error("\"" + sName + "\" is expected to be a number"); 00868 i = iDefaultValue; 00869 } 00870 else 00871 { 00872 i = (int)lua_tonumber(pLua_, -1); 00873 lua_pop(pLua_, 1); 00874 } 00875 #ifdef DEBUG_STACK 00876 Log("~get_global_int : "+get_top()+" "+sName); 00877 #endif 00878 return i; 00879 } 00880 00881 double state::get_global_double( const std::string& sName, bool bCritical, double fDefaultValue ) 00882 { 00883 #ifdef DEBUG_STACK 00884 Log("get_global_float : "+get_top()+" "+sName); 00885 #endif 00886 double f; 00887 get_global(sName); 00888 if (lua_isnil(pLua_, -1)) 00889 { 00890 lua_pop(pLua_, 1); 00891 if (bCritical) 00892 { 00893 print_error("Missing " + sName + " attribute"); 00894 f = fDefaultValue; 00895 } 00896 else 00897 f = fDefaultValue; 00898 } 00899 else if (!lua_isnumber(pLua_, -1)) 00900 { 00901 lua_pop(pLua_, 1); 00902 print_error("\"" + sName + "\" is expected to be a number"); 00903 f = fDefaultValue; 00904 } 00905 else 00906 { 00907 f = static_cast<double>(lua_tonumber(pLua_, -1)); 00908 lua_pop(pLua_, 1); 00909 } 00910 #ifdef DEBUG_STACK 00911 Log("~get_global_float : "+get_top()+" "+sName); 00912 #endif 00913 return f; 00914 } 00915 00916 std::string state::get_global_string( const std::string& sName, bool bCritical, const std::string& sDefaultValue ) 00917 { 00918 #ifdef DEBUG_STACK 00919 Log("get_global_string : "+get_top()+" "+sName); 00920 #endif 00921 std::string s; 00922 get_global(sName); 00923 if (lua_isnil(pLua_, -1)) 00924 { 00925 lua_pop(pLua_, 1); 00926 if (bCritical) 00927 { 00928 print_error("Missing " + sName + " attribute"); 00929 s = sDefaultValue; 00930 } 00931 else 00932 s = sDefaultValue; 00933 } 00934 else if (!lua_isstring(pLua_, -1)) 00935 { 00936 lua_pop(pLua_, 1); 00937 print_error("\"" + sName + "\" is expected to be a string"); 00938 s = sDefaultValue; 00939 } 00940 else 00941 { 00942 s = lua_tostring(pLua_, -1); 00943 lua_pop(pLua_, 1); 00944 } 00945 #ifdef DEBUG_STACK 00946 Log("~get_global_string : "+get_top()+" "+sName); 00947 #endif 00948 return s; 00949 } 00950 00951 bool state::get_global_bool( const std::string& sName, bool bCritical, bool bDefaultValue ) 00952 { 00953 #ifdef DEBUG_STACK 00954 Log("get_global_bool : "+get_top()+" "+sName); 00955 #endif 00956 bool b; 00957 get_global(sName); 00958 if (lua_isnil(pLua_, -1)) 00959 { 00960 lua_pop(pLua_, 1); 00961 if (bCritical) 00962 { 00963 print_error("Missing " + sName + " attribute"); 00964 b = bDefaultValue; 00965 } 00966 else 00967 b = bDefaultValue; 00968 } 00969 else if (!lua_isboolean(pLua_, -1)) 00970 { 00971 lua_pop(pLua_, 1); 00972 print_error("\"" + sName + "\" is expected to be a bool"); 00973 b = bDefaultValue; 00974 } 00975 else 00976 { 00977 b = (lua_toboolean(pLua_, -1) != 0); 00978 lua_pop(pLua_, 1); 00979 } 00980 #ifdef DEBUG_STACK 00981 Log("~get_global_bool : "+get_top()+" "+sName); 00982 #endif 00983 return b; 00984 } 00985 00986 void state::get_field( const std::string& sName, int iIndex ) 00987 { 00988 #ifdef DEBUG_STACK 00989 Log("get_field : "+get_top()+" "+sName); 00990 #endif 00991 lua_getfield(pLua_, iIndex, sName.c_str()); 00992 #ifdef DEBUG_STACK 00993 Log("~get_field : "+get_top()+" "+sName); 00994 #endif 00995 } 00996 00997 void state::get_field( int iID, int iIndex ) 00998 { 00999 #ifdef DEBUG_STACK 01000 Log("get_field : "+get_top()+" "+iID); 01001 #endif 01002 lua_pushnumber(pLua_, iID); 01003 if (iIndex >= 0) 01004 lua_gettable(pLua_, iIndex); 01005 else 01006 lua_gettable(pLua_, iIndex - 1); 01007 #ifdef DEBUG_STACK 01008 Log("~get_field : "+get_top()+" "+iID); 01009 #endif 01010 } 01011 01012 int state::get_field_int( const std::string& sName, bool bCritical, int iDefaultValue, bool bSetValue ) 01013 { 01014 #ifdef DEBUG_STACK 01015 Log("get_field_int : "+get_top()+" "+sName); 01016 #endif 01017 int i = 0; 01018 lua_getfield(pLua_, -1, sName.c_str()); 01019 if (lua_isnil(pLua_, -1)) 01020 { 01021 lua_pop(pLua_, 1); 01022 if (bCritical) 01023 print_error("Missing " + sName + " attribute"); 01024 else if (bSetValue) 01025 { 01026 set_field_int(sName, iDefaultValue); 01027 i = iDefaultValue; 01028 } 01029 else 01030 i = iDefaultValue; 01031 } 01032 else if (!lua_isnumber(pLua_, -1)) 01033 { 01034 print_error("Field is expected to be a number"); 01035 lua_pop(pLua_, 1); 01036 i = iDefaultValue; 01037 } 01038 else 01039 { 01040 i = (int)lua_tonumber(pLua_, -1); 01041 lua_pop(pLua_, 1); 01042 } 01043 #ifdef DEBUG_STACK 01044 Log("~get_field_int : "+get_top()+" "+sName); 01045 #endif 01046 return i; 01047 } 01048 01049 double state::get_field_double( const std::string& sName, bool bCritical, double fDefaultValue, bool bSetValue ) 01050 { 01051 #ifdef DEBUG_STACK 01052 Log("get_field_float : "+get_top()+" "+sName); 01053 #endif 01054 double f = 0.0f; 01055 lua_getfield(pLua_, -1, sName.c_str()); 01056 if (lua_isnil(pLua_, -1)) 01057 { 01058 lua_pop(pLua_, 1); 01059 if (bCritical) 01060 print_error("Missing " + sName + " attribute"); 01061 else if (bSetValue) 01062 { 01063 set_field_double(sName, fDefaultValue); 01064 f = fDefaultValue; 01065 } 01066 else 01067 f = fDefaultValue; 01068 } 01069 else if (!lua_isnumber(pLua_, -1)) 01070 { 01071 print_error("Field is expected to be a number"); 01072 lua_pop(pLua_, 1); 01073 f = fDefaultValue; 01074 } 01075 else 01076 { 01077 f = static_cast<double>(lua_tonumber(pLua_, -1)); 01078 lua_pop(pLua_, 1); 01079 01080 } 01081 #ifdef DEBUG_STACK 01082 Log("~get_field_float : "+get_top()+" "+sName); 01083 #endif 01084 return f; 01085 } 01086 01087 std::string state::get_field_string( const std::string& sName, bool bCritical, const std::string& sDefaultValue, bool bSetValue ) 01088 { 01089 #ifdef DEBUG_STACK 01090 Log("get_field_string : "+get_top()+" "+sName); 01091 #endif 01092 std::string s; 01093 lua_getfield(pLua_, -1, sName.c_str()); 01094 if (lua_isnil(pLua_, -1)) 01095 { 01096 lua_pop(pLua_, 1); 01097 if (bCritical) 01098 print_error("Missing " + sName + " attribute"); 01099 else if (bSetValue) 01100 { 01101 set_field_string(sName, sDefaultValue); 01102 s = sDefaultValue; 01103 } 01104 else 01105 s = sDefaultValue; 01106 } 01107 else if (!lua_isstring(pLua_, -1)) 01108 { 01109 print_error("Field is expected to be a string"); 01110 lua_pop(pLua_, 1); 01111 s = sDefaultValue; 01112 } 01113 else 01114 { 01115 s = lua_tostring(pLua_, -1); 01116 lua_pop(pLua_, 1); 01117 } 01118 #ifdef DEBUG_STACK 01119 Log("~get_field_string : "+get_top()+" "+sName); 01120 #endif 01121 return s; 01122 } 01123 01124 bool state::get_field_bool( const std::string& sName, bool bCritical, bool bDefaultValue, bool bSetValue ) 01125 { 01126 #ifdef DEBUG_STACK 01127 Log("get_fieldBool : "+get_top()+" "+sName); 01128 #endif 01129 bool b = false; 01130 lua_getfield(pLua_, -1, sName.c_str()); 01131 if (lua_isnil(pLua_, -1)) 01132 { 01133 lua_pop(pLua_, 1); 01134 if (bCritical) 01135 print_error("Missing " + sName + " attribute"); 01136 else if (bSetValue) 01137 { 01138 set_field_bool(sName, bDefaultValue); 01139 b = bDefaultValue; 01140 } 01141 else 01142 b = bDefaultValue; 01143 } 01144 else if (!lua_isboolean(pLua_, -1)) 01145 { 01146 print_error("Field is expected to be a bool"); 01147 lua_pop(pLua_, 1); 01148 b = bDefaultValue; 01149 } 01150 else 01151 { 01152 b = (lua_toboolean(pLua_, -1) != 0); 01153 lua_pop(pLua_, 1); 01154 } 01155 #ifdef DEBUG_STACK 01156 Log("~get_fieldBool : "+get_top()+" "+sName); 01157 #endif 01158 return b; 01159 } 01160 01161 void state::set_field( const std::string& sName ) 01162 { 01163 #ifdef DEBUG_STACK 01164 Log("set_field : "+get_top()+" "+sName); 01165 #endif 01166 lua_pushstring(pLua_, sName.c_str()); 01167 lua_pushvalue(pLua_, -2); 01168 lua_settable(pLua_, -4); 01169 lua_pop(pLua_, 1); 01170 #ifdef DEBUG_STACK 01171 Log("~set_field : "+get_top()+" "+sName); 01172 #endif 01173 } 01174 01175 void state::set_field( int iID ) 01176 { 01177 #ifdef DEBUG_STACK 01178 Log("set_field : "+get_top()+" "+iID); 01179 #endif 01180 lua_pushnumber(pLua_, iID); 01181 lua_pushvalue(pLua_, -2); 01182 lua_settable(pLua_, -4); 01183 lua_pop(pLua_, 1); 01184 #ifdef DEBUG_STACK 01185 Log("~set_field : "+get_top()+" "+iID); 01186 #endif 01187 } 01188 01189 void state::set_field_int( const std::string& sName, int iValue ) 01190 { 01191 #ifdef DEBUG_STACK 01192 Log("set_field_int : "+get_top()+" "+sName); 01193 #endif 01194 lua_pushstring(pLua_, sName.c_str()); 01195 lua_pushnumber(pLua_, iValue); 01196 lua_settable(pLua_, -3); 01197 #ifdef DEBUG_STACK 01198 Log("~set_field_int : "+get_top()+" "+sName); 01199 #endif 01200 } 01201 01202 void state::set_field_double( const std::string& sName, double fValue ) 01203 { 01204 #ifdef DEBUG_STACK 01205 Log("set_field_double : "+get_top()+" "+sName); 01206 #endif 01207 lua_pushstring(pLua_, sName.c_str()); 01208 lua_pushnumber(pLua_, fValue); 01209 lua_settable(pLua_, -3); 01210 #ifdef DEBUG_STACK 01211 Log("~set_field_double : "+get_top()+" "+sName); 01212 #endif 01213 } 01214 01215 void state::set_field_string( const std::string& sName, const std::string& sValue ) 01216 { 01217 #ifdef DEBUG_STACK 01218 Log("set_field_string : "+get_top()+" "+sName); 01219 #endif 01220 lua_pushstring(pLua_, sName.c_str()); 01221 lua_pushstring(pLua_, sValue.c_str()); 01222 lua_settable(pLua_, -3); 01223 #ifdef DEBUG_STACK 01224 Log("~set_field_string : "+get_top()+" "+sName); 01225 #endif 01226 } 01227 01228 void state::set_field_bool( const std::string& sName, bool bValue ) 01229 { 01230 #ifdef DEBUG_STACK 01231 Log("set_field_bool : "+get_top()+" "+sName); 01232 #endif 01233 lua_pushstring(pLua_, sName.c_str()); 01234 lua_pushboolean(pLua_, bValue); 01235 lua_settable(pLua_, -3); 01236 #ifdef DEBUG_STACK 01237 Log("~set_field_bool : "+get_top()+" "+sName); 01238 #endif 01239 } 01240 01241 void state::set_field_int( int iID, int iValue ) 01242 { 01243 #ifdef DEBUG_STACK 01244 Log("set_field_int : "+get_top()+" "+iID); 01245 #endif 01246 lua_pushnumber(pLua_, iID); 01247 lua_pushnumber(pLua_, iValue); 01248 lua_settable(pLua_, -3); 01249 #ifdef DEBUG_STACK 01250 Log("~set_field_int : "+get_top()+" "+iID); 01251 #endif 01252 } 01253 01254 void state::set_field_double( int iID, double fValue ) 01255 { 01256 #ifdef DEBUG_STACK 01257 Log("set_field_double : "+get_top()+" "+iID); 01258 #endif 01259 lua_pushnumber(pLua_, iID); 01260 lua_pushnumber(pLua_, fValue); 01261 lua_settable(pLua_, -3); 01262 #ifdef DEBUG_STACK 01263 Log("~set_field_double : "+get_top()+" "+iID); 01264 #endif 01265 } 01266 01267 void state::set_field_string( int iID, const std::string& sValue ) 01268 { 01269 #ifdef DEBUG_STACK 01270 Log("set_field_string : "+get_top()+" "+iID); 01271 #endif 01272 lua_pushnumber(pLua_, iID); 01273 lua_pushstring(pLua_, sValue.c_str()); 01274 lua_settable(pLua_, -3); 01275 #ifdef DEBUG_STACK 01276 Log("~set_field_string : "+get_top()+" "+iID); 01277 #endif 01278 } 01279 01280 void state::set_field_bool( int iID, bool bValue ) 01281 { 01282 #ifdef DEBUG_STACK 01283 Log("set_field_bool : "+get_top()+" "+iID); 01284 #endif 01285 lua_pushnumber(pLua_, iID); 01286 lua_pushboolean(pLua_, bValue); 01287 lua_settable(pLua_, -3); 01288 #ifdef DEBUG_STACK 01289 Log("~set_field_bool : "+get_top()+" "+iID); 01290 #endif 01291 } 01292 01293 void state::set_top( uint uiSize ) 01294 { 01295 #ifdef DEBUG_STACK 01296 Log("SetTop : "+uiSize); 01297 #endif 01298 lua_settop(pLua_, uiSize); 01299 } 01300 }