use std::collections::HashMap;
use std::collections::{BTreeMap};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SyncMode {
LockStep,
Predictive,
Interpolation,
ServerAuthoritative,
}
impl Default for SyncMode {
fn default() -> Self {
Self::Interpolation
}
}
#[derive(Debug, Clone)]
pub struct AvatarConfig {
pub user_id: String,
pub avatar_model: String,
pub enable_expressions: bool,
pub enable_lip_sync: bool,
}
#[derive(Debug, Clone)]
pub struct UserAvatar {
config: AvatarConfig,
position: [f32; 3],
rotation: [f32; 4],
head_position: [f32; 3],
head_rotation: [f32; 4],
online: bool,
}
impl UserAvatar {
pub fn new(config: AvatarConfig) -> Self {
Self {
config,
position: [0.0, 0.0, 0.0],
rotation: [0.0, 0.0, 0.0, 1.0],
head_position: [0.0, 1.7, 0.0],
head_rotation: [0.0, 0.0, 0.0, 1.0],
online: true,
}
}
pub fn user_id(&self) -> &str {
&self.config.user_id
}
pub fn update_position(&mut self, position: [f32; 3], rotation: [f32; 4]) {
self.position = position;
self.rotation = rotation;
}
pub fn update_head(&mut self, position: [f32; 3], rotation: [f32; 4]) {
self.head_position = position;
self.head_rotation = rotation;
}
pub fn is_online(&self) -> bool {
self.online
}
pub fn set_online(&mut self, online: bool) {
self.online = online;
}
}
pub struct MultiuserRenderer {
sync_mode: SyncMode,
avatars: HashMap<String, UserAvatar>,
max_users: u32,
}
impl MultiuserRenderer {
pub fn new(sync_mode: SyncMode) -> Result<Self, MultiuserError> {
Ok(Self {
sync_mode,
avatars: HashMap::new(),
max_users: 1000,
})
}
pub fn add_avatar(&mut self, config: AvatarConfig) -> Result<(), MultiuserError> {
if self.avatars.len() >= self.max_users as usize {
return Err(MultiuserError::MaxUsersReached(self.max_users));
}
let user_id: _ = config.user_id.clone();
let avatar: _ = UserAvatar::new(config);
self.avatars.insert(user_id, avatar);
Ok(())
}
pub fn remove_avatar(&mut self, user_id: &str) -> Option<UserAvatar> {
self.avatars.remove(user_id)
}
pub fn get_avatar(&self, user_id: &str) -> Option<&UserAvatar> {
self.avatars.get(user_id)
}
pub fn get_avatar_mut(&mut self, user_id: &str) -> Option<&mut UserAvatar> {
self.avatars.get_mut(user_id)
}
pub fn user_count(&self) -> usize {
self.avatars.len()
}
pub fn sync_mode(&self) -> SyncMode {
self.sync_mode
}
pub fn broadcast_update(&self, user_id: &str) -> Result<(), MultiuserError> {
if !self.avatars.contains_key(user_id) {
return Err(MultiuserError::UserNotFound(user_id.to_string()));
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub enum MultiuserError {
InitializationFailed(String),
MaxUsersReached(u32),
UserNotFound(String),
SyncFailed(String),
}
impl std::fmt::Display for MultiuserError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::InitializationFailed(msg) => write!(f, "初始化失败: {}", msg),
Self::MaxUsersReached(max) => write!(f, "达到最大用户数: {}", max),
Self::UserNotFound(id) => write!(f, "用户未找到: {}", id),
Self::SyncFailed(msg) => write!(f, "同步失败: {}", msg),
}
}
}
impl std::error::Error for MultiuserError {}