Lua_icxx
1.02 (Aug 2011)
|
00001 /* 00002 This file is part of the Lua_icxx library. 00003 Copyright 2010 (c) by Oliver Schoenborn. 00004 License terms in LICENSE.txt. 00005 */ 00006 00007 00008 #pragma once 00009 00010 #ifndef LUA_ICXX_FUNCREF_INCLUDED 00011 #define LUA_ICXX_FUNCREF_INCLUDED 00012 00013 00014 #include "LuaObjRef.h" 00015 #include "LuaAdapters.h" 00016 #include "luaFuncCalls.h" 00017 00018 00019 class LuaFuncCallParams; 00020 class LuaTableRef; 00021 00022 00029 class LUA_ICXX_CPP_API 00030 LuaFuncRef: public LuaObjRef 00031 { 00032 public: 00034 explicit LuaFuncRef( const std::string& id = "nil" ): LuaObjRef(id) {} 00035 00037 00038 LuaFuncRef( const LuaTempResult& res): LuaObjRef(res) {} 00039 LuaFuncRef( const LuaTempResult::Item& item): LuaObjRef(item) {} 00040 LuaFuncRef( lua_State* lua, int stackPos ): LuaObjRef(lua, stackPos) {} 00042 00044 bool setEnv(const LuaTableRef&); 00048 LuaTempResult getEnv() const; 00049 00051 00052 DECL_FN_CALLS(operator()); 00053 DECL_FN_CALLS(call); 00055 00056 private: 00057 inline LuaFuncCallParams prepCall() const; 00058 }; 00059 00060 00070 class LUA_ICXX_CPP_API 00071 LuaBoundMethRef 00072 { 00073 public: 00075 LuaBoundMethRef() {} // nil 00077 LuaBoundMethRef( const LuaObjRef & obj, const LuaFuncRef & fn ) 00078 : mMethRef( fn ), mObjRef(obj) {} 00080 LuaBoundMethRef( const LuaTempResult & res ) 00081 : mObjRef( res[1] ), mMethRef( res[2] ) {} 00082 00084 00085 void resetRef( const LuaObjRef & obj, const LuaFuncRef & fn ); 00086 void resetRef( const LuaTempResult& result ) { resetRef(result[1], result[2]); } 00087 LuaBoundMethRef& operator=(const LuaTempResult& result ) { resetRef(result); return *this;} 00089 00091 bool isNil() const { return mObjRef.isNil() || mMethRef.isNil(); } 00093 std::string typeName() const { return isNil() ? "nil" : "boundmethod"; } 00095 std::string getID() const { return mObjRef.getID() + ":" + mMethRef.getID(); } 00096 00098 00099 00100 DECL_FN_CALLS(operator()); 00101 DECL_FN_CALLS(call); 00103 00104 private: 00105 LuaObjRef mObjRef; 00106 LuaFuncRef mMethRef; 00107 }; 00108 00109 00117 class LUA_ICXX_CPP_API 00118 LuaClassObjRef: public LuaObjRef 00119 { 00120 public: 00122 explicit LuaClassObjRef( const std::string& id = "nil" ): LuaObjRef(id) {} 00124 00125 LuaClassObjRef( const LuaTempResult& res): LuaObjRef(res) {} 00126 LuaClassObjRef( const LuaTempResult::Item& item): LuaObjRef(item) {} 00127 LuaClassObjRef( lua_State* lua, int stackPos ): LuaObjRef(lua, stackPos) {} 00129 00131 LuaBoundMethRef getBoundMethod(const std::string&) const; 00132 00134 00135 00136 DECL_FN_CALLS(callMethod); 00138 00139 private: 00140 inline LuaFuncCallParams prepCall(const std::string&) const; 00141 }; 00142 00143 00144 // ---------------------------------------------------------------------- 00145 00162 template <typename TT> 00163 struct NotAllowedAsFunctionArgument 00164 { 00166 static inline const TT& ref(const TT& obj) { return obj; } 00167 }; 00168 00170 template <> 00171 struct NotAllowedAsFunctionArgument<LuaTempResult>; 00172 00174 template <> 00175 struct NotAllowedAsFunctionArgument<LuaTempResult::Item>; 00176 00177 00178 /* Puts the function call parameters on the Lua stack, makes the call, and 00179 encapsulates the return values in a LuaTempResult. 00180 */ 00181 class LUA_ICXX_CPP_API 00182 LuaFuncCallParams 00183 { 00184 public: 00185 LuaFuncCallParams(const std::string& funcID, lua_State* lua, int currStackTop, 00186 int alreadyOnStack = 0) 00187 : mFuncID(funcID.empty() ? "<anonymous>" : funcID), mLua(lua), 00188 preStackTop(currStackTop), argsOnStack(alreadyOnStack) {} 00189 00190 public: 00191 template <typename TT> 00192 inline LuaFuncCallParams& operator<<(const TT& obj) 00193 { 00194 pushValToStack(mLua, NotAllowedAsFunctionArgument<TT>::ref(obj)); 00195 argsOnStack ++; 00196 return *this; 00197 } 00198 00199 LuaTempResult doCall() const 00200 { 00201 assert(mLua); 00202 const int numRets = LUA_MULTRET; 00203 const int errCode = lua_pcall(mLua, argsOnStack, numRets, 0); 00204 return LuaTempResult(mLua, preStackTop, errCode, "Function call " + mFuncID + "()"); 00205 } 00206 00207 // doesn't work: 00208 //operator LuaTempResult() const 00209 00210 private: 00211 lua_State * mLua; 00212 std::string mFuncID; 00213 const int preStackTop; 00214 int argsOnStack; 00215 }; 00216 00217 00218 inline LuaFuncCallParams 00219 LuaFuncRef::prepCall() 00220 const 00221 { 00222 const int curStackTop = (mLua ? lua_gettop(mLua) : 0); 00223 pushObj(); 00224 return LuaFuncCallParams(getID(), mLua, curStackTop); 00225 } 00226 00227 00228 inline LuaFuncCallParams 00229 LuaClassObjRef::prepCall(const std::string& methName) 00230 const 00231 { 00232 const int curStackTop = (mLua ? lua_gettop(mLua) : 0); 00233 // get method of object: 00234 pushObj(); 00235 lua_getfield(mLua, -1, methName.c_str()); 00236 // move method before object since object must be first arg to function call: 00237 lua_insert(mLua, -2); 00238 assert( lua_gettop(mLua) == curStackTop + 2 ); 00239 return LuaFuncCallParams(getID(), mLua, curStackTop, 1); 00240 } 00241 00242 00243 // ----------- LuaFuncRef::call(...) and operator()(...) for 0 to 9 args of any type ------------------------ 00244 00245 DEF_FN_CALL_0(LuaFuncRef::call, prepCall().doCall() ); 00246 DEF_FN_CALL_1(LuaFuncRef::call, ( prepCall() << arg1 ).doCall() ); 00247 DEF_FN_CALL_2(LuaFuncRef::call, ( prepCall() << arg1 << arg2 ).doCall() ); 00248 DEF_FN_CALL_3(LuaFuncRef::call, ( prepCall() << arg1 << arg2 << arg3 ).doCall() ); 00249 DEF_FN_CALL_4(LuaFuncRef::call, ( prepCall() << arg1 << arg2 << arg3 << arg4 ).doCall() ); 00250 DEF_FN_CALL_5(LuaFuncRef::call, ( prepCall() << arg1 << arg2 << arg3 << arg4 << arg5 ).doCall() ); 00251 DEF_FN_CALL_6(LuaFuncRef::call, ( prepCall() << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 ).doCall() ); 00252 DEF_FN_CALL_7(LuaFuncRef::call, ( prepCall() << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 ).doCall() ); 00253 DEF_FN_CALL_8(LuaFuncRef::call, ( prepCall() << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 ).doCall() ); 00254 DEF_FN_CALL_9(LuaFuncRef::call, ( prepCall() << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 ).doCall() ); 00255 00256 DEF_FN_CALL_0(LuaFuncRef::operator(), call() ); 00257 DEF_FN_CALL_1(LuaFuncRef::operator(), call(arg1) ); 00258 DEF_FN_CALL_2(LuaFuncRef::operator(), call(arg1, arg2 ) ); 00259 DEF_FN_CALL_3(LuaFuncRef::operator(), call(arg1, arg2, arg3 ) ); 00260 DEF_FN_CALL_4(LuaFuncRef::operator(), call(arg1, arg2, arg3, arg4 ) ); 00261 DEF_FN_CALL_5(LuaFuncRef::operator(), call(arg1, arg2, arg3, arg4, arg5 ) ); 00262 DEF_FN_CALL_6(LuaFuncRef::operator(), call(arg1, arg2, arg3, arg4, arg5, arg6 ) ); 00263 DEF_FN_CALL_7(LuaFuncRef::operator(), call(arg1, arg2, arg3, arg4, arg5, arg6, arg7 ) ); 00264 DEF_FN_CALL_8(LuaFuncRef::operator(), call(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ) ); 00265 DEF_FN_CALL_9(LuaFuncRef::operator(), call(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ) ); 00266 00267 00268 // same for LuaBoundMethRef: 00269 00270 DEF_FN_CALL_0(LuaBoundMethRef::call, mMethRef(mObjRef) ); 00271 DEF_FN_CALL_1(LuaBoundMethRef::call, mMethRef(mObjRef, arg1) ); 00272 DEF_FN_CALL_2(LuaBoundMethRef::call, mMethRef(mObjRef, arg1, arg2) ); 00273 DEF_FN_CALL_3(LuaBoundMethRef::call, mMethRef(mObjRef, arg1, arg2, arg3) ); 00274 DEF_FN_CALL_4(LuaBoundMethRef::call, mMethRef(mObjRef, arg1, arg2, arg3, arg4) ); 00275 DEF_FN_CALL_5(LuaBoundMethRef::call, mMethRef(mObjRef, arg1, arg2, arg3, arg4, arg5) ); 00276 DEF_FN_CALL_6(LuaBoundMethRef::call, mMethRef(mObjRef, arg1, arg2, arg3, arg4, arg5, arg6) ); 00277 DEF_FN_CALL_7(LuaBoundMethRef::call, mMethRef(mObjRef, arg1, arg2, arg3, arg4, arg5, arg6, arg7) ); 00278 DEF_FN_CALL_8(LuaBoundMethRef::call, mMethRef(mObjRef, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) ); 00279 DEF_FN_CALL_9(LuaBoundMethRef::call, mMethRef(mObjRef, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) ); 00280 00281 DEF_FN_CALL_0(LuaBoundMethRef::operator(), call() ); 00282 DEF_FN_CALL_1(LuaBoundMethRef::operator(), call( arg1) ); 00283 DEF_FN_CALL_2(LuaBoundMethRef::operator(), call( arg1, arg2) ); 00284 DEF_FN_CALL_3(LuaBoundMethRef::operator(), call( arg1, arg2, arg3) ); 00285 DEF_FN_CALL_4(LuaBoundMethRef::operator(), call( arg1, arg2, arg3, arg4) ); 00286 DEF_FN_CALL_5(LuaBoundMethRef::operator(), call( arg1, arg2, arg3, arg4, arg5) ); 00287 DEF_FN_CALL_6(LuaBoundMethRef::operator(), call( arg1, arg2, arg3, arg4, arg5, arg6) ); 00288 DEF_FN_CALL_7(LuaBoundMethRef::operator(), call( arg1, arg2, arg3, arg4, arg5, arg6, arg7) ); 00289 DEF_FN_CALL_8(LuaBoundMethRef::operator(), call( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) ); 00290 DEF_FN_CALL_9(LuaBoundMethRef::operator(), call( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) ); 00291 00292 00293 // for LuaClassObjRef: 00294 00295 DEF_FN_CALL_1(LuaClassObjRef::callMethod, prepCall(arg1).doCall() ); 00296 DEF_FN_CALL_2(LuaClassObjRef::callMethod, ( prepCall(arg1) << arg2 ).doCall() ); 00297 DEF_FN_CALL_3(LuaClassObjRef::callMethod, ( prepCall(arg1) << arg2 << arg3 ).doCall() ); 00298 DEF_FN_CALL_4(LuaClassObjRef::callMethod, ( prepCall(arg1) << arg2 << arg3 << arg4 ).doCall() ); 00299 DEF_FN_CALL_5(LuaClassObjRef::callMethod, ( prepCall(arg1) << arg2 << arg3 << arg4 << arg5 ).doCall() ); 00300 DEF_FN_CALL_6(LuaClassObjRef::callMethod, ( prepCall(arg1) << arg2 << arg3 << arg4 << arg5 << arg6 ).doCall() ); 00301 DEF_FN_CALL_7(LuaClassObjRef::callMethod, ( prepCall(arg1) << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 ).doCall() ); 00302 DEF_FN_CALL_8(LuaClassObjRef::callMethod, ( prepCall(arg1) << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 ).doCall() ); 00303 DEF_FN_CALL_9(LuaClassObjRef::callMethod, ( prepCall(arg1) << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 ).doCall() ); 00304 00305 00306 #endif // LUA_ICXX_FUNCREF_INCLUDED