Merge pull request #1379 from twpayne/observable-struct

Make ol.Observable and ol.Object @structs
This commit is contained in:
Tom Payne
2013-12-13 12:33:40 -08:00
2 changed files with 40 additions and 52 deletions
+38 -52
View File
@@ -103,15 +103,6 @@ ol.ObjectAccessor.prototype.transform = function(from, to) {
}; };
/**
* @enum {string}
*/
ol.ObjectProperty = {
ACCESSORS: 'ol_accessors_',
BINDINGS: 'ol_bindings_'
};
/** /**
* Base class implementing KVO (Key Value Observing). * Base class implementing KVO (Key Value Observing).
@@ -129,6 +120,12 @@ ol.Object = function(opt_values) {
*/ */
this.values_ = {}; this.values_ = {};
/**
* @private
* @type {Object.<string, ol.ObjectAccessor>}
*/
this.accessors_ = {};
/** /**
* Lookup of beforechange listener keys. * Lookup of beforechange listener keys.
* @type {Object.<string, goog.events.Key>} * @type {Object.<string, goog.events.Key>}
@@ -136,6 +133,12 @@ ol.Object = function(opt_values) {
*/ */
this.beforeChangeListeners_ = {}; this.beforeChangeListeners_ = {};
/**
* @private
* @type {Object.<string, goog.events.Key>}
*/
this.listeners_ = {};
if (goog.isDef(opt_values)) { if (goog.isDef(opt_values)) {
this.setValues(opt_values); this.setValues(opt_values);
} }
@@ -173,16 +176,6 @@ ol.Object.capitalize = function(str) {
}; };
/**
* @param {ol.Object} obj Object.
* @return {Object.<string, ol.ObjectAccessor>} Accessors.
*/
ol.Object.getAccessors = function(obj) {
return obj[ol.ObjectProperty.ACCESSORS] ||
(obj[ol.ObjectProperty.ACCESSORS] = {});
};
/** /**
* @param {string} key Key name. * @param {string} key Key name.
* @return {string} Change name. * @return {string} Change name.
@@ -205,16 +198,6 @@ ol.Object.getGetterName = function(key) {
}; };
/**
* @param {ol.Object} obj Object.
* @return {Object.<string, goog.events.Key>} Listeners.
*/
ol.Object.getListeners = function(obj) {
return obj[ol.ObjectProperty.BINDINGS] ||
(obj[ol.ObjectProperty.BINDINGS] = {});
};
/** /**
* @param {string} key String. * @param {string} key String.
* @return {string} Setter name. * @return {string} Setter name.
@@ -261,8 +244,7 @@ ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
// listen for change:targetkey events // listen for change:targetkey events
var eventType = ol.Object.getChangeEventType(targetKey); var eventType = ol.Object.getChangeEventType(targetKey);
var listeners = ol.Object.getListeners(this); this.listeners_[key] = goog.events.listen(target, eventType, function() {
listeners[key] = goog.events.listen(target, eventType, function() {
this.notifyInternal_(key); this.notifyInternal_(key);
}, undefined, this); }, undefined, this);
@@ -273,8 +255,7 @@ ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
undefined, this); undefined, this);
var accessor = new ol.ObjectAccessor(target, targetKey); var accessor = new ol.ObjectAccessor(target, targetKey);
var accessors = ol.Object.getAccessors(this); this.accessors_[key] = accessor;
accessors[key] = accessor;
this.notifyInternal_(key); this.notifyInternal_(key);
return accessor; return accessor;
}; };
@@ -312,14 +293,16 @@ ol.Object.prototype.createBeforeChangeListener_ = function(key, targetKey) {
*/ */
ol.Object.prototype.get = function(key) { ol.Object.prototype.get = function(key) {
var value; var value;
var accessors = ol.Object.getAccessors(this); var accessors = this.accessors_;
if (accessors.hasOwnProperty(key)) { if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key]; var accessor = accessors[key];
var target = accessor.target; var target = accessor.target;
var targetKey = accessor.key; var targetKey = accessor.key;
var getterName = ol.Object.getGetterName(targetKey); var getterName = ol.Object.getGetterName(targetKey);
if (target[getterName]) { var getter = /** @type {function(): *|undefined} */
value = target[getterName](); (goog.object.get(target, getterName));
if (goog.isDef(getter)) {
value = getter.call(target);
} else { } else {
value = target.get(targetKey); value = target.get(targetKey);
} }
@@ -336,7 +319,7 @@ ol.Object.prototype.get = function(key) {
* @return {Array.<string>} List of property names. * @return {Array.<string>} List of property names.
*/ */
ol.Object.prototype.getKeys = function() { ol.Object.prototype.getKeys = function() {
var accessors = ol.Object.getAccessors(this); var accessors = this.accessors_;
var keysObject; var keysObject;
if (goog.object.isEmpty(this.values_)) { if (goog.object.isEmpty(this.values_)) {
if (goog.object.isEmpty(accessors)) { if (goog.object.isEmpty(accessors)) {
@@ -372,7 +355,7 @@ ol.Object.prototype.getProperties = function() {
for (key in this.values_) { for (key in this.values_) {
properties[key] = this.values_[key]; properties[key] = this.values_[key];
} }
for (key in ol.Object.getAccessors(this)) { for (key in this.accessors_) {
properties[key] = this.get(key); properties[key] = this.get(key);
} }
return properties; return properties;
@@ -387,7 +370,7 @@ ol.Object.prototype.getProperties = function() {
* @todo stability experimental * @todo stability experimental
*/ */
ol.Object.prototype.notify = function(key) { ol.Object.prototype.notify = function(key) {
var accessors = ol.Object.getAccessors(this); var accessors = this.accessors_;
if (accessors.hasOwnProperty(key)) { if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key]; var accessor = accessors[key];
var target = accessor.target; var target = accessor.target;
@@ -420,15 +403,17 @@ ol.Object.prototype.notifyInternal_ = function(key) {
ol.Object.prototype.set = function(key, value) { ol.Object.prototype.set = function(key, value) {
this.dispatchEvent( this.dispatchEvent(
new ol.ObjectEvent(ol.ObjectEventType.BEFOREPROPERTYCHANGE, key)); new ol.ObjectEvent(ol.ObjectEventType.BEFOREPROPERTYCHANGE, key));
var accessors = ol.Object.getAccessors(this); var accessors = this.accessors_;
if (accessors.hasOwnProperty(key)) { if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key]; var accessor = accessors[key];
var target = accessor.target; var target = accessor.target;
var targetKey = accessor.key; var targetKey = accessor.key;
var setterName = ol.Object.getSetterName(targetKey);
value = accessor.from(value); value = accessor.from(value);
if (target[setterName]) { var setterName = ol.Object.getSetterName(targetKey);
target[setterName](value); var setter = /** @type {function(*)|undefined} */
(goog.object.get(target, setterName));
if (goog.isDef(setter)) {
setter.call(target, value);
} else { } else {
target.set(targetKey, value); target.set(targetKey, value);
} }
@@ -445,12 +430,14 @@ ol.Object.prototype.set = function(key, value) {
* @todo stability experimental * @todo stability experimental
*/ */
ol.Object.prototype.setValues = function(values) { ol.Object.prototype.setValues = function(values) {
var key, value, setterName; var key;
for (key in values) { for (key in values) {
value = values[key]; var value = values[key];
setterName = ol.Object.getSetterName(key); var setterName = ol.Object.getSetterName(key);
if (this[setterName]) { var setter = /** @type {function(*)|undefined} */
this[setterName](value); (goog.object.get(this, setterName));
if (goog.isDef(setter)) {
setter.call(this, value);
} else { } else {
this.set(key, value); this.set(key, value);
} }
@@ -465,14 +452,13 @@ ol.Object.prototype.setValues = function(values) {
* @todo stability experimental * @todo stability experimental
*/ */
ol.Object.prototype.unbind = function(key) { ol.Object.prototype.unbind = function(key) {
var listeners = ol.Object.getListeners(this); var listeners = this.listeners_;
var listener = listeners[key]; var listener = listeners[key];
if (listener) { if (listener) {
delete listeners[key]; delete listeners[key];
goog.events.unlistenByKey(listener); goog.events.unlistenByKey(listener);
var value = this.get(key); var value = this.get(key);
var accessors = ol.Object.getAccessors(this); delete this.accessors_[key];
delete accessors[key];
this.values_[key] = value; this.values_[key] = value;
} }
@@ -490,7 +476,7 @@ ol.Object.prototype.unbind = function(key) {
* @todo stability experimental * @todo stability experimental
*/ */
ol.Object.prototype.unbindAll = function() { ol.Object.prototype.unbindAll = function() {
for (var key in ol.Object.getListeners(this)) { for (var key in this.listeners_) {
this.unbind(key); this.unbind(key);
} }
}; };
+2
View File
@@ -10,6 +10,8 @@ goog.require('goog.events.EventTarget');
* and unregistration. * and unregistration.
* @constructor * @constructor
* @extends {goog.events.EventTarget} * @extends {goog.events.EventTarget}
* @suppress {checkStructDictInheritance}
* @struct
* @todo stability experimental * @todo stability experimental
*/ */
ol.Observable = function() { ol.Observable = function() {