Lua_icxx  1.02 (Aug 2011)
LuaObjRef.h
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_OBJREF_INCLUDED
00011 #define LUA_ICXX_OBJREF_INCLUDED
00012 
00013 #include <string>
00014 
00015 #include "LuaRegistryRef.h"
00016 #include "LuaTempResult.h"
00017 #include "LuaStackCleaner.h"
00018 
00019 class LuaTableRef; 
00020 class LuaFuncRef; 
00021 
00022 
00028 class LUA_ICXX_CPP_API
00029 LuaObjRef
00030 {
00031 public:
00033     explicit LuaObjRef( const std::string& id = "nil" );
00034 
00036 
00037     LuaObjRef( const LuaTempResult& );
00038     LuaObjRef( const LuaTempResult::Item& );
00039     LuaObjRef( lua_State*, int stackPos );
00041     virtual ~LuaObjRef() {}
00042 
00043 public: 
00044 
00046 
00047     void resetRef( const LuaTempResult& result ) { resetRef(result[1]); }
00048     void resetRef( const LuaTempResult::Item& );
00049     LuaObjRef& operator=(const LuaTempResult& result )  { resetRef(result[1]); return *this;}
00050     LuaObjRef& operator=(const LuaTempResult::Item& resultItem )  { resetRef(resultItem); return *this;}
00052 
00054     void setNil() { mRegKey.setNil(); }
00056     bool isNil() const { return mErrCode ? true : mRegKey.isNil(); }
00058     int getTypeID() const { return mErrCode ? LUA_TNIL : mRegKey.getTypeID(); }
00060     std::string typeName() const { return ( mLua ? lua_typename(mLua, getTypeID()) : "nil" ); }
00062     bool isError() const { return mErrCode != LUA_ERR_NONE; }
00064     std::string getErrMsg() const;
00065 
00067     void setID(const std::string& id) { mID = id; }
00069     const std::string& getID() const { return mID; }
00070 
00072 
00073     template <typename TT>  inline operator TT() const { return getAs<TT>(); }
00074     template <typename TT>  TT getAs() const;
00076 
00077 public: // values
00079 
00080     template <typename TT> inline bool operator==(TT val) const { return getAs<TT>() == typename ValueType<TT>::Type(val); }
00081     template <typename TT> inline bool operator!=(TT val) const { return getAs<TT>() != typename ValueType<TT>::Type(val); }
00082     template <typename TT> inline bool operator>=(TT val) const { return getAs<TT>() >= typename ValueType<TT>::Type(val); }
00083     template <typename TT> inline bool operator<=(TT val) const { return getAs<TT>() <= typename ValueType<TT>::Type(val); }
00084     template <typename TT> inline bool operator>(TT val)  const { return getAs<TT>() >  typename ValueType<TT>::Type(val); }
00085     template <typename TT> inline bool operator<(TT val)  const { return getAs<TT>() <  typename ValueType<TT>::Type(val); }
00087 
00088 public: // meta tables
00089     // Customize behavior of this object by changing its metatable
00091     bool setMetaProtected( bool val = true );
00093     bool hasMetaTable() const;
00095     void setMetaTable(const LuaTableRef&);
00097     LuaTempResult getMetaTable() const;
00099     void setMetaBase(const LuaTableRef&);
00101     bool hasMetaBase() const;
00102 
00104     enum MetaMethod
00105     {
00106         MM_ADD,           
00107         MM_MULTIPLY,      
00108         MM_SUBTRACT,      
00109         MM_DIVIDE,        
00110         MM_UNARY_MINUS,   
00111         MM_NEGATE,        
00112         MM_CONCATENATE,   
00113 
00114         MM_EQUAL,         
00115         MM_LESS_THAN,     
00116         MM_LESS_OR_EQUAL, 
00117 
00118         MM_TOSTRING,      
00119         MM_INDEX,         
00120         MM_FIELD,         
00121         MM_NEW_INDEX,     
00122         MM_NEW_FIELD,     
00123     };
00124 
00126     void setMetaMethod(MetaMethod id, const LuaFuncRef& func); 
00127 
00128 public: // interact via C API directly
00130     void pushObj() const 
00131     { 
00132         if (mErrCode) 
00133         {
00134             assert( lua_checkstack(mLua, 1) ); 
00135             lua_pushnil(mLua); 
00136         }
00137         else 
00138             mRegKey.pushObj(); 
00139     }
00141     lua_State* getLuaState() const { return mLua; }
00142 
00143 protected:
00144     lua_State * mLua; 
00145 
00146 private:
00147     struct AutoPop;
00148     template <typename TT> struct DefaultValue;
00149 
00150     const char* getMetaMethodFromID( MetaMethod id );
00151 
00152 private:
00153     LuaRegRef mRegKey;
00154     std::string mID;
00155     LuaErrCode mErrCode;
00156 };
00157 
00158 
00159 inline void 
00160 pushValToStack(lua_State* L, const LuaObjRef& objRef) 
00161 { 
00162     objRef.pushObj(); 
00163 }
00164 
00165 // -------------------------------------------------------
00166 
00167 
00168 template <typename TT> 
00169 struct LuaObjRef::DefaultValue
00170 {
00171     static inline TT value() {return 0;}
00172 };
00173 template <>
00174 struct LuaObjRef::DefaultValue<const char*>
00175 {
00176     static inline const char* value() {return "";}
00177 };
00178 template <>
00179 struct LuaObjRef::DefaultValue<std::string>
00180 {
00181     static inline std::string value() {return "";}
00182 };
00183 
00184 
00185 template <typename TT>
00186 inline TT
00187 LuaObjRef::getAs() 
00188 const 
00189 { 
00190     if (mErrCode)
00191         return DefaultValue<TT>::value();
00192 
00193     LuaStackCleaner s(mLua); 
00194     mRegKey.pushObj(); 
00195     return getObjFromStack<TT>(mLua); 
00196 }
00197 
00198 
00199 #endif // LUA_ICXX_OBJREF_INCLUDED