Skip to content

Commit

Permalink
use system allocator to free given array
Browse files Browse the repository at this point in the history
  • Loading branch information
boozook committed Aug 24, 2024
1 parent b98e1cc commit 6d6f97b
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/playdate/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"]
Expand Down
43 changes: 43 additions & 0 deletions api/sprite/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![cfg_attr(not(test), no_std)]
#![feature(const_alloc_layout)]

extern crate sys;
extern crate alloc;
Expand Down Expand Up @@ -293,3 +294,45 @@ impl<T: TypedSprite> SpriteType for T {
type Userdata = <T as TypedSprite>::Userdata;
const FREE_ON_DROP: bool = <T as TypedSprite>::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<T> Drop for Arr<'_, T> {
fn drop(&mut self) {
let p = self.0.as_ptr() as _;

#[inline]
const fn inner<T>(len: usize) -> core::alloc::Layout {
if let Ok(l) = core::alloc::Layout::array::<T>(len) {
l
} else {
use core::mem::{size_of, align_of};
let (size, align) = (size_of::<T>(), align_of::<T>());
unsafe { core::alloc::Layout::from_size_align_unchecked(size.unchecked_mul(len), align) }
}
}

let l = inner::<T>(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<T> Deref for Arr<'_, T> {
type Target = [T];
fn deref(&self) -> &Self::Target { self.0 }
}
impl<T> AsRef<[T]> for Arr<'_, T> {
fn as_ref(&self) -> &[T] { self.0 }
}
}
41 changes: 11 additions & 30 deletions api/sprite/src/sprite.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -703,36 +714,6 @@ impl<Userdata, Api: api::Api, const FOD: bool> Sprite<Userdata, Api, FOD> {
}


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<T> 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::<T>();
// or alloc::alloc::dealloc(p, l);
sys::allocator::dealloc(p);
};
}
}

impl<T> Deref for Arr<'_, T> {
type Target = [T];
fn deref(&self) -> &Self::Target { self.0 }
}
impl<T> AsRef<[T]> for Arr<'_, T> {
fn as_ref(&self) -> &[T] { self.0 }
}
}


#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 6d6f97b

Please sign in to comment.