pmed / v8pp

Bind C++ functions and classes into V8 JavaScript engine
http://pmed.github.io/v8pp/
Other
890 stars 120 forks source link

How to export static constants? #84

Closed VitaminCpp closed 5 years ago

VitaminCpp commented 5 years ago

I would like to write the following Javascript:

console.log(MyClass.VERSION);
var myClass = new MyClass(MyClass.MY_CONSTANT);

My current class wrapper looks like this:

MyClassWrapper myClassWrapper(isolate);
  myClassWrapper
    .ctor<MyClass::Type>()
    .set_const("MY_CONSTANT", &MyClass::MY_CONSTANT);

But as expected this wont work, because MY_CONSTANT is a V8 prototype property instead of a V8 ObjectTemplate property.

But because I can't break our current API, I would need some workaround without having to change my existing API.

VitaminCpp commented 5 years ago

I would suggest the following proposal for class.hpp:

/// Set a static value
template<typename Value>
class_& set_static(char const* name, Value const& value, bool readonly = false)
{
v8::HandleScope scope(isolate());

class_info_.js_function_template()->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked()
    ->DefineOwnProperty(isolate()->GetCurrentContext(),
    v8pp::to_v8(isolate(), name), to_v8(isolate(), value),
    v8::PropertyAttribute(v8::DontDelete | (readonly ? v8::ReadOnly : 0))).FromJust();
return *this;
}

So you can define (const) static members this way:

MyClassWrapper myClassWrapper(isolate);
  myClassWrapper
    .ctor<MyClass::Type>()
    .set_static("MY_CONSTANT", &MyClass::MY_READONLY_CONSTANT, true)
    .set_static("MY_CONSTANT", &MyClass::MY_CONSTANT);
pmed commented 5 years ago

Hi,

I can’t check it now, but what if just add the constant value into class_info_.js_function_template() inside of set_const() function, similar to the set() implementation for static functions.

пт, 24 авг. 2018 г. в 13:14, VitaminCpp notifications@github.com:

I would suggest the following proposal for class.hpp:

/// Set a static value template class_& set_static(char const* name, Value const& value, bool readonly = false) { v8::HandleScope scope(isolate());

classinfo.js_function_template()->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() ->DefineOwnProperty(isolate()->GetCurrentContext(), v8pp::to_v8(isolate(), name), to_v8(isolate(), value), v8::PropertyAttribute(v8::DontDelete | (readonly ? v8::ReadOnly : 0))).FromJust(); return *this; }

So you can define (const) static members this way:

MyClassWrapper myClassWrapper(isolate); myClassWrapper .ctor() .set_static("MY_CONSTANT", &MyClass::MY_READONLY_CONSTANT, true) .set_static("MY_CONSTANT", &MyClass::MY_CONSTANT);

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pmed/v8pp/issues/84#issuecomment-415716825, or mute the thread https://github.com/notifications/unsubscribe-auth/ABEgUr9UvMuoVZlLmwtBDg87lxz1o2EWks5uT9IGgaJpZM4WK8Ln .

-- Sincerely, Pavel

atvise commented 5 years ago

Hi @pmed,

if I understood you right that would mean that every variable set through set_const would be accessible without a class instantiation. Furthermore the static variable would only available as const variable and for some applications there is maybe a need of writable static variables.

So I think it would be best if there is a seperate set of functions which register either member variables (const or writeable) or static variables (const or writeable) of a class like @VitaminCpp made an example of.

Regards, atvise

pmed commented 5 years ago

Fixed in #89, but note that static property definition works only at the end of v8pp::class_ declaration.