const Utils = require('r3-utils'); /** OPTIONS_START OPTIONS_END **/ class Event { //CONSTRUCTOR_TEMPLATE_START constructor(options) { Event.Emit(Event.OBJECT_CREATED, this); //OPTIONS_INIT_START if (typeof options === 'undefined') { options = {}; } //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 //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.COMPONENT_INITIALIZED = 0x1; Event.CREATE_INSTANCE_BEFORE = 0x2; Event.DISPOSE_INSTANCE = 0x3; Event.DISPOSE_OBJECT = 0x4; Event.GET_RUNTIME = 0x5; Event.GET_WINDOW_SIZE = 0x6; Event.INSTANCE_CREATED = 0x7; Event.INSTANCE_DISPOSED = 0x8; Event.OBJECT_CREATED = 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 'component_initialized'; case 0x2 : return 'create_instance_before'; case 0x3 : return 'dispose_instance'; case 0x4 : return 'dispose_object'; case 0x5 : return 'get_runtime'; case 0x6 : return 'get_window_size'; case 0x7 : return 'instance_created'; case 0x8 : return 'instance_disposed'; case 0x9 : return 'object_created'; 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;