const Event = require('r3-event'); const Utils = require('r3-utils'); /** OPTIONS_START OPTIONS_END INSTANCE_OPTIONS_MAPPING_START INSTANCE_OPTIONS_MAPPING_END LINKED_OBJECTS_START LINKED_OBJECTS_END EXCLUDED_FROM_INSTANCE_OPTIONS_START EXCLUDED_FROM_INSTANCE_OPTIONS_END **/ class Event { //CONSTRUCTOR_TEMPLATE_START constructor(options) { if (Utils.UndefinedOrNull(options)) { options = {}; } options.id = Utils.RandomId(10); options.name = 'Event (' + options.id + ')'; Event.Emit(Event.OBJECT_CREATED, this); //OPTIONS_INIT_START //OPTIONS_INIT_END //CUSTOM_OPTIONS_INIT_START //CUSTOM_OPTIONS_INIT_END Object.assign(this, options); //CUSTOM_BEFORE_INIT_START //CUSTOM_BEFORE_INIT_END Event.Emit(Event.OBJECT_INITIALIZED, this); } //CONSTRUCTOR_TEMPLATE_END //CREATE_INSTANCE_TEMPLATE_START createInstance() { //CREATE_INSTANCE_BEFORE_START super.createInstance(); this.emit(Event.CREATE_INSTANCE, this); if (this.runtime === 'graphics') { this.graphics.createInstance( { //CREATE_INSTANCE_OPTIONS_START //CREATE_INSTANCE_OPTIONS_END }, this ) } //CREATE_INSTANCE_BEFORE_END //CUSTOM_CREATE_INSTANCE_START //CUSTOM_CREATE_INSTANCE_END //CREATE_INSTANCE_AFTER_START this.emit(Event.INSTANCE_CREATED, this); //CREATE_INSTANCE_AFTER_END } //CREATE_INSTANCE_TEMPLATE_END //UPDATE_INSTANCE_TEMPLATE_START updateInstance(property) { //UPDATE_INSTANCE_BEFORE_START this.emit(Event.UPDATE_INSTANCE_BEFORE, this); //UPDATE_INSTANCE_BEFORE_END //UPDATE_INSTANCE_OPTIONS_START //UPDATE_INSTANCE_OPTIONS_END //CUSTOM_UPDATE_INSTANCE_START //CUSTOM_UPDATE_INSTANCE_END //UPDATE_INSTANCE_AFTER_START this.emit(Event.UPDATE_INSTANCE_AFTER, this); //UPDATE_INSTANCE_AFTER_END } //UPDATE_INSTANCE_TEMPLATE_END //UPDATE_FROM_INSTANCE_TEMPLATE_START updateFromInstance(property) { //UPDATE_FROM_INSTANCE_BEFORE_START this.emit(Event.UPDATE_FROM_INSTANCE_BEFORE, this); //UPDATE_FROM_INSTANCE_BEFORE_END //UPDATE_FROM_INSTANCE_OPTIONS_START //UPDATE_FROM_INSTANCE_OPTIONS_END //CUSTOM_UPDATE_FROM_INSTANCE_START //CUSTOM_UPDATE_FROM_INSTANCE_END //UPDATE_FROM_INSTANCE_AFTER_START this.emit(Event.UPDATE_FROM_INSTANCE_AFTER, this); //UPDATE_FROM_INSTANCE_AFTER_END } //UPDATE_FROM_INSTANCE_TEMPLATE_END //DISPOSE_TEMPLATE_START dispose() { //DISPOSE_BEFORE_START this.emit(Event.DISPOSE_OBJECT, this); //DISPOSE_BEFORE_END //CUSTOM_DISPOSE_START //CUSTOM_DISPOSE_END //DISPOSE_AFTER_START this.emit(Event.OBJECT_DISPOSED, this); //DISPOSE_AFTER_END } //DISPOSE_TEMPLATE_END //DISPOSE_INSTANCE_TEMPLATE_START disposeInstance() { //DISPOSE_INSTANCE_BEFORE_START super.disposeInstance(); this.emit(Event.DISPOSE_INSTANCE, this); //DISPOSE_INSTANCE_BEFORE_END //CUSTOM_DISPOSE_INSTANCE_START //CUSTOM_DISPOSE_INSTANCE_END //DISPOSE_INSTANCE_AFTER_START this.emit(Event.INSTANCE_DISPOSED, this); //DISPOSE_INSTANCE_AFTER_END } //DISPOSE_INSTANCE_TEMPLATE_END //CUSTOM_IMPLEMENTATION_START /** * Some nice Events handling * @type {{}} */ static Subscriptions = {}; static Subscribe( eventName, fn ) { /** * Todo - maybe eventually store a boolean which indicates if the function has been executed */ let subscriptionId = Utils.RandomId(10); if (Event.Subscriptions.hasOwnProperty(eventName)) { if (Event.Subscriptions[eventName][subscriptionId]) { throw new Error('A component can only subscribe to a particular event ID once'); } Event.Subscriptions[eventName][subscriptionId] = fn; } else { Event.Subscriptions[eventName] = {}; Event.Subscriptions[eventName][subscriptionId] = fn; } /** * Return a handle to the caller to allow us to unsubscribe to this event */ return { fn: fn, remove: function (eventId, subscriptionId) { return function () { /** * Stop listening for this event from this component */ delete Event.Subscriptions[eventId][subscriptionId]; /** * If the length of listeners is 0, stop referencing this event * @type {string[]} */ let listeners = Object.keys(Event.Subscriptions[eventId]); if (listeners.length === 0) { delete Event.Subscriptions[eventId]; } } }(eventName, subscriptionId), subscriptionId : subscriptionId }; }; /** * Subscribe to some events * @param eventName * @param callback */ subscribe( eventName, callback ) { return Event.Subscribe(eventName, callback.bind(this)); }; /** * Static Synchronous Event - Calls clientCallback directly after the event result is obtained * @param eventId * @param data * @param clientCallback is executed ideally when the event completed * @param clientErrorCallback * @returns {number} of callbacks executed * @constructor */ static Emit( eventId, data, clientCallback, clientErrorCallback ) { if (Event.Subscriptions.hasOwnProperty(eventId)) { let subscriptionIds = Object.keys(Event.Subscriptions[eventId]); subscriptionIds.map( function(subscriptionId) { try { let result = Event.Subscriptions[eventId][subscriptionId](data); if (clientCallback) { clientCallback(result); } } catch (error) { if (clientErrorCallback) { clientErrorCallback(error); } else { console.error(error); throw error; } } } ) } } emit( eventName, data, clientCallback, clientErrorCallback ) { return Event.Emit( eventName, data, clientCallback, clientErrorCallback ); } /** * Execute the functions which subscribe to this event, but don't process the client callback - the subscription function * should execute the client callback * @param eventId * @param data * @param clientCallback * @param clientErrorCallback * @returns {number} * @constructor */ static Async( eventId, data, clientCallback, clientErrorCallback ) { if (Event.Subscriptions.hasOwnProperty(eventId)) { let subscriptionIds = Object.keys(Event.Subscriptions[eventId]); subscriptionIds.map( function(subscriptionId) { try { Event.Subscriptions[eventId][subscriptionId](data, clientCallback, clientErrorCallback); } catch (error) { if (clientErrorCallback) { clientErrorCallback(error); } else { console.error(error); throw error; } } } ) } }; //CUSTOM_IMPLEMENTATION_END } //CUSTOM_OUT_OF_CLASS_IMPLEMENTATION_START //EVENT_GENERATED_START Event.CREATE_INSTANCE = 0x1; Event.DISPOSE_INSTANCE = 0x2; Event.DISPOSE_OBJECT = 0x3; Event.GET_RUNTIME = 0x4; Event.GET_WINDOW_SIZE = 0x5; Event.INSTANCE_CREATED = 0x6; Event.INSTANCE_DISPOSED = 0x7; Event.OBJECT_CREATED = 0x8; Event.OBJECT_DISPOSED = 0x9; Event.OBJECT_INITIALIZED = 0xa; Event.PAUSE = 0xb; Event.RESTART = 0xc; Event.START = 0xd; Event.UPDATE_FROM_INSTANCE_AFTER = 0xe; Event.UPDATE_FROM_INSTANCE_BEFORE = 0xf; Event.UPDATE_INSTANCE_AFTER = 0x10; Event.UPDATE_INSTANCE_BEFORE = 0x11; Event.MAX_EVENTS = 0x12; Event.GetEventName = function(eventId) { switch(eventId) { case 0x1 : return 'create_instance'; case 0x2 : return 'dispose_instance'; case 0x3 : return 'dispose_object'; case 0x4 : return 'get_runtime'; case 0x5 : return 'get_window_size'; case 0x6 : return 'instance_created'; case 0x7 : return 'instance_disposed'; case 0x8 : return 'object_created'; case 0x9 : return 'object_disposed'; case 0xa : return 'object_initialized'; case 0xb : return 'pause'; case 0xc : return 'restart'; case 0xd : return 'start'; case 0xe : return 'update_from_instance_after'; case 0xf : return 'update_from_instance_before'; case 0x10 : return 'update_instance_after'; case 0x11 : return 'update_instance_before'; default : throw new Error('Event type not defined : ' + eventId); } }; //EVENT_GENERATED_END //CUSTOM_OUT_OF_CLASS_IMPLEMENTATION_END module.exports = Event;