1pub mod asset;
27pub mod asset_path;
28pub mod component;
29pub mod debug_snapshot;
30pub mod entity;
31pub mod handle;
32pub mod hierarchy;
33pub mod materializable;
34pub mod message;
35pub mod plugin;
36pub mod registry;
37pub mod reload_request;
38pub mod resource;
39
40pub use pybevy_storage::{
42 component_storage, field_storage, list_storage, resource_storage, storage, storage_error,
43 storage_traits, validity_guard, value_storage, view_bridge,
44};
45
46pybevy_storage::impl_py_list!(PyF32List, "F32List", f32);
48
49use bevy::ecs::{
50 component::ComponentId,
51 entity::Entity,
52 hierarchy::{ChildOf, Children},
53 world::{FilteredEntityMut, World},
54};
55use pyo3::prelude::*;
56
57pub struct ChildOfBridge;
60
61impl ComponentBridge for ChildOfBridge {
62 fn bevy_type_id(&self) -> std::any::TypeId {
63 std::any::TypeId::of::<ChildOf>()
64 }
65
66 fn py_type_ptr(&self) -> *const pyo3::ffi::PyTypeObject {
67 Python::attach(|py| {
68 <hierarchy::PyChildOf as pyo3::PyTypeInfo>::type_object(py).as_type_ptr()
69 })
70 }
71
72 fn py_type<'py>(&self, py: Python<'py>) -> pyo3::Bound<'py, pyo3::types::PyType> {
73 <hierarchy::PyChildOf as pyo3::PyTypeInfo>::type_object(py)
74 }
75
76 fn name(&self) -> &'static str {
77 "ChildOf"
78 }
79
80 fn register(&self, world: &mut World) -> ComponentId {
81 world.register_component::<ChildOf>()
82 }
83
84 #[inline(always)]
85 fn extract(
86 &self,
87 entity: &mut FilteredEntityMut,
88 component_id: ComponentId,
89 _validity: ValidityFlagWithMode,
90 py: Python,
91 ) -> PyResult<Py<PyAny>> {
92 let ptr = entity
95 .get_by_id(component_id)
96 .ok_or_else(|| pyo3::exceptions::PyRuntimeError::new_err("ChildOf not found"))?;
97
98 let component = unsafe { ptr.deref::<ChildOf>() };
99 let py_component = hierarchy::PyChildOf::try_from(component)?;
100 let obj = Py::new(py, (py_component, PyComponent))?;
101 Ok(obj.into_any())
102 }
103
104 fn insert(
105 &self,
106 world: &mut World,
107 entity: Entity,
108 component: &pyo3::Bound<PyAny>,
109 ) -> PyResult<()> {
110 let py_component = component.extract::<pyo3::PyRef<hierarchy::PyChildOf>>()?;
111 let native: ChildOf = py_component.storage.as_ref()?.clone();
112
113 world.entity_mut(entity).insert(native);
114 Ok(())
115 }
116
117 fn insert_into_entity(
118 &self,
119 entity: &mut bevy::ecs::world::EntityWorldMut,
120 component: &pyo3::Bound<PyAny>,
121 ) -> PyResult<()> {
122 let py_component = component.extract::<pyo3::PyRef<hierarchy::PyChildOf>>()?;
123 let native: ChildOf = py_component.storage.as_ref()?.clone();
124
125 entity.insert(native);
126 Ok(())
127 }
128
129 fn extract_fn(&self) -> ExtractFn {
130 #[inline(always)]
131 fn extract_impl(
132 entity: &mut FilteredEntityMut,
133 component_id: ComponentId,
134 _validity: ValidityFlagWithMode,
135 py: Python,
136 ) -> PyResult<Py<PyAny>> {
137 let ptr = entity
140 .get_by_id(component_id)
141 .ok_or_else(|| pyo3::exceptions::PyRuntimeError::new_err("ChildOf not found"))?;
142
143 let component = unsafe { ptr.deref::<bevy::ecs::hierarchy::ChildOf>() };
144 let py_component = crate::hierarchy::PyChildOf::try_from(component)?;
145 let obj = Py::new(py, (py_component, crate::component::PyComponent))?;
146 Ok(obj.into_any())
147 }
148 extract_impl
149 }
150
151 fn entity_contains(&self, entity: &bevy::ecs::world::EntityRef) -> bool {
152 entity.contains::<ChildOf>()
153 }
154
155 fn extract_from_entity_ref(
156 &self,
157 entity: &bevy::ecs::world::EntityRef,
158 validity: ValidityFlagWithMode,
159 py: Python,
160 ) -> PyResult<Option<Py<PyAny>>> {
161 if let Some(component) = entity.get::<ChildOf>() {
162 let ptr = component as *const ChildOf as *mut ChildOf;
163 let storage = unsafe { ComponentStorage::borrowed(ptr, validity) };
164 let obj = Py::new(py, hierarchy::PyChildOf::from_borrowed(storage))?;
165 Ok(Some(obj.into_any()))
166 } else {
167 Ok(None)
168 }
169 }
170
171 fn extract_from_entity_mut(
172 &self,
173 entity: &mut bevy::ecs::world::EntityWorldMut,
174 _validity: ValidityFlagWithMode,
175 py: Python,
176 ) -> PyResult<Option<Py<PyAny>>> {
177 if let Some(component) = entity.get::<ChildOf>() {
180 let py_component = hierarchy::PyChildOf::try_from(component)?;
181 let obj = Py::new(py, (py_component, PyComponent))?;
182 Ok(Some(obj.into_any()))
183 } else {
184 Ok(None)
185 }
186 }
187}
188
189pub struct ChildrenBridge;
194
195impl ComponentBridge for ChildrenBridge {
196 fn bevy_type_id(&self) -> std::any::TypeId {
197 std::any::TypeId::of::<Children>()
198 }
199
200 fn py_type_ptr(&self) -> *const pyo3::ffi::PyTypeObject {
201 Python::attach(|py| {
202 <hierarchy::PyChildren as pyo3::PyTypeInfo>::type_object(py).as_type_ptr()
203 })
204 }
205
206 fn py_type<'py>(&self, py: Python<'py>) -> pyo3::Bound<'py, pyo3::types::PyType> {
207 <hierarchy::PyChildren as pyo3::PyTypeInfo>::type_object(py)
208 }
209
210 fn name(&self) -> &'static str {
211 "Children"
212 }
213
214 fn register(&self, world: &mut World) -> ComponentId {
215 world.register_component::<Children>()
216 }
217
218 #[inline(always)]
219 fn extract(
220 &self,
221 entity: &mut FilteredEntityMut,
222 component_id: ComponentId,
223 _validity: ValidityFlagWithMode,
224 py: Python,
225 ) -> PyResult<Py<PyAny>> {
226 let ptr = entity
228 .get_by_id(component_id)
229 .ok_or_else(|| pyo3::exceptions::PyRuntimeError::new_err("Children not found"))?;
230
231 let component = unsafe { ptr.deref::<Children>() };
232 let py_component = hierarchy::PyChildren::try_from(component)?;
233 let obj = Py::new(py, (py_component, PyComponent))?;
234 Ok(obj.into_any())
235 }
236
237 fn insert(
238 &self,
239 _world: &mut World,
240 _entity: Entity,
241 _component: &pyo3::Bound<PyAny>,
242 ) -> PyResult<()> {
243 Err(pyo3::exceptions::PyNotImplementedError::new_err(
244 "Children cannot be spawned from Python - it is auto-managed by Bevy",
245 ))
246 }
247
248 fn insert_into_entity(
249 &self,
250 _entity: &mut bevy::ecs::world::EntityWorldMut,
251 _component: &pyo3::Bound<PyAny>,
252 ) -> PyResult<()> {
253 Err(pyo3::exceptions::PyNotImplementedError::new_err(
254 "Children cannot be spawned from Python - it is auto-managed by Bevy",
255 ))
256 }
257
258 fn extract_fn(&self) -> ExtractFn {
259 #[inline(always)]
260 fn extract_impl(
261 entity: &mut FilteredEntityMut,
262 component_id: ComponentId,
263 _validity: ValidityFlagWithMode,
264 py: Python,
265 ) -> PyResult<Py<PyAny>> {
266 let ptr = entity
267 .get_by_id(component_id)
268 .ok_or_else(|| pyo3::exceptions::PyRuntimeError::new_err("Children not found"))?;
269
270 let component = unsafe { ptr.deref::<bevy::ecs::hierarchy::Children>() };
271 let py_component = crate::hierarchy::PyChildren::try_from(component)?;
272 let obj = Py::new(py, (py_component, crate::component::PyComponent))?;
273 Ok(obj.into_any())
274 }
275 extract_impl
276 }
277
278 fn entity_contains(&self, entity: &bevy::ecs::world::EntityRef) -> bool {
279 entity.contains::<Children>()
280 }
281
282 fn extract_from_entity_ref(
283 &self,
284 entity: &bevy::ecs::world::EntityRef,
285 _validity: ValidityFlagWithMode,
286 py: Python,
287 ) -> PyResult<Option<Py<PyAny>>> {
288 if let Some(component) = entity.get::<Children>() {
289 let py_component = hierarchy::PyChildren::try_from(component)?;
290 let obj = Py::new(py, (py_component, PyComponent))?;
291 Ok(Some(obj.into_any()))
292 } else {
293 Ok(None)
294 }
295 }
296
297 fn extract_from_entity_mut(
298 &self,
299 entity: &mut bevy::ecs::world::EntityWorldMut,
300 _validity: ValidityFlagWithMode,
301 py: Python,
302 ) -> PyResult<Option<Py<PyAny>>> {
303 if let Some(component) = entity.get::<Children>() {
305 let py_component = hierarchy::PyChildren::try_from(component)?;
306 let obj = Py::new(py, (py_component, PyComponent))?;
307 Ok(Some(obj.into_any()))
308 } else {
309 Ok(None)
310 }
311 }
312}
313
314pub use asset::{NativeAsset, PyAsset};
316pub use asset_path::PyAssetPath;
317pub use component::PyComponent;
318pub use debug_snapshot::{DebugSnapshot, ReloadMemorySnapshotInfo};
319pub use entity::PyEntity;
320pub use handle::{PyHandle, extract_handle_from_any};
321pub use hierarchy::{PyChildOf, PyChildren, PyChildrenIterator};
322pub use materializable::PyMaterializable;
323pub use message::{PyMessage, PyMessageId};
324pub use plugin::{PluginBridge, PyPlugin};
325pub use pybevy_storage::{
327 AccessMode, AssetStorage, BorrowableStorage, ComponentStorage, ComponentStorageInner,
328 FieldOffset, FieldStorage, FieldStorageInner, FromBorrowedStorage, ListStorage,
329 ListStorageInner, ResourceStorage, ResourceStorageInner, StorageError, ValidityFlag,
330 ValidityFlagWithMode, ValidityGuard, ValueStorage, ValueStorageInner, ViewBridge,
331 ViewFieldAccess, normalize_index,
332};
333pub use registry::{
334 AssetBridge, BatchComponent, BatchFieldMeta, BatchableField, ComponentBatchInsertFn,
335 ComponentBatchMeta, ComponentBridge, DynamicAssetRegistry, DynamicComponentRegistry,
336 DynamicResourceRegistry, ExtractFn, MessageBridge, PluginConfigs, PyRustComponentBatch,
337 ResourceBridge, batch_field_meta_for, field_offset_view_meta_for, set_field_from_numpy,
338};
339pub use reload_request::{
340 CustomComponentEntry, CustomComponentInfo, CustomResourceEntry, CustomResourceInfo,
341 LastSystemError, PendingReloadRequest, PyResourceStorage, ReloadRequestMode, ReloadResult,
342};
343pub use resource::PyResource;
344pub use uuid;
346
347pub fn register_core_bridges() {
350 registry::global_registry::register_component_bridge(ChildOfBridge);
351 registry::global_registry::register_component_bridge(ChildrenBridge);
352 registry::rust_batch::register_rust_batch_bridge();
353}