00001
00002
00003
00004
00005
00006
00007
00009
00017 #ifndef __SCRIPT_READ_HEADER__
00018 #define __SCRIPT_READ_HEADER__
00019
00020 #include "utils.h"
00021 #include "defs.h"
00022
00023 #include "script.h"
00024
00025 namespace hoa_script {
00026
00027 namespace private_script {
00028
00037 const int32 INTEGER_TYPE = 0x12345678;
00038 const int32 UINTEGER_TYPE = 0x87654321;
00039 const int32 FLOAT_TYPE = 0x12344321;
00041
00042 }
00043
00070 class ReadScriptDescriptor : public ScriptDescriptor {
00071 friend class GameScript;
00072 public:
00073 virtual ~ReadScriptDescriptor();
00074
00080 virtual bool OpenFile(const std::string& file_name);
00081 virtual bool OpenFile();
00082 virtual void CloseFile();
00084
00099 bool DoesVariableExist(const std::string& key)
00100 { return _DoesDataExist(key, LUA_TNIL); }
00101
00102 bool DoesVariableExist(int32 key)
00103 { return _DoesDataExist(key, LUA_TNIL); }
00104
00105 bool DoesBoolExist(const std::string& key)
00106 { return _DoesDataExist(key, LUA_TBOOLEAN); }
00107
00108 bool DoesBoolExist(int32 key)
00109 { return _DoesDataExist(key, LUA_TBOOLEAN); }
00110
00111 bool DoesIntExist(const std::string& key)
00112 { return _DoesDataExist(key, private_script::INTEGER_TYPE); }
00113
00114 bool DoesIntExist(int32 key)
00115 { return _DoesDataExist(key, private_script::INTEGER_TYPE); }
00116
00117 bool DoesUIntExist(const std::string& key)
00118 { return _DoesDataExist(key, private_script::UINTEGER_TYPE); }
00119
00120 bool DoesUIntExist(int32 key)
00121 { return _DoesDataExist(key, private_script::UINTEGER_TYPE); }
00122
00123 bool DoesFloatExist(const std::string& key)
00124 { return _DoesDataExist(key, private_script::FLOAT_TYPE); }
00125
00126 bool DoesFloatExist(int32 key)
00127 { return _DoesDataExist(key, private_script::FLOAT_TYPE); }
00128
00129 bool DoesStringExist(const std::string& key)
00130 { return _DoesDataExist(key, LUA_TSTRING); }
00131
00132 bool DoesStringExist(int32 key)
00133 { return _DoesDataExist(key, LUA_TSTRING); }
00134
00135 bool DoesFunctionExist(const std::string& key)
00136 { return _DoesDataExist(key, LUA_TFUNCTION); }
00137
00138 bool DoesFunctionExist(int32 key)
00139 { return _DoesDataExist(key, LUA_TFUNCTION); }
00140
00141 bool DoesTableExist(const std::string& key)
00142 { return _DoesDataExist(key, LUA_TTABLE); }
00143
00144 bool DoesTableExist(int32 key)
00145 { return _DoesDataExist(key, LUA_TTABLE); }
00147
00157 bool ReadBool(const std::string& key)
00158 { return _ReadData<bool>(key, false); }
00159
00160 bool ReadBool(int32 key)
00161 { return _ReadData<bool>(key, false); }
00162
00163 int32 ReadInt(const std::string& key)
00164 { return _ReadData<int32>(key, 0); }
00165
00166 int32 ReadInt(int32 key)
00167 { return _ReadData<uint32>(key, 0); }
00168
00169 uint32 ReadUInt(const std::string& key)
00170 { return _ReadData<int32>(key, 0); }
00171
00172 uint32 ReadUInt(int32 key)
00173 { return _ReadData<uint32>(key, 0); }
00174
00175 float ReadFloat(const std::string& key)
00176 { return _ReadData<float>(key, 0.0f); }
00177
00178 float ReadFloat(int32 key)
00179 { return _ReadData<float>(key, 0.0f); }
00180
00181 std::string ReadString(const std::string& key)
00182 { return _ReadData<std::string>(key, ""); }
00183
00184 std::string ReadString(int32 key)
00185 { return _ReadData<std::string>(key, ""); }
00186
00187 hoa_utils::ustring ReadUString(const std::string& key)
00188 { return _ReadData<hoa_utils::ustring>(key, hoa_utils::MakeUnicodeString("")); }
00189
00190 hoa_utils::ustring ReadUString(int32 key)
00191 { return _ReadData<hoa_utils::ustring>(key, hoa_utils::MakeUnicodeString("")); }
00193
00207 void ReadBoolVector(const std::string& key, std::vector<bool>& vect)
00208 { _ReadDataVector<bool>(key, vect); }
00209
00210 void ReadBoolVector(int32 key, std::vector<bool>& vect)
00211 { _ReadDataVector<bool>(key, vect); }
00212
00213 void ReadIntVector(const std::string& key, std::vector<int32>& vect)
00214 { _ReadDataVector<int32>(key, vect); }
00215
00216 void ReadIntVector(int32 key, std::vector<int32>& vect)
00217 { _ReadDataVector<int32>(key, vect); }
00218
00219 void ReadUIntVector(const std::string& key, std::vector<uint32>& vect)
00220 { _ReadDataVector<uint32>(key, vect); }
00221
00222 void ReadUIntVector(int32 key, std::vector<uint32>& vect)
00223 { _ReadDataVector<uint32>(key, vect); }
00224
00225 void ReadFloatVector(const std::string& key, std::vector<float>& vect)
00226 { _ReadDataVector<float>(key, vect); }
00227
00228 void ReadFloatVector(int32 key, std::vector<float>& vect)
00229 { _ReadDataVector<float>(key, vect); }
00230
00231 void ReadStringVector(const std::string& key, std::vector<std::string>& vect)
00232 { _ReadDataVector<std::string>(key, vect); }
00233
00234 void ReadStringVector(int32 key, std::vector<std::string>& vect)
00235 { _ReadDataVector<std::string>(key, vect); }
00236
00237 void ReadUStringVector(const std::string& key, std::vector<hoa_utils::ustring>& vect)
00238 { _ReadDataVector<hoa_utils::ustring>(key, vect); }
00239
00240 void ReadUStringVector(int32 key, std::vector<hoa_utils::ustring>& vect)
00241 { _ReadDataVector<hoa_utils::ustring>(key, vect); }
00243
00251 luabind::object ReadFunctionPointer(const std::string& key);
00252
00254 luabind::object ReadFunctionPointer(int32 key);
00256
00263
00264 void OpenTable(const std::string& table_name);
00265
00269 void OpenTable(int32 table_name);
00270
00272 void CloseTable();
00273
00275 void CloseAllTables();
00276
00280 uint32 GetTableSize(const std::string& table_name);
00281
00286 uint32 GetTableSize(int32 table_name);
00287
00289 uint32 GetTableSize();
00290
00307 void ReadTableKeys(std::vector<std::string>& keys)
00308 { _ReadTableKeys(keys); }
00309
00310 void ReadTableKeys(std::vector<int32>& keys)
00311 { _ReadTableKeys(keys); }
00312
00313 void ReadTableKeys(std::vector<uint32>& keys)
00314 { _ReadTableKeys(keys); }
00315
00316 void ReadTableKeys(const std::string& table_name, std::vector<std::string>& keys)
00317 { OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
00318
00319 void ReadTableKeys(const std::string& table_name, std::vector<int32>& keys)
00320 { OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
00321
00322 void ReadTableKeys(const std::string& table_name, std::vector<uint32>& keys)
00323 { OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
00324
00325 void ReadTableKeys(int32 table_name, std::vector<std::string>& keys)
00326 { OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
00327
00328 void ReadTableKeys(int32 table_name, std::vector<int32>& keys)
00329 { OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
00330
00331 void ReadTableKeys(int32 table_name, std::vector<uint32>& keys)
00332 { OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
00334
00335
00337 lua_State* GetLuaState()
00338 { return _lstack; }
00339
00343 void DEBUG_PrintLuaStack();
00344
00346 void DEBUG_PrintGlobals();
00347
00348 protected:
00350 lua_State *_lstack;
00351
00360 bool _DoesDataExist(const std::string& key, int32 type);
00361 bool _DoesDataExist(int32 key, int32 type);
00362
00368 bool _CheckDataType(int32 type, luabind::object& obj_check);
00370
00379 template <class T> T _ReadData(const std::string& key, T default_value);
00380 template <class T> T _ReadData(int32 key, T default_value);
00382
00390 template <class T> void _ReadDataVector(const std::string& key, std::vector<T>& vect);
00391 template <class T> void _ReadDataVector(int32 key, std::vector<T>& vect);
00393 template <class T> void _ReadDataVectorHelper(std::vector<T>& vect);
00395
00402 template <class T> void _ReadTableKeys(std::vector<T>& keys);
00403 };
00404
00405
00406
00407
00408
00409 template <class T> T ReadScriptDescriptor::_ReadData(const std::string &key, T default_value) {
00410
00411 if (_open_tables.size() == 0) {
00412 lua_getglobal(_lstack, key.c_str());
00413 luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
00414
00415 if (!o) {
00416 _error_messages << "* _ReadData() was unable to access the global variable: " << key << std::endl;
00417 return default_value;
00418 }
00419
00420 try {
00421 T ret_val = luabind::object_cast<T>(o);
00422 lua_pop(_lstack, 1);
00423 return ret_val;
00424 }
00425 catch (...) {
00426 _error_messages << "* _ReadData() was unable to cast value to correct type for global variable: " << key << std::endl;
00427 return default_value;
00428 }
00429 }
00430
00431 else {
00432 luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
00433 if (luabind::type(o) != LUA_TTABLE) {
00434 _error_messages << "* _ReadData() failed because the top of the stack was not a table when trying to read variable: " << key << std::endl;
00435 return default_value;
00436 }
00437
00438 try {
00439 return luabind::object_cast<T>(o[key]);
00440 }
00441 catch (...) {
00442 _error_messages << "* _ReadData() was unable to access the table variable: " << key << std::endl;
00443 return default_value;
00444 }
00445 }
00446 return default_value;
00447 }
00448
00449
00450
00451 template <class T> T ReadScriptDescriptor::_ReadData(int32 key, T default_value) {
00452 if (_open_tables.size() == 0) {
00453 _error_messages << "* _ReadData() failed because no tables were open when trying to access the table variable: "
00454 << key << std::endl;
00455 return default_value;
00456 }
00457
00458 luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
00459 if (luabind::type(o) != LUA_TTABLE) {
00460 _error_messages << "* _ReadData() failed because the top of the stack was not a table when trying to read variable: "
00461 << key << std::endl;
00462 return default_value;
00463 }
00464
00465 try {
00466 return luabind::object_cast<T>(o[key]);
00467 }
00468 catch (...) {
00469 _error_messages << "* _ReadData() was unable to access the table variable: "
00470 << key << std::endl;
00471 return default_value;
00472 }
00473
00474 return default_value;
00475 }
00476
00477
00478
00479 template <class T> void ReadScriptDescriptor::_ReadDataVector(const std::string& key, std::vector<T>& vect) {
00480
00481 OpenTable(key);
00482 _ReadDataVectorHelper(vect);
00483 CloseTable();
00484 }
00485
00486
00487
00488 template <class T> void ReadScriptDescriptor::_ReadDataVector(int32 key, std::vector<T>& vect) {
00489 if (_open_tables.size() == 0) {
00490 _error_messages << "* _ReadDataVector() failed because no tables were open when trying to access the table variable: "
00491 << key << std::endl;;
00492 return;
00493 }
00494
00495
00496 OpenTable(key);
00497 _ReadDataVectorHelper(vect);
00498 CloseTable();
00499 }
00500
00501
00502
00503 template <class T> void ReadScriptDescriptor::_ReadDataVectorHelper(std::vector<T>& vect) {
00504 luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
00505
00506 if (luabind::type(o) != LUA_TTABLE) {
00507 _error_messages << "* _ReadDataVectorHelper() failed because the top of the stack was not a table" << std::endl;
00508 return;
00509 }
00510
00511
00512 for (luabind::iterator it(o); it != private_script::TABLE_END; it++) {
00513 try {
00514 vect.push_back(luabind::object_cast<T>((*it)));
00515 }
00516 catch (...) {
00517 _error_messages << "* _ReadDataVectorHelper() failed due to a type cast failure when reading the table" << std::endl;
00518 }
00519 }
00520 }
00521
00522
00523
00524 template <class T> void ReadScriptDescriptor::_ReadTableKeys(std::vector<T>& keys) {
00525 keys.clear();
00526
00527 if (_open_tables.size() == 0) {
00528 _error_messages << "* _ReadTableKeys() failed because there were no open tables to get the keys of" << std::endl;
00529 return;
00530 }
00531
00532 luabind::object table(luabind::from_stack(_lstack, private_script::STACK_TOP));
00533
00534 if (luabind::type(table) != LUA_TTABLE) {
00535 _error_messages << "* _ReadTableKeys() failed because the top of the stack was not a table" << std::endl;
00536 return;
00537 }
00538
00539 for (luabind::iterator i(table); i != private_script::TABLE_END; i++) {
00540 try {
00541 keys.push_back(luabind::object_cast<T>(i.key()));
00542 }
00543 catch (...) {
00544 _error_messages << "* _ReadTableKeys() failed due to a type cast failure when retrieving a table key" << std::endl;
00545 keys.clear();
00546 return;
00547 }
00548 }
00549 }
00550
00551 }
00552
00553 #endif // __SCRIPT_READ_HEADER__