diff --git a/Cargo.lock b/Cargo.lock index 00f4d7de..5900a30c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4037,7 +4037,7 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "playdate" -version = "0.2.2" +version = "0.2.3" dependencies = [ "playdate-controls", "playdate-display", diff --git a/api/playdate/Cargo.toml b/api/playdate/Cargo.toml index af486b37..6115bc92 100644 --- a/api/playdate/Cargo.toml +++ b/api/playdate/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "playdate" -version = "0.2.2" +version = "0.2.3" readme = "README.md" description = "High-level Playdate API" keywords = ["playdate", "sdk", "api", "gamedev"] diff --git a/api/sprite/src/lib.rs b/api/sprite/src/lib.rs index dfb2682e..9a076ccd 100644 --- a/api/sprite/src/lib.rs +++ b/api/sprite/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(not(test), no_std)] +#![feature(const_alloc_layout)] extern crate sys; extern crate alloc; @@ -293,3 +294,45 @@ impl SpriteType for T { type Userdata = ::Userdata; const FREE_ON_DROP: bool = ::FREE_ON_DROP; } + + +pub mod utils { + use core::ops::Deref; + + /// C array syzed at runtime. + #[must_use] + #[repr(transparent)] + pub struct Arr<'t, T>(pub(super) &'t [T]); + + impl Drop for Arr<'_, T> { + fn drop(&mut self) { + let p = self.0.as_ptr() as _; + + #[inline] + const fn inner(len: usize) -> core::alloc::Layout { + if let Ok(l) = core::alloc::Layout::array::(len) { + l + } else { + use core::mem::{size_of, align_of}; + let (size, align) = (size_of::(), align_of::()); + unsafe { core::alloc::Layout::from_size_align_unchecked(size.unchecked_mul(len), align) } + } + } + + let l = inner::(self.0.len()); + unsafe { + // We could simply `sys::allocator::dealloc(p)`, but we have to use SYSTEM GLOBAL allocator, + // which can be a user's custom allocator, not that one in `playdate-sys`. + alloc::alloc::dealloc(p, l); + }; + } + } + + impl Deref for Arr<'_, T> { + type Target = [T]; + fn deref(&self) -> &Self::Target { self.0 } + } + impl AsRef<[T]> for Arr<'_, T> { + fn as_ref(&self) -> &[T] { self.0 } + } +} diff --git a/api/sprite/src/sprite.rs b/api/sprite/src/sprite.rs index 6df81e73..c4cf5173 100644 --- a/api/sprite/src/sprite.rs +++ b/api/sprite/src/sprite.rs @@ -1,5 +1,15 @@ //! Sprite implementations. +/* +TODO: Cover api-methods: + - [] querySpritesInRect + - [] querySpritesAlongLine + - [] querySpriteInfoAlongLine + - [] overlappingSprites + - [] allOverlappingSprites +*/ + + use core::ffi::c_int; use core::ffi::c_void; use core::ffi::c_float; @@ -18,6 +28,7 @@ use gfx::bitmap::BitmapRef; use gfx::bitmap::BitmapDrawMode; use gfx::bitmap::BitmapFlip; +use crate::utils; use crate::AnySprite; use crate::SpriteApi; use crate::TypedSprite; @@ -703,36 +714,6 @@ impl Sprite { } -pub mod utils { - use core::ops::Deref; - - /// C array syzed at runtime. - #[repr(transparent)] - #[must_use] - pub struct Arr<'t, T>(pub(super) &'t [T]); - - impl Drop for Arr<'_, T> { - fn drop(&mut self) { - let p = self.0.as_ptr() as _; - unsafe { - // May be here to use SYSTEM allocator? Needed if custom user's alocator used. - // let l = core::alloc::Layout::new::(); - // or alloc::alloc::dealloc(p, l); - sys::allocator::dealloc(p); - }; - } - } - - impl Deref for Arr<'_, T> { - type Target = [T]; - fn deref(&self) -> &Self::Target { self.0 } - } - impl AsRef<[T]> for Arr<'_, T> { - fn as_ref(&self) -> &[T] { self.0 } - } -} - - #[cfg(test)] mod tests { use super::*;