1use std::{
2 any::{Any, TypeId},
3 collections::HashMap,
4 fmt::Debug,
5 sync::Arc,
6};
7
8use crate::{async_task::MistyAsyncTaskContext, client::AsReadonlyMistyClientHandle};
9
10pub trait MistyServiceTrait: Any + Send + Sync + Sized + 'static {
11 fn of<'a>(cx: impl AsReadonlyMistyClientHandle<'a>) -> Arc<Self> {
12 let services = &cx.readonly_handle().inner.service_manager;
13 let service = services.services.get(&TypeId::of::<Self>());
14 if service.is_none() {
15 panic!(
16 "service {} is not registered",
17 std::any::type_name::<Self>()
18 );
19 }
20 let service = service.unwrap().clone();
21 let service = service.downcast::<Self>().unwrap();
22 service
23 }
24
25 fn of_async<'a>(cx: &MistyAsyncTaskContext) -> Arc<Self> {
26 let handle = cx.handle();
27 let handle = handle.handle();
28 Self::of(handle)
29 }
30}
31
32pub struct MistyServiceManagerBuilder {
33 services: HashMap<TypeId, Arc<dyn Any + Send + Sync + 'static>>,
34}
35
36#[derive(Debug)]
37pub struct MistyServiceManager {
38 services: HashMap<TypeId, Arc<dyn Any + Send + Sync + 'static>>,
39}
40
41pub enum ServiceImplPtr<T: ?Sized> {
42 Boxed(Box<T>),
43 Arc(Arc<T>),
44}
45
46impl MistyServiceManagerBuilder {
47 pub fn new() -> Self {
48 MistyServiceManagerBuilder {
49 services: Default::default(),
50 }
51 }
52
53 pub fn add<C>(mut self, service: C) -> Self
54 where
55 C: MistyServiceTrait,
56 {
57 let service = Arc::new(service);
58 self.services.insert(TypeId::of::<C>(), service);
59 self
60 }
61
62 pub fn build(self) -> MistyServiceManager {
63 MistyServiceManager {
64 services: self.services,
65 }
66 }
67}
68
69impl MistyServiceManager {
70 pub fn builder() -> MistyServiceManagerBuilder {
71 MistyServiceManagerBuilder::new()
72 }
73}