-
Notifications
You must be signed in to change notification settings - Fork 66
/
script_read.h
605 lines (486 loc) · 23.7 KB
/
script_read.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004-2010 by The Allacrost Project
// All Rights Reserved
//
// This code is licensed under the GNU GPL version 2. It is free software
// and you may modify it and/or redistribute it under the terms of this license.
// See http://www.gnu.org/copyleft/gpl.html for details.
///////////////////////////////////////////////////////////////////////////////
/** ****************************************************************************
*** \file script_read.h
*** \author Daniel Steuernol - steu@allacrost.org,
*** Tyler Olsen - roots@allacrost.org
*** \brief Header file for the ReadScriptDescriptor class.
*** ***************************************************************************/
#ifndef __SCRIPT_READ_HEADER__
#define __SCRIPT_READ_HEADER__
#include "utils.h"
#include "defs.h"
#include "script.h"
namespace hoa_script {
namespace private_script {
/** \brief Constants used in the ReadScriptDescriptor data existence checking functions
*** These members are necessary because the Lua type constants defined do not distinguish
*** between integers and floats (there is only a single LUA_TNUMBER). We, however, need
*** to sometimes distinguish between the two types when reading in data. These constants
*** were assigned arbitrary and unlikely values to be represented by other Lua types
*** (which as of Lua 5.0, go from -1 to 8).
**/
//@{
const int32 INTEGER_TYPE = 0x12345678;
const int32 UINTEGER_TYPE = 0x87654321;
const int32 FLOAT_TYPE = 0x12344321;
//@}
} // namespace private_script
/** ****************************************************************************
*** \brief Represents a Lua file opened with read and execute permissions
***
*** This is the most commonly used of the script descriptor classes. This class
*** allows you to read simple data types, open and close tables contained within
*** the file, check for the existence of specific variable names and identifiers,
*** retrieve pointers to Lua functions which can then be executed, and more.
***
*** The most important concept for understanding how to use this class is that of
*** <b>table scope</b>. A scope is the portion of the Lua file that many of the
*** data read operations in this class operate on. For example, the global scope
*** contains all global variables, functions, and tables. There is a unique scope
*** inherit inside each table in the file (including the tables of tables). When
*** you invoke a read operation, ReadInt() for example, it attempts to read an
*** integer in the current scope. If you have no tables open, it will look in the
*** global space. Otherwise, it will look in the most recently opened table. Thus,
*** it is <b>extremely</b> important that you know which scope is "active", and
*** to know when to open and close tables to be in the correct scope.
***
*** \note With the exception of the open/close file functions, all methods of
*** this class assume that the file is open and do not check otherwise. If you
*** try to invoke these functions with an unopened file, you will generate a
*** segmentation fault.
*** ***************************************************************************/
class ReadScriptDescriptor : public ScriptDescriptor {
friend class ScriptEngine;
public:
ReadScriptDescriptor() :
_lstack(NULL) {}
virtual ~ReadScriptDescriptor();
/** \name File Access Functions.
*** \note These are derived from ScriptDescriptor, refer to the comments for these
*** methods in the header file for that class.
**/
//@{
virtual bool OpenFile(const std::string& file_name);
virtual bool OpenFile();
virtual void CloseFile();
//@}
/** \name Existence Checking Functions
*** \brief Methods which check if there exist certain data names and types in a script file
*** \param key The variable, table, or function name to check for
*** \return True if the appropriate data type represented by that variable name was found.
***
*** Under normal circumstances, invoking any of these functions should not result in error
*** messages being printed, even if the variable could not be found. There are some
*** circumstances, however, where error messages may be added, such as when it is detected
*** that a table is missing or the active scope is not appropriate for the function call.
***
*** \note The DoesVariableExist checks if is there is <b>any</b> data type, structure, or
*** function referenced by the key name.
***
*** \note The DoesNumberExists checks if there is <b>any</b> numeric data type integer or
*** floating point value referenced by the key name.
**/
//@{
bool DoesVariableExist(const std::string& key)
{ return _DoesDataExist(key, LUA_TNIL); }
bool DoesVariableExist(int32 key)
{ return _DoesDataExist(key, LUA_TNIL); }
bool DoesNumberExist(const std::string& key)
{ return _DoesDataExist(key, LUA_TNUMBER); }
bool DoesNumberExist(int32 key)
{ return _DoesDataExist(key, LUA_TNUMBER); }
bool DoesBoolExist(const std::string& key)
{ return _DoesDataExist(key, LUA_TBOOLEAN); }
bool DoesBoolExist(int32 key)
{ return _DoesDataExist(key, LUA_TBOOLEAN); }
bool DoesIntExist(const std::string& key)
{ return _DoesDataExist(key, private_script::INTEGER_TYPE); }
bool DoesIntExist(int32 key)
{ return _DoesDataExist(key, private_script::INTEGER_TYPE); }
bool DoesUIntExist(const std::string& key)
{ return _DoesDataExist(key, private_script::UINTEGER_TYPE); }
bool DoesUIntExist(int32 key)
{ return _DoesDataExist(key, private_script::UINTEGER_TYPE); }
bool DoesFloatExist(const std::string& key)
{ return _DoesDataExist(key, private_script::FLOAT_TYPE); }
bool DoesFloatExist(int32 key)
{ return _DoesDataExist(key, private_script::FLOAT_TYPE); }
bool DoesStringExist(const std::string& key)
{ return _DoesDataExist(key, LUA_TSTRING); }
bool DoesStringExist(int32 key)
{ return _DoesDataExist(key, LUA_TSTRING); }
bool DoesFunctionExist(const std::string& key)
{ return _DoesDataExist(key, LUA_TFUNCTION); }
bool DoesFunctionExist(int32 key)
{ return _DoesDataExist(key, LUA_TFUNCTION); }
bool DoesTableExist(const std::string& key)
{ return _DoesDataExist(key, LUA_TTABLE); }
bool DoesTableExist(int32 key)
{ return _DoesDataExist(key, LUA_TTABLE); }
//@}
/** \name Variable Read Functions
*** \brief These functions grab a basic data type from the Lua file and return its value.
*** \param key The name or numeric id of the Lua variable to access.
*** \return The value of the variable requested.
*** \note The integer keys are only valid for variables stored in a table, not for global variables.
***
*** These functions call the template _ReadData() functions with a default return value.
**/
//@{
bool ReadBool(const std::string& key)
{ return _ReadData<bool>(key, false); }
bool ReadBool(int32 key)
{ return _ReadData<bool>(key, false); }
int32 ReadInt(const std::string& key)
{ return _ReadData<int32>(key, 0); }
int32 ReadInt(int32 key)
{ return _ReadData<uint32>(key, 0); }
uint32 ReadUInt(const std::string& key)
{ return _ReadData<int32>(key, 0); }
uint32 ReadUInt(int32 key)
{ return _ReadData<uint32>(key, 0); }
float ReadFloat(const std::string& key)
{ return _ReadData<float>(key, 0.0f); }
float ReadFloat(int32 key)
{ return _ReadData<float>(key, 0.0f); }
std::string ReadString(const std::string& key)
{ return _ReadData<std::string>(key, ""); }
std::string ReadString(int32 key)
{ return _ReadData<std::string>(key, ""); }
hoa_utils::ustring ReadUString(const std::string& key)
{ return _ReadData<hoa_utils::ustring>(key, hoa_utils::MakeUnicodeString("")); }
hoa_utils::ustring ReadUString(int32 key)
{ return _ReadData<hoa_utils::ustring>(key, hoa_utils::MakeUnicodeString("")); }
//@}
/** \name Vector Read Functions
*** \brief These functions fill a vector with members of a table read from the Lua file.
*** \param key The name of the table to use to fill the vector.
*** \param vect A reference to the vector of elements to fill.
***
*** The table that these functions attempt to access is assumed to be <b>closed</b>. If the
*** table is open prior to calling these functions, they will not operate properly. All of
*** these functions call the template _ReadDataVector() functions to perform their operations.
***
*** \note The integer keys are only valid for tables that are elements of a parent table.
*** They can not be used to access tables in the global space.
**/
//@{
void ReadBoolVector(const std::string& key, std::vector<bool>& vect)
{ _ReadDataVector<bool>(key, vect); }
void ReadBoolVector(int32 key, std::vector<bool>& vect)
{ _ReadDataVector<bool>(key, vect); }
void ReadIntVector(const std::string& key, std::vector<int32>& vect)
{ _ReadDataVector<int32>(key, vect); }
void ReadIntVector(int32 key, std::vector<int32>& vect)
{ _ReadDataVector<int32>(key, vect); }
void ReadUIntVector(const std::string& key, std::vector<uint32>& vect)
{ _ReadDataVector<uint32>(key, vect); }
void ReadUIntVector(int32 key, std::vector<uint32>& vect)
{ _ReadDataVector<uint32>(key, vect); }
void ReadFloatVector(const std::string& key, std::vector<float>& vect)
{ _ReadDataVector<float>(key, vect); }
void ReadFloatVector(int32 key, std::vector<float>& vect)
{ _ReadDataVector<float>(key, vect); }
void ReadStringVector(const std::string& key, std::vector<std::string>& vect)
{ _ReadDataVector<std::string>(key, vect); }
void ReadStringVector(int32 key, std::vector<std::string>& vect)
{ _ReadDataVector<std::string>(key, vect); }
void ReadUStringVector(const std::string& key, std::vector<hoa_utils::ustring>& vect)
{ _ReadDataVector<hoa_utils::ustring>(key, vect); }
void ReadUStringVector(int32 key, std::vector<hoa_utils::ustring>& vect)
{ _ReadDataVector<hoa_utils::ustring>(key, vect); }
//@}
/** \name Function Pointer Read Functions
*** \param key The name of the function if it is contained in the global space, or the key
*** if the function is embedded in a table.
*** \return A luabind::object class object, which can be used to call the function. It effectively
*** serves as a function pointer.
**/
//@{
luabind::object ReadFunctionPointer(const std::string& key);
//! \note The calling function may <b>not</b> be contained within the global space for an integer key.
luabind::object ReadFunctionPointer(int32 key);
//@}
/** \name Table Operation Functions
*** After a table is opened, it becomes the active "space" that all of the data read
*** operations operate on. You must <b>always</b> remember to close a table once you are
*** finished reading data from it.
**/
//@{
//! \param table_name The name of the table to open
//! \param use_global This overrides the open_tables vector, the reason for this is
//! when a function is called from lua, any open tables are no longer on the stack passed to the function
//! so to start a new chain of open tables we have to ignore the open tables vector
void OpenTable(const std::string& table_name, bool use_global = false);
/** \param table_name The integer key of the table to open
*** \note This function will only work when there is at least one other table already open
**/
void OpenTable(int32 table_name);
/** Opens the lua file own tablespace. It's useful to permit having several lua files
*** with their own function without worrying too much about the global naming collisions.
*** \note the tablespace must be named like the lua filename, but without the extension:
*** e.g.: dat/script/my_script.lua should have a 'my_script' tablespace defined
*** at the beginning of the file using the following way:
***
*** local ns = {}
*** setmetatable(ns, {__index = _G})
*** my_script = ns;
*** setfenv(1, ns);
***
*** @See WriteScriptDescriptor::WriteTablespace(const std::string &ns);
*** \return the tablespace name or an empty string when it failed.
**/
std::string OpenTablespace();
//! \brief Closes the most recently opened table
void CloseTable();
//! \brief Closes any open tables and returns the user to the global scope
void CloseAllTables();
/** \brief Returns the number of elements stored in an un-opened table
*** \param table_name The name of the (un-open) table to get the size of
**/
uint32 GetTableSize(const std::string& table_name);
/** \brief Returns the number of elements stored in an un-opened table
*** \param table_name The integer key of the (un-open) table to get the size of
*** \note This function will only work when there is at least one other table already open
**/
uint32 GetTableSize(int32 table_name);
//! \brief Returns the number of elements stored in the most recently opened table
uint32 GetTableSize();
//! \brief Emptys all values off the lua stack
void ClearStack(uint32 levels_to_clear);
/** \brief Fills a vector with all of the keys of a table
*** \param table_name The name of the table to open and retrieve the keys from
*** \param keys A reference to the vector where to store the table keys
***
*** The functions without a table_name argument will retrieve the keys for the
*** most recently opened table. The keys vector will cleared before the function
*** starts populating it with table keys, so make sure nothing important is contained
*** in the keys vector before calling this function. If the keys vector is empty
*** after the function was called, either an error occured or the table was empty.
***
*** \note These functions will only work successfully for tables that have the same
*** data type for all their keys (ie, all string keys or all integer keys). A table
*** with mixed key types (integers and strings for example) will not be processed
*** successfully by these functions.
**/
//@{
void ReadTableKeys(std::vector<std::string>& keys)
{ _ReadTableKeys(keys); }
void ReadTableKeys(std::vector<int32>& keys)
{ _ReadTableKeys(keys); }
void ReadTableKeys(std::vector<uint32>& keys)
{ _ReadTableKeys(keys); }
void ReadTableKeys(const std::string& table_name, std::vector<std::string>& keys)
{ OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
void ReadTableKeys(const std::string& table_name, std::vector<int32>& keys)
{ OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
void ReadTableKeys(const std::string& table_name, std::vector<uint32>& keys)
{ OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
void ReadTableKeys(int32 table_name, std::vector<std::string>& keys)
{ OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
void ReadTableKeys(int32 table_name, std::vector<int32>& keys)
{ OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
void ReadTableKeys(int32 table_name, std::vector<uint32>& keys)
{ OpenTable(table_name); _ReadTableKeys(keys); CloseTable(); }
//@}
//@}
//! \brief Returns a pointer to the local lua state (use with caution)
lua_State* GetLuaState()
{ return _lstack; }
/** \brief Generic functions permitting to quickly load script function with the usual checks.
*** \param filename the script file
*** \param function_name The script function name
*** \param global when false, uses the file tablespace, if true don't use it and search into the global space.
*** \return whether everything went fine.
**/
bool RunScriptFunction(const std::string& filename, const std::string& function_name, bool global = false);
//! \brief The same function as its homonym but using a opened file and not closing it afterwards.
bool RunScriptFunction(const std::string& function_name);
/** \brief Generic function running a lua script using an object pointer with the usual checks.
*** \note that this function can only call fonctions without parameters atm.
**/
static bool RunScriptObject(const ScriptObject& object);
/** \brief Prints out the contents of the Lua stack mechanism to standard output
*** The elements are printed from stack top to stack bottom.
**/
void DEBUG_PrintLuaStack();
//! \brief Prints out all global variable names to standard output
void DEBUG_PrintGlobals();
//! \brief Prints out a specific table
void DEBUG_PrintTable(luabind::object table, int tab = 0);
protected:
//! \brief The Lua stack, which handles all data sharing between C++ and Lua.
lua_State *_lstack;
/** \name Data Existence Check Functions
*** \brief These functions are called by the public DoesTYPEExist functions of this class.
*** \param key The name or numeric id of the Lua data to check.
*** \param type The correct type that the data should check out to be (uses the Lua type constants)
*** \return True if data of the corresponding key and type is found.
*** \note The integer keys are only valid for variables stored in a table, not for global variables.
**/
//@{
bool _DoesDataExist(const std::string& key, int32 type);
bool _DoesDataExist(int32 key, int32 type);
/** \brief A helper function for the _DoesDataExist functions that performs the data type check
*** \param type An integer type to compare with the type of the object
*** \param obj_check The Luabind object whose type to compare to the integer type
*** \return True if the two types are equivalent
**/
bool _CheckDataType(int32 type, luabind::object& obj_check);
//@}
/** \name Variable Read Templates
*** \brief These template functions are called by the public ReadTYPE functions of this class.
*** \param key The name or numeric identifier of the Lua variable to access.
*** \param default_value The value for the function to return if an error occurs.
*** \return The value of the variable requested.
*** \note Integer keys are only valid for variables stored in a table, not for global variables.
**/
//@{
template <class T> T _ReadData(const std::string& key, T default_value);
template <class T> T _ReadData(int32 key, T default_value);
//@}
/** \name Vector Read Templates
*** \brief These template functions are called by the public ReadTYPEVector functions of this class.
*** \param key The name or numeric identifier of the Lua variable to access.
*** \param vect A reference to the vector where the read variables should be stored
*** \note Integer keys are only valid for variables stored in a table, not for global variables.
**/
//@{
template <class T> void _ReadDataVector(const std::string& key, std::vector<T>& vect);
template <class T> void _ReadDataVector(int32 key, std::vector<T>& vect);
//! \brief This template method is a helper function for the other two
template <class T> void _ReadDataVectorHelper(std::vector<T>& vect);
//@}
/** \name Table Key Template
*** \brief This template function fills a vector with all of the keys contained by the table
*** \param vect A reference to the vector where the keys should be stored
*** \note This function will fail for any table that has multiple key types (ie, contains both
*** integer and string keys).
**/
template <class T> void _ReadTableKeys(std::vector<T>& keys);
}; // class ReadScriptDescriptor
//-----------------------------------------------------------------------------
// Template Function Definitions
//-----------------------------------------------------------------------------
template <class T> T ReadScriptDescriptor::_ReadData(const std::string &key, T default_value) {
// Check whether the user is trying to read a global variable or one stored in a table
if (_open_tables.size() == 0) { // Variable is a global
lua_getglobal(_lstack, key.c_str());
luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
if (!o) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "unable to access the global variable: " << key
<< " Type: " << luabind::type(o) << std::endl;
return default_value;
}
try {
T ret_val = luabind::object_cast<T>(o);
lua_pop(_lstack, 1);
return ret_val;
}
catch (...) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "unable to cast value to correct type for global variable: " << key << std::endl;
return default_value;
}
}
else { // Variable is a member of a table
luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
if (luabind::type(o) != LUA_TTABLE) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed because the top of the stack was not a table when trying to read variable: " << key
<< " Type: " << luabind::type(o) << std::endl;
return default_value;
}
try {
return luabind::object_cast<T>(o[key]);
}
catch (...) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "unable to access the table variable: " << key << std::endl;
return default_value;
}
}
return default_value;
} // template <class T> T ReadScriptDescriptor::_ReadData(const char *key, T default_value)
template <class T> T ReadScriptDescriptor::_ReadData(int32 key, T default_value) {
if (_open_tables.size() == 0) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed because no tables were open when trying to access the table variable: "
<< key << std::endl;
return default_value;
}
luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
if (luabind::type(o) != LUA_TTABLE) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed because the top of the stack was not a table when trying to read variable: "
<< key << std::endl;
return default_value;
}
try {
return luabind::object_cast<T>(o[key]);
}
catch (...) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "unable to access the table variable: " << key << std::endl;
return default_value;
}
return default_value;
} // template <class T> T ReadScriptDescriptor::_ReadData(int32 key, T default_value)
template <class T> void ReadScriptDescriptor::_ReadDataVector(const std::string& key, std::vector<T>& vect) {
// Open the table and grab if off the stack
OpenTable(key);
_ReadDataVectorHelper(vect);
CloseTable();
} // template <class T> void ReadScriptDescriptor::_ReadDataVector(std::string key, std::vector<T> &vect)
template <class T> void ReadScriptDescriptor::_ReadDataVector(int32 key, std::vector<T>& vect) {
if (_open_tables.size() == 0) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed because no tables were open when trying to access the table variable: "
<< key << std::endl;;
return;
}
// Open the table and grab if off the stack
OpenTable(key);
_ReadDataVectorHelper(vect);
CloseTable();
} // template <class T> void ReadScriptDescriptor::_ReadDataVector(int32 key, std::vector<T> &vect)
template <class T> void ReadScriptDescriptor::_ReadDataVectorHelper(std::vector<T>& vect) {
luabind::object o(luabind::from_stack(_lstack, private_script::STACK_TOP));
if (luabind::type(o) != LUA_TTABLE) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed because the top of the stack was not a table" << std::endl;
return;
}
// Iterate through all the items of the table and place it in the vector
for (luabind::iterator it(o); it != private_script::TABLE_END; it++) {
try {
vect.push_back(luabind::object_cast<T>((*it)));
}
catch (...) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed due to a type cast failure when reading the table" << std::endl;
}
}
} // template <class T> void ReadScriptDescriptor::_ReadDataVectorHelper(std::vector<T>& vect)
template <class T> void ReadScriptDescriptor::_ReadTableKeys(std::vector<T>& keys) {
keys.clear();
if (_open_tables.size() == 0) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed because there were no open tables to get the keys of" << std::endl;
return;
}
luabind::object table(luabind::from_stack(_lstack, private_script::STACK_TOP));
if (luabind::type(table) != LUA_TTABLE) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed because the top of the stack was not a table" << std::endl;
return;
}
for (luabind::iterator i(table); i != private_script::TABLE_END; i++) {
try {
keys.push_back(luabind::object_cast<T>(i.key()));
}
catch (...) {
IF_PRINT_WARNING(SCRIPT_DEBUG) << "failed due to a type cast failure when retrieving a table key" << std::endl;
keys.clear();
return;
}
}
} // template <class T> void ReadScriptDescriptor::ReadTableKeys(std::vector<T>& keys) {
} // namespace hoa_script
#endif // __SCRIPT_READ_HEADER__