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<Script&>(s)) {}
/**
* A copied value presently points to the same value, except the
* 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.
* 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;
}
* 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));
}
* 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;
}
* 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
{
{
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 <typename T>
+ template <class T>
bool get(T& value) const
{
if (isNumber())
{
- value = (T)lua_tointeger(mState, index);
+ value = (T)lua_tointeger(mScript.mState, index);
return true;
}
return false;
{
if (isNumber())
{
- value = (float)lua_tonumber(mState, index);
+ value = (float)lua_tonumber(mScript.mState, index);
return true;
}
return false;
{
if (isNumber())
{
- value = (double)lua_tonumber(mState, index);
+ value = (double)lua_tonumber(mScript.mState, index);
return true;
}
return false;
{
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 <typename T>
+ bool get(void*& value) const
+ {
+ if (isData())
+ {
+ value = lua_touserdata(mScript.mState, index);
+ return true;
+ }
+ return false;
+ }
+
+ template <class T>
bool get(std::vector<T>& 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 <typename T>
+ template <class T>
bool get(std::map<std::string,T>& 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))
T v;
if (value.get(v)) dictionary[k] = v;
}
- lua_pop(mState, 1);
+ mScript.pop();
}
- lua_pop(mState, 1);
+ mScript.pop();
return true;
}
* Get the value of a field from the table.
*/
- template <typename T, typename V>
+ template <class T, class V>
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 <class T, class V>
+ 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 <class T>
+ void setField(const std::string& field, T value)
+ {
+ setField(field.c_str(), value);
+ }
+ template <class T>
+ 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 <class T>
+ 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);
}
/**
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 <class T>
+ 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;
};
{
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);
}
* after cleaning up such objects.
*/
- void throwError()
+ void raise()
{
lua_error(mState);
}
* 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());
}
/**
* 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);
}
* Concatenates the top-most n slots on the stack.
*/
- void concat(int n = 2)
+ void concatenate(int n = 2)
{
lua_concat(mState, n);
}
* Push some values onto the stack.
*/
- template <typename T>
- void push(T value)
+ template <class T>
+ 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();
}
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);
}
}
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())
{
}
else
{
- stream << slot.getTypeName() << " (" << slot.getIdentifier() << ")";
+ stream << slot.typeName() << " (" << slot.id() << ")";
}
return stream;