]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Script.hh
reformatting
[chaz/yoink] / src / Moof / Script.hh
index f67c62c20d27f67a09732650d4cdb4adb70b88c4..9af54402ae74846e88418531d8b679e71595c02d 100644 (file)
@@ -1,43 +1,27 @@
 
-/*******************************************************************************
-
- Copyright (c) 2009, Charles McGarvey
- All rights reserved.
- Redistribution   and   use  in  source  and  binary  forms,  with  or  without
- modification, are permitted provided that the following conditions are met:
-   * Redistributions  of  source  code  must retain the above copyright notice,
-     this list of conditions and the following disclaimer.
-   * Redistributions  in binary form must reproduce the above copyright notice,
-     this  list of conditions and the following disclaimer in the documentation
-     and/or other materials provided with the distribution.
- THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*******************************************************************************/
+/*]  Copyright (c) 2009-2010, Charles McGarvey  [**************************
+**]  All rights reserved.
+*
+* vi:ts=4 sw=4 tw=75
+*
+* Distributable under the terms and conditions of the 2-clause BSD license;
+* see the file COPYING for a complete text of the license.
+*
+**************************************************************************/
 
 #ifndef _MOOF_SCRIPT_HH_
 #define _MOOF_SCRIPT_HH_
 
 /**
  * @file Script.hh
- * A thin wrapper over Lua.  This is not meant as a complicated binding package
- * between C++ and Lua.  It does not try to make the boundary invisible.  It
- * does not hide the concept of the Lua stack, but rather provides that
- * mechanism with a certain level of abstraction while also providing a cleaner,
- * more consistent API.
+ * A thin wrapper over Lua.  This is not meant as a complicated binding
+ * package between C++ and Lua.  It does not try to make the boundary
+ * invisible.  It does not hide the concept of the Lua stack, but rather
+ * provides that mechanism with a certain level of abstraction while also
+ * providing a cleaner, more consistent API.
  */
 
+#include <iostream>
 #include <list>
 #include <map>
 #include <string>
@@ -46,7 +30,6 @@
 #include <boost/bind.hpp>
 #include <boost/function.hpp>
 #include <boost/shared_ptr.hpp>
-
 #include <lua.hpp>
 
 #include <Moof/Log.hh>
@@ -79,7 +62,7 @@ public:
                THREAD                  = LUA_TTHREAD
        };
 
-       enum Status
+       enum Result
        {
                SUCCESS                 = 0,
                YIELD                   = LUA_YIELD,
@@ -98,72 +81,87 @@ public:
        };
 
        /**
-        * This is the most prominent abstraction on top of the standard Lua API.
-        * A Value object represents a value on the stack.  More specifically, it
-        * represents a position on the stack.  The distinction is only important
-        * when values are moved around on the stack or if the Value represents a
-        * negative index on the stack (the value of which will change as things are
-        * pushed onto and popped from the stack).
+        * This is the most prominent abstraction on top of the standard Lua
+        * API.  A Slot object represents a value on the stack.  More
+        * specifically, it represents a position on the stack.  The
+        * distinction is only important when objects are moved around on the
+        * stack or if the Slot represents a negative index on the stack (the
+        * value of which will change as things are pushed onto and popped from
+        * the stack).
         */
 
-       struct Value
+       struct Slot
        {
                /**
-                * You have direct access to the index of the value on the stack being
-                * represented.
+                * You have direct access to the index of the value on the stack
+                * being represented.
                 */
 
                int index;
 
 
                /**
-                * A default-constructed Value is invalid until a valid Value is
+                * A default-constructed Slot is invalid until a valid Slot is
                 * assigned to it.  The only method that should be called on such a
-                * Value is isValid(), otherwise chaos may ensue.  In this case, the
-                * Value will be invalid even if index is manually changed to a valid
-                * index.  You have to index the script itself to get a valid Value.
+                * 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.
                 */
-               Value(lua_State* s = 0, int i = 0) :
+               Slot(lua_State* s = 0, int i = 0) :
                        index(i),
                        mState(s) {}
 
                /**
-                * A copied value presently points to the same value, except the real
-                * index is used.  That means that if a value that refers to a frame
-                * referenced from the top of the stack will have its normalized index
-                * copied into the new value object.
+                * A copied value presently points to the same value, except the
+                * real index is used.  That means that if a value that refers to a
+                * frame referenced from the top of the stack will have its
+                * normalized index copied into the new value object.
                 */
 
-               Value(const Value& copy) :
+               Slot(const Slot& copy) :
                        index(copy.getRealIndex()),
                        mState(copy.mState) {}
 
 
                // check the type of the value
-               bool isBoolean() const   { return (bool)lua_isboolean(mState, index); }
-               bool isFunction() const  { return (bool)lua_isfunction(mState, index); }
-               bool isNil() const       { return (bool)lua_isnil(mState, index); }
-               bool isNone() const      { return (bool)lua_isnone(mState, index); }
-               bool isValid() const     { return mState != 0 && !isNone(); }
-               bool isNoneOrNil() const { return (bool)lua_isnoneornil(mState, index); }
-               bool isNumber() const    { return (bool)lua_isnumber(mState, index); }
-               bool isString() const    { return (bool)lua_isstring(mState, index); }
-               bool isTable() const     { return (bool)lua_istable(mState, index); }
-               bool isThread() const    { return (bool)lua_isthread(mState, index); }
-               bool isData() const      { return (bool)lua_isuserdata(mState, index); }
-               bool isLightData() const { return (bool)lua_islightuserdata(mState, index); }
+               bool isBoolean() const
+               { return (bool)lua_isboolean(mState, index); }
+               bool isFunction() const
+               { return (bool)lua_isfunction(mState, index); }
+               bool isNil() const
+               { return (bool)lua_isnil(mState, index); }
+               bool isNone() const
+               { return (bool)lua_isnone(mState, index); }
+               bool isValid() const
+               { return mState != 0 && !isNone(); }
+               bool isNoneOrNil() const
+               { return (bool)lua_isnoneornil(mState, index); }
+               bool isNumber() const
+               { return (bool)lua_isnumber(mState, index); }
+               bool isString() const
+               { return (bool)lua_isstring(mState, index); }
+               bool isTable() const
+               { return (bool)lua_istable(mState, index); }
+               bool isThread() const
+               { return (bool)lua_isthread(mState, index); }
+               bool isData() const
+               { return (bool)lua_isuserdata(mState, index); }
+               bool isLightData() const
+               { return (bool)lua_islightuserdata(mState, index); }
 
                /**
-                * Check the value and throw an error if its the wrong type.  There's a
-                * little caveat: This method never returns because it does a long jump.
-                * Consequently, constructed C++ objects which exist on the stack
-                * between the current frame and some lua function will not be
-                * destructed.  That's not a problem for objects that only exist on the
-                * stack, but any objects that allocate memory on the heap (such as
-                * containers or strings) will leak.  Therefore, you should only call
-                * this method after cleaning up such objects.  The best thing to do for
-                * defining functions is to simply check all the parameters at the
-                * get-go before any C++ objects are even constructed.
+                * Check the value and throw an error if its the wrong type.
+                * There's a little caveat: This method never returns because it
+                * does a long jump.  Consequently, constructed C++ objects which
+                * exist on the stack between the current frame and some lua
+                * function will not be destructed.  That's not a problem for
+                * objects that only exist on the stack, but any objects that
+                * allocate memory on the heap (such as containers or strings) will
+                * leak.  Therefore, you should only call this method after
+                * cleaning up such objects.  The best thing to do for defining
+                * functions is to simply check all the parameters at the get-go
+                * before any C++ objects are even constructed.
                 */
 
                void requireType(Type type) const
@@ -180,42 +178,42 @@ public:
                }
 
 
-               Value& requireBoolean()
+               Slot& requireBoolean()
                {
                        if (!isBoolean()) luaL_typerror(mState, index, "boolean");
                        return *this;
                }
-               Value& requireNumber()
+               Slot& requireNumber()
                {
                        if (!isNumber()) luaL_typerror(mState, index, "number");
                        return *this;
                }
-               Value& requireString()
+               Slot& requireString()
                {
                        if (!isString()) luaL_typerror(mState, index, "string");
                        return *this;
                }
-               Value& requireTable()
+               Slot& requireTable()
                {
                        if (!isTable()) luaL_typerror(mState, index, "table");
                        return *this;
                }
-               Value& requireFunction()
+               Slot& requireFunction()
                {
                        if (!isFunction()) luaL_typerror(mState, index, "function");
                        return *this;
                }
-               Value& requireData()
+               Slot& requireData()
                {
                        if (!isData()) luaL_typerror(mState, index, "data");
                        return *this;
                }
-               Value& requireNil()
+               Slot& requireNil()
                {
                        if (!isNil()) luaL_typerror(mState, index, "nil");
                        return *this;
                }
-               Value& requireThread()
+               Slot& requireThread()
                {
                        if (!isThread()) luaL_typerror(mState, index, "thread");
                        return *this;
@@ -242,7 +240,8 @@ public:
 
 
                /**
-                * Get the length of the value according to the definition given by Lua.
+                * Get the length of the value according to the definition given by
+                * Lua.
                 */
 
                size_t getLength() const
@@ -258,7 +257,8 @@ public:
 
 
                /**
-                * Get a pointer value (for userdata, tables, threads, and functions).
+                * Get a pointer value (for userdata, tables, threads, and
+                * functions).
                 */
 
                const void* getIdentifier() const
@@ -267,27 +267,27 @@ public:
                }
 
 
-               bool operator == (const Value& rhs) const
+               bool operator == (const Slot& rhs) const
                {
                        return (bool)lua_equal(mState, index, rhs.index);
                }
-               bool operator != (const Value& rhs) const
+               bool operator != (const Slot& rhs) const
                {
                        return !(*this == rhs);
                }
-               bool operator < (const Value& rhs) const
+               bool operator < (const Slot& rhs) const
                {
                        return (bool)lua_lessthan(mState, index, rhs.index);
                }
-               bool operator <= (const Value& rhs) const
+               bool operator <= (const Slot& rhs) const
                {
                        return *this < rhs || *this == rhs;
                }
-               bool operator > (const Value& rhs) const
+               bool operator > (const Slot& rhs) const
                {
                        return !(*this <= rhs);
                }
-               bool operator >= (const Value& rhs) const
+               bool operator >= (const Slot& rhs) const
                {
                        return !(*this < rhs);
                }
@@ -296,7 +296,7 @@ public:
                        return (bool)lua_toboolean(mState, index);
                }
 
-               Value& operator = (const Value& rhs)
+               Slot& operator = (const Slot& rhs)
                {
                        rhs.pushCopy();
                        replaceWithTop();
@@ -367,7 +367,7 @@ public:
 
                        array.clear();
 
-                       Value   value(mState, -1);
+                       Slot    value(mState, -1);
                        int             realIndex = getRealIndex();
 
                        bool done = false;
@@ -392,8 +392,8 @@ public:
 
                        dictionary.clear();
 
-                       Value   key(mState, -2);
-                       Value   value(mState, -1);
+                       Slot    key(mState, -2);
+                       Slot    value(mState, -1);
                        int             realIndex = getRealIndex();
 
                        lua_pushnil(mState);
@@ -413,7 +413,6 @@ public:
                }
 
 
-
                /**
                 * Copy the value and push the copy to the stack.
                 */
@@ -438,8 +437,8 @@ public:
                }
 
                /**
-                * Inserts the top-most value on the stack at position index, shifting other
-                * values as needed.
+                * Inserts the top-most value on the stack at position index,
+                * shifting other values as needed.
                 */
 
                void insertTopHere()
@@ -498,7 +497,7 @@ public:
                if (mState) destroy();
                mState = luaL_newstate();
                lua_pushlightuserdata(mState, this);
-               lua_setfield(mState, LUA_REGISTRYINDEX, "_script_obj");
+               lua_setfield(mState, LUA_REGISTRYINDEX, "Script_hh_Object");
        }
 
 
@@ -571,14 +570,14 @@ public:
        }
 
 
-       Status doString(const std::string& commands)
+       Result doString(const std::string& commands)
        {
-               return (Status)luaL_dostring(mState, commands.c_str());
+               return (Result)luaL_dostring(mState, commands.c_str());
        }
 
-       Status doFile(const std::string& file)
+       Result doFile(const std::string& file)
        {
-               return (Status)luaL_dofile(mState, file.c_str());
+               return (Result)luaL_dofile(mState, file.c_str());
        }
 
 
@@ -596,14 +595,14 @@ public:
                lua_pushthread(mState);
        }
 
-       Status resume(int nargs)
+       Result resume(int nargs)
        {
-               return (Status)lua_resume(mState, nargs);
+               return (Result)lua_resume(mState, nargs);
        }
 
-       Status getStatus() const
+       Result getStatus() const
        {
-               return (Status)lua_status(mState);
+               return (Result)lua_status(mState);
        }
 
        int yield(int results)
@@ -618,13 +617,14 @@ public:
 
 
        /**
-        * Throw an error with the value at the top of the stack.  This method never
-        * returns because it does a long jump.  Consequently, constructed C++
-        * objects  which exist on the stack between the current frame and some lua
-        * function will not be destructed.  That's not a problem for objects that
-        * only exist on the stack, but any objects that allocate memory on the heap
-        * (such as containers or strings) will leak.  Therefore, you should only
-        * call this method after cleaning up such objects.
+        * Throw an error with the value at the top of the stack.  This method
+        * never returns because it does a long jump.  Consequently,
+        * constructed C++ objects  which exist on the stack between the
+        * current frame and some lua function will not be destructed.  That's
+        * not a problem for objects that only exist on the stack, but any
+        * objects that allocate memory on the heap (such as containers or
+        * strings) will leak.  Therefore, you should only call this method
+        * after cleaning up such objects.
         */
 
        void throwError()
@@ -637,28 +637,29 @@ public:
         * Get significant values.
         */
 
-       Value getGlobalTable() const
+       Slot getGlobalTable() const
        {
-               return Value(mState, GLOBALS);
+               return Slot(mState, GLOBALS);
        }
 
-       Value getRegistryTable() const
+       Slot getRegistryTable() const
        {
-               return Value(mState, REGISTRY);
+               return Slot(mState, REGISTRY);
        }
 
-       Value getEnvironmentTable() const
+       Slot getEnvironmentTable() const
        {
-               return Value(mState, ENVIRONMENT);
+               return Slot(mState, ENVIRONMENT);
        }
 
-       Value getTop() const
+       Slot getTop() const
        {
-               return Value(mState, lua_gettop(mState));
+               return Slot(mState, lua_gettop(mState));
        }
 
        /**
-        * Get the size of the stack; this is also the index of the top-most value.
+        * Get the size of the stack; this is also the index of the top-most
+        * value.
         */
 
        int getSize() const
@@ -678,11 +679,11 @@ public:
 
 
        /**
-        * Makes sure there is at least extra more places on the stack.  Returns
-        * false if space couldn't be created.  Just like with the regular Lua API,
-        * you are responsible to make sure the stack is big enough to hold whatever
-        * you want to push on it.  This is usually only an issue if you're pushing
-        * stuff in a loop.
+        * Makes sure there is at least extra more places on the stack.
+        * Returns false if space couldn't be created.  Just like with the
+        * regular Lua API, you are responsible to make sure the stack is big
+        * enough to hold whatever you want to push on it.  This is usually
+        * only an issue if you're pushing stuff in a loop.
         */
 
        bool checkStack(int extra)
@@ -692,10 +693,10 @@ public:
 
 
        /**
-        * Concatenates the top-most n values on the stack.
+        * Concatenates the top-most n slots on the stack.
         */
 
-       void concat(int n)
+       void concat(int n = 2)
        {
                lua_concat(mState, n);
        }
@@ -761,14 +762,15 @@ public:
                lua_xmove(thread.mState, mState, n);
        }
 
-       Status pushCode(const std::string& filename)
+       Result pushCode(const std::string& filename)
        {
-               return (Status)luaL_loadfile(mState, filename.c_str());
+               return (Result)luaL_loadfile(mState, filename.c_str());
        }
 
-       Status pushCode(const std::string& name, const char* buffer, size_t size)
+       Result pushCode(const std::string& name, const char* buffer,
+                                       size_t size)
        {
-               return (Status)luaL_loadbuffer(mState, buffer, size, name.c_str());
+               return (Result)luaL_loadbuffer(mState, buffer, size, name.c_str());
        }
 
        void* pushNewData(size_t size)
@@ -784,14 +786,14 @@ public:
 
        /**
         * Call a function on the stack.  The correct procedure is to push a
-        * function onto the stack followed by nargs arguments.  This method will
-        * pop them off upon return, leaving up to nresults return values (default
-        * is any number of return values, depending on the callee).
+        * function onto the stack followed by nargs arguments.  This method
+        * will pop them off upon return, leaving up to nresults return values
+        * (default is any number of return values, depending on the callee).
         */
 
-       Status call(int nargs, int nresults = LUA_MULTRET)
+       Result call(int nargs = 0, int nresults = LUA_MULTRET)
        {
-               return (Status)lua_pcall(mState, nargs, nresults, 0);
+               return (Result)lua_pcall(mState, nargs, nresults, 0);
        }
 
 
@@ -806,12 +808,12 @@ public:
 
 
        /**
-        * Index into the stack to get a Value.
+        * Index into the stack to get a Slot.
         */
 
-       Value operator [] (int index) const
+       Slot operator [] (int index) const
        {
-               return Value(mState, index);
+               return Slot(mState, index);
        }
 
 
@@ -819,7 +821,7 @@ public:
         * Getting and setting fields of a table.
         */
 
-       void get(const std::string& field,  int index = GLOBALS) const
+       void pushField(const std::string& field, int index = GLOBALS) const
        {
                lua_getfield(mState, index, field.c_str());
        }
@@ -878,7 +880,7 @@ private:
                const Function* function = (const Function*)lua_touserdata(state,
                                lua_upvalueindex(1));
 
-               lua_getfield(state, LUA_REGISTRYINDEX, "_script_obj");
+               lua_getfield(state, LUA_REGISTRYINDEX, "Script_hh_Object");
                Script* script = (Script*)lua_touserdata(state, -1);
                lua_pop(state, 1);
 
@@ -896,9 +898,34 @@ private:
 };
 
 
+inline std::ostream& operator << (std::ostream& stream,
+               const Script::Slot& slot)
+{
+       if (slot.isString())
+       {
+               std::string str;
+               slot.get(str);
+               stream << str;
+       }
+       else if (slot.isBoolean())
+       {
+               if (slot) stream << "true";
+               else      stream << "false";
+       }
+       else if (slot.isNil())
+       {
+               stream << "nil";
+       }
+       else
+       {
+               stream << slot.getTypeName() << " (" << slot.getIdentifier() << ")";
+       }
+
+       return stream;
+}
+
+
 } // namespace Mf
 
 #endif // _MOOF_SCRIPT_HH_
 
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-
This page took 0.035776 seconds and 4 git commands to generate.