sclass Dyn_FieldWatcher is AutoCloseable { DynModule module; S field; O value; Runnable action; Runnable changeListener = r check; VF1 fieldChangeListener = voidfunc(S f) { if (eq(f, field)) check(); }; swappable O cloneValue(O o) { ret o; } *(DynModule module, S field, Runnable action) { this(module, field, action, null); } *(DynModule *module, S *field, Runnable *action, IF1 *cloneValue) { value = cloneValue(get(module, field)); // Let's do both for safety module.onChange(changeListener); module.onFieldChange(fieldChangeListener); } void check { O newValue = cloneValue(get(module, field)); if (eq(value, newValue)) ret; value = newValue; dm_q(module, action); } close { module.removeChangeListener(changeListener); module.removeFieldChangeListener(fieldChangeListener); } }