Yes, however what I need to store is the v8::FunctionTemplate, v8::Local<v8::FunctionTemplate> to be more specific, which does not inherit from Value and there is a static_assert that checks for that.
So perhaps, maybe if go to the real problem a different solution may arise.
{
v8::Local<v8::Context> context = aIsolate->GetCurrentContext();
//---------------------------------------
// Store constructor on a callback data object
v8::Local<v8::ObjectTemplate> constructor_data_template = v8::ObjectTemplate::New ( aIsolate );
constructor_data_template->SetInternalFieldCount ( 1 );
v8::Local<v8::Object> constructor_data =
constructor_data_template->NewInstance ( context ).ToLocalChecked();
// Prepare EventTarget constructor template
v8::Local<v8::FunctionTemplate> constructor_template = v8::FunctionTemplate::New ( aIsolate, JsObjectWrap::New<EventTarget>, constructor_data ); // <----- THIS IS THE FunctionTemplate I NEED TO STORE
constructor_template->SetClassName ( v8::String::NewFromUtf8 ( aIsolate, "EventTarget" ).ToLocalChecked() );
constructor_template->InstanceTemplate()->SetInternalFieldCount ( 1 );
AddFunctionTemplate ( aIsolate, typeid ( EventTarget ), constructor_template ); // <---- THIS IS MY CURRENT SOLUTION
//----------------------------------------------------------------
v8::Local<v8::Function> event = event_template->GetFunction ( context ).ToLocalChecked();
context->Global()->Set ( context, v8::String::NewFromUtf8 (
aIsolate, "Event" ).ToLocalChecked(),
event ).FromJust();
v8::Local<v8::Function> constructor = constructor_template->GetFunction ( context ).ToLocalChecked();
constructor_data->SetInternalField ( 0, constructor );
context->Global()->Set ( context, v8::String::NewFromUtf8 (
aIsolate, "EventTarget" ).ToLocalChecked(),
constructor ).FromJust();
}
Then, when I want to have Node inherit from EventTarget I write a similar static function (the previous one is also static)
void Node::Initialize ( v8::Isolate* aIsolate )
{
if ( HasFunctionTemplate ( aIsolate, typeid ( Node ) ) )
{
throw std::runtime_error ( "Isolate already initialized." );
}
v8::Local<v8::Context> context = aIsolate->GetCurrentContext();
// Prepare Node constructor template
v8::Local<v8::FunctionTemplate> constructor_template = v8::FunctionTemplate::New ( aIsolate );
constructor_template->SetClassName ( v8::String::NewFromUtf8 ( aIsolate, "Node" ).ToLocalChecked() );
constructor_template->Inherit ( EventTarget::GetFunctionTemplate ( aIsolate, typeid ( EventTarget ) ) ); // <-- THIS IS WHAT I REALLY NEED
AddFunctionTemplate ( aIsolate, typeid ( Node ), constructor_template );
v8::Local<v8::Function> constructor = constructor_template->GetFunction ( context ).ToLocalChecked();
context->Global()->Set ( context, v8::String::NewFromUtf8 (
aIsolate, "Node" ).ToLocalChecked(),
constructor ).FromJust();
}
As I said before, this works but I feel that makes the code too verbose and prone to error, for example now I am now forced to have a trivial Finalize function on all classes:
void Node::Finalize ( v8::Isolate* aIsolate )
{
RemoveFunctionTemplate ( aIsolate, typeid ( Node ) );
}
because the FunctionTemplate objects are stored as Persistent Handles in this map:
static std::unordered_map<std::pair<v8::Isolate*, size_t>, v8::Persistent<v8::FunctionTemplate, v8::CopyablePersistentTraits<v8::FunctionTemplate>>> FunctionTemplates{};
So I need to free them all, unlike a Local.
So, perhaps there is a way where I can either store the template in the constructor, or maybe there is a way to have Node inherit from EventTarget without requiring the FunctionTemplate, but instead require just the function?
Thanks for taking a look!