Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,134 changes: 1,813 additions & 1,321 deletions Client/App/App.vcproj

Large diffs are not rendered by default.

211 changes: 211 additions & 0 deletions Client/App/include/lua/LuaBridge.h
Original file line number Diff line number Diff line change
@@ -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 <stdexcept>

namespace RBX
{
namespace Lua
{
template <typename T, bool isComparable>
class Bridge
{
protected:
static const char* className;

public:
static T* pushNewObject(lua_State* L)
{
T* ptr = static_cast<T*>(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<T*>(luaL_checkudata(L, static_cast<int>(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<typename Param1Type>
static T* pushNewObject(lua_State* L, Param1Type param1)
{
T* ptr = static_cast<T*>(lua_newuserdata(L, sizeof(T)));
new(ptr) T(param1);
luaL_getmetatable(L, className);
lua_setmetatable(L, -2);
return ptr;
}

template<typename Object>
static bool getValue(lua_State* L, size_t index, Object& value)
{
const Object* object = static_cast<const Object*>(lua_touserdata(L,static_cast<int>(index)));
if (object)
{
if (lua_getmetatable(L, static_cast<int>(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<T>::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 <typename T>
class SharedPtrBridge : protected Bridge<boost::shared_ptr<T>, false>
{
public:
static void registerClass(lua_State* L)
{
Bridge<boost::shared_ptr<T>, 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<T> 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<T> getPtr(lua_State* L, size_t index)
{
// TODO: check match for T=boost::shared_ptr<Reflection::DescribedBase>
// when security is implemented

if (lua_type(L, static_cast<int>(index)) == LUA_TNIL)
{
return boost::shared_ptr<T>();
}
else
{
return getObject(L, index);
}
}

public:
template<typename ValueType>
static bool getPtr(lua_State* L, size_t index, ValueType& value)
{
if (lua_type(L, static_cast<int>(index)) == LUA_TNIL)
{
value = boost::shared_ptr<T>();
return 1;
}

return getValue(L, index, value);
}
};
}
}
28 changes: 28 additions & 0 deletions Client/App/include/lua/lua.hpp
Original file line number Diff line number Diff line change
@@ -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);
}
};
}
}
30 changes: 9 additions & 21 deletions Client/App/include/reflection/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace RBX
NeedTrustedCaller = 0,
AnyCaller = 1
};

public:
class Arguments
{
Expand All @@ -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
Expand All @@ -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<typename Class>
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&);
};
}
}
Loading