mod system_builder;
mod system_runner_fluent;
pub use system_builder::*;
pub use system_runner_fluent::*;
use core::ops::DerefMut;
use core::{ffi::c_void, ops::Deref, ptr::NonNull};
use crate::core::*;
use crate::sys;
#[derive(Clone, Copy)]
pub struct System<'a> {
pub(crate) entity: EntityView<'a>,
}
impl<'a> Deref for System<'a> {
type Target = EntityView<'a>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.entity
}
}
impl DerefMut for System<'_> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.entity
}
}
impl<'a> WorldProvider<'a> for System<'a> {
#[inline(always)]
fn world(&self) -> WorldRef<'a> {
self.world
}
}
impl<'a> System<'a> {
pub fn new(world: impl WorldProvider<'a>, desc: sys::ecs_system_desc_t) -> Self {
let id = unsafe { sys::ecs_system_init(world.world_ptr_mut(), &desc) };
let entity = EntityView::new_from(world.world(), id);
Self { entity }
}
pub fn new_from_existing(system_entity: EntityView<'a>) -> Self {
Self {
entity: system_entity,
}
}
pub fn set_context(&mut self, context: *mut c_void) {
let desc: sys::ecs_system_desc_t = sys::ecs_system_desc_t {
entity: *self.id(),
ctx: context,
..Default::default()
};
unsafe {
sys::ecs_system_init(self.world.world_ptr_mut(), &desc);
}
}
pub fn context(&self) -> *mut c_void {
unsafe { (*sys::ecs_system_get(self.world.world_ptr(), *self.id())).ctx }
}
pub fn query(&self) -> Query<()> {
let query = unsafe {
NonNull::new_unchecked((*sys::ecs_system_get(self.world.world_ptr(), *self.id())).query)
};
unsafe { Query::<()>::new_from(query) }
}
pub fn immediate(&self) -> bool {
unsafe { (*sys::ecs_system_get(self.world.world_ptr(), *self.id())).immediate }
}
pub fn multi_threaded(&self) -> bool {
unsafe { (*sys::ecs_system_get(self.world.world_ptr(), *self.id())).multi_threaded }
}
#[inline]
pub fn run_dt_param(&self, delta_time: FTime, param: *mut c_void) -> SystemRunnerFluent<'_> {
SystemRunnerFluent::new(self.world.real_world(), *self.id(), 0, 0, delta_time, param)
}
#[inline]
pub fn run_dt(&self, delta_time: FTime) -> SystemRunnerFluent<'_> {
self.run_dt_param(delta_time, core::ptr::null_mut())
}
#[inline]
pub fn run(&self) -> SystemRunnerFluent<'_> {
self.run_dt_param(0.0, core::ptr::null_mut())
}
pub fn run_worker(
&self,
stage_current: i32,
stage_count: i32,
delta_time: FTime,
param: *mut c_void,
) -> SystemRunnerFluent<'_> {
SystemRunnerFluent::new(
self.world,
*self.id(),
stage_current,
stage_count,
delta_time,
param,
)
}
}