@@ -45,12 +45,14 @@ pub(crate) struct WritableComponent<'a> {
4545 pub ( crate ) ptr : Ptr < ' a > ,
4646 pub ( crate ) fns_id : FnsId ,
4747 pub ( crate ) ctx : SerializeCtx < ' a > ,
48- diff : Option < WritableDiffComponent < ' a > > ,
4948}
5049
51- struct WritableDiffComponent < ' a > {
52- fns : DiffFns ,
53- log : Ptr < ' a > ,
50+ #[ derive( Clone , Copy ) ]
51+ pub ( crate ) struct WritableDiff < ' a > {
52+ /// Diff functions for the same component type as [`WritableComponent`].
53+ pub ( crate ) fns : DiffFns ,
54+ /// Pointer to `DiffLog<C>` for the same component type as [`WritableComponent`].
55+ pub ( crate ) log : Ptr < ' a > ,
5456}
5557
5658pub ( crate ) struct WrittenComponent {
@@ -64,12 +66,9 @@ impl<'a> WritableComponent<'a> {
6466 /// # Safety
6567 ///
6668 /// The caller must ensure that `fns` and `ptr` was created for the same type.
67- /// If `diff` is set, its log pointer must point to the matching `DiffLog` for
68- /// that same component type.
6969 pub ( crate ) unsafe fn new (
7070 fns : SerdeFns < ' a > ,
7171 ptr : Ptr < ' a > ,
72- diff : Option < ( DiffFns , Ptr < ' a > ) > ,
7372 fns_id : FnsId ,
7473 component_id : ComponentId ,
7574 server_tick : RepliconTick ,
@@ -84,69 +83,77 @@ impl<'a> WritableComponent<'a> {
8483 server_tick,
8584 type_registry,
8685 } ,
87- diff : diff. map ( |( fns, log) | WritableDiffComponent { fns, log } ) ,
8886 }
8987 }
9088
91- /// Writes component data for a mutation message.
89+ /// Writes component data for an update or mutation message.
9290 ///
93- /// Non-diff components can reuse the same serialized range for all clients.
94- /// Diff components depend on each client's last ACKed patch cursor, so they
95- /// are serialized per client and return the patch cursor that should advance
96- /// when the mutation message is ACKed.
91+ /// Without `diff`, this uses the normal cached component serialization.
92+ /// With `diff`, `acked_patch_cursor` controls the payload: [`None`] writes a
93+ /// cacheable snapshot, and [`Some`] writes patches after that cursor or falls
94+ /// back to a snapshot. The returned patch cursor should be tracked only for
95+ /// mutation messages that passed [`Some`].
9796 pub ( crate ) fn write_mutation (
9897 & self ,
9998 serialized : & mut SerializedData ,
10099 cached_range : & mut Option < Range < usize > > ,
101- acked_patch_cursor : PatchIndex ,
100+ diff : Option < WritableDiff < ' a > > ,
101+ acked_patch_cursor : Option < PatchIndex > ,
102102 ) -> Result < WrittenComponent > {
103- if self . diff . is_some ( ) {
104- self . write_uncached ( serialized, Some ( acked_patch_cursor) )
105- } else {
106- Ok ( WrittenComponent {
103+ let Some ( diff) = diff else {
104+ return Ok ( WrittenComponent {
107105 range : self . write_cached ( serialized, cached_range) ?,
108106 patch_cursor : None ,
109- } )
107+ } ) ;
108+ } ;
109+
110+ if acked_patch_cursor. is_none ( )
111+ && let Some ( range) = cached_range. clone ( )
112+ {
113+ return Ok ( WrittenComponent {
114+ range,
115+ patch_cursor : None ,
116+ } ) ;
110117 }
111- }
112118
113- fn write_uncached (
114- & self ,
115- serialized : & mut SerializedData ,
116- acked_patch_cursor : Option < PatchIndex > ,
117- ) -> Result < WrittenComponent > {
118119 let start = serialized. len ( ) ;
119120
120121 postcard_utils:: to_extend_mut ( & self . fns_id , & mut serialized. 0 ) ?;
121- let patch_cursor = if let Some ( diff) = & self . diff {
122- // SAFETY: `diff`, `ptr` and `log` were created for the same component type.
123- Some ( unsafe {
124- diff. fns . serialize_mutation (
125- & self . ctx ,
126- self . ptr ,
127- diff. log ,
128- acked_patch_cursor,
129- & mut serialized. 0 ,
130- ) ?
131- } )
132- } else {
133- // SAFETY: `fns` and `ptr` were created for the same component type.
134- unsafe { self . fns . serialize ( & self . ctx , self . ptr , & mut serialized. 0 ) ? } ;
135- None
122+ // SAFETY: `diff`, `ptr` and `log` were created for the same component type.
123+ let cursor = unsafe {
124+ diff. fns . serialize_mutation (
125+ & self . ctx ,
126+ self . ptr ,
127+ diff. log ,
128+ acked_patch_cursor,
129+ & mut serialized. 0 ,
130+ ) ?
136131 } ;
137132
138133 let end = serialized. len ( ) ;
134+ let range = start..end;
135+ if acked_patch_cursor. is_none ( ) {
136+ * cached_range = Some ( range. clone ( ) ) ;
137+ }
139138
140139 Ok ( WrittenComponent {
141- range : start..end ,
142- patch_cursor,
140+ range,
141+ patch_cursor : acked_patch_cursor . map ( |_| cursor ) ,
143142 } )
144143 }
145144}
146145
147146impl MessageWrite for WritableComponent < ' _ > {
148147 fn write ( & self , serialized : & mut SerializedData ) -> Result < Range < usize > > {
149- Ok ( self . write_uncached ( serialized, None ) ?. range )
148+ let start = serialized. len ( ) ;
149+
150+ postcard_utils:: to_extend_mut ( & self . fns_id , & mut serialized. 0 ) ?;
151+ // SAFETY: `fns` and `ptr` were created for the same component type.
152+ unsafe { self . fns . serialize ( & self . ctx , self . ptr , & mut serialized. 0 ) ? } ;
153+
154+ let end = serialized. len ( ) ;
155+
156+ Ok ( start..end)
150157 }
151158}
152159
0 commit comments