diff --git a/Client/App/App.vcproj b/Client/App/App.vcproj
index 69a3788c..1524efbb 100644
--- a/Client/App/App.vcproj
+++ b/Client/App/App.vcproj
@@ -1,1321 +1,1813 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/App/include/lua/LuaBridge.h b/Client/App/include/lua/LuaBridge.h
new file mode 100644
index 00000000..b6f3db71
--- /dev/null
+++ b/Client/App/include/lua/LuaBridge.h
@@ -0,0 +1,211 @@
+#pragma once
+#include "lua.h"
+#include "lauxlib.h"
+#include "boost/shared_ptr.hpp"
+#include "util/Utilities.h"
+#include "G3D/format.h"
+#include
+
+namespace RBX
+{
+ namespace Lua
+ {
+ template
+ class Bridge
+ {
+ protected:
+ static const char* className;
+
+ public:
+ static T* pushNewObject(lua_State* L)
+ {
+ T* ptr = static_cast(lua_newuserdata(L, sizeof(T)));
+ new(ptr) T();
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+ return ptr;
+ }
+ static T& getObject(lua_State* L, size_t index)
+ {
+ return *static_cast(luaL_checkudata(L, static_cast(index), className));
+ }
+ static void registerClass(lua_State* L)
+ {
+ luaL_newmetatable(L, className);
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, on_index);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, on_newindex);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__gc");
+ lua_pushcfunction(L, on_gc);
+ lua_settable(L, -3);
+
+ if (isComparable)
+ {
+ lua_pushstring(L, "__eq");
+ lua_pushcfunction(L, on_eq);
+ lua_settable(L, -3);
+ }
+
+ lua_pushstring(L, "__tostring");
+ lua_pushcfunction(L, on_tostring);
+ lua_settable(L, -3);
+
+ lua_pop(L, 1);
+ }
+
+ public:
+ template
+ static T* pushNewObject(lua_State* L, Param1Type param1)
+ {
+ T* ptr = static_cast(lua_newuserdata(L, sizeof(T)));
+ new(ptr) T(param1);
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+ return ptr;
+ }
+
+ template
+ static bool getValue(lua_State* L, size_t index, Object& value)
+ {
+ const Object* object = static_cast(lua_touserdata(L,static_cast(index)));
+ if (object)
+ {
+ if (lua_getmetatable(L, static_cast(index)))
+ {
+ luaL_getmetatable(L, className);
+ if (lua_rawequal(L, -1, -2))
+ {
+ lua_pop(L, 2);
+ value = *object;
+ return true;
+ }
+ }
+ else
+ {
+ lua_pop(L, 1);
+ }
+ }
+
+ return false;
+ }
+
+ protected:
+ static int on_index(lua_State* L)
+ {
+ const char* name = luaL_checkstring(L, 2);
+ T& object = getObject(L, 1);
+ return on_index(object, name, L);
+ }
+ static int on_index(const T& object, const char* name, lua_State* L);
+ static int on_newindex(lua_State* L)
+ {
+ // TODO: function return not matching
+ const char* name = luaL_checkstring(L, 2);
+ T& object = getObject(L, 1);
+ on_newindex(object, name, L);
+ return 0;
+ }
+ static void on_newindex(T& object, const char* name, lua_State* L)
+ {
+ throw std::runtime_error(G3D::format("%s cannot be assigned to", name));
+ }
+ static int on_tostring(lua_State* L)
+ {
+ T& object = getObject(L, 1);
+ return on_tostring(object, L);
+ }
+ static int on_tostring(const T& object, lua_State* L)
+ {
+ std::string name = StringConverter::convertToString(object);
+ lua_pushstring(L, name.c_str());
+ return 1;
+ }
+ static int on_gc(lua_State* L)
+ {
+ T& object = getObject(L, 1);
+ object.~T();
+ return 0;
+ }
+ static int on_eq(lua_State* L)
+ {
+ lua_pushboolean(L, getObject(L, 1) == getObject(L, 2));
+ return 1;
+ }
+ };
+
+ template
+ class SharedPtrBridge : protected Bridge, false>
+ {
+ public:
+ static void registerClass(lua_State* L)
+ {
+ Bridge, false>::registerClass(L);
+ }
+ static void registerClassLibrary(lua_State* L)
+ {
+ lua_pushlightuserdata(L, push);
+ newweaktable(L, "v");
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ }
+ static void push(lua_State* L, boost::shared_ptr instance)
+ {
+ if (!instance)
+ {
+ lua_pushnil(L);
+ }
+ else
+ {
+ lua_gettop(L);
+ lua_pushlightuserdata(L, push);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ lua_pushlightuserdata(L, instance.get());
+ lua_rawget(L, -2);
+
+ if (lua_type(L, -1) == LUA_TNIL)
+ {
+ lua_pop(L, 1);
+ pushNewObject(L, instance);
+ lua_pushlightuserdata(L, instance.get());
+ lua_pushvalue(L, -2);
+ lua_rawset(L, -4);
+ }
+
+ lua_remove(L, -2);
+ }
+ }
+ static boost::shared_ptr getPtr(lua_State* L, size_t index)
+ {
+ // TODO: check match for T=boost::shared_ptr
+ // when security is implemented
+
+ if (lua_type(L, static_cast(index)) == LUA_TNIL)
+ {
+ return boost::shared_ptr();
+ }
+ else
+ {
+ return getObject(L, index);
+ }
+ }
+
+ public:
+ template
+ static bool getPtr(lua_State* L, size_t index, ValueType& value)
+ {
+ if (lua_type(L, static_cast(index)) == LUA_TNIL)
+ {
+ value = boost::shared_ptr();
+ return 1;
+ }
+
+ return getValue(L, index, value);
+ }
+ };
+ }
+}
diff --git a/Client/App/include/lua/lua.hpp b/Client/App/include/lua/lua.hpp
new file mode 100644
index 00000000..dc270422
--- /dev/null
+++ b/Client/App/include/lua/lua.hpp
@@ -0,0 +1,28 @@
+#pragma once
+#include "lua.h"
+
+namespace RBX
+{
+ namespace Lua
+ {
+ class ScopedPopper
+ {
+ private:
+ int popCount;
+ lua_State* thread;
+
+ public:
+ ScopedPopper(lua_State* thread, int popCount)
+ : popCount(popCount),
+ thread(thread)
+ {
+ }
+ ScopedPopper& operator+=(int);
+ ScopedPopper& operator-=(int);
+ ~ScopedPopper()
+ {
+ lua_pop(thread, popCount);
+ }
+ };
+ }
+}
diff --git a/Client/App/include/reflection/function.h b/Client/App/include/reflection/function.h
index 2dfbf995..0a5d3b6a 100644
--- a/Client/App/include/reflection/function.h
+++ b/Client/App/include/reflection/function.h
@@ -16,6 +16,7 @@ namespace RBX
NeedTrustedCaller = 0,
AnyCaller = 1
};
+
public:
class Arguments
{
@@ -25,32 +26,23 @@ namespace RBX
public:
virtual size_t size() const = 0;
virtual void get(int, Value&) const = 0;
- public:
- //Arguments(const Arguments&);
- Arguments();
- ~Arguments();
- public:
- //Arguments& operator=(const Arguments&);
};
+
public:
typedef Function Describing;
public:
const Security security;
+
protected:
SignatureDescriptor signature;
- public:
- //FunctionDescriptor(const FunctionDescriptor&);
protected:
FunctionDescriptor(ClassDescriptor& classDescriptor, const char* name, Security security);
+
public:
const SignatureDescriptor& getSignature() const;
virtual void execute(DescribedBase*, Arguments&) const = 0;
- public:
- virtual ~FunctionDescriptor();
- public:
- //FunctionDescriptor& operator=(const FunctionDescriptor&);
};
class Function
@@ -60,29 +52,25 @@ namespace RBX
const DescribedBase* instance;
public:
- //Function(const Function&);
+ Function(const Function&);
Function(const FunctionDescriptor&, const DescribedBase*);
- public:
Function& operator=(const Function&);
const Name& getName() const;
- const FunctionDescriptor* getDescriptor() const;
+ const FunctionDescriptor* getDescriptor() const
+ {
+ return descriptor;
+ }
void execute(FunctionDescriptor::Arguments&) const;
};
template
class FuncDesc : public FunctionDescriptor
{
- public:
- //FuncDesc(const FuncDesc&);
protected:
FuncDesc(const char* name, Security security)
: FunctionDescriptor(Class::classDescriptor(), name, security)
{
}
- public:
- virtual ~FuncDesc();
- public:
- //FuncDesc& operator=(const FuncDesc&);
};
}
}
diff --git a/Client/App/include/reflection/member.h b/Client/App/include/reflection/member.h
index ba33aeb6..1bb6be82 100644
--- a/Client/App/include/reflection/member.h
+++ b/Client/App/include/reflection/member.h
@@ -16,8 +16,6 @@ namespace RBX
const Name& category;
const ClassDescriptor& owner;
- public:
- //MemberDescriptor(const MemberDescriptor&);
protected:
MemberDescriptor(const ClassDescriptor& owner, const char* name, const char* category)
: Descriptor(name),
@@ -26,47 +24,72 @@ namespace RBX
{
}
virtual ~MemberDescriptor();
+
public:
bool isMemberOf(const DescribedBase*) const;
bool isMemberOf(const ClassDescriptor&) const;
- //MemberDescriptor& operator=(const MemberDescriptor&);
};
template
class MemberDescriptorContainer
{
public:
- typedef std::vector Collection;
+ typedef std::vector CollectionType;
+ class Collection : public CollectionType
+ {
+ };
public:
class Iterator : public std::iterator
{
private:
DescribedBase* instance;
- typename Collection::const_iterator iter;
+ typename CollectionType::const_iterator iter;
public:
- Iterator(const typename Collection::const_iterator&, DescribedBase*);
+ Iterator(const typename CollectionType::const_iterator& iter, DescribedBase* instance)
+ : instance(instance),
+ iter(iter)
+ {
+ }
+
public:
typename TheDescriptor::Describing operator*() const;
- bool operator==(const Iterator&) const;
- bool operator!=(const Iterator&) const;
+ bool operator==(const Iterator& other) const
+ {
+ return iter == other.iter;
+ }
+ bool operator!=(const Iterator& other) const
+ {
+ return iter != other.iter;
+ }
Iterator operator++(int);
Iterator& operator++();
};
+ public:
class ConstIterator : public std::iterator
{
private:
const DescribedBase* instance;
- typename Collection::const_iterator iter;
+ typename CollectionType::const_iterator iter;
public:
- ConstIterator(const typename Collection::const_iterator&, const DescribedBase*);
+ ConstIterator(const typename CollectionType::const_iterator& iter, const DescribedBase* instance)
+ : instance(instance),
+ iter(iter)
+ {
+ }
public:
typename TheDescriptor::Describing operator*() const;
- bool operator==(const ConstIterator&) const;
- bool operator!=(const ConstIterator&) const;
+ bool operator==(const ConstIterator& other) const
+ {
+ return iter == other.iter;
+ }
+ bool operator!=(const ConstIterator& other) const
+ {
+ return iter != other.iter;
+ }
ConstIterator operator++(int);
ConstIterator& operator++();
const TheDescriptor& getDescriptor() const;
@@ -77,8 +100,6 @@ namespace RBX
std::vector derivedContainers;
MemberDescriptorContainer* base;
- public:
- //MemberDescriptorContainer(const MemberDescriptorContainer&);
protected:
// TODO: check if matches
MemberDescriptorContainer(MemberDescriptorContainer* base)
@@ -93,20 +114,93 @@ namespace RBX
base->derivedContainers.push_back(this);
}
}
+
public:
void declare(TheDescriptor*);
- typename Collection::const_iterator descriptors_begin() const;
- typename Collection::const_iterator descriptors_end() const;
- typename Collection::const_iterator findDescriptor(const Name&) const;
- Iterator findMember(const Name&, DescribedBase*) const;
- ConstIterator findConstMember(const Name&, const DescribedBase*) const;
- Iterator members_begin(DescribedBase*) const;
- ConstIterator members_begin(const DescribedBase*) const;
- Iterator members_end(DescribedBase*) const;
- ConstIterator members_end(const DescribedBase*) const;
+
+ typename CollectionType::const_iterator descriptors_begin() const
+ {
+ return descriptors.begin();
+ }
+ typename CollectionType::const_iterator descriptors_end() const
+ {
+ return descriptors.end();
+ }
+ typename CollectionType::const_iterator findDescriptor(const Name& name) const
+ {
+ size_t posStart = 0;
+ size_t posEnd = descriptors.size();
+
+ if (posEnd)
+ {
+ size_t i;
+ bool found = false;
+
+ do
+ {
+ i = (posStart+posEnd)/2;
+
+ const Name& descName = descriptors[i]->name;
+
+ if (name == descName)
+ {
+ found = true;
+ break;
+ }
+
+ int compare = name.compare(descName);
+
+ if (compare < 0)
+ {
+ posEnd = i;
+ }
+ else
+ {
+ if (compare <= 0)
+ {
+ found = true;
+ break;
+ }
+
+ posStart = i+1;
+ }
+ } while (posStart < posEnd);
+
+ if (found)
+ return descriptors.begin()+i;
+ }
+
+ return descriptors.end();
+ }
+
+ Iterator findMember(const Name& name, DescribedBase* instance) const
+ {
+ return Iterator::Iterator(findDescriptor(name), instance);
+ }
+ ConstIterator findConstMember(const Name& name, const DescribedBase* instance) const
+ {
+ return ConstIterator::ConstIterator(findDescriptor(name), instance);
+ }
+
+ Iterator members_begin(DescribedBase* instance) const
+ {
+ return Iterator::Iterator(descriptors_begin(), instance);
+ }
+ ConstIterator members_begin(const DescribedBase* instance) const
+ {
+ return ConstIterator::ConstIterator(descriptors_begin(), instance);
+ }
+
+ Iterator members_end(DescribedBase* instance) const
+ {
+ return Iterator::Iterator(descriptors_end(), instance);
+ }
+ ConstIterator members_end(const DescribedBase* instance) const
+ {
+ return ConstIterator::ConstIterator(descriptors_end(), instance);
+ }
+
void mergeMembers(const MemberDescriptorContainer*);
- public:
- ~MemberDescriptorContainer() {} // TODO: does not match
public:
static bool compare(const TheDescriptor*, const TheDescriptor*);
diff --git a/Client/App/include/reflection/object.h b/Client/App/include/reflection/object.h
index 68936e5d..43df43fd 100644
--- a/Client/App/include/reflection/object.h
+++ b/Client/App/include/reflection/object.h
@@ -13,24 +13,35 @@ namespace RBX
{
namespace Reflection
{
- class ClassDescriptor : public Descriptor, public MemberDescriptorContainer, public MemberDescriptorContainer, public MemberDescriptorContainer
- {
- public:
- typedef MemberDescriptorContainer PropertyContainer;
- typedef MemberDescriptorContainer SignalContainer;
- typedef MemberDescriptorContainer FunctionContainer;
+ typedef MemberDescriptorContainer PropertyContainer;
+ typedef MemberDescriptorContainer::Iterator PropertyIterator;
+ typedef MemberDescriptorContainer::ConstIterator ConstPropertyIterator;
+
+ typedef MemberDescriptorContainer FunctionContainer;
+ typedef MemberDescriptorContainer::ConstIterator FunctionIterator;
+ typedef MemberDescriptorContainer SignalContainer;
+ typedef MemberDescriptorContainer::Iterator SignalIterator;
+ typedef MemberDescriptorContainer::ConstIterator ConstSignalIterator;
+
+ class ClassDescriptor : public Descriptor,
+ public MemberDescriptorContainer,
+ public MemberDescriptorContainer,
+ public MemberDescriptorContainer
+ {
private:
std::vector derivedClasses;
ClassDescriptor* base;
+
public:
static bool lockedDown;
public:
- //ClassDescriptor(const ClassDescriptor&);
ClassDescriptor(ClassDescriptor& base, const char* name);
+
private:
ClassDescriptor();
+
public:
const ClassDescriptor* getBase() const
{
@@ -44,10 +55,6 @@ namespace RBX
std::vector::const_iterator derivedClasses_end() const;
bool operator==(const ClassDescriptor& other) const;
bool operator!=(const ClassDescriptor& other) const;
- public:
- virtual ~ClassDescriptor();
- public:
- //ClassDescriptor& operator=(const ClassDescriptor&);
public:
static ClassDescriptor& rootDescriptor() // TODO: check
@@ -59,11 +66,6 @@ namespace RBX
class __declspec(novtable) DescribedBase : public SignalSource
{
- public:
- typedef MemberDescriptorContainer MDCProperty;
- typedef MemberDescriptorContainer MDCFunction;
- typedef MemberDescriptorContainer MDCSignal;
-
protected:
const ClassDescriptor* descriptor;
@@ -73,26 +75,76 @@ namespace RBX
ClassDescriptor::lockedDown = true;
descriptor = &ClassDescriptor::rootDescriptor();
}
+
public:
const ClassDescriptor& getDescriptor() const
{
return *descriptor;
}
- MDCProperty::ConstIterator findProperty(const Name&) const;
- MDCProperty::Iterator findProperty(const Name&);
- MDCProperty::Iterator properties_begin();
- MDCProperty::ConstIterator properties_begin() const;
- MDCProperty::Iterator properties_end();
- MDCProperty::ConstIterator properties_end() const;
- MDCFunction::ConstIterator findFunction(const Name&) const;
- MDCFunction::ConstIterator functions_begin() const;
- MDCFunction::ConstIterator functions_end() const;
- MDCSignal::ConstIterator findSignal(const Name&) const;
- MDCSignal::Iterator findSignal(const Name&);
- MDCSignal::Iterator signals_begin();
- MDCSignal::ConstIterator signals_begin() const;
- MDCSignal::Iterator signals_end();
- MDCSignal::ConstIterator signals_end() const;
+
+ // TODO: find iterators don't fully match when inlined (see LuaInstanceBridge.cpp)
+ ConstPropertyIterator findProperty(const Name& name) const
+ {
+ return getDescriptor().PropertyContainer::findConstMember(name, this);
+ }
+ PropertyIterator findProperty(const Name& name)
+ {
+ return getDescriptor().PropertyContainer::findMember(name, this);
+ }
+ PropertyIterator properties_begin()
+ {
+ return getDescriptor().PropertyContainer::members_begin(this);
+ }
+ ConstPropertyIterator properties_begin() const
+ {
+ return getDescriptor().PropertyContainer::members_begin(this);
+ }
+ PropertyIterator properties_end()
+ {
+ return getDescriptor().PropertyContainer::members_end(this);
+ }
+ ConstPropertyIterator properties_end() const
+ {
+ return getDescriptor().PropertyContainer::members_end(this);
+ }
+
+ FunctionIterator findFunction(const Name& name) const
+ {
+ return getDescriptor().FunctionContainer::findConstMember(name, this);
+ }
+ FunctionIterator functions_begin() const
+ {
+ return getDescriptor().FunctionContainer::members_begin(this);
+ }
+ FunctionIterator functions_end() const
+ {
+ return getDescriptor().FunctionContainer::members_end(this);
+ }
+
+ ConstSignalIterator findSignal(const Name& name) const
+ {
+ return getDescriptor().SignalContainer::findConstMember(name, this);
+ }
+ SignalIterator findSignal(const Name& name)
+ {
+ return getDescriptor().SignalContainer::findMember(name, this);
+ }
+ SignalIterator signals_begin()
+ {
+ return getDescriptor().SignalContainer::members_begin(this);
+ }
+ ConstSignalIterator signals_begin() const
+ {
+ return getDescriptor().SignalContainer::members_begin(this);
+ }
+ SignalIterator signals_end()
+ {
+ return getDescriptor().SignalContainer::members_end(this);
+ }
+ ConstSignalIterator signals_end() const
+ {
+ return getDescriptor().SignalContainer::members_end(this);
+ }
public:
static ClassDescriptor& classDescriptor()
diff --git a/Client/App/include/reflection/property.h b/Client/App/include/reflection/property.h
index 2660483f..49a42d21 100644
--- a/Client/App/include/reflection/property.h
+++ b/Client/App/include/reflection/property.h
@@ -22,37 +22,38 @@ namespace RBX
STREAMING = 4,
LEGACY = 0
};
+
public:
typedef Property Describing;
private:
size_t bIsPublic : 1;
size_t bCanStreamWrite : 1;
+
public:
const Type& type;
- public:
- //PropertyDescriptor(const PropertyDescriptor&);
protected:
PropertyDescriptor(ClassDescriptor& classDescriptor, const Type& type, const char* name, const char* category, Functionality flags);
+
public:
bool isPublic() const;
virtual bool isReadOnly() const = 0;
bool canStreamWrite() const;
- bool operator==(const PropertyDescriptor&) const;
+ bool operator==(const PropertyDescriptor& other) const
+ {
+ return this == &other;
+ }
virtual bool equalValues(const DescribedBase*, const DescribedBase*) const = 0;
virtual bool hasStringValue() const = 0;
virtual std::string getStringValue(const DescribedBase*) const = 0;
virtual bool setStringValue(DescribedBase*, const std::string&) const = 0;
XmlElement* write(const DescribedBase*, bool) const;
virtual void read(DescribedBase*, const XmlElement*, IReferenceBinder&) const;
+
private:
virtual void writeValue(const DescribedBase*, XmlElement*) const = 0;
virtual void readValue(DescribedBase*, const XmlElement*, IReferenceBinder&) const = 0;
- public:
- virtual ~PropertyDescriptor();
- public:
- //PropertyDescriptor& operator=(const PropertyDescriptor&);
};
class ConstProperty
@@ -62,7 +63,11 @@ namespace RBX
const DescribedBase* instance;
public:
- //ConstProperty(const ConstProperty&);
+ ConstProperty(const ConstProperty& other)
+ : descriptor(other.descriptor),
+ instance(other.instance)
+ {
+ }
ConstProperty(const PropertyDescriptor& descriptor, const DescribedBase* instance)
: descriptor(&descriptor),
instance(instance)
@@ -78,23 +83,28 @@ namespace RBX
{
return *descriptor; // might be wrong?
}
- //ConstProperty& operator=(const ConstProperty&); // maybe?
+ ConstProperty& operator=(const ConstProperty&);
const Name& getName() const;
bool hasStringValue() const;
std::string getStringValue() const;
XmlElement* write() const;
+
+ public:
+ template
+ T getValue() const;
};
class Property : public ConstProperty
{
public:
- //Property(const Property&);
+ Property(const Property&);
Property(const PropertyDescriptor& descriptor, DescribedBase* instance)
: ConstProperty(descriptor, instance)
{
}
+
public:
- //Property& operator=(const Property&); // maybe?
+ Property& operator=(const Property&);
bool operator==(const Property&) const;
bool operator!=(const Property&) const;
DescribedBase* getInstance() const
@@ -103,6 +113,10 @@ namespace RBX
}
bool setStringValue(const std::string&);
void read(const XmlElement*, IReferenceBinder&);
+
+ public:
+ template
+ void setValue(const T& value);
};
template
@@ -115,20 +129,11 @@ namespace RBX
virtual bool isReadOnly() const = 0;
virtual PropType getValue(const DescribedBase*) const = 0;
virtual void setValue(DescribedBase*, const PropType&) const = 0;
- public:
- //GetSet(const GetSet&);
- GetSet()
- {
- }
- public:
- //GetSet& operator=(const GetSet&);
};
protected:
std::auto_ptr getset;
- public:
- //TypedPropertyDescriptor(TypedPropertyDescriptor&);
protected:
TypedPropertyDescriptor(ClassDescriptor& classDescriptor, const char* name, const char* category, std::auto_ptr getset, Functionality flags)
: PropertyDescriptor(classDescriptor, Type::singleton(), name, category, flags),
@@ -136,6 +141,7 @@ namespace RBX
{
}
TypedPropertyDescriptor(ClassDescriptor&, const Type&, const char*, const char*, std::auto_ptr, Functionality);
+
public:
virtual bool isReadOnly() const;
PropType getValue(const DescribedBase*) const;
@@ -144,13 +150,10 @@ namespace RBX
virtual bool hasStringValue() const;
virtual std::string getStringValue(const DescribedBase*) const;
virtual bool setStringValue(DescribedBase*, const std::string&) const;
+
private:
virtual void readValue(DescribedBase*, const XmlElement*, IReferenceBinder&) const;
virtual void writeValue(const DescribedBase*, XmlElement*) const;
- public:
- virtual ~TypedPropertyDescriptor();
- public:
- //TypedPropertyDescriptor& operator=(TypedPropertyDescriptor&);
};
class RefPropertyDescriptor : public PropertyDescriptor
@@ -158,21 +161,15 @@ namespace RBX
public:
virtual DescribedBase* getRefValue(const DescribedBase*) const = 0;
virtual void setRefValue(DescribedBase*, DescribedBase*) const = 0;
- public:
- //RefPropertyDescriptor(const RefPropertyDescriptor&);
+
protected:
RefPropertyDescriptor(ClassDescriptor& classDescriptor, const Type& type, const char* name, const char* category, Functionality flags)
: PropertyDescriptor(classDescriptor, type, name, category, flags)
{
}
- protected:
virtual bool hasStringValue() const;
virtual std::string getStringValue(const DescribedBase*) const;
virtual bool setStringValue(DescribedBase*, const std::string&) const;
- public:
- virtual ~RefPropertyDescriptor();
- public:
- //RefPropertyDescriptor& operator=(const RefPropertyDescriptor&);
};
class EnumPropertyDescriptor : public PropertyDescriptor
@@ -185,14 +182,9 @@ namespace RBX
virtual bool setIndexValue(DescribedBase*, unsigned) const = 0;
virtual int getEnumValue(const DescribedBase*) const = 0;
virtual bool setEnumValue(DescribedBase*, int) const = 0;
- public:
- //EnumPropertyDescriptor(const EnumPropertyDescriptor&);
+
protected:
EnumPropertyDescriptor(ClassDescriptor&, const EnumDescriptor&, const char*, const char*, Functionality);
- public:
- virtual ~EnumPropertyDescriptor();
- public:
- //EnumPropertyDescriptor& operator=(const EnumPropertyDescriptor&);
};
}
}
diff --git a/Client/App/include/reflection/reflection.h b/Client/App/include/reflection/reflection.h
index ed61eebf..e13c13ff 100644
--- a/Client/App/include/reflection/reflection.h
+++ b/Client/App/include/reflection/reflection.h
@@ -65,23 +65,16 @@ namespace RBX
// helps with constructors
typedef DescribedCreatable Base;
- public:
- //DescribedCreatable(const DescribedCreatable&);
protected:
DescribedCreatable();
+
template
DescribedCreatable(Arg0Type arg0);
- public:
- virtual ~DescribedCreatable();
- public:
- //DescribedCreatable& operator=(const DescribedCreatable&);
};
template
class DescribedNonCreatable : public Reflection::Described>
{
- public:
- //DescribedNonCreatable(const DescribedNonCreatable&);
protected:
DescribedNonCreatable()
: Described()
@@ -93,10 +86,6 @@ namespace RBX
: Described(arg0)
{
}
- public:
- virtual ~DescribedNonCreatable();
- public:
- //DescribedNonCreatable& operator=(const DescribedNonCreatable&);
};
namespace Reflection
@@ -116,7 +105,6 @@ namespace RBX
void (Class::*changed)(const PropertyDescriptor&);
public:
- //BoundPropGetSet(const BoundPropGetSet&);
BoundPropGetSet(BoundProp& desc, PropType (Class::*member), void (Class::*changed)(const PropertyDescriptor&))
: desc(desc),
member(member),
@@ -147,16 +135,19 @@ namespace RBX
};
public:
- //BoundProp(BoundProp&);
template
BoundProp(const char* name, const char* category, PropType (Class::*member), Functionality flags)
: TypedPropertyDescriptor(Class::classDescriptor(), name, category, std::auto_ptr(), flags)
{
getset.reset(new BoundPropGetSet(*this, member, NULL));
}
- virtual ~BoundProp();
- public:
- //BoundProp& operator=(BoundProp&);
+
+ template
+ BoundProp(const char* name, const char* category, PropType (Class::*member), void (Class::*changed)(const PropertyDescriptor&), Functionality flags)
+ : TypedPropertyDescriptor(Class::classDescriptor(), name, category, std::auto_ptr(), flags)
+ {
+ getset.reset(new BoundPropGetSet(*this, member, changed));
+ }
};
// PropDescriptor
@@ -299,8 +290,6 @@ namespace RBX
private:
std::auto_ptr::GetSet> getset;
- public:
- //RefPropDescriptor(RefPropDescriptor&);
public:
virtual bool isReadOnly() const;
ReturnType* getValue(const DescribedBase*) const;
@@ -311,6 +300,7 @@ namespace RBX
virtual void readValue(DescribedBase*, const XmlElement*, IReferenceBinder&) const;
virtual void writeValue(const DescribedBase*, XmlElement*) const;
virtual void assignIDREF(DescribedBase*, const InstanceHandle&) const;
+
public:
template
RefPropDescriptor(char const* name, char const* category, typename GetFunction get, typename SetFunction set, Functionality flags)
@@ -319,9 +309,6 @@ namespace RBX
getset(PropDescriptor::getset(get, set))
{
}
- virtual ~RefPropDescriptor();
- public:
- //RefPropDescriptor& operator=(RefPropDescriptor&);
};
// EnumPropDescriptor
diff --git a/Client/App/include/reflection/signal.h b/Client/App/include/reflection/signal.h
index 96ea802d..029a81b8 100644
--- a/Client/App/include/reflection/signal.h
+++ b/Client/App/include/reflection/signal.h
@@ -13,17 +13,30 @@ namespace RBX
{
namespace Reflection
{
+ typedef std::vector Arguments;
+
class GenericSlotWrapper
{
public:
virtual ~GenericSlotWrapper();
- public:
virtual void execute(const std::vector&) = 0;
+
public:
- //GenericSlotWrapper(const GenericSlotWrapper&);
- GenericSlotWrapper();
+ template
+ static GenericSlotWrapper* create(T);
+ };
+
+ template
+ class TGenericSlotWrapper : public GenericSlotWrapper
+ {
+ private:
+ T slot;
+
+ private:
+ TGenericSlotWrapper(const T&);
+
public:
- //GenericSlotWrapper& operator=(const GenericSlotWrapper&);
+ virtual void execute(const Arguments&);
};
class SignalSource;
@@ -35,22 +48,25 @@ namespace RBX
public:
const SignalDescriptor& descriptor;
- public:
- //SignalInstance(const SignalInstance&);
protected:
SignalInstance(SignalSource* source, const SignalDescriptor& descriptor)
: source(source),
descriptor(descriptor)
{
}
+
public:
virtual ~SignalInstance();
+
public:
SignalSource* getSource()
{
return source;
}
- //SignalInstance& operator=(const SignalInstance&);
+
+ public:
+ template
+ boost::signals::connection connectGeneric(T slot, boost::signals::connect_position pos);
};
class __declspec(novtable) SignalSource
@@ -74,25 +90,23 @@ namespace RBX
public:
void (*signalCreatedHook)(SignalSource*);
+
protected:
SignatureDescriptor signature;
- public:
- //SignalDescriptor(const SignalDescriptor&);
protected:
SignalDescriptor(ClassDescriptor& classDescriptor, const char* name);
+
protected:
SignalInstance* findSignalInstance(const SignalSource* source) const;
+
private:
virtual boost::signals::connection connectGeneric(SignalInstance*, GenericSlotWrapper*, boost::signals::connect_position) const = 0;
virtual SignalInstance* newSignalInstance(SignalSource&) const = 0;
+
public:
boost::shared_ptr getSignalInstance(SignalSource& source) const;
const SignatureDescriptor& getSignature() const;
- public:
- virtual ~SignalDescriptor() {}
- public:
- //SignalDescriptor& operator=(const SignalDescriptor&);
};
class Signal
@@ -102,10 +116,11 @@ namespace RBX
DescribedBase* instance;
public:
- //Signal(const Signal&);
+ Signal(const Signal&);
Signal(const SignalDescriptor&, DescribedBase*);
+
public:
- //Signal& operator=(const Signal&); // maybe?
+ Signal& operator=(const Signal&);
const Name& getName() const;
const SignalDescriptor* getDescriptor() const;
boost::shared_ptr getSignalInstance() const;
@@ -118,29 +133,25 @@ namespace RBX
class TSignalInstance : public SignalInstance, public boost::signal
{
public:
- //TSignalInstance(const TSignalInstance&);
TSignalInstance(SignalSource* source, const SignalDescriptor& descriptor)
: SignalInstance(source, descriptor),
boost::signal()
{
}
- virtual ~TSignalInstance() {}
- public:
- //TSignalInstance& operator=(const TSignalInstance&);
};
- public:
- //TSignalDesc(const TSignalDesc&);
protected:
TSignalDesc(ClassDescriptor& classDescriptor, const char* name)
: SignalDescriptor(classDescriptor, name)
{
}
+
private:
virtual SignalInstance* newSignalInstance(SignalSource& source) const
{
return new TSignalInstance(&source, *this);
}
+
protected:
TSignalInstance* findSig(const SignalSource* source) const
{
@@ -150,6 +161,7 @@ namespace RBX
{
return *(TSignalInstance*)(getSignalInstance(source).get());
}
+
public:
boost::signals::connection connect(SignalSource* source, const boost::slot>& slot)
{
@@ -163,8 +175,6 @@ namespace RBX
TSignalInstance* instance = findSig(source);
return !instance || instance->empty();
}
- virtual ~TSignalDesc() {}
- //TSignalDesc& operator=(const TSignalDesc&);
};
@@ -184,18 +194,12 @@ namespace RBX
boost::shared_ptr wrapper;
public:
- //GenericSlotAdapter(const GenericSlotAdapter&);
GenericSlotAdapter(GenericSlotWrapper*);
+
public:
void operator()();
- public:
- ~GenericSlotAdapter();
- public:
- //GenericSlotAdapter& operator=(const GenericSlotAdapter&);
};
- public:
- //SignalDescImpl(const SignalDescImpl&);
protected:
SignalDescImpl(ClassDescriptor& classDescriptor, const char* name)
: TSignalDesc(classDescriptor, name)
@@ -212,11 +216,6 @@ namespace RBX
protected:
virtual boost::signals::connection connectGeneric(SignalInstance*, GenericSlotWrapper*, boost::signals::connect_position) const;
-
- public:
- virtual ~SignalDescImpl() {}
- public:
- //SignalDescImpl& operator=(const SignalDescImpl&);
};
template
@@ -229,8 +228,8 @@ namespace RBX
boost::shared_ptr wrapper;
public:
- //GenericSlotAdapter(const GenericSlotAdapter&);
GenericSlotAdapter(GenericSlotWrapper*);
+
public:
void operator()(typename FunctionTraits::Arg1Type arg1)
{
@@ -239,14 +238,8 @@ namespace RBX
wrapper->execute(args);
}
- public:
- ~GenericSlotAdapter();
- public:
- //GenericSlotAdapter& operator=(const GenericSlotAdapter&);
};
- public:
- //SignalDescImpl(const SignalDescImpl&);
protected:
SignalDescImpl(ClassDescriptor& classDescriptor, const char* name)
: TSignalDesc(classDescriptor, name)
@@ -263,35 +256,24 @@ namespace RBX
protected:
virtual boost::signals::connection connectGeneric(SignalInstance*, GenericSlotWrapper*, boost::signals::connect_position) const;
-
- public:
- virtual ~SignalDescImpl() {}
- public:
- //SignalDescImpl& operator=(const SignalDescImpl&);
};
template
class SignalDescImpl<2, CallbackSignature> : public TSignalDesc
{
- protected:
+ public:
class GenericSlotAdapter
{
private:
boost::shared_ptr wrapper;
public:
- //GenericSlotAdapter(const GenericSlotAdapter&);
GenericSlotAdapter(GenericSlotWrapper*);
+
public:
void operator()(typename FunctionTraits::Arg1Type arg1, typename FunctionTraits::Arg2Type arg2);
- public:
- ~GenericSlotAdapter();
- public:
- //GenericSlotAdapter& operator=(const GenericSlotAdapter&);
};
- public:
- //SignalDescImpl(const SignalDescImpl&);
protected:
SignalDescImpl(ClassDescriptor& classDescriptor, const char* name)
: TSignalDesc(classDescriptor, name)
@@ -308,18 +290,12 @@ namespace RBX
protected:
virtual boost::signals::connection connectGeneric(SignalInstance*, GenericSlotWrapper*, boost::signals::connect_position) const;
-
- public:
- virtual ~SignalDescImpl() {}
- public:
- //SignalDescImpl& operator=(const SignalDescImpl&);
};
template
class SignalDesc : public SignalDescImpl::ArgCount, CallbackSignature>
{
public:
- //SignalDesc(const SignalDesc&);
SignalDesc(const char* name, const char* arg1name, const char* arg2name)
: SignalDescImpl(Class::classDescriptor(), name)
{
@@ -339,9 +315,6 @@ namespace RBX
: SignalDescImpl(Class::classDescriptor(), name)
{
}
- virtual ~SignalDesc() {}
- public:
- //SignalDesc& operator=(const SignalDesc&);
};
}
}
diff --git a/Client/App/include/reflection/type.h b/Client/App/include/reflection/type.h
index 18a4b09e..2f7c72da 100644
--- a/Client/App/include/reflection/type.h
+++ b/Client/App/include/reflection/type.h
@@ -2,12 +2,15 @@
#include
#include
#include
+#include
#include "reflection/descriptor.h"
namespace RBX
{
namespace Reflection
{
+ typedef std::vector ValueCollection;
+
class Type : public Descriptor
{
public:
@@ -15,11 +18,15 @@ namespace RBX
const Name& tag;
public:
- bool operator==(const Type&) const;
- bool operator!=(const Type&) const;
+ bool operator==(const Type& other) const
+ {
+ return this == &other;
+ }
+ bool operator!=(const Type& other) const
+ {
+ return this != &other;
+ }
- public:
- //Type(const Type&);
protected:
Type(const char* name, const type_info& type, const char* tag) // TODO: check if matches (will only match in a /GS project)
: Descriptor(name),
@@ -33,8 +40,6 @@ namespace RBX
tag(Name::lookup(name))
{
}
- public:
- virtual ~Type() {}
public:
template
@@ -43,17 +48,11 @@ namespace RBX
class RefType : public Type
{
- public:
- //RefType(const RefType&);
private:
RefType(const char* name, const type_info& type)
: Type(name, type, "Ref")
{
}
- public:
- virtual ~RefType() {}
- public:
- //RefType& operator=(const RefType&);
public:
template
@@ -71,38 +70,72 @@ namespace RBX
boost::any value;
public:
- //Value(const Value&);
// TODO: check ctor
Value();
+ // TODO: this is autogenerated
template
Value(typename ValueType& value)
: _type(&Type::singleton()),
value(value)
{
}
+
public:
- Value& operator=(const Value& other)
+ const Type& type() const
{
- this->_type = other._type;
- this->value = other.value;
+ return *_type;
}
- const Type& type() const;
- bool isVoid() const;
- public:
- ~Value() {}
+ bool isVoid() const
+ {
+ // this is a guess
+ return isType();
+ }
+
public:
+ template
+ T cast() const
+ {
+ return boost::any_cast(value);
+ }
+
+ // not in resym but it might exist
+ template
+ T cast()
+ {
+ return boost::any_cast(value);
+ }
+
template
T& convert();
+ template
+ T& genericConvert();
+
+ template
+ T get() const;
+
+ template
+ bool isType() const
+ {
+ return typeid(T) == type().type;
+ }
+
+ template
+ Value& operator=(const T& rhs)
+ {
+ this->_type = &Type::singleton();
+ this->value = rhs;
+ return *this;
+ }
+
+ // TODO: replace all mentions with operator=?
template
void set(const T& value)
{
this->_type = &Type::singleton();
this->value = value;
}
-
- // TODO: definitions for all the template functions
};
class SignatureDescriptor
@@ -115,6 +148,7 @@ namespace RBX
const Type* type;
const Value defaultValue;
+ // TODO: these are all autogenerated
public:
//template
//Item(const char* name)
@@ -134,7 +168,6 @@ namespace RBX
{
}
~Item() {}
- //Item(const Item&);
};
public:
@@ -143,12 +176,10 @@ namespace RBX
public:
void addArgument(const Name& name, const Type& type, const Value& defaultValue);
+
public:
- //SignatureDescriptor(const SignatureDescriptor&);
SignatureDescriptor();
- ~SignatureDescriptor();
- public:
- //SignatureDescriptor& operator=(const SignatureDescriptor&);
+ ~SignatureDescriptor(); // TODO: this is autogenerated
};
}
}
diff --git a/Client/App/include/script/LuaArguments.h b/Client/App/include/script/LuaArguments.h
new file mode 100644
index 00000000..6e6da5a4
--- /dev/null
+++ b/Client/App/include/script/LuaArguments.h
@@ -0,0 +1,239 @@
+#pragma once
+#include "reflection/reflection.h"
+#include "script/ThreadRef.h"
+#include "script/LuaAtomicClasses.h"
+#include "script/LuaInstanceBridge.h"
+#include "lua.h"
+
+namespace RBX
+{
+ namespace Lua
+ {
+ class LuaArguments : public Reflection::FunctionDescriptor::Arguments
+ {
+ private:
+ const int offset;
+ lua_State* L;
+
+ public:
+ LuaArguments(lua_State*, int);
+ virtual size_t size() const
+ {
+ // TODO: check match
+ return lua_gettop(L)-1;
+ }
+ virtual void get(int index, Reflection::Value& value) const
+ {
+ // TODO: check match
+ int pos = index + offset;
+ RBXASSERT(pos > 0);
+ get(L, pos, value);
+ }
+ int push(const Reflection::Value&) const;
+ int pushReturnValue() const;
+
+ public:
+ // TODO: 97.00%
+ static void get(lua_State* L, int luaIndex, Reflection::Value& value)
+ {
+ // (018310) S_BPREL32: [FFFFFF80], Type: 0x11DC, n ; const int
+ // (018320) S_BPREL32: [FFFFFF84], Type: 0x928D, values ; *std::vector / *ValueCollection
+
+ if (luaIndex <= lua_gettop(L))
+ {
+ switch (lua_type(L, luaIndex))
+ {
+ case LUA_TNUMBER:
+ {
+ float rhs = lua_tonumber(L, luaIndex);
+ value = rhs;
+ return;
+ }
+
+ case LUA_TBOOLEAN:
+ {
+ bool rhs = lua_toboolean(L, luaIndex) != 0;
+ value = rhs;
+ return;
+ }
+
+ case LUA_TSTRING:
+ {
+ const char* str = lua_tostring(L, luaIndex);
+ value = std::string(str);
+ return;
+ }
+
+ case LUA_TTABLE:
+ {
+ const int n = static_cast(lua_objlen(L, luaIndex));
+ value = Reflection::ValueCollection(n);
+ Reflection::ValueCollection& values = value.cast();
+
+ if (n >= 1)
+ {
+ int i = 1;
+ do
+ {
+ Reflection::Value& ival = values[i-1];
+ lua_rawgeti(L, luaIndex, i);
+ LuaArguments::get(L, -1, ival);
+ lua_pop(L, 1);
+ i++;
+ } while (i <= n);
+ }
+
+ return;
+ }
+
+ case LUA_TNIL:
+ value = Reflection::Value();
+ break;
+
+ case LUA_TFUNCTION:
+ value = lua_tofunction(L, luaIndex);
+ return;
+
+ case LUA_TUSERDATA:
+ if (CoordinateFrameBridge::getValue(L, luaIndex, value)
+ || Vector3Bridge::getValue(L, luaIndex, value)
+ || Color3Bridge::getValue(L, luaIndex, value)
+ || BrickColorBridge::getValue(L, luaIndex, value)
+ || ObjectBridge::getPtr(L, luaIndex, value))
+ return;
+
+ value = Reflection::Value();
+ break;
+
+ default:
+ value = Reflection::Value();
+ break;
+ }
+ }
+ }
+
+ static int push(const Reflection::Value& value, lua_State* const L)
+ {
+ if (value.isType())
+ return 0;
+
+ if (value.isType())
+ {
+ lua_pushinteger(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ lua_pushboolean(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ lua_pushnumber(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ lua_pushnumber(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ lua_pushfunction(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ lua_pushstring(L, value.cast().c_str());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ Vector3Bridge::pushVector3(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ CoordinateFrameBridge::pushCoordinateFrame(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ Color3Bridge::pushColor3(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ BrickColorBridge::pushNewObject(L, value.cast());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ lua_pushstring(L, value.cast().c_str());
+ return 1;
+ }
+
+ if (value.isType>())
+ {
+ ObjectBridge::push(L, value.cast&>());
+ return 1;
+ }
+
+ if (value.isType>())
+ {
+ ObjectBridge::push(L, value.cast&>());
+ return 1;
+ }
+
+ if (value.isType())
+ {
+ const Reflection::ValueCollection& collection = value.cast();
+ return pushTable(collection.begin(), collection.end(), L);
+ }
+
+ if (value.isType>())
+ {
+ boost::shared_ptr values = value.cast>();
+
+ if (values)
+ {
+ return pushTable(values->begin(), values->end(), L);
+ }
+ else
+ {
+ lua_newtable(L);
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+ public:
+ template
+ static int pushTable(T _First, T _Last, lua_State* const L)
+ {
+ lua_createtable(L, _Last-_First, 0);
+
+ int i = 0;
+ for (; _First != _Last; _First++)
+ {
+ push(*_First, L);
+ lua_rawseti(L, -2, ++i);
+ }
+
+ return 1;
+ }
+ };
+ }
+}
diff --git a/Client/App/include/script/LuaAtomicClasses.h b/Client/App/include/script/LuaAtomicClasses.h
new file mode 100644
index 00000000..d455e610
--- /dev/null
+++ b/Client/App/include/script/LuaAtomicClasses.h
@@ -0,0 +1,205 @@
+#pragma once
+#include "v8datamodel/BrickColor.h"
+#include "lua/LuaBridge.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Vector3.h"
+#include "G3D/Color3.h"
+#include "lauxlib.h"
+
+namespace RBX
+{
+ namespace Lua
+ {
+ class CoordinateFrameBridge : public Bridge
+ {
+ friend class Bridge;
+
+ private:
+ static const luaL_Reg classLibrary[4];
+
+ public:
+ static void registerClassLibrary(lua_State* L)
+ {
+ luaL_register(L, className, classLibrary);
+ lua_pop(L, 1);
+ }
+ static void pushCoordinateFrame(lua_State* L, G3D::CoordinateFrame CF)
+ {
+ pushNewObject(L, CF);
+ }
+
+ private:
+ static int newCoordinateFrame(lua_State* L);
+ static int fromEulerAnglesXYZ(lua_State* L);
+ static int fromAxisAngle(lua_State* L);
+ static int on_add(lua_State* L);
+ static int on_sub(lua_State* L);
+ static int on_mul(lua_State* L);
+ static int on_inverse(lua_State* L);
+ static int on_toWorldSpace(lua_State* L);
+ static int on_toObjectSpace(lua_State* L);
+ static int on_pointToWorldSpace(lua_State* L);
+ static int on_pointToObjectSpace(lua_State* L);
+ static int on_vectorToWorldSpace(lua_State* L);
+ static int on_vectorToObjectSpace(lua_State* L);
+ static int on_toEulerAnglesXYZ(lua_State* L);
+ static int on_components(lua_State* L);
+ };
+
+ class Vector3Bridge : public Bridge
+ {
+ friend class Bridge;
+
+ private:
+ static const luaL_Reg classLibrary[2];
+
+ public:
+ static void registerClassLibrary(lua_State* L)
+ {
+ luaL_register(L, className, classLibrary);
+ lua_pop(L, 1);
+ }
+ static void pushVector3(lua_State* L, G3D::Vector3 color)
+ {
+ pushNewObject(L, color);
+ }
+
+ private:
+ static int newVector3(lua_State* L);
+ static int on_add(lua_State* L);
+ static int on_sub(lua_State* L);
+ static int on_mul(lua_State* L);
+ static int on_div(lua_State* L);
+ static int on_unm(lua_State* L);
+ };
+
+ class Color3Bridge : public Bridge
+ {
+ private:
+ static const luaL_Reg classLibrary[2];
+
+ public:
+ static void registerClassLibrary(lua_State* L)
+ {
+ luaL_register(L, className, classLibrary);
+ lua_pop(L, 1);
+ }
+ static void pushColor3(lua_State* L, G3D::Color3 color)
+ {
+ pushNewObject(L, color);
+ }
+
+ private:
+ static int newColor3(lua_State* L);
+ };
+
+ class BrickColorBridge : public Bridge
+ {
+ private:
+ static const luaL_Reg classLibrary[13];
+
+ public:
+ static void registerClassLibrary(lua_State* L)
+ {
+ luaL_register(L, className, classLibrary);
+ lua_pop(L, 1);
+ }
+
+ private:
+ static int newBrickColor(lua_State* L);
+ static int randomBrickColor(lua_State* L);
+ };
+
+ template<>
+ void Vector3Bridge::registerClass(lua_State *L)
+ {
+ luaL_newmetatable(L, className);
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, on_index);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, on_newindex);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__gc");
+ lua_pushcfunction(L, on_gc);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__eq");
+ lua_pushcfunction(L, on_eq);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__tostring");
+ lua_pushcfunction(L, on_tostring);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__add");
+ lua_pushcfunction(L, Vector3Bridge::on_add);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__sub");
+ lua_pushcfunction(L, Vector3Bridge::on_sub);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__mul");
+ lua_pushcfunction(L, Vector3Bridge::on_mul);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__div");
+ lua_pushcfunction(L, Vector3Bridge::on_div);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__unm");
+ lua_pushcfunction(L, Vector3Bridge::on_unm);
+ lua_settable(L, -3);
+
+ lua_pop(L, 1);
+ }
+
+ template<>
+ void CoordinateFrameBridge::registerClass(lua_State *L)
+ {
+ luaL_newmetatable(L, className);
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, on_index);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, on_newindex);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__gc");
+ lua_pushcfunction(L, on_gc);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__eq");
+ lua_pushcfunction(L, on_eq);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__tostring");
+ lua_pushcfunction(L, on_tostring);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__add");
+ lua_pushcfunction(L, CoordinateFrameBridge::on_add);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__sub");
+ lua_pushcfunction(L, CoordinateFrameBridge::on_sub);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__mul");
+ lua_pushcfunction(L, CoordinateFrameBridge::on_mul);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "inverse");
+ lua_pushcfunction(L, CoordinateFrameBridge::on_inverse);
+ lua_settable(L, -3);
+
+ lua_pop(L, 1);
+ }
+ }
+}
diff --git a/Client/App/include/script/LuaInstanceBridge.h b/Client/App/include/script/LuaInstanceBridge.h
new file mode 100644
index 00000000..8b0be79d
--- /dev/null
+++ b/Client/App/include/script/LuaInstanceBridge.h
@@ -0,0 +1,54 @@
+#pragma once
+#include "lua/LuaBridge.h"
+#include "reflection/reflection.h"
+#include "v8tree/Instance.h"
+#include "lua.h"
+#include "lauxlib.h"
+#include "G3D/format.h"
+
+namespace RBX
+{
+ namespace Lua
+ {
+ void newweaktable(lua_State* L, const char* mode);
+
+ template <>
+ int SharedPtrBridge::on_tostring(const boost::shared_ptr& object, lua_State* L)
+ {
+ Instance* instance = dynamic_cast(object.get());
+
+ if (instance)
+ lua_pushstring(L, instance->getName().c_str());
+ else
+ lua_pushstring(L, object->classDescriptor().name.c_str());
+
+ return 1;
+ }
+
+ class ObjectBridge : public SharedPtrBridge
+ {
+ private:
+ static const luaL_Reg classLibrary[2];
+
+ public:
+ static int callMemberFunction(lua_State* L);
+ static void registerInstanceClassLibrary(lua_State* L)
+ {
+ luaL_register(L, "Instance", classLibrary);
+ lua_pop(L, 1);
+ }
+ static int newInstance(lua_State* thread);
+ // TODO: 98.30% (functional match)
+ static boost::shared_ptr getInstance(lua_State* L, size_t index)
+ {
+ boost::shared_ptr object = getPtr(L, index);
+ Reflection::DescribedBase* object2 = object.get();
+
+ if (object2 && !dynamic_cast(object2))
+ throw std::runtime_error(G3D::format("Object %s is not an Instance", object->classDescriptor().name.c_str()));
+
+ return shared_from(static_cast(object2));
+ }
+ };
+ }
+}
diff --git a/Client/App/include/script/LuaMemory.h b/Client/App/include/script/LuaMemory.h
new file mode 100644
index 00000000..b9bbc742
--- /dev/null
+++ b/Client/App/include/script/LuaMemory.h
@@ -0,0 +1,20 @@
+#pragma once
+
+class LuaAllocator
+{
+private:
+ size_t heapSize;
+ size_t heapCount;
+ size_t maxHeapSize;
+ size_t maxHeapCount;
+
+public:
+ LuaAllocator();
+ void clearHeapMax();
+ void getHeapStats(size_t&, size_t&) const;
+ void getHeapStats(size_t& heapSize, size_t& heapCount, size_t& maxHeapSize, size_t& maxHeapCount) const;
+ void* alloc(void* ptr, size_t osize, size_t nsize);
+
+public:
+ static void* alloc(void* ud, void* ptr, size_t osize, size_t nsize);
+};
diff --git a/Client/App/include/script/LuaSignalBridge.h b/Client/App/include/script/LuaSignalBridge.h
new file mode 100644
index 00000000..94e7c8a4
--- /dev/null
+++ b/Client/App/include/script/LuaSignalBridge.h
@@ -0,0 +1,67 @@
+#pragma once
+#include "lua/LuaBridge.h"
+#include "script/Script.h"
+#include "script/ScriptContext.h"
+#include "script/ThreadRef.h"
+#include "reflection/reflection.h"
+#include "boost/signals.hpp"
+
+namespace RBX
+{
+ namespace Lua
+ {
+ template<>
+ int SharedPtrBridge::on_tostring(const boost::shared_ptr& object, lua_State* L)
+ {
+ std::string name = "Signal ";
+ name += object->descriptor.name.name;
+ lua_pushstring(L, name.c_str());
+ return 1;
+ }
+
+ class SignalBridge : public SharedPtrBridge
+ {
+ public:
+ static int connect(lua_State* L);
+ static int wait(lua_State* L);
+ };
+
+ class SignalConnectionBridge : public Bridge
+ {
+ // hmm
+ friend class Bridge;
+
+ private:
+ static int disconnect(lua_State* L);
+ };
+
+ template<>
+ int SignalConnectionBridge::on_tostring(const boost::signals::connection& object, lua_State* L)
+ {
+ lua_pushstring(L, "Connection");
+ return 1;
+ }
+ }
+}
+
+class FunctionScriptSlot : public RBX::Script::Slot
+{
+private:
+ RBX::ScriptContext& context;
+ RBX::Lua::FunctionRef function;
+ RBX::Lua::ThreadRef cachedSlotThread;
+
+public:
+ FunctionScriptSlot(lua_State* thread, int functionIndex);
+ void operator()(const RBX::Reflection::Arguments&);
+};
+
+class WaitScriptSlot : public RBX::Script::Slot
+{
+private:
+ RBX::Lua::ThreadRef waitThread;
+
+public:
+ WaitScriptSlot(lua_State* thread);
+ void operator()(const RBX::Reflection::Arguments&);
+};
diff --git a/Client/App/include/script/Script.h b/Client/App/include/script/Script.h
index 298f1e49..0f7c4a39 100644
--- a/Client/App/include/script/Script.h
+++ b/Client/App/include/script/Script.h
@@ -1,29 +1,90 @@
#pragma once
+#include "script/ScriptContext.h"
+#include "v8tree/Instance.h"
#include "util/Debug.h"
+#include "boost/shared_ptr.hpp"
+#include "boost/signals.hpp"
namespace RBX
{
- class Script;
class ScriptContext;
- class IScriptOwner
+ extern const char* sScript;
+ class Script : public DescribedCreatable