From 4df8a275bd49f5c486c1fde4619dd80bab3a4e54 Mon Sep 17 00:00:00 2001 From: Alexander Koptelov Date: Fri, 1 Mar 2024 21:26:14 +0300 Subject: [PATCH 1/6] feat(enabling-cond): enabling conditions with time --- src/action/enabling_condition.rs | 11 ++++++++++- src/store.rs | 15 +++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/action/enabling_condition.rs b/src/action/enabling_condition.rs index 88b04a7..dc593de 100644 --- a/src/action/enabling_condition.rs +++ b/src/action/enabling_condition.rs @@ -1,8 +1,17 @@ +#[allow(unused_variables)] pub trait EnablingCondition { /// Enabling condition for the Action. /// /// Checks if the given action is enabled for a given state. - fn is_enabled(&self, #[allow(unused_variables)] state: &State) -> bool { + fn is_enabled(&self, state: &State) -> bool { true } + + /// Enabling condition for the Action. + /// + /// Checks if the given action is enabled for a given state. + fn is_enabled_with_time(&self, state: &State, time: crate::Timestamp) -> bool { + self.is_enabled(state) + } } + diff --git a/src/store.rs b/src/store.rs index b5225f2..6440c4a 100644 --- a/src/store.rs +++ b/src/store.rs @@ -138,10 +138,9 @@ where where T: Into + EnablingCondition, { - if !action.is_enabled(self.state()) { + if !action.is_enabled_with_time(self.state(), self.last_action_id.into()) { return false; } - self.dispatch_enabled(action.into()); true @@ -153,15 +152,13 @@ where /// to reducer and then effects. /// /// If action is not enabled, we return false and do nothing. - pub fn sub_dispatch(&mut self, action: A) -> bool + pub fn sub_dispatch(&mut self, action: A) -> bool where - A: Into + EnablingCondition, - SubAction: Into, + A: Into + EnablingCondition, { - if !action.is_enabled(self.state()) { + if !action.is_enabled_with_time(self.state(), self.last_action_id.into()) { return false; } - self.dispatch_enabled(action.into().into()); true @@ -173,13 +170,11 @@ where let time_passed = monotonic_time .duration_since(self.monotonic_time) .as_nanos(); - - self.monotonic_time = monotonic_time; self.last_action_id = self.last_action_id.next(time_passed as u64); + self.recursion_depth += 1; let action_with_meta = ActionMeta::new(self.last_action_id, self.recursion_depth).with_action(action); - self.recursion_depth += 1; self.dispatch_reducer(&action_with_meta); self.dispatch_effects(action_with_meta); From 0a85a1efb6c817f9714010b801efc7cd882cb947 Mon Sep 17 00:00:00 2001 From: Alexander Koptelov Date: Fri, 1 Mar 2024 21:39:04 +0300 Subject: [PATCH 2/6] feat(enabling-cond): lax enablingcond for substore Assuming that there will be no stricter enabling conditions for actions from substores. --- src/store.rs | 8 +++++--- src/sub_store.rs | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/store.rs b/src/store.rs index 6440c4a..6c4f854 100644 --- a/src/store.rs +++ b/src/store.rs @@ -2,7 +2,7 @@ use std::sync::OnceLock; use crate::{ ActionId, ActionMeta, ActionWithMeta, Effects, EnablingCondition, Instant, Reducer, SystemTime, - TimeService, + TimeService, SubStore, }; /// Wraps around State and allows only immutable borrow, @@ -154,9 +154,11 @@ where /// If action is not enabled, we return false and do nothing. pub fn sub_dispatch(&mut self, action: A) -> bool where - A: Into + EnablingCondition, + A: Into<>::SubAction> + EnablingCondition, + >::SubAction: Into, + Self: SubStore, { - if !action.is_enabled_with_time(self.state(), self.last_action_id.into()) { + if !action.is_enabled_with_time(>::state(self), self.last_action_id.into()) { return false; } self.dispatch_enabled(action.into().into()); diff --git a/src/sub_store.rs b/src/sub_store.rs index 17b1514..6417a93 100644 --- a/src/sub_store.rs +++ b/src/sub_store.rs @@ -10,5 +10,5 @@ pub trait SubStore { fn state_and_service(&mut self) -> (&SubState, &mut Self::Service); fn dispatch(&mut self, action: A) -> bool where - A: Into + crate::EnablingCondition; + A: Into + crate::EnablingCondition; } From e353731cfb113b0cfc6a79eb414ad655283fd0c6 Mon Sep 17 00:00:00 2001 From: Alexander Koptelov Date: Mon, 4 Mar 2024 16:56:29 +0300 Subject: [PATCH 3/6] feat(enabling-cond): use single trait method --- src/action/enabling_condition.rs | 11 ++--------- src/store.rs | 4 ++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/action/enabling_condition.rs b/src/action/enabling_condition.rs index dc593de..fc30d5f 100644 --- a/src/action/enabling_condition.rs +++ b/src/action/enabling_condition.rs @@ -2,16 +2,9 @@ pub trait EnablingCondition { /// Enabling condition for the Action. /// - /// Checks if the given action is enabled for a given state. - fn is_enabled(&self, state: &State) -> bool { + /// Checks if the given action is enabled for a given state and timestamp. + fn is_enabled(&self, state: &State, time: crate::Timestamp) -> bool { true } - - /// Enabling condition for the Action. - /// - /// Checks if the given action is enabled for a given state. - fn is_enabled_with_time(&self, state: &State, time: crate::Timestamp) -> bool { - self.is_enabled(state) - } } diff --git a/src/store.rs b/src/store.rs index 6c4f854..8de0ade 100644 --- a/src/store.rs +++ b/src/store.rs @@ -138,7 +138,7 @@ where where T: Into + EnablingCondition, { - if !action.is_enabled_with_time(self.state(), self.last_action_id.into()) { + if !action.is_enabled(self.state(), self.last_action_id.into()) { return false; } self.dispatch_enabled(action.into()); @@ -158,7 +158,7 @@ where >::SubAction: Into, Self: SubStore, { - if !action.is_enabled_with_time(>::state(self), self.last_action_id.into()) { + if !action.is_enabled(>::state(self), self.last_action_id.into()) { return false; } self.dispatch_enabled(action.into().into()); From c1707773f9008198d2ce350f77388b9e3bd16a78 Mon Sep 17 00:00:00 2001 From: Alexander Koptelov Date: Mon, 4 Mar 2024 18:10:20 +0300 Subject: [PATCH 4/6] feat(enabling-cond): add prev action time to meta --- src/action/action_meta.rs | 14 ++++++++++++-- src/store.rs | 5 +++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/action/action_meta.rs b/src/action/action_meta.rs index 93dcc05..5147344 100644 --- a/src/action/action_meta.rs +++ b/src/action/action_meta.rs @@ -11,6 +11,8 @@ pub type RecursionDepth = u32; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ActionMeta { id: ActionId, + /// Previously applied action. + prev: ActionId, /// Recursion depth of a given action. depth: RecursionDepth, } @@ -18,18 +20,20 @@ pub struct ActionMeta { impl ActionMeta { pub const ZERO: Self = Self { id: ActionId::ZERO, + prev: ActionId::ZERO, depth: 0, }; #[inline(always)] - pub(crate) fn new(id: ActionId, depth: RecursionDepth) -> Self { - Self { id, depth } + pub(crate) fn new(id: ActionId, prev: ActionId, depth: RecursionDepth) -> Self { + Self { id, prev, depth } } #[inline(always)] pub fn zero_custom(time: Timestamp) -> Self { Self { id: ActionId::new_unchecked(time.into()), + prev: ActionId::new_unchecked(time.into()), depth: 0, } } @@ -45,6 +49,12 @@ impl ActionMeta { self.depth } + /// Time of previously applied action. + #[inline(always)] + pub fn prev_time(&self) -> Timestamp { + self.prev.into() + } + #[inline(always)] pub fn time(&self) -> Timestamp { self.id.into() diff --git a/src/store.rs b/src/store.rs index 8de0ade..890afea 100644 --- a/src/store.rs +++ b/src/store.rs @@ -172,11 +172,12 @@ where let time_passed = monotonic_time .duration_since(self.monotonic_time) .as_nanos(); - self.last_action_id = self.last_action_id.next(time_passed as u64); + let prev = self.last_action_id; + self.last_action_id = prev.next(time_passed as u64); self.recursion_depth += 1; let action_with_meta = - ActionMeta::new(self.last_action_id, self.recursion_depth).with_action(action); + ActionMeta::new(self.last_action_id, prev, self.recursion_depth).with_action(action); self.dispatch_reducer(&action_with_meta); self.dispatch_effects(action_with_meta); From 9826c5223104acdd547c36c27966a4be89b34b17 Mon Sep 17 00:00:00 2001 From: Alexander Koptelov Date: Tue, 5 Mar 2024 21:26:34 +0300 Subject: [PATCH 5/6] feat(enabling-cond): fix monotonic time update --- src/store.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/store.rs b/src/store.rs index 890afea..ff12cac 100644 --- a/src/store.rs +++ b/src/store.rs @@ -1,8 +1,8 @@ use std::sync::OnceLock; use crate::{ - ActionId, ActionMeta, ActionWithMeta, Effects, EnablingCondition, Instant, Reducer, SystemTime, - TimeService, SubStore, + ActionId, ActionMeta, ActionWithMeta, Effects, EnablingCondition, Instant, Reducer, SubStore, + SystemTime, TimeService, }; /// Wraps around State and allows only immutable borrow, @@ -158,7 +158,10 @@ where >::SubAction: Into, Self: SubStore, { - if !action.is_enabled(>::state(self), self.last_action_id.into()) { + if !action.is_enabled( + >::state(self), + self.last_action_id.into(), + ) { return false; } self.dispatch_enabled(action.into().into()); @@ -172,12 +175,16 @@ where let time_passed = monotonic_time .duration_since(self.monotonic_time) .as_nanos(); + self.monotonic_time = monotonic_time; + let prev = self.last_action_id; - self.last_action_id = prev.next(time_passed as u64); - self.recursion_depth += 1; + let curr = prev.next(time_passed as u64); let action_with_meta = - ActionMeta::new(self.last_action_id, prev, self.recursion_depth).with_action(action); + ActionMeta::new(curr, prev, self.recursion_depth).with_action(action); + + self.last_action_id = curr; + self.recursion_depth += 1; self.dispatch_reducer(&action_with_meta); self.dispatch_effects(action_with_meta); From b190ad1e59efba04477b65f26cea36867fc481ae Mon Sep 17 00:00:00 2001 From: Zura Benashvili Date: Mon, 13 May 2024 14:24:24 +0400 Subject: [PATCH 6/6] fix(action): recursion depth always 0 --- src/store.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/store.rs b/src/store.rs index ff12cac..7022740 100644 --- a/src/store.rs +++ b/src/store.rs @@ -180,12 +180,12 @@ where let prev = self.last_action_id; let curr = prev.next(time_passed as u64); - let action_with_meta = - ActionMeta::new(curr, prev, self.recursion_depth).with_action(action); - self.last_action_id = curr; self.recursion_depth += 1; + let action_with_meta = + ActionMeta::new(curr, prev, self.recursion_depth).with_action(action); + self.dispatch_reducer(&action_with_meta); self.dispatch_effects(action_with_meta);