1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- "use strict";
- module.metadata = {
- "stability": "experimental"
- };
- let { Class } = require("./heritage");
- let { on, off } = require('../system/events');
- let unloadSubject = require('@loader/unload');
- let disposables = WeakMap();
- function initialize(instance) {
- // Create an event handler that will dispose instance on unload.
- function handler(event) {
- if (event.subject.wrappedJSObject === unloadSubject) {
- instance.destroy();
- }
- }
- // Form weak reference between disposable instance and an unload event
- // handler associated with it. This will make sure that event handler can't
- // be garbage collected as long as instance is referenced. Also note that
- // system events intentionally hold weak reference to an event handler, this
- // will let GC claim both instance and an unload handler before actual add-on
- // unload if instance contains no other references.
- disposables.set(instance, handler);
- on("sdk:loader:destroy", handler);
- }
- exports.initialize = initialize;
- function dispose(instance) {
- // Disposes given instance by removing it from weak map so that handler can
- // be GC-ed even if references to instance are kept. Also unregister unload
- // handler.
- let handler = disposables.get(instance);
- if (handler) off("sdk:loader:destroy", handler);
- disposables.delete(instance);
- }
- exports.dispose = dispose;
- // Base type that takes care of disposing it's instances on add-on unload.
- // Also makes sure to remove unload listener if it's already being disposed.
- let Disposable = Class({
- initialize: function setupDisposable() {
- // First setup instance before initializing it's disposal. If instance
- // fails to initialize then there is no instance to be disposed at the
- // unload.
- this.setup.apply(this, arguments);
- initialize(this);
- },
- setup: function setup() {
- // Implement your initialize logic here.
- },
- dispose: function dispose() {
- // Implement your cleanup logic here.
- },
- destroy: function destroy() {
- // Destroying disposable removes unload handler so that attempt to dispose
- // won't be made at unload & delegates to dispose.
- if (disposables.has(this)) {
- dispose(this);
- this.dispose();
- }
- }
- });
- exports.Disposable = Disposable;
|