1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
use std::{any::Any, collections::HashSet};
use naia_serde::{BitReader, BitWrite, SerdeErr};
use crate::world::update::component_update::ComponentUpdate;
use crate::world::update::diff_mask::DiffMask;
use crate::{
named::Named,
world::{
component::{
component_kinds::{ComponentKind, ComponentKinds},
property_mutate::PropertyMutator,
replica_ref::{ReplicaDynMut, ReplicaDynRef},
},
delegation::auth_channel::EntityAuthAccessor,
entity::entity_converters::LocalEntityAndGlobalEntityConverter,
},
ComponentFieldUpdate, LocalEntityAndGlobalEntityConverterMut, RemoteEntity,
};
/// Result of splitting a component update into a waiting set (unresolved entity refs) and a ready payload.
pub type SplitUpdateResult = Result<
(
Option<Vec<(RemoteEntity, ComponentFieldUpdate)>>,
Option<ComponentUpdate>,
),
SerdeErr,
>;
/// Factory trait for deserializing a concrete `Replicate` component or its partial updates from raw bits.
pub trait ReplicateBuilder: Send + Sync + Named {
/// Returns true if the component type is marked `#[replicate(immutable)]`.
fn is_immutable(&self) -> bool {
false
}
/// Create new Component from incoming bit stream
fn read(
&self,
reader: &mut BitReader,
converter: &dyn LocalEntityAndGlobalEntityConverter,
) -> Result<Box<dyn Replicate>, SerdeErr>;
/// Create new Component Update from incoming bit stream
fn read_create_update(&self, reader: &mut BitReader) -> Result<ComponentUpdate, SerdeErr>;
/// Split a Component update into Waiting and Ready updates
fn split_update(
&self,
converter: &dyn LocalEntityAndGlobalEntityConverter,
update: ComponentUpdate,
) -> SplitUpdateResult;
/// Returns a heap-allocated clone of this builder.
fn box_clone(&self) -> Box<dyn ReplicateBuilder>;
}
/// A struct that implements Replicate is a Component, or otherwise,
/// a container of Properties that can be scoped, tracked, and synced, with a
/// remote host
pub trait Replicate: Sync + Send + 'static + Named + Any {
/// Returns true if this component type never sends mutation updates.
/// Immutable components are written once on spawn and never diff-tracked.
/// Override in the derive macro by adding `#[replicate(immutable)]`.
fn is_immutable(&self) -> bool {
false
}
/// Gets the ComponentKind of this type
fn kind(&self) -> ComponentKind;
/// Returns a shared `Any` reference for downcasting.
fn to_any(&self) -> &dyn Any;
/// Returns a mutable `Any` reference for downcasting.
fn to_any_mut(&mut self) -> &mut dyn Any;
/// Converts this boxed component into a `Box<dyn Any>` for downcasting.
fn to_boxed_any(self: Box<Self>) -> Box<dyn Any>;
/// Returns a heap-allocated clone of this component as a trait object.
fn copy_to_box(&self) -> Box<dyn Replicate>;
/// Creates the `ReplicateBuilder` used to deserialize instances of this type.
fn create_builder() -> Box<dyn ReplicateBuilder>
where
Self: Sized;
/// Gets the number of bytes of the Component's DiffMask
fn diff_mask_size(&self) -> u8;
/// Get an immutable reference to the inner Component as a Replicate trait object
fn dyn_ref(&self) -> ReplicaDynRef<'_>;
/// Get an mutable reference to the inner Component as a Replicate trait object
fn dyn_mut(&mut self) -> ReplicaDynMut<'_>;
/// Sets the current Component to the state of another Component of the
/// same type
fn mirror(&mut self, other: &dyn Replicate);
/// Mirror a SINGLE Property field from `other` into `self`, identified
/// by its 0-based property index (the same index used by the diff-mask
/// bit positions). Calls `Property::mirror` on exactly one field —
/// fires that field's PropertyMutator without touching any others.
///
/// Used by the Replicated Resources Mode B mirror system to propagate
/// per-field changes from the user-facing bevy `Resource` storage to
/// the entity-component without over-replicating untouched fields.
///
/// **Out-of-range indices are silently no-op'd** (schema evolution
/// across protocol versions may produce stale dirty indices; we
/// tolerate that without panicking).
///
/// **Type mismatch** (`other` is not the same concrete type as
/// `self`) is a programming error: the derive-macro impl
/// `debug_assert!`s in debug builds and silently no-ops in release.
/// This is hostile to ignore but a hot per-tick sync system shouldn't
/// panic in production.
fn mirror_single_field(&mut self, field_index: u8, other: &dyn Replicate);
/// Set the Component's PropertyMutator, which keeps track
/// of which Properties have been mutated, necessary to sync only the
/// Properties that have changed with the client
fn set_mutator(&mut self, mutator: &PropertyMutator);
/// Writes data into an outgoing byte stream, sufficient to completely
/// recreate the Component on the client
fn write(
&self,
component_kinds: &ComponentKinds,
writer: &mut dyn BitWrite,
converter: &mut dyn LocalEntityAndGlobalEntityConverterMut,
);
/// Write data into an outgoing byte stream, sufficient only to update the
/// mutated Properties of the Component on the client
fn write_update(
&self,
diff_mask: &DiffMask,
writer: &mut dyn BitWrite,
converter: &mut dyn LocalEntityAndGlobalEntityConverterMut,
);
/// Reads data from an incoming packet, sufficient to sync the in-memory
/// Component with it's replica on the Server
fn read_apply_update(
&mut self,
converter: &dyn LocalEntityAndGlobalEntityConverter,
update: ComponentUpdate,
) -> Result<(), SerdeErr>;
/// Applies a single-field update from the network, updating the corresponding property in-place.
fn read_apply_field_update(
&mut self,
converter: &dyn LocalEntityAndGlobalEntityConverter,
update: ComponentFieldUpdate,
) -> Result<(), SerdeErr>;
/// Returns a list of LocalEntities contained within the Component's EntityProperty fields, which are waiting to be converted to GlobalEntities
fn relations_waiting(&self) -> Option<HashSet<RemoteEntity>>;
/// Converts any LocalEntities contained within the Component's EntityProperty fields to GlobalEntities
fn relations_complete(&mut self, converter: &dyn LocalEntityAndGlobalEntityConverter);
/// Publish Replicate
fn publish(&mut self, mutator: &PropertyMutator);
/// Unpublish Replicate
fn unpublish(&mut self);
/// Enable Delegation Replicate
fn enable_delegation(
&mut self,
accessor: &EntityAuthAccessor,
mutator_opt: Option<&PropertyMutator>,
);
/// Disable Delegation Replicate
fn disable_delegation(&mut self);
/// Convert to Local Replicate
fn localize(&mut self);
}
cfg_if! {
if #[cfg(feature = "bevy_support")]
{
// Require that Bevy Component to be implemented
use bevy_ecs::component::{Component, Mutable};
/// Marker trait combining `Replicate` with the Bevy `Component` bound; auto-implemented.
pub trait ReplicatedComponent: Replicate + Component<Mutability = Mutable> {}
impl<T: Replicate + Component<Mutability = Mutable>> ReplicatedComponent for T {}
}
else
{
/// Marker trait equivalent to `Replicate`; auto-implemented for all `Replicate` types when Bevy is not in use.
pub trait ReplicatedComponent: Replicate {}
impl<T: Replicate> ReplicatedComponent for T {}
}
}