Fixed bidi binding not propagating double update values.

This commit is contained in:
Samuel Guerra 2023-05-30 17:00:32 -03:00
parent 2e0ea549e9
commit 43196349dc
3 changed files with 21 additions and 14 deletions

View File

@ -31,9 +31,6 @@
# Localization # Localization
* Changing lang can sometimes show the template fallback title.
- Change to pseudo as soon as the window open to see.
- After changing back and forth the actual pseudo-title is set.
* Review wait, how do handles work when request is not found yet? * Review wait, how do handles work when request is not found yet?
* Test live update of localization file. * Test live update of localization file.

View File

@ -227,7 +227,7 @@ impl ClickArgs {
} }
/// Gets the click position, if the click was generated by a device with position. /// Gets the click position, if the click was generated by a device with position.
/// ///
/// The position is in the coordinates of [`target`](ClickArgs::target). /// The position is in the coordinates of [`target`](ClickArgs::target).
pub fn position(&self) -> Option<DipPoint> { pub fn position(&self) -> Option<DipPoint> {
match &self.source { match &self.source {

View File

@ -1364,14 +1364,19 @@ pub trait Var<T: VarValue>: IntoVar<T, Var = Self> + AnyVar + Clone {
M: FnMut(&T) -> T2 + Send + 'static, M: FnMut(&T) -> T2 + Send + 'static,
B: FnMut(&T2) -> T + Send + 'static, B: FnMut(&T2) -> T + Send + 'static,
{ {
let last_update = Arc::new(Atomic::new(VarUpdateId::never())); // (self_to_other_id, other_to_self_id)
// used to stop an extra "map_back" caused by "map" itself
// using two ids allows us to support double updates flowing in the same direction.
let last_update = Arc::new(Atomic::new((VarUpdateId::never(), VarUpdateId::never())));
let self_to_other = var_bind( let self_to_other = var_bind(
self, self,
other, other,
clmv!(last_update, |value, other| { clmv!(last_update, |value, other| {
let update_id = VARS.update_id(); let update_id = VARS.update_id();
if update_id != last_update.load(Relaxed) { let (_, ots_id) = last_update.load(Relaxed);
last_update.store(update_id, Relaxed); if update_id != ots_id {
// other_to_self did not cause this assign, propagate.
last_update.store((update_id, ots_id), Relaxed);
let _ = other.set(map(value)); let _ = other.set(map(value));
} }
}), }),
@ -1379,8 +1384,10 @@ pub trait Var<T: VarValue>: IntoVar<T, Var = Self> + AnyVar + Clone {
let other_to_self = var_bind(other, self, move |value, self_| { let other_to_self = var_bind(other, self, move |value, self_| {
let update_id = VARS.update_id(); let update_id = VARS.update_id();
if update_id != last_update.load(Relaxed) { let (sto_id, _) = last_update.load(Relaxed);
last_update.store(update_id, Relaxed); if update_id != sto_id {
// self_to_other did not cause this assign.
last_update.store((sto_id, update_id), Relaxed);
let _ = self_.set(map_back(value)); let _ = self_.set(map_back(value));
} }
}); });
@ -1402,14 +1409,15 @@ pub trait Var<T: VarValue>: IntoVar<T, Var = Self> + AnyVar + Clone {
M: FnMut(&T) -> Option<T2> + Send + 'static, M: FnMut(&T) -> Option<T2> + Send + 'static,
B: FnMut(&T2) -> Option<T> + Send + 'static, B: FnMut(&T2) -> Option<T> + Send + 'static,
{ {
let last_update = Arc::new(Atomic::new(VarUpdateId::never())); let last_update = Arc::new(Atomic::new((VarUpdateId::never(), VarUpdateId::never())));
let self_to_other = var_bind( let self_to_other = var_bind(
self, self,
other, other,
clmv!(last_update, |value, other| { clmv!(last_update, |value, other| {
let update_id = VARS.update_id(); let update_id = VARS.update_id();
if update_id != last_update.load(Relaxed) { let (_, ots_id) = last_update.load(Relaxed);
last_update.store(update_id, Relaxed); if update_id != ots_id {
// other_to_self did not cause this assign, propagate.
if let Some(value) = map(value) { if let Some(value) = map(value) {
let _ = other.set(value); let _ = other.set(value);
} }
@ -1419,8 +1427,10 @@ pub trait Var<T: VarValue>: IntoVar<T, Var = Self> + AnyVar + Clone {
let other_to_self = var_bind(other, self, move |value, self_| { let other_to_self = var_bind(other, self, move |value, self_| {
let update_id = VARS.update_id(); let update_id = VARS.update_id();
if update_id != last_update.load(Relaxed) { let (sto_id, _) = last_update.load(Relaxed);
last_update.store(update_id, Relaxed); if update_id != sto_id {
// self_to_other did not cause this assign.
last_update.store((sto_id, update_id), Relaxed);
if let Some(value) = map_back(value) { if let Some(value) = map_back(value) {
let _ = self_.set(value); let _ = self_.set(value);
} }