Add logging/debugging controls for the wrapper lifecycle
This commit is contained in:
parent
fcdbfb07c3
commit
0f9ad1e028
@ -189,3 +189,6 @@ export { Margins } from './lib/utils/Margins';
|
||||
|
||||
// Test:
|
||||
export { CacheTestQObject } from './lib/core/__test__/CacheTestQObject';
|
||||
|
||||
// Debug:
|
||||
export { setLogCreateQObject, setLogDestroyQObject } from './lib/core/WrapperCache';
|
||||
|
||||
@ -14,14 +14,29 @@ import { NativeElement } from './Component';
|
||||
* wrapper automatically and unexpectedly garbage collected.
|
||||
*/
|
||||
export class WrapperCache {
|
||||
// Cache for wrapper where we always hold onto the wrapper until the C++
|
||||
// object is destroyed by Qt. We don't let the V8 GC destroy the wrapper
|
||||
// first. These wrapper often have signal handlers which are kept alive
|
||||
// by the wrapper themselves, and not because they are part of a
|
||||
// `NFooBar` subclass. For example, the `QScreen` attaches signal
|
||||
// handlers to the C++ `QScreen`. If the wrapper is GC'ed, then the
|
||||
// signals handlers also stop working.
|
||||
private _strongCache = new Map<number, QObject>();
|
||||
|
||||
// WeakCache is for normal wrappers around `QObject` based `NFooBar`
|
||||
// subclasses.
|
||||
private _weakCache = new Map<number, WeakRef<QObject>>();
|
||||
|
||||
private _wrapperRegistry = new Map<string, { new (native: any): QObject }>();
|
||||
|
||||
constructor() {
|
||||
addon.WrapperCache_injectCallback(this._objectDestroyedCallback.bind(this));
|
||||
}
|
||||
|
||||
logCreateQObject = false;
|
||||
logDestoryQObject = false;
|
||||
|
||||
// This is only need for testing purposes
|
||||
_flush(): void {
|
||||
this._strongCache = new Map<number, QObject>();
|
||||
this._weakCache = new Map<number, WeakRef<QObject>>();
|
||||
@ -32,6 +47,11 @@ export class WrapperCache {
|
||||
const wrapper = this._strongCache.get(objectId);
|
||||
wrapper.native = null;
|
||||
this._strongCache.delete(objectId);
|
||||
|
||||
if (this.logDestoryQObject) {
|
||||
console.log(`NodeGui: Destroyed C++ object with ID: ${objectId}.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const wrapperRef = this._weakCache.get(objectId);
|
||||
@ -40,17 +60,20 @@ export class WrapperCache {
|
||||
if (wrapper != null) {
|
||||
wrapper.native = null;
|
||||
this._weakCache.delete(objectId);
|
||||
if (this.logDestoryQObject) {
|
||||
console.log(`NodeGui: Destroyed C++ object with ID: ${objectId}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get<T extends QObject>(wrapperConstructor: { new (native: any): T }, native: NativeElement): T {
|
||||
const id = native.__id__();
|
||||
if (this._strongCache.has(id)) {
|
||||
return this._strongCache.get(id) as T;
|
||||
const objectId = native.__id__();
|
||||
if (this._strongCache.has(objectId)) {
|
||||
return this._strongCache.get(objectId) as T;
|
||||
}
|
||||
const wrapper = new wrapperConstructor(native);
|
||||
this._strongCache.set(id, wrapper);
|
||||
this._strongCache.set(objectId, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@ -90,11 +113,34 @@ export class WrapperCache {
|
||||
|
||||
store(wrapper: QObject): void {
|
||||
if (wrapper.native != null) {
|
||||
const id = wrapper.native.__id__();
|
||||
this._weakCache.set(id, new WeakRef<QObject>(wrapper));
|
||||
const objectId = wrapper.native.__id__();
|
||||
this._weakCache.set(objectId, new WeakRef<QObject>(wrapper));
|
||||
|
||||
addon.WrapperCache_store(wrapper.native, wrapper.native.__external_qobject__());
|
||||
if (this.logCreateQObject) {
|
||||
console.log(`NodeGui: Created C++ object with ID: ${objectId}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export const wrapperCache = new WrapperCache();
|
||||
|
||||
/**
|
||||
* Turn on/off logging when QObjects are created.
|
||||
*
|
||||
* @param on When true, logging is written to console when QObjects are
|
||||
* created by NodeGui.
|
||||
*/
|
||||
export function setLogCreateQObject(on: boolean): void {
|
||||
wrapperCache.logCreateQObject = on;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn on/off logging when QObjects are destoryed.
|
||||
*
|
||||
* @param on When true, logging is written to console when QObjects are
|
||||
* destroyed.
|
||||
*/
|
||||
export function setLogDestroyQObject(on: boolean): void {
|
||||
wrapperCache.logDestoryQObject = on;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user