mirror of
https://port.numenaute.org/aleajactaest/khanat-code-old.git
synced 2024-12-25 02:00:54 +00:00
Moved some Lua stuff over to the NelGUI library.
This commit is contained in:
parent
e1b6690e6f
commit
2af7e250b2
23 changed files with 1264 additions and 1233 deletions
388
code/nel/include/nel/gui/lua_helper.h
Normal file
388
code/nel/include/nel/gui/lua_helper.h
Normal file
|
@ -0,0 +1,388 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef RZ_LUA_HELPER_H
|
||||||
|
#define RZ_LUA_HELPER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "nel/misc/types_nl.h"
|
||||||
|
#include "nel/misc/smart_ptr.h"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include "lua_loadlib.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
|
||||||
|
class CLuaState;
|
||||||
|
|
||||||
|
namespace LuaHelperStuff
|
||||||
|
{
|
||||||
|
void formatLuaStackContext( std::string &stackContext );
|
||||||
|
std::string formatLuaErrorSysInfo( const std::string &error );
|
||||||
|
std::string formatLuaErrorNlWarn( const std::string &error );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
/** Helper class to see if a stack is restored at its initial size (or with n return results).
|
||||||
|
* Check that the stack size remains unchanged when the object goes out of scope
|
||||||
|
*/
|
||||||
|
class CLuaStackChecker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CLuaStackChecker(CLuaState *state, int numWantedResults = 0);
|
||||||
|
~CLuaStackChecker();
|
||||||
|
/** Increment exception context counter
|
||||||
|
* When an exception is thrown, lua stack checker do any assert bu will
|
||||||
|
* rather restore the lua stack at its original size, and will
|
||||||
|
* let the exception a chance to propagate
|
||||||
|
*/
|
||||||
|
static void incrementExceptionContextCounter();
|
||||||
|
static void decrementExceptionContextCounter();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CLuaState *_State;
|
||||||
|
int _FinalWantedSize;
|
||||||
|
static uint _ExceptionContextCounter;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
/** Helper class to restore the lua stack to the desired size when this object goes out of scope
|
||||||
|
*/
|
||||||
|
class CLuaStackRestorer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CLuaStackRestorer(CLuaState *state, int finalSize);
|
||||||
|
~CLuaStackRestorer();
|
||||||
|
private:
|
||||||
|
int _FinalSize;
|
||||||
|
CLuaState *_State;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
// EXCEPTIONS //
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
class ELuaError : public NLMISC::Exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ELuaError() { CLuaStackChecker::incrementExceptionContextCounter(); }
|
||||||
|
virtual ~ELuaError() throw() { CLuaStackChecker::decrementExceptionContextCounter(); }
|
||||||
|
ELuaError(const std::string &reason) : Exception(reason) { CLuaStackChecker::incrementExceptionContextCounter(); }
|
||||||
|
// what(), plus append the Reason
|
||||||
|
virtual std::string luaWhat() const throw() {return NLMISC::toString("LUAError: %s", what());}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A parse error occured
|
||||||
|
class ELuaParseError : public ELuaError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ELuaParseError() {}
|
||||||
|
ELuaParseError(const std::string &reason) : ELuaError(reason) {}
|
||||||
|
virtual ~ELuaParseError() throw() { }
|
||||||
|
// what(), plus append the Reason
|
||||||
|
virtual std::string luaWhat() const throw() {return NLMISC::toString("ELuaParseError: %s", what());}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Exception thrown when something went wrong inside a wrapped function called by lua
|
||||||
|
*/
|
||||||
|
class ELuaWrappedFunctionException : public ELuaError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ELuaWrappedFunctionException(CLuaState *luaState);
|
||||||
|
ELuaWrappedFunctionException(CLuaState *luaState, const std::string &reason);
|
||||||
|
ELuaWrappedFunctionException(CLuaState *luaState, const char *format, ...);
|
||||||
|
virtual ~ELuaWrappedFunctionException() throw() { }
|
||||||
|
virtual const char *what() const throw() {return _Reason.c_str();}
|
||||||
|
protected:
|
||||||
|
void init(CLuaState *ls, const std::string &reason);
|
||||||
|
protected:
|
||||||
|
std::string _Reason;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A execution error occured
|
||||||
|
class ELuaExecuteError : public ELuaError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ELuaExecuteError() {}
|
||||||
|
ELuaExecuteError(const std::string &reason) : ELuaError(reason) {}
|
||||||
|
virtual ~ELuaExecuteError() throw() { }
|
||||||
|
// what(), plus append the Reason
|
||||||
|
virtual std::string luaWhat() const throw() {return NLMISC::toString("ELuaExecuteError: %s", what());}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A bad cast occured when using lua_checkcast
|
||||||
|
class ELuaBadCast : public ELuaError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ELuaBadCast() {}
|
||||||
|
ELuaBadCast(const std::string &reason) : ELuaError(reason) {}
|
||||||
|
// what(), plus append the Reason
|
||||||
|
virtual std::string luaWhat() const throw() {return NLMISC::toString("ELuaBadCast: %s", what());}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Error when trying to indexate an object that is not a table
|
||||||
|
class ELuaNotATable : public ELuaError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ELuaNotATable() {}
|
||||||
|
ELuaNotATable(const std::string &reason) : ELuaError(reason) {}
|
||||||
|
// what(), plus append the Reason
|
||||||
|
virtual std::string luaWhat() const throw() {return NLMISC::toString("ELuaNotATable: %s", what());}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// a function to be used with a CLuaState instance
|
||||||
|
typedef int (* TLuaWrappedFunction) (CLuaState &ls);
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
/** C++ version of a lua state
|
||||||
|
*/
|
||||||
|
class CLuaState : public NLMISC::CRefCount
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef NLMISC::CRefPtr<CLuaState> TRefPtr;
|
||||||
|
|
||||||
|
// Create a new environement
|
||||||
|
CLuaState( bool debugger = false );
|
||||||
|
~CLuaState();
|
||||||
|
|
||||||
|
|
||||||
|
/// \name Registering
|
||||||
|
// @{
|
||||||
|
// register a wrapped function
|
||||||
|
void registerFunc(const char *name, TLuaWrappedFunction function);
|
||||||
|
// @}
|
||||||
|
|
||||||
|
|
||||||
|
/// \name Script execution
|
||||||
|
// @{
|
||||||
|
|
||||||
|
/** Parse a script and push as a function in top of the LUA stack
|
||||||
|
* \throw ELuaParseError
|
||||||
|
* \param dbgSrc is a string for debug. Should be a filename (preceded with '@'), or a short script.
|
||||||
|
*/
|
||||||
|
void loadScript(const std::string &code, const std::string &dbgSrc);
|
||||||
|
|
||||||
|
/** Execute a script from a string, possibly throwing an exception if there's a parse error
|
||||||
|
* \throw ELuaParseError, ELuaExecuteError
|
||||||
|
*/
|
||||||
|
void executeScript(const std::string &code, int numRet = 0);
|
||||||
|
|
||||||
|
/** Execute a script from a string. If an errors occurs it is printed in the log
|
||||||
|
* \return true if script execution was successful
|
||||||
|
*/
|
||||||
|
bool executeScriptNoThrow(const std::string &code, int numRet = 0);
|
||||||
|
|
||||||
|
/** Load a Script from a File (maybe in a BNP), and execute it
|
||||||
|
* \return false if file not found
|
||||||
|
* \throw ELuaParseError, ELuaExecuteError
|
||||||
|
*/
|
||||||
|
bool executeFile(const std::string &pathName);
|
||||||
|
|
||||||
|
/** execute a very Small Script (a function call for instance)
|
||||||
|
* It is different from doString() in such there is a cache (where the key is the script itself)
|
||||||
|
* so that the second time this script is executed, there is no parsing
|
||||||
|
* Note: I experienced optim with about 10 times faster than a executeScript() on a simple "a= a+1;" script
|
||||||
|
* \throw ELuaParseError, ELuaExecuteError
|
||||||
|
*/
|
||||||
|
void executeSmallScript(const std::string &script);
|
||||||
|
|
||||||
|
// @}
|
||||||
|
|
||||||
|
|
||||||
|
/// \name Stack Manipulation
|
||||||
|
// @{
|
||||||
|
// stack manipulation (indices start at 1)
|
||||||
|
void setTop(int index); // set new size of stack
|
||||||
|
void clear() { setTop(0); }
|
||||||
|
int getTop();
|
||||||
|
bool empty() { return getTop() == 0; }
|
||||||
|
void pushValue(int index); // copie nth element of stack to the top of the stack
|
||||||
|
void remove(int index); // remove nth element of stack
|
||||||
|
void insert(int index); // insert last element of the stack before the given position
|
||||||
|
void replace(int index); // replace nth element of the stack with the top of the stack
|
||||||
|
void pop(int numElem = 1); // remove n elements from the top of the stack
|
||||||
|
// test the type of an element in the stack
|
||||||
|
// return one of the following values :
|
||||||
|
// LUA_TNIL
|
||||||
|
// LUA_TNUMBER
|
||||||
|
// LUA_TBOOLEAN
|
||||||
|
// LUA_TSTRING
|
||||||
|
// LUA_TTABLE
|
||||||
|
// LUA_TFUNCTION
|
||||||
|
// LUA_TUSERDATA
|
||||||
|
// LUA_TTHREAD
|
||||||
|
// LUA_TLIGHTUSERDATA
|
||||||
|
int type(int index = -1);
|
||||||
|
const char *getTypename(int type);
|
||||||
|
bool isNil(int index = -1);
|
||||||
|
bool isBoolean(int index = -1);
|
||||||
|
bool isNumber(int index = -1);
|
||||||
|
bool isString(int index = -1);
|
||||||
|
bool isTable(int index = -1);
|
||||||
|
bool isFunction(int index = -1);
|
||||||
|
bool isCFunction(int index = -1);
|
||||||
|
bool isUserData(int index = -1);
|
||||||
|
bool isLightUserData(int index = -1);
|
||||||
|
// converting then getting a value from the stack
|
||||||
|
bool toBoolean(int index = -1);
|
||||||
|
lua_Number toNumber(int index = -1);
|
||||||
|
const char *toString(int index = -1);
|
||||||
|
void toString(int index, std::string &str); // convert to a std::string, with a NULL check.
|
||||||
|
size_t strlen(int index = -1);
|
||||||
|
lua_CFunction toCFunction(int index = -1);
|
||||||
|
void *toUserData(int index = -1);
|
||||||
|
const void *toPointer(int index = -1);
|
||||||
|
/** Helper functions : get value of the wanted type in the top table after conversion
|
||||||
|
* A default value is used if the stack entry is NULL.
|
||||||
|
* If conversion fails then an exception is thrown (with optional msg)
|
||||||
|
*/
|
||||||
|
bool getTableBooleanValue(const char *name, bool defaultValue= false);
|
||||||
|
double getTableNumberValue(const char *name, double defaultValue= 0);
|
||||||
|
const char *getTableStringValue(const char *name, const char *defaultValue= NULL);
|
||||||
|
// pushing value onto the stack
|
||||||
|
void push(bool value);
|
||||||
|
void push(lua_Number value);
|
||||||
|
void push(const char *str);
|
||||||
|
void push(const char *str, int length);
|
||||||
|
void push(const std::string &str);
|
||||||
|
void pushNil();
|
||||||
|
void push(lua_CFunction f);
|
||||||
|
void push(TLuaWrappedFunction function);
|
||||||
|
void pushLightUserData(void *); // push a light user data (use newUserData to push a full userdata)
|
||||||
|
// metatables
|
||||||
|
bool getMetaTable(int index = -1);
|
||||||
|
bool setMetaTable(int index = -1); // set the metatable at top of stack to the object at 'index' (usually -2), then pop the metatable
|
||||||
|
// even if asignment failed
|
||||||
|
// comparison
|
||||||
|
bool equal(int index1, int index2);
|
||||||
|
bool rawEqual(int index1, int index2);
|
||||||
|
bool lessThan(int index1, int index2);
|
||||||
|
// concatenation of the n element at the top of the stack (using lua semantic)
|
||||||
|
void concat(int numElem);
|
||||||
|
// tables
|
||||||
|
void newTable(); // create a new table at top of the stack
|
||||||
|
void getTable(int index); // get value from a table at index 'index' (key is at top)
|
||||||
|
void rawGet(int index);
|
||||||
|
void setTable(int index); // set (key, value) from top of the stack into the given table
|
||||||
|
// both key and value are poped
|
||||||
|
void rawSet(int index);
|
||||||
|
bool next(int index); // table traversal
|
||||||
|
// UserData
|
||||||
|
void *newUserData(uint size);
|
||||||
|
// seting value by int index in a table
|
||||||
|
void rawSetI(int index, int n);
|
||||||
|
void rawGetI(int index, int n);
|
||||||
|
/** Calling functions (it's up to the caller to clear the results)
|
||||||
|
* The function should have been pushed on the stack
|
||||||
|
*/
|
||||||
|
void call(int nargs, int nresults);
|
||||||
|
int pcall(int nargs, int nresults, int errfunc = 0);
|
||||||
|
/** Helper : Execute a function by name. Lookup for the function is done in the table at the index 'funcTableIndex'
|
||||||
|
* the behaviour is the same than with call of pcall.
|
||||||
|
*/
|
||||||
|
int pcallByName(const char *functionName, int nargs, int nresults, int funcTableIndex = LUA_GLOBALSINDEX, int errfunc = 0);
|
||||||
|
|
||||||
|
// push a C closure (pop n element from the stack and associate with the function)
|
||||||
|
void pushCClosure(lua_CFunction function, int n);
|
||||||
|
// @}
|
||||||
|
|
||||||
|
|
||||||
|
/// \name Misc
|
||||||
|
// @{
|
||||||
|
/** Retrieve pointer to a CLuaState environment from its lua_State pointer, or NULL
|
||||||
|
* if there no such environment
|
||||||
|
*/
|
||||||
|
static CLuaState *fromStatePointer(lua_State *state);
|
||||||
|
// Get state pointer. The state should not be closed (this object has ownership)
|
||||||
|
lua_State *getStatePointer() const {return _State;}
|
||||||
|
// check that an index is valid when accessing the stack
|
||||||
|
// an assertion is raised if the index is not valid
|
||||||
|
void checkIndex(int index);
|
||||||
|
|
||||||
|
// registering C function to use with a lua state pointer
|
||||||
|
void registerFunc(const char *name, lua_CFunction function);
|
||||||
|
|
||||||
|
// Garbage collector
|
||||||
|
int getGCCount(); // get memory in use in KB
|
||||||
|
int getGCThreshold(); // get max memory in KB
|
||||||
|
void setGCThreshold(int kb); // set max memory in KB (no-op with ref-counted version)
|
||||||
|
|
||||||
|
// handle garbage collector for ref-counted version of lua (no-op with standard version, in which case gc handling is automatic)
|
||||||
|
void handleGC();
|
||||||
|
|
||||||
|
/** For Debug: get the Stack context of execution (filename / line)
|
||||||
|
* \param stackLevel: get the context of execution of the given stackLevel.
|
||||||
|
* 0 for the current function
|
||||||
|
* 1 for the function that called 0
|
||||||
|
* 2 ....
|
||||||
|
* NB: if called from a C function called from LUA, remember that stackLevel 0 is the current function.
|
||||||
|
* Hence if you want to know what LUA context called you, pass stackLevel=1!
|
||||||
|
* \param ret string cleared if any error, else filled with formated FileName / LineNumber
|
||||||
|
*/
|
||||||
|
void getStackContext(std::string &ret, uint stackLevel);
|
||||||
|
// @}
|
||||||
|
|
||||||
|
// for debug : dump the current content of the stack (no recursion)
|
||||||
|
void dumpStack();
|
||||||
|
static void dumpStack(lua_State *ls);
|
||||||
|
void getStackAsString(std::string &dest);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
lua_State *_State;
|
||||||
|
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
int _GCThreshold; // if refcounted gc is used, then garbage collector is handled manually
|
||||||
|
#endif
|
||||||
|
// Small Script Cache
|
||||||
|
uint _SmallScriptPool;
|
||||||
|
typedef std::map<std::string, uint> TSmallScriptCache;
|
||||||
|
TSmallScriptCache _SmallScriptCache;
|
||||||
|
static const char * _NELSmallScriptTableName;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// this object isn't intended to be copied
|
||||||
|
CLuaState(const CLuaState &/* other */):NLMISC::CRefCount() { nlassert(0); }
|
||||||
|
CLuaState &operator=(const CLuaState &/* other */) { nlassert(0); return *this; }
|
||||||
|
|
||||||
|
void executeScriptInternal(const std::string &code, const std::string &dbgSrc, int numRet = 0);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Access to lua function
|
||||||
|
// one should not include lua.h directly because if a debugger is present, lua
|
||||||
|
// function pointer will be taken from a dynamic library.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================================
|
||||||
|
// include implementation
|
||||||
|
#define RZ_INCLUDE_LUA_HELPER_INLINE
|
||||||
|
#include "lua_helper_inline.h"
|
||||||
|
#undef RZ_INCLUDE_LUA_HELPER_INLINE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
835
code/nel/src/gui/lua_helper.cpp
Normal file
835
code/nel/src/gui/lua_helper.cpp
Normal file
|
@ -0,0 +1,835 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "nel/gui/lua_helper.h"
|
||||||
|
#include "nel/misc/file.h"
|
||||||
|
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
#include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "nel/gui/lua_loadlib.h"
|
||||||
|
|
||||||
|
// to get rid of you_must_not_use_assert___use_nl_assert___read_debug_h_file messages
|
||||||
|
#include <cassert>
|
||||||
|
#ifdef assert
|
||||||
|
#undef assert
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NL_DEBUG
|
||||||
|
#define assert(x) nlassert(x)
|
||||||
|
#else
|
||||||
|
#define assert(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <luabind/luabind.hpp>
|
||||||
|
#include <nel/misc/algo.h>
|
||||||
|
#include <nel/misc/path.h>
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace NLMISC;
|
||||||
|
|
||||||
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace LuaHelperStuff
|
||||||
|
{
|
||||||
|
void formatLuaStackContext( std::string &stackContext )
|
||||||
|
{
|
||||||
|
stackContext = std::string( "@{FC8A}" ).append( stackContext ).append( "@{FC8F} " );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string formatLuaErrorSysInfo( const std::string &error )
|
||||||
|
{
|
||||||
|
return std::string( "@{FC8F}" ).append( error );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string formatLuaErrorNlWarn( const std::string &error )
|
||||||
|
{
|
||||||
|
// Remove color tags (see formatLuaErrorSC())
|
||||||
|
std::string ret = error;
|
||||||
|
strFindReplace( ret, "@{FC8A}", "" );
|
||||||
|
strFindReplace( ret, "@{FC8F}", "" );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
const char *CLuaState::_NELSmallScriptTableName= "NELSmallScriptTable";
|
||||||
|
uint CLuaStackChecker::_ExceptionContextCounter = 0;
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaStackChecker::incrementExceptionContextCounter()
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaStackChecker_incrementExceptionContextCounter)
|
||||||
|
++ _ExceptionContextCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaStackChecker::decrementExceptionContextCounter()
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaStackChecker_decrementExceptionContextCounter)
|
||||||
|
nlassert(_ExceptionContextCounter > 0);
|
||||||
|
-- _ExceptionContextCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
ILuaIDEInterface *LuaDebuggerIDE = NULL;
|
||||||
|
static bool LuaDebuggerVisible = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
HMODULE LuaDebuggerModule = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void luaDebuggerMainLoop()
|
||||||
|
{
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
if (!LuaDebuggerIDE) return;
|
||||||
|
if (!LuaDebuggerVisible)
|
||||||
|
{
|
||||||
|
LuaDebuggerIDE->showDebugger(true);
|
||||||
|
LuaDebuggerIDE->expandProjectTree();
|
||||||
|
LuaDebuggerIDE->sortFiles();
|
||||||
|
LuaDebuggerVisible = true;
|
||||||
|
}
|
||||||
|
LuaDebuggerIDE->doMainLoop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static std::allocator<uint8> l_stlAlloc;
|
||||||
|
|
||||||
|
|
||||||
|
static void l_free_func(void *block, int oldSize)
|
||||||
|
{
|
||||||
|
l_stlAlloc.deallocate((uint8 *) block, oldSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *l_realloc_func(void *b, int os, int s)
|
||||||
|
{
|
||||||
|
if (os == s) return b;
|
||||||
|
void *newB = l_stlAlloc.allocate(s);
|
||||||
|
memcpy(newB, b, std::min(os, s));
|
||||||
|
l_free_func(b, os);
|
||||||
|
return newB;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const int MinGCThreshold = 128; // min value at which garbage collector will be triggered (in kilobytes)
|
||||||
|
// ***************************************************************************
|
||||||
|
CLuaState::CLuaState( bool debugger )
|
||||||
|
{
|
||||||
|
_State = NULL;
|
||||||
|
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
_GCThreshold = MinGCThreshold;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
if( debugger )
|
||||||
|
{
|
||||||
|
#ifndef LUA_NEVRAX_VERSION
|
||||||
|
static bool warningShown = false;
|
||||||
|
if (!warningShown)
|
||||||
|
{
|
||||||
|
nldebug( "Lua debugger was asked, but the static lua library against which the client was linked is too old. Please update to lua-5.0.2_nevrax. Debugging won't be available!" );
|
||||||
|
//MessageBox (NULL, "Lua debugger was asked, but the static lua library against which the client was linked is too old. Please update to lua-5.0.2_nevrax. Debugging won't be available!", "Lua support", MB_OK);
|
||||||
|
warningShown = true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
nlassert(LuaDebuggerIDE == NULL); // for now, only one debugger supported...
|
||||||
|
#ifdef NL_DEBUG
|
||||||
|
LuaDebuggerModule = ::LoadLibrary("lua_ide2_dll_d.dll");
|
||||||
|
#else
|
||||||
|
LuaDebuggerModule = ::LoadLibrary("lua_ide2_dll_r.dll");
|
||||||
|
#endif
|
||||||
|
if (LuaDebuggerModule)
|
||||||
|
{
|
||||||
|
TGetLuaIDEInterfaceVersion getVersion = (TGetLuaIDEInterfaceVersion) GetProcAddress(LuaDebuggerModule, "GetLuaIDEInterfaceVersion");
|
||||||
|
nlassert(getVersion);
|
||||||
|
int dllInterfaceVersion = getVersion();
|
||||||
|
if (dllInterfaceVersion > LUA_IDE_INTERFACE_VERSION)
|
||||||
|
{
|
||||||
|
MessageBox (NULL, "Lua debugger interface is newer than the application. Debugging will be disabled. Please update your client", "Lua support", MB_OK);
|
||||||
|
}
|
||||||
|
else if (dllInterfaceVersion < LUA_IDE_INTERFACE_VERSION)
|
||||||
|
{
|
||||||
|
MessageBox (NULL, "Lua debugger interface is too old. Lua debugging will be disabled. Please ask for a more recent dll.", "Lua support", MB_OK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TGetLuaIDEInterface getter = (TGetLuaIDEInterface) GetProcAddress(LuaDebuggerModule, "GetLuaIDEInterface");
|
||||||
|
nlassert(getter);
|
||||||
|
LuaDebuggerIDE = getter();
|
||||||
|
LuaDebuggerIDE->prepareDebug("save\\___external_debug.lpr", l_realloc_func, l_free_func, Driver->getDisplay());
|
||||||
|
_State = LuaDebuggerIDE->getLuaState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!_State)
|
||||||
|
{
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
_State = lua_open(l_realloc_func, l_free_func);
|
||||||
|
#else
|
||||||
|
_State = lua_open();
|
||||||
|
#endif
|
||||||
|
nlassert(_State);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** Load base libs
|
||||||
|
{
|
||||||
|
CLuaStackChecker lsc(this);
|
||||||
|
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
||||||
|
luaL_openlibs(_State);
|
||||||
|
#else
|
||||||
|
luaopen_base (_State);
|
||||||
|
luaopen_table (_State);
|
||||||
|
luaopen_io (_State);
|
||||||
|
luaopen_string (_State);
|
||||||
|
luaopen_math (_State);
|
||||||
|
luaopen_debug (_State);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// open are buggy????
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** Register basics
|
||||||
|
CLuaStackChecker lsc(this);
|
||||||
|
|
||||||
|
// do: LUA_REGISTRYINDEX.(lightuserdata*)this.classes= {}
|
||||||
|
pushLightUserData((void *) this);
|
||||||
|
newTable();
|
||||||
|
push("classes");
|
||||||
|
newTable(); // registry class
|
||||||
|
setTable(-3);
|
||||||
|
setTable(LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
// add pointer from lua state to this CLuaState object
|
||||||
|
// do: LUA_REGISTRYINDEX.(lightuserdata*)_State= this
|
||||||
|
pushLightUserData((void *) _State); // NB : as creator of the state, we make the assumption that
|
||||||
|
// no one will be using this pointer in the registry (cf. ref manual about registry)
|
||||||
|
pushLightUserData((void *) this);
|
||||||
|
setTable(LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
// Create the Table that contains Function cache for small script execution
|
||||||
|
push(_NELSmallScriptTableName); // 1:TableName
|
||||||
|
newTable(); // 1:TableName 2:table
|
||||||
|
setTable(LUA_REGISTRYINDEX); // ...
|
||||||
|
_SmallScriptPool= 0;
|
||||||
|
|
||||||
|
// *** luabind init
|
||||||
|
luabind::open(_State);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
CLuaStackRestorer::CLuaStackRestorer(CLuaState *state, int finalSize) : _FinalSize(finalSize), _State(state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
CLuaStackRestorer::~CLuaStackRestorer()
|
||||||
|
{
|
||||||
|
nlassert(_State);
|
||||||
|
_State->setTop(_FinalSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
static int NoOpReportHook( int /* reportType */, char * /* message */, int * /* returnValue */ )
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
CLuaState::~CLuaState()
|
||||||
|
{
|
||||||
|
nlassert(_State);
|
||||||
|
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
if (!LuaDebuggerIDE)
|
||||||
|
#else
|
||||||
|
if (1)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
lua_close(_State);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
LuaDebuggerIDE->stopDebug(); // this will also close the lua state
|
||||||
|
LuaDebuggerIDE = NULL;
|
||||||
|
LuaDebuggerVisible = false;
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
nlassert(LuaDebuggerModule)
|
||||||
|
_CrtSetReportHook(NoOpReportHook); // prevent dump of memory leaks at this point
|
||||||
|
//::FreeLibrary(LuaDebuggerModule); // don't free the library now (seems that it destroy, the main window, causing
|
||||||
|
// a crash when the app window is destroyed for real...
|
||||||
|
// -> FreeLibrary will be called when the application is closed
|
||||||
|
LuaDebuggerModule = 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear Small Script Cache
|
||||||
|
_SmallScriptPool= 0;
|
||||||
|
_SmallScriptCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
CLuaState *CLuaState::fromStatePointer(lua_State *state)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_fromStatePointer)
|
||||||
|
nlassert(state);
|
||||||
|
int initialStackSize = lua_gettop(state);
|
||||||
|
lua_checkstack(state, initialStackSize + 2);
|
||||||
|
lua_pushlightuserdata(state, (void *) state);
|
||||||
|
lua_gettable(state, LUA_REGISTRYINDEX);
|
||||||
|
if (!lua_islightuserdata(state, -1))
|
||||||
|
{
|
||||||
|
lua_pop(state, 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
CLuaState *ls = (CLuaState *) lua_touserdata(state, -1);
|
||||||
|
lua_pop(state, 1);
|
||||||
|
nlassert(initialStackSize == lua_gettop(state));
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
struct CLuaReader
|
||||||
|
{
|
||||||
|
const std::string *Str;
|
||||||
|
bool Done;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CLuaState::loadScript(const std::string &code, const std::string &dbgSrc)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_loadScript)
|
||||||
|
if (code.empty()) return;
|
||||||
|
struct CHelper
|
||||||
|
{
|
||||||
|
static const char *luaChunkReaderFromString(lua_State * /* L */, void *ud, size_t *sz)
|
||||||
|
{
|
||||||
|
CLuaReader *rd = (CLuaReader *) ud;
|
||||||
|
if (!rd->Done)
|
||||||
|
{
|
||||||
|
rd->Done = true;
|
||||||
|
*sz = rd->Str->size();
|
||||||
|
return rd->Str->c_str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*sz = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
CLuaReader rd;
|
||||||
|
rd.Str = &code;
|
||||||
|
rd.Done = false;
|
||||||
|
|
||||||
|
int result = lua_load(_State, CHelper::luaChunkReaderFromString, (void *) &rd, dbgSrc.c_str());
|
||||||
|
if (result !=0)
|
||||||
|
{
|
||||||
|
// pop the error code
|
||||||
|
string err= toString();
|
||||||
|
pop();
|
||||||
|
// throw error
|
||||||
|
throw ELuaParseError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::executeScriptInternal(const std::string &code, const std::string &dbgSrc, int numRet)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_executeScriptInternal)
|
||||||
|
CLuaStackChecker lsc(this, numRet);
|
||||||
|
|
||||||
|
// load the script
|
||||||
|
loadScript(code, dbgSrc);
|
||||||
|
|
||||||
|
// execute
|
||||||
|
if (pcall(0, numRet) != 0)
|
||||||
|
{
|
||||||
|
// pop the error code
|
||||||
|
string err= toString();
|
||||||
|
pop();
|
||||||
|
// throw error
|
||||||
|
throw ELuaExecuteError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::executeScript(const std::string &code, int numRet)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_executeScript)
|
||||||
|
// run the script, with dbgSrc==script
|
||||||
|
executeScriptInternal(code, code, numRet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
bool CLuaState::executeScriptNoThrow(const std::string &code, int numRet)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_executeScriptNoThrow)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
executeScript(code, numRet);
|
||||||
|
}
|
||||||
|
catch (const ELuaError &e)
|
||||||
|
{
|
||||||
|
nlwarning(e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
bool CLuaState::executeFile(const std::string &pathName)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_executeFile)
|
||||||
|
|
||||||
|
CIFile inputFile;
|
||||||
|
if(!inputFile.open(pathName))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
if (LuaDebuggerIDE)
|
||||||
|
{
|
||||||
|
std::string path = NLMISC::CPath::getCurrentPath() + "/" + pathName.c_str();
|
||||||
|
path = CPath::standardizeDosPath(path);
|
||||||
|
LuaDebuggerIDE->addFile(path.c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// load the script text
|
||||||
|
string script;
|
||||||
|
/*
|
||||||
|
while(!inputFile.eof())
|
||||||
|
{
|
||||||
|
char tmpBuff[5000];
|
||||||
|
inputFile.getline(tmpBuff, 5000);
|
||||||
|
script+= tmpBuff;
|
||||||
|
script+= "\n";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
script.resize(CFile::getFileSize(pathName));
|
||||||
|
inputFile.serialBuffer((uint8 *) &script[0], (uint)script.size());
|
||||||
|
|
||||||
|
|
||||||
|
// execute the script text, with dbgSrc==filename (use @ for lua internal purpose)
|
||||||
|
executeScriptInternal(script, string("@") + CFile::getFilename(pathName));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::executeSmallScript(const std::string &script)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_executeSmallScript)
|
||||||
|
if (script.empty()) return;
|
||||||
|
// *** if the small script has not already been called before, parse it now
|
||||||
|
TSmallScriptCache::iterator it= _SmallScriptCache.find(script);
|
||||||
|
if(it==_SmallScriptCache.end())
|
||||||
|
{
|
||||||
|
CLuaStackChecker lsc(this);
|
||||||
|
|
||||||
|
// add it to a function
|
||||||
|
loadScript(script, script);
|
||||||
|
|
||||||
|
// Assign the method to the NEL table: NELSmallScriptTable[_SmallScriptPool]= function
|
||||||
|
push(_NELSmallScriptTableName); // 1:function 2:NelTableName
|
||||||
|
getTable(LUA_REGISTRYINDEX); // 1:function 2:NelTable
|
||||||
|
insert(-2); // 1:NelTable 2:function
|
||||||
|
rawSetI(-2, _SmallScriptPool); // 1:NelTable
|
||||||
|
pop();
|
||||||
|
|
||||||
|
// bkup in cache map
|
||||||
|
it= _SmallScriptCache.insert(make_pair(script, _SmallScriptPool)).first;
|
||||||
|
|
||||||
|
// next allocated
|
||||||
|
_SmallScriptPool++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** Execute the function associated to the script
|
||||||
|
CLuaStackChecker lsc(this);
|
||||||
|
push(_NELSmallScriptTableName); // 1:NelTableName
|
||||||
|
getTable(LUA_REGISTRYINDEX); // 1:NelTable
|
||||||
|
// get the function at the given index in the "NELSmallScriptTable" table
|
||||||
|
rawGetI(-1, it->second); // 1:NelTable 2:function
|
||||||
|
|
||||||
|
// execute
|
||||||
|
if (pcall(0, 0) != 0)
|
||||||
|
{
|
||||||
|
// Stack: 1: NelTable 2:errorcode
|
||||||
|
// pop the error code, and clear stack
|
||||||
|
string err= toString();
|
||||||
|
pop(); // 1:NelTable
|
||||||
|
pop(); // ....
|
||||||
|
// throw error
|
||||||
|
throw ELuaExecuteError(err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Stack: 1:NelTable
|
||||||
|
pop(); // ....
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::registerFunc(const char *name, lua_CFunction function)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_registerFunc)
|
||||||
|
lua_register(_State, name, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::pushCClosure(lua_CFunction function, int n)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_pushCClosure)
|
||||||
|
nlassert(function);
|
||||||
|
nlassert(getTop() >= n);
|
||||||
|
lua_pushcclosure(_State, function, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::push(TLuaWrappedFunction function)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_push)
|
||||||
|
struct CForwarder
|
||||||
|
{
|
||||||
|
static int callFunc(lua_State *ls)
|
||||||
|
{
|
||||||
|
nlassert(ls);
|
||||||
|
TLuaWrappedFunction func = (TLuaWrappedFunction) lua_touserdata(ls, lua_upvalueindex(1));
|
||||||
|
CLuaState *state = (CLuaState *) lua_touserdata(ls, lua_upvalueindex(2));
|
||||||
|
nlassert(func);
|
||||||
|
nlassert(state);
|
||||||
|
// get real function pointer from the values in the closure
|
||||||
|
int numResults = 0;
|
||||||
|
int initialStackSize = state->getTop();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// call the actual function
|
||||||
|
numResults = func(*state);
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
// restore stack to its initial size
|
||||||
|
state->setTop(initialStackSize);
|
||||||
|
lua_pushstring(ls, e.what());
|
||||||
|
// TODO : see if this is safe to call lua error there" ... (it does a long jump)
|
||||||
|
lua_error(ls);
|
||||||
|
}
|
||||||
|
return numResults;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
pushLightUserData((void *) function);
|
||||||
|
pushLightUserData((void *) this);
|
||||||
|
pushCClosure(CForwarder::callFunc, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Wrapped function
|
||||||
|
void CLuaState::registerFunc(const char *name, TLuaWrappedFunction function)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_registerFunc)
|
||||||
|
nlassert(function);
|
||||||
|
CLuaStackChecker lsc(this);
|
||||||
|
push(name);
|
||||||
|
push(function);
|
||||||
|
setTable(LUA_GLOBALSINDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
bool CLuaState::getTableBooleanValue(const char *name, bool defaultValue)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_getTableBooleanValue)
|
||||||
|
nlassert(name);
|
||||||
|
push(name);
|
||||||
|
getTable(-2);
|
||||||
|
if (isNil())
|
||||||
|
{
|
||||||
|
pop();
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
bool result = toBoolean(-1);
|
||||||
|
pop();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
double CLuaState::getTableNumberValue(const char *name, double defaultValue)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_getTableNumberValue)
|
||||||
|
nlassert(name);
|
||||||
|
push(name);
|
||||||
|
getTable(-2);
|
||||||
|
if (isNil())
|
||||||
|
{
|
||||||
|
pop();
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
double result = toNumber(-1);
|
||||||
|
pop();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
const char *CLuaState::getTableStringValue(const char *name, const char *defaultValue)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_getTableStringValue)
|
||||||
|
nlassert(name);
|
||||||
|
push(name);
|
||||||
|
getTable(-2);
|
||||||
|
if (isNil())
|
||||||
|
{
|
||||||
|
pop();
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
const char *result = toString(-1);
|
||||||
|
pop();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::getStackContext(string &ret, uint stackLevel)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_getStackContext)
|
||||||
|
nlassert(_State);
|
||||||
|
ret.clear();
|
||||||
|
lua_Debug dbg;
|
||||||
|
if(lua_getstack (_State, stackLevel, &dbg))
|
||||||
|
{
|
||||||
|
if(lua_getinfo(_State, "lS", &dbg))
|
||||||
|
{
|
||||||
|
ret= NLMISC::toString("%s:%d:", dbg.short_src, dbg.currentline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
int CLuaState::pcallByName(const char *functionName, int nargs, int nresults, int funcTableIndex /*=LUA_GLOBALSINDEX*/, int errfunc /*= 0*/)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_pcallByName)
|
||||||
|
int initialStackSize = getTop();
|
||||||
|
nlassert(functionName);
|
||||||
|
nlassert(isTable(funcTableIndex));
|
||||||
|
pushValue(funcTableIndex);
|
||||||
|
push(functionName);
|
||||||
|
getTable(-2);
|
||||||
|
remove(-2); // get rid of the table
|
||||||
|
nlassert(getTop() >= nargs); // not enough arguments on the stack
|
||||||
|
// insert function before its arguments
|
||||||
|
insert(- 1 - nargs);
|
||||||
|
int result = pcall(nargs, nresults, errfunc);
|
||||||
|
int currSize = getTop();
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
nlassert(currSize == initialStackSize - nargs + nresults);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// errors, the stack contains a single string
|
||||||
|
if (errfunc == 0)
|
||||||
|
{
|
||||||
|
nlassert(currSize == initialStackSize - nargs + 1);
|
||||||
|
}
|
||||||
|
// else if there's an error handler, can't know the size of stack
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::dumpStack()
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_dumpStack)
|
||||||
|
nlinfo("LUA STACK CONTENT (size = %d)", getTop());
|
||||||
|
nlinfo("=================");
|
||||||
|
CLuaStackChecker lsc(this);
|
||||||
|
for(int k = 1; k <= getTop(); ++k)
|
||||||
|
{
|
||||||
|
pushValue(k);
|
||||||
|
std::string value = toString(-1) ? toString(-1) : "?";
|
||||||
|
nlinfo("Stack entry %d : type = %s, value = %s", k, getTypename(type(-1)), value.c_str());
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CLuaState::getStackAsString(std::string &dest)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_getStackAsString)
|
||||||
|
dest = NLMISC::toString("Stack size = %d\n", getTop());
|
||||||
|
CLuaStackChecker lsc(this);
|
||||||
|
for(int k = 1; k <= getTop(); ++k)
|
||||||
|
{
|
||||||
|
pushValue(k);
|
||||||
|
std::string value = toString(-1) ? toString(-1) : "?";
|
||||||
|
dest += NLMISC::toString("Stack entry %d : type = %s, value = %s\n", k, getTypename(type(-1)), value.c_str());
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
CLuaStackChecker::~CLuaStackChecker()
|
||||||
|
{
|
||||||
|
nlassert(_State);
|
||||||
|
if (!_ExceptionContextCounter)
|
||||||
|
{
|
||||||
|
int currSize = _State->getTop();
|
||||||
|
if (currSize != _FinalWantedSize)
|
||||||
|
{
|
||||||
|
static volatile bool assertWanted = true;
|
||||||
|
if (assertWanted)
|
||||||
|
{
|
||||||
|
nlwarning("Lua stack size error : expected size is %d, current size is %d", _FinalWantedSize, currSize);
|
||||||
|
_State->dumpStack();
|
||||||
|
nlassert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this object dtor was called because an exception was thrown, so let the exception
|
||||||
|
// propagate (the stack must be broken, but because of the exception, not because of code error)
|
||||||
|
_State->setTop(_FinalWantedSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void ELuaWrappedFunctionException::init(CLuaState *ls, const std::string &reason)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_ELuaWrappedFunctionException_init)
|
||||||
|
// Print first Lua Stack Context
|
||||||
|
if(ls)
|
||||||
|
{
|
||||||
|
ls->getStackContext(_Reason, 1); // 1 because 0 is the current C function => return 1 for script called
|
||||||
|
// enclose with cool colors
|
||||||
|
LuaHelperStuff::formatLuaStackContext(_Reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the reason
|
||||||
|
_Reason+= reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
ELuaWrappedFunctionException::ELuaWrappedFunctionException(CLuaState *luaState)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_ELuaWrappedFunctionException_ELuaWrappedFunctionException)
|
||||||
|
init(luaState, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
ELuaWrappedFunctionException::ELuaWrappedFunctionException(CLuaState *luaState, const std::string &reason)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_ELuaWrappedFunctionException_ELuaWrappedFunctionException)
|
||||||
|
init(luaState, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
ELuaWrappedFunctionException::ELuaWrappedFunctionException(CLuaState *luaState, const char *format, ...)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_ELuaWrappedFunctionException_ELuaWrappedFunctionException)
|
||||||
|
std::string reason;
|
||||||
|
NLMISC_CONVERT_VARGS (reason, format, NLMISC::MaxCStringSize);
|
||||||
|
init(luaState, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
void CLuaState::newTable()
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_newTable)
|
||||||
|
nlverify( lua_checkstack(_State, 1) );
|
||||||
|
lua_newtable(_State);
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
int CLuaState::getGCCount()
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_getGCCount)
|
||||||
|
return lua_getgccount(_State);
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
int CLuaState::getGCThreshold()
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_getGCThreshold)
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
return _GCThreshold;
|
||||||
|
#else
|
||||||
|
# if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
||||||
|
return lua_gc(_State, LUA_GCCOUNT, 0);
|
||||||
|
# else
|
||||||
|
return lua_getgcthreshold(_State);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
void CLuaState::setGCThreshold(int kb)
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_setGCThreshold)
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
_GCThreshold = kb;
|
||||||
|
handleGC();
|
||||||
|
#else
|
||||||
|
# if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
||||||
|
lua_gc(_State, LUA_GCCOLLECT, kb);
|
||||||
|
# else
|
||||||
|
lua_setgcthreshold(_State, kb);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
void CLuaState::handleGC()
|
||||||
|
{
|
||||||
|
//H_AUTO(Lua_CLuaState_handleGC)
|
||||||
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
|
// must handle gc manually with the refcounted version
|
||||||
|
int gcCount = getGCCount();
|
||||||
|
if (gcCount >= _GCThreshold)
|
||||||
|
{
|
||||||
|
nlwarning("Triggering GC : memory in use = %d kb, current threshold = %d kb", gcCount, _GCThreshold);
|
||||||
|
lua_setgcthreshold(_State, 0);
|
||||||
|
gcCount = getGCCount();
|
||||||
|
_GCThreshold = std::max(MinGCThreshold, gcCount * 2);
|
||||||
|
nlwarning("After GC : memory in use = %d kb, threshold = %d kb", gcCount, _GCThreshold);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -40,7 +40,8 @@
|
||||||
#include "interface_v3/interface_manager.h"
|
#include "interface_v3/interface_manager.h"
|
||||||
#include "interface_v3/sphrase_manager.h"
|
#include "interface_v3/sphrase_manager.h"
|
||||||
#include "entities.h"
|
#include "entities.h"
|
||||||
#include "interface_v3/lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
#include "character_cl.h"
|
#include "character_cl.h"
|
||||||
#include "r2/editor.h"
|
#include "r2/editor.h"
|
||||||
#include "r2/dmc/client_edition_module.h"
|
#include "r2/dmc/client_edition_module.h"
|
||||||
|
|
|
@ -106,7 +106,12 @@
|
||||||
#include "chat_text_manager.h"
|
#include "chat_text_manager.h"
|
||||||
#include "../npc_icon.h"
|
#include "../npc_icon.h"
|
||||||
|
|
||||||
#include "lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
extern void luaDebuggerMainLoop();
|
||||||
|
}
|
||||||
|
using namespace NLGUI;
|
||||||
#include "lua_ihm.h"
|
#include "lua_ihm.h"
|
||||||
|
|
||||||
#include "add_on_manager.h"
|
#include "add_on_manager.h"
|
||||||
|
@ -1359,7 +1364,6 @@ void CInterfaceManager::updateFrameEvents()
|
||||||
pPM->update();
|
pPM->update();
|
||||||
|
|
||||||
// if there's an external lua debugger, update it
|
// if there's an external lua debugger, update it
|
||||||
extern void luaDebuggerMainLoop();
|
|
||||||
luaDebuggerMainLoop();
|
luaDebuggerMainLoop();
|
||||||
|
|
||||||
// handle gc for lua
|
// handle gc for lua
|
||||||
|
|
|
@ -105,7 +105,8 @@
|
||||||
#include "inventory_manager.h"
|
#include "inventory_manager.h"
|
||||||
#include "task_bar_manager.h"
|
#include "task_bar_manager.h"
|
||||||
#include "../commands.h"
|
#include "../commands.h"
|
||||||
#include "lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
#include "lua_ihm.h"
|
#include "lua_ihm.h"
|
||||||
#include "../r2/editor.h"
|
#include "../r2/editor.h"
|
||||||
|
|
||||||
|
@ -4661,7 +4662,7 @@ void CInterfaceParser::initLUA()
|
||||||
|
|
||||||
// create a new LUA environnement
|
// create a new LUA environnement
|
||||||
nlassert(_LuaState==NULL);
|
nlassert(_LuaState==NULL);
|
||||||
_LuaState= new CLuaState;
|
_LuaState= new CLuaState( ClientCfg.LoadLuaDebugger );
|
||||||
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
#ifdef LUA_NEVRAX_VERSION
|
||||||
extern ILuaIDEInterface *LuaDebuggerIDE;
|
extern ILuaIDEInterface *LuaDebuggerIDE;
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
#include "interface_link.h"
|
#include "interface_link.h"
|
||||||
#include "nel/misc/smart_ptr.h"
|
#include "nel/misc/smart_ptr.h"
|
||||||
#include "game_share/brick_types.h"
|
#include "game_share/brick_types.h"
|
||||||
#include "lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
class CInterfaceElement;
|
class CInterfaceElement;
|
||||||
|
|
|
@ -1,829 +0,0 @@
|
||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "stdpch.h"
|
|
||||||
|
|
||||||
#include "lua_helper.h"
|
|
||||||
#include "nel/misc/file.h"
|
|
||||||
//#include "interface_manager.h"
|
|
||||||
#include "../client_cfg.h"
|
|
||||||
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
#include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "lua_loadlib.h"
|
|
||||||
|
|
||||||
// to get rid of you_must_not_use_assert___use_nl_assert___read_debug_h_file messages
|
|
||||||
#include <cassert>
|
|
||||||
#ifdef assert
|
|
||||||
#undef assert
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NL_DEBUG
|
|
||||||
#define assert(x) nlassert(x)
|
|
||||||
#else
|
|
||||||
#define assert(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <luabind/luabind.hpp>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace NLMISC;
|
|
||||||
|
|
||||||
namespace LuaHelperStuff
|
|
||||||
{
|
|
||||||
void formatLuaStackContext( std::string &stackContext )
|
|
||||||
{
|
|
||||||
stackContext = std::string( "@{FC8A}" ).append( stackContext ).append( "@{FC8F} " );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string formatLuaErrorSysInfo( const std::string &error )
|
|
||||||
{
|
|
||||||
return std::string( "@{FC8F}" ).append( error );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string formatLuaErrorNlWarn( const std::string &error )
|
|
||||||
{
|
|
||||||
// Remove color tags (see formatLuaErrorSC())
|
|
||||||
std::string ret = error;
|
|
||||||
strFindReplace( ret, "@{FC8A}", "" );
|
|
||||||
strFindReplace( ret, "@{FC8F}", "" );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
const char *CLuaState::_NELSmallScriptTableName= "NELSmallScriptTable";
|
|
||||||
uint CLuaStackChecker::_ExceptionContextCounter = 0;
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaStackChecker::incrementExceptionContextCounter()
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaStackChecker_incrementExceptionContextCounter)
|
|
||||||
++ _ExceptionContextCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaStackChecker::decrementExceptionContextCounter()
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaStackChecker_decrementExceptionContextCounter)
|
|
||||||
nlassert(_ExceptionContextCounter > 0);
|
|
||||||
-- _ExceptionContextCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
ILuaIDEInterface *LuaDebuggerIDE = NULL;
|
|
||||||
static bool LuaDebuggerVisible = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
HMODULE LuaDebuggerModule = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void luaDebuggerMainLoop()
|
|
||||||
{
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
if (!LuaDebuggerIDE) return;
|
|
||||||
if (!LuaDebuggerVisible)
|
|
||||||
{
|
|
||||||
LuaDebuggerIDE->showDebugger(true);
|
|
||||||
LuaDebuggerIDE->expandProjectTree();
|
|
||||||
LuaDebuggerIDE->sortFiles();
|
|
||||||
LuaDebuggerVisible = true;
|
|
||||||
}
|
|
||||||
LuaDebuggerIDE->doMainLoop();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static std::allocator<uint8> l_stlAlloc;
|
|
||||||
|
|
||||||
|
|
||||||
static void l_free_func(void *block, int oldSize)
|
|
||||||
{
|
|
||||||
l_stlAlloc.deallocate((uint8 *) block, oldSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *l_realloc_func(void *b, int os, int s)
|
|
||||||
{
|
|
||||||
if (os == s) return b;
|
|
||||||
void *newB = l_stlAlloc.allocate(s);
|
|
||||||
memcpy(newB, b, std::min(os, s));
|
|
||||||
l_free_func(b, os);
|
|
||||||
return newB;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const int MinGCThreshold = 128; // min value at which garbage collector will be triggered (in kilobytes)
|
|
||||||
// ***************************************************************************
|
|
||||||
CLuaState::CLuaState()
|
|
||||||
{
|
|
||||||
_State = NULL;
|
|
||||||
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
_GCThreshold = MinGCThreshold;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
if (ClientCfg.LoadLuaDebugger)
|
|
||||||
{
|
|
||||||
#ifndef LUA_NEVRAX_VERSION
|
|
||||||
static bool warningShown = false;
|
|
||||||
if (!warningShown)
|
|
||||||
{
|
|
||||||
MessageBox (NULL, "Lua debugger was asked, but the static lua library against which the client was linked is too old. Please update to lua-5.0.2_nevrax. Debugging won't be available!", "Lua support", MB_OK);
|
|
||||||
warningShown = true;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
nlassert(LuaDebuggerIDE == NULL); // for now, only one debugger supported...
|
|
||||||
#ifdef NL_DEBUG
|
|
||||||
LuaDebuggerModule = ::LoadLibrary("lua_ide2_dll_d.dll");
|
|
||||||
#else
|
|
||||||
LuaDebuggerModule = ::LoadLibrary("lua_ide2_dll_r.dll");
|
|
||||||
#endif
|
|
||||||
if (LuaDebuggerModule)
|
|
||||||
{
|
|
||||||
TGetLuaIDEInterfaceVersion getVersion = (TGetLuaIDEInterfaceVersion) GetProcAddress(LuaDebuggerModule, "GetLuaIDEInterfaceVersion");
|
|
||||||
nlassert(getVersion);
|
|
||||||
int dllInterfaceVersion = getVersion();
|
|
||||||
if (dllInterfaceVersion > LUA_IDE_INTERFACE_VERSION)
|
|
||||||
{
|
|
||||||
MessageBox (NULL, "Lua debugger interface is newer than the application. Debugging will be disabled. Please update your client", "Lua support", MB_OK);
|
|
||||||
}
|
|
||||||
else if (dllInterfaceVersion < LUA_IDE_INTERFACE_VERSION)
|
|
||||||
{
|
|
||||||
MessageBox (NULL, "Lua debugger interface is too old. Lua debugging will be disabled. Please ask for a more recent dll.", "Lua support", MB_OK);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TGetLuaIDEInterface getter = (TGetLuaIDEInterface) GetProcAddress(LuaDebuggerModule, "GetLuaIDEInterface");
|
|
||||||
nlassert(getter);
|
|
||||||
LuaDebuggerIDE = getter();
|
|
||||||
LuaDebuggerIDE->prepareDebug("save\\___external_debug.lpr", l_realloc_func, l_free_func, Driver->getDisplay());
|
|
||||||
_State = LuaDebuggerIDE->getLuaState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!_State)
|
|
||||||
{
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
_State = lua_open(l_realloc_func, l_free_func);
|
|
||||||
#else
|
|
||||||
_State = lua_open();
|
|
||||||
#endif
|
|
||||||
nlassert(_State);
|
|
||||||
}
|
|
||||||
|
|
||||||
// *** Load base libs
|
|
||||||
{
|
|
||||||
CLuaStackChecker lsc(this);
|
|
||||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
|
||||||
luaL_openlibs(_State);
|
|
||||||
#else
|
|
||||||
luaopen_base (_State);
|
|
||||||
luaopen_table (_State);
|
|
||||||
luaopen_io (_State);
|
|
||||||
luaopen_string (_State);
|
|
||||||
luaopen_math (_State);
|
|
||||||
luaopen_debug (_State);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// open are buggy????
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// *** Register basics
|
|
||||||
CLuaStackChecker lsc(this);
|
|
||||||
|
|
||||||
// do: LUA_REGISTRYINDEX.(lightuserdata*)this.classes= {}
|
|
||||||
pushLightUserData((void *) this);
|
|
||||||
newTable();
|
|
||||||
push("classes");
|
|
||||||
newTable(); // registry class
|
|
||||||
setTable(-3);
|
|
||||||
setTable(LUA_REGISTRYINDEX);
|
|
||||||
|
|
||||||
// add pointer from lua state to this CLuaState object
|
|
||||||
// do: LUA_REGISTRYINDEX.(lightuserdata*)_State= this
|
|
||||||
pushLightUserData((void *) _State); // NB : as creator of the state, we make the assumption that
|
|
||||||
// no one will be using this pointer in the registry (cf. ref manual about registry)
|
|
||||||
pushLightUserData((void *) this);
|
|
||||||
setTable(LUA_REGISTRYINDEX);
|
|
||||||
|
|
||||||
// Create the Table that contains Function cache for small script execution
|
|
||||||
push(_NELSmallScriptTableName); // 1:TableName
|
|
||||||
newTable(); // 1:TableName 2:table
|
|
||||||
setTable(LUA_REGISTRYINDEX); // ...
|
|
||||||
_SmallScriptPool= 0;
|
|
||||||
|
|
||||||
// *** luabind init
|
|
||||||
luabind::open(_State);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
CLuaStackRestorer::CLuaStackRestorer(CLuaState *state, int finalSize) : _FinalSize(finalSize), _State(state)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
CLuaStackRestorer::~CLuaStackRestorer()
|
|
||||||
{
|
|
||||||
nlassert(_State);
|
|
||||||
_State->setTop(_FinalSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
static int NoOpReportHook( int /* reportType */, char * /* message */, int * /* returnValue */ )
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
CLuaState::~CLuaState()
|
|
||||||
{
|
|
||||||
nlassert(_State);
|
|
||||||
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
if (!LuaDebuggerIDE)
|
|
||||||
#else
|
|
||||||
if (1)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
lua_close(_State);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
LuaDebuggerIDE->stopDebug(); // this will also close the lua state
|
|
||||||
LuaDebuggerIDE = NULL;
|
|
||||||
LuaDebuggerVisible = false;
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
nlassert(LuaDebuggerModule)
|
|
||||||
_CrtSetReportHook(NoOpReportHook); // prevent dump of memory leaks at this point
|
|
||||||
//::FreeLibrary(LuaDebuggerModule); // don't free the library now (seems that it destroy, the main window, causing
|
|
||||||
// a crash when the app window is destroyed for real...
|
|
||||||
// -> FreeLibrary will be called when the application is closed
|
|
||||||
LuaDebuggerModule = 0;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear Small Script Cache
|
|
||||||
_SmallScriptPool= 0;
|
|
||||||
_SmallScriptCache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
CLuaState *CLuaState::fromStatePointer(lua_State *state)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_fromStatePointer)
|
|
||||||
nlassert(state);
|
|
||||||
int initialStackSize = lua_gettop(state);
|
|
||||||
lua_checkstack(state, initialStackSize + 2);
|
|
||||||
lua_pushlightuserdata(state, (void *) state);
|
|
||||||
lua_gettable(state, LUA_REGISTRYINDEX);
|
|
||||||
if (!lua_islightuserdata(state, -1))
|
|
||||||
{
|
|
||||||
lua_pop(state, 1);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
CLuaState *ls = (CLuaState *) lua_touserdata(state, -1);
|
|
||||||
lua_pop(state, 1);
|
|
||||||
nlassert(initialStackSize == lua_gettop(state));
|
|
||||||
return ls;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
struct CLuaReader
|
|
||||||
{
|
|
||||||
const std::string *Str;
|
|
||||||
bool Done;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CLuaState::loadScript(const std::string &code, const std::string &dbgSrc)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_loadScript)
|
|
||||||
if (code.empty()) return;
|
|
||||||
struct CHelper
|
|
||||||
{
|
|
||||||
static const char *luaChunkReaderFromString(lua_State * /* L */, void *ud, size_t *sz)
|
|
||||||
{
|
|
||||||
CLuaReader *rd = (CLuaReader *) ud;
|
|
||||||
if (!rd->Done)
|
|
||||||
{
|
|
||||||
rd->Done = true;
|
|
||||||
*sz = rd->Str->size();
|
|
||||||
return rd->Str->c_str();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*sz = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
CLuaReader rd;
|
|
||||||
rd.Str = &code;
|
|
||||||
rd.Done = false;
|
|
||||||
|
|
||||||
int result = lua_load(_State, CHelper::luaChunkReaderFromString, (void *) &rd, dbgSrc.c_str());
|
|
||||||
if (result !=0)
|
|
||||||
{
|
|
||||||
// pop the error code
|
|
||||||
string err= toString();
|
|
||||||
pop();
|
|
||||||
// throw error
|
|
||||||
throw ELuaParseError(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::executeScriptInternal(const std::string &code, const std::string &dbgSrc, int numRet)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_executeScriptInternal)
|
|
||||||
CLuaStackChecker lsc(this, numRet);
|
|
||||||
|
|
||||||
// load the script
|
|
||||||
loadScript(code, dbgSrc);
|
|
||||||
|
|
||||||
// execute
|
|
||||||
if (pcall(0, numRet) != 0)
|
|
||||||
{
|
|
||||||
// pop the error code
|
|
||||||
string err= toString();
|
|
||||||
pop();
|
|
||||||
// throw error
|
|
||||||
throw ELuaExecuteError(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::executeScript(const std::string &code, int numRet)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_executeScript)
|
|
||||||
// run the script, with dbgSrc==script
|
|
||||||
executeScriptInternal(code, code, numRet);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
bool CLuaState::executeScriptNoThrow(const std::string &code, int numRet)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_executeScriptNoThrow)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
executeScript(code, numRet);
|
|
||||||
}
|
|
||||||
catch (const ELuaError &e)
|
|
||||||
{
|
|
||||||
nlwarning(e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
bool CLuaState::executeFile(const std::string &pathName)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_executeFile)
|
|
||||||
|
|
||||||
CIFile inputFile;
|
|
||||||
if(!inputFile.open(pathName))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
if (LuaDebuggerIDE)
|
|
||||||
{
|
|
||||||
std::string path = NLMISC::CPath::getCurrentPath() + "/" + pathName.c_str();
|
|
||||||
path = CPath::standardizeDosPath(path);
|
|
||||||
LuaDebuggerIDE->addFile(path.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// load the script text
|
|
||||||
string script;
|
|
||||||
/*
|
|
||||||
while(!inputFile.eof())
|
|
||||||
{
|
|
||||||
char tmpBuff[5000];
|
|
||||||
inputFile.getline(tmpBuff, 5000);
|
|
||||||
script+= tmpBuff;
|
|
||||||
script+= "\n";
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
script.resize(CFile::getFileSize(pathName));
|
|
||||||
inputFile.serialBuffer((uint8 *) &script[0], (uint)script.size());
|
|
||||||
|
|
||||||
|
|
||||||
// execute the script text, with dbgSrc==filename (use @ for lua internal purpose)
|
|
||||||
executeScriptInternal(script, string("@") + CFile::getFilename(pathName));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::executeSmallScript(const std::string &script)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_executeSmallScript)
|
|
||||||
if (script.empty()) return;
|
|
||||||
// *** if the small script has not already been called before, parse it now
|
|
||||||
TSmallScriptCache::iterator it= _SmallScriptCache.find(script);
|
|
||||||
if(it==_SmallScriptCache.end())
|
|
||||||
{
|
|
||||||
CLuaStackChecker lsc(this);
|
|
||||||
|
|
||||||
// add it to a function
|
|
||||||
loadScript(script, script);
|
|
||||||
|
|
||||||
// Assign the method to the NEL table: NELSmallScriptTable[_SmallScriptPool]= function
|
|
||||||
push(_NELSmallScriptTableName); // 1:function 2:NelTableName
|
|
||||||
getTable(LUA_REGISTRYINDEX); // 1:function 2:NelTable
|
|
||||||
insert(-2); // 1:NelTable 2:function
|
|
||||||
rawSetI(-2, _SmallScriptPool); // 1:NelTable
|
|
||||||
pop();
|
|
||||||
|
|
||||||
// bkup in cache map
|
|
||||||
it= _SmallScriptCache.insert(make_pair(script, _SmallScriptPool)).first;
|
|
||||||
|
|
||||||
// next allocated
|
|
||||||
_SmallScriptPool++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// *** Execute the function associated to the script
|
|
||||||
CLuaStackChecker lsc(this);
|
|
||||||
push(_NELSmallScriptTableName); // 1:NelTableName
|
|
||||||
getTable(LUA_REGISTRYINDEX); // 1:NelTable
|
|
||||||
// get the function at the given index in the "NELSmallScriptTable" table
|
|
||||||
rawGetI(-1, it->second); // 1:NelTable 2:function
|
|
||||||
|
|
||||||
// execute
|
|
||||||
if (pcall(0, 0) != 0)
|
|
||||||
{
|
|
||||||
// Stack: 1: NelTable 2:errorcode
|
|
||||||
// pop the error code, and clear stack
|
|
||||||
string err= toString();
|
|
||||||
pop(); // 1:NelTable
|
|
||||||
pop(); // ....
|
|
||||||
// throw error
|
|
||||||
throw ELuaExecuteError(err);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Stack: 1:NelTable
|
|
||||||
pop(); // ....
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::registerFunc(const char *name, lua_CFunction function)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_registerFunc)
|
|
||||||
lua_register(_State, name, function);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::pushCClosure(lua_CFunction function, int n)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_pushCClosure)
|
|
||||||
nlassert(function);
|
|
||||||
nlassert(getTop() >= n);
|
|
||||||
lua_pushcclosure(_State, function, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::push(TLuaWrappedFunction function)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_push)
|
|
||||||
struct CForwarder
|
|
||||||
{
|
|
||||||
static int callFunc(lua_State *ls)
|
|
||||||
{
|
|
||||||
nlassert(ls);
|
|
||||||
TLuaWrappedFunction func = (TLuaWrappedFunction) lua_touserdata(ls, lua_upvalueindex(1));
|
|
||||||
CLuaState *state = (CLuaState *) lua_touserdata(ls, lua_upvalueindex(2));
|
|
||||||
nlassert(func);
|
|
||||||
nlassert(state);
|
|
||||||
// get real function pointer from the values in the closure
|
|
||||||
int numResults = 0;
|
|
||||||
int initialStackSize = state->getTop();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// call the actual function
|
|
||||||
numResults = func(*state);
|
|
||||||
}
|
|
||||||
catch(const std::exception &e)
|
|
||||||
{
|
|
||||||
// restore stack to its initial size
|
|
||||||
state->setTop(initialStackSize);
|
|
||||||
lua_pushstring(ls, e.what());
|
|
||||||
// TODO : see if this is safe to call lua error there" ... (it does a long jump)
|
|
||||||
lua_error(ls);
|
|
||||||
}
|
|
||||||
return numResults;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
pushLightUserData((void *) function);
|
|
||||||
pushLightUserData((void *) this);
|
|
||||||
pushCClosure(CForwarder::callFunc, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
// Wrapped function
|
|
||||||
void CLuaState::registerFunc(const char *name, TLuaWrappedFunction function)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_registerFunc)
|
|
||||||
nlassert(function);
|
|
||||||
CLuaStackChecker lsc(this);
|
|
||||||
push(name);
|
|
||||||
push(function);
|
|
||||||
setTable(LUA_GLOBALSINDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
bool CLuaState::getTableBooleanValue(const char *name, bool defaultValue)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_getTableBooleanValue)
|
|
||||||
nlassert(name);
|
|
||||||
push(name);
|
|
||||||
getTable(-2);
|
|
||||||
if (isNil())
|
|
||||||
{
|
|
||||||
pop();
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
bool result = toBoolean(-1);
|
|
||||||
pop();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
double CLuaState::getTableNumberValue(const char *name, double defaultValue)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_getTableNumberValue)
|
|
||||||
nlassert(name);
|
|
||||||
push(name);
|
|
||||||
getTable(-2);
|
|
||||||
if (isNil())
|
|
||||||
{
|
|
||||||
pop();
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
double result = toNumber(-1);
|
|
||||||
pop();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
const char *CLuaState::getTableStringValue(const char *name, const char *defaultValue)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_getTableStringValue)
|
|
||||||
nlassert(name);
|
|
||||||
push(name);
|
|
||||||
getTable(-2);
|
|
||||||
if (isNil())
|
|
||||||
{
|
|
||||||
pop();
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
const char *result = toString(-1);
|
|
||||||
pop();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::getStackContext(string &ret, uint stackLevel)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_getStackContext)
|
|
||||||
nlassert(_State);
|
|
||||||
ret.clear();
|
|
||||||
lua_Debug dbg;
|
|
||||||
if(lua_getstack (_State, stackLevel, &dbg))
|
|
||||||
{
|
|
||||||
if(lua_getinfo(_State, "lS", &dbg))
|
|
||||||
{
|
|
||||||
ret= NLMISC::toString("%s:%d:", dbg.short_src, dbg.currentline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
int CLuaState::pcallByName(const char *functionName, int nargs, int nresults, int funcTableIndex /*=LUA_GLOBALSINDEX*/, int errfunc /*= 0*/)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_pcallByName)
|
|
||||||
int initialStackSize = getTop();
|
|
||||||
nlassert(functionName);
|
|
||||||
nlassert(isTable(funcTableIndex));
|
|
||||||
pushValue(funcTableIndex);
|
|
||||||
push(functionName);
|
|
||||||
getTable(-2);
|
|
||||||
remove(-2); // get rid of the table
|
|
||||||
nlassert(getTop() >= nargs); // not enough arguments on the stack
|
|
||||||
// insert function before its arguments
|
|
||||||
insert(- 1 - nargs);
|
|
||||||
int result = pcall(nargs, nresults, errfunc);
|
|
||||||
int currSize = getTop();
|
|
||||||
if (result == 0)
|
|
||||||
{
|
|
||||||
nlassert(currSize == initialStackSize - nargs + nresults);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// errors, the stack contains a single string
|
|
||||||
if (errfunc == 0)
|
|
||||||
{
|
|
||||||
nlassert(currSize == initialStackSize - nargs + 1);
|
|
||||||
}
|
|
||||||
// else if there's an error handler, can't know the size of stack
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::dumpStack()
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_dumpStack)
|
|
||||||
nlinfo("LUA STACK CONTENT (size = %d)", getTop());
|
|
||||||
nlinfo("=================");
|
|
||||||
CLuaStackChecker lsc(this);
|
|
||||||
for(int k = 1; k <= getTop(); ++k)
|
|
||||||
{
|
|
||||||
pushValue(k);
|
|
||||||
std::string value = toString(-1) ? toString(-1) : "?";
|
|
||||||
nlinfo("Stack entry %d : type = %s, value = %s", k, getTypename(type(-1)), value.c_str());
|
|
||||||
pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void CLuaState::getStackAsString(std::string &dest)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_getStackAsString)
|
|
||||||
dest = NLMISC::toString("Stack size = %d\n", getTop());
|
|
||||||
CLuaStackChecker lsc(this);
|
|
||||||
for(int k = 1; k <= getTop(); ++k)
|
|
||||||
{
|
|
||||||
pushValue(k);
|
|
||||||
std::string value = toString(-1) ? toString(-1) : "?";
|
|
||||||
dest += NLMISC::toString("Stack entry %d : type = %s, value = %s\n", k, getTypename(type(-1)), value.c_str());
|
|
||||||
pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
CLuaStackChecker::~CLuaStackChecker()
|
|
||||||
{
|
|
||||||
nlassert(_State);
|
|
||||||
if (!_ExceptionContextCounter)
|
|
||||||
{
|
|
||||||
int currSize = _State->getTop();
|
|
||||||
if (currSize != _FinalWantedSize)
|
|
||||||
{
|
|
||||||
static volatile bool assertWanted = true;
|
|
||||||
if (assertWanted)
|
|
||||||
{
|
|
||||||
nlwarning("Lua stack size error : expected size is %d, current size is %d", _FinalWantedSize, currSize);
|
|
||||||
_State->dumpStack();
|
|
||||||
nlassert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// this object dtor was called because an exception was thrown, so let the exception
|
|
||||||
// propagate (the stack must be broken, but because of the exception, not because of code error)
|
|
||||||
_State->setTop(_FinalWantedSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
void ELuaWrappedFunctionException::init(CLuaState *ls, const std::string &reason)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_ELuaWrappedFunctionException_init)
|
|
||||||
// Print first Lua Stack Context
|
|
||||||
if(ls)
|
|
||||||
{
|
|
||||||
ls->getStackContext(_Reason, 1); // 1 because 0 is the current C function => return 1 for script called
|
|
||||||
// enclose with cool colors
|
|
||||||
LuaHelperStuff::formatLuaStackContext(_Reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the reason
|
|
||||||
_Reason+= reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
ELuaWrappedFunctionException::ELuaWrappedFunctionException(CLuaState *luaState)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_ELuaWrappedFunctionException_ELuaWrappedFunctionException)
|
|
||||||
init(luaState, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
ELuaWrappedFunctionException::ELuaWrappedFunctionException(CLuaState *luaState, const std::string &reason)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_ELuaWrappedFunctionException_ELuaWrappedFunctionException)
|
|
||||||
init(luaState, reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
ELuaWrappedFunctionException::ELuaWrappedFunctionException(CLuaState *luaState, const char *format, ...)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_ELuaWrappedFunctionException_ELuaWrappedFunctionException)
|
|
||||||
std::string reason;
|
|
||||||
NLMISC_CONVERT_VARGS (reason, format, NLMISC::MaxCStringSize);
|
|
||||||
init(luaState, reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
void CLuaState::newTable()
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_newTable)
|
|
||||||
nlverify( lua_checkstack(_State, 1) );
|
|
||||||
lua_newtable(_State);
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
int CLuaState::getGCCount()
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_getGCCount)
|
|
||||||
return lua_getgccount(_State);
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
int CLuaState::getGCThreshold()
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_getGCThreshold)
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
return _GCThreshold;
|
|
||||||
#else
|
|
||||||
# if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
|
||||||
return lua_gc(_State, LUA_GCCOUNT, 0);
|
|
||||||
# else
|
|
||||||
return lua_getgcthreshold(_State);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
void CLuaState::setGCThreshold(int kb)
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_setGCThreshold)
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
_GCThreshold = kb;
|
|
||||||
handleGC();
|
|
||||||
#else
|
|
||||||
# if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
|
||||||
lua_gc(_State, LUA_GCCOLLECT, kb);
|
|
||||||
# else
|
|
||||||
lua_setgcthreshold(_State, kb);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
void CLuaState::handleGC()
|
|
||||||
{
|
|
||||||
//H_AUTO(Lua_CLuaState_handleGC)
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
// must handle gc manually with the refcounted version
|
|
||||||
int gcCount = getGCCount();
|
|
||||||
if (gcCount >= _GCThreshold)
|
|
||||||
{
|
|
||||||
nlwarning("Triggering GC : memory in use = %d kb, current threshold = %d kb", gcCount, _GCThreshold);
|
|
||||||
lua_setgcthreshold(_State, 0);
|
|
||||||
gcCount = getGCCount();
|
|
||||||
_GCThreshold = std::max(MinGCThreshold, gcCount * 2);
|
|
||||||
nlwarning("After GC : memory in use = %d kb, threshold = %d kb", gcCount, _GCThreshold);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,385 +0,0 @@
|
||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef RZ_LUA_HELPER_H
|
|
||||||
#define RZ_LUA_HELPER_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "nel/misc/types_nl.h"
|
|
||||||
#include "nel/misc/smart_ptr.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include "lua_loadlib.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
class CLuaState;
|
|
||||||
|
|
||||||
namespace LuaHelperStuff
|
|
||||||
{
|
|
||||||
void formatLuaStackContext( std::string &stackContext );
|
|
||||||
std::string formatLuaErrorSysInfo( const std::string &error );
|
|
||||||
std::string formatLuaErrorNlWarn( const std::string &error );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
/** Helper class to see if a stack is restored at its initial size (or with n return results).
|
|
||||||
* Check that the stack size remains unchanged when the object goes out of scope
|
|
||||||
*/
|
|
||||||
class CLuaStackChecker
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CLuaStackChecker(CLuaState *state, int numWantedResults = 0);
|
|
||||||
~CLuaStackChecker();
|
|
||||||
/** Increment exception context counter
|
|
||||||
* When an exception is thrown, lua stack checker do any assert bu will
|
|
||||||
* rather restore the lua stack at its original size, and will
|
|
||||||
* let the exception a chance to propagate
|
|
||||||
*/
|
|
||||||
static void incrementExceptionContextCounter();
|
|
||||||
static void decrementExceptionContextCounter();
|
|
||||||
|
|
||||||
private:
|
|
||||||
CLuaState *_State;
|
|
||||||
int _FinalWantedSize;
|
|
||||||
static uint _ExceptionContextCounter;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
/** Helper class to restore the lua stack to the desired size when this object goes out of scope
|
|
||||||
*/
|
|
||||||
class CLuaStackRestorer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CLuaStackRestorer(CLuaState *state, int finalSize);
|
|
||||||
~CLuaStackRestorer();
|
|
||||||
private:
|
|
||||||
int _FinalSize;
|
|
||||||
CLuaState *_State;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////
|
|
||||||
// EXCEPTIONS //
|
|
||||||
////////////////
|
|
||||||
|
|
||||||
class ELuaError : public NLMISC::Exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ELuaError() { CLuaStackChecker::incrementExceptionContextCounter(); }
|
|
||||||
virtual ~ELuaError() throw() { CLuaStackChecker::decrementExceptionContextCounter(); }
|
|
||||||
ELuaError(const std::string &reason) : Exception(reason) { CLuaStackChecker::incrementExceptionContextCounter(); }
|
|
||||||
// what(), plus append the Reason
|
|
||||||
virtual std::string luaWhat() const throw() {return NLMISC::toString("LUAError: %s", what());}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A parse error occured
|
|
||||||
class ELuaParseError : public ELuaError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ELuaParseError() {}
|
|
||||||
ELuaParseError(const std::string &reason) : ELuaError(reason) {}
|
|
||||||
virtual ~ELuaParseError() throw() { }
|
|
||||||
// what(), plus append the Reason
|
|
||||||
virtual std::string luaWhat() const throw() {return NLMISC::toString("ELuaParseError: %s", what());}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Exception thrown when something went wrong inside a wrapped function called by lua
|
|
||||||
*/
|
|
||||||
class ELuaWrappedFunctionException : public ELuaError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ELuaWrappedFunctionException(CLuaState *luaState);
|
|
||||||
ELuaWrappedFunctionException(CLuaState *luaState, const std::string &reason);
|
|
||||||
ELuaWrappedFunctionException(CLuaState *luaState, const char *format, ...);
|
|
||||||
virtual ~ELuaWrappedFunctionException() throw() { }
|
|
||||||
virtual const char *what() const throw() {return _Reason.c_str();}
|
|
||||||
protected:
|
|
||||||
void init(CLuaState *ls, const std::string &reason);
|
|
||||||
protected:
|
|
||||||
std::string _Reason;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A execution error occured
|
|
||||||
class ELuaExecuteError : public ELuaError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ELuaExecuteError() {}
|
|
||||||
ELuaExecuteError(const std::string &reason) : ELuaError(reason) {}
|
|
||||||
virtual ~ELuaExecuteError() throw() { }
|
|
||||||
// what(), plus append the Reason
|
|
||||||
virtual std::string luaWhat() const throw() {return NLMISC::toString("ELuaExecuteError: %s", what());}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A bad cast occured when using lua_checkcast
|
|
||||||
class ELuaBadCast : public ELuaError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ELuaBadCast() {}
|
|
||||||
ELuaBadCast(const std::string &reason) : ELuaError(reason) {}
|
|
||||||
// what(), plus append the Reason
|
|
||||||
virtual std::string luaWhat() const throw() {return NLMISC::toString("ELuaBadCast: %s", what());}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Error when trying to indexate an object that is not a table
|
|
||||||
class ELuaNotATable : public ELuaError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ELuaNotATable() {}
|
|
||||||
ELuaNotATable(const std::string &reason) : ELuaError(reason) {}
|
|
||||||
// what(), plus append the Reason
|
|
||||||
virtual std::string luaWhat() const throw() {return NLMISC::toString("ELuaNotATable: %s", what());}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
// a function to be used with a CLuaState instance
|
|
||||||
typedef int (* TLuaWrappedFunction) (CLuaState &ls);
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
/** C++ version of a lua state
|
|
||||||
*/
|
|
||||||
class CLuaState : public NLMISC::CRefCount
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef NLMISC::CRefPtr<CLuaState> TRefPtr;
|
|
||||||
|
|
||||||
// Create a new environement
|
|
||||||
CLuaState();
|
|
||||||
~CLuaState();
|
|
||||||
|
|
||||||
|
|
||||||
/// \name Registering
|
|
||||||
// @{
|
|
||||||
// register a wrapped function
|
|
||||||
void registerFunc(const char *name, TLuaWrappedFunction function);
|
|
||||||
// @}
|
|
||||||
|
|
||||||
|
|
||||||
/// \name Script execution
|
|
||||||
// @{
|
|
||||||
|
|
||||||
/** Parse a script and push as a function in top of the LUA stack
|
|
||||||
* \throw ELuaParseError
|
|
||||||
* \param dbgSrc is a string for debug. Should be a filename (preceded with '@'), or a short script.
|
|
||||||
*/
|
|
||||||
void loadScript(const std::string &code, const std::string &dbgSrc);
|
|
||||||
|
|
||||||
/** Execute a script from a string, possibly throwing an exception if there's a parse error
|
|
||||||
* \throw ELuaParseError, ELuaExecuteError
|
|
||||||
*/
|
|
||||||
void executeScript(const std::string &code, int numRet = 0);
|
|
||||||
|
|
||||||
/** Execute a script from a string. If an errors occurs it is printed in the log
|
|
||||||
* \return true if script execution was successful
|
|
||||||
*/
|
|
||||||
bool executeScriptNoThrow(const std::string &code, int numRet = 0);
|
|
||||||
|
|
||||||
/** Load a Script from a File (maybe in a BNP), and execute it
|
|
||||||
* \return false if file not found
|
|
||||||
* \throw ELuaParseError, ELuaExecuteError
|
|
||||||
*/
|
|
||||||
bool executeFile(const std::string &pathName);
|
|
||||||
|
|
||||||
/** execute a very Small Script (a function call for instance)
|
|
||||||
* It is different from doString() in such there is a cache (where the key is the script itself)
|
|
||||||
* so that the second time this script is executed, there is no parsing
|
|
||||||
* Note: I experienced optim with about 10 times faster than a executeScript() on a simple "a= a+1;" script
|
|
||||||
* \throw ELuaParseError, ELuaExecuteError
|
|
||||||
*/
|
|
||||||
void executeSmallScript(const std::string &script);
|
|
||||||
|
|
||||||
// @}
|
|
||||||
|
|
||||||
|
|
||||||
/// \name Stack Manipulation
|
|
||||||
// @{
|
|
||||||
// stack manipulation (indices start at 1)
|
|
||||||
void setTop(int index); // set new size of stack
|
|
||||||
void clear() { setTop(0); }
|
|
||||||
int getTop();
|
|
||||||
bool empty() { return getTop() == 0; }
|
|
||||||
void pushValue(int index); // copie nth element of stack to the top of the stack
|
|
||||||
void remove(int index); // remove nth element of stack
|
|
||||||
void insert(int index); // insert last element of the stack before the given position
|
|
||||||
void replace(int index); // replace nth element of the stack with the top of the stack
|
|
||||||
void pop(int numElem = 1); // remove n elements from the top of the stack
|
|
||||||
// test the type of an element in the stack
|
|
||||||
// return one of the following values :
|
|
||||||
// LUA_TNIL
|
|
||||||
// LUA_TNUMBER
|
|
||||||
// LUA_TBOOLEAN
|
|
||||||
// LUA_TSTRING
|
|
||||||
// LUA_TTABLE
|
|
||||||
// LUA_TFUNCTION
|
|
||||||
// LUA_TUSERDATA
|
|
||||||
// LUA_TTHREAD
|
|
||||||
// LUA_TLIGHTUSERDATA
|
|
||||||
int type(int index = -1);
|
|
||||||
const char *getTypename(int type);
|
|
||||||
bool isNil(int index = -1);
|
|
||||||
bool isBoolean(int index = -1);
|
|
||||||
bool isNumber(int index = -1);
|
|
||||||
bool isString(int index = -1);
|
|
||||||
bool isTable(int index = -1);
|
|
||||||
bool isFunction(int index = -1);
|
|
||||||
bool isCFunction(int index = -1);
|
|
||||||
bool isUserData(int index = -1);
|
|
||||||
bool isLightUserData(int index = -1);
|
|
||||||
// converting then getting a value from the stack
|
|
||||||
bool toBoolean(int index = -1);
|
|
||||||
lua_Number toNumber(int index = -1);
|
|
||||||
const char *toString(int index = -1);
|
|
||||||
void toString(int index, std::string &str); // convert to a std::string, with a NULL check.
|
|
||||||
size_t strlen(int index = -1);
|
|
||||||
lua_CFunction toCFunction(int index = -1);
|
|
||||||
void *toUserData(int index = -1);
|
|
||||||
const void *toPointer(int index = -1);
|
|
||||||
/** Helper functions : get value of the wanted type in the top table after conversion
|
|
||||||
* A default value is used if the stack entry is NULL.
|
|
||||||
* If conversion fails then an exception is thrown (with optional msg)
|
|
||||||
*/
|
|
||||||
bool getTableBooleanValue(const char *name, bool defaultValue= false);
|
|
||||||
double getTableNumberValue(const char *name, double defaultValue= 0);
|
|
||||||
const char *getTableStringValue(const char *name, const char *defaultValue= NULL);
|
|
||||||
// pushing value onto the stack
|
|
||||||
void push(bool value);
|
|
||||||
void push(lua_Number value);
|
|
||||||
void push(const char *str);
|
|
||||||
void push(const char *str, int length);
|
|
||||||
void push(const std::string &str);
|
|
||||||
void pushNil();
|
|
||||||
void push(lua_CFunction f);
|
|
||||||
void push(TLuaWrappedFunction function);
|
|
||||||
void pushLightUserData(void *); // push a light user data (use newUserData to push a full userdata)
|
|
||||||
// metatables
|
|
||||||
bool getMetaTable(int index = -1);
|
|
||||||
bool setMetaTable(int index = -1); // set the metatable at top of stack to the object at 'index' (usually -2), then pop the metatable
|
|
||||||
// even if asignment failed
|
|
||||||
// comparison
|
|
||||||
bool equal(int index1, int index2);
|
|
||||||
bool rawEqual(int index1, int index2);
|
|
||||||
bool lessThan(int index1, int index2);
|
|
||||||
// concatenation of the n element at the top of the stack (using lua semantic)
|
|
||||||
void concat(int numElem);
|
|
||||||
// tables
|
|
||||||
void newTable(); // create a new table at top of the stack
|
|
||||||
void getTable(int index); // get value from a table at index 'index' (key is at top)
|
|
||||||
void rawGet(int index);
|
|
||||||
void setTable(int index); // set (key, value) from top of the stack into the given table
|
|
||||||
// both key and value are poped
|
|
||||||
void rawSet(int index);
|
|
||||||
bool next(int index); // table traversal
|
|
||||||
// UserData
|
|
||||||
void *newUserData(uint size);
|
|
||||||
// seting value by int index in a table
|
|
||||||
void rawSetI(int index, int n);
|
|
||||||
void rawGetI(int index, int n);
|
|
||||||
/** Calling functions (it's up to the caller to clear the results)
|
|
||||||
* The function should have been pushed on the stack
|
|
||||||
*/
|
|
||||||
void call(int nargs, int nresults);
|
|
||||||
int pcall(int nargs, int nresults, int errfunc = 0);
|
|
||||||
/** Helper : Execute a function by name. Lookup for the function is done in the table at the index 'funcTableIndex'
|
|
||||||
* the behaviour is the same than with call of pcall.
|
|
||||||
*/
|
|
||||||
int pcallByName(const char *functionName, int nargs, int nresults, int funcTableIndex = LUA_GLOBALSINDEX, int errfunc = 0);
|
|
||||||
|
|
||||||
// push a C closure (pop n element from the stack and associate with the function)
|
|
||||||
void pushCClosure(lua_CFunction function, int n);
|
|
||||||
// @}
|
|
||||||
|
|
||||||
|
|
||||||
/// \name Misc
|
|
||||||
// @{
|
|
||||||
/** Retrieve pointer to a CLuaState environment from its lua_State pointer, or NULL
|
|
||||||
* if there no such environment
|
|
||||||
*/
|
|
||||||
static CLuaState *fromStatePointer(lua_State *state);
|
|
||||||
// Get state pointer. The state should not be closed (this object has ownership)
|
|
||||||
lua_State *getStatePointer() const {return _State;}
|
|
||||||
// check that an index is valid when accessing the stack
|
|
||||||
// an assertion is raised if the index is not valid
|
|
||||||
void checkIndex(int index);
|
|
||||||
|
|
||||||
// registering C function to use with a lua state pointer
|
|
||||||
void registerFunc(const char *name, lua_CFunction function);
|
|
||||||
|
|
||||||
// Garbage collector
|
|
||||||
int getGCCount(); // get memory in use in KB
|
|
||||||
int getGCThreshold(); // get max memory in KB
|
|
||||||
void setGCThreshold(int kb); // set max memory in KB (no-op with ref-counted version)
|
|
||||||
|
|
||||||
// handle garbage collector for ref-counted version of lua (no-op with standard version, in which case gc handling is automatic)
|
|
||||||
void handleGC();
|
|
||||||
|
|
||||||
/** For Debug: get the Stack context of execution (filename / line)
|
|
||||||
* \param stackLevel: get the context of execution of the given stackLevel.
|
|
||||||
* 0 for the current function
|
|
||||||
* 1 for the function that called 0
|
|
||||||
* 2 ....
|
|
||||||
* NB: if called from a C function called from LUA, remember that stackLevel 0 is the current function.
|
|
||||||
* Hence if you want to know what LUA context called you, pass stackLevel=1!
|
|
||||||
* \param ret string cleared if any error, else filled with formated FileName / LineNumber
|
|
||||||
*/
|
|
||||||
void getStackContext(std::string &ret, uint stackLevel);
|
|
||||||
// @}
|
|
||||||
|
|
||||||
// for debug : dump the current content of the stack (no recursion)
|
|
||||||
void dumpStack();
|
|
||||||
static void dumpStack(lua_State *ls);
|
|
||||||
void getStackAsString(std::string &dest);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
lua_State *_State;
|
|
||||||
|
|
||||||
#ifdef LUA_NEVRAX_VERSION
|
|
||||||
int _GCThreshold; // if refcounted gc is used, then garbage collector is handled manually
|
|
||||||
#endif
|
|
||||||
// Small Script Cache
|
|
||||||
uint _SmallScriptPool;
|
|
||||||
typedef std::map<std::string, uint> TSmallScriptCache;
|
|
||||||
TSmallScriptCache _SmallScriptCache;
|
|
||||||
static const char * _NELSmallScriptTableName;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// this object isn't intended to be copied
|
|
||||||
CLuaState(const CLuaState &/* other */):NLMISC::CRefCount() { nlassert(0); }
|
|
||||||
CLuaState &operator=(const CLuaState &/* other */) { nlassert(0); return *this; }
|
|
||||||
|
|
||||||
void executeScriptInternal(const std::string &code, const std::string &dbgSrc, int numRet = 0);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Access to lua function
|
|
||||||
// one should not include lua.h directly because if a debugger is present, lua
|
|
||||||
// function pointer will be taken from a dynamic library.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================================
|
|
||||||
// include implementation
|
|
||||||
#define RZ_INCLUDE_LUA_HELPER_INLINE
|
|
||||||
#include "lua_helper_inline.h"
|
|
||||||
#undef RZ_INCLUDE_LUA_HELPER_INLINE
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
|
|
||||||
#include "stdpch.h"
|
#include "stdpch.h"
|
||||||
#include "lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
#define NL_LUA_IHM_H
|
#define NL_LUA_IHM_H
|
||||||
|
|
||||||
#include "nel/misc/types_nl.h"
|
#include "nel/misc/types_nl.h"
|
||||||
#include "lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
|
|
||||||
|
|
||||||
namespace NLMISC
|
namespace NLMISC
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
#include "stdpch.h"
|
#include "stdpch.h"
|
||||||
#include "lua_object.h"
|
#include "lua_object.h"
|
||||||
#include "lua_ihm.h"
|
#include "lua_ihm.h"
|
||||||
#include "lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
//
|
//
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
#include "nel/misc/smart_ptr.h"
|
#include "nel/misc/smart_ptr.h"
|
||||||
#include "nel/misc/rgba.h"
|
#include "nel/misc/rgba.h"
|
||||||
//
|
//
|
||||||
#include "lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,10 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class CReflectable;
|
class CReflectable;
|
||||||
class CLuaState;
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
class CLuaState;
|
||||||
|
}
|
||||||
struct CClassInfo;
|
struct CClassInfo;
|
||||||
|
|
||||||
/** A property of a reflectable object
|
/** A property of a reflectable object
|
||||||
|
|
|
@ -48,7 +48,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
#include "../../interface_v3/lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
#include "../../interface_v3/lua_ihm.h"
|
#include "../../interface_v3/lua_ihm.h"
|
||||||
|
|
||||||
#include "../../entities.h"
|
#include "../../entities.h"
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "../../interface_v3/lua_loadlib.h"
|
#include "nel/gui/lua_loadlib.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "../../interface_v3/lua_loadlib.h"
|
#include "nel/gui/lua_loadlib.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,8 @@
|
||||||
|
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
//
|
//
|
||||||
#include "../interface_v3/lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
#include "../interface_v3/group_tree.h"
|
#include "../interface_v3/group_tree.h"
|
||||||
#include "../interface_v3/interface_manager.h"
|
#include "../interface_v3/interface_manager.h"
|
||||||
#include "../contextual_cursor.h"
|
#include "../contextual_cursor.h"
|
||||||
|
|
|
@ -27,7 +27,10 @@
|
||||||
#include "lua_event_forwarder.h"
|
#include "lua_event_forwarder.h"
|
||||||
|
|
||||||
class CEntityCL;
|
class CEntityCL;
|
||||||
|
namespace NLGUI
|
||||||
|
{
|
||||||
class CLuaState;
|
class CLuaState;
|
||||||
|
}
|
||||||
|
|
||||||
namespace R2
|
namespace R2
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,10 @@
|
||||||
#ifndef R2_LUA_EVENT_FORWARDER_H
|
#ifndef R2_LUA_EVENT_FORWARDER_H
|
||||||
#define R2_LUA_EVENT_FORWARDER_H
|
#define R2_LUA_EVENT_FORWARDER_H
|
||||||
|
|
||||||
class CLuaState;
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
class CLuaState;
|
||||||
|
}
|
||||||
class CLuaString;
|
class CLuaString;
|
||||||
|
|
||||||
namespace R2
|
namespace R2
|
||||||
|
@ -53,7 +56,7 @@ public:
|
||||||
const std::string &targetAttrName, sint32 targetAttrIndex);
|
const std::string &targetAttrName, sint32 targetAttrIndex);
|
||||||
protected:
|
protected:
|
||||||
// for derivers
|
// for derivers
|
||||||
virtual CLuaState *getLua() = 0;
|
virtual NLGUI::CLuaState *getLua() = 0;
|
||||||
virtual void executeHandler(const CLuaString &eventName, int numArgs) = 0;
|
virtual void executeHandler(const CLuaString &eventName, int numArgs) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
|
|
||||||
#include "session_browser.h"
|
#include "session_browser.h"
|
||||||
#include "game_share/ring_session_manager_itf.h"
|
#include "game_share/ring_session_manager_itf.h"
|
||||||
#include "interface_v3/lua_helper.h"
|
#include "nel/gui/lua_helper.h"
|
||||||
|
using namespace NLGUI;
|
||||||
#include "far_tp.h"
|
#include "far_tp.h"
|
||||||
|
|
||||||
class CSessionBrowserImpl : public CSessionBrowser,
|
class CSessionBrowserImpl : public CSessionBrowser,
|
||||||
|
|
Loading…
Reference in a new issue