Added bridge between old and new event models

This commit is contained in:
Andrew Henry 2016-08-22 14:25:39 +01:00
parent 10e90519c0
commit bd3c6665fb
5 changed files with 47 additions and 40 deletions

View File

@ -1,11 +1,11 @@
define([ define([
'./object-utils', './object-utils',
'./ObjectAPI', './ObjectAPI',
'./objectEventBus' './objectEventEmitter'
], function ( ], function (
utils, utils,
ObjectAPI, ObjectAPI,
objectEventBus objectEventEmitter
) { ) {
function ObjectServiceProvider(objectService, instantiate, topic) { function ObjectServiceProvider(objectService, instantiate, topic) {
this.objectService = objectService; this.objectService = objectService;
@ -13,30 +13,42 @@ define([
this.topicService = topic; this.topicService = topic;
this.generalTopic = topic('mutation'); this.generalTopic = topic('mutation');
this.bridgeEventBuses(this.topicService, this.generalTopic); this.bridgeEventBuses();
} }
/** /**
* Bridges old and new style mutation events to provide compatibility between the two APIs * Bridges old and new style mutation events to provide compatibility between the two APIs
* @private * @private
*/ */
ObjectServiceProvider.prototype.bridgeEventBuses = function (topicService, generalTopic) { ObjectServiceProvider.prototype.bridgeEventBuses = function () {
var generalTopicListener;
function handleMutation(newStyleObject) { var handleMutation = function (newStyleObject) {
var oldStyleObject = utils.toOldFormat(newStyleObject); var keyString = utils.makeKeyString(newStyleObject.key);
var specificTopic = topicService("mutation:" + oldStyleObject.getId()); var oldStyleObject = this.instantiate(utils.toOldFormat(newStyleObject), keyString);
var specificTopic = this.topicService("mutation:" + keyString);
generalTopic.notify(oldStyleObject); // Don't trigger self
if (generalTopicListener){
generalTopicListener();
}
this.generalTopic.notify(oldStyleObject);
specificTopic.notify(oldStyleObject.getModel()); specificTopic.notify(oldStyleObject.getModel());
}
function handleLegacyMutation(legacyObject){ generalTopicListener = this.generalTopic.listen(handleLegacyMutation);
}.bind(this);
var handleLegacyMutation = function (legacyObject){
var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId()); var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
objectEventBus.emit(newStyleObject.key.identifier + ":*", newStyleObject);
}
objectEventBus.on('mutation', handleMutation) //Don't trigger self
generalTopic.listen(handleLegacyMutation); objectEventEmitter.off('mutation', handleMutation);
objectEventEmitter.emit(newStyleObject.key.identifier + ":*", newStyleObject);
objectEventEmitter.on('mutation', handleMutation);
}.bind(this);
objectEventEmitter.on('mutation', handleMutation);
generalTopicListener = this.generalTopic.listen(handleLegacyMutation);
}; };
ObjectServiceProvider.prototype.save = function (object) { ObjectServiceProvider.prototype.save = function (object) {
@ -66,7 +78,7 @@ define([
// Injects new object API as a decorator so that it hijacks all requests. // Injects new object API as a decorator so that it hijacks all requests.
// Object providers implemented on new API should just work, old API should just work, many things may break. // Object providers implemented on new API should just work, old API should just work, many things may break.
function LegacyObjectAPIInterceptor(ROOTS, instantiate, objectService) { function LegacyObjectAPIInterceptor(ROOTS, instantiate, topic, objectService) {
this.getObjects = function (keys) { this.getObjects = function (keys) {
var results = {}, var results = {},
promises = keys.map(function (keyString) { promises = keys.map(function (keyString) {
@ -85,7 +97,7 @@ define([
}; };
ObjectAPI._supersecretSetFallbackProvider( ObjectAPI._supersecretSetFallbackProvider(
new ObjectServiceProvider(objectService, instantiate) new ObjectServiceProvider(objectService, instantiate, topic)
); );
ROOTS.forEach(function (r) { ROOTS.forEach(function (r) {

View File

@ -1,9 +1,13 @@
define([ define([
'lodash' 'lodash',
'./objectEventEmitter'
], function ( ], function (
_ _,
objectEventEmitter
) { ) {
var ANY_OBJECT_EVENT = "mutation";
/** /**
* The MutableObject wraps a DomainObject and provides getters and * The MutableObject wraps a DomainObject and provides getters and
* setters for * setters for
@ -11,8 +15,7 @@ define([
* @param object * @param object
* @constructor * @constructor
*/ */
function MutableObject(eventEmitter, object) { function MutableObject(object) {
this.eventEmitter = eventEmitter;
this.object = object; this.object = object;
this.unlisteners = []; this.unlisteners = [];
} }
@ -29,18 +32,22 @@ define([
MutableObject.prototype.on = function(path, callback) { MutableObject.prototype.on = function(path, callback) {
var fullPath = qualifiedEventName(this.object, path); var fullPath = qualifiedEventName(this.object, path);
this.eventEmitter.on(fullPath, callback); objectEventEmitter.on(fullPath, callback);
this.unlisteners.push(this.eventEmitter.off.bind(this.eventEmitter, fullPath, callback)); this.unlisteners.push(objectEventEmitter.off.bind(objectEventEmitter, fullPath, callback));
}; };
MutableObject.prototype.set = function (path, value) { MutableObject.prototype.set = function (path, value) {
_.set(this.object, path, value); _.set(this.object, path, value);
_.set(this.object, 'modified', Date.now());
//Emit event specific to property //Emit event specific to property
this.eventEmitter.emit(qualifiedEventName(this.object, path), value); objectEventEmitter.emit(qualifiedEventName(this.object, path), value);
//Emit wildcare event //Emit wildcare event
this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object); objectEventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
//Emit a general "any object" event
objectEventEmitter.emit(ANY_OBJECT_EVENT, this.object);
}; };
return MutableObject; return MutableObject;

View File

@ -1,11 +1,9 @@
define([ define([
'lodash', 'lodash',
'EventEmitter',
'./object-utils', './object-utils',
'./MutableObject' './MutableObject'
], function ( ], function (
_, _,
EventEmitter,
utils, utils,
MutableObject MutableObject
) { ) {
@ -18,8 +16,7 @@ define([
var Objects = {}, var Objects = {},
ROOT_REGISTRY = [], ROOT_REGISTRY = [],
PROVIDER_REGISTRY = {}, PROVIDER_REGISTRY = {},
FALLBACK_PROVIDER, FALLBACK_PROVIDER;
eventEmitter = new EventEmitter();
Objects._supersecretSetFallbackProvider = function (p) { Objects._supersecretSetFallbackProvider = function (p) {
FALLBACK_PROVIDER = p; FALLBACK_PROVIDER = p;
@ -83,17 +80,7 @@ define([
}; };
Objects.getMutable = function (object) { Objects.getMutable = function (object) {
var mutable = new MutableObject(eventEmitter, object); return new MutableObject(object);
var id = object.key.identifier;
var specificTopic = topic("mutation:" + id);
function legacyEvent (modifiedObject) {
specificTopic.notify(utils.toOldFormat(modifiedObject));
};
// Add legacy event support
mutable.on("*", legacyEvent);
return mutable;
}; };
return Objects; return Objects;

View File

@ -40,7 +40,8 @@ define([
implementation: LegacyObjectAPIInterceptor, implementation: LegacyObjectAPIInterceptor,
depends: [ depends: [
"roots[]", "roots[]",
"instantiate" "instantiate",
"topic"
] ]
} }
] ]