Last active
June 29, 2017 11:20
-
-
Save LFSaw/00b42cd38138adec61a0 to your computer and use it in GitHub Desktop.
towards SmartSetter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// relative set, useful for increment/decrement knobs, | |
// as they appear e.g. in cerain midi controllers | |
// different modes depending on get/set methods for the inner object. | |
///// _____ | |
p = Point(1, 2); | |
r = SmartSetter(p, \x, [-100, 100]); | |
///// getSet | |
p = (); | |
////// with basicNew | |
p = Point(1, 2); | |
r = RelSetX(p, { |obj, val| obj.x = val }, { |obj| obj.x }, [-100, 100]); | |
///////////// tests | |
// use as regular get/set interface | |
r.get; | |
r.set(2); // set absolute value of object.x | |
// change value directly, unconstrained | |
r.change(1, true); p; | |
// or use constraint from spec | |
r.change(100, true); p; | |
// change with delta value in unipolar range, | |
// i.e. 0.1 = 10% of range | |
r.changeMapped(-0.1); p; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SmartSetter { | |
var <>obj, <>setFunc, <>getFunc, spec, <paramName; | |
*new {|obj, paramName, spec, type=\_| | |
var setFunc, getFunc; | |
#setFunc, getFunc = type.switch( | |
\_, [{ |obj, val| | |
obj.perform(paramName.asSetter, val); | |
}, { |obj| | |
obj.perform(paramName.asGetter); | |
}], | |
\gs, [{ |obj, val| | |
obj.set(paramName, val); | |
}, { |obj| | |
obj.get(paramName); | |
}], | |
\ap, [{ |obj, val| | |
obj.put(paramName, val); | |
}, { |obj| | |
obj.at(paramName); | |
}] | |
); | |
^this.basicNew(obj, setFunc, getFunc, spec).pr_paramName_(paramName); | |
} | |
*basicNew { |obj, setFunc, getFunc, spec| | |
^super.newCopyArgs(obj, setFunc, getFunc, spec); | |
} | |
// get set | |
*gs{|obj, paramName, spec| | |
^this.new(obj, paramName, spec, \gs); | |
} | |
// at put | |
*ap{|obj, item, spec| | |
^this.new(obj, item, spec, \ap); | |
} | |
pr_paramName_{|val| | |
paramName = val; | |
} | |
get { ^getFunc.value(obj); } | |
set { |val, constrain = false| | |
var mySpec; | |
constrain.if({ | |
val = this.getSpec.constrain(val); | |
}); | |
setFunc.value(obj, val); | |
} | |
value { | |
"%: value called... really needed?".format(this).inform; | |
^obj | |
} | |
spec_ { |newspec| | |
spec = newspec.asSpec; | |
} | |
spec { | |
^(spec ?? { obj.getSpec(paramName); }).asSpec; | |
} | |
change { |delta, constrain = false| | |
var currVal = this.get; | |
// cannot set relative if object has no currVal | |
if (currVal.isNil) { ^nil }; | |
//// or, if constrain shouldn't be implemented in set: | |
// var currval = this.get; | |
// currval = constrain.if({ | |
// spec.constrain(currval + delta); | |
// }, { | |
// currval + delta; | |
// }); | |
// this.set(currval); | |
this.set(currVal + delta, constrain); | |
} | |
changeMapped { |delta| | |
var mySpec = this.spec; | |
var mappedval = this.get; | |
var unmappedval = mySpec.unmap(mappedval); | |
unmappedval = unmappedval + delta; | |
mappedval = mySpec.map(unmappedval); | |
this.set(mappedval); | |
} | |
// printOn { | stream | | |
// stream << "a " << this.class.name << "(" << this.get.cs << ")" ; | |
// } | |
} | |
+ NodeProxy { | |
addSetter { |paramName| | |
Halo.put(this, \setter, paramName, SmartSetter.gs(this, paramName)); | |
} | |
getSetter { |paramName| | |
if (paramName.isNil) { ^Halo.at(this, \setter) }; | |
^Halo.at(this, \setter, paramName); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment