7 #ifndef CAFU_UNI_SCRIPT_STATE_HPP_INCLUDED
8 #define CAFU_UNI_SCRIPT_STATE_HPP_INCLUDED
10 #include "Templates/Array.hpp"
11 #include "Templates/Pointer.hpp"
12 #include "TypeSys.hpp"
33 : m_LuaState(LuaState),
34 m_StartTop(lua_gettop(m_LuaState) + Change)
40 assert(m_StartTop == lua_gettop(m_LuaState));
46 lua_State* m_LuaState;
99 template<
class T>
bool Push(T Object);
126 template<
class T>
class TraitsT
130 static T* GetIdentity(T& Object) {
return &Object; }
133 static bool IsRefCounted() {
return false; }
137 template<
class T>
class TraitsT< IntrusivePtrT<T> >
144 static bool IsRefCounted() {
return true; }
172 void Anchor(
int StackIndex);
192 int abs_index(
int i)
const
194 return (i > 0 || i <= LUA_REGISTRYINDEX) ? i : lua_gettop(m_LuaState) + i + 1;
198 template<
class T>
static int GetRefCount(lua_State* LuaState);
201 template<
class T>
static int Destruct(lua_State* LuaState);
203 lua_State* m_LuaState;
226 bool DoString(
const char* s,
const char* Signature =
"", ...);
229 bool DoFile(
const char* FileName,
const char* Signature =
"", ...);
246 bool Call(
const char* FuncName,
const char* Signature=
"", ...);
260 template<
class T>
bool CallMethod(T Object,
const std::string& MethodName,
const char* Signature=
"", ...);
266 template<
class T>
bool CallMethod_Impl(T Object,
const std::string& MethodName,
int NumExtraArgs,
const char* Signature, va_list vl);
285 unsigned int NumParams;
291 static unsigned int InstCount;
298 bool StartNewCoroutine(
int NumExtraArgs,
const char* Signature, va_list vl,
const std::string& DbgName);
301 static int RegisterThread(lua_State* LuaState);
304 static void CheckCallbackDoc(
const cf::TypeSys::TypeInfoT* TI,
const std::string& MethodName,
int NumExtraArgs,
const char* Signature);
306 lua_State* m_LuaState;
308 unsigned int m_CheckCppRefsCount;
313 template<
class T>
int cf::ScriptBinderT::GetRefCount(lua_State* LuaState)
317 lua_getfield(LuaState, -1,
"__userdata_cf");
320 T* UserData=(T*)lua_touserdata(LuaState, -1);
323 lua_pushinteger(LuaState, UserData ? (*UserData)->GetRefCount() : 0);
328 template<
class T>
int cf::ScriptBinderT::Destruct(lua_State* LuaState)
330 T* UserData=(T*)lua_touserdata(LuaState, 1);
347 lua_getfield(m_LuaState, LUA_REGISTRYINDEX,
"__identity_to_object");
351 lua_pushlightuserdata(m_LuaState, TraitsT<T>::GetIdentity(Object));
352 lua_rawget(m_LuaState, -2);
355 if (lua_isnil(m_LuaState, -1))
358 lua_pop(m_LuaState, 1);
361 const int USERDATA_INDEX=lua_gettop(m_LuaState) + 2;
362 const int TABLE_INDEX =lua_gettop(m_LuaState) + 1;
365 lua_newtable(m_LuaState);
368 new (lua_newuserdata(m_LuaState,
sizeof(T))) T(Object);
371 lua_pushvalue(m_LuaState, USERDATA_INDEX);
372 lua_setfield(m_LuaState, TABLE_INDEX,
"__userdata_cf");
378 luaL_getmetatable(m_LuaState, TraitsT<T>::GetTypeInfo(Object).ClassName);
379 assert(lua_istable(m_LuaState, -1));
380 lua_getfield(m_LuaState, -1,
"__gc");
381 if (lua_isnil(m_LuaState, -1))
383 lua_pushcfunction(m_LuaState, Destruct<T>);
384 lua_setfield(m_LuaState, -3,
"__gc");
386 lua_pop(m_LuaState, 2);
391 luaL_getmetatable(m_LuaState, TraitsT<T>::GetTypeInfo(Object).ClassName);
392 assert(lua_istable(m_LuaState, -1));
393 lua_setmetatable(m_LuaState, TABLE_INDEX);
400 luaL_getmetatable(m_LuaState, TraitsT<T>::GetTypeInfo(Object).ClassName);
401 assert(lua_istable(m_LuaState, -1));
402 lua_setmetatable(m_LuaState, USERDATA_INDEX);
406 if (TraitsT<T>::IsRefCounted())
413 luaL_getmetatable(m_LuaState, TI->
ClassName);
414 lua_getfield(m_LuaState, -1,
"__index");
415 lua_getfield(m_LuaState, -1,
"GetRefCount");
416 if (lua_isnil(m_LuaState, -1))
418 lua_pushcfunction(m_LuaState, GetRefCount<T>);
419 lua_setfield(m_LuaState, -3,
"GetRefCount");
421 lua_pop(m_LuaState, 3);
425 lua_pop(m_LuaState, 1);
428 lua_pushlightuserdata(m_LuaState, TraitsT<T>::GetIdentity(Object));
429 lua_pushvalue(m_LuaState, TABLE_INDEX);
430 lua_rawset(m_LuaState, -4);
440 lua_remove(m_LuaState, -2);
454 StackIndex = abs_index(StackIndex);
457 luaL_argcheck(m_LuaState, lua_istable(m_LuaState, StackIndex), StackIndex,
"Expected a table that represents an object." );
460 lua_getfield(m_LuaState, StackIndex,
"__userdata_cf");
467 luaL_getmetatable(m_LuaState, TraitsT<T>::GetTypeInfo().ClassName);
470 if (!lua_getmetatable(m_LuaState, -2)) lua_pushnil(m_LuaState);
472 while (lua_istable(m_LuaState, -1))
474 if (lua_rawequal(m_LuaState, -1, -2))
476 T* UserData=(T*)lua_touserdata(m_LuaState, -3);
479 luaL_error(m_LuaState,
"NULL userdata in object table.");
482 lua_pop(m_LuaState, 3);
492 lua_getfield(m_LuaState, -1,
"__index");
493 if (!lua_getmetatable(m_LuaState, -1)) lua_pushnil(m_LuaState);
494 lua_remove(m_LuaState, -2);
495 lua_remove(m_LuaState, -2);
499 luaL_argerror(m_LuaState, StackIndex, lua_pushfstring(m_LuaState,
"%s expected, got %s", TraitsT<T>::GetTypeInfo().ClassName, luaL_typename(m_LuaState, StackIndex)));
501 static T* Invalid = NULL;
505 T* UserData=(T*)luaL_checkudata(m_LuaState, -1, TraitsT<T>::GetTypeInfo().ClassName);
508 luaL_error(m_LuaState,
"NULL userdata in object table.");
521 va_start(vl, Signature);
522 const bool Result=CallMethod_Impl(Object, MethodName, 0, Signature, vl);
535 CheckCallbackDoc(Object->GetType(), MethodName, NumExtraArgs, Signature);
542 lua_getfield(m_LuaState, -1, MethodName.c_str());
544 if (!lua_isfunction(m_LuaState, -1))
549 lua_pop(m_LuaState, 2 + NumExtraArgs);
556 lua_insert(m_LuaState, -2 - NumExtraArgs);
557 lua_insert(m_LuaState, -1 - NumExtraArgs);
560 return StartNewCoroutine(1 + NumExtraArgs, Signature, vl, std::string(
"method ") + MethodName +
"()");
bool IsBound(void *Identity)
Returns if the object with the given identity is currently bound to the Lua state, i.e.
Definition: UniScriptState.cpp:214
void RunPendingCoroutines(float FrameTime)
Runs the pending coroutines.
Definition: UniScriptState.cpp:458
UniScriptStateT()
The constructor.
Definition: UniScriptState.cpp:312
This class implements smart (reference-counted) pointers.
Definition: Pointer.hpp:43
void Init(const cf::TypeSys::TypeInfoManT &TIM)
This method registers all C++ classes known to the TIM in the related Lua state.
Definition: UniScriptState.cpp:158
bool CallMethod(T Object, const std::string &MethodName, const char *Signature="",...)
Calls a method with the given name of the given object.
Definition: UniScriptState.hpp:517
bool DoString(const char *s, const char *Signature="",...)
Loads the given string as a Lua chunk, then runs it.
Definition: UniScriptState.cpp:379
ScriptBinderT(lua_State *LuaState)
The constructor.
Definition: UniScriptState.cpp:28
lua_State * GetLuaState()
Returns the Lua state that implements this script state.
Definition: UniScriptState.hpp:272
T & GetCheckedObjectParam(int StackIndex)
Checks if the value at the given stack index is a Lua object of type T::TypeInfo, or a subclass deriv...
Definition: UniScriptState.hpp:447
This class manages the type infos.
Definition: TypeSys.hpp:145
~UniScriptStateT()
The destructor.
Definition: UniScriptState.cpp:362
This class checks if the Lua stack has the same size at the start and the end of a function...
Definition: UniScriptState.hpp:28
T * get() const
Returns the stored pointer.
Definition: Pointer.hpp:99
This class implements and encapsulates the strategy with which we bind C++ objects to Lua...
Definition: UniScriptState.hpp:82
bool Push(T Object)
Pushes the given C++ object onto the stack.
Definition: UniScriptState.hpp:342
bool DoFile(const char *FileName, const char *Signature="",...)
Loads the given file as a Lua chunk, then runs it.
Definition: UniScriptState.cpp:403
void Disconnect(void *Identity)
Breaks the connection between a C++ object and its alter ego in Lua.
Definition: UniScriptState.cpp:237
const char * ClassName
The name of this class.
Definition: TypeSys.hpp:109
bool CallMethod_Impl(T Object, const std::string &MethodName, int NumExtraArgs, const char *Signature, va_list vl)
Like CallMethod() above, but the arguments and results are passed via vl rather than "...
Definition: UniScriptState.hpp:529
This class represents the state of a script: the underlying Lua state, pending coroutines, metatables for C++ class hierarchies, etc.
Definition: UniScriptState.hpp:214
This class keeps type information (about an entity class that occurs in the game).
Definition: TypeSys.hpp:79
const TypeInfoT * Base
The type info for the base class.
Definition: TypeSys.hpp:114
bool Call(const char *FuncName, const char *Signature="",...)
Calls the global script function with the given name.
Definition: UniScriptState.cpp:429