dependency-observable changes (#2584)

* Improved es6.d.ts
Small perf improvement in resetValues

* Fix tslint errors

* Removed all comments from es6.d.ts (TSLint hell)
This commit is contained in:
Hristo Hristov
2016-08-15 15:14:03 +03:00
committed by GitHub
parent ddc351f78c
commit fc0048c4a1
5 changed files with 68 additions and 82 deletions

View File

@ -1,9 +1,20 @@
declare var Symbol: any; interface Symbol {
toString(): string;
valueOf(): Object;
}
interface SymbolConstructor {
prototype: Symbol;
(description?: string | number): symbol;
}
declare var Symbol: SymbolConstructor;
interface ObjectConstructor { interface ObjectConstructor {
assign(target: any, ...sources: any[]): any; assign(target: any, ...sources: any[]): any;
is(value1: any, value2: any): boolean; is(value1: any, value2: any): boolean;
setPrototypeOf(o: any, proto: any): any; setPrototypeOf(o: any, proto: any): any;
getOwnPropertySymbols(o: any): symbol[];
} }
declare var Object: ObjectConstructor; declare var Object: ObjectConstructor;

View File

@ -243,6 +243,7 @@ declare module "ui/core/dependency-observable" {
/** /**
* Iterates all the properties which have a PropertyEntry registered for this instance. * Iterates all the properties which have a PropertyEntry registered for this instance.
*/ */
_resetValues(valueSource: number): void;
_eachSetProperty(callback: (property: Property) => boolean): void; _eachSetProperty(callback: (property: Property) => boolean): void;
_eachSetPropertyValue(callback: (property: Property, value: any) => void): void; _eachSetPropertyValue(callback: (property: Property, value: any) => void): void;
//@endprivate //@endprivate

View File

@ -77,40 +77,23 @@ export class PropertyMetadata implements definition.PropertyMetadata {
} }
} }
// function property(property: Property): PropertyDecorator {
// function _getValue() {
// return this._getValue(property);
// }
// function _setValue(value: any) {
// this._setValueInternal(property, value, ValueSource.Local);
// }
// return (target: Object, propertyKey: string) => {
// Object.defineProperty(target, propertyKey, {
// get: _getValue,
// set: _setValue,
// enumerable: true,
// configurable: true
// });
// };
// }
export class Property implements definition.Property { export class Property implements definition.Property {
public key: string; public key: string;
public id: number; public id: number;
public defaultValue; public defaultValue;
public onValidateValue;
public equalityComparer; public equalityComparer;
public inheritable; public inheritable;
public affectsStyle; public affectsStyle;
public affectsLayout; public affectsLayout;
public onValueChanged: definition.PropertyChangedCallback;
public nameEvent: string; public nameEvent: string;
public onValidateValue;
public onValueChanged: definition.PropertyChangedCallback;
constructor(public name: string, public ownerType: string, public metadata: PropertyMetadata, public valueConverter?: (value: string) => any) { constructor(public name: string, public ownerType: string, public metadata: PropertyMetadata, public valueConverter?: (value: string) => any) {
// register key // register key
this.key = generatePropertyKey(name, ownerType, true); this.key = generatePropertyKey(name, ownerType, true);
if (propertyFromKey[this.key]) { if (propertyFromKey[this.key]) {
throw new Error("Property " + name + " already registered for type " + ownerType + "."); throw new Error("Property " + name + " already registered for type " + ownerType + ".");
} }
@ -150,7 +133,6 @@ export class PropertyEntry implements definition.PropertyEntry {
public visualStateValue: any; public visualStateValue: any;
constructor(public property: Property) { constructor(public property: Property) {
this.property = property;
} }
public resetValue() { public resetValue() {
@ -159,8 +141,6 @@ export class PropertyEntry implements definition.PropertyEntry {
} }
} }
var defaultValueForPropertyPerType: Map<string, any> = new Map<string, any>();
export class DependencyObservable extends Observable implements definition.DependencyObservable { export class DependencyObservable extends Observable implements definition.DependencyObservable {
private _propertyEntries = {}; private _propertyEntries = {};
@ -206,17 +186,15 @@ export class DependencyObservable extends Observable implements definition.Depen
} }
private _getDefaultValue(property: Property): any { private _getDefaultValue(property: Property): any {
if (property.defaultValueGetter) { // we check for cached properties only for these which have 'defaultValueGetter' defined; if (property.defaultValueGetter) {
// we check for cached properties only for these which have 'defaultValueGetter' defined;
// When DependencyProperties are removed from Style - fix this check. // When DependencyProperties are removed from Style - fix this check.
var view = (<any>this)._view || this; let defaultValueResult = property.defaultValueGetter(this);
let key = types.getClass(view) + "." + property.id; let defaultValue = defaultValueResult.result;
let defaultValue = defaultValueForPropertyPerType.get(key); if (defaultValueResult.cacheable) {
if (!defaultValueForPropertyPerType.has(key) && view._nativeView) { let entry = new PropertyEntry(property);
let defaultValueResult = property.defaultValueGetter(this); entry.effectiveValue = defaultValue;
defaultValue = defaultValueResult.result; this._propertyEntries[property.id] = entry;
if (defaultValueResult.cacheable) {
defaultValueForPropertyPerType.set(key, defaultValue);
}
} }
return defaultValue; return defaultValue;
@ -225,13 +203,25 @@ export class DependencyObservable extends Observable implements definition.Depen
return property.defaultValue; return property.defaultValue;
} }
public _resetValue(property: Property, source: number = ValueSource.Local) { public _resetValues(valueSource: number): void {
for (let i = 0, keys = Object.keys(this._propertyEntries); i < keys.length; i++) {
let key = keys[i];
let entry: PropertyEntry = this._propertyEntries[key];
this._resetValueInternal(entry.property, entry, valueSource);
}
}
public _resetValue(property: Property, valueSource: number = ValueSource.Local): void {
let entry: PropertyEntry = this._propertyEntries[property.id]; let entry: PropertyEntry = this._propertyEntries[property.id];
if (!entry) { if (!entry) {
return; return;
} }
switch (source) { this._resetValueInternal(property, entry, valueSource);
}
private _resetValueInternal(property: Property, entry: PropertyEntry, valueSource: number): void {
switch (valueSource) {
case ValueSource.Inherited: case ValueSource.Inherited:
entry.inheritedValue = undefined; entry.inheritedValue = undefined;
break; break;
@ -247,7 +237,7 @@ export class DependencyObservable extends Observable implements definition.Depen
} }
let currentValueSource = entry.valueSource; let currentValueSource = entry.valueSource;
if (currentValueSource !== source) { if (currentValueSource !== valueSource) {
// If current valueSource is larget than the one we reset - do nothing. // If current valueSource is larget than the one we reset - do nothing.
// We are reseting property will lower priority and it won't change effectValue; // We are reseting property will lower priority and it won't change effectValue;
// Reseting larger source means we somehow was able to set value without updating currentValueSource which is clearly a bug. // Reseting larger source means we somehow was able to set value without updating currentValueSource which is clearly a bug.
@ -255,15 +245,15 @@ export class DependencyObservable extends Observable implements definition.Depen
} }
let currentValue = entry.effectiveValue; let currentValue = entry.effectiveValue;
let newValue = this.getEffectiveValue(currentValueSource, entry, property); let newValue = this.getEffectiveValueAndUpdateEntry(currentValueSource, entry, property);
if (!property.equalityComparer(currentValue, newValue)) { if (!property.equalityComparer(currentValue, newValue)) {
// If we fallback to defalutValue - remove propertyEntry. // // If we fallback to defalutValue - remove propertyEntry.
if (entry.valueSource === ValueSource.Default) { // if (entry.valueSource === ValueSource.Default) {
delete this._propertyEntries[property.id]; // delete this._propertyEntries[property.id];
} // }
else { // else {
entry.effectiveValue = newValue; entry.effectiveValue = newValue;
} // }
this._onPropertyChanged(property, currentValue, newValue); this._onPropertyChanged(property, currentValue, newValue);
} }
@ -314,7 +304,9 @@ export class DependencyObservable extends Observable implements definition.Depen
for (let i = 0, keys = Object.keys(this._propertyEntries); i < keys.length; i++) { for (let i = 0, keys = Object.keys(this._propertyEntries); i < keys.length; i++) {
let key = keys[i]; let key = keys[i];
let entry: PropertyEntry = this._propertyEntries[key]; let entry: PropertyEntry = this._propertyEntries[key];
callback(entry.property, entry.effectiveValue); if (!callback(entry.property, entry.effectiveValue)) {
break;
}
} }
} }
@ -345,28 +337,25 @@ export class DependencyObservable extends Observable implements definition.Depen
let currentValue; let currentValue;
if (!entry) { if (!entry) {
entry = new PropertyEntry(property); entry = new PropertyEntry(property);
entry.effectiveValue = this._getDefaultValue(property);
this._propertyEntries[property.id] = entry; this._propertyEntries[property.id] = entry;
currentValue = this._getDefaultValue(property);
// In rare case when we set local value equal to default value we need to update effectiveValue as well.
// Otherwise effectiveValue will stay undefined.
if (property.equalityComparer(currentValue, realValue)) {
entry.effectiveValue = realValue;
}
}
else {
currentValue = entry.effectiveValue;
} }
currentValue = entry.effectiveValue;
switch (source) { switch (source) {
case ValueSource.Inherited: case ValueSource.Inherited:
entry.inheritedValue = realValue; entry.inheritedValue = realValue;
break; break;
case ValueSource.Css: case ValueSource.Css:
entry.cssValue = realValue; entry.cssValue = realValue;
break; break;
case ValueSource.Local: case ValueSource.Local:
entry.localValue = realValue; entry.localValue = realValue;
break; break;
case ValueSource.VisualState: case ValueSource.VisualState:
entry.visualStateValue = realValue; entry.visualStateValue = realValue;
break; break;
@ -386,7 +375,7 @@ export class DependencyObservable extends Observable implements definition.Depen
} }
} }
private getEffectiveValue(currentValueSource: number, entry: PropertyEntry, property: Property): any { private getEffectiveValueAndUpdateEntry(currentValueSource: number, entry: PropertyEntry, property: Property): any {
let newValue: any; let newValue: any;
switch (currentValueSource) { switch (currentValueSource) {
case ValueSource.Inherited: case ValueSource.Inherited:

View File

@ -1061,10 +1061,14 @@ export class View extends ProxyObject implements definition.View {
view.onUnloaded(); view.onUnloaded();
} }
view._setValue(ProxyObject.bindingContextProperty, undefined, ValueSource.Inherited); view.unsetInheritedProperties();
view._eachSetProperty((property) => { }
public unsetInheritedProperties(): void {
this._setValue(ProxyObject.bindingContextProperty, undefined, ValueSource.Inherited);
this._eachSetProperty((property) => {
if (!(property instanceof styling.Property) && property.inheritable) { if (!(property instanceof styling.Property) && property.inheritable) {
view._resetValue(property, ValueSource.Inherited); this._resetValue(property, ValueSource.Inherited);
} }
return true; return true;
}); });

View File

@ -891,20 +891,11 @@ export class Style extends DependencyObservable implements styling.Style {
public _resetCssValues() { public _resetCssValues() {
this._view._unregisterAllAnimations(); this._view._unregisterAllAnimations();
this._resetValues(ValueSource.Css);
const that = this;
this._eachSetProperty(function (property: Property) {
that._resetValue(property, ValueSource.Css);
return true;
});
} }
public _resetLocalValues() { public _resetLocalValues() {
const that = this; this._resetValues(ValueSource.Local);
this._eachSetProperty(function (property: Property) {
that._resetValue(property);
return true;
});
} }
public _inheritStyleProperties(parent: View) { public _inheritStyleProperties(parent: View) {
@ -918,16 +909,6 @@ export class Style extends DependencyObservable implements styling.Style {
}); });
} }
// public _inheritStyleProperty(property: Property, value: any) {
// // let currentParent = this._view.parent;
// // if (currentParent) {
// // let valueSource = currentParent.style._getValueSource(property);
// // if (valueSource > ValueSource.Default) {
// this._setValue(property, value, ValueSource.Inherited);
// // }
// // }
// }
public _onPropertyChanged(property: Property, oldValue: any, newValue: any) { public _onPropertyChanged(property: Property, oldValue: any, newValue: any) {
if (trace.enabled) { if (trace.enabled) {
trace.write( trace.write(