Skip to main content

dreamwell_runtime/authority/
protocol.rs

1//! Authority protocol — trait contract for local and remote authority backends.
2//!
3//! Both LocalAuthority and RemoteAuthorityClient implement AuthorityClient.
4//! The runtime holds `Box<dyn AuthorityClient>` and calls it at phase boundaries,
5//! never in hot inner loops.
6
7use dreamwell_fabric::packets::ClientIntent;
8
9/// Connection state for the authority backend.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ConnectionState {
12    /// No connection attempt.
13    Disconnected,
14    /// Connection in progress.
15    Connecting,
16    /// Connected and synchronized.
17    Connected,
18    /// Connected but state diverged — needs resync.
19    Desynced,
20}
21
22/// Event received from the authority backend.
23#[derive(Debug, Clone)]
24pub enum AuthorityEvent {
25    /// Acknowledgment of a submitted intent.
26    Ack { seq: u64 },
27    /// Rejection of a submitted intent.
28    Reject { seq: u64, reason: String },
29    /// Canonical event from the authority.
30    CanonEvent {
31        tick: u64,
32        event_type: String,
33        payload: Vec<u8>,
34    },
35    /// Snapshot chunk for initial or re-sync.
36    SnapshotChunk {
37        chunk_id: u32,
38        total_chunks: u32,
39        data: Vec<u8>,
40    },
41}
42
43/// Authority client contract. Implemented by LocalAuthority and RemoteAuthorityClient.
44/// Called at phase boundaries (PollAuthority, StageAuthorityEvents), never in hot loops.
45pub trait AuthorityClient: Send {
46    /// Submit client intents to the authority for processing.
47    fn submit_intents(&mut self, intents: &[ClientIntent]);
48
49    /// Poll for authority events (non-blocking).
50    fn poll_events(&mut self, out: &mut Vec<AuthorityEvent>);
51
52    /// Request a full state snapshot for initial sync or resync.
53    fn request_snapshot(&mut self);
54
55    /// Current connection state.
56    fn connection_state(&self) -> ConnectionState;
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn connection_state_variants() {
65        let states = [
66            ConnectionState::Disconnected,
67            ConnectionState::Connecting,
68            ConnectionState::Connected,
69            ConnectionState::Desynced,
70        ];
71        assert_eq!(states.len(), 4);
72    }
73
74    #[test]
75    fn authority_event_variants() {
76        let _ack = AuthorityEvent::Ack { seq: 1 };
77        let _reject = AuthorityEvent::Reject {
78            seq: 2,
79            reason: "test".into(),
80        };
81        let _canon = AuthorityEvent::CanonEvent {
82            tick: 100,
83            event_type: "move".into(),
84            payload: vec![],
85        };
86        let _snapshot = AuthorityEvent::SnapshotChunk {
87            chunk_id: 0,
88            total_chunks: 1,
89            data: vec![],
90        };
91    }
92}