Cool, by thinking of IO at this level outside of sodium, I ended up creating two separate streams:
- sTick - sends every tick
- sTickPointer - sends every tick with the pointer data, if and only if there's a new pointer event since the last firing (configurable so pointer event could be "pointermove")
With those streams:
- sTick ultimately drives the repaints (and will drive animation too)
- sTickPointer drives things that are affected by move events
Along with the optimisation, this is also nice since it's much more declarative from the program itself. i.e. "position is a function of sTickPointer". Nice, clean, and easy to reason about. As opposed to "position is a function of sTick and the last cached move event if hasn't been updated since last update"
More declarative and generic since it lifts that logic up outside the whole network
There are some missed pointer events in this case - but that's really a non-issue (see the Google article). Anyway, the wrapper around sTickPointer could consolidate and send all the cached events as a batch if the need arises. Also I haven't tested on Edge yet since I'm not at a windows machine, but I can't imagine that this would be a performance hit, at the very least_