X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FScript.hh;h=08284117359418234f4df58b2d84b04bbd34ca7d;hp=620db5bc6906c82bd58446be23a2075367c20208;hb=4107dd30ca1a4c7d1a5cd6c0999b9afb5adff779;hpb=58c1f9a499d3bb80ea2869b29c714f61e656d48d diff --git a/src/Moof/Script.hh b/src/Moof/Script.hh index 620db5b..0828411 100644 --- a/src/Moof/Script.hh +++ b/src/Moof/Script.hh @@ -99,17 +99,9 @@ public: int index; - /** - * A default-constructed Slot is invalid until a valid Slot is - * assigned to it. The only method that should be called on such a - * Slot is isValid(), otherwise chaos may ensue. In this case, the - * Slot will be invalid even if index is manually changed to a - * valid index. You have to index the script itself to get a valid - * Slot. - */ - Slot(lua_State* s = 0, int i = 0) : + Slot(const Script& s, int i = 0) : index(i), - mState(s) {} + mScript(const_cast(s)) {} /** * A copied value presently points to the same value, except the @@ -118,36 +110,36 @@ public: * normalized index copied into the new value object. */ - Slot(const Slot& copy) : - index(copy.getRealIndex()), - mState(copy.mState) {} + //Slot(const Slot& copy) : + //index(copy.positiveIndex()), + //mScript(copy.mScript) {} // check the type of the value bool isBoolean() const - { return (bool)lua_isboolean(mState, index); } + { return (bool)lua_isboolean(mScript.mState, index); } + bool isImportedFunction() const + { return (bool)lua_iscfunction(mScript.mState, index); } bool isFunction() const - { return (bool)lua_isfunction(mState, index); } + { return (bool)lua_isfunction(mScript.mState, index); } bool isNil() const - { return (bool)lua_isnil(mState, index); } + { return (bool)lua_isnil(mScript.mState, index); } bool isNone() const - { return (bool)lua_isnone(mState, index); } - bool isValid() const - { return mState != 0 && !isNone(); } + { return (bool)lua_isnone(mScript.mState, index); } bool isNoneOrNil() const - { return (bool)lua_isnoneornil(mState, index); } + { return (bool)lua_isnoneornil(mScript.mState, index); } bool isNumber() const - { return (bool)lua_isnumber(mState, index); } + { return (bool)lua_isnumber(mScript.mState, index); } bool isString() const - { return (bool)lua_isstring(mState, index); } + { return (bool)lua_isstring(mScript.mState, index); } bool isTable() const - { return (bool)lua_istable(mState, index); } + { return (bool)lua_istable(mScript.mState, index); } bool isThread() const - { return (bool)lua_isthread(mState, index); } + { return (bool)lua_isthread(mScript.mState, index); } bool isData() const - { return (bool)lua_isuserdata(mState, index); } + { return (bool)lua_isuserdata(mScript.mState, index); } bool isLightData() const - { return (bool)lua_islightuserdata(mState, index); } + { return (bool)lua_islightuserdata(mScript.mState, index); } /** * Check the value and throw an error if its the wrong type. @@ -163,58 +155,83 @@ public: * before any C++ objects are even constructed. */ - void requireType(Type type) const + void requireType(Type t) const { - if (type != getType()) + if (t != type()) { - luaL_typerror(mState, index, lua_typename(mState, type)); + luaL_typerror(mScript.mState, index, + lua_typename(mScript.mState, t)); } } - void throwError(const char* error) + void raise(const char* error) { - luaL_argerror(mState, index, error); + luaL_argerror(mScript.mState, index, error); } Slot& requireBoolean() { - if (!isBoolean()) luaL_typerror(mState, index, "boolean"); + if (!isBoolean()) + { + luaL_typerror(mScript.mState, index, "boolean"); + } return *this; } Slot& requireNumber() { - if (!isNumber()) luaL_typerror(mState, index, "number"); + if (!isNumber()) + { + luaL_typerror(mScript.mState, index, "number"); + } return *this; } Slot& requireString() { - if (!isString()) luaL_typerror(mState, index, "string"); + if (!isString()) + { + luaL_typerror(mScript.mState, index, "string"); + } return *this; } Slot& requireTable() { - if (!isTable()) luaL_typerror(mState, index, "table"); + if (!isTable()) + { + luaL_typerror(mScript.mState, index, "table"); + } return *this; } Slot& requireFunction() { - if (!isFunction()) luaL_typerror(mState, index, "function"); + if (!isFunction()) + { + luaL_typerror(mScript.mState, index, "function"); + } return *this; } Slot& requireData() { - if (!isData()) luaL_typerror(mState, index, "data"); + if (!isData()) + { + luaL_typerror(mScript.mState, index, "data"); + } return *this; } Slot& requireNil() { - if (!isNil()) luaL_typerror(mState, index, "nil"); + if (!isNil()) + { + luaL_typerror(mScript.mState, index, "nil"); + } return *this; } Slot& requireThread() { - if (!isThread()) luaL_typerror(mState, index, "thread"); + if (!isThread()) + { + luaL_typerror(mScript.mState, index, "thread"); + } return *this; } @@ -223,18 +240,18 @@ public: * Get the type of the value. */ - Type getType() const + Type type() const { - return (Type)lua_type(mState, index); + return (Type)lua_type(mScript.mState, index); } /** * Get the name of the type of the value as a string. */ - std::string getTypeName() const + std::string typeName() const { - return std::string(luaL_typename(mState, index)); + return std::string(luaL_typename(mScript.mState, index)); } @@ -243,14 +260,14 @@ public: * Lua. */ - size_t getLength() const + size_t length() const { - return lua_objlen(mState, index); + return lua_objlen(mScript.mState, index); } - int getRealIndex() const + int positiveIndex() const { - if (index < 0) return lua_gettop(mState) + 1 + index; + if (index < 0) return index + lua_gettop(mScript.mState) + 1; else return index; } @@ -260,23 +277,34 @@ public: * functions). */ - const void* getIdentifier() const + const void* id() const + { + return lua_topointer(mScript.mState, index); + } + + bool isIdentical(const Slot& rhs) const + { + return &mScript == &(rhs.mScript) && index == rhs.index; + } + + operator bool () const { - return lua_topointer(mState, index); + return !isNone(); } bool operator == (const Slot& rhs) const { - return (bool)lua_equal(mState, index, rhs.index); + return (bool)lua_equal(mScript.mState, index, rhs.index); } bool operator != (const Slot& rhs) const { return !(*this == rhs); } + bool operator < (const Slot& rhs) const { - return (bool)lua_lessthan(mState, index, rhs.index); + return (bool)lua_lessthan(mScript.mState, index, rhs.index); } bool operator <= (const Slot& rhs) const { @@ -290,29 +318,18 @@ public: { return !(*this < rhs); } - operator bool () const - { - return (bool)lua_toboolean(mState, index); - } - - Slot& operator = (const Slot& rhs) - { - rhs.pushCopy(); - replaceWithTop(); - return *this; - } /** * Convert the underlying value to a C++ type. */ - template + template bool get(T& value) const { if (isNumber()) { - value = (T)lua_tointeger(mState, index); + value = (T)lua_tointeger(mScript.mState, index); return true; } return false; @@ -322,7 +339,7 @@ public: { if (isNumber()) { - value = (float)lua_tonumber(mState, index); + value = (float)lua_tonumber(mScript.mState, index); return true; } return false; @@ -331,7 +348,7 @@ public: { if (isNumber()) { - value = (double)lua_tonumber(mState, index); + value = (double)lua_tonumber(mScript.mState, index); return true; } return false; @@ -341,62 +358,82 @@ public: { if (isBoolean()) { - value = (bool)lua_toboolean(mState, index); + value = (bool)lua_toboolean(mScript.mState, index); return true; } return false; } - bool get(std::string& value) const + bool get(const char*& value, size_t& size) const { if (isString()) { - size_t size; - const char* str = lua_tolstring(mState, index, &size); + value = lua_tolstring(mScript.mState, index, &size); + return true; + } + return false; + } + + bool get(std::string& value) const + { + const char* str; + size_t size; + if (get(str, size)) + { value.assign(str, size); return true; } return false; } - template + bool get(void*& value) const + { + if (isData()) + { + value = lua_touserdata(mScript.mState, index); + return true; + } + return false; + } + + template bool get(std::vector& array) const { if (!isTable()) return false; array.clear(); - Slot value(mState, -1); - int realIndex = getRealIndex(); + Slot value = mScript[-1]; + int realIndex = positiveIndex(); bool done = false; for (int i = 1; !done; ++i) { - lua_rawgeti(mState, realIndex, i); + lua_rawgeti(mScript.mState, realIndex, i); T v; if (value.get(v)) array.push_back(v); else done = true; - lua_pop(mState, 1); + mScript.pop(); } return true; } - template + template bool get(std::map& dictionary) const { if (!isTable()) return false; dictionary.clear(); - Slot key(mState, -2); - Slot value(mState, -1); - int realIndex = getRealIndex(); + Slot key = mScript[-2]; + Slot value = mScript[-1]; + int realIndex = positiveIndex(); - lua_pushnil(mState); - while (lua_next(mState, realIndex) != 0) + mScript.pushNil(); + while (lua_next(mScript.mState, realIndex) != 0) { std::string k; if (!key.isNumber() && key.get(k)) @@ -404,9 +441,9 @@ public: T v; if (value.get(v)) dictionary[k] = v; } - lua_pop(mState, 1); + mScript.pop(); } - lua_pop(mState, 1); + mScript.pop(); return true; } @@ -415,37 +452,79 @@ public: * Get the value of a field from the table. */ - template + template bool get(T& value, V field) const { - pushField(field); - bool ret = Slot(mState, -1).get(value); - lua_pop(mState, 1); + bool ret = pushField(field).get(value); + mScript.pop(); return ret; } + template + void setField(T field, V value) + { + logWarning << "setting " << field << ", " << value << std::endl; + mScript.push(field); + mScript.push(value); + setField(); + } + + void setField() + { + lua_settable(mScript.mState, index); + } + + + template + void setField(const std::string& field, T value) + { + setField(field.c_str(), value); + } + template + void setField(const char* field, T value) + { + logWarning << "setfield " << field << ", " << value << std::endl; + mScript.push(value); + lua_setfield(mScript.mState, index, field); + } + + /** - * Copy the value and push the copy to the stack. + * This set method, as opposed to the others, sets the value of the + * actual slot. The others set table values. */ + template + void set(T value) + { + mScript.push(value); + replace(); + } - void pushCopy() const + void set() { - lua_pushvalue(mState, index); + replace(); } + /** * Replace this value with the value at the top of the stack. */ - void replaceWithTop() + void replace() { - lua_replace(mState, index); + lua_replace(mScript.mState, index); } void remove() { - lua_remove(mState, index); + lua_remove(mScript.mState, index); + } + + void pop() + { + // removes this slot, taking with it everything above it + mScript.pop(mScript.stackSize() - index + 1); } /** @@ -455,35 +534,70 @@ public: void insertTopHere() { - lua_insert(mState, index); + lua_insert(mScript.mState, index); } + + /** + * Copy the value and push the copy to the stack. + */ + + Slot pushCopy() const + { + lua_pushvalue(mScript.mState, index); + return mScript.top(); + } - void pushMetaTable() const + Slot pushMetaTable() const + { + lua_getmetatable(mScript.mState, index); + return mScript.top(); + } + + Slot pushEnvironment() const + { + lua_getfenv(mScript.mState, index); + return mScript.top(); + } + + + Slot pushField() const { - lua_getmetatable(mState, index); + lua_gettable(mScript.mState, index); + return mScript.top(); } - void pushField() const + template + Slot pushField(T index) const { - lua_gettable(mState, index); + mScript.push(index); + return pushField(); } - void pushField(const std::string& name) const + Slot pushField(const std::string& name) const + { + return pushField(name.c_str()); + } + Slot pushField(const char* name) const { - lua_getfield(mState, index, name.c_str()); + lua_getfield(mScript.mState, index, name); + return mScript.top(); } - void pushField(size_t index) const + + Script& script() { - lua_pushinteger(mState, lua_Integer(index)); - pushField(); + return mScript; } + const Script& script() const + { + return mScript; + } private: - lua_State* mState; + Script& mScript; }; @@ -508,8 +622,7 @@ public: { if (mState) destroy(); mState = luaL_newstate(); - lua_pushlightuserdata(mState, this); - lua_setfield(mState, LUA_REGISTRYINDEX, "Script_hh_Object"); + registry().setField("Script_hh_Object", (void*)this); } @@ -638,7 +751,7 @@ public: * after cleaning up such objects. */ - void throwError() + void raise() { lua_error(mState); } @@ -648,24 +761,24 @@ public: * Get significant values. */ - Slot getGlobalTable() const + Slot globals() const { - return Slot(mState, GLOBALS); + return Slot(*this, GLOBALS); } - Slot getRegistryTable() const + Slot registry() const { - return Slot(mState, REGISTRY); + return Slot(*this, REGISTRY); } - Slot getEnvironmentTable() const + Slot environment() const { - return Slot(mState, ENVIRONMENT); + return Slot(*this, ENVIRONMENT); } - Slot getTop() const + Slot top() const { - return Slot(mState, lua_gettop(mState)); + return Slot(*this, stackSize()); } /** @@ -673,19 +786,19 @@ public: * value. */ - int getSize() const + int stackSize() const { return lua_gettop(mState); } - void setSize(int size) + void setStackSize(int size) { lua_settop(mState, size); } - void clear() + void clearStack() { - setSize(0); + setStackSize(0); } @@ -707,7 +820,7 @@ public: * Concatenates the top-most n slots on the stack. */ - void concat(int n = 2) + void concatenate(int n = 2) { lua_concat(mState, n); } @@ -717,81 +830,96 @@ public: * Push some values onto the stack. */ - template - void push(T value) + template + Slot push(T value) { lua_pushinteger(mState, lua_Integer(value)); + return top(); } - void push(bool value) + Slot push(bool value) { lua_pushboolean(mState, int(value)); + return top(); } - void push(float value) + Slot push(float value) { lua_pushnumber(mState, (lua_Number)value); + return top(); } - void push(double value) + Slot push(double value) { lua_pushnumber(mState, (lua_Number)value); + return top(); } - void push(const std::string& value) + Slot push(const std::string& value) { lua_pushlstring(mState, value.c_str(), value.length()); + return top(); } - void push(const char* value) + Slot push(const char* value) { lua_pushstring(mState, value); + return top(); } - void push(const char* value, size_t length) + Slot push(const char* value, size_t length) { lua_pushlstring(mState, value, length); + return top(); } - void push(const Function& function) + Slot push(const Function& function) { mFunctions.push_back(function); - lua_pushlightuserdata(mState, (void*)&mFunctions.back()); lua_pushcclosure(mState, dispatchCall, 1); + return top(); } - void push(void* data) + Slot push(void* data) { lua_pushlightuserdata(mState, data); + return top(); } - void pushNil() + Slot pushNil() { lua_pushnil(mState); + return top(); } - void pushFromThread(Script& thread, int n) + Slot pushFromThread(Script& thread, int n) { lua_xmove(thread.mState, mState, n); + return top(); } - Result pushCode(const std::string& filename) + Slot pushCode(const std::string& file, Result& result) { - return (Result)luaL_loadfile(mState, filename.c_str()); + result = (Result)luaL_loadfile(mState, file.c_str()); + return top(); } - Result pushCode(const std::string& name, const char* buffer, - size_t size) + Slot pushCode(const std::string& name, const char* buffer, + size_t size, Result& result) { - return (Result)luaL_loadbuffer(mState, buffer, size, name.c_str()); + result = (Result)luaL_loadbuffer(mState, + buffer, size, name.c_str()); + return top(); } - void* pushNewData(size_t size) + Slot pushNewData(void*& data, size_t size) { - return lua_newuserdata(mState, size); + data = lua_newuserdata(mState, size); + return top(); } - void pushNewTable() + Slot pushNewTable(int narr = 0, int nrec = 0) { - lua_newtable(mState); + lua_createtable(mState, narr, nrec); + return top(); } @@ -824,22 +952,7 @@ public: Slot operator [] (int index) const { - return Slot(mState, index); - } - - - /** - * Getting and setting fields of a table. - */ - - void pushField(const std::string& field, int index = GLOBALS) const - { - lua_getfield(mState, index, field.c_str()); - } - - void set(const std::string& field, int index = GLOBALS) - { - lua_setfield(mState, index, field.c_str()); + return Slot(*this, index); } @@ -920,8 +1033,10 @@ inline std::ostream& operator << (std::ostream& stream, } else if (slot.isBoolean()) { - if (slot) stream << "true"; - else stream << "false"; + bool value; + slot.get(value); + if (value) stream << "true"; + else stream << "false"; } else if (slot.isNil()) { @@ -929,7 +1044,7 @@ inline std::ostream& operator << (std::ostream& stream, } else { - stream << slot.getTypeName() << " (" << slot.getIdentifier() << ")"; + stream << slot.typeName() << " (" << slot.id() << ")"; } return stream;