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}