Skip to main content

hitbox_backend/composition/policy/
builder.rs

1//! CompositionPolicy builder for configuring all three policies together.
2
3use super::{
4    CompositionReadPolicy, CompositionWritePolicy, OptimisticParallelWritePolicy, RefillPolicy,
5    SequentialReadPolicy,
6};
7
8/// Bundle of read, write, and refill policies for CompositionBackend.
9///
10/// This struct provides a builder pattern for configuring all three policy types
11/// together, making it easy to create and reuse policy configurations.
12///
13/// # Example
14///
15/// ```ignore
16/// use hitbox_backend::composition::{CompositionPolicy, CompositionBackend};
17/// use hitbox_backend::composition::policy::{RaceReadPolicy, SequentialWritePolicy, RefillPolicy};
18///
19/// let policy = CompositionPolicy::new()
20///     .read(RaceReadPolicy::new())
21///     .write(SequentialWritePolicy::new())
22///     .refill(RefillPolicy::Always);
23///
24/// let backend = CompositionBackend::new(l1, l2)
25///     .with_policy(policy);
26/// ```
27#[derive(Debug, Clone)]
28pub struct CompositionPolicy<R = SequentialReadPolicy, W = OptimisticParallelWritePolicy>
29where
30    R: CompositionReadPolicy,
31    W: CompositionWritePolicy,
32{
33    /// Read policy
34    pub(crate) read: R,
35    /// Write policy
36    pub(crate) write: W,
37    /// Refill policy
38    pub(crate) refill: RefillPolicy,
39}
40
41impl CompositionPolicy<SequentialReadPolicy, OptimisticParallelWritePolicy> {
42    /// Create a new policy bundle with default policies.
43    ///
44    /// Default policies:
45    /// - Read: `SequentialReadPolicy` (try L1 first, then L2)
46    /// - Write: `OptimisticParallelWritePolicy` (write to both, succeed if ≥1 succeeds)
47    /// - Refill: `RefillPolicy::Never` (do not populate L1 after L2 hit)
48    pub fn new() -> Self {
49        Self {
50            read: SequentialReadPolicy::new(),
51            write: OptimisticParallelWritePolicy::new(),
52            refill: RefillPolicy::default(),
53        }
54    }
55}
56
57impl Default for CompositionPolicy<SequentialReadPolicy, OptimisticParallelWritePolicy> {
58    fn default() -> Self {
59        Self::new()
60    }
61}
62
63impl<R, W> CompositionPolicy<R, W>
64where
65    R: CompositionReadPolicy,
66    W: CompositionWritePolicy,
67{
68    /// Set the read policy (builder pattern).
69    ///
70    /// # Example
71    /// ```ignore
72    /// use hitbox_backend::composition::CompositionPolicy;
73    /// use hitbox_backend::composition::policy::RaceReadPolicy;
74    ///
75    /// let policy = CompositionPolicy::new()
76    ///     .read(RaceReadPolicy::new());
77    /// ```
78    pub fn read<NewR: CompositionReadPolicy>(self, read: NewR) -> CompositionPolicy<NewR, W> {
79        CompositionPolicy {
80            read,
81            write: self.write,
82            refill: self.refill,
83        }
84    }
85
86    /// Set the write policy (builder pattern).
87    ///
88    /// # Example
89    /// ```ignore
90    /// use hitbox_backend::composition::CompositionPolicy;
91    /// use hitbox_backend::composition::policy::SequentialWritePolicy;
92    ///
93    /// let policy = CompositionPolicy::new()
94    ///     .write(SequentialWritePolicy::new());
95    /// ```
96    pub fn write<NewW: CompositionWritePolicy>(self, write: NewW) -> CompositionPolicy<R, NewW> {
97        CompositionPolicy {
98            read: self.read,
99            write,
100            refill: self.refill,
101        }
102    }
103
104    /// Set the refill policy (builder pattern).
105    ///
106    /// # Example
107    /// ```ignore
108    /// use hitbox_backend::composition::CompositionPolicy;
109    /// use hitbox_backend::composition::policy::RefillPolicy;
110    ///
111    /// let policy = CompositionPolicy::new()
112    ///     .refill(RefillPolicy::Always);
113    /// ```
114    pub fn refill(self, refill: RefillPolicy) -> CompositionPolicy<R, W> {
115        CompositionPolicy {
116            read: self.read,
117            write: self.write,
118            refill,
119        }
120    }
121
122    /// Get a reference to the read policy.
123    pub fn read_policy(&self) -> &R {
124        &self.read
125    }
126
127    /// Get a reference to the write policy.
128    pub fn write_policy(&self) -> &W {
129        &self.write
130    }
131
132    /// Get a reference to the refill policy.
133    pub fn refill_policy(&self) -> &RefillPolicy {
134        &self.refill
135    }
136}