-
Alejandro Perea authored
* Partial commit * Partial commit * Partial commit * Some suggested changes and fixed tests (except infinite) * Replaced `tile` member in `LayerTileRef` with a function to get an `Option<&Tile>`. * Replaced `Map::get_tile_by_gid` with `Map::get_tileset_for_gid`, which just returns the `Option<&Tileset>`. It also does a reverse search, which fixes the lookup in case an external tileset has grown since the map was last saved. * Replaced `Tileset::get_tile_by_gid` with `Tileset::get_tile`, since subtracting of the `first_gid` already happens when creating the `LayerTileRef`. Also, we eventually should remove `first_gid` from `Tileset`, since it should be possible to share a single tileset instance betweeen several maps. * Pre-allocate the tiles hash map for the expected number of tiles and use `or_default` instead of `or_insert_with(Default::default)`. * [nonbuilding] Move ownership of tilesets - Moves the ownership of tilesets from Map to an object implementing `TilesetCache` * Clean up * More cleanup * Organize layers into modules * Further modularization * Add layer wrappers * Implement `Clone + PartialEq + Debug` for wrappers * Fix example * Fix all tests except for test_infinite_tileset * Move layer utils to its own module * Better `Map::layers` documentation * `TilesetCache` -> `cache::ResourceCache` * Add `ResourcePath`, rename and add errors * Interface changes - Move embedded tilesets from cache to map - Store `Option<LayerTileData>` instead of `LayerTileData` * parser ->`&mut impl Iterator<Item=XmlEventResult>` * Document that tilesets are ordered by first GID * Fix the layer tiles using GIDs issue * Run `cargo fix` * Fix `test_infinite_tileset` tests * Implement a way to access object tile data * Rename `TiledWrapper` to `MapWrapper` * More efficient `get_or_try_insert_tileset_with` * Add `ResourcePathBuf`, use `Rc<Tileset>` in `Map` * Remove `MapTileset::first_gid` * Run `cargo fix` * Remove unrelated `Tileset` changes * Requested changes * Avoid reference counting when accessing tiles * Store tile data instead of (u32, u32)` in objects * Remove unneeded functions from `ResourceCache` * Address PR comments * Misc improvements in `layers::tile` * Improve example * Convert `LayerTile` properties to fields Co-authored-by:
Thorbjørn Lindeijer <bjorn@lindeijer.nl>
Unverifieddf98e9f3
cache.rs 1.38 KiB
use std::{
collections::HashMap,
path::{Path, PathBuf},
rc::Rc,
};
use crate::Tileset;
pub type ResourcePath = Path;
pub type ResourcePathBuf = PathBuf;
pub trait ResourceCache {
fn get_tileset(&self, path: impl AsRef<ResourcePath>) -> Option<Rc<Tileset>>;
fn get_or_try_insert_tileset_with<F, E>(
&mut self,
path: ResourcePathBuf,
f: F,
) -> Result<Rc<Tileset>, E>
where
F: FnOnce() -> Result<Tileset, E>;
}
/// A cache that identifies resources by their path in the user's filesystem.
pub struct FilesystemResourceCache {
tilesets: HashMap<ResourcePathBuf, Rc<Tileset>>,
}
impl FilesystemResourceCache {
pub fn new() -> Self {
Self {
tilesets: HashMap::new(),
}
}
}
impl ResourceCache for FilesystemResourceCache {
fn get_tileset(&self, path: impl AsRef<ResourcePath>) -> Option<Rc<Tileset>> {
self.tilesets.get(path.as_ref()).map(Clone::clone)
}
fn get_or_try_insert_tileset_with<F, E>(
&mut self,
path: ResourcePathBuf,
f: F,
) -> Result<Rc<Tileset>, E>
where
F: FnOnce() -> Result<Tileset, E>,
{
Ok(match self.tilesets.entry(path) {
std::collections::hash_map::Entry::Occupied(o) => o.into_mut(),
std::collections::hash_map::Entry::Vacant(v) => v.insert(Rc::new(f()?)),
}
.clone())
}
}