nadako / TinkStateSharp

Handle those pesky states, now in C#
https://nadako.github.io/TinkStateSharp/
The Unlicense
40 stars 1 forks source link

Visualize & debug observable dependencies #23

Open nadako opened 9 months ago

nadako commented 9 months ago

Disclaimer: I personally never really needed this, but still it looks useful.

The original Haxe tink_state library has a special compilation flag (tink_state.debug) that adds extra debugging info to each observable and a way to get the dependency tree of any observable at the given moment, which is pretty handy for debugging.

For example this code would output a nice indented tree of observables that depend on each other.

import tink.state.Observable;
import tink.state.State;

function main() {
    var duration = 100;
    var timestamp = new State(0);
    var endTime = timestamp.value + duration * 0.6;

    var timeLeft = Observable.auto(() -> endTime - timestamp.value);
    var progress = Observable.auto(() -> timeLeft.value / duration);

    Sys.println(progress.value); // track dependencies

    var dependencyTree = progress.dependencyTree();

    Sys.println(dependencyTree.toString());
}
tink.state.internal.AutoObservable#2(src/Main.hx:10)
  tink.state.internal.AutoObservable#1(src/Main.hx:9)
    tink.state._State.SimpleState#0(src/Main.hx:6)

As we can see, it also stores the file/line where the observable were instantiated, which definitely helps tracking them down. It is also possible to provide custom toString methods to give them specific names, but this is usually not needed.

Note that in C# the positions can also be magically aquired, similar to haxe.PosInfos, via CallerLineNumber attribute and friends. I imagine that this can be also integrated into a Unity/Godot inspector to display nicely.

Another thing this compilation flag does is logging invalidations and the whole auto-observable machinery, which also seems quite useful.

nadako commented 1 week ago

Another idea to consider is tracking dispatcher subscriptions in general (so both bindings and auto-observable dependencies), so we could have a debug tool to visualize all connections, similarly to R3 ObservableTracker.