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
#![deny(missing_docs)]
#[cfg(feature = "plugin")]
pub mod parallax;
#[cfg(feature = "plugin")]
mod plugin;
#[cfg(feature = "plugin")]
mod scene;
pub mod tmx;
#[cfg(not(feature = "plugin"))]
mod loader {
use super::tmx::Map;
use anyhow::*;
use std::path::{Component, Path, PathBuf};
use std::sync::Arc;
#[derive(Clone)]
pub(crate) struct TmxLoadContext<'a> {
relative: Arc<Path>,
lifetime: &'a (),
}
impl<'a> TmxLoadContext<'a> {
pub async fn load_file<'p>(
&'p self,
path: impl AsRef<Path> + Send + 'p,
) -> Result<Vec<u8>> {
Ok(std::fs::read(self.file_path(path))?)
}
pub fn file_path(&self, path: impl AsRef<Path>) -> PathBuf {
let mut joined = PathBuf::new();
for c in self.relative.join(path.as_ref()).components() {
match c {
Component::Prefix(prefix) => joined.push(prefix.as_os_str()),
Component::RootDir => joined.push("/"),
Component::CurDir => (),
Component::ParentDir => {
joined.pop();
}
Component::Normal(c) => joined.push(c),
}
}
joined
}
pub fn file_directory(&self, path: impl AsRef<Path>) -> Self {
Self {
relative: if let Some(parent) = path.as_ref().parent() {
Arc::from(self.relative.join(parent))
} else {
self.relative.clone()
},
lifetime: self.lifetime,
}
}
}
pub async fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Map> {
let path = path.as_ref();
let context = ();
let context = if let Some(parent) = path.parent() {
TmxLoadContext {
relative: Arc::from(parent.to_path_buf()),
lifetime: &context,
}
} else {
TmxLoadContext {
relative: Path::new(".").to_path_buf().into(),
lifetime: &context,
}
};
let reader = xml::EventReader::new(std::fs::File::open(path)?);
Ok(Map::load_from_xml_reader(context, reader).await?)
}
}
#[cfg(not(feature = "plugin"))]
pub use loader::*;
#[cfg(feature = "plugin")]
pub use plugin::*;