diff --git a/compiler/js/component.py b/compiler/js/component.py index 48b0848d..ff732707 100644 --- a/compiler/js/component.py +++ b/compiler/js/component.py @@ -358,6 +358,16 @@ def generate_prototype(self, registry, ident_n = 1): args.append(default_value) r.append("%score.addProperty(%s)" %(ident, ", ".join(args))) + setup_on_changed = [] + + for target, value in self.assignments.items(): + if target == "id" or target.endswith(".id"): + continue + else: + if "." not in target and lang.value_is_trivial(value): + r.append("%s$core._protoDefault(%s, '%s', %s)" %(ident, self.proto_name, target, value)) + setup_on_changed.append("%s$core._setProtoDefault($this, '%s')" %(ident, target )) + for name, prop in self.enums.items(): values = prop.values @@ -411,6 +421,7 @@ def put_in_prototype(handler): for (path, name) in handlers: assert not path r.append("%s$core._protoOnChanged(%s, '%s', %s)" %(ident, self.proto_name, name, code)) + setup_on_changed.append("%s$core._setProtoDefault($this, '%s')" %(ident, name)) for code, handlers in self.transform_handlers(registry, self.signal_handlers): handlers = list(filter(put_in_prototype, handlers)) @@ -448,10 +459,10 @@ def put_in_prototype(handler): setup_code = self.generate_setup_code(registry, '$this', '$c', ident_n + 2).strip() b = '%s%s.$s.call($this, $c.$b); delete $c.$b' %(ident, self.base_proto_name) - if setup_code: + if setup_code or setup_on_changed: generate = True - setup_code = '%s%s.$s = function($c) {\n\t\tvar $this = this;\n%s\n%s\n}' \ - %(ident, self.proto_name, b, setup_code) + setup_code = '%s%s.$s = function($c) {\n\t\tvar $this = this;\n%s\n%s\n%s\n}' \ + %(ident, self.proto_name, b, "\n".join(setup_on_changed), setup_code) if generate: r.append('') @@ -640,6 +651,8 @@ def generate_setup_code(self, registry, parent, closure, ident_n = 1): for target, value in self.assignments.items(): if target == "id": continue + if self.prototype and "." not in target and lang.value_is_trivial(value): + continue t = type(value) #print self.name, target, value target_owner, target_lvalue, target_prop = self.get_lvalue(registry, parent, target) diff --git a/core/core.js b/core/core.js index 8e2d6412..04c05d15 100644 --- a/core/core.js +++ b/core/core.js @@ -643,20 +643,27 @@ exports.addProperty = function(proto, type, name, defaultValue) { defaultValue = getDefaultValueForType(type) } + var protoDefault = '__default__' + name + var getDefaultValue = function(parent) { + if (protoDefault in parent) + return parent[protoDefault] + return defaultValue + } + var createStorage = function(newValue) { var properties = this.__properties var storage = properties[name] if (storage === undefined) { //no storage - if (newValue === defaultValue) //value === defaultValue, no storage allocation + if (newValue === getDefaultValue(this)) //value === defaultValue, no storage allocation return - storage = properties[name] = new PropertyStorage(defaultValue) + storage = properties[name] = new PropertyStorage(getDefaultValue(this)) } return storage } var simpleGet = function() { var storage = this.__properties[name] - return storage !== undefined? storage.getSimpleValue(defaultValue): defaultValue + return storage !== undefined? storage.getSimpleValue(getDefaultValue(this)): getDefaultValue(this) } var simpleSet = function(newValue) { @@ -665,14 +672,14 @@ exports.addProperty = function(proto, type, name, defaultValue) { if (storage === undefined) return - storage.set(this, name, newValue, defaultValue, true) + storage.set(this, name, newValue, getDefaultValue(this), true) } var animatedGet = function() { var storage = this.__properties[name] return storage !== undefined? - storage.getCurrentValue(defaultValue): - defaultValue + storage.getCurrentValue(getDefaultValue(this)): + getDefaultValue(this) } var animatedSet = function(newValue) { @@ -691,7 +698,7 @@ exports.addProperty = function(proto, type, name, defaultValue) { storage.started = Date.now() - var src = storage.getCurrentValue(defaultValue) + var src = storage.getCurrentValue(getDefaultValue(this)) var dst = newValue var self = this @@ -721,7 +728,7 @@ exports.addProperty = function(proto, type, name, defaultValue) { complete() } else { storage.interpolatedValue = convert(animation.interpolate(dst, src, t)) - storage.callOnChanged(self, name, storage.getCurrentValue(defaultValue), src) + storage.callOnChanged(self, name, storage.getCurrentValue(getDefaultValue(this)), src) storage.frameRequest = backend.requestAnimationFrame(nextFrame) } }) @@ -735,7 +742,7 @@ exports.addProperty = function(proto, type, name, defaultValue) { animation.running = true animation.complete = complete } - storage.set(this, name, newValue, defaultValue, !animation) + storage.set(this, name, newValue, getDefaultValue(this), !animation) // if ((!animation || !animation.running) && newValue === defaultValue) // this.__properties[name] = undefined } @@ -831,6 +838,21 @@ $core._protoOnChanged = function(proto, name, callback) $core._protoOnKey = function(proto, name, callback) { protoEvent('__key__', proto, name, callback) } +$core._protoDefault = function(proto, name, value) +{ proto['__default__' + name] = value } + +$core._setProtoDefault = function(object, name) { + if (!('__properties' in object)) + return + + var value = object['__default__' + name] + if (value === undefined) + return + + var storage = object.__properties[name] + _callOnChanged(object, name, value, storage? storage.onChanged: undefined) +} + $core.callMethod = function(obj, name) { if (!obj) return