Goal: flip the app theme or language at runtime and have every derived label / colour update automatically, with no manual refresh.
The framework piece is just Property<T> + Computed<T>: model the current theme/locale as a Property, and derive every user-visible string/colour as a Computed that reads it. The app defines its own Theme / Locale enums — Aria provides the reactivity, not the catalogue.
enum class Locale { En, Zh, Ja };
enum class Theme { Light, Dark };
case Locale::Zh: return std::string{"你好"};
case Locale::Ja: return std::string{"こんにちは"};
default: return std::string{"Hello"};
}
}};
return theme.
get() == Theme::Dark ? Color::Charcoal : Color::White;
}};
Definition computed.hpp:86
Definition property.hpp:103
T get() const
Auto-tracked read.
Definition property.hpp:138
Bind the computed values to widgets; switching is a single Property write:
auto g_sub = greeting.
bind([](
const std::string& s){ title_label.text = s; });
auto c_sub = bg.
bind ([](Color c){ root_view.background = c; });
void switch_to_chinese_dark() {
});
}
::aria::Subscription bind(std::function< void(const T &)> fn)
Definition effect.hpp:179
void set(const T &new_val)
Commit a new value.
Definition property.hpp:179
auto batch(Fn &&fn) -> decltype(fn())
Sugar: batch([&]{ firstName = "..."; lastName = "..."; }).
Definition graph.hpp:369
Why this is glitch-free
- Computed is pull-based and equality-gated (L-21 / L-22): a recompute that produces the same value does not notify downstream, so flipping theme does not needlessly refire locale-only labels.
- batch coalesces (L-20): wrapping the two writes means the graph flushes once, after both Properties are set — observers never see the intermediate "Chinese + Light" half-state.
- Dynamic dependencies (L-17): a Computed that reads locale only in some branches is subscribed to locale only while that branch is live — no ghost subscriptions when the branch flips.
Scaling up
For a real string catalogue, make the Computed read both locale and a Property<const StringTable*> (hot-reloadable translations), or keep a Computed<const StringTable&> selected by locale and have each label Computed read table().lookup(key). The pattern composes: every label is a node that re-pulls only when something it actually read changed.