use super::protocol::{AuthorityClient, AuthorityEvent, ConnectionState};
use dreamwell_fabric::packets::ClientIntent;
pub struct LocalAuthority {
state: ConnectionState,
next_seq: u64,
pending_events: Vec<AuthorityEvent>,
}
impl LocalAuthority {
pub fn new() -> Self {
Self {
state: ConnectionState::Connected, next_seq: 0,
pending_events: Vec::new(),
}
}
}
impl Default for LocalAuthority {
fn default() -> Self {
Self::new()
}
}
impl AuthorityClient for LocalAuthority {
fn submit_intents(&mut self, intents: &[ClientIntent]) {
for _intent in intents {
self.pending_events.push(AuthorityEvent::Ack { seq: self.next_seq });
self.next_seq += 1;
}
}
fn poll_events(&mut self, out: &mut Vec<AuthorityEvent>) {
out.append(&mut self.pending_events);
}
fn request_snapshot(&mut self) {
self.pending_events.push(AuthorityEvent::SnapshotChunk {
chunk_id: 0,
total_chunks: 1,
data: Vec::new(),
});
}
fn connection_state(&self) -> ConnectionState {
self.state
}
}
#[cfg(test)]
mod tests {
use super::*;
use dreamwell_fabric::packets::IntentKind;
#[test]
fn local_authority_always_connected() {
let auth = LocalAuthority::new();
assert_eq!(auth.connection_state(), ConnectionState::Connected);
}
#[test]
fn submit_intents_produces_acks() {
let mut auth = LocalAuthority::new();
let intents = vec![
ClientIntent {
actor_id: 1,
tick_hint: 0,
action: IntentKind::Move { dx: 1, dy: 0 },
},
ClientIntent {
actor_id: 1,
tick_hint: 1,
action: IntentKind::Ability { slot: 2 },
},
];
auth.submit_intents(&intents);
let mut events = Vec::new();
auth.poll_events(&mut events);
assert_eq!(events.len(), 2);
assert!(matches!(events[0], AuthorityEvent::Ack { seq: 0 }));
assert!(matches!(events[1], AuthorityEvent::Ack { seq: 1 }));
}
#[test]
fn poll_events_drains() {
let mut auth = LocalAuthority::new();
auth.submit_intents(&[ClientIntent {
actor_id: 1,
tick_hint: 0,
action: IntentKind::UiCommand { id: 42 },
}]);
let mut first = Vec::new();
auth.poll_events(&mut first);
assert_eq!(first.len(), 1);
let mut second = Vec::new();
auth.poll_events(&mut second);
assert!(second.is_empty());
}
#[test]
fn request_snapshot_produces_chunk() {
let mut auth = LocalAuthority::new();
auth.request_snapshot();
let mut events = Vec::new();
auth.poll_events(&mut events);
assert_eq!(events.len(), 1);
assert!(matches!(
events[0],
AuthorityEvent::SnapshotChunk {
chunk_id: 0,
total_chunks: 1,
..
}
));
}
}