Source: components/BaseComponent.js

/**
 * When initialize component.
 * @callback OnInitComponentCallback
 */

/**
 * When load resource.
 * @callback OnLoadResourceComponentCallback
 */

/**
 * When unload resource.
 * @callback OnUnloadResourceComponentCallback
 */

/**
 * When update component.
 * @callback OnUpdateComponentCallback
 * @param {Number} deltaTime The delta time in seconds.
 */

/**
 * Get the center position.
 * @callback GetCenterFunction
 * @param {Array<Number>} target The target to save result.
 * @returns {Array<Number>} The reference of target.
 */

/**
 * Convert self position to world position.
 * @callback SelfToWorldFunction
 * @param {Array<Number>} position The world position.
 * @param {Boolean} ignoreScale True indicates to ignore scale.
 * @param {Array<Number>} target The target to save result.
 * @returns {Array<Number>} The reference of target.
 */

/**
 * Convert world position to screen position.
 * @callback WorldToScreenFunction
 * @param {Array<Number>} position The world position.
 * @param {Array<Number>} target The target to save result.
 * @returns {Array<Number>} The reference of target.
 */

/**
 * @typedef {Object} RenderLayout
 * @property {GetCenterFunction} getCenter
 * @property {SelfToWorldFunction} selfToWorld
 * @property {WorldToScreenFunction} worldToScreen
 * @private
 */

/**
 * When render component.
 * @callback OnRenderComponentCallback
 * @param {RenderLayout} layout The layout info
 * @private
 */

/**
 * When parent change.
 * @callback OnParentChangeComponentCallback
 * @param {THING.BaseObject} parent The new parent.
 */

/**
 * When resize component.
 * @callback OnResizeComponentCallback
 * @param {Number} width The width in pixel.
 * @param {Number} height The height in pixel.
 */

/**
 * When refresh component.
 * @callback OnRefreshComponentCallback
 */

/**
 * When active state change.
 * @callback OnActiveChangeComponentCallback
 * @param {Boolean} value The active state.
 */

/**
 * When (body) visible change.
 * @callback OnVisibleChangeComponentCallback
 * @param {Boolean} value The visible state.
 */

/**
 * When copy component.
 * @callback OnCopyComponentCallback
 * @param {THING.BaseComponent} component The component.
 */

/**
 * When add child object.
 * @callback OnAddChildComponentCallback
 * @param {THING.BaseObject} object The child object.
 */

/**
 * When remove child object.
 * @callback OnRemoveChildComponentCallback
 * @param {THING.BaseObject} object The child object.
 */

/**
 * When before add component.
 * @callback OnBeforeAddComponentCallback
 * @param {THING.BaseObject} object The child object.
 */

/**
 * When after add component.
 * @callback OnAfterAddComponentCallback
 */

/**
 * When before remove component.
 * @callback OnBeforeRemoveComponentCallback
 */

/**
 * When after remove component.
 * @callback OnAfterRemoveComponentCallback
 */

/**
 * When import data.
 * @callback OnImportComponentCallback
 * @param {Object} param The parameters.
 */

/**
 * When export data.
 * @callback OnExportComponentCallback
 * @returns {Object}
 */

/**
 * @class BaseComponent
 * The base component.
 * @memberof THING
 */
class BaseComponent {

	/**
	 * The base component of all components, each component should inherit from it.
	 */
	constructor() {
		/**
		 * Check whether it's instanced component, true indicates auto create it when in register component.
		 * @member {Boolean} isInstancedComponent
		 * @memberof THING.BaseComponent
		 * @instance
		 * @static
		 * @private
		 */

		// #region Overrides

		/**
		 * When initialize callback function.
		 * @member {OnInitComponentCallback} onInit
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When load resource callback function.
		 * @member {OnLoadResourceComponentCallback} onLoadResource
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When unload resource callback function.
		 * @member {OnUnloadResourceComponentCallback} onUnloadResource
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When update callback function.
		 * @member {OnUpdateComponentCallback} onUpdate
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When render callback function.
		 * @member {OnRenderComponentCallback} onRender
		 * @memberof THING.BaseComponent
		 * @instance
		 * @private
		 */

		/**
		 * When change parent callback function.
		 * @member {OnParentChangeComponentCallback} onParentChange
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When resize callback function.
		 * @member {OnResizeComponentCallback} onResize
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When refresh callback function.
		 * @member {OnRefreshComponentCallback} onRefresh
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When active change callback function.
		 * @member {OnActiveChangeComponentCallback} onActiveChange
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When visible change callback function.
		 * @member {OnVisibleChangeComponentCallback} onVisibleChange
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When copy callback function.
		 * @member {OnCopyComponentCallback} onCopy
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When before add child callback function.
		 * @member {OnAddChildComponentCallback} onBeforeAddChild
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When after add child callback function.
		 * @member {OnAddChildComponentCallback} onAfterAddChild
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When before remove child callback function.
		 * @member {OnRemoveChildComponentCallback} onBeforeRemoveChild
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When after remove child callback function.
		 * @member {OnRemoveChildComponentCallback} onAfterRemoveChild
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * Before add.
		 * @member {OnBeforeAddComponentCallback} onBeforeAdd
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * After add.
		 * @member {OnAfterAddComponentCallback} onAfterAdd
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * Before remove.
		 * @member {OnBeforeRemoveComponentCallback} onBeforeRemove
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * After remove.
		 * @member {OnAfterRemoveComponentCallback} onAfterRemove
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When import data.
		 * @member {OnImportComponentCallback} onImport
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		/**
		 * When export data.
		 * @member {OnExportComponentCallback} onExport
		 * @memberof THING.BaseComponent
		 * @instance
		 */

		// #endregion

		this._object = null;
		this._active = true;
	}

	// #region BaseComponent Interface

	/**
	 * When add component.
	 * @param {THING.BaseObject} object The object.
	 */
	onAdd(object) {
		this.triggerBeforeAddCallback(object);
		this._object = object;
		this.triggerAfterAddCallback();
	}

	triggerBeforeAddCallback() {
		if (this.onBeforeAdd) {
			this.onBeforeAdd();
		}
	}

	triggerAfterAddCallback() {
		if (this.onAfterAdd) {
			this.onAfterAdd();
		}
	}

	/**
	 * When remove component.
	 */
	onRemove() {
		this.triggerBeforeRemoveCallback();
		let object = this._object;
		this._object = null;
		this.triggerAfterRemoveCallback(object);
	}

	triggerBeforeRemoveCallback() {
		if (this.onBeforeRemove) {
			this.onBeforeRemove();
		}
	}

	triggerAfterRemoveCallback() {
		if (this.onAfterRemove) {
			this.onAfterRemove();
		}
	}

	// #endregion

	/**
	 * Active or deactive component.
	 * @type {Boolean}
	 */
	get active() {
		return this._active;
	}
	set active(value) {
		if (this._active == value) {
			return;
		}

		this._active = value;

		if (this.onActiveChange) {
			this.onActiveChange(value);
		}
	}

	/**
	 * Get object.
	 * @type {THING.BaseObject}
	 */
	get object() {
		return this._object;
	}

	/**
	 * Get application.
	 * @type {THING.App}
	 */
	get app() {
		let object = this._object;
		if (!object) {
			return null;
		}

		if (object.isApp) {
			return object;
		}
		else {
			return object.app;
		}
	}

}

export { BaseComponent }