1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::astar::AStar;
use crate::errors::my_errors::{MyError, RetResult};
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use chrono::Utc;

use crate::map::map::Map;
use crate::map::map::MapType;
use crate::map::IndexType;

pub struct MapManager {
    map_collections: HashMap<i64, MapType>,
}

impl MapManager {
    pub fn get_instance() -> Arc<RwLock<MapManager>> {
        Arc::clone(&MAP_MANAGER)
    }

    fn new() -> Arc<RwLock<MapManager>> {
        Arc::new(RwLock::new(MapManager {
            map_collections: HashMap::new(),
        }))
    }
    pub async fn new_astar(&mut self) -> i64 {
        let map_id = Utc::now().timestamp_millis();
        self.map_collections.insert(map_id, AStar::new());
        map_id
    }
    
    pub async fn remove_map(&mut self, map_id: &i64) {
        self.map_collections.remove(map_id);
    }

    pub fn load(&self, map_id: &i64, points: Vec<Vec<i32>>) -> RetResult<()> {
        let res = self.map_collections.get(map_id);
        match res {
            None => Err(MyError::MapNotExist(map_id.clone()).into()),
            Some(m) => m.clone().write().map_or_else(
                |e| Err(MyError::UnknownErr(e.to_string()).into()),
                |mut v| v.load(points),
            ),
        }
    }

    pub async fn load_from_file(&self, map_id: &i64, file: String) -> RetResult<()> {
        if let Some(m) = self.map_collections.get(&map_id) {
            return match m.clone().write() {
                Ok(mut x) => Ok(x.load_from_file(file).await?),
                Err(e) => Err(MyError::UnknownErr(e.to_string()).into()),
            };
        }

        Err(MyError::MapNotExist(map_id.clone()).into())
    }

    pub async fn load_from_string(&self, map_id: &i64, file: String) -> RetResult<()> {
        if let Some(m) = self.map_collections.get(&map_id) {
            return match m.clone().write() {
                Ok(mut x) => Ok(x.load_from_string(file).await?),
                Err(e) => Err(MyError::UnknownErr(e.to_string()).into()),
            };
        }

        Err(MyError::MapNotExist(map_id.clone()).into())
    }

    pub fn set_walkable(
        &self,
        map_id: &i64,
        point: (IndexType, IndexType),
        walkable: i32,
    ) -> RetResult<()> {
        let res = self.map_collections.get(map_id);
        match res {
            None => Err(MyError::MapNotExist(map_id.clone()).into()),
            Some(m) => match m.clone().write() {
                Ok(mut v) => Ok(v.set_walkable(point, walkable)),
                Err(e) => Err(MyError::UnknownErr(e.to_string()).into()),
            },
        }
    }

    pub fn find_path(
        &self,
        map_id: &i64,
        start: (IndexType, IndexType),
        end: (IndexType, IndexType),
    ) -> RetResult<Vec<(IndexType, IndexType)>> {
        let res = self.map_collections.get(map_id);
        match res {
            None => Err(MyError::MapNotExist(map_id.clone()).into()),
            Some(m) => match m.clone().read() {
                Ok(v) => Ok(v.find_path(start, end)),
                Err(e) => Err(MyError::UnknownErr(e.to_string()).into()),
            },
        }
    }
}

lazy_static! {
    static ref MAP_MANAGER: Arc<RwLock<MapManager>> = MapManager::new();

    //异步方式的生成单例,因为有些生成单例的代码,是await的,所以整体就需要await。 比如mongodb的client
    /*
    pub static ref MONGODB_CLIENT: AsyncOnce<mongodb::Database> = AsyncOnce::new( async {
        let config = &GLOBAL_CONFIG;
        let client_options = ClientOptions::parse(&config.mongodb.url).await.unwrap();
        let client = Client::with_options(client_options).unwrap();
        client.database(&config.mongodb.db)
    });
    */
}