misty_vm/
services.rs

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}