Polo.mcpp Source CodeΒΆ

~import std::exception;
~import boost::format;
~import Macaroni::Lua::LuaClass;
~import Macaroni::Lua::LuaGlueCode;
~import Macaroni::Lua::LuaFunction;
~import Macaroni::Lua::LuaOperator;
~import Macaroni::Lua::LuaProperty;
~import std::string;
~import Macaroni::Tests::Lua::Polo;
~import Macaroni::Tests::Lua::PoloPtr;
~import Macaroni::Tests::Lua::PoloList;
~import Macaroni::Tests::Lua::PoloListPtr;
~import boost::intrusive_ptr;

// Plain old Lua Object

namespace Macaroni::Tests::Lua
{
    class PoloException : public exception
    {
            public virtual const char * what() const throw()
            {
                    return  "Wait, I didn't notice when you set it "
                                    "originally, but now I realize that Suzy is a variant of "
                                    "Sue.  Get ready for one freakin' mother of an exception, "
                                    "bubb.";
            }
    };

    class SueNameException : public exception
    {
            public virtual const char * what() const throw()
            {
                    return  "No! Not Sue, I hate that name.";
            }
    };

    class Polo {};

    typedef intrusive_ptr<Polo> PoloPtr
            @LuaClass [ SameAsNode = Polo ]
    ;

    class Polo
      @LuaClass
      [
        ReferenceType = PoloPtr,
      ]
    {
            ~import Macaroni::Tests::Lua::PoloException;
            ~import Macaroni::Tests::Lua::SueNameException;
            private string name;
            private int refCount;

            public Polo()
            : name(""),
              refCount(0)
            {
            }

            public static PoloPtr Create(const string name)
            @LuaFunction "Create"
            {
                    PoloPtr rtn(new Polo());
                    rtn->name = name;
                    return rtn;
            }


            public inline int GetReferenceCount() const
            @LuaFunction "GetReferenceCount"
            {
                    return refCount;
            }

            public ~friend ~global void intrusive_ptr_add_ref(Polo * p)
            {
                    p->refCount ++;
            }

            //friend intrusive_ptr_add_ref;

            public ~friend ~global void intrusive_ptr_release(Polo * p)
            {
                    p->refCount --;
                    if (p->refCount <= 0)
                    {
                            delete p;
                    }
            }

            // friend intrusive_ptr_release;

            public void NonLuaFunction(string & something)
            {
                    something = "This should not be called from Lua...";
            }

            public const string & GetName() const
            @LuaFunction "GetName"
            @LuaProperty ={Name}
            {
                    if (name == "Suzy")
                    {
                            throw PoloException();
                    }
                    return name;
            }

            public void SetName(const string & newName)
            @LuaFunction "SetName"
            @LuaProperty "Name"
            {
                    if (newName == "Sue")
                    {
                            throw SueNameException();
                    }
                    this->name = newName;
            }

            public static string PointlessStaticFunctionGet(const PoloPtr & ptr)
            @LuaFunction "PointlessStaticFunctionGet"
            {
                    return ptr->GetName();
            }

            public static void PointlessStaticFunctionSet(const PoloPtr & ptr,
                                                          string name)
            @LuaFunction "PointlessStaticFunctionSet"
            {
                    ptr->SetName(name);
            }

            public string ToString()
            @LuaOperator "__tostring"
            {
                    return str(boost::format("%s, reference count=%d")
                                   % name % refCount);
            }

            public bool operator==(const Polo & rhs) const
                    @LuaOperator "__eq"
            {
                    return this->name == rhs.name;
            }

            private static void __internal()
                    @LuaFunction "PrintLuaStackTimesRef"
                    @LuaGlueCode ={
                            PoloPtr & instance = PoloLuaMetaData::GetInstance(L, 1);
                            const auto count = lua_gettop(L)
                                               * instance->GetReferenceCount();
                            lua_pushinteger(L, count);
                            return 1;
                    }
            {
                    // Do not call!
                    throw std::exception();
            }

            public static PoloListPtr CreateList()
                    @LuaFunction "CreateList"
            {
                    PoloListPtr ptr(new PoloList());
                    ptr->push_back(Create("a"));
                    ptr->push_back(Create("b"));
                    ptr->push_back(Create("c"));
                    return ptr;
            }

    };

} //end ns