rerun-io / rerun

Visualize streams of multimodal data. Fast, easy to use, and simple to integrate. Built in Rust using egui.
https://rerun.io/
Apache License 2.0
6.34k stars 304 forks source link

Replace VisualizerOverrides boolean indicator components #6626

Open jleibs opened 3 months ago

jleibs commented 3 months ago

Background

Indicators are currently valueless. They are always logged as null, and as such their only purpose is to force the inclusion of a particular magic component-name into the list of components that exist on an entity path.

This means you can never clear an indicator. Once it's been logged it will always be present.

But whether a visualizer is enabled is is something we would like to both enable/disable from the blueprint. The fact that indicators cannot be cleared in a meaningful way makes them not currently suitable for usage in a blueprint context.

To work around this we have introduced awkward constructs like "VisualizerOverride", or it's newely proposed inverse, "HideVisualizers." Both of these are ultimately poor substitutes for what we would really like to do: explicitly enable or disable a visualizer via default/override.

Proposal

Instead of investing all this effort to work around this, let's just make indicators an optional bool.

By default, archetypes would leave the value of indicator as null. It's still possible for some parts of the system to treat "exists and null" as subtly different than "doesn't exist."

Once indicators are a bool, it becomes meaningful to make the query latest_at_with_blueprint_resolved_data:

However, as this is now a component with blueprint-provided resolution, we have several options for how this gets set via the new override/default/fallback stack:

Of note, this also opens up a pathway to both data-sourced and time-varying visualizer controls.

Complications

The biggest complication to this is avoiding overhead of a bunch of boolean values in every chunk. However, I believe we should have generalized null-value optimization anyways, where if a component is null for every row, then we can bypass needing to store a list-array/value-buffer at all.

Wumpf commented 3 months ago

I like it! In particular the per Visualizer interaction via the FallbackProvider system is rather charming. Don't know why we rolled up changing the indicators themselves again, probably size considerations?

If a view-level default was provided explicitly, we would use it.

if this is rare enough we could even do that on a per visualizer basis using data conveyed via the ViewState as we do in some other places. Meaning we don't have to formalize this.

teh-cmc commented 3 months ago

Indicators are currently valueless. They are always logged as null, and as such their only purpose is to force the inclusion of a particular magic component-name into the list of components that exist on an entity path.

This means you can never clear an indicator. Once it's been logged it will always be present.

No opinion on the topic of valued indicators themselves, and not sure whether that's relevant here, but adding more context just in case: indicator components are currently logged as an array of null values whose length is the same as the primary/required component on that row (which is free because of how null arrays are encoded). And that length becomes zero if the indicator gets cleared as part of a legacy cascaded clear.

We've made the choice to never actually look at the data for indicators, but technically one could already check the length today and know whether the indicator has been cleared or not.

Obviously very related to query-time clears and the whole discussion about missing data vs. cleared data vs. empty data etc.