00001
00002
00003
00004
00005
00006
00007
00009
00017 #include "utils.h"
00018
00019 #include "script.h"
00020 #include "script_read.h"
00021
00022 using namespace std;
00023 using namespace luabind;
00024
00025 using namespace hoa_utils;
00026 using namespace hoa_script::private_script;
00027
00028 namespace hoa_script {
00029
00030 ReadScriptDescriptor::~ReadScriptDescriptor() {
00031 if (IsFileOpen()) {
00032 if (SCRIPT_DEBUG)
00033 cerr << "SCRIPT WARNING: ReadScriptDescriptor destructor was called when file was still open: "
00034 << _filename << endl;
00035 CloseFile();
00036 }
00037
00038 _filename = "";
00039 _access_mode = SCRIPT_CLOSED;
00040 _error_messages.clear();
00041 _open_tables.clear();
00042 }
00043
00044
00045
00046
00047
00048 bool ReadScriptDescriptor::OpenFile(const string& file_name) {
00049 if (ScriptManager->IsFileOpen(file_name) == true) {
00050 if (SCRIPT_DEBUG)
00051 cerr << "SCRIPT WARNING: ReadScriptDescriptor::OpenFile() attempted to open file that is already opened: "
00052 << file_name << endl;
00053 return false;
00054 }
00055
00056
00057
00058 lua_checkstack(ScriptManager->GetGlobalState(),1);
00059 _lstack = lua_newthread(ScriptManager->GetGlobalState());
00060
00061
00062 if (lua_dofile(_lstack, file_name.c_str()) != 0) {
00063 cerr << "SCRIPT ERROR: ReadScriptDescriptor::OpenFile() could not open the file " << file_name << endl;
00064 _access_mode = SCRIPT_CLOSED;
00065 return false;
00066 }
00067
00068 _filename = file_name;
00069 _access_mode = SCRIPT_READ;
00070 ScriptManager->_AddOpenFile(this);
00071 return true;
00072 }
00073
00074
00075
00076 bool ReadScriptDescriptor::OpenFile() {
00077 if (_filename == "") {
00078 if (SCRIPT_DEBUG)
00079 cerr << "SCRIPT ERROR: ReadScriptDescriptor::OpenFile(), could not open file "
00080 << "because of an invalid file name (empty string)." << endl;
00081 return false;
00082 }
00083
00084 return OpenFile(_filename);
00085 }
00086
00087
00088
00089 void ReadScriptDescriptor::CloseFile() {
00090 if (IsFileOpen() == false) {
00091 if (SCRIPT_DEBUG)
00092 cerr << "SCRIPT ERROR: ReadScriptDescriptor::CloseFile() could not close the "
00093 << "file because it was not open." << endl;
00094 return;
00095 }
00096
00097 if (SCRIPT_DEBUG && IsErrorDetected()) {
00098 cerr << "SCRIPT WARNING: In ReadScriptDescriptor::CloseFile(), the file " << _filename
00099 << " had error messages remaining. They are as follows:" << endl;
00100 cerr << _error_messages.str() << endl;
00101 }
00102
00103 _lstack = NULL;
00104 _error_messages.clear();
00105 _open_tables.clear();
00106 _access_mode = SCRIPT_CLOSED;
00107 ScriptManager->_RemoveOpenFile(this);
00108 }
00109
00110
00111
00112
00113
00114 bool ReadScriptDescriptor::_DoesDataExist(const string& key, int32 type) {
00115
00116 if (_open_tables.size() == 0) {
00117 lua_getglobal(_lstack, key.c_str());
00118 luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
00119 return _CheckDataType(type, o);
00120 }
00121
00122 else {
00123 luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
00124 if (luabind::type(o) != LUA_TTABLE) {
00125 _error_messages << "* _DoesDataExist() failed because the top of the stack was not "
00126 << "a table when trying to check for the table member: " << key << endl;
00127 return false;
00128 }
00129
00130 luabind::object obj(o[key]);
00131 return _CheckDataType(type, obj);
00132 }
00133 }
00134
00135
00136
00137 bool ReadScriptDescriptor::_DoesDataExist(int32 key, int32 type) {
00138 if (_open_tables.size() == 0) {
00139 _error_messages << "* _DoesDataExist() failed because no tables were open when trying to "
00140 << "examine the table member: " << key << endl;
00141 return false;
00142 }
00143
00144 luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
00145 if (luabind::type(o) != LUA_TTABLE) {
00146 _error_messages << "* _DoesDataExist() failed because the top of the stack was not "
00147 << "a table when trying to check for the table member: " << key << endl;
00148 return false;
00149 }
00150
00151 luabind::object obj(o[key]);
00152 return _CheckDataType(type, obj);
00153 }
00154
00155
00156
00157 bool ReadScriptDescriptor::_CheckDataType(int32 type, luabind::object& obj_check) {
00158 int32 object_type = luabind::type(obj_check);
00159
00160 if (obj_check.is_valid() == false)
00161 return false;
00162
00163
00164
00165 if (type == LUA_TNIL) {
00166 return true;
00167 }
00168
00169
00170 else if (type == object_type) {
00171 return true;
00172 }
00173
00174
00175
00176 else if (object_type == LUA_TNUMBER) {
00177 if (type == INTEGER_TYPE) {
00178 try {
00179 luabind::object_cast<int32>(obj_check);
00180 lua_pop(_lstack, 1);
00181 return true;
00182 }
00183 catch (...) {
00184 return false;
00185 }
00186 }
00187 else if (type == UINTEGER_TYPE) {
00188 try {
00189 luabind::object_cast<uint32>(obj_check);
00190 lua_pop(_lstack, 1);
00191 return true;
00192 }
00193 catch (...) {
00194 return false;
00195 }
00196 }
00197 else if (type == FLOAT_TYPE) {
00198 try {
00199 luabind::object_cast<float>(obj_check);
00200 lua_pop(_lstack, 1);
00201 return true;
00202 }
00203 catch (...) {
00204 return false;
00205 }
00206 }
00207 }
00208
00209 else {
00210 return false;
00211 }
00212 }
00213
00214
00215
00216
00217
00218 object ReadScriptDescriptor::ReadFunctionPointer(const string& key) {
00219 if (_open_tables.size() == 0) {
00220 lua_getglobal(_lstack, key.c_str());
00221
00222 luabind::object o(from_stack(_lstack, STACK_TOP));
00223
00224 if (!o) {
00225 _error_messages << "* ReadFunctionPointer() failed because it was unable to access the function "
00226 << "for the global key: " << key << endl;
00227 return luabind::object();
00228 }
00229
00230 if (type(o) != LUA_TFUNCTION) {
00231 _error_messages << "* ReadFunctionPointer() failed because the data retrieved was not a function "
00232 << "for the global key: " << key << endl;
00233 return luabind::object();
00234 }
00235
00236 return o;
00237 }
00238
00239 else {
00240 luabind::object o(from_stack(_lstack, STACK_TOP));
00241 if (type(o) != LUA_TTABLE) {
00242 _error_messages << "* ReadFunctionPointer() failed because the top of the stack was not a table "
00243 << "for the table element key: " << key << endl;
00244 return luabind::object();
00245 }
00246
00247 if (type(o[key]) != LUA_TFUNCTION) {
00248 _error_messages << "* ReadFunctionPointer() failed because the data retrieved was not a function "
00249 << "for the table element key: " << key << endl;
00250 return luabind::object();
00251 }
00252
00253 return o[key];
00254 }
00255 }
00256
00257
00258
00259 object ReadScriptDescriptor::ReadFunctionPointer(int32 key) {
00260
00261 luabind::object o(from_stack(_lstack, STACK_TOP));
00262 if (type(o) != LUA_TTABLE) {
00263 _error_messages << "* _ReadFunctionPointer() failed because the top of the stack was not a table "
00264 << "for the table element key: " << key << endl;
00265 return o;
00266 }
00267
00268 if (type(o[key]) != LUA_TFUNCTION) {
00269 _error_messages << "* _ReadFunctionPointer() failed because the data retrieved was not a function "
00270 << "for the table element key: " << key << endl;
00271 return o;
00272 }
00273
00274 return o[key];
00275 }
00276
00277
00278
00279
00280
00281 void ReadScriptDescriptor::OpenTable(const string& table_name) {
00282 if (_open_tables.size() == 0) {
00283 lua_getglobal(_lstack, table_name.c_str());
00284 if (!lua_istable(_lstack, STACK_TOP)) {
00285 _error_messages << "* OpenTable() failed because the data retrieved was not a table "
00286 << "or did not exist for the global key " << table_name << endl;
00287 return;
00288 }
00289 _open_tables.push_back(table_name);
00290 }
00291
00292 else {
00293 lua_pushstring(_lstack, table_name.c_str());
00294 lua_gettable(_lstack, STACK_TOP - 1);
00295 if (!lua_istable(_lstack, STACK_TOP)) {
00296 _error_messages << "* OpenTable() failed because the data retrieved was not a table "
00297 << "or did not exist for the table element key " << table_name << endl;
00298 return;
00299 }
00300 _open_tables.push_back(table_name);
00301 }
00302 }
00303
00304
00305
00306 void ReadScriptDescriptor::OpenTable(int32 table_name) {
00307
00308 if (_open_tables.size() == 0) {
00309 _error_messages << "* OpenTable() failed because there were no tables open when trying "
00310 << "to open the with the element key " << table_name << endl;
00311 return;
00312 }
00313
00314 lua_pushnumber(_lstack, table_name);
00315 lua_gettable(_lstack, STACK_TOP - 1);
00316 if (!lua_istable(_lstack, STACK_TOP)) {
00317 _error_messages << "* OpenTable() failed because the data retrieved was not a table "
00318 << "or did not exist for the table element key " << table_name << endl;
00319 return;
00320 }
00321
00322 _open_tables.push_back(NumberToString(table_name));
00323 }
00324
00325
00326
00327 void ReadScriptDescriptor::CloseTable() {
00328 if (_open_tables.size() == 0) {
00329 _error_messages << "* CloseTable() failed because there were no open tables to close" << endl;
00330 return;
00331 }
00332
00333 _open_tables.pop_back();
00334 lua_pop(_lstack, 1);
00335 }
00336
00337
00338
00339 void ReadScriptDescriptor::CloseAllTables() {
00340 while (_open_tables.size() != 0) {
00341 CloseTable();
00342 }
00343 }
00344
00345
00346
00347 uint32 ReadScriptDescriptor::GetTableSize(const string& table_name) {
00348 uint32 size = 0;
00349
00350 OpenTable(table_name);
00351 size = GetTableSize();
00352 CloseTable();
00353 return size;
00354 }
00355
00356
00357
00358 uint32 ReadScriptDescriptor::GetTableSize(int32 table_name) {
00359 uint32 size = 0;
00360
00361 OpenTable(table_name);
00362 size = GetTableSize();
00363 CloseTable();
00364
00365 return size;
00366 }
00367
00368
00369
00370 uint32 ReadScriptDescriptor::GetTableSize() {
00371 if (_open_tables.size() == 0) {
00372 _error_messages << "* GetTableSize() failed because there were no open tables to get the size of" << endl;
00373 return 0;
00374 }
00375
00376 return static_cast<uint32>(luaL_getn(_lstack, STACK_TOP));
00377 }
00378
00379
00380
00381
00382
00383 void ReadScriptDescriptor::DEBUG_PrintLuaStack() {
00384 int32 type;
00385
00386 cout << "SCRIPT DEBUG: Printing script's lua stack:" << endl;
00387 for (int32 i = lua_gettop(_lstack); i > 0; i--) {
00388 type = lua_type(_lstack, i);
00389 switch (type) {
00390 case LUA_TNIL:
00391 cout << "* " << i << "= NIL" << endl;
00392 break;
00393 case LUA_TBOOLEAN:
00394 cout << "* " << i << "= BOOLEAN: " << lua_toboolean(_lstack, i) << endl;
00395 break;
00396 case LUA_TNUMBER:
00397 cout << "* " << i << "= NUMBER: " << lua_tonumber(_lstack, i) << endl;
00398 break;
00399 case LUA_TSTRING:
00400 cout << "* " << i << "= STRING: " << lua_tostring(_lstack, i) << endl;
00401 break;
00402 case LUA_TTABLE:
00403 cout << "* " << i << "= TABLE" << endl;
00404 break;
00405 case LUA_TFUNCTION:
00406 cout << "* " << i << "= FUNCTION" << endl;
00407 break;
00408 case LUA_TUSERDATA:
00409 cout << "* " << i << "= USERDATA " << endl;
00410 break;
00411 case LUA_TLIGHTUSERDATA:
00412 cout << "* " << i << "= LIGHTUSERDATA " << endl;
00413 break;
00414 case LUA_TTHREAD:
00415 cout << "* " << i << "= THREAD " << endl;
00416 break;
00417 default:
00418 cout << "* " << i << "= OTHER: " << lua_typename(_lstack, type) << endl;
00419 break;
00420 }
00421 }
00422 cout << endl;
00423 }
00424
00425
00426
00427 void ReadScriptDescriptor::DEBUG_PrintGlobals() {
00428 cout << "SCRIPT DEBUG: Printing script's global variables:" << endl;
00429
00430 object o(from_stack(_lstack, LUA_GLOBALSINDEX));
00431 for (luabind::iterator it(o), end; it != end; ++it) {
00432 cout << it.key() << " = " << (*it) << " ::: data type = " << type(*it) << endl;
00433 if (luabind::type(*it) == LUA_TTABLE) {
00434
00435 }
00436 }
00437 cout << endl;
00438 }
00439
00440 }