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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.8)
project(Selene)

set(LUA_INCLUDE_DIR "" CACHE FILEPATH "Path to lua headers")
set(LUA_LIB_DIR "" CACHE FILEPATH "Path to lua libs")

if(${LUA_INCLUDE_DIR})
if(NOT EXISTS ${LUA_INCLUDE_DIR}/lua.h)
Expand All @@ -10,6 +11,7 @@ if(${LUA_INCLUDE_DIR})
endif()

include_directories(${LUA_INCLUDE_DIR})
link_directories(${LUA_LIB_DIR})
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you check if this directory exists or is set similar to how it's done to LUA_INCLUDE_DIR above?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the variable isn't set, link_directories won't do anything


if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++11 -stdlib=libc++")
Expand Down
18 changes: 10 additions & 8 deletions include/selene/Obj.h
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "ObjFun.h"
#include "MetatableRegistry.h"
#include <functional>
#include <memory>
#include "State.h"
Expand All @@ -16,6 +17,7 @@ template <typename T, typename... Members>
class Obj : public BaseObj {
private:
std::vector<std::unique_ptr<BaseFun>> _funs;
MetatableRegistry& _meta_registry;

template <typename M>
void _register_member(lua_State *state,
Expand All @@ -36,14 +38,14 @@ class Obj : public BaseObj {
return t->*member;
};
_funs.emplace_back(
new ObjFun<1, M>{state, std::string{member_name}, lambda_get});
new ObjFun<1, M>{state, _meta_registry, std::string{member_name}, lambda_get});

std::function<void(M)> lambda_set = [t, member](M value) {
t->*member = value;
};
_funs.emplace_back(
new ObjFun<0, void, M>
{state, std::string{"set_"} + member_name, lambda_set});
{state, _meta_registry, std::string{"set_"} + member_name, lambda_set});
}

template <typename M>
Expand All @@ -56,35 +58,35 @@ class Obj : public BaseObj {
return t->*member;
};
_funs.emplace_back(
new ObjFun<1, M>{state, std::string{member_name}, lambda_get});
new ObjFun<1, M>{state, _meta_registry, std::string{member_name}, lambda_get});
}

template <typename Ret, typename... Args>
void _register_member(lua_State *state,
T *t,
const char *fun_name,
Ret(T::*fun)(Args&&...)) {
std::function<Ret(Args&&...)> lambda = [t, fun](Args&&... args) {
std::function<Ret(Args&&...)> lambda = [t, fun](Args&&... args) -> Ret {
return (t->*fun)(std::forward<Args>(args)...);
};
constexpr int arity = detail::_arity<Ret>::value;
_funs.emplace_back(
new ObjFun<arity, Ret, Args...>
{state, std::string(fun_name), lambda});
{state, _meta_registry, std::string(fun_name), lambda});
}

template <typename Ret, typename... Args>
void _register_member(lua_State *state,
T *t,
const char *fun_name,
Ret(T::*fun)(Args...)) {
std::function<Ret(Args...)> lambda = [t, fun](Args... args) {
std::function<Ret(Args...)> lambda = [t, fun](Args... args) -> Ret {
return (t->*fun)(args...);
};
constexpr int arity = detail::_arity<Ret>::value;
_funs.emplace_back(
new ObjFun<arity, Ret, Args...>
{state, std::string(fun_name), lambda});
{state, _meta_registry, std::string(fun_name), lambda});
}

void _register_members(lua_State *state, T *t) {}
Expand All @@ -98,7 +100,7 @@ class Obj : public BaseObj {
_register_members(state, t, members...);
}
public:
Obj(lua_State *state, T *t, Members... members) {
Obj(lua_State *state, MetatableRegistry & meta_registry, T *t, Members... members) : _meta_registry(meta_registry) {
lua_createtable(state, 0, sizeof...(Members));
_register_members(state, t, members...);
}
Expand Down
14 changes: 10 additions & 4 deletions include/selene/ObjFun.h
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "BaseFun.h"
#include "MetatableRegistry.h"
#include <string>

namespace sel {
Expand All @@ -10,16 +11,19 @@ class ObjFun : public BaseFun {
private:
using _fun_type = std::function<Ret(Args...)>;
_fun_type _fun;
MetatableRegistry& _meta_registry;

public:
ObjFun(lua_State *l,
MetatableRegistry &meta_registry,
const std::string &name,
Ret(*fun)(Args...))
: ObjFun(l, name, _fun_type{fun}) {}
: ObjFun(l, meta_registry, name, _fun_type{fun}) {}

ObjFun(lua_State *l,
MetatableRegistry &meta_registry,
const std::string &name,
_fun_type fun) : _fun(fun) {
_fun_type fun) : _fun(fun), _meta_registry(meta_registry) {
lua_pushlightuserdata(l, (void *)static_cast<BaseFun *>(this));
lua_pushcclosure(l, &detail::_lua_dispatcher, 1);
lua_setfield(l, -2, name.c_str());
Expand All @@ -30,7 +34,7 @@ class ObjFun : public BaseFun {
int Apply(lua_State *l) {
std::tuple<Args...> args = detail::_get_args<Args...>(l);
Ret value = detail::_lift(_fun, args);
detail::_push(l, std::forward<Ret>(value));
detail::_push(l, _meta_registry, std::forward<Ret>(value));
return N;
}
};
Expand All @@ -43,11 +47,13 @@ class ObjFun<0, void, Args...> : public BaseFun {

public:
ObjFun(lua_State *l,
MetatableRegistry &dummy,
const std::string &name,
void(*fun)(Args...))
: ObjFun(l, name, _fun_type{fun}) {}
: ObjFun(l, dummy, name, _fun_type{fun}) {}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer just having the base constructor not have this argument and omitting the name altogether.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean? the argument is necessary because of _register_member on line 65 & 79 of Obj.h isn't it?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right so can you make a new constructor that doesn't require it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see. The same can be done for the Fun class, will make the change when I get a chance.


ObjFun(lua_State *l,
MetatableRegistry &,
const std::string &name,
_fun_type fun) : _fun(fun) {
lua_pushlightuserdata(l, (void *)static_cast<BaseFun *>(this));
Expand Down
2 changes: 1 addition & 1 deletion include/selene/Registry.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class Registry {
template <typename T, typename... Funs>
void RegisterObj(T &t, Funs... funs) {
auto tmp = std::unique_ptr<BaseObj>(
new Obj<T, Funs...>{_state, &t, funs...});
new Obj<T, Funs...>{_state, _metatables, &t, funs...});
_objs.push_back(std::move(tmp));
}

Expand Down
2 changes: 2 additions & 0 deletions test/Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ static TestMap tests = {
{"test_register_obj_const_member_variable", test_register_obj_const_member_variable},
{"test_bind_vector_push_back", test_bind_vector_push_back},
{"test_bind_vector_push_back_string", test_bind_vector_push_back_string},
{"test_obj_pointer_return", test_obj_pointer_return},
{"test_obj_reference_return", test_obj_reference_return},

{"test_select_global", test_select_global},
{"test_select_field", test_select_field},
Expand Down
24 changes: 24 additions & 0 deletions test/obj_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
#include <selene.h>
#include <vector>

struct Bla {
int y;
};

struct Foo {
int x;
const int y;
Bla bla;
Foo(int x_) : x(x_), y(3) {}
int GetX() { return x; }
int DoubleAdd(int y) {
Expand All @@ -14,6 +19,12 @@ struct Foo {
void SetX(int x_) {
x = x_;
}
Bla & GetBlaRef() {
return bla;
}
Bla * GetBlaPtr() {
return &bla;
}
};

bool test_register_obj(sel::State &state) {
Expand Down Expand Up @@ -85,3 +96,16 @@ bool test_bind_vector_push_back_string(sel::State &state) {
state["vec"]["push_back"]("hi");
return test_vector[0] == "hi";
}

bool test_obj_pointer_return(sel::State &state) {
Foo foo_instance(1);
state["foo_instance"].SetObj(foo_instance, "get_bla_ptr", &Foo::GetBlaPtr);
return state["foo_instance"]["get_bla_ptr"]() == &foo_instance.bla;
}

bool test_obj_reference_return(sel::State &state) {
Foo foo_instance(1);
state["foo_instance"].SetObj(foo_instance, "get_bla_ref", &Foo::GetBlaRef);
Bla &ref = state["foo_instance"]["get_bla_ref"]();
return &ref == &foo_instance.bla;
}