~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