networks-2.rs/data/src/synchronized/mod.rs

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();
}
}