summaryrefslogtreecommitdiff
path: root/alligator_resources/src
diff options
context:
space:
mode:
authorMicha White <botahamec@outlook.com>2022-10-25 11:13:37 -0400
committerMicha White <botahamec@outlook.com>2022-10-25 11:13:37 -0400
commit323c6ca03bc1d560b02114445764dab5e753049e (patch)
tree68b60475d670dfcab27ec5eab0de61c32f8b81ca /alligator_resources/src
parent578fc0aa670067991135921ab9a03d223036a598 (diff)
Started the alligator_resources project
Diffstat (limited to 'alligator_resources/src')
-rw-r--r--alligator_resources/src/lib.rs7
-rw-r--r--alligator_resources/src/texture.rs92
2 files changed, 99 insertions, 0 deletions
diff --git a/alligator_resources/src/lib.rs b/alligator_resources/src/lib.rs
new file mode 100644
index 0000000..5ea8ad1
--- /dev/null
+++ b/alligator_resources/src/lib.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::nursery)]
+#![warn(clippy::pedantic)]
+#![allow(clippy::module_name_repetitions)]
+
+pub mod texture;
+
+struct ResourceManager {}
diff --git a/alligator_resources/src/texture.rs b/alligator_resources/src/texture.rs
new file mode 100644
index 0000000..ba0ff47
--- /dev/null
+++ b/alligator_resources/src/texture.rs
@@ -0,0 +1,92 @@
+use std::collections::HashMap;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+use exun::{Expect, Expected, Unexpected};
+use thiserror::Error;
+
+static NEXT_TEXTURE_ID: AtomicUsize = AtomicUsize::new(0);
+
+type Rgba16Texture = image::ImageBuffer<image::Rgba<u16>, Box<[u16]>>;
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub struct TextureId(usize);
+
+impl TextureId {
+ fn new() -> Self {
+ Self(NEXT_TEXTURE_ID.fetch_add(1, Ordering::Relaxed))
+ }
+}
+
+/// These are the formats supported by the renderer.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+#[non_exhaustive]
+pub enum ImageFormat {
+ Bmp,
+ Ico,
+ Farbfeld,
+}
+
+impl From<ImageFormat> for image::ImageFormat {
+ fn from(format: ImageFormat) -> Self {
+ match format {
+ ImageFormat::Bmp => Self::Bmp,
+ ImageFormat::Ico => Self::Ico,
+ ImageFormat::Farbfeld => Self::Farbfeld,
+ }
+ }
+}
+
+#[derive(Debug, Error)]
+#[error("{}", .0)]
+pub struct DecodingError(#[from] image::error::DecodingError);
+
+type LoadError = Expect<DecodingError>;
+
+pub struct TextureManager {
+ textures: HashMap<TextureId, Rgba16Texture>,
+}
+
+#[allow(clippy::missing_const_for_fn)]
+fn convert_image_decoding(e: image::ImageError) -> Expect<DecodingError> {
+ if let image::ImageError::Decoding(de) = e {
+ Expected(de.into())
+ } else {
+ Unexpected(e.into())
+ }
+}
+
+impl TextureManager {
+ #[must_use]
+ pub fn new() -> Self {
+ Self {
+ textures: HashMap::new(),
+ }
+ }
+
+ /// Loads a texture from memory in the given format.
+ ///
+ /// # Errors
+ ///
+ /// This returns `Expected(DecodingError)` if the given buffer was invalid
+ /// for the given format.
+ #[allow(clippy::missing_panics_doc)]
+ pub fn load_from_memory(
+ &mut self,
+ buf: &[u8],
+ format: ImageFormat,
+ ) -> Result<TextureId, LoadError> {
+ let id = TextureId::new();
+ let texture = image::load_from_memory_with_format(buf, format.into())
+ .map_err(convert_image_decoding)?;
+
+ let texture = texture.into_rgb16();
+
+ let width = texture.width();
+ let height = texture.height();
+ let buf = texture.into_raw().into_boxed_slice();
+ let texture = image::ImageBuffer::from_raw(width, height, buf).unwrap();
+ self.textures.insert(id, texture);
+
+ Ok(id)
+ }
+}