Use uint keys inside the C++ wrapper cache
This commit is contained in:
parent
9faf63d5d3
commit
1d92cc8f3e
@ -30,7 +30,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget {
|
||||
Napi::Env env = this->emitOnNode.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen);
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen, false);
|
||||
this->emitOnNode.Call(
|
||||
{Napi::String::New(env, "primaryScreenChanged"), instance});
|
||||
});
|
||||
@ -39,7 +39,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget {
|
||||
Napi::Env env = this->emitOnNode.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen);
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen, false);
|
||||
this->emitOnNode.Call({Napi::String::New(env, "screenAdded"), instance});
|
||||
});
|
||||
|
||||
@ -48,7 +48,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget {
|
||||
Napi::Env env = this->emitOnNode.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen);
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen, false);
|
||||
this->emitOnNode.Call(
|
||||
{Napi::String::New(env, "screenRemoved"), instance});
|
||||
});
|
||||
|
||||
@ -427,7 +427,7 @@
|
||||
Napi::Env env = info.Env(); \
|
||||
QWindow* window = this->instance->windowHandle(); \
|
||||
if (window) { \
|
||||
return WrapperCache::instance.get<QWindow, QWindowWrap>(env, window); \
|
||||
return WrapperCache::instance.get<QWindow, QWindowWrap>(env, window, false); \
|
||||
} else { \
|
||||
return env.Null(); \
|
||||
} \
|
||||
|
||||
@ -6,7 +6,8 @@
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "Extras/Export/export.h"
|
||||
#include "QtGui/QScreen/qscreen_wrap.h"
|
||||
#include "Extras/Utils/nutils.h"
|
||||
|
||||
|
||||
struct CachedObject {
|
||||
napi_ref ref;
|
||||
@ -24,7 +25,7 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QMap<const QObject*, CachedObject> cache;
|
||||
QMap<uint64_t, CachedObject> cache;
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -44,29 +45,53 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
* @return The JS wrapper object.
|
||||
*/
|
||||
template <class T, class W>
|
||||
Napi::Object get(Napi::Env env, T* object) {
|
||||
if (this->cache.contains(object)) {
|
||||
Napi::Object get(Napi::Env env, T* object, bool isCreatedByNodeGui) {
|
||||
uint64_t ptrHash = extrautils::hashPointerTo53bit(object);
|
||||
if (this->cache.contains(ptrHash)) {
|
||||
napi_value result = nullptr;
|
||||
napi_get_reference_value(env, this->cache[object].ref, &result);
|
||||
return Napi::Object(env, result);
|
||||
napi_get_reference_value(env, this->cache[ptrHash].ref, &result);
|
||||
|
||||
napi_valuetype valuetype;
|
||||
napi_typeof(env, result, &valuetype);
|
||||
if (valuetype != napi_null) {
|
||||
return Napi::Object(env, result);
|
||||
}
|
||||
}
|
||||
|
||||
Napi::Object wrapper =
|
||||
W::constructor.New({Napi::External<T>::New(env, object)});
|
||||
|
||||
napi_ref ref = nullptr;
|
||||
napi_create_reference(env, wrapper, 1, &ref);
|
||||
this->cache[object].env = napi_env(env);
|
||||
this->cache[object].ref = ref;
|
||||
|
||||
QObject::connect(object, &QObject::destroyed, this,
|
||||
&WrapperCache::handleDestroyed);
|
||||
store(env, extrautils::hashPointerTo53bit(object), object, wrapper, isCreatedByNodeGui);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a mapping from Qt Object to wrapper
|
||||
*
|
||||
* @param T - (template argument) The Qt class of the object being cached,
|
||||
* e.g. `QScreen`.
|
||||
* @param W - (template argument) The wrapper type which matches the object
|
||||
* `QScreenWrap`.
|
||||
* @param env = Napi environment
|
||||
* @param object - Pointer to the QObject for which a wrapper is required.
|
||||
* @param wrapper - The wrapper object matching `object`.
|
||||
*/
|
||||
void store(Napi::Env env, uint64_t ptrHash, QObject *qobject, Napi::Object wrapper, bool isWeak) {
|
||||
napi_ref ref = nullptr;
|
||||
|
||||
napi_create_reference(env, wrapper, isWeak ? 0 : 1, &ref);
|
||||
this->cache[ptrHash].env = napi_env(env);
|
||||
this->cache[ptrHash].ref = ref;
|
||||
|
||||
QObject::connect(qobject, &QObject::destroyed, this,
|
||||
&WrapperCache::handleDestroyed);
|
||||
}
|
||||
|
||||
static Napi::Object init(Napi::Env env, Napi::Object exports) {
|
||||
exports.Set("WrapperCache_injectCallback",
|
||||
Napi::Function::New<injectDestroyCallback>(env));
|
||||
// exports.Set("WrapperCache_storeJS",
|
||||
// Napi::Function::New<storeJS>(env));
|
||||
return exports;
|
||||
}
|
||||
|
||||
@ -81,7 +106,8 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
|
||||
public Q_SLOTS:
|
||||
void handleDestroyed(const QObject* object) {
|
||||
if (!this->cache.contains(object)) {
|
||||
uint64_t ptrHash = extrautils::hashPointerTo53bit(object);
|
||||
if (!this->cache.contains(ptrHash)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -92,12 +118,14 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
Napi::HandleScope scope(env);
|
||||
destroyedCallback.Call(
|
||||
env.Global(),
|
||||
{Napi::Value::From(env, extrautils::hashPointerTo53bit(object))});
|
||||
{Napi::Value::From(env, ptrHash)});
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
napi_reference_unref(this->cache[object].env, this->cache[object].ref,
|
||||
// TODO: Grab the wrapper C++ object and null out its ref to the Qt object.
|
||||
|
||||
napi_reference_unref(this->cache[ptrHash].env, this->cache[ptrHash].ref,
|
||||
&result);
|
||||
this->cache.remove(object);
|
||||
this->cache.remove(ptrHash);
|
||||
}
|
||||
};
|
||||
|
||||
@ -119,7 +119,7 @@ Napi::Value StaticQApplicationWrapMethods::clipboard(
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
if (clipboard) {
|
||||
return WrapperCache::instance.get<QClipboard, QClipboardWrap>(env,
|
||||
clipboard);
|
||||
clipboard, false);
|
||||
} else {
|
||||
return env.Null();
|
||||
}
|
||||
@ -163,7 +163,7 @@ Napi::Value StaticQApplicationWrapMethods::primaryScreen(
|
||||
Napi::Env env = info.Env();
|
||||
auto screen = QApplication::primaryScreen();
|
||||
if (screen) {
|
||||
return WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen);
|
||||
return WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen, false);
|
||||
} else {
|
||||
return env.Null();
|
||||
}
|
||||
@ -177,7 +177,7 @@ Napi::Value StaticQApplicationWrapMethods::screens(
|
||||
for (int i = 0; i < screens.size(); i++) {
|
||||
QScreen* screen = screens[i];
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen);
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen, false);
|
||||
jsArray[i] = instance;
|
||||
}
|
||||
return jsArray;
|
||||
|
||||
@ -56,7 +56,7 @@ void QWindowWrap::connectSignalsToEventEmitter() {
|
||||
Napi::Env env = this->emitOnNode.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen);
|
||||
WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen, false);
|
||||
this->emitOnNode.Call(
|
||||
{Napi::String::New(env, "screenChanged"), instance});
|
||||
});
|
||||
@ -81,7 +81,7 @@ Napi::Value QWindowWrap::screen(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
QScreen* screen = this->instance->screen();
|
||||
if (screen) {
|
||||
return WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen);
|
||||
return WrapperCache::instance.get<QScreen, QScreenWrap>(env, screen, false);
|
||||
} else {
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ Napi::Value CacheTestQObjectWrap::foo(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
CacheTestQObject* foo = this->instance->foo();
|
||||
return WrapperCache::instance.get<CacheTestQObject, CacheTestQObjectWrap>(
|
||||
env, foo);
|
||||
env, foo, false);
|
||||
}
|
||||
|
||||
Napi::Value CacheTestQObjectWrap::clearFoo(const Napi::CallbackInfo& info) {
|
||||
@ -61,5 +61,5 @@ Napi::Value CacheTestQObjectWrap::bar(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
CacheTestQObject* bar = this->instance->bar();
|
||||
return WrapperCache::instance.get<CacheTestQObject, CacheTestQObjectWrap>(
|
||||
env, bar);
|
||||
env, bar, false);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user