diff --git a/test/test_class.cpp b/test/test_class.cpp index d0deb0b9..bf600083 100644 --- a/test/test_class.cpp +++ b/test/test_class.cpp @@ -95,9 +95,21 @@ void test_class_() using x_prop_get = int (X::*)() const; using x_prop_set = void (X::*)(int); - v8pp::class_ X_class(isolate); + int extra_ctor_context = 1; + auto const X_ctor = [extra_ctor_context](v8::FunctionCallbackInfo const& args) + { + return create_X(args); + }; + Z extra_dtor_context; + auto const X_dtor = [extra_dtor_context](v8::Isolate* isolate, typename Traits::template object_pointer_type const& obj) + { + Traits::destroy(obj); + }; + + v8pp::class_ X_class(isolate, X_dtor); X_class .ctor(&create_X) + .template ctor const&>(X_ctor) .set_const("konst", 99) .set("var", &X::var) .set("rprop", v8pp::property(&X::get)) diff --git a/v8pp/class.hpp b/v8pp/class.hpp index 293aa57c..b2f8dada 100644 --- a/v8pp/class.hpp +++ b/v8pp/class.hpp @@ -48,15 +48,15 @@ class object_registry final : public class_info using const_pointer_type = typename Traits::const_pointer_type; using object_id = typename Traits::object_id; - using ctor_function = pointer_type (*)(v8::FunctionCallbackInfo const& args); - using dtor_function = void (*)(v8::Isolate*, pointer_type const&); + using ctor_function = std::function const& args)>; + using dtor_function = std::function; using cast_function = pointer_type (*)(pointer_type const&); - object_registry(v8::Isolate* isolate, type_info const& type, dtor_function dtor) + object_registry(v8::Isolate* isolate, type_info const& type, dtor_function&& dtor) : class_info(type, type_id()) , isolate_(isolate) - , ctor_(nullptr) // no wrapped class constructor available by default - , dtor_(dtor) + , ctor_() // no wrapped class constructor available by default + , dtor_(std::move(dtor)) { v8::HandleScope scope(isolate_); @@ -121,7 +121,7 @@ class object_registry final : public class_info return to_local(isolate_, js_func_); } - void set_ctor(ctor_function ctor) { ctor_ = ctor; } + void set_ctor(ctor_function&& ctor) { ctor_ = std::move(ctor); } void add_base(object_registry& info, cast_function cast) { @@ -344,7 +344,7 @@ class classes public: template static object_registry& add(v8::Isolate* isolate, type_info const& type, - typename object_registry::dtor_function dtor) + typename object_registry::dtor_function&& dtor) { classes* info = instance(operation::add, isolate); auto it = info->find(type); @@ -354,7 +354,7 @@ class classes throw std::runtime_error((*it)->class_name() + " is already exist in isolate " + pointer_str(isolate)); } - info->classes_.emplace_back(new object_registry(isolate, type, dtor)); + info->classes_.emplace_back(new object_registry(isolate, type, std::move(dtor))); return *static_cast*>(info->classes_.back().get()); } @@ -450,25 +450,27 @@ class class_ } }; - static void factory_destroy(v8::Isolate* isolate, pointer_type const& obj) - { - factory::destroy(isolate, Traits::template static_pointer_cast(obj)); - } - - using ctor_function = object_pointer_type (*)(v8::FunctionCallbackInfo const& args); - using dtor_function = void (*)(v8::Isolate* isolate, pointer_type const& obj); + using ctor_function = std::function const& args)>; + using dtor_function = std::function; public: - explicit class_(v8::Isolate* isolate, dtor_function destroy = factory_destroy) - : class_info_(detail::classes::add(isolate, detail::type_id(), destroy)) + explicit class_(v8::Isolate* isolate, dtor_function destroy = &factory::destroy) + : class_info_(detail::classes::add(isolate, detail::type_id(), + [destroy = std::move(destroy)](v8::Isolate* isolate, pointer_type const& obj) + { + destroy(isolate, Traits::template static_pointer_cast(obj)); + })) { } /// Set class constructor signature template> - class_& ctor(ctor_function create = Create::call) + class_& ctor(ctor_function create = &Create::call) { - class_info_.set_ctor(reinterpret_cast(create)); + class_info_.set_ctor([create = std::move(create)](v8::FunctionCallbackInfo const& args) + { + return create(args); + }); return *this; }