/** @module delite/Destroyable */
define([
"dcl/advise",
"dcl/dcl"
], function (advise, dcl) {
// module:
// delite/Destroyable
/**
* @summary
* Mixin to track handles and release them when instance is destroyed.
* @description
* Call this.own(...) on list of handles (returned from dojo/aspect, dojo/on,
* dojo/Stateful::watch, or any class (including widgets) with a destroy() or remove() method.
* Then call destroy() later to destroy this instance and release the resources.
* @class module:delite/Destroyable
* @mixin
*/
var Destroyable = dcl(null, /** @lends module:delite/Destroyable# */{
// summary:
// Mixin to track handles and release them when instance is destroyed.
// description:
// Call this.own(...) on list of handles (returned from dojo/aspect, dojo/on,
// dojo/Stateful::watch, or any class (including widgets) with a destroy() or remove() method.
// Then call destroy() later to destroy this instance and release the resources.
/**
* Destroy this class, releasing any resources registered via own().
*/
destroy: dcl.advise({
before: function () { this._beingDestroyed = true; },
after: function () { this._destroyed = true; }
}),
/*=====
destroy: function () {
// summary:
// Destroy this class, releasing any resources registered via own().
},
=====*/
/**
* Track specified handles and remove/destroy them when this instance is destroyed, unless they were
* already removed/destroyed manually.
*/
own: function () {
// summary:
// Track specified handles and remove/destroy them when this instance is destroyed, unless they were
// already removed/destroyed manually.
// tags:
// protected
// returns:
// The array of specified handles, so you can do for example:
// | var handle = this.own(on(...))[0];
// transform arguments into an Array
var ary = Array.prototype.slice.call(arguments);
ary.forEach(function (handle) {
var destroyMethodName = "destroy" in handle ? "destroy" : "remove";
// When this.destroy() is called, destroy handle. Since I'm using aspect.before(),
// the handle will be destroyed before a subclass's destroy() method starts running.
var odh = advise.before(this, "destroy", function () {
handle[destroyMethodName]();
});
// If handle is destroyed manually before this.destroy() is called,
// remove the listener set directly above.
var hdh = advise.after(handle, destroyMethodName, function () {
odh.destroy();
hdh.destroy();
});
}, this);
return ary; // [handle]
}
});
dcl.chainBefore(Destroyable, "destroy");
return Destroyable;
});