use crate::{
FuncType,
RawHandle,
collections::arena::{ArenaKey, DedupArena},
engine::{EngineId, EngineOwned},
};
define_handle! {
#[derive(PartialEq, Eq)]
struct DedupFuncType(u32, EngineOwned) => FuncType;
}
#[derive(Debug)]
pub struct FuncTypeRegistry {
engine_id: EngineId,
func_types: DedupArena<RawHandle<DedupFuncType>, FuncType>,
}
impl FuncTypeRegistry {
pub(crate) fn new(engine_id: EngineId) -> Self {
Self {
engine_id,
func_types: DedupArena::default(),
}
}
fn unwrap_or_panic<T>(&self, func_type: EngineOwned<T>) -> T
where
T: ArenaKey,
{
self.engine_id.unwrap(func_type).unwrap_or_else(|| {
panic!(
"encountered foreign entity in func type registry: {:?}",
self.engine_id,
)
})
}
pub(crate) fn alloc_func_type(&mut self, func_type: FuncType) -> DedupFuncType {
let key = match self.func_types.alloc(func_type) {
Ok(key) => key,
Err(err) => panic!("failed to alloc func type: {err}"),
};
DedupFuncType(self.engine_id.wrap(key))
}
pub(crate) fn resolve_func_type(&self, key: &DedupFuncType) -> &FuncType {
let raw_key = self.unwrap_or_panic(key.0);
self.func_types
.get(raw_key)
.unwrap_or_else(|err| panic!("failed to resolve function type at {key:?}: {err}"))
}
}