106 lines
3.3 KiB
Rust
106 lines
3.3 KiB
Rust
use crate::ServersStorage;
|
|
use crate::synchronized::iterator::SyncedIterator;
|
|
use bgtu_networks_2_gui_abstract::ServersStorage as ServersGuiCtx;
|
|
use bgtu_networks_2_network_abstract::{Address, ServersContext as ServersNetworkCtx};
|
|
use std::cell::UnsafeCell;
|
|
use std::hash::Hash;
|
|
use std::ptr::NonNull;
|
|
mod iterator;
|
|
|
|
mod rw_lock;
|
|
use rw_lock::CustomRwLock;
|
|
|
|
pub struct SynchronizedServersStorage<A: Address + Hash + Eq> {
|
|
mutex: CustomRwLock,
|
|
data: UnsafeCell<ServersStorage<A>>,
|
|
}
|
|
|
|
unsafe impl<A: Address + Hash + Eq> Sync for SynchronizedServersStorage<A> {}
|
|
|
|
impl<A: Address + Hash + Eq> SynchronizedServersStorage<A> {
|
|
pub fn new(history_capacity: usize) -> Self {
|
|
return Self {
|
|
mutex: CustomRwLock::new(),
|
|
data: UnsafeCell::new(ServersStorage::new(history_capacity)),
|
|
};
|
|
}
|
|
|
|
pub fn new_network_ctx(&self) -> impl ServersNetworkCtx<A> {
|
|
return _Impl { data: self };
|
|
}
|
|
|
|
pub fn new_gui_ctx(&self) -> impl ServersGuiCtx<Address = A> {
|
|
return _Impl { data: self };
|
|
}
|
|
}
|
|
|
|
struct _Impl<'o, A: Address + Hash + Eq> {
|
|
data: &'o SynchronizedServersStorage<A>,
|
|
}
|
|
|
|
impl<A: Address + Hash + Eq> _Impl<'_, A> {
|
|
unsafe fn get_unprotected(&self) -> &mut ServersStorage<A> {
|
|
return NonNull::new_unchecked(self.data.data.get()).as_mut();
|
|
}
|
|
}
|
|
|
|
impl<A: Address + Hash + Eq> ServersNetworkCtx<A> for _Impl<'_, A> {
|
|
fn start_measuring(&mut self) -> (u64, impl Iterator<Item = A>) {
|
|
let w_lock_scope = self.data.mutex.write();
|
|
let data = unsafe { self.get_unprotected() }.start_measuring();
|
|
let r_lock_scope = w_lock_scope.write_to_read();
|
|
return (data.0, SyncedIterator::wrap(data.1, r_lock_scope));
|
|
}
|
|
|
|
fn report_ping(&mut self, addr: A, id: u64, ping_ms: u128) {
|
|
let lock_scope = self.data.mutex.read();
|
|
unsafe { self.get_unprotected() }.report_ping(addr, id, ping_ms);
|
|
}
|
|
|
|
fn report_error(&mut self, addr: A, id: u64) {
|
|
let lock_scope = self.data.mutex.read();
|
|
unsafe { self.get_unprotected() }.report_error(addr, id);
|
|
}
|
|
|
|
fn is_running(&self) -> bool {
|
|
return unsafe { self.get_unprotected() }.is_running();
|
|
}
|
|
}
|
|
|
|
impl<A: Address + Hash + Eq> ServersGuiCtx for _Impl<'_, A> {
|
|
type Address = A;
|
|
|
|
fn add_server(&mut self, addr: Self::Address, memo: String) {
|
|
let w_lock_scope = self.data.mutex.write();
|
|
unsafe { self.get_unprotected() }.add_server(addr, memo);
|
|
}
|
|
|
|
fn remove_server(&mut self, addr: &Self::Address) {
|
|
let w_lock_scope = self.data.mutex.write();
|
|
unsafe { self.get_unprotected() }.remove_server(addr);
|
|
}
|
|
|
|
fn edit_memo(&mut self, addr: &Self::Address, new_memo: String) {
|
|
let r_lock_scope = self.data.mutex.read();
|
|
unsafe { self.get_unprotected() }.edit_memo(addr, new_memo);
|
|
}
|
|
|
|
fn iter_servers(
|
|
&self,
|
|
) -> impl Iterator<Item = (&Self::Address, &str, impl Iterator<Item = Option<u128>>)> {
|
|
let r_lock_scope = self.data.mutex.read();
|
|
return SyncedIterator::wrap(
|
|
unsafe { self.get_unprotected() }.iter_servers(),
|
|
r_lock_scope,
|
|
);
|
|
}
|
|
|
|
fn graph_sections_count(&self) -> usize {
|
|
return unsafe { self.get_unprotected() }.graph_sections_count();
|
|
}
|
|
|
|
fn terminate(&mut self) {
|
|
unsafe { self.get_unprotected() }.terminate();
|
|
}
|
|
}
|