Not to sure about SimpleController, haven’t found anyone who uses the MVC stuff.
However, since you are already in an Event, why not just extend it.
Below is a pretty basic implementation that gives you a onKeyChanged
, onAnyChanged
,
onKeyRemoved
, and onKeyChangedDefault
. You do, however, have to call ~set.(\someKey, "SomeValue")
when you want to change something.
~onAnyChangedStore /* : FunctionList(Environment, ChangedKeySymbol, Value) */ = FunctionList();
~onKeyChangedStore /* : Event[KeySymbol -> FunctionList(Value)] */ = ();
~onKeyRemovedStore /* : Event[KeySymbol -> FunctionList()] */ = ();
~onAnyChanged = {|func| currentEnvironment[\onAnyChangedStore].addFunc(func) };
~onKeyChanged = {|key, func|
var f_list_safe = currentEnvironment[\onKeyChangedStore][key.asSymbol] ?? {
currentEnvironment[\onKeyChangedStore][key.asSymbol] = FunctionList();
currentEnvironment[\onKeyChangedStore][key.asSymbol]
};
f_list_safe.addFunc(func);
};
~onKeyChangedDefault = {|key, default, func|
var f_list = currentEnvironment[\onKeyChanged].(key, func);
f_list.array.last.(default);
};
~onKeyRemoved = { |key, func|
var f_list_safe = currentEnvironment[\onKeyRemovedStore][key.asSymbol] ?? {
currentEnvironment[\onKeyRemovedStore][key.asSymbol] = FunctionList();
currentEnvironment[\onKeyRemovedStore][key.asSymbol]
};
f_list_safe.addFunc(func);
};
~set_ = {
|k, v|
if(currentEnvironment[k.asSymbol] != v, {
currentEnvironment[k.asSymbol] = v;
currentEnvironment[\onAnyChangedStore].(currentEnvironment, k.asSymbol, currentEnvironment[k.asSymbol]);
currentEnvironment[\onKeyChangedStore][k.asSymbol].(currentEnvironment[k.asSymbol]);
});
currentEnvironment[k.asSymbol]
};
~remove_ = {
|k|
currentEnvironment[k.asSymbol] = nil;
currentEnvironment[\onAnyChangedStore].(currentEnvironment, k.asSymbol, currentEnvironment[k.asSymbol]);
currentEnvironment[\onKeyChangedStore][k.asSymbol].(currentEnvironment[k.asSymbol]);
currentEnvironment[\onKeyRemovedStore][k.asSymbol].();
};
~onAnyChanged.({|envir, key, value|
postf("key: % changed to: %\n", key, value)
});
~onKeyChanged.(\a, { |value|
postf("\a has changed to: %\n", value)
});
~onKeyChanged.(\b, { |value|
postf("\b has changed to: %\n", value)
});
~onKeyChanged.(\c, { |value|
postf("\c has changed to: %\n", value)
});
~onKeyRemoved.(\rm, {
"rm was removed".postln;
});
~set_.(\a, 2)
~set_.(\b, 4)
~set_.(\c, 1)
~rm = "value" // do not do this.
~set_.(\rm, 2) // instead do this.
~onKeyChanged.(\rm, {|v| "rm changed".postln })
~set_.(\rm, 2) // instead do this.
~onKeyRemoved.(\rm, { "rm removed".postln })
~remove_.(\rm)
~rm
// is evaled when first defined with the default value.
~onKeyChangedDefault.(\c, "defaultValue", { |value|
postf("\c has changed to: %\n", value)
});
However, to create this by default and make things easier, you should be able to do this…
~e = Environment.make{
~onAnyChangedStore /* : FunctionList(Environment, ChangedKeySymbol, Value) */ = FunctionList();
~onKeyChangedStore /* : Event[KeySymbol -> FunctionList(Value)] */ = ();
~onKeyRemovedStore /* : Event[KeySymbol -> FunctionList()] */ = ();
~onAnyChanged = {|self, func|
self[\onAnyChangedStore].addFunc(func)
};
~onKeyChanged = {|self, key, func|
var f_list_safe = self[\onKeyChangedStore][key.asSymbol] ?? {
self[\onKeyChangedStore][key.asSymbol] = FunctionList();
self[\onKeyChangedStore][key.asSymbol]
};
f_list_safe.addFunc(func);
};
~onKeyChangedDefault = {|self, key, default, func|
var f_list = self[\onKeyChanged].(key, func);
f_list.array.last.(default);
};
~onKeyRemoved = { |self, key, func|
var f_list_safe = self[\onKeyRemovedStore][key.asSymbol] ?? {
self[\onKeyRemovedStore][key.asSymbol] = FunctionList();
self[\onKeyRemovedStore][key.asSymbol]
};
f_list_safe.addFunc(func);
};
~set_ = {
|self, k, v|
if(self[k.asSymbol] != v, {
self[k.asSymbol] = v;
self[\onAnyChangedStore].(self, k.asSymbol, self[k.asSymbol]);
self[\onKeyChangedStore][k.asSymbol].(self[k.asSymbol]);
});
currentEnvironment[k.asSymbol]
};
~remove_ = {
|self, k|
self[k.asSymbol] = nil;
self[\onAnyChangedStore].(currentEnvironment, k.asSymbol, currentEnvironment[k.asSymbol]);
self[\onKeyChangedStore][k.asSymbol].(currentEnvironment[k.asSymbol]);
self[\onKeyRemovedStore][k.asSymbol].();
};
};
~e.know = true;
Then you can do this…
~e.onAnyChanged({|envir, key, value|
postf("key: % changed to: %\n", key, value)
});
~e.onKeyChanged(\b, { |value|
postf("B has changed to: %\n", value)
});
~e.set_(\a, 1)
~e.set_(\b, 20)
Hopefully that’s helpful?