lugre_luabind.h

Go to the documentation of this file.
00001 /*
00002 http://www.opensource.org/licenses/mit-license.php  (MIT-License)
00003 
00004 Copyright (c) 2007 Lugre-Team
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a copy
00007 of this software and associated documentation files (the "Software"), to deal
00008 in the Software without restriction, including without limitation the rights
00009 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, subject to the following conditions:
00012 
00013 The above copyright notice and this permission notice shall be included in
00014 all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00019 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00020 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00021 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00022 THE SOFTWARE.
00023 */
00024 #ifndef LUGRE_LUABIND_H
00025 #define LUGRE_LUABIND_H
00026 
00027 #include <map>
00028 #include <vector>
00029 #include "lugre_gfx3D.h"
00030 #include "lugre_gfx2D.h"
00031 #include "lugre_smartptr.h"
00032 #include "lugre_robstring.h"
00033 #include <OgreVector3.h>
00034 #include <OgreVector2.h>
00035 #include <OgreQuaternion.h>
00036 #include <OgreColourValue.h>
00037 
00038 extern "C" {
00039     #include "lua.h"
00040     #include "lauxlib.h"
00041     #include "lualib.h"
00042 }
00043 
00044 namespace Lugre {
00045 
00046 #define luaL_checkbool(L,i) (lua_isboolean(L,i) ? lua_toboolean(L,i) : luaL_checkint(L,i))
00047 
00048 // from scripting.cpp
00049 int     PCallWithErrFuncWrapper     (lua_State *L,int narg, int nret);
00050 void    LuaErrorHandler             (lua_State *L, const char *fmt, ...);
00051 struct  luaL_reg make_luaL_reg      (const char *name,lua_CFunction func);
00052 
00053 // WARNING : this whole cLuaBind thing is very hacky, but it is kinda useful ;)
00054 
00055 #define cMemberVar_REGISTER(prototype,vartype,name,flags) mlMemberVar[#name] = new cMemberVar(vartype,((char*)&prototype->name) - ((char*)prototype),flags)
00056 template<class _T> class cLuaBind { public:
00058     struct udata { cSmartPtr<_T>* pSmartPtr; };
00059     
00060     // miType for mlMemberVar
00061     enum {
00062         kVarType_int,
00063         kVarType_size_t,
00064         kVarType_bool,
00065         kVarType_Float,
00066         kVarType_Real,
00067         kVarType_Vector2,
00068         kVarType_Vector3,
00069         kVarType_Colour,
00070         kVarType_Quaternion,
00071         kVarType_String,
00072         kVarType_Gfx3D,
00073         kVarType_Gfx2D,
00074         kVarType_ObjSmartPtr,   // set takes udata, but get returns objID, // TODO : FIX to return udata ? or set to also take objID ?
00075     };
00076     // miFlags for mlMemberVar
00077     enum {
00078         kVarFlag_Readonly       = (1<<0),
00079         kVarFlag_NotifyChange   = (1<<1),
00080     };
00081 
00082     class cMemberVar { public:
00083         size_t  miType;
00084         size_t  miOffset;
00085         size_t  miFlags;
00086         cMemberVar(size_t iType,size_t iOffset,size_t iFlags) : miType(iType), miOffset(iOffset), miFlags(iFlags) { PROFILE}
00087     };
00088 
00089     // WARNING : small memory leak : cMemberVar pointers are never released, but will be a permanent global anyhow...
00090     std::map<std::string,cMemberVar*>   mlMemberVar;
00091     std::vector<struct luaL_reg>        mlMethod;
00092     std::string                         msError_X_expected;
00093     std::string                         msError_dead_X_ptr;
00094     const char*                         mszError_X_expected;
00095     const char*                         mszError_dead_X_ptr;
00096 
00097     static cLuaBind<_T>*     GetSingletonPtr    (cLuaBind<_T>* prototype=0) { PROFILE
00098         static cLuaBind<_T>* pSingleton = 0;
00099         if (pSingleton) return pSingleton;      
00100         pSingleton = prototype;
00101         assert(pSingleton);
00102         pSingleton->msError_X_expected = strprintf("`%s' expected",pSingleton->GetLuaTypeName());
00103         pSingleton->msError_dead_X_ptr = strprintf("dead `%s' pointer",pSingleton->GetLuaTypeName());
00104         pSingleton->mszError_X_expected = pSingleton->msError_X_expected.c_str();
00105         pSingleton->mszError_dead_X_ptr = pSingleton->msError_dead_X_ptr.c_str();
00106         return pSingleton;
00107     }
00108 
00109     // set to a unique name for this class, like "iris.obj"
00110     virtual const char* GetLuaTypeName () = 0;
00111 
00113 
00114         void    LuaRegister  (lua_State *L) { PROFILE
00115             mlMethod.clear(); // avoid doubling when preparing multithreading / multiple lua states
00116             
00117             // do it just like that in RegisterMethods()
00118             mlMethod.push_back(make_luaL_reg("Get",     cLuaBind<_T>::l_Get));
00119             mlMethod.push_back(make_luaL_reg("Set",     cLuaBind<_T>::l_Set));
00120             mlMethod.push_back(make_luaL_reg("IsAlive", cLuaBind<_T>::IsAlive));
00121             mlMethod.push_back(make_luaL_reg("__gc",    cLuaBind<_T>::LuaGC));
00122 
00123             // you can also make a nice little macro to avoid double typing :
00124             //#define REGISTER_METHOD(methodname) mlMethod.push_back(make_luaL_reg(#methodname,&cYourDerivedClass::methodname));
00125             //REGISTER_METHOD(Spawn);
00126 
00127             // you can register static methods or global functions in RegisterMethods() like this :
00128             // lua_register(L,"MyGlobalFun",    MyGlobalFun);
00129             // lua_register(L,"MyStaticMethod", &cSomeClass::MyStaticMethod);
00130 
00131             RegisterMethods(L);
00132             RegisterMembers();
00133 
00134             struct luaL_reg* pMethodBuffer = new luaL_reg[mlMethod.size()+1];
00135             unsigned int i; for (i=0;i<mlMethod.size();++i) pMethodBuffer[i] = mlMethod[i];
00136             pMethodBuffer[i] = make_luaL_reg(0,0);
00137 
00138             // const struct luaL_reg methods [] = { {a, b},...,{0, 0} };
00139             
00140             /*
00141             old:
00142             assert(GetLuaTypeName());
00143             luaL_newmetatable(L,GetLuaTypeName());
00144             lua_pushstring(L, "__index");
00145             lua_pushvalue(L, -2);  // pushes the metatable 
00146             lua_settable(L, -3);  // metatable.__index = metatable 
00147             luaL_openlib(L, NULL, pMethodBuffer, 0); // = luaL_register in lua5.1 // TODO : put this into a new table, not in the metatable
00148             */
00149 
00150             const char* luafunc_RegisterUDataType = "RegisterUDataType";
00151             lua_getglobal(L,luafunc_RegisterUDataType);
00152             // stack -1 : function : RegisterUDataType 
00153             
00154             const char* myLuaTypeName = GetLuaTypeName();
00155             assert(myLuaTypeName);
00156             lua_pushstring(L,myLuaTypeName);
00157             // stack -1 : string : myLuaTypeName
00158             // stack -2 : function : RegisterUDataType 
00159             
00160             if (luaL_newmetatable(L,myLuaTypeName) == 0) {
00161                 // should not happen
00162                 assert(0 && "WARNING ! every luabind-type must have a unique name, see GetLuaTypeName()");
00163             }
00164             // stack -1 : metatable
00165             // stack -2 : string : myLuaTypeName
00166             // stack -3 : function : RegisterUDataType 
00167             
00168             // push key for lua_settable
00169             lua_pushstring(L,"methods");
00170             // stack -1 : string "methods"
00171             // stack -2 : metatable
00172             // stack -3 : string : myLuaTypeName
00173             // stack -4 : function : RegisterUDataType 
00174             
00175             // push value for lua_settable
00176             lua_newtable(L);
00177             luaL_openlib(L, NULL, pMethodBuffer, 0); // = luaL_register in lua5.1
00178             // luaL_openlib : NULL : luaL_openlib does not create any table to pack the functions; instead, it assumes that the package table is on the stack
00179             // stack -1 : table with methods
00180             // stack -2 : string "methods"
00181             // stack -3 : metatable
00182             // stack -4 : string : myLuaTypeName
00183             // stack -5 : function : RegisterUDataType 
00184             
00185             lua_settable(L,-3); // metatable.methods = table with pMethodBuffer (top of stack), pops top of stack
00186             // stack -1 : metatable
00187             // stack -2 : string : myLuaTypeName
00188             // stack -3 : function : RegisterUDataType 
00189             
00190             // call lua function :  RegisterUDataType(name,metatable)
00191             int narg = 2;
00192             if (PCallWithErrFuncWrapper(L,narg, 0) != 0)  // do the call
00193                 LuaErrorHandler(L, "error running function `%s': %s",luafunc_RegisterUDataType, lua_tostring(L, -1));
00194             // stack is empty now
00195             
00196             delete [] pMethodBuffer;
00197         }
00198 
00201         virtual ~cLuaBind(){};
00202         
00204         virtual void NotifyGC           (lua_State *L,_T* target) { PROFILE }
00205 
00207         virtual void RegisterMethods    (lua_State *L) { PROFILE }
00208 
00209 
00210 
00213         virtual void    RegisterMembers () { PROFILE}
00214         /* Example :
00215         void cMyMemberVarList::RegisterMembers () {
00216             cObject* prototype = new cObject(0); // memory leak : never deleted, but better than side effekts
00217             cMemberVar_REGISTER(prototype,  kVarType_size_t,    miVar1, kVarFlag_Readonly);
00218             cMemberVar_REGISTER(prototype,  kVarType_Real,      miVar2, kVarFlag_NotifyChange);
00219             cMemberVar_REGISTER(prototype,  kVarType_size_t,    miVar3, 0);
00220         }
00221         */
00222 
00224         virtual void    NotifyChange    (_T* pObj,const char* sMemberVarName) { PROFILE} // default implementation is empty dummy
00225         /* Example :
00226         void cMyMemberVarList::NotifyChange (_T* pObj,const char* sMemberVarName) {
00227             assert(pObj);
00228             pObj->mbNeedResync = true;
00229         }
00230         */
00231         
00233 
00235         static int      CreateUData (lua_State *L,_T* target) { PROFILE 
00236             const char* myLuaTypeName = GetSingletonPtr()->GetLuaTypeName();
00237             const char* luafunc_WrapUData = "WrapUData";
00238             lua_getglobal(L,luafunc_WrapUData);
00239             // stack -1 : function : WrapUData 
00240             
00241             udata *o = (udata*)lua_newuserdata(L,sizeof(udata));
00242             o->pSmartPtr = new cSmartPtr<_T>(target);
00243             luaL_getmetatable(L, myLuaTypeName);
00244             lua_setmetatable(L, -2);
00245             // stack -1 : udata
00246             // stack -2 : function : WrapUData 
00247             
00248             // call lua function :  WrapUData(udata)
00249             int narg = 1;
00250             int nres = 1;
00251             if (PCallWithErrFuncWrapper(L,narg, nres) != 0) { // do the call
00252                 LuaErrorHandler(L, "error running function `%s': %s",luafunc_WrapUData, lua_tostring(L, -1));
00253                 return 0;
00254             }
00255             // stack now contains the result from the WrapUData function
00256             return nres;  // number of results
00257         }
00258         
00260         static int      CreateUDataOrNil    (lua_State *L,_T* target)   { PROFILE
00261             if(target)return CreateUData(L,target);
00262             else return 0;
00263         }
00264 
00266         inline static _T*   checkudata          (lua_State *L,int index=1) { PROFILE
00267             udata* o;
00268             cLuaBind<_T>* pSingleton = GetSingletonPtr();
00269             if (lua_istable(L,index)) {
00270                 // extract udata field from table, avoiding metat
00271                 lua_pushstring(L,"udata");
00272                 lua_rawget(L,index-((index<0)?1:0)); // index might be negative (relative from top), so we might have to adjust it (-1)
00273                 
00274                 o = (udata*)luaL_checkudata(L, -1, pSingleton->GetLuaTypeName());
00275                 lua_pop(L,1); // pop the temporary udata from stack
00276                 /*
00277                 void lua_rawget (lua_State *L, int index);
00278                 Pushes onto the stack the value t[k], where 
00279                 t is the value at the given valid index index and 
00280                 k is the value at the top of the stack.
00281                 This function pops the key from the stack (putting the resulting value in its place). 
00282                 As in Lua, this function may trigger a metamethod for the "index" event (see 2.8). 
00283                 */
00284                 // can't be used here : lua_getfield(L,index,"udata"); // warning, might use metatable if udata field is not set
00285             } else {
00286                 o = (udata*)luaL_checkudata(L, index, pSingleton->GetLuaTypeName());
00287             }
00288             luaL_argcheck(L, o != NULL, index,pSingleton->mszError_X_expected);
00289             if (!o->pSmartPtr) return 0;
00290             return *(*o->pSmartPtr);
00291         }
00292 
00294         inline static _T*   checkudata_alive    (lua_State *L,int index=1) { PROFILE
00295             _T* res = checkudata(L,index);
00296             luaL_argcheck(L, res != NULL, index,GetSingletonPtr()->mszError_dead_X_ptr);
00297             return res;
00298         }
00299 
00301 
00305         static int      LuaGC       (lua_State *L) { PROFILE
00306             cLuaBind<_T>* pSingleton = GetSingletonPtr();
00307             udata* o = (udata*)luaL_checkudata(L, 1, pSingleton->GetLuaTypeName());
00308             luaL_argcheck(L, o != NULL, 1,pSingleton->mszError_X_expected);
00309             pSingleton->NotifyGC(L,**o->pSmartPtr);
00310             if (o->pSmartPtr) delete o->pSmartPtr;
00311             o->pSmartPtr = 0;
00312             return 0;
00313         }
00314         
00315         // TODO : function to list membervar names
00316         // TODO : function to get membervar type & flags
00317 
00319         static int      l_Get   (lua_State *L) { PROFILE
00320             _T* pObj = checkudata(L);
00321             if (!pObj) return 0;
00322             const char *sMemberVarName = luaL_checkstring(L,2);
00323             return GetSingletonPtr()->Get(pObj,sMemberVarName,L);
00324         }
00325     
00327         static int      l_Set   (lua_State *L) { PROFILE
00328             _T* pObj = checkudata(L);
00329             if (!pObj) return 0;
00330             const char *sMemberVarName = luaL_checkstring(L,2);
00331             return GetSingletonPtr()->Set(pObj,sMemberVarName,L,3);
00332         }
00333 
00335         static int      IsAlive             (lua_State *L) { PROFILE
00336             lua_pushboolean(L,checkudata(L) ? 1 : 0);
00337             return 1;
00338         }
00339         
00341 
00344         int     Set (_T* pObj,const char* sMemberVarName,lua_State *L,size_t index=3) { PROFILE
00345             //printf("cLuaBind::Set(%08x,%s)\n",(size_t)pObj,sMemberVarName);
00346             if (!pObj)                              { lua_pushstring(L,"pObj=0");           return 1; }
00347             if (!sMemberVarName)                    { lua_pushstring(L,"sMemberVarName=0"); return 1; }
00348             cMemberVar* mv = mlMemberVar[sMemberVarName];
00349             if (!mv)                                { lua_pushstring(L,"not found");        return 1; }
00350             if (mv->miFlags & kVarFlag_Readonly)    { lua_pushstring(L,"readonly");         return 1; }
00351 
00352             char* myptr = ((char*)pObj) + mv->miOffset;
00353             switch (mv->miType) {
00354                 case kVarType_String:   *(std::string*)myptr    = luaL_checkstring(L,index);    break;
00355                 case kVarType_int:      *(int*)myptr            = luaL_checkint(L,index);       break;
00356                 case kVarType_size_t:   *(size_t*)myptr         = luaL_checkint(L,index);       break;
00357                 case kVarType_bool:
00358                         if (lua_isboolean(L,index))
00359                                 *(bool*)myptr       = lua_toboolean(L,index);
00360                         else    *(bool*)myptr       = luaL_checkint(L,index);
00361                 break;
00362                 case kVarType_Float:    *(float*)myptr  = luaL_checknumber(L,index);    break;
00363                 case kVarType_Real:     *(Ogre::Real*)myptr = luaL_checknumber(L,index);    break;
00364                 case kVarType_Colour: {
00365                     //Ogre::Real r,g,b;
00366                     if (lua_istable(L,index)) {
00367                         /*  void lua_rawgeti (lua_State *L, int index, int n);
00368                             Pushes onto the stack the value t[n], where t is the value at the given valid index index.
00369                             The access is raw; that is, it does not invoke metamethods.
00370                         */
00371                         lua_rawgeti(L,index,3);
00372                         lua_rawgeti(L,index,2);
00373                         lua_rawgeti(L,index,1);
00374                         (*(Ogre::ColourValue*)myptr).r = luaL_checknumber(L,-1);
00375                         (*(Ogre::ColourValue*)myptr).g = luaL_checknumber(L,-2);
00376                         (*(Ogre::ColourValue*)myptr).b = luaL_checknumber(L,-3);
00377                         lua_pop(L,3); // clean stack
00378                     } else {
00379                         (*(Ogre::ColourValue*)myptr).r = luaL_checknumber(L,index);
00380                         (*(Ogre::ColourValue*)myptr).g = luaL_checknumber(L,index+1);
00381                         (*(Ogre::ColourValue*)myptr).b = luaL_checknumber(L,index+2);
00382                     }
00383                 } break;
00384                 case kVarType_Vector2: {
00385                     if (lua_istable(L,index)) {
00386                         /*  void lua_rawgeti (lua_State *L, int index, int n);
00387                             Pushes onto the stack the value t[n], where t is the value at the given valid index index.
00388                             The access is raw; that is, it does not invoke metamethods.
00389                         */
00390                         lua_rawgeti(L,index,2);
00391                         lua_rawgeti(L,index,1);
00392                         (*(Ogre::Vector2*)myptr).x = luaL_checknumber(L,-1);
00393                         (*(Ogre::Vector2*)myptr).y = luaL_checknumber(L,-2);
00394                         lua_pop(L,2); // clean stack
00395                     } else {
00396                         (*(Ogre::Vector2*)myptr).x = luaL_checknumber(L,index);
00397                         (*(Ogre::Vector2*)myptr).y = luaL_checknumber(L,index+1);
00398                     }
00399                 } break;
00400                 case kVarType_Vector3: {
00401                     if (lua_istable(L,index)) {
00402                         /*  void lua_rawgeti (lua_State *L, int index, int n);
00403                             Pushes onto the stack the value t[n], where t is the value at the given valid index index.
00404                             The access is raw; that is, it does not invoke metamethods.
00405                         */
00406                         lua_rawgeti(L,index,3);
00407                         lua_rawgeti(L,index,2);
00408                         lua_rawgeti(L,index,1);
00409                         (*(Ogre::Vector3*)myptr).x = luaL_checknumber(L,-1);
00410                         (*(Ogre::Vector3*)myptr).y = luaL_checknumber(L,-2);
00411                         (*(Ogre::Vector3*)myptr).z = luaL_checknumber(L,-3);
00412                         lua_pop(L,3); // clean stack
00413                     } else {
00414                         (*(Ogre::Vector3*)myptr).x = luaL_checknumber(L,index);
00415                         (*(Ogre::Vector3*)myptr).y = luaL_checknumber(L,index+1);
00416                         (*(Ogre::Vector3*)myptr).z = luaL_checknumber(L,index+2);
00417                     }
00418                 } break;
00419                 case kVarType_Quaternion: {
00420                     if (lua_istable(L,index)) {
00421                         /*  void lua_rawgeti (lua_State *L, int index, int n);
00422                             Pushes onto the stack the value t[n], where t is the value at the given valid index index.
00423                             The access is raw; that is, it does not invoke metamethods.
00424                         */
00425                         lua_rawgeti(L,index,4);
00426                         lua_rawgeti(L,index,3);
00427                         lua_rawgeti(L,index,2);
00428                         lua_rawgeti(L,index,1);
00429                         (*(Ogre::Quaternion*)myptr).w = luaL_checknumber(L,-1);
00430                         (*(Ogre::Quaternion*)myptr).x = luaL_checknumber(L,-2);
00431                         (*(Ogre::Quaternion*)myptr).y = luaL_checknumber(L,-3);
00432                         (*(Ogre::Quaternion*)myptr).z = luaL_checknumber(L,-4);
00433                         lua_pop(L,4); // clean stack
00434                     } else {
00435                         (*(Ogre::Quaternion*)myptr).w = luaL_checknumber(L,index);
00436                         (*(Ogre::Quaternion*)myptr).x = luaL_checknumber(L,index+1);
00437                         (*(Ogre::Quaternion*)myptr).y = luaL_checknumber(L,index+2);
00438                         (*(Ogre::Quaternion*)myptr).z = luaL_checknumber(L,index+3);
00439                     }
00440                 } break;
00441                 /*
00442                 case kVarType_ObjSmartPtr: {
00443                     cObject* target = luaSFZ_checkObject(L,index);
00444                     *(cSmartPtr<cObject>*)myptr = target;
00445                 } break;
00446                 */
00447             }
00448 
00449             if (mv->miFlags & kVarFlag_NotifyChange) NotifyChange(pObj,sMemberVarName);
00450             return 0;
00451         }
00452 
00456         int     Get (_T* pObj,const char* sMemberVarName,lua_State *L) { PROFILE
00457             if (!pObj)              return 0;
00458             if (!sMemberVarName)    return 0;
00459             cMemberVar* mv = mlMemberVar[sMemberVarName];
00460             if (!mv)                return 0; // not found
00461 
00462             char* myptr = ((char*)pObj) + mv->miOffset;
00463             switch (mv->miType) {
00464                 case kVarType_String:   lua_pushstring(L,(*(std::string*)myptr).c_str());   return 1;break;
00465                 case kVarType_int:      lua_pushnumber(L,*(int*)myptr);     return 1;break;
00466                 case kVarType_size_t:   lua_pushnumber(L,*(size_t*)myptr);  return 1;break;
00467                 case kVarType_bool:     lua_pushboolean(L,*(bool*)myptr);   return 1;break;
00468                 case kVarType_Float:    lua_pushnumber(L,*(float*)myptr);   return 1;break;
00469                 case kVarType_Real:     lua_pushnumber(L,*(Ogre::Real*)myptr);  return 1;break;
00470                 case kVarType_Vector2: {
00471                     /* void lua_rawseti (lua_State *L, int index, int n);
00472                     Does the equivalent of t[n] = v, where t is a table at "index" and v is the value at the top of the stack,
00473                     This function pops the value from the stack. The assignment is raw; that is, it does not invoke metamethods.
00474                     */
00475                     lua_newtable(L);
00476                     lua_pushnumber(L,(*(Ogre::Vector2*)myptr).x); lua_rawseti(L,-2,1);
00477                     lua_pushnumber(L,(*(Ogre::Vector2*)myptr).y); lua_rawseti(L,-2,2);
00478                     return 1;
00479                 } break;
00480                 case kVarType_Vector3: {
00481                     /* void lua_rawseti (lua_State *L, int index, int n);
00482                     Does the equivalent of t[n] = v, where t is a table at "index" and v is the value at the top of the stack,
00483                     This function pops the value from the stack. The assignment is raw; that is, it does not invoke metamethods.
00484                     */
00485                     lua_newtable(L);
00486                     lua_pushnumber(L,(*(Ogre::Vector3*)myptr).x); lua_rawseti(L,-2,1);
00487                     lua_pushnumber(L,(*(Ogre::Vector3*)myptr).y); lua_rawseti(L,-2,2);
00488                     lua_pushnumber(L,(*(Ogre::Vector3*)myptr).z); lua_rawseti(L,-2,3);
00489                     return 1;
00490                 } break;
00491                 case kVarType_Colour: {
00492                     lua_newtable(L);
00493                     lua_pushnumber(L,(*(Ogre::ColourValue*)myptr).r); lua_rawseti(L,-2,1);
00494                     lua_pushnumber(L,(*(Ogre::ColourValue*)myptr).g); lua_rawseti(L,-2,2);
00495                     lua_pushnumber(L,(*(Ogre::ColourValue*)myptr).b); lua_rawseti(L,-2,3);
00496                     return 1;
00497                 } break;
00498                 case kVarType_Quaternion: {
00499                     lua_newtable(L);
00500                     lua_pushnumber(L,(*(Ogre::Quaternion*)myptr).w); lua_rawseti(L,-2,1);
00501                     lua_pushnumber(L,(*(Ogre::Quaternion*)myptr).x); lua_rawseti(L,-2,2);
00502                     lua_pushnumber(L,(*(Ogre::Quaternion*)myptr).y); lua_rawseti(L,-2,3);
00503                     lua_pushnumber(L,(*(Ogre::Quaternion*)myptr).z); lua_rawseti(L,-2,4);
00504                     return 1;
00505                 } break;
00506                 case kVarType_Gfx3D: {
00507                     return cLuaBind<cGfx3D>::CreateUData(L,*(cGfx3D**)myptr);
00508                 } break;
00509                 case kVarType_Gfx2D: {
00510                     return cLuaBind<cGfx2D>::CreateUData(L,*(cGfx2D**)myptr);
00511                 } break;
00512                 /*
00513                 case kVarType_ObjSmartPtr: {
00514                     cObject* target = *(*(cSmartPtr<cObject>*)myptr);
00515                     lua_pushnumber(L,target ? target->miID : 0); // TODO : fix this to return udata
00516                     return 1;
00517                 } break;
00518                 */
00519             }
00520             return 0;
00521         }
00522 };
00523 
00524 
00525 
00526 
00527 
00528 
00529 inline Ogre::Vector3 luaSFZ_checkVector3 (lua_State *L,const size_t index) { PROFILE
00530     return Ogre::Vector3(luaL_checknumber(L,index),luaL_checknumber(L,index+1),luaL_checknumber(L,index+2));
00531 }
00532 
00533 // increments index : +1 if table, +3 if 3 floats
00534 inline Ogre::ColourValue luaSFZ_checkColour3 (lua_State *L,size_t& index) { PROFILE
00535     if (lua_istable(L,index)) {
00536         /*  void lua_rawgeti (lua_State *L, int index, int n);
00537             Pushes onto the stack the value t[n], where t is the value at the given valid index index.
00538             The access is raw; that is, it does not invoke metamethods.
00539         */
00540         lua_rawgeti(L,index,3);
00541         lua_rawgeti(L,index,2);
00542         lua_rawgeti(L,index,1);
00543         Ogre::ColourValue res(luaL_checknumber(L,-1),luaL_checknumber(L,-2),luaL_checknumber(L,-3));
00544         lua_pop(L,3); // clean stack
00545         index += 1;
00546         return res;
00547     } else {
00548         Ogre::ColourValue res(luaL_checknumber(L,index),luaL_checknumber(L,index+1),luaL_checknumber(L,index+2));
00549         index += 3;
00550         return res;
00551     }
00552 }
00553 
00554 // increments index : +1 if table, +4 if 4 floats
00555 inline Ogre::ColourValue luaSFZ_checkColour4 (lua_State *L,const int index) { PROFILE
00556     if (lua_istable(L,index)) {
00557         /*  void lua_rawgeti (lua_State *L, int index, int n);
00558             Pushes onto the stack the value t[n], where t is the value at the given valid index index.
00559             The access is raw; that is, it does not invoke metamethods.
00560         */
00561         lua_rawgeti(L,index,4);
00562         lua_rawgeti(L,index,3);
00563         lua_rawgeti(L,index,2);
00564         lua_rawgeti(L,index,1);
00565         Ogre::ColourValue res(luaL_checknumber(L,-1),luaL_checknumber(L,-2),luaL_checknumber(L,-3),luaL_checknumber(L,-4));
00566         lua_pop(L,4); // clean stack
00567         //index += 1;  old... should not be used anymore
00568         return res;
00569     } else {
00570         Ogre::ColourValue res(luaL_checknumber(L,index),luaL_checknumber(L,index+1),luaL_checknumber(L,index+2),luaL_checknumber(L,index+3));
00571         //index += 4;  old... should not be used anymore
00572         return res;
00573     }
00574 }
00575 
00576 /*
00577 inline cObject* luaSFZ_checkObject (lua_State *L,const size_t index) { PROFILE
00578     return cLuaBind<cObject>::checkudata(L,index);
00579 }
00580 */
00581 
00582 };
00583 
00584 #endif

Generated on Wed Feb 8 06:00:12 2012 for cpp by  doxygen 1.5.6