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 { mutex: CustomRwLock, data: UnsafeCell>, } unsafe impl Sync for SynchronizedServersStorage {} impl SynchronizedServersStorage { 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 { return _Impl { data: self }; } pub fn new_gui_ctx(&self) -> impl ServersGuiCtx
{ return _Impl { data: self }; } } struct _Impl<'o, A: Address + Hash + Eq> { data: &'o SynchronizedServersStorage, } impl _Impl<'_, A> { unsafe fn get_unprotected(&self) -> &mut ServersStorage { return NonNull::new_unchecked(self.data.data.get()).as_mut(); } } impl ServersNetworkCtx for _Impl<'_, A> { fn start_measuring(&mut self) -> (u64, impl Iterator) { 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 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>)> { 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(); } }