2026-03-24 13:40:24 +00:00

91 lines
3.1 KiB
Rust

use std::sync::{Arc, RwLock};
use prometeu_abi::model::{SoundBank, TileBank};
/// Non-generic interface for peripherals to access graphical tile banks.
pub trait TileBankPoolAccess: Send + Sync {
/// Returns a reference to the resident TileBank in the specified slot, if any.
fn tile_bank_slot(&self, slot: usize) -> Option<Arc<TileBank>>;
/// Returns the total number of slots available in this bank.
fn tile_bank_slot_count(&self) -> usize;
}
/// Non-generic interface for the AssetManager to install graphical tile banks.
pub trait TileBankPoolInstaller: Send + Sync {
/// Atomically swaps the resident TileBank in the specified slot.
fn install_tile_bank(&self, slot: usize, bank: Arc<TileBank>);
}
/// Non-generic interface for peripherals to access sound banks.
pub trait SoundBankPoolAccess: Send + Sync {
/// Returns a reference to the resident SoundBank in the specified slot, if any.
fn sound_bank_slot(&self, slot: usize) -> Option<Arc<SoundBank>>;
/// Returns the total number of slots available in this bank.
fn sound_bank_slot_count(&self) -> usize;
}
/// Non-generic interface for the AssetManager to install sound banks.
pub trait SoundBankPoolInstaller: Send + Sync {
/// Atomically swaps the resident SoundBank in the specified slot.
fn install_sound_bank(&self, slot: usize, bank: Arc<SoundBank>);
}
/// Centralized container for all hardware memory banks.
///
/// MemoryBanks represent the actual hardware slot state.
/// Peripherals consume this state via narrow, non-generic traits.
/// AssetManager coordinates residency and installs assets into these slots.
pub struct MemoryBanks {
tile_bank_pool: Arc<RwLock<[Option<Arc<TileBank>>; 16]>>,
sound_bank_pool: Arc<RwLock<[Option<Arc<SoundBank>>; 16]>>,
}
impl MemoryBanks {
/// Creates a new set of memory banks with empty slots.
pub fn new() -> Self {
Self {
tile_bank_pool: Arc::new(RwLock::new(std::array::from_fn(|_| None))),
sound_bank_pool: Arc::new(RwLock::new(std::array::from_fn(|_| None))),
}
}
}
impl TileBankPoolAccess for MemoryBanks {
fn tile_bank_slot(&self, slot: usize) -> Option<Arc<TileBank>> {
let pool = self.tile_bank_pool.read().unwrap();
pool.get(slot).and_then(|s| s.as_ref().map(Arc::clone))
}
fn tile_bank_slot_count(&self) -> usize {
16
}
}
impl TileBankPoolInstaller for MemoryBanks {
fn install_tile_bank(&self, slot: usize, bank: Arc<TileBank>) {
let mut pool = self.tile_bank_pool.write().unwrap();
if slot < 16 {
pool[slot] = Some(bank);
}
}
}
impl SoundBankPoolAccess for MemoryBanks {
fn sound_bank_slot(&self, slot: usize) -> Option<Arc<SoundBank>> {
let pool = self.sound_bank_pool.read().unwrap();
pool.get(slot).and_then(|s| s.as_ref().map(Arc::clone))
}
fn sound_bank_slot_count(&self) -> usize {
16
}
}
impl SoundBankPoolInstaller for MemoryBanks {
fn install_sound_bank(&self, slot: usize, bank: Arc<SoundBank>) {
let mut pool = self.sound_bank_pool.write().unwrap();
if slot < 16 {
pool[slot] = Some(bank);
}
}
}