Channels and Unit

Channels do really not work well with Reactive.Unit out of the box, since the channel’s inherent change check optimization does not play well with Unit

  • Demos don’t translate from other types to Unit.
  • generic usecases of channels have to change in case of type unit (just happened to me when i had to change some imgui from toggle button = boolean to button = unit
  • switching between observable world (with all the operators) back to channel requires extra attention (see Observable<Unit> ToChannel)

even though i’m aware of the special case of a Unit message i consistently stumble over it. issue is, one has to remember when ‘chaining’ unit messages to always force them. either SetValue, or EnsureValue (force), Consume and Merge push eagerly etc.

i’d nearly call it a bug, at least a serious design flaw. since Unit messages are not some esoteric special case but quite integral due to the imgui.
were channels not still labelled experimental? maybe it’s not too late to do some breaking changes…


possible solutions come to my mind:

  1. change Unit type to a unique instance to trigger channels change check if it’s actually a new message. pro: no need to change any other channel nodes + one could actually work with a spread of units and know which changed, cons: introduces friction when wrapping observables where unit is a basis type.

  2. split channel nodes into safe/simple and advanced nodes, i don’t mean different versions. more like we already have it with EnforceValue (safe) and SetValue (guards off). so the observables conversions are imho more advanced, so get rid of internal change check.
    Merge has two flavours anyways. the one with optional could use setvalue instead of EnsureValue internally.

  3. extend channels with properties like ValueChanged & MessageReceived


besides the all the ranting channels are a refreshing tool separate view from state/logic when used with other simple types. cheers @gregsn i guess

4 Likes

I’d use integers that count up for each click instead of Unit. You can do that yourself as well, but having bang buttons send changing integers directly would also help to understand how many clicks happened between frames without extra patching.

1 Like

@tonfilm good idea!

  1. Had another look at this: shying away from merging this back right away because of this being a breaking change, but did change the type from Unit to Bang with the main benefit, that equality checks typically return false, thus most operators work as expected.

  2. maybe not necessary, if Bang is used everywhere. I made buttons use them, needs more testing.

  3. ValueChanged being a process node with an Update call, outputting true outof the perspective of that patch - e.g. since last looked at by this “observer”?
    MessageReceived along those lines?

refreshing tool

thank you!

didn’t have the chance to compile and test yet.
first question would be, how does chaining work (consume / merge) with an increment.

the usecase from my last project was a couple of reset something buttons and one reset all. the all trigger would be consumed by the individual ones which each did their thing.
would a consumed bang have the same increment as the source or just also increment it’s own counter?

I made a special build to try it out.
Merge should propagate events as each Bang is different. The increment / integer value is not perceivable from the outside. It’s better to think of each bang to be just some unique thing.
Let’s test it out and take it from there.

1 Like