use drop of iterator to clear rest of objects

This commit is contained in:
Corwin 2023-04-03 02:43:18 +01:00
parent d8f0d78d4b
commit 57f24acdf9
No known key found for this signature in database
2 changed files with 27 additions and 22 deletions

View file

@ -167,8 +167,6 @@ impl OAMManager<'_> {
} }
pub fn commit(&self) { pub fn commit(&self) {
let mut count = 0;
let mut unmanaged = UnmanagedOAM::new(); let mut unmanaged = UnmanagedOAM::new();
// do interactions with OAM // do interactions with OAM
@ -179,9 +177,7 @@ impl OAMManager<'_> {
.zip(unmanaged.iter()) .zip(unmanaged.iter())
{ {
slot.set(object); slot.set(object);
count += 1;
} }
unmanaged.clear_from(count);
// finished OAM interactions // finished OAM interactions

View file

@ -1,4 +1,7 @@
use core::{cell::UnsafeCell, marker::PhantomData}; use core::{
cell::{Cell, UnsafeCell},
marker::PhantomData,
};
use agb_fixnum::Vector2D; use agb_fixnum::Vector2D;
@ -11,16 +14,17 @@ use super::attributes::{AffineMode, Attributes};
pub struct UnmanagedOAM<'gba> { pub struct UnmanagedOAM<'gba> {
phantom: PhantomData<&'gba ()>, phantom: PhantomData<&'gba ()>,
up_to: Cell<i32>,
} }
pub struct OAMIterator<'oam> { pub struct OAMIterator<'oam> {
phantom: PhantomData<&'oam ()>,
index: usize, index: usize,
up_to: &'oam Cell<i32>,
} }
pub struct OAMSlot<'oam> { pub struct OAMSlot<'oam> {
phantom: PhantomData<&'oam ()>,
slot: usize, slot: usize,
up_to: &'oam Cell<i32>,
} }
impl OAMSlot<'_> { impl OAMSlot<'_> {
@ -31,6 +35,8 @@ impl OAMSlot<'_> {
let sprites = unsafe { &mut *object.sprites.get() }; let sprites = unsafe { &mut *object.sprites.get() };
sprites.previous_sprite = Some(sprites.sprite.clone()); sprites.previous_sprite = Some(sprites.sprite.clone());
self.up_to.set(self.slot as i32);
} }
fn set_bytes(&mut self, bytes: [u8; 6]) { fn set_bytes(&mut self, bytes: [u8; 6]) {
@ -52,39 +58,42 @@ impl<'oam> Iterator for OAMIterator<'oam> {
None None
} else { } else {
Some(OAMSlot { Some(OAMSlot {
phantom: PhantomData,
slot: idx, slot: idx,
up_to: self.up_to,
}) })
} }
} }
} }
impl Drop for OAMIterator<'_> {
fn drop(&mut self) {
let last_written = self.up_to.get();
let number_writen = (last_written + 1) as usize;
for idx in number_writen..128 {
unsafe {
let ptr = (OBJECT_ATTRIBUTE_MEMORY as *mut u16).add(idx * 4);
ptr.write_volatile(0b10 << 8);
}
}
}
}
impl UnmanagedOAM<'_> { impl UnmanagedOAM<'_> {
pub fn iter(&mut self) -> OAMIterator<'_> { pub fn iter(&mut self) -> OAMIterator<'_> {
OAMIterator { OAMIterator {
phantom: PhantomData,
index: 0, index: 0,
up_to: &mut self.up_to,
} }
} }
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
Self { Self {
up_to: Cell::new(0),
phantom: PhantomData, phantom: PhantomData,
} }
} }
pub fn clear_from(&self, from: usize) {
if from >= 128 {
return;
}
for i in from..128 {
unsafe {
let ptr = (OBJECT_ATTRIBUTE_MEMORY as *mut u16).add(i * 4);
ptr.write_volatile(0b10 << 8);
}
}
}
} }
#[derive(Debug)] #[derive(Debug)]