forked from lavina/lavina
reorder modules a bit
This commit is contained in:
parent
b7995584f0
commit
f9a6d8bdfc
|
@ -0,0 +1,3 @@
|
|||
//! Domain definitions and implementation of common chat logic.
|
||||
pub mod player;
|
||||
pub mod room;
|
|
@ -1,3 +1,12 @@
|
|||
//! Domain of chat participants.
|
||||
//!
|
||||
//! Player is a single user account, which is used to participate in chats,
|
||||
//! including sending messages, receiving messaged, retrieving history and running privileged actions.
|
||||
//! A player corresponds to a single user account. Usually a person has only one account,
|
||||
//! but it is possible to have multiple accounts for one person and therefore multiple player entities.
|
||||
//!
|
||||
//! A player actor is a serial handler of commands from a single player. It is preferable to run all per-player validations in the player actor,
|
||||
//! so that they don't overload the room actor.
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, RwLock},
|
||||
|
@ -9,14 +18,15 @@ use tokio::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
room::{RoomId, RoomRegistry},
|
||||
table::AnonTable,
|
||||
core::room::{RoomId, RoomRegistry},
|
||||
util::table::AnonTable,
|
||||
};
|
||||
|
||||
/// Opaque player id
|
||||
/// Opaque player identifier.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct PlayerId(u64);
|
||||
|
||||
/// Handle to a player actor.
|
||||
#[derive(Clone)]
|
||||
pub struct PlayerHandle {
|
||||
tx: Sender<PlayerCommand>,
|
||||
|
@ -58,6 +68,7 @@ impl PlayerHandle {
|
|||
}
|
||||
}
|
||||
|
||||
/// Player update event type which is sent to a connection handler.
|
||||
pub enum Updates {
|
||||
RoomJoined { room_id: RoomId },
|
||||
NewMessage { room_id: RoomId, body: String },
|
||||
|
@ -81,6 +92,7 @@ enum PlayerCommand {
|
|||
},
|
||||
}
|
||||
|
||||
/// Handle to a player registry — a shared data structure containing information about players.
|
||||
#[derive(Clone)]
|
||||
pub struct PlayerRegistry(Arc<RwLock<PlayerRegistryInner>>);
|
||||
impl PlayerRegistry {
|
||||
|
@ -106,12 +118,14 @@ impl PlayerRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
/// The player registry state representation.
|
||||
struct PlayerRegistryInner {
|
||||
next_id: PlayerId,
|
||||
room_registry: RoomRegistry,
|
||||
players: HashMap<PlayerId, (PlayerHandle, JoinHandle<Player>)>,
|
||||
}
|
||||
|
||||
/// Player actor inner state representation.
|
||||
struct Player {
|
||||
sockets: AnonTable<Sender<Updates>>,
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//! Domain of rooms — chats with multiple participants.
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
hash::Hash,
|
||||
|
@ -7,7 +8,7 @@ use std::{
|
|||
use tokio::sync::mpsc::{channel, Sender};
|
||||
|
||||
use crate::{
|
||||
player::{PlayerHandle, PlayerId},
|
||||
core::player::{PlayerHandle, PlayerId},
|
||||
prelude::*,
|
||||
};
|
||||
|
11
src/http.rs
11
src/http.rs
|
@ -1,6 +1,7 @@
|
|||
use crate::player::PlayerRegistry;
|
||||
use crate::core::player::PlayerRegistry;
|
||||
use crate::core::room::*;
|
||||
use crate::prelude::*;
|
||||
use crate::room::*;
|
||||
use crate::projections::trivial::handle_request;
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
|
@ -14,8 +15,6 @@ use tokio::net::TcpListener;
|
|||
use tokio::sync::oneshot::Sender;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
mod ws;
|
||||
|
||||
type BoxBody = http_body_util::combinators::BoxBody<Bytes, Infallible>;
|
||||
|
||||
async fn hello(
|
||||
|
@ -48,9 +47,7 @@ async fn route(
|
|||
) -> std::result::Result<Response<BoxBody>, Infallible> {
|
||||
match (request.method(), request.uri().path()) {
|
||||
(&Method::GET, "/hello") => Ok(hello(request).await?.map(BodyExt::boxed)),
|
||||
(&Method::GET, "/socket") => Ok(ws::handle_request(request, chats)
|
||||
.await?
|
||||
.map(BodyExt::boxed)),
|
||||
(&Method::GET, "/socket") => Ok(handle_request(request, chats).await?.map(BodyExt::boxed)),
|
||||
(&Method::GET, "/metrics") => Ok(metrics(registry)?.map(BodyExt::boxed)),
|
||||
_ => Ok(not_found()?.map(BodyExt::boxed)),
|
||||
}
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -1,13 +1,13 @@
|
|||
mod core;
|
||||
mod http;
|
||||
mod player;
|
||||
mod prelude;
|
||||
mod room;
|
||||
mod table;
|
||||
mod projections;
|
||||
mod tcp;
|
||||
mod util;
|
||||
|
||||
use crate::player::PlayerRegistry;
|
||||
use crate::core::player::PlayerRegistry;
|
||||
use crate::core::room::RoomRegistry;
|
||||
use crate::prelude::*;
|
||||
use crate::room::*;
|
||||
use prometheus::{IntCounter, Opts, Registry};
|
||||
use tcp::ClientSocketActor;
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
//! Protocol projections — implementations of public APIs.
|
||||
pub mod trivial;
|
|
@ -1,3 +1,4 @@
|
|||
//! Projection into a primitive WebSocket-based protocol for testing.
|
||||
use http_body_util::Empty;
|
||||
use hyper::body::Incoming;
|
||||
use hyper::header::{
|
||||
|
@ -18,8 +19,8 @@ use tokio_tungstenite::WebSocketStream;
|
|||
use futures_util::sink::SinkExt;
|
||||
use futures_util::stream::StreamExt;
|
||||
|
||||
use crate::player::{PlayerRegistry, Updates};
|
||||
use crate::room::RoomId;
|
||||
use crate::core::player::{PlayerRegistry, Updates};
|
||||
use crate::core::room::RoomId;
|
||||
|
||||
enum WsCommand {
|
||||
CreateRoom,
|
|
@ -0,0 +1 @@
|
|||
pub mod table;
|
|
@ -1,7 +1,9 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
||||
pub struct Key(u32);
|
||||
|
||||
/// Hash map with auto-generated surrogate key.
|
||||
pub struct AnonTable<V> {
|
||||
next: u32,
|
||||
inner: HashMap<u32, V>,
|
||||
|
@ -15,10 +17,12 @@ impl<V> AnonTable<V> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, value: V) -> Option<V> {
|
||||
/// Generate a free key and insert a table under that key.
|
||||
pub fn insert(&mut self, value: V) -> Key {
|
||||
let id = self.next;
|
||||
self.next += 1;
|
||||
self.inner.insert(id, value)
|
||||
self.inner.insert(id, value); // should be always empty
|
||||
Key(id)
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, key: Key) -> Option<&mut V> {
|
Loading…
Reference in New Issue