electron/atom/browser/lib/objects-registry.js

95 lines
2.4 KiB
JavaScript
Raw Normal View History

2016-01-15 22:15:42 +00:00
'use strict';
2016-01-12 02:40:23 +00:00
2016-01-15 22:29:36 +00:00
const v8Util = process.atomBinding('v8_util');
2016-01-12 02:40:23 +00:00
class ObjectsRegistry {
2016-01-15 22:15:42 +00:00
constructor() {
this.nextId = 0;
2016-01-15 22:15:42 +00:00
// Stores all objects by ref-counting.
// (id) => {object, count}
this.storage = {};
2016-01-15 22:15:42 +00:00
// Stores the IDs of objects referenced by WebContents.
// (webContentsId) => [id]
2016-01-15 22:15:42 +00:00
this.owners = {};
}
// Register a new object and return its assigned ID. If the object is already
// registered then the already assigned ID would be returned.
add(webContents, obj) {
// Get or assign an ID to the object.
let id = this.saveToStorage(obj);
2016-01-15 22:15:42 +00:00
// Add object to the set of referenced objects.
let webContentsId = webContents.getId();
let owner = this.owners[webContentsId];
if (!owner) {
owner = this.owners[webContentsId] = new Set();
// Clear the storage when webContents is reloaded/navigated.
webContents.once('render-view-deleted', (event, id) => {
this.clear(id);
});
}
if (!owner.has(id)) {
owner.add(id);
// Increase reference count if not referenced before.
this.storage[id].count++;
2016-01-15 22:15:42 +00:00
}
return id;
}
2016-01-15 22:15:42 +00:00
// Get an object according to its ID.
get(id) {
return this.storage[id].object;
}
2016-01-15 22:15:42 +00:00
// Dereference an object according to its ID.
remove(webContentsId, id) {
// Dereference from the storage.
this.dereference(id);
2016-01-15 22:15:42 +00:00
// Also remove the reference in owner.
this.owners[webContentsId].delete(id);
}
2016-01-15 22:15:42 +00:00
// Clear all references to objects refrenced by the WebContents.
clear(webContentsId) {
let owner = this.owners[webContentsId];
if (!owner)
2016-01-15 22:15:42 +00:00
return;
for (let id of owner)
this.dereference(id);
delete this.owners[webContentsId];
}
2016-01-15 22:15:42 +00:00
// Private: Saves the object into storage and assigns an ID for it.
saveToStorage(object) {
let id = v8Util.getHiddenValue(object, 'atomId');
2016-01-15 22:15:42 +00:00
if (!id) {
id = ++this.nextId;
this.storage[id] = {
count: 0,
object: object
};
v8Util.setHiddenValue(object, 'atomId', id);
}
return id;
}
2016-01-15 22:15:42 +00:00
// Private: Dereference the object from store.
dereference(id) {
let pointer = this.storage[id];
2016-01-15 22:15:42 +00:00
if (pointer == null) {
return;
}
pointer.count -= 1;
2016-01-15 22:15:42 +00:00
if (pointer.count === 0) {
v8Util.deleteHiddenValue(pointer.object, 'atomId');
return delete this.storage[id];
}
}
2016-01-15 22:15:42 +00:00
}
2016-01-12 02:40:23 +00:00
module.exports = new ObjectsRegistry;