use tokio::sync::broadcast;
use crate::bot::Bot;
use crate::bot::components::position::Position;
use crate::bot::components::rotation::Rotation;
use crate::bot::options::BotStatus;
use crate::bot::world::StorageLock;
pub trait BotPackage: Clone + Send + 'static {
fn describe<P: BotPackage>(bot: &Bot<P>) -> Self;
}
#[derive(Clone)]
pub struct BotTransmitter<B: BotPackage> {
sender: broadcast::Sender<B>,
}
impl<B: BotPackage> BotTransmitter<B> {
pub fn new(capacity: usize) -> Self {
let (sender, _) = broadcast::channel(capacity);
Self { sender: sender }
}
pub fn subscribe(&self) -> broadcast::Receiver<B> {
self.sender.subscribe()
}
pub fn emit(&self, package: B) {
let _ = self.sender.send(package);
}
pub fn receiver_count(&self) -> usize {
self.sender.receiver_count()
}
}
#[derive(Clone)]
pub struct NullPackage;
impl BotPackage for NullPackage {
fn describe<B: BotPackage>(_bot: &Bot<B>) -> Self {
Self
}
}
#[derive(Clone, Debug)]
pub struct MinimalPackage {
pub position: Position,
pub rotation: Rotation,
}
impl BotPackage for MinimalPackage {
fn describe<B: BotPackage>(bot: &Bot<B>) -> Self {
Self {
position: bot.components.position.clone(),
rotation: bot.components.rotation.clone(),
}
}
}
#[derive(Clone, Debug)]
pub struct StandardPackage {
pub status: BotStatus,
pub position: Position,
pub rotation: Rotation,
pub health: f32,
pub satiety: u32,
}
impl BotPackage for StandardPackage {
fn describe<B: BotPackage>(bot: &Bot<B>) -> Self {
Self {
status: bot.status.clone(),
position: bot.components.position.clone(),
rotation: bot.components.rotation.clone(),
health: bot.components.state.health,
satiety: bot.components.state.satiety,
}
}
}
#[derive(Clone, Debug)]
pub struct FullPackage {
pub status: BotStatus,
pub position: Position,
pub rotation: Rotation,
pub health: f32,
pub satiety: u32,
pub local_storage: StorageLock,
pub shared_storage: Option<StorageLock>,
}
impl BotPackage for FullPackage {
fn describe<B: BotPackage>(bot: &Bot<B>) -> Self {
Self {
status: bot.status.clone(),
position: bot.components.position.clone(),
rotation: bot.components.rotation.clone(),
health: bot.components.state.health,
satiety: bot.components.state.satiety,
local_storage: bot.local_storage.clone(),
shared_storage: bot.shared_storage.clone(),
}
}
}