|
|
@ -3,7 +3,7 @@ |
|
|
|
|
|
|
|
|
use parking_lot::Mutex;
|
|
|
use parking_lot::Mutex;
|
|
|
use solstice_proto::ServerRequest;
|
|
|
use solstice_proto::ServerRequest;
|
|
|
use tokio::sync::mpsc::Sender;
|
|
|
|
|
|
|
|
|
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
|
|
|
|
|
|
|
|
use crate::room::RoomMap;
|
|
|
use crate::room::RoomMap;
|
|
|
use crate::user::UserMap;
|
|
|
use crate::user::UserMap;
|
|
|
@ -18,13 +18,66 @@ pub struct State { |
|
|
/// Holds process-wide context for message handlers to execute against.
|
|
|
/// Holds process-wide context for message handlers to execute against.
|
|
|
#[derive(Debug)]
|
|
|
#[derive(Debug)]
|
|
|
pub struct Context {
|
|
|
pub struct Context {
|
|
|
|
|
|
/// Mutable state.
|
|
|
pub state: Mutex<State>,
|
|
|
pub state: Mutex<State>,
|
|
|
|
|
|
|
|
|
|
|
|
/// Sender half of a channel used to send requests to the server.
|
|
|
pub server_request_tx: Sender<ServerRequest>,
|
|
|
pub server_request_tx: Sender<ServerRequest>,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Convenience bundle for creating new `Context` structs.
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
|
pub struct ContextBundle {
|
|
|
|
|
|
/// The context itself.
|
|
|
|
|
|
pub context: Context,
|
|
|
|
|
|
|
|
|
|
|
|
/// The receiver corresponding to `context.server_request_tx`.
|
|
|
|
|
|
pub server_request_rx: Receiver<ServerRequest>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Specifies options for new `ContextBundle` structs.
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
|
pub struct ContextOptions {
|
|
|
|
|
|
/// The state to start out with.
|
|
|
|
|
|
pub initial_state: State,
|
|
|
|
|
|
|
|
|
|
|
|
/// The buffer size of the server request channel.
|
|
|
|
|
|
pub server_request_buffer: usize,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Default for ContextOptions {
|
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
|
Self {
|
|
|
|
|
|
server_request_buffer: 100,
|
|
|
|
|
|
initial_state: State::default(),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl ContextBundle {
|
|
|
|
|
|
/// Builds a new context bundle as configured by `options`.
|
|
|
|
|
|
fn new(options: ContextOptions) -> Self {
|
|
|
|
|
|
let (server_request_tx, server_request_rx) =
|
|
|
|
|
|
channel(options.server_request_buffer);
|
|
|
|
|
|
Self {
|
|
|
|
|
|
context: Context {
|
|
|
|
|
|
state: Mutex::new(options.initial_state),
|
|
|
|
|
|
server_request_tx,
|
|
|
|
|
|
},
|
|
|
|
|
|
server_request_rx,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Default for ContextBundle {
|
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
|
Self::new(ContextOptions::default())
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
#[cfg(test)]
|
|
|
mod tests {
|
|
|
mod tests {
|
|
|
use super::{Context, State};
|
|
|
|
|
|
|
|
|
use super::{Context, ContextBundle, State};
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
#[test]
|
|
|
fn default_state_is_empty() {
|
|
|
fn default_state_is_empty() {
|
|
|
@ -40,4 +93,12 @@ mod tests { |
|
|
let _sync: &dyn Sync = &context;
|
|
|
let _sync: &dyn Sync = &context;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
fn default_bundle_state_is_empty() {
|
|
|
|
|
|
let bundle = ContextBundle::default();
|
|
|
|
|
|
let guard = bundle.context.state.lock();
|
|
|
|
|
|
assert_eq!(guard.rooms.get_room_list(), vec![]);
|
|
|
|
|
|
assert_eq!(guard.users.get_list(), vec![]);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|