use crate::components::context::Context;
use crate::thread_manager::{ThreadManager, MAIN_THREAD};
use dashmap::DashMap;
use std::sync::OnceLock;
pub(crate) struct ContextManager
{
data: DashMap<String, Vec<Context>>,
}
static SINGLETON: OnceLock<ContextManager> = OnceLock::new();
impl ContextManager
{
pub fn singleton() -> &'static Self
{
return SINGLETON.get_or_init(|| Self::new());
}
pub fn add(&self, context: Context) -> u64
{
let threadName = ThreadManager::local_getName().unwrap_or(MAIN_THREAD.to_string());
return match self.data.get_mut(&threadName)
{
None =>
{
self.data.insert(threadName, vec![context.clone()]);
0
}
Some(mut inner) =>
{
let size = inner.len();
inner.push(context.clone());
size as u64
}
};
}
pub fn remove(&self, contextId: u64)
{
let threadName = ThreadManager::local_getName().unwrap_or(MAIN_THREAD.to_string());
if let Some(mut inner) = self.data.get_mut(&threadName)
{
if(inner.iter().len()==1 && threadName==MAIN_THREAD)
{
return;
}
while (contextId < inner.iter().len() as u64)
{
inner.pop();
}
}
}
pub(crate) fn global_set(&self, context: Context)
{
let globalName = MAIN_THREAD.to_string();
self.data.insert(globalName,vec![context]);
}
pub(crate) fn global_get(&self) -> Option<Context>
{
let globalName = MAIN_THREAD.to_string();
match self.data.get(&globalName) {
None => None,
Some(contextArray) => contextArray.get(0).cloned()
}
}
pub fn resolve(&self) -> Context
{
let Some(threadName) = ThreadManager::local_getName()
else
{
return self.resolve_internal(MAIN_THREAD.to_string());
};
return self.resolve_internal(threadName);
}
fn new() -> Self
{
return ContextManager {
data: DashMap::new(),
};
}
fn resolve_internal(&self, threadName: String) -> Context
{
let mut resolvedContext = self.resolve_main();
let Some(contextArray) = self.data.get(&threadName)
else
{
return resolvedContext;
};
contextArray.iter().for_each(|oneContext| {
oneContext
.modules_get()
.iter()
.for_each(|(key, context)| {
match context
{
None => resolvedContext.module_discard(key),
Some(inner) => resolvedContext.module_add_arc(key, inner.clone()),
}
});
resolvedContext.level_setMin(oneContext.level_getMin().cloned());
if let Some(name) = oneContext.threadName_get()
{
resolvedContext.threadName_set(name);
}
if let Some(name) = oneContext.name_get()
{
resolvedContext.name_set(name);
}
resolvedContext.extra_merge(oneContext.extra_getAll());
});
return resolvedContext;
}
fn resolve_main(&self) -> Context
{
let defaultContext = || {
let mut context = Context::default();
context.threadName_set(MAIN_THREAD);
return context;
};
let Some(contextArray) = self.data.get(&MAIN_THREAD.to_string())
else
{
return defaultContext();
};
let Some(context) = contextArray.get(0)
else
{
return defaultContext();
};
return context.clone();
}
}