use super::{
bindings::{EcsRef, SchemaLuaEcsRefMetatable},
*,
};
pub trait CtxExt {
fn singletons(&self) -> &LuaSingletons;
}
impl CtxExt for piccolo::Context<'_> {
fn singletons(&self) -> &LuaSingletons {
let Value::UserData(data) = self.globals().get(*self, "luasingletons") else {
unreachable!();
};
data.downcast_static::<LuaSingletons>().unwrap()
}
}
pub trait MetatableFn {
fn metatable_fn(&self) -> fn(piccolo::Context) -> piccolo::Table;
}
impl MetatableFn for SchemaRef<'_> {
fn metatable_fn(&self) -> fn(piccolo::Context) -> piccolo::Table {
self.schema()
.type_data
.get::<SchemaLuaEcsRefMetatable>()
.map(|x| x.0)
.unwrap_or(bindings::ecsref::metatable)
}
}
impl MetatableFn for SchemaRefMut<'_> {
fn metatable_fn(&self) -> fn(piccolo::Context) -> piccolo::Table {
self.schema()
.type_data
.get::<SchemaLuaEcsRefMetatable>()
.map(|x| x.0)
.unwrap_or(bindings::ecsref::metatable)
}
}
impl MetatableFn for EcsRef {
fn metatable_fn(&self) -> fn(piccolo::Context) -> piccolo::Table {
(|| {
let b = self.borrow();
Some(b.schema_ref().ok()?.metatable_fn())
})()
.unwrap_or(bindings::ecsref::metatable)
}
}
pub trait ValueExt<'gc> {
fn as_static_user_data<T: 'static>(&self) -> Result<&'gc T, piccolo::TypeError>;
}
impl<'gc> ValueExt<'gc> for Value<'gc> {
fn as_static_user_data<T: 'static>(&self) -> Result<&'gc T, piccolo::TypeError> {
if let Value::UserData(t) = self {
Ok(t.downcast_static().map_err(|_| piccolo::TypeError {
expected: std::any::type_name::<T>(),
found: "other user data",
})?)
} else {
Err(piccolo::TypeError {
expected: std::any::type_name::<T>(),
found: "other lua value",
})
}
}
}