UNPKG

lettuce

Version:

Lettuce JS, Mini Mobile Framework for Romantic with DSL.

317 lines (289 loc) 9.96 kB
/** * @preserve MinPubSub * a micro publish/subscribe messaging framework * @see https://github.com/daniellmb/MinPubSub * @author Daniel Lamb <daniellmb.com> * * Released under the MIT License */ (function () { /** * There is no constructor function for me.event * @namespace me.event * @memberOf me */ me.event = (function () { // hold public stuff inside the singleton var api = {}; /** * the channel/subscription hash * @ignore */ var cache = {}; /* * PUBLIC */ /** * Channel Constant when the game is paused <br> * Data passed : none <br> * @public * @constant * @type String * @name me.event#STATE_PAUSE */ api.STATE_PAUSE = "me.state.onPause"; /** * Channel Constant for when the game is resumed <br> * Data passed : {Number} time in ms the game was paused * @public * @constant * @type String * @name me.event#STATE_RESUME */ api.STATE_RESUME = "me.state.onResume"; /** * Channel Constant when the game is stopped <br> * Data passed : none <br> * @public * @constant * @type String * @name me.event#STATE_STOP */ api.STATE_STOP = "me.state.onStop"; /** * Channel Constant for when the game is restarted <br> * Data passed : {Number} time in ms the game was stopped * @public * @constant * @type String * @name me.event#STATE_RESTART */ api.STATE_RESTART = "me.state.onRestart"; /** * Channel Constant for when the game manager is initialized <br> * Data passed : none <br> * @public * @constant * @type String * @name me.event#GAME_INIT */ api.GAME_INIT = "me.game.onInit"; /** * Channel Constant for when a level is loaded <br> * Data passed : {String} Level Name * @public * @constant * @type String * @name me.event#LEVEL_LOADED */ api.LEVEL_LOADED = "me.game.onLevelLoaded"; /** * Channel Constant for when everything has loaded <br> * Data passed : none <br> * @public * @constant * @type String * @name me.event#LOADER_COMPLETE */ api.LOADER_COMPLETE = "me.loader.onload"; /** * Channel Constant for displaying a load progress indicator <br> * Data passed : {Number} [0 .. 1], {Resource} resource object<br> * @public * @constant * @type String * @name me.event#LOADER_PROGRESS */ api.LOADER_PROGRESS = "me.loader.onProgress"; /** * Channel Constant for pressing a binded key <br> * Data passed : {String} user-defined action, {Number} keyCode, * {Boolean} edge state <br> * Edge-state is for detecting "locked" key bindings. When a locked key * is pressed and held, the first event will have have the third * argument set true. subsequent events will continue firing with the * third argument set false. * @public * @constant * @type String * @name me.event#KEYDOWN * @example * me.input.bindKey(me.input.KEY.X, "jump", true); // Edge-triggered * me.input.bindKey(me.input.KEY.Z, "shoot"); // Level-triggered * me.event.subscribe(me.event.KEYDOWN, function (action, keyCode, edge) { * // Checking bound keys * if (action === "jump") { * if (edge) { * this.doJump(); * } * * // Make character fall slower when holding the jump key * this.vel.y = this.gravity; * } * }); */ api.KEYDOWN = "me.input.keydown"; /** * Channel Constant for releasing a binded key <br> * Data passed : {String} user-defined action, {Number} keyCode <br> * @public * @constant * @type String * @name me.event#KEYUP * @example * me.event.subscribe(me.event.KEYUP, function (action, keyCode) { * // Checking unbound keys * if (keyCode == me.input.KEY.ESC) { * if (me.state.isPaused()) { * me.state.resume(); * } * else { * me.state.pause(); * } * } * }); */ api.KEYUP = "me.input.keyup"; /** * Channel Constant for mousemove or dragmove events on the game viewport <br> * Data passed : {Object} the mousemove or dragmove event <br> * @public * @constant * @type String * @name me.event#MOUSEMOVE */ api.MOUSEMOVE = "me.game.pointermove"; /** * Channel Constant for dragstart events on a Draggable entity <br> * Data passed: * {Object} the drag event <br> * {Object} the Draggable entity <br> * @public * @constant * @type String * @name me.event#DRAGSTART */ api.DRAGSTART = "me.game.dragstart"; /** * Channel Constant for dragend events on a Draggable entity <br> * Data passed: * {Object} the drag event <br> * {Object} the Draggable entity <br> * @public * @constant * @type String * @name me.event#DRAGEND */ api.DRAGEND = "me.game.dragend"; /** * Channel Constant for when the (browser) window is resized <br> * Data passed : {Event} Event object <br> * @public * @constant * @type String * @name me.event#WINDOW_ONRESIZE */ api.WINDOW_ONRESIZE = "window.onresize"; /** * Channel Constant for when the device is rotated <br> * Data passed : {Event} Event object <br> * @public * @constant * @type String * @name me.event#WINDOW_ONORIENTATION_CHANGE */ api.WINDOW_ONORIENTATION_CHANGE = "window.orientationchange"; /** * Channel Constant for when the (browser) window is scrolled <br> * Data passed : {Event} Event object <br> * @public * @constant * @type String * @name me.event#WINDOW_ONSCROLL */ api.WINDOW_ONSCROLL = "window.onscroll"; /** * Channel Constant for when the viewport position is updated <br> * Data passed : {me.Vector2d} viewport position vector <br> * @public * @constant * @type String * @name me.event#VIEWPORT_ONCHANGE */ api.VIEWPORT_ONCHANGE = "viewport.onchange"; /** * Publish some data on a channel * @name me.event#publish * @public * @function * @param {String} channel The channel to publish on * @param {Array} arguments The data to publish * * @example Publish stuff on '/some/channel'. * Anything subscribed will be called with a function * signature like: function (a,b,c){ ... } * * me.event.publish("/some/channel", ["a","b","c"]); * */ api.publish = function (channel, args) { var subs = cache[channel], len = subs ? subs.length : 0; //can change loop or reverse array if the order matters while (len--) { subs[len].apply(window, args || []); // is window correct here? } }; /** * Register a callback on a named channel. * @name me.event#subscribe * @public * @function * @param {String} channel The channel to subscribe to * @param {Function} callback The event handler, any time something is * published on a subscribed channel, the callback will be called * with the published array as ordered arguments * @return {handle} A handle which can be used to unsubscribe this * particular subscription * @example * me.event.subscribe("/some/channel", function (a, b, c){ doSomething(); }); */ api.subscribe = function (channel, callback) { if (!cache[channel]) { cache[channel] = []; } cache[channel].push(callback); return [ channel, callback ]; // Array }; /** * Disconnect a subscribed function for a channel. * @name me.event#unsubscribe * @public * @function * @param {Array|String} handle The return value from a subscribe call or the * name of a channel as a String * @param {Function} [callback] The callback to be unsubscribed. * @example * var handle = me.event.subscribe("/some/channel", function (){}); * me.event.unsubscribe(handle); * * // Or alternatively ... * * var callback = function (){}; * me.event.subscribe("/some/channel", callback); * me.event.unsubscribe("/some/channel", callback); */ api.unsubscribe = function (handle, callback) { var subs = cache[callback ? handle : handle[0]], len = subs ? subs.length : 0; callback = callback || handle[1]; while (len--) { if (subs[len] === callback) { subs.splice(len, 1); } } }; // return our object return api; })(); })();