mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Avoid re-fetching system data on every link persist
This commit is contained in:
parent
451e586aac
commit
ec5e3fe716
@ -6,13 +6,13 @@ pub trait Link: Sized + Send + Sync + 'static {
|
||||
type Error;
|
||||
|
||||
type CreateData<'a>: SystemData<'a>;
|
||||
fn create(this: &LinkHandle<Self>, data: Self::CreateData<'_>) -> Result<(), Self::Error>;
|
||||
fn create(this: &LinkHandle<Self>, data: &mut Self::CreateData<'_>) -> Result<(), Self::Error>;
|
||||
|
||||
type PersistData<'a>: SystemData<'a>;
|
||||
fn persist(this: &LinkHandle<Self>, data: Self::PersistData<'_>) -> bool;
|
||||
fn persist(this: &LinkHandle<Self>, data: &mut Self::PersistData<'_>) -> bool;
|
||||
|
||||
type DeleteData<'a>: SystemData<'a>;
|
||||
fn delete(this: &LinkHandle<Self>, data: Self::DeleteData<'_>);
|
||||
fn delete(this: &LinkHandle<Self>, data: &mut Self::DeleteData<'_>);
|
||||
}
|
||||
|
||||
pub trait Role {
|
||||
@ -27,7 +27,9 @@ pub struct Is<R: Role> {
|
||||
}
|
||||
|
||||
impl<R: Role> Is<R> {
|
||||
pub fn delete(&self, data: <R::Link as Link>::DeleteData<'_>) { Link::delete(&self.link, data) }
|
||||
pub fn delete(&self, data: &mut <R::Link as Link>::DeleteData<'_>) {
|
||||
Link::delete(&self.link, data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Role> Clone for Is<R> {
|
||||
|
@ -67,7 +67,7 @@ impl Link for Mounting {
|
||||
|
||||
fn create(
|
||||
this: &LinkHandle<Self>,
|
||||
(uid_allocator, mut is_mounts, mut is_riders, is_volume_rider): Self::CreateData<'_>,
|
||||
(uid_allocator, is_mounts, is_riders, is_volume_rider): &mut Self::CreateData<'_>,
|
||||
) -> Result<(), Self::Error> {
|
||||
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into());
|
||||
|
||||
@ -94,7 +94,7 @@ impl Link for Mounting {
|
||||
|
||||
fn persist(
|
||||
this: &LinkHandle<Self>,
|
||||
(uid_allocator, entities, healths, bodies, is_mounts, is_riders, character_states): Self::PersistData<'_>,
|
||||
(uid_allocator, entities, healths, bodies, is_mounts, is_riders, character_states): &mut Self::PersistData<'_>,
|
||||
) -> bool {
|
||||
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into());
|
||||
|
||||
@ -123,7 +123,7 @@ impl Link for Mounting {
|
||||
|
||||
fn delete(
|
||||
this: &LinkHandle<Self>,
|
||||
(uid_allocator, mut is_mounts, mut is_riders, mut positions, mut force_update, terrain): Self::DeleteData<'_>,
|
||||
(uid_allocator, is_mounts, is_riders, positions, force_update, terrain): &mut Self::DeleteData<'_>,
|
||||
) {
|
||||
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into());
|
||||
|
||||
@ -311,14 +311,14 @@ impl Link for VolumeMounting {
|
||||
fn create(
|
||||
this: &LinkHandle<Self>,
|
||||
(
|
||||
mut terrain_riders,
|
||||
mut volume_riders,
|
||||
mut is_volume_riders,
|
||||
terrain_riders,
|
||||
volume_riders,
|
||||
is_volume_riders,
|
||||
is_riders,
|
||||
terrain_grid,
|
||||
uid_allocator,
|
||||
colliders,
|
||||
): Self::CreateData<'_>,
|
||||
): &mut Self::CreateData<'_>,
|
||||
) -> Result<(), Self::Error> {
|
||||
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into());
|
||||
|
||||
@ -337,7 +337,7 @@ impl Link for VolumeMounting {
|
||||
{
|
||||
let block = this
|
||||
.pos
|
||||
.get_block(&terrain_grid, &uid_allocator, &colliders)
|
||||
.get_block(terrain_grid, uid_allocator, colliders)
|
||||
.ok_or(MountingError::NoSuchEntity)?;
|
||||
|
||||
if block == this.block {
|
||||
@ -363,7 +363,7 @@ impl Link for VolumeMounting {
|
||||
terrain_grid,
|
||||
uid_allocator,
|
||||
colliders,
|
||||
): Self::PersistData<'_>,
|
||||
): &mut Self::PersistData<'_>,
|
||||
) -> bool {
|
||||
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into());
|
||||
let is_alive =
|
||||
@ -387,7 +387,7 @@ impl Link for VolumeMounting {
|
||||
|
||||
let block_exists = this
|
||||
.pos
|
||||
.get_block(&terrain_grid, &uid_allocator, &colliders)
|
||||
.get_block(terrain_grid, uid_allocator, colliders)
|
||||
.map_or(false, |block| block == this.block);
|
||||
|
||||
rider_exists && mount_spot_exists && block_exists
|
||||
@ -395,12 +395,12 @@ impl Link for VolumeMounting {
|
||||
|
||||
fn delete(
|
||||
this: &LinkHandle<Self>,
|
||||
(mut terrain_riders, mut volume_riders, mut is_rider, uid_allocator): Self::DeleteData<'_>,
|
||||
(terrain_riders, volume_riders, is_rider, uid_allocator): &mut Self::DeleteData<'_>,
|
||||
) {
|
||||
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into());
|
||||
|
||||
let riders = match this.pos.kind {
|
||||
Volume::Terrain => Some(&mut *terrain_riders),
|
||||
Volume::Terrain => Some(&mut **terrain_riders),
|
||||
Volume::Entity(uid) => {
|
||||
entity(uid).and_then(|entity| volume_riders.get_mut_or_default(entity))
|
||||
},
|
||||
|
@ -1074,7 +1074,7 @@ impl StateExt for State {
|
||||
fn link<L: Link>(&mut self, link: L) -> Result<(), L::Error> {
|
||||
let linker = LinkHandle::from_link(link);
|
||||
|
||||
L::create(&linker, self.ecs().system_data())?;
|
||||
L::create(&linker, &mut self.ecs().system_data())?;
|
||||
|
||||
self.ecs_mut()
|
||||
.entry::<Vec<LinkHandle<L>>>()
|
||||
@ -1087,11 +1087,18 @@ impl StateExt for State {
|
||||
fn maintain_links(&mut self) {
|
||||
fn maintain_link<L: Link>(state: &State) {
|
||||
if let Some(mut handles) = state.ecs().try_fetch_mut::<Vec<LinkHandle<L>>>() {
|
||||
let mut persist_data = None;
|
||||
handles.retain(|link| {
|
||||
if L::persist(link, state.ecs().system_data()) {
|
||||
if L::persist(
|
||||
link,
|
||||
persist_data.get_or_insert_with(|| state.ecs().system_data()),
|
||||
) {
|
||||
true
|
||||
} else {
|
||||
L::delete(link, state.ecs().system_data());
|
||||
// Make sure to drop persist data before running deletion to avoid potential
|
||||
// access violations
|
||||
persist_data.take();
|
||||
L::delete(link, &mut state.ecs().system_data());
|
||||
false
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user