Add QObject.parent() and infra for correct subclass wrappers
This commit is contained in:
parent
bc9bf12e11
commit
880ea7c998
@ -35,9 +35,7 @@ class DLL_EXPORT NAbstractItemModel : public QAbstractItemModel,
|
||||
return *newIndex;
|
||||
}
|
||||
|
||||
QObject *parent() const {
|
||||
return nullptr;
|
||||
}
|
||||
QObject* parent() const { return nullptr; }
|
||||
|
||||
QModelIndex parent(const QModelIndex& child) const override {
|
||||
Napi::Env env = this->dispatchOnNode.Env();
|
||||
|
||||
@ -8,10 +8,9 @@
|
||||
#include "core/WrapperCache/wrappercache.h"
|
||||
|
||||
/*
|
||||
|
||||
This macro adds common QObject exported methods
|
||||
The exported methods are taken into this macro to avoid writing them in each
|
||||
and every widget we export.
|
||||
This macro adds common QObject exported methods
|
||||
The exported methods are taken into this macro to avoid writing them in each
|
||||
and every widget we export.
|
||||
*/
|
||||
|
||||
#ifndef QOBJECT_WRAPPED_METHODS_DECLARATION_WITH_EVENT_SOURCE
|
||||
@ -22,7 +21,8 @@
|
||||
Napi::Value __id__(const Napi::CallbackInfo& info) { \
|
||||
Napi::Env env = info.Env(); \
|
||||
return Napi::Value::From( \
|
||||
env, extrautils::hashPointerTo53bit(this->instance.data())); \
|
||||
env, extrautils::hashPointerTo53bit( \
|
||||
static_cast<QObject*>(this->instance.data()))); \
|
||||
} \
|
||||
Napi::Value inherits(const Napi::CallbackInfo& info) { \
|
||||
Napi::Env env = info.Env(); \
|
||||
@ -93,7 +93,7 @@
|
||||
} \
|
||||
Napi::Value parent(const Napi::CallbackInfo& info) { \
|
||||
Napi::Env env = info.Env(); \
|
||||
QObject *parent = this->instance->parent(); \
|
||||
QObject* parent = this->instance->parent(); \
|
||||
if (parent) { \
|
||||
return WrapperCache::instance.getWrapper(env, parent); \
|
||||
} else { \
|
||||
@ -109,8 +109,7 @@
|
||||
Napi::Env env = info.Env(); \
|
||||
delete static_cast<QObject*>(this->instance); \
|
||||
return env.Null(); \
|
||||
} \
|
||||
|
||||
}
|
||||
|
||||
// Ideally this macro below should go in
|
||||
// QOBJECT_WRAPPED_METHODS_DECLARATION_WITH_EVENT_SOURCE but some wrappers
|
||||
@ -176,4 +175,22 @@
|
||||
#define QOBJECT_SIGNALS QOBJECT_SIGNALS_ON_TARGET(this)
|
||||
#endif // QOBJECT_SIGNALS
|
||||
|
||||
/*
|
||||
Macro to register a function to wrap QObject pointers of a
|
||||
given subclass to wrapper instances. First parameter is the
|
||||
plain name of the QObject subclass (no quotes), seconds is the
|
||||
name of the wrapper class.
|
||||
*/
|
||||
#ifndef QOBJECT_REGISTER_WRAPPER
|
||||
#define QOBJECT_REGISTER_WRAPPER(qobjectType, ComponentWrapName) \
|
||||
WrapperCache::instance.registerWrapper( \
|
||||
QString(#qobjectType), \
|
||||
[](Napi::Env env, QObject* qobject) -> Napi::Object { \
|
||||
qobjectType* exactQObject = dynamic_cast<qobjectType*>(qobject); \
|
||||
Napi::Object wrapper = ComponentWrapName::constructor.New( \
|
||||
{Napi::External<QObject>::New(env, exactQObject)}); \
|
||||
return wrapper; \
|
||||
});
|
||||
#endif // QOBJECT_REGISTER_WRAPPER
|
||||
|
||||
#include "QtCore/QObject/qobject_wrap.h"
|
||||
|
||||
@ -29,8 +29,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget {
|
||||
this, &QGuiApplication::primaryScreenChanged, [=](QScreen* screen) {
|
||||
Napi::Env env = this->emitOnNode.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen>(env, screen, &QScreenWrap::constructor, false);
|
||||
auto instance = WrapperCache::instance.getWrapper(env, screen, true);
|
||||
this->emitOnNode.Call(
|
||||
{Napi::String::New(env, "primaryScreenChanged"), instance});
|
||||
});
|
||||
@ -38,8 +37,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget {
|
||||
QObject::connect(this, &QGuiApplication::screenAdded, [=](QScreen* screen) {
|
||||
Napi::Env env = this->emitOnNode.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen>(env, screen, &QScreenWrap::constructor, false);
|
||||
auto instance = WrapperCache::instance.getWrapper(env, screen, true);
|
||||
this->emitOnNode.Call({Napi::String::New(env, "screenAdded"), instance});
|
||||
});
|
||||
|
||||
@ -47,8 +45,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget {
|
||||
this, &QGuiApplication::screenRemoved, [=](QScreen* screen) {
|
||||
Napi::Env env = this->emitOnNode.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen>(env, screen, &QScreenWrap::constructor, false);
|
||||
auto instance = WrapperCache::instance.getWrapper(env, screen, true);
|
||||
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>(env, window, &QWindowWrap::constructor, false); \
|
||||
return WrapperCache::instance.getWrapper(env, window, true); \
|
||||
} else { \
|
||||
return env.Null(); \
|
||||
} \
|
||||
|
||||
@ -2,19 +2,19 @@
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "Extras/Export/export.h"
|
||||
#include "Extras/Utils/nutils.h"
|
||||
|
||||
|
||||
struct CachedObject {
|
||||
napi_ref ref;
|
||||
napi_env env;
|
||||
};
|
||||
|
||||
typedef Napi::Object (*WrapFunc)(Napi::Env, QObject *);
|
||||
typedef Napi::Object (*WrapFunc)(Napi::Env, QObject*);
|
||||
|
||||
/**
|
||||
* C++ side cache for wrapper objects.
|
||||
@ -37,41 +37,28 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
static WrapperCache instance;
|
||||
|
||||
/**
|
||||
* Get a wrapper for a given Qt object.
|
||||
* Register a function to wrap certain instances of a `QObject` subclass.
|
||||
*
|
||||
* @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.
|
||||
* @return The JS wrapper object.
|
||||
* @param typeName - The name of the `QObject` subclass this wrapper function
|
||||
* applies to.
|
||||
* @param wrapFunc - Function to wrap `QObject` instances.
|
||||
*/
|
||||
template <class T>
|
||||
Napi::Object get(Napi::Env env, T* object, Napi::FunctionReference* constructorFunc, bool isCreatedByNodeGui) {
|
||||
uint64_t ptrHash = extrautils::hashPointerTo53bit(object);
|
||||
if (this->cache.contains(ptrHash)) {
|
||||
napi_value result = nullptr;
|
||||
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 = constructorFunc->New({Napi::External<T>::New(env, object)});
|
||||
|
||||
store(env, extrautils::hashPointerTo53bit(object), object, wrapper, isCreatedByNodeGui);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
void registerWrapper(QString typeName, WrapFunc wrapFunc) {
|
||||
this->wrapperRegistry[typeName] = wrapFunc;
|
||||
}
|
||||
|
||||
Napi::Value getWrapper(Napi::Env env, QObject* qobject) {
|
||||
/**
|
||||
* Get a wrapper for a QObject
|
||||
*
|
||||
* @param env - Napi environment
|
||||
* @param qobject - The QObject or subclass instance to wrap
|
||||
* @param keepAlive - Set this to true if the wrapper object should be kept
|
||||
* alive until the underlying QObject is destroyed regardless of whether
|
||||
* the JS side holding a reference to it or not. (Defaults to false).
|
||||
* @return Napi object wrapping the object
|
||||
*/
|
||||
Napi::Value getWrapper(Napi::Env env, QObject* qobject,
|
||||
bool keepAlive = false) {
|
||||
if (qobject == nullptr) {
|
||||
return env.Null();
|
||||
}
|
||||
@ -88,10 +75,15 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
}
|
||||
}
|
||||
|
||||
// QString className(object->metaObject()->className());
|
||||
// if (this->wrapperRegistry.contains(className)) {
|
||||
// this->wrapperRegistry[className]
|
||||
// }
|
||||
QString className(qobject->metaObject()->className());
|
||||
if (this->wrapperRegistry.contains(className)) {
|
||||
Napi::Object wrapper = this->wrapperRegistry[className](env, qobject);
|
||||
store(env, ptrHash, qobject, wrapper, !keepAlive);
|
||||
return wrapper;
|
||||
} else {
|
||||
qDebug() << "NodeGui: Unable to find wrapper for instance of class "
|
||||
<< className << ".\n\n";
|
||||
}
|
||||
|
||||
return env.Null();
|
||||
}
|
||||
@ -107,7 +99,8 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
* @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) {
|
||||
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);
|
||||
@ -121,8 +114,7 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
static Napi::Object init(Napi::Env env, Napi::Object exports) {
|
||||
exports.Set("WrapperCache_injectCallback",
|
||||
Napi::Function::New<injectDestroyCallback>(env));
|
||||
exports.Set("WrapperCache_store",
|
||||
Napi::Function::New<storeJS>(env));
|
||||
exports.Set("WrapperCache_store", Napi::Function::New<storeJS>(env));
|
||||
return exports;
|
||||
}
|
||||
|
||||
@ -158,14 +150,10 @@ class DLL_EXPORT WrapperCache : public QObject {
|
||||
if (destroyedCallback) {
|
||||
Napi::Env env = destroyedCallback.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
destroyedCallback.Call(
|
||||
env.Global(),
|
||||
{Napi::Value::From(env, ptrHash)});
|
||||
destroyedCallback.Call(env.Global(), {Napi::Value::From(env, ptrHash)});
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
// 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(ptrHash);
|
||||
|
||||
@ -12,13 +12,7 @@ Napi::Object QObjectWrap::init(Napi::Env env, Napi::Object exports) {
|
||||
env, CLASSNAME, {QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QObjectWrap)});
|
||||
constructor = Napi::Persistent(func);
|
||||
exports.Set(CLASSNAME, func);
|
||||
|
||||
WrapperCache::instance.registerWrapper(QString("NObject"),
|
||||
[](Napi::Env env, QObject *qobject) -> Napi::Object {
|
||||
QObject *exactQObject = dynamic_cast<QObject*>(qobject);
|
||||
Napi::Object wrapper = QObjectWrap::constructor.New({Napi::External<QObject>::New(env, exactQObject)});
|
||||
return wrapper;
|
||||
});
|
||||
QOBJECT_REGISTER_WRAPPER(NObject, QObjectWrap);
|
||||
return exports;
|
||||
}
|
||||
|
||||
|
||||
@ -118,8 +118,7 @@ Napi::Value StaticQApplicationWrapMethods::clipboard(
|
||||
Napi::Env env = info.Env();
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
if (clipboard) {
|
||||
return WrapperCache::instance.get<QClipboard>(env,
|
||||
clipboard, &QClipboardWrap::constructor, false);
|
||||
return WrapperCache::instance.getWrapper(env, clipboard, true);
|
||||
} else {
|
||||
return env.Null();
|
||||
}
|
||||
@ -163,7 +162,7 @@ Napi::Value StaticQApplicationWrapMethods::primaryScreen(
|
||||
Napi::Env env = info.Env();
|
||||
auto screen = QApplication::primaryScreen();
|
||||
if (screen) {
|
||||
return WrapperCache::instance.get<QScreen>(env, screen, &QScreenWrap::constructor, false);
|
||||
return WrapperCache::instance.getWrapper(env, screen, true);
|
||||
} else {
|
||||
return env.Null();
|
||||
}
|
||||
@ -176,8 +175,7 @@ Napi::Value StaticQApplicationWrapMethods::screens(
|
||||
Napi::Array jsArray = Napi::Array::New(env, screens.size());
|
||||
for (int i = 0; i < screens.size(); i++) {
|
||||
QScreen* screen = screens[i];
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen>(env, screen, &QScreenWrap::constructor, false);
|
||||
auto instance = WrapperCache::instance.getWrapper(env, screen, true);
|
||||
jsArray[i] = instance;
|
||||
}
|
||||
return jsArray;
|
||||
|
||||
@ -19,6 +19,7 @@ Napi::Object QClipboardWrap::init(Napi::Env env, Napi::Object exports) {
|
||||
QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QClipboardWrap)});
|
||||
constructor = Napi::Persistent(func);
|
||||
exports.Set(CLASSNAME, func);
|
||||
QOBJECT_REGISTER_WRAPPER(QClipboard, QClipboardWrap);
|
||||
return exports;
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ Napi::Object QScreenWrap::init(Napi::Env env, Napi::Object exports) {
|
||||
QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QScreenWrap)});
|
||||
constructor = Napi::Persistent(func);
|
||||
exports.Set(CLASSNAME, func);
|
||||
QOBJECT_REGISTER_WRAPPER(QScreen, QScreenWrap);
|
||||
return exports;
|
||||
}
|
||||
|
||||
|
||||
@ -55,8 +55,7 @@ void QWindowWrap::connectSignalsToEventEmitter() {
|
||||
this->instance.data(), &QWindow::screenChanged, [=](QScreen* screen) {
|
||||
Napi::Env env = this->emitOnNode.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
auto instance =
|
||||
WrapperCache::instance.get<QScreen>(env, screen, &QScreenWrap::constructor, false);
|
||||
auto instance = WrapperCache::instance.getWrapper(env, screen, true);
|
||||
this->emitOnNode.Call(
|
||||
{Napi::String::New(env, "screenChanged"), instance});
|
||||
});
|
||||
@ -81,7 +80,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>(env, screen, &QScreenWrap::constructor, false);
|
||||
return WrapperCache::instance.getWrapper(env, screen, true);
|
||||
} else {
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ Napi::Object QWidgetWrap::init(Napi::Env env, Napi::Object exports) {
|
||||
env, CLASSNAME, {QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QWidgetWrap)});
|
||||
constructor = Napi::Persistent(func);
|
||||
exports.Set(CLASSNAME, func);
|
||||
QOBJECT_REGISTER_WRAPPER(NWidget, QWidgetWrap);
|
||||
return exports;
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ Napi::Object CacheTestQObjectWrap::init(Napi::Env env, Napi::Object exports) {
|
||||
QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(CacheTestQObjectWrap)});
|
||||
constructor = Napi::Persistent(func);
|
||||
exports.Set(CLASSNAME, func);
|
||||
QOBJECT_REGISTER_WRAPPER(CacheTestQObject, CacheTestQObjectWrap);
|
||||
return exports;
|
||||
}
|
||||
|
||||
@ -47,8 +48,7 @@ void CacheTestQObjectWrap::connectSignalsToEventEmitter() {
|
||||
Napi::Value CacheTestQObjectWrap::foo(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
CacheTestQObject* foo = this->instance->foo();
|
||||
return WrapperCache::instance.get<CacheTestQObject>(
|
||||
env, foo, &CacheTestQObjectWrap::constructor, false);
|
||||
return WrapperCache::instance.getWrapper(env, foo);
|
||||
}
|
||||
|
||||
Napi::Value CacheTestQObjectWrap::clearFoo(const Napi::CallbackInfo& info) {
|
||||
@ -60,6 +60,5 @@ Napi::Value CacheTestQObjectWrap::clearFoo(const Napi::CallbackInfo& info) {
|
||||
Napi::Value CacheTestQObjectWrap::bar(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
CacheTestQObject* bar = this->instance->bar();
|
||||
return WrapperCache::instance.get<CacheTestQObject>(
|
||||
env, bar, &CacheTestQObjectWrap::constructor, false);
|
||||
return WrapperCache::instance.getWrapper(env, bar);
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { QObject } from '../QtCore/QObject';
|
||||
import addon from '../utils/addon';
|
||||
import { NativeElement } from './Component';
|
||||
|
||||
@ -15,11 +16,17 @@ import { NativeElement } from './Component';
|
||||
export class WrapperCache {
|
||||
private _strongCache = new Map<number, QObject>();
|
||||
private _weakCache = new Map<number, WeakRef<QObject>>();
|
||||
private _wrapperRegistry = new Map<string, { new (native: any): QObject }>();
|
||||
|
||||
constructor() {
|
||||
addon.WrapperCache_injectCallback(this._objectDestroyedCallback.bind(this));
|
||||
}
|
||||
|
||||
_flush(): void {
|
||||
this._strongCache = new Map<number, QObject>();
|
||||
this._weakCache = new Map<number, WeakRef<QObject>>();
|
||||
}
|
||||
|
||||
private _objectDestroyedCallback(objectId: number): void {
|
||||
if (this._strongCache.has(objectId)) {
|
||||
const wrapper = this._strongCache.get(objectId);
|
||||
@ -47,12 +54,13 @@ export class WrapperCache {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
getWrapper(native: any): QObject | null {
|
||||
if (native == null) {
|
||||
return null;
|
||||
}
|
||||
const id = native.__id__();
|
||||
|
||||
const id = native.__id__();
|
||||
if (this._strongCache.has(id)) {
|
||||
return this._strongCache.get(id);
|
||||
}
|
||||
@ -65,7 +73,19 @@ export class WrapperCache {
|
||||
}
|
||||
}
|
||||
|
||||
return null; // FIXME: Create new wrapper on demand.
|
||||
if (this._wrapperRegistry.has(native.wrapperType)) {
|
||||
const wrapper = new (this._wrapperRegistry.get(native.wrapperType))(native);
|
||||
this.store(wrapper);
|
||||
return wrapper;
|
||||
} else {
|
||||
console.log(`NodeGui: Unable to find JS wrapper for type '${native.wrapperType}'.`);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
registerWrapper(qobjectClassName: string, wrapperConstructor: { new (native: any): QObject }): void {
|
||||
this._wrapperRegistry.set(qobjectClassName, wrapperConstructor);
|
||||
}
|
||||
|
||||
store(wrapper: QObject): void {
|
||||
|
||||
@ -6,7 +6,7 @@ import { wrapperCache } from '../../core/WrapperCache';
|
||||
export class CacheTestQObject extends QObject<QObjectSignals> {
|
||||
constructor(arg?: NativeElement) {
|
||||
let native;
|
||||
if (native == null) {
|
||||
if (arg == null) {
|
||||
native = new addon.CacheTestQObject();
|
||||
} else {
|
||||
native = arg;
|
||||
@ -16,7 +16,7 @@ export class CacheTestQObject extends QObject<QObjectSignals> {
|
||||
}
|
||||
|
||||
foo(): CacheTestQObject {
|
||||
return wrapperCache.get<CacheTestQObject>(CacheTestQObject, this.native.foo());
|
||||
return wrapperCache.getWrapper(this.native.foo()) as CacheTestQObject;
|
||||
}
|
||||
|
||||
clearFoo(): void {
|
||||
@ -24,6 +24,7 @@ export class CacheTestQObject extends QObject<QObjectSignals> {
|
||||
}
|
||||
|
||||
bar(): CacheTestQObject {
|
||||
return wrapperCache.get<CacheTestQObject>(CacheTestQObject, this.native.bar());
|
||||
return wrapperCache.getWrapper(this.native.bar()) as CacheTestQObject;
|
||||
}
|
||||
}
|
||||
wrapperCache.registerWrapper('CacheTestQObjectWrap', CacheTestQObject);
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
import { QObject } from '../../QtCore/QObject';
|
||||
import { QApplication } from '../../QtGui/QApplication';
|
||||
import { CacheTestQObject } from './CacheTestQObject';
|
||||
import { wrapperCache } from '../WrapperCache';
|
||||
|
||||
describe('WrapperCache using CacheTestQObject', () => {
|
||||
const qApp = QApplication.instance();
|
||||
qApp.setQuitOnLastWindowClosed(true);
|
||||
|
||||
it('Cached foo', () => {
|
||||
wrapperCache._flush();
|
||||
const a = new CacheTestQObject();
|
||||
expect(a).not.toBeNull();
|
||||
|
||||
@ -14,11 +16,12 @@ describe('WrapperCache using CacheTestQObject', () => {
|
||||
expect(foo).not.toBeNull();
|
||||
|
||||
const foo2 = a.foo();
|
||||
expect(foo).toBe(foo2);
|
||||
expect(foo.native.__id__()).toBe(foo2.native.__id__());
|
||||
expect(foo).toBe(foo2);
|
||||
});
|
||||
|
||||
it('clearFoo() and wrapper expiration', () => {
|
||||
wrapperCache._flush();
|
||||
const a = new CacheTestQObject();
|
||||
const foo = a.foo();
|
||||
a.clearFoo();
|
||||
@ -26,6 +29,7 @@ describe('WrapperCache using CacheTestQObject', () => {
|
||||
});
|
||||
|
||||
it('clearFoo() and new wrapper', () => {
|
||||
wrapperCache._flush();
|
||||
const a = new CacheTestQObject();
|
||||
const foo = a.foo();
|
||||
const fooId = foo.native.__id__();
|
||||
@ -38,6 +42,7 @@ describe('WrapperCache using CacheTestQObject', () => {
|
||||
});
|
||||
|
||||
it('Cached foo and bar', () => {
|
||||
wrapperCache._flush();
|
||||
const a = new CacheTestQObject();
|
||||
const foo = a.foo();
|
||||
const bar = a.bar();
|
||||
@ -46,11 +51,13 @@ describe('WrapperCache using CacheTestQObject', () => {
|
||||
});
|
||||
|
||||
it('QObject.parent() can be null', () => {
|
||||
wrapperCache._flush();
|
||||
const a = new QObject();
|
||||
expect(a.parent()).toBeNull();
|
||||
});
|
||||
|
||||
it('QObject.parent() === QObject.parent()', () => {
|
||||
wrapperCache._flush();
|
||||
const a = new QObject();
|
||||
const b = new QObject(a);
|
||||
expect(a.native.__id__()).toEqual(b.parent().native.__id__());
|
||||
@ -60,12 +67,14 @@ describe('WrapperCache using CacheTestQObject', () => {
|
||||
});
|
||||
|
||||
it('QObject.delete() clears the native field', () => {
|
||||
wrapperCache._flush();
|
||||
const a = new QObject();
|
||||
a.delete();
|
||||
expect(a.native).toBeNull();
|
||||
});
|
||||
|
||||
it('QObject.delete() clears chains of QObjects and their native field', () => {
|
||||
wrapperCache._flush();
|
||||
const a = new QObject();
|
||||
const b = new QObject(a);
|
||||
a.delete();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user