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_TABLEREF_INCLUDED 00011 #define LUA_ICXX_TABLEREF_INCLUDED 00012 00014 // Includes and declarations 00016 00017 00018 #include <string> 00019 00020 #include "LuaObjRef.h" 00021 #include "LuaStackCleaner.h" 00022 00023 00025 // Types/Classes 00027 00028 00032 class LUA_ICXX_CPP_API 00033 LuaTableRef : public LuaObjRef 00034 { 00035 public: 00036 // C++ requires all constructors to be duplicated 00037 00039 explicit LuaTableRef( const std::string& id = "nil" ): LuaObjRef(id) {} 00040 00042 00043 LuaTableRef( const LuaTempResult& res ): LuaObjRef(res) {} 00044 LuaTableRef( const LuaTempResult::Item& item ): LuaObjRef(item) {} 00045 LuaTableRef( lua_State* lua, int stackPos ): LuaObjRef(lua, stackPos) {} 00047 00048 template <typename KeyType> 00049 class Field; 00050 00052 template <typename KeyType> 00053 inline bool hasField( const KeyType& key ) const; 00054 00056 00057 template <typename KeyType> 00058 inline LuaTempResult getField(const KeyType& key) const; 00059 template <typename KeyType> 00060 inline Field<KeyType> operator[] (const KeyType& key) { return Field<KeyType>(*this, key); } 00062 00064 template <typename ValType> 00065 inline void setField( const char* key, const ValType& obj ); 00066 template <typename ValType> 00067 inline void setField( const std::string& key, const ValType& obj ) { setField(key.c_str(), obj); } 00068 template <typename KeyType, typename ValType> 00069 inline void setField( const KeyType& key, const ValType& obj ); 00071 00073 00074 inline void delField( const char* key ); 00075 inline void delField( const std::string& key ) { delField(key.c_str()); } 00076 template <typename KeyType> 00077 inline void delField( const KeyType& key ); 00079 00080 private: 00081 00082 // all pushFieldValue methods assume table already on stack 00083 00084 // push t[key] on top of stack 00085 void pushFieldValue( int key ) const { assert( lua_checkstack(mLua, 1) ); lua_rawgeti(mLua, -1, key); } 00086 void pushFieldValue( const char* key ) const { assert( lua_checkstack(mLua, 1) ); lua_getfield(mLua, -1, key); } 00087 void pushFieldValue( const std::string& key ) const { pushFieldValue(key.c_str()); } 00088 // when key=bool, float, double, short, etc 00089 template <typename TT> 00090 inline void pushFieldValue( const TT& key ) const; 00091 }; 00092 00093 00095 // LuaTableRef::Field<KeyType> 00097 00098 00103 template <typename KeyType> 00104 class LuaTableRef::Field 00105 { 00106 public: 00108 Field(LuaTableRef& table, const KeyType& key): mTable(table), mKey(key) {} 00109 00110 00112 template <typename ValType> 00113 void operator=(const ValType& obj) { mTable.setField(mKey, obj); } 00115 void operator=(const Field& rhs) { mTable.setField(mKey, rhs); } 00116 00118 operator LuaTempResult() const { return mTable.getField(mKey); } 00120 template <typename TT> 00121 operator TT() const { return TT(mTable.getField(mKey)); } 00122 00124 template <typename ValType> 00125 bool operator==(const ValType& obj) const { return mTable.getField(mKey) == obj; } 00127 bool isNil() const { return mTable.getField(mKey).isNil(); } 00128 00129 public: 00131 inline void pushObj() const; 00132 00133 private: 00134 LuaTableRef& mTable; 00135 const KeyType& mKey; 00136 }; 00137 00138 00140 // inlines and templates for LuaTableRef::Field<KeyType> 00142 00143 00144 template <typename KeyType> 00145 inline void 00146 LuaTableRef::Field<KeyType>::pushObj() 00147 const 00148 { 00149 mTable.pushObj(); 00150 mTable.pushFieldValue(mKey); 00151 lua_remove(mTable.getLuaState(), -2); // remove table (just need value) 00152 } 00153 00154 00155 template <typename KeyType> 00156 inline void 00157 pushValToStack(lua_State* L, const LuaTableRef::Field<KeyType>& field) 00158 { 00159 field.pushObj(); 00160 } 00161 00162 00164 // inlines and templates for LuaTableRef 00166 00167 00168 // push the value for given key onto stack 00169 template <typename TT> 00170 inline void 00171 LuaTableRef::pushFieldValue( const TT& key ) 00172 const 00173 { 00174 pushValToStack(mLua, key); 00175 lua_gettable(mLua, -2); // get t[key] on top of stack 00176 } 00177 00178 00179 template <typename KeyType> 00180 inline bool 00181 LuaTableRef::hasField( const KeyType& key ) 00182 const 00183 { 00184 const LuaStackCleaner s(mLua); 00185 pushObj(); 00186 pushFieldValue(key); 00187 assert( s.willPop(2) ); 00188 return ! lua_isnil(mLua, -1); 00189 } 00190 00191 00192 template <typename KeyType> 00193 inline LuaTempResult 00194 LuaTableRef::getField( const KeyType& key ) 00195 const 00196 { 00197 const int prevStackTop = lua_gettop(mLua); 00198 pushObj(); // push table on stack 00199 pushFieldValue(key); // get value for key 00200 lua_remove(mLua, -2); // remove table (just need value) 00201 return LuaTempResult(mLua, prevStackTop); 00202 } 00203 00204 00205 template <typename ValType> 00206 inline void 00207 LuaTableRef::setField( const char* key, const ValType& obj ) 00208 { 00209 const LuaStackCleaner s(mLua); 00210 pushObj(); 00211 pushValToStack(mLua, obj); 00212 lua_setfield(mLua, -2, key); 00213 assert( s.willPop(1) ); 00214 } 00215 00216 00217 template <typename KeyType, typename ValType> 00218 inline void 00219 LuaTableRef::setField( const KeyType& key, const ValType& obj ) 00220 { 00221 const LuaStackCleaner s(mLua); 00222 pushObj(); 00223 pushValToStack(mLua, key); 00224 pushValToStack(mLua, obj); 00225 lua_settable(mLua, -3); 00226 assert( s.willPop(1) ); 00227 } 00228 00229 00230 inline void 00231 LuaTableRef::delField( const char* key ) 00232 { 00233 const LuaStackCleaner s(mLua); 00234 pushObj(); 00235 assert( lua_checkstack(mLua, 1) ); 00236 lua_pushnil(mLua); 00237 lua_setfield(mLua, -2, key); 00238 assert( s.willPop(1) ); 00239 } 00240 00241 00242 template <typename KeyType> 00243 inline void 00244 LuaTableRef::delField( const KeyType& key ) 00245 { 00246 const LuaStackCleaner s(mLua); 00247 pushObj(); 00248 pushValToStack(mLua, key); 00249 assert( lua_checkstack(mLua, 1) ); 00250 lua_pushnil(mLua); 00251 lua_settable(mLua, -3); 00252 assert( s.willPop(1) ); 00253 } 00254 00255 00256 #endif // LUA_ICXX_TABLEREF_INCLUDED 00257