use std::sync::{atomic::AtomicU32, Arc};
use async_channel::{Receiver, Sender};
use async_trait::async_trait;
use bevy::prelude::Resource;
use dashmap::DashMap;
use futures_lite::Stream;
use crate::{
error::NetworkError, runtime::JoinHandle, AsyncChannel, Connection, ConnectionId, NetworkPacket,
};
pub mod network;
pub mod network_request;
#[derive(Resource)]
pub struct Network<NP: NetworkProvider> {
recv_message_map: Arc<DashMap<&'static str, Vec<(ConnectionId, Vec<u8>)>>>,
established_connections: Arc<DashMap<ConnectionId, Connection>>,
new_connections: AsyncChannel<NP::Socket>,
disconnected_connections: AsyncChannel<ConnectionId>,
error_channel: AsyncChannel<NetworkError>,
server_handle: Option<Box<dyn JoinHandle>>,
connection_tasks: Arc<DashMap<u32, Box<dyn JoinHandle>>>,
connection_task_counts: AtomicU32,
connection_count: u32,
}
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
pub trait NetworkProvider: 'static + Send + Sync {
type NetworkSettings: Resource + Clone;
type Socket: Send;
type ReadHalf: Send;
type WriteHalf: Send;
type ConnectInfo: Send;
type AcceptInfo: Send;
type AcceptStream: Stream<Item = Self::Socket> + Unpin + Send;
async fn accept_loop(
accept_info: Self::AcceptInfo,
network_settings: Self::NetworkSettings,
) -> Result<Self::AcceptStream, NetworkError>;
async fn connect_task(
connect_info: Self::ConnectInfo,
network_settings: Self::NetworkSettings,
) -> Result<Self::Socket, NetworkError>;
async fn recv_loop(
read_half: Self::ReadHalf,
messages: Sender<NetworkPacket>,
settings: Self::NetworkSettings,
);
async fn send_loop(
write_half: Self::WriteHalf,
messages: Receiver<NetworkPacket>,
settings: Self::NetworkSettings,
);
fn split(combined: Self::Socket) -> (Self::ReadHalf, Self::WriteHalf);
}