shura 0.6.0

A fast cross-plattform 2D component-based game framework
Documentation
use rapier2d::prelude::{ColliderHandle, RigidBodyHandle};

use crate::{
    physics::{ColliderComponent, RigidBodyComponent, World},
    ComponentDerive, ComponentHandle,
};

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
enum WorldChange {
    AddCollider {
        component_handle: ComponentHandle,
        collider_handle: ColliderHandle,
    },
    AddRigidBody {
        component_handle: ComponentHandle,
        rigid_body_handle: RigidBodyHandle,
    },
    RemoveCollider {
        collider_handle: ColliderHandle,
    },
    RemoveRigidBody {
        rigid_body_handle: RigidBodyHandle,
    },
}

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Default)]
pub(crate) struct WorldChanges {
    changes: Vec<WorldChange>,
}

impl WorldChanges {
    pub fn new() -> Self {
        Self {
            changes: Default::default(),
        }
    }

    pub fn apply(&mut self, world: &mut World) {
        for change in self.changes.drain(..) {
            match change {
                WorldChange::AddCollider {
                    component_handle,
                    collider_handle,
                } => world.register_collider(component_handle, collider_handle),
                WorldChange::AddRigidBody {
                    component_handle,
                    rigid_body_handle,
                } => world.register_rigid_body(component_handle, rigid_body_handle),
                WorldChange::RemoveCollider { collider_handle } => {
                    world.unregister_collider(collider_handle)
                }
                WorldChange::RemoveRigidBody { rigid_body_handle } => {
                    world.unregister_rigid_body(rigid_body_handle)
                }
            }
        }
    }

    pub fn register_add(
        &mut self,
        component_handle: ComponentHandle,
        component: &dyn ComponentDerive,
    ) {
        if let Some(component) = component.base().downcast_ref::<RigidBodyComponent>() {
            self.changes.push(WorldChange::AddRigidBody {
                component_handle,
                rigid_body_handle: component.rigid_body_handle,
            });
        } else if let Some(component) = component.base().downcast_ref::<ColliderComponent>() {
            self.changes.push(WorldChange::AddCollider {
                component_handle,
                collider_handle: component.collider_handle,
            });
        }
    }

    pub fn register_remove(&mut self, component: &dyn ComponentDerive) {
        if let Some(component) = component.base().downcast_ref::<RigidBodyComponent>() {
            self.changes.push(WorldChange::RemoveRigidBody {
                rigid_body_handle: component.rigid_body_handle,
            });
        } else if let Some(component) = component.base().downcast_ref::<ColliderComponent>() {
            self.changes.push(WorldChange::RemoveCollider {
                collider_handle: component.collider_handle,
            });
        }
    }
}