Newer
Older
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
use anyhow::Error;
use bevy::asset::{AssetEvent, AssetLoader, Assets, BoxedFuture, LoadContext, LoadedAsset};
use bevy::prelude::{EventReader, EventWriter, Res, ResMut, Resource};
use ldtk_rust::Project;
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
pub struct LdtkProject(pub Project);
impl Deref for LdtkProject {
type Target = Project;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for LdtkProject {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl LdtkProject {}
#[derive(Default)]
pub struct LdtkLoader;
impl AssetLoader for LdtkLoader {
fn load<'a>(
&'a self,
bytes: &'a [u8],
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, anyhow::Result<(), Error>> {
Box::pin(async move {
let mut ldtk: Project = serde_json::from_slice(bytes)?;
if ldtk.external_levels {
ldtk.load_external_levels(load_context.path());
}
load_context.set_default_asset(LoadedAsset::new(LdtkProject(ldtk)));
Ok(())
})
}
fn extensions(&self) -> &[&str] {
&["ldtk"]
}
}
#[derive(Resource, Default)]
pub struct LevelIndex(pub HashMap<String, LdtkLevel>);
type Target = HashMap<String, LdtkLevel>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for LevelIndex {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[derive(Default)]
pub struct TileMetadata(pub HashMap<i64, Value>);
#[derive(Resource, Default)]
pub struct TilesetIndex(pub HashMap<String, TileMetadata>);
impl Deref for TilesetIndex {
type Target = HashMap<String, TileMetadata>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for TilesetIndex {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub fn handle_ldtk_project_events(
mut events: EventReader<AssetEvent<LdtkProject>>,
assets: Res<Assets<LdtkProject>>,
mut level_index: ResMut<LevelIndex>,
mut tilset_index: ResMut<TilesetIndex>,
mut update_events: EventWriter<LevelDataUpdated>,
) {
for event in events.iter() {
match event {
AssetEvent::Created { handle } | AssetEvent::Modified { handle } => {
if let Some(LdtkProject(project)) = assets.get(handle) {
for level in &project.levels {
level_index.insert(
level.identifier.clone(),
LdtkLevel::from(level.serde_clone()),
);
update_events.send(LevelDataUpdated(level.identifier.clone()));
}
for tileset in &project.defs.tilesets {
let mut tile_meta = HashMap::new();
for custom in &tileset.custom_data {
tile_meta.insert(
custom.tile_id,
serde_json::from_str(&custom.data).unwrap(),