use std::collections::HashMap;
use std::sync::Arc;
#[derive(Debug, Default, Clone)]
pub struct SpriteManager {
sprites: HashMap<Arc<str>, Sprite>,
sprite_list: Vec<(u8, Arc<str>)>,
}
#[derive(Debug, Clone)]
pub struct Sprite {
texture: Arc<str>,
x: f32,
y: f32,
z: u8,
width: f32,
height: f32,
}
impl SpriteManager {
pub fn new() -> Self {
Self {
sprites: HashMap::new(),
sprite_list: Vec::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
sprites: HashMap::with_capacity(capacity),
sprite_list: Vec::with_capacity(capacity),
}
}
pub fn add_sprite(&mut self, name: Arc<str>, sprite: Sprite) {
let z = sprite.z;
self.sprites.insert(name.clone(), sprite);
self.sprite_list.push((z, name));
}
pub fn clear(&mut self) {
self.sprites.clear();
self.sprite_list.clear();
}
pub fn remove_sprite(&mut self, name: Arc<str>) {
self.sprites.remove(&name);
self.sprite_list.retain(|(_, n)| name != n.clone());
}
pub fn get_mut_sprite(&mut self, name: &str) -> Option<&mut Sprite> {
self.sprites.get_mut(name)
}
pub fn set_sprite_z(&mut self, name: Arc<str>, new_z: u8) -> Option<()> {
let sprite = self.sprites.get_mut(&name)?;
sprite.z = new_z;
for (depth, n) in &mut self.sprite_list {
if n.clone() == name {
*depth = new_z;
}
}
Some(())
}
fn sort(&mut self) {
// in case it's unclear, this is insertion sort
// the list is usually already sorted, so this is the most efficient algorithm
for i in 0..self.sprite_list.len() {
let t = self.sprite_list[i].clone();
let mut j = i;
while j > 0 && self.sprite_list[j - 1].0 > t.0 {
self.sprite_list[j] = self.sprite_list[j - 1].clone();
j -= 1;
}
self.sprite_list[j] = t;
}
}
pub fn sorted_sprites(&mut self) -> Vec<Sprite> {
self.sort();
let mut sprites = Vec::new();
for (_, sprite) in &self.sprite_list {
// i don't like accessing the hashmap every time, but i can't think
// of anything better
sprites.push(self.sprites[sprite].clone());
}
sprites
}
}
impl Sprite {
pub fn new(x: f32, y: f32, z: u8, width: f32, height: f32, texture: Arc<str>) -> Self {
Self {
texture,
x,
y,
z,
width,
height,
}
}
pub fn x(&self) -> f32 {
self.x
}
pub fn y(&self) -> f32 {
self.y
}
pub fn z(&self) -> u8 {
self.z
}
pub fn width(&self) -> f32 {
self.width
}
pub fn height(&self) -> f32 {
self.height
}
pub fn texture_name(&self) -> &Arc<str> {
&self.texture
}
pub fn set_x(&mut self, x: f32) {
self.x = x;
}
pub fn set_y(&mut self, y: f32) {
self.y = y;
}
pub fn set_width(&mut self, width: f32) {
self.width = width;
}
pub fn set_height(&mut self, height: f32) {
self.height = height;
}
pub fn set_texture(&mut self, texture_name: Arc<str>) {
self.texture = texture_name;
}
}
|