game_pathfinding 0.1.3

一个寻路库,包含AStar和Recast,目前还在开发阶段
Documentation
use crate::astar::AStar;
use crate::errors::my_errors::{MyError, RetResult};
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::sync::{Arc};
use tokio::sync::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 async 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().await.load(points),/*.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 Ok(m.clone().write().await.load_from_file(file).await?)
            /*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 Ok(m.clone().write().await.load_from_string(file).await?)
            /*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 async 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) => Ok(m.clone().write().await.set_walkable(point, walkable)),
            /*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 async 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) => Ok(m.clone().read().await.find_path(start, end)),
            /*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)
    });
    */
}