I'm pretty much trying to make a AddInputEvent but, after a month, can't find a way to turn a local "function from FunctionCallbackInfo"(i'll just call this argf) in to a Persistent Function so that garbage collection doesn't erase the pointers.
Most stakeoverflow threads and example code I can find just say to Cast argf with a Local Function; then to throw that in to a Persistent New. This results in a error: cannot convert 'v8::Local<v8::Function>' to 'v8::Function*'
here is the code, not completely sure why I can't convert it
class inputevnt_feld{
public:
char* call_on;
v8::Persistent<v8::Function> func;
};
int entvcount = -1;
vector<inputevnt_feld> event_calls; //this is pretty much a array of events that we can call later
// in js looks like this "AddInputEvent("string", function);"
void AddInputEvent( const v8::FunctionCallbackInfo<v8::Value>& args ) {
v8::HandleScope handle_scope(args.GetIsolate());
//gotta make sure that we ain't letting in some trojan horse that has nothing in it
if (args[1]->IsFunction() && args[0]->IsString()) {
inputevnt_feld newt;
//converts js string to char array
v8::String::Utf8Value str(args.GetIsolate(), args[0]);
const char* cstr = ToCString(str);
newt.call_on = (char*)cstr;
//here is where the problem is with function casting
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[1]);
newt.func = v8::Persistent<v8::Function>::New(args.GetIsolate(), callback);
//push the new stuff in to even array
event_calls.push_back(newt);
//getting vector array size is too much for my smol brain
//so I'ma just do this myself
entvcount++;
//cout << event_calls[entvcount].call_on << endl; //debug
}
}
Most stakeoverflow threads and example code I can find just say to Cast argf with a Local Function; then to throw that in to a Persistent New
Yes, that's correct. If you know how to read it, the C++ type system is your friend for figuring out the details.
If you look at the definition of v8::PersistentBase<T>::New
, you'll see that it takes a T*
(for its template type T
). If you look at the v8::Local<T>
class, you'll see that a way to get a T*
from it is to use its operator*
. That leads to:
v8::Local<v8::Function> callback = ...Cast(args[1]);
... = v8::Persistent<v8::Function>::New(..., *callback);
Alternatively, you can use the Persistent
constructor directly, and pass it the Local
without dereferencing it first:
v8::Local<v8::Function> callback = ...Cast(args[1]);
... = v8::Persistent<v8::Function>(..., callback);
Both options are entirely equivalent. Personally I'd prefer the latter as it takes slightly fewer characters to spell out, but that's really the only difference.
(Your current code as posted does something else: it ignores the result of the cast and passes the original args[1]
directly to Persistent::New
-- that's not going to work.)