use std::any::Any;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::mem::transmute;
use std::ops::{Deref, DerefMut};
use pi_share::Share;
use crate::system::{Relation, SystemMeta, TypeInfo};
use crate::system_params::SystemParam;
use crate::world::{Downcast, Tick, TickMut, World};
use crate::world_ptr::Ptr;
#[derive(Debug, Default)]
pub struct TickRes<T> {
pub(crate) res: T,
pub(crate) changed_tick: Tick,
}
unsafe impl<T> Send for TickRes<T> {}
unsafe impl<T> Sync for TickRes<T> {}
impl<T: 'static> Downcast for TickRes<T> {
fn into_any(self: Share<Self>) -> Share<dyn Any + Send + Sync> {
self
}
fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
self
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
impl<T: 'static> TickMut for TickRes<T> {
fn get_tick(&self) -> Tick {
self.changed_tick
}
fn set_tick(&mut self, tick: Tick) {
self.changed_tick = tick;
}
}
impl<T: 'static> TickRes<T> {
pub fn new(res: T) -> Self {
TickRes {
res,
changed_tick: Tick::default(),
}
}
}
impl<T: 'static> Deref for TickRes<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.res
}
}
impl<T: 'static> DerefMut for TickRes<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.res
}
}
pub struct SingleRes<'w, T: 'static + Send + Sync> {
pub(crate) state: &'w ResState<T>,
}
impl<T: 'static + Debug + Send + Sync> Debug for SingleRes<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SingleRes").field("value", &**self).finish()
}
}
unsafe impl<T: 'static + Send + Sync> Send for SingleRes<'_, T> {}
unsafe impl<T: 'static + Send + Sync> Sync for SingleRes<'_, T> {}
impl<'w, T: 'static + Send + Sync> SingleRes<'w, T> {
pub(crate) fn new(state: &'w ResState<T>) -> Self {
SingleRes { state }
}
pub fn changed_tick(&self) -> Tick {
unsafe {&*self.state.value}.changed_tick
}
pub fn is_changed(&self) -> bool {
unsafe {&*self.state.value}.changed_tick > self.state.state.system_meta.last_run
}
}
pub struct ResState<T:'static + Send + Sync> {
value: *mut TickRes<T>,
state: ResState1,
}
unsafe impl<T:'static + Send + Sync> Send for ResState<T> {}
unsafe impl<T:'static + Send + Sync> Sync for ResState<T> {}
pub struct ResState1{
system_meta: Ptr<SystemMeta>,
world: Ptr<World>,
index: usize,
}
impl<T: 'static + Send + Sync> SystemParam for SingleRes<'_, T> {
type State = ResState<T>;
type Item<'w> = SingleRes<'w, T>;
fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
init_state::<T>(world, meta)
}
#[inline(always)]
fn init<'world>(state: &'world mut Self::State) {
init_opt_state::<T>(state);
}
fn get_param<'world>(
state: &'world mut Self::State,
) -> Self::Item<'world> {
SingleRes::new(state)
}
fn get_self<'world>(
state: &'world mut Self::State,
) -> Self {
unsafe { transmute(Self::get_param(state)) }
}
}
impl<'w, T: Sync + Send + 'static> Deref for SingleRes<'w, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe {&*self.state.value}
}
}
pub struct SingleResMut<'w, T: 'static + Send + Sync> {
pub(crate) state: &'w ResState<T>,
mark: PhantomData<T>
}
impl<T: 'static + Send + Sync + Debug> Debug for SingleResMut<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SingleResMut").field("value", &**self).finish()
}
}
unsafe impl<T: 'static + Send + Sync> Send for SingleResMut<'_, T> {}
unsafe impl<T: 'static + Send + Sync> Sync for SingleResMut<'_, T> {}
impl<'w, T: 'static + Send + Sync> SingleResMut<'w, T> {
pub(crate) fn new(state: &'w ResState<T>) -> Self {
SingleResMut { state, mark: PhantomData }
}
pub fn changed_tick(&self) -> Tick {
unsafe {&*self.state.value}.changed_tick
}
pub fn tick(&self) -> Tick {
self.state.state.system_meta.this_run
}
}
impl<T: 'static + Send + Sync> SystemParam for SingleResMut<'_, T> {
type State = ResState<T>;
type Item<'w> = SingleResMut<'w, T>;
fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
init_state::<T>(world, meta)
}
#[inline(always)]
fn init<'world>(state: &'world mut Self::State) {
init_opt_state::<T>(state);
}
#[inline(always)]
fn get_param<'world>(
state: &'world mut Self::State,
) -> Self::Item<'world> {
SingleResMut::new( state)
}
#[inline(always)]
fn get_self<'world>(
state: &'world mut Self::State,
) -> Self {
unsafe { transmute(Self::get_param(state)) }
}
}
impl<'w, T: Sync + Send + 'static> Deref for SingleResMut<'w, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe {&*self.state.value}
}
}
impl<'w, T: Sync + Send + 'static> DerefMut for SingleResMut<'w, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {&mut *self.state.value}.changed_tick = self.state.state.system_meta.this_run;
unsafe {&mut **self.state.value}
}
}
impl<T: 'static + Send + Sync> SystemParam for Option<SingleRes<'_, T>> {
type State = ResState<T>;
type Item<'w> = Option<SingleRes<'w, T>>;
fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
init_state::<T>(world, meta)
}
fn get_param<'world>(
state: &'world mut Self::State,
) -> Self::Item<'world> {
match _get_opt(&state.state.world, state.state.index) {
Some(res) => {
state.value = Share::as_ptr(&Share::downcast::<TickRes<T>>(res).unwrap()) as usize as *mut TickRes<T>;
Some(SingleRes::new(state))
},
None => None,
}
}
fn get_self<'world>(
state: &'world mut Self::State,
) -> Self {
unsafe { transmute(Self::get_param( state )) }
}
}
impl<T: 'static + Send + Sync> SystemParam for Option<SingleResMut<'_, T>> {
type State = ResState<T>;
type Item<'w> = Option<SingleResMut<'w, T>>;
fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
init_state::<T>(world, meta)
}
#[inline(always)]
fn get_param<'world>(
state: &'world mut Self::State,
) -> Self::Item<'world> {
match _get_opt(&state.state.world, state.state.index) {
Some(res) => {
state.value = Share::as_ptr(&Share::downcast::<TickRes<T>>(res).unwrap()) as usize as *mut TickRes<T>;
Some(SingleResMut::new(state))
},
None => None,
}
}
#[inline(always)]
fn get_self<'world>(
state: &'world mut Self::State,
) -> Self {
unsafe { transmute(Self::get_param(state)) }
}
}
#[inline]
fn init_state<T: 'static + Send + Sync>(
world: &mut World,
meta: &mut SystemMeta,
) -> ResState<T> {
let t = TypeInfo::of::<T>();
ResState {
value: 0 as *mut TickRes<T>,
state: _init_state(t, world, meta)
}
}
fn _init_state(
t: TypeInfo,
world: &mut World,
meta: &mut SystemMeta,
) -> ResState1 {
let r = Relation::Read(t.type_id);
let index = meta.add_single_res(world, t, r);
ResState1 {
index,
world: Ptr::new(world),
system_meta: Ptr::new(meta)
}
}
#[inline(always)]
fn init_opt_state<T: 'static + Send + Sync>(state: &mut ResState<T>) {
state.value = Share::as_ptr(&Share::downcast::<TickRes<T>>(_init_opt_state(&state.state.world, state.state.index)).unwrap()) as usize as *mut TickRes<T>;
}
fn _init_opt_state(world: &World, index: usize) -> Share<dyn Any + Send + Sync> {
let s = world.index_single_res_any(index).unwrap();
s.clone().into_any()
}
#[inline(always)]
fn get_opt<'w, T: 'static + Send + Sync>(state: &'w ResState1) -> Option<*mut TickRes<T>> {
match state.world.index_single_res_any(state.index) {
Some(s) => Some(Share::as_ptr(&Share::downcast::<TickRes<T>>(s.clone().into_any()).unwrap()) as usize as *mut TickRes<T>),
None => None,
}
}
fn _get_opt(world: &World, index: usize) -> Option<Share<dyn Any + Send + Sync>> {
match world.index_single_res_any(index) {
Some(s) => Some(s.clone().into_any()),
None => None,
}
}