diff --git a/src/sprite.rs b/src/sprite.rs index ece33fb..967084c 100644 --- a/src/sprite.rs +++ b/src/sprite.rs @@ -140,6 +140,32 @@ extern "C" fn get_sprite_collision_response( } impl SpriteInner { + pub fn get_userdata(&self) -> Result>, Error> + where + T: Userdata, + { + let ptr = + pd_func_caller!((*self.playdate_sprite).getUserdata, self.raw_sprite)? as *const Box; + + let rc = unsafe { Rc::from_raw(ptr) }; + + unsafe { Rc::increment_strong_count(Rc::as_ptr(&rc)) } + Ok(rc) + } + + pub fn set_userdata(&mut self, userdata: Rc>) -> Result<(), Error> + where + T: Userdata, + { + let ptr = Rc::into_raw(userdata); + + pd_func_caller!( + (*self.playdate_sprite).setUserdata, + self.raw_sprite, + ptr as *mut core::ffi::c_void + ) + } + pub fn set_use_custom_draw(&mut self) -> Result<(), Error> { self.set_draw_function(unsafe { SPRITE_DRAW.expect("SPRITE_DRAW") }) } @@ -287,8 +313,30 @@ impl SpriteInner { } } +pub trait Userdata {} + impl Drop for SpriteInner { fn drop(&mut self) { + fn free_userdata(sprite: &SpriteInner) -> Result<(), Error> { + let ptr = pd_func_caller!((*sprite.playdate_sprite).getUserdata, sprite.raw_sprite)?; + + if ptr as *const _ == core::ptr::null() { + // No userdata on this sprite, nothing to do + return Ok(()); + } + + let rc = unsafe { Rc::from_raw(ptr as *const Box) }; + + // Just for clarity, we're dropping the rc which will decrease the strong count + drop(rc); + + Ok(()) + } + + if let Err(err) = free_userdata(self) { + log_to_console!("error dropping userdata: {}", err); + } + pd_func_caller_log!((*self.playdate_sprite).freeSprite, self.raw_sprite); unsafe { if let Some(collision_responses) = SPRITE_COLLISION_RESPONSES.as_mut() { @@ -318,6 +366,23 @@ pub struct Sprite { } impl Sprite { + pub fn get_userdata(&self) -> Result>, Error> + where + T: Userdata, + { + self.inner.try_borrow().map_err(Error::msg)?.get_userdata() + } + + pub fn set_userdata(&mut self, userdata: Rc>) -> Result<(), Error> + where + T: Userdata, + { + self.inner + .try_borrow_mut() + .map_err(Error::msg)? + .set_userdata(userdata) + } + pub fn set_use_custom_draw(&mut self) -> Result<(), Error> { self.inner .try_borrow_mut() @@ -495,6 +560,17 @@ impl SpriteManager { ) } + pub fn get_sprite_count(&self) -> Result { + pd_func_caller!((*self.playdate_sprite).getSpriteCount) + } + + pub fn remove_sprite(&self, sprite: &Sprite) -> Result<(), Error> { + pd_func_caller!( + (*self.playdate_sprite).removeSprite, + sprite.inner.borrow().raw_sprite + ) + } + pub fn add_dirty_rect(dirty_rect: LCDRect) -> Result<(), Error> { pd_func_caller!((*Self::get_mut().playdate_sprite).addDirtyRect, dirty_rect) }