Skip to content

Instantly share code, notes, and snippets.

@LFSaw
Last active June 29, 2017 11:20
Show Gist options
  • Save LFSaw/00b42cd38138adec61a0 to your computer and use it in GitHub Desktop.
Save LFSaw/00b42cd38138adec61a0 to your computer and use it in GitHub Desktop.
towards SmartSetter
// 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;
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