Style handlers caching revised

This commit is contained in:
vakrilov
2015-05-22 18:07:36 +03:00
parent aeebe2df7f
commit 27b38da248
2 changed files with 52 additions and 37 deletions

View File

@@ -13,9 +13,11 @@ import imageSource = require("image-source");
import utils = require("utils/utils"); import utils = require("utils/utils");
// key is the property id and value is Dictionary<string, StylePropertyChangedHandler>; // key is the property id and value is Dictionary<string, StylePropertyChangedHandler>;
var _registeredHandlers = {}; var _registeredHandlers = Array<Object>();
// key is a className + property id and value is StylePropertyChangedHandler; // key is a className + property id and value is StylePropertyChangedHandler;
var _handlersCache = {}; var _handlersCache = {};
// classes like Frame that does not need to handle styling properties. // classes like Frame that does not need to handle styling properties.
var noStylingClasses = {}; var noStylingClasses = {};
@@ -292,14 +294,14 @@ export function registerHandler(property: dependencyObservable.Property,
handler: styling.stylers.StylePropertyChangedHandler, handler: styling.stylers.StylePropertyChangedHandler,
className?: string) { className?: string) {
var realClassName = className ? className : "default"; var realClassName = className ? className : "default";
if (_registeredHandlers.hasOwnProperty(property.id + "")) {
_registeredHandlers[property.id][realClassName] = handler; var handlerRecord = _registeredHandlers[property.id];
} if (!handlerRecord) {
else { handlerRecord = {};
var handlerRecord = {};
handlerRecord[realClassName] = handler;
_registeredHandlers[property.id] = handlerRecord; _registeredHandlers[property.id] = handlerRecord;
} }
handlerRecord[realClassName] = handler;
} }
export function registerNoStylingClass(className) { export function registerNoStylingClass(className) {
@@ -307,33 +309,38 @@ export function registerNoStylingClass(className) {
} }
export function getHandler(property: dependencyObservable.Property, view: view.View): styling.stylers.StylePropertyChangedHandler { export function getHandler(property: dependencyObservable.Property, view: view.View): styling.stylers.StylePropertyChangedHandler {
var classNames = types.getBaseClasses(view); return getHandlerInternal(property.id, types.getClassInfo(view));
// adding default as last class name if no other class is found default handler will be used }
classNames.push("default");
if (_handlersCache.hasOwnProperty(classNames[0] + property.id)) { function getHandlerInternal(propertyId: number, classInfo: types.ClassInfo): styling.stylers.StylePropertyChangedHandler {
return _handlersCache[classNames[0] + property.id]; var className = classInfo ? classInfo.name : "default";
var handlerKey = className + propertyId;
// try the cache first
var result = _handlersCache[handlerKey];
if (types.isDefined(result)) {
return result;
}
var propertyHandlers = _registeredHandlers[propertyId];
if (noStylingClasses.hasOwnProperty(className) || !propertyHandlers) {
// Reached 'no-styling' class or no property handlers are registered for this proeprtyID
result = null;
}
else if (propertyHandlers.hasOwnProperty(className)) {
// Found handler for this class
result = propertyHandlers[className];
}
else if (classInfo) {
// Check the base class
result = getHandlerInternal(propertyId, classInfo.baseClassInfo);
} }
else { else {
var i; result = null;
var propertyHandlers;
var handler;
propertyHandlers = _registeredHandlers[property.id];
for (i = 0; i < classNames.length; i++) {
if (propertyHandlers) {
var loopClassName = classNames[i];
if (noStylingClasses.hasOwnProperty(loopClassName)) {
_handlersCache[loopClassName + property.id] = null;
return null;
}
if (propertyHandlers.hasOwnProperty(loopClassName)) {
handler = propertyHandlers[loopClassName];
_handlersCache[loopClassName + property.id] = handler;
return handler;
}
}
}
} }
return null;
_handlersCache[handlerKey] = result;
return result;
} }
// Property registration // Property registration

View File

@@ -79,15 +79,23 @@ export class ClassInfo {
get baseClassInfo(): ClassInfo { get baseClassInfo(): ClassInfo {
if (isUndefined(this._baseClassInfo)) { if (isUndefined(this._baseClassInfo)) {
var constructorProto = this._typeCosntructor.prototype; this._baseClassInfo = ClassInfo._getBase(this);
if (constructorProto.__proto__) {
this._baseClassInfo = getClassInfo(constructorProto.__proto__); // While extending some classes for platform specific versions results in duplicate class types in hierarchy.
} if (this._baseClassInfo && this._baseClassInfo.name === this.name) {
else { this._baseClassInfo = ClassInfo._getBase(this._baseClassInfo);
this._baseClassInfo = null;
} }
} }
return this._baseClassInfo; return this._baseClassInfo;
} }
private static _getBase(info: ClassInfo): ClassInfo {
var result = null;
var constructorProto = info._typeCosntructor.prototype;
if (constructorProto.__proto__) {
result = getClassInfo(constructorProto.__proto__);
}
return result;
}
} }