Events, subscriptions, shortcuts
At the top of any subclass of
CocoModel, etc.) can be any combination of three objects:
shortcuts. These are the main place for callbacks to be specified.
module.exports = class TomeView extends View subscriptions: 'tome:spell-loaded': 'onSpellLoaded' 'tome:cast-spell': 'onCastSpell' 'tome:toggle-spell-list': 'onToggleSpellList' 'surface:sprite-selected': 'onSpriteSelected'
Subscriptions are built on Validated-Backbone-Mediator. These are for inter-object communication that needs to be very generalized. This happens for example when:
- Relationships between objects are distant, varied or subject to change
- Scripts in levels need to be able to use them, either to trigger the script or to cause an effect of the script.
CocoView subclasses support subscriptions. Objects subscribe on construction by default and tear them down when destroy is called.
See the Backbone-Mediator repository for more details.
If one object needs to listen to another and they are closely related, such as a view that opens a modal and needs to wait for the modal to return a result, use Backbone Events instead.
To regulate what objects get passed around (or published), all such objects are subject to JSON Schema validation. This allows for all of these objects to be defined and documented in a central location, namely
app/schemas. The validation itself is done by tv4; all we need to do is write down the schemas.
Schemas go into two categories: object definitions and channel descriptions. The latter is the most important as it defines what the objects look like that a certain channel will accept. The former allows for describing other objects (anything, really) that other schemas may refer to for completeness.
An example of this is the
level:view-switched channel, which simply accepts
Here's a short
jQueryEvent: title: "jQuery Event" id: "jQueryEvent" $schema: "http://json-schema.org/draft-04/schema#" description: "A standard jQuery Event" type: "object" properties: altKey: type: "boolean" required:  additionalProperties: true
... and here follows the
level:view-switched definition, which is actually just a
jQueryEvent with a
"level:view-switched": title: "Level View Switched" $schema: "http://json-schema.org/draft-04/schema#" description: "Published whenever the view switches" $ref: "jQueryEvent"
See how the
level:view-switched schema uses
$ref to refer to the
jQueryEvent? It's that simple really.
module.exports = class PlayLevelView extends View events: 'click #level-done-btn': 'onClickLevelDoneButton' 'change #language-select': 'onChangeLanguageSelect'
Events are Backbone Events for Backbone Views. These are for things like mouse clicks or other DOM events.
CocoView is a subclass of Backbone's
View class so they all support events, and are handled by Backbone as usual. See the Backbone docs for more details.
Callback functions should start with "on", with the rest being the CamelCase version the jQuery event signature. Give the element an id or class which leads to a sensible callback function name, one that ends with the HTML element or Bootstrap component name, such as in the above example. This guideline makes it easier to match element with callback and encourages names which describe both the element and the action.
module.exports = Surface = class Surface extends FoundationClass shortcuts: 'alt+\\': 'onToggleDebug' 'alt+g': 'onToggleGrid'
Shortcuts are keyboard shortcuts. These are handled by keymaster.
Coco* subclasses support keyboard shortcuts. They are enabled when the object is created and removed when
destroy is called.
Shortcuts that have to work inside the LevelView must go through ACE in the SpellView--see the Tome docs for more info.
All these are defined as objects in the class prototype. Normally subclassing would overwrite superclass properties, but for events, subscriptions and shortcuts the classes will merge these objects together. So for example, subscriptions in
CocoView would apply to all its subclasses, unless the subclasses have their own handlers for the same subscription.