/// Internal namespace. pub( crate ) mod private { use crate::*; use crate::abs::*; use once_cell::sync::Lazy; use std::sync::Mutex; use dashmap::DashMap; use std::sync::Arc; /// Registry of contexts. #[ derive( Debug ) ] pub struct Registry< Context > where Context : ContextInterface, { contexts : DashMap< Id, Context >, contexts_with_name : DashMap< String, Id >, current_context_name : Option< String >, } impl< Context > Registry< Context > where Context : ContextInterface, { /// Static constructor. pub const fn new() -> Lazy< Arc< Mutex< Registry< Context > > > > { Lazy::new( || { let contexts = DashMap::new(); let contexts_with_name = DashMap::new(); let current_context_name = None; Arc::new( Mutex::new( Registry::< Context > { contexts, contexts_with_name, current_context_name, })) }) } // /// Get current context or crate a new one if it does not exist. // pub fn current( _registry : &mut Lazy< Arc< Mutex< Registry< Context > > > > ) -> Context::Changer // { // // unsafe // // { // let registry = _registry.lock().unwrap(); // let current_name : Option< String > = registry.current_context_name.clone(); // /* xxx : redo */ // if current_name.is_none() // { // drop( registry ); // Self::obtain( _registry ) // } // else // { // let id = *registry.contexts_with_name.get( ¤t_name.unwrap() ).unwrap().value(); // // registry.contexts.get_mut( &id ).unwrap().value_mut(); // registry.contexts.get_mut( &id ).unwrap().value_mut().changer() // } // // } // } /// Construct a new context. pub fn current( _registry : &mut Lazy< Arc< Mutex< Registry< Context > > > > ) -> Context::Changer { // unsafe // { let registry = _registry.lock().unwrap(); let mut current_name : Option< String > = registry.current_context_name.clone(); if current_name.is_none() { current_name = Some( "default".into() ) } let current_name = current_name.unwrap(); if registry.contexts_with_name.contains_key( ¤t_name ) { let id = *registry.contexts_with_name.get( ¤t_name ).unwrap().value(); registry.contexts.get_mut( &id ).unwrap().value_mut().changer() } else { let context : Context = make!(); let id = context.id(); registry.contexts_with_name.insert( current_name.clone(), context.id() ); registry.contexts.insert( id, context ); registry.contexts.get_mut( &id ).unwrap().value_mut().changer() } // } } } // static mut REGISTRY : Lazy< Arc< Mutex< Registry > > > = Lazy::new( || // { // let contexts = DashMap::new(); // let contexts_with_name = DashMap::new(); // let current_context_name = None; // Arc::new( Mutex::new( Registry // { // contexts, // contexts_with_name, // current_context_name, // })) // }); // // /// Get current context or crate a new one if it does not exist. // pub fn current< Context : ContextInterface >() -> ContextChanger // { // unsafe // { // let registry = REGISTRY.lock().unwrap(); // let current_name : Option< String > = registry.current_context_name.clone(); // /* xxx : redo */ // if current_name.is_none() // { // drop( registry ); // obtain::< Context >() // } // else // { // let id = *registry.contexts_with_name.get( ¤t_name.unwrap() ).unwrap().value(); // registry.contexts.get( &id ).unwrap().value().changer() // } // } // } // // /// Construct a new context. // pub fn obtain< Context : ContextInterface >() -> ContextChanger // { // unsafe // { // let registry = REGISTRY.lock().unwrap(); // let mut current_name : Option< String > = registry.current_context_name.clone(); // if current_name.is_none() // { // current_name = Some( "default".into() ) // } // let current_name = current_name.unwrap(); // if registry.contexts_with_name.contains_key( ¤t_name ) // { // let id = *registry.contexts_with_name.get( ¤t_name ).unwrap().value(); // registry.contexts.get( &id ).unwrap().value().changer() // } // else // { // let context : Context = make!(); // let id = context.id(); // registry.contexts_with_name.insert( current_name.clone(), context.id() ); // registry.contexts.insert( id, context ); // registry.contexts.get( &id ).unwrap().value().changer() // } // } // } } /// Protected namespace of the module. pub mod protected { pub use super:: { orphan::*, // private::current, // private::obtain, // private:: Registry, }; } pub use protected::*; /// Parented namespace of the module. pub mod orphan { pub use super:: { exposed::*, private:: Registry, }; } /// Exposed namespace of the module. pub mod exposed { pub use super:: { prelude::*, // private::current as context, }; } pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. pub mod prelude { pub use super::private:: { }; }