use pybevy_core::registry::global_registry;
use pyo3::{exceptions::PyTypeError, ffi::PyTypeObject, prelude::*, types::PyType};
#[pyclass(name = "AssetTypeParam", frozen)]
#[derive(Debug, Clone)]
pub struct PyAssetTypeParam {
type_ptr: *const PyTypeObject,
wrapper_class: Option<*const PyTypeObject>,
}
unsafe impl Send for PyAssetTypeParam {}
unsafe impl Sync for PyAssetTypeParam {}
impl PyAssetTypeParam {
pub fn try_from_py_type(asset_type: &Bound<'_, PyType>) -> PyResult<Self> {
let type_ptr = asset_type.as_type_ptr();
if global_registry::contains_asset_py_type(type_ptr) {
Ok(Self {
type_ptr,
wrapper_class: None,
})
} else {
Err(PyTypeError::new_err(format!(
"Invalid asset type. Expected a subclass of `Asset`, but got `{}`",
asset_type
)))
}
}
pub fn with_redirect(
actual_type: &Bound<'_, PyType>,
wrapper: &Bound<'_, PyType>,
) -> PyResult<Self> {
let type_ptr = actual_type.as_type_ptr();
if global_registry::contains_asset_py_type(type_ptr) {
Ok(Self {
type_ptr,
wrapper_class: Some(wrapper.as_type_ptr()),
})
} else {
Err(PyTypeError::new_err(format!(
"Invalid asset type. Expected a subclass of `Asset`, but got `{}`",
actual_type
)))
}
}
pub fn type_ptr(&self) -> *const PyTypeObject {
self.type_ptr
}
pub fn wrapper_class(&self) -> Option<*const PyTypeObject> {
self.wrapper_class
}
}
#[pymethods]
impl PyAssetTypeParam {
pub fn asset_type_class(&self) -> PyResult<Py<PyType>> {
if let Some(bridge) = global_registry::get_asset_bridge_by_py_type(self.type_ptr) {
Ok(Python::attach(|py| bridge.py_type(py).unbind()))
} else {
Err(PyTypeError::new_err("Asset bridge not found for type"))
}
}
}