Skip to content

Commit

Permalink
full test
Browse files Browse the repository at this point in the history
  • Loading branch information
lucklove committed Dec 22, 2015
1 parent e2720b6 commit e531aa4
Show file tree
Hide file tree
Showing 21 changed files with 289 additions and 192 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
PROJECT(nua_test)

SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(CMAKE_CXX_COMPILER clang++)
SET(CMAKE_CXX_COMPILER g++)
ADD_COMPILE_OPTIONS("-std=c++1y")
ADD_COMPILE_OPTIONS("-Wall")

Expand Down
Binary file removed core.12508
Binary file not shown.
27 changes: 24 additions & 3 deletions inc/BaseFunc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,31 @@ namespace detail
return first;
}

template <typename T>
constexpr T forward_ref(T t, std::false_type)
{
return t;
}

template <typename T>
constexpr std::reference_wrapper<typename std::decay<T>::type> forward_ref(T t, std::true_type)
{
return std::reference_wrapper<typename std::decay<T>::type>(t);
}

template <typename Ret, typename... Args, size_t... Is>
void apply_n(lua_State* l, std::function<Ret(Args...)> func, std::index_sequence<Is...>)
{
Ret ret = func(stack::get<Args>(l, int(Is - sizeof...(Is)))...);
lua_pop(l, int(sizeof...(Is)));
stack::push(l, ret);
if(std::is_lvalue_reference<Ret>::value)
{
stack::push(l, std::ref(ret));
}
else
{
stack::push(l, ret);
}
}

template <typename... Args, size_t... Is>
Expand All @@ -38,10 +57,12 @@ namespace detail
std::index_sequence<RetIs...>,
std::index_sequence<ArgIs...>)
{
static_assert(is_all_true(is_primitive<Rets>::value...), "not support return userdata temporarily");
// static_assert(is_all_true(is_primitive<Rets>::value...), "not support return userdata temporarily");
std::tuple<Rets...> ret = func(stack::get<Args>(l, int(ArgIs - sizeof...(ArgIs)))...);
lua_pop(l, int(sizeof...(ArgIs)));
(void)std::initializer_list<int>{(stack::push(l, std::get<RetIs>(ret)), 0)...};
(void)std::initializer_list<int>{(
stack::push(l, forward_ref<Rets>(std::get<RetIs>(ret), typename std::is_lvalue_reference<Rets>::type{})),
0)...};
}
}

Expand Down
16 changes: 3 additions & 13 deletions inc/Class.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "BaseFunc.hh"
#include "Func.hh"
#include "ClassFunc.hh"
#include "Ctor.hh"
#include "Dtor.hh"

namespace nua
Expand All @@ -14,20 +13,14 @@ namespace nua
virtual ~BaseClass() = default;
};

template <typename T, typename R, typename A, typename... Members>
template <typename T, typename R, typename... Members>
class Class : public BaseClass
{
private:
std::vector<std::unique_ptr<BaseFunc>> funcs_;
std::string metatable_name_;
std::unique_ptr<A> ctor_;
std::unique_ptr<Dtor<R>> dtor_;

void register_ctor(lua_State* l)
{
ctor_.reset(new A(l, metatable_name_.c_str()));
}

void register_dtor(lua_State* l)
{
dtor_.reset(new Dtor<R>(l, metatable_name_.c_str()));
Expand Down Expand Up @@ -98,15 +91,12 @@ namespace nua
Class() = default;

public:
Class(lua_State* l, const std::string& name, Members... members)
Class(lua_State* l, Members... members) : metatable_name_{typeid(T).name()}
{
metatable_name_ = name + "_lib";
metatable_name_ += "_lib";
MetatableRegistry::push_new_metatable<T>(l, metatable_name_);
if(std::is_same<T, R>::value)
{
register_ctor(l);
register_dtor(l);
}
register_members(l, members...);
lua_pushvalue(l, -1);
lua_setfield(l, -1, "__index");
Expand Down
87 changes: 68 additions & 19 deletions inc/ClassFunc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,50 @@
#include "BaseFunc.hh"

namespace nua
{
namespace detail
{
template <typename T, typename Ret, typename... Args>
class ClassFunc : public BaseFunc
class BaseClassFunc : public BaseFunc
{
public:
using func_t = std::function<Ret(T*, Args...)>;

protected:
using func_t = std::function<Ret(T*, Args...)>;

func_t func_;
std::string name_;
std::string metatable_name_;

public:
BaseClassFunc(lua_State *l, const std::string &name, const std::string &metatable_name, func_t func)
: func_{func}, name_{name}, metatable_name_{metatable_name}
{
lua_pushlightuserdata(l, (void *)static_cast<BaseFunc*>(this));
lua_pushcclosure(l, &BaseFunc::dispatcher, 1);
lua_setfield(l, -2, name.c_str());
}
};
}
template <typename T, typename Ret, typename... Args>
class ClassFunc : public detail::BaseClassFunc<T, Ret, Args...>
{
protected:
int apply_impl(lua_State* l, T* ptr)
{
using decay_ret = typename std::decay<Ret>::type;
std::function<decay_ret(Args...)> func = [this, ptr](Args... args) -> decay_ret
std::function<Ret(Args...)> func = [this, ptr](Args... args) -> Ret
{
return func_(ptr, args...);
return this->func_(ptr, args...);
};

detail::apply_n(l, func, std::make_index_sequence<sizeof...(Args)>());
return !std::is_same<decay_ret, void>::value;
return !std::is_same<Ret, void>::value;
}

public:
ClassFunc(lua_State *l, const std::string &name, const std::string &metatable_name, func_t func)
: func_{func}, name_{name}, metatable_name_{metatable_name}
{
lua_pushlightuserdata(l, (void *)static_cast<BaseFunc*>(this));
lua_pushcclosure(l, &BaseFunc::dispatcher, 1);
lua_setfield(l, -2, name.c_str());
}

using detail::BaseClassFunc<T, Ret, Args...>::BaseClassFunc;

int apply(lua_State* l) override
{
T* ptr = (T*)luaL_checkudata(l, 1, metatable_name_.c_str());
T* ptr = (T*)luaL_checkudata(l, 1, this->metatable_name_.c_str());
return apply_impl(l, ptr);
}
};
Expand All @@ -48,10 +57,50 @@ namespace nua

int apply(lua_State* l) override
{
std::cout << this->metatable_name_ << std::endl;
T* ptr = *(T**)luaL_checkudata(l, 1, this->metatable_name_.c_str());
std::cout << ptr << std::endl;
return this->apply_impl(l, ptr);
}
};

template <typename T, typename... Rets, typename... Args>
struct ClassFunc<T, std::tuple<Rets...>, Args...> : detail::BaseClassFunc<T, std::tuple<Rets...>, Args...>
{
protected:
int apply_impl(lua_State* l, T* ptr)
{
std::function<std::tuple<Rets...>(Args...)> func = [this, ptr](Args... args) -> std::tuple<Rets...>
{
return this->func_(ptr, args...);
};

detail::apply_n(l,
func,
std::make_index_sequence<sizeof...(Rets)>(),
std::make_index_sequence<sizeof...(Args)>());
return sizeof...(Rets);
}

public:
using detail::BaseClassFunc<T, std::tuple<Rets...>, Args...>::BaseClassFunc;

int apply(lua_State* l) override
{
T* ptr = (T*)luaL_checkudata(l, 1, this->metatable_name_.c_str());
return apply_impl(l, ptr);
}
};

template <typename T, typename... Rets, typename... Args>
struct ClassFunc<std::reference_wrapper<T>, std::tuple<Rets...>, Args...>
: ClassFunc<T, std::tuple<Rets...>, Args...>
{
public:
using ClassFunc<T, std::tuple<Rets...>, Args...>::ClassFunc;

int apply(lua_State* l) override
{
T* ptr = *(T**)luaL_checkudata(l, 1, this->metatable_name_.c_str());
return this->apply_impl(l, ptr);
}
};
}
10 changes: 9 additions & 1 deletion inc/Context.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace nua
private:
lua_State* lua_ctx_;
std::unique_ptr<Registry> registry_;

public:
explicit Context(bool should_open_libs = true)
{
Expand Down Expand Up @@ -75,5 +75,13 @@ namespace nua
{
lua_gc(lua_ctx_, LUA_GCCOLLECT, 0);
}

template <typename T, typename... Funcs>
typename std::enable_if<!is_primitive<T>::value, void>::type
setClass(Funcs... funcs)
{
registry_->registerClass<T>(lua_ctx_, funcs...);
registry_->registerClass<std::reference_wrapper<T>>(lua_ctx_, funcs...);
}
};
}
34 changes: 0 additions & 34 deletions inc/Ctor.hh

This file was deleted.

1 change: 0 additions & 1 deletion inc/Dtor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ namespace nua

int apply(lua_State* l)
{
std::cout << "gc" << std::endl;
T *t = (T *)luaL_checkudata(l, 1, metatable_name_.c_str());
t->~T();
return 0;
Expand Down
2 changes: 1 addition & 1 deletion inc/MetatableRegistry.hh
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ namespace nua

lua_pop(ctx, 2);
}

if(name.empty())
name = lua_typename(ctx, lua_type(ctx, index));

Expand Down
6 changes: 3 additions & 3 deletions inc/Registry.hh
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ namespace nua
funcs_.push_back(std::make_unique<Func<Ret, Args...>>(l, func));
}

template <typename T, typename... Args, typename... Funcs>
void registerClass(lua_State*l, const std::string& name, Funcs... funcs)
template <typename T, typename... Funcs>
void registerClass(lua_State*l, Funcs... funcs)
{
using R = typename reference_traits<T>::type;
classes_.push_back(std::make_unique<Class<T, R, Ctor<R, Args...>, Funcs...>>(l, name, funcs...));
classes_.push_back(std::make_unique<Class<T, R, Funcs...>>(l, funcs...));
}
};
}
43 changes: 23 additions & 20 deletions inc/ScopeGuard.hh
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
#pragma once

class ScopeGuard
namespace nua
{
public:
explicit ScopeGuard(std::function<void()> on_exit)
: on_exit_(on_exit), dismissed_(false)
{}

~ScopeGuard()
class ScopeGuard
{
if (!dismissed_)
public:
explicit ScopeGuard(std::function<void()> on_exit)
: on_exit_(on_exit), dismissed_(false)
{}

~ScopeGuard()
{
on_exit_();
if(!dismissed_)
{
on_exit_();
}
}
}

void dismiss(bool dismissed=true)
{
dismissed_ = dismissed;
}
void dismiss(bool dismissed=true)
{
dismissed_ = dismissed;
}

ScopeGuard(const ScopeGuard&) = delete;
ScopeGuard& operator=(ScopeGuard const&) = delete;
ScopeGuard(const ScopeGuard&) = delete;
ScopeGuard& operator=(ScopeGuard const&) = delete;

private:
std::function<void()> on_exit_;
bool dismissed_;
};
private:
std::function<void()> on_exit_;
bool dismissed_;
};
}
Loading

0 comments on commit e531aa4

Please sign in to comment.