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