Skip to content

Commit

Permalink
Update Bevy
Browse files Browse the repository at this point in the history
  • Loading branch information
Suficio committed Nov 3, 2022
1 parent 2044a02 commit e7012cb
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 119 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ members = ["crates/*"]

[workspace.dependencies]
# TODO(https://github.com/bevyengine/bevy/pull/6121) Detached non-Send tasks don't run
bevy = { git = "https://github.com/Suficio/bevy.git", branch = "query-state-with-state" }
bevy = { git = "https://github.com/Suficio/bevy.git", branch = "js-prototype" }
deno_core = "0.155.0"

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy_js::{self as bjs, runtimes::BevyRuntime};
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_plugin(LogPlugin)
.add_plugin(LogPlugin::default())
.add_plugin(bjs::JsPlugin::<BevyRuntime>::default())
.add_startup_system(setup_runtime)
.run();
Expand Down
2 changes: 1 addition & 1 deletion examples/startup_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use bevy_js::{self as bjs, runtimes::BevyRuntime};
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_plugin(LogPlugin)
.add_plugin(LogPlugin::default())
.add_plugin(bjs::JsPlugin::<BevyRuntime>::default())
.add_startup_system(setup_runtime)
.run();
Expand Down
105 changes: 38 additions & 67 deletions src/query/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use bevy::{
ecs::{
archetype::{Archetype, ArchetypeComponentId},
component::{ComponentId, StorageType},
query::{Access, FilteredAccess, ReadOnlyWorldQuery, WorldQuery, WorldQueryGats},
storage::{ComponentSparseSet, Table, Tables},
query::{Access, FilteredAccess, ReadOnlyWorldQuery, WorldQuery},
storage::{ComponentSparseSet, Table},
},
prelude::*,
ptr::{Ptr, ThinSlicePtr},
ptr::Ptr,
};

/// Type used to query non-dense components
Expand All @@ -18,23 +18,15 @@ pub struct ReadFetchSparse<'w> {
storage_type: StorageType,
component_size: usize,

// T::Storage = TableStorage
table_components: Option<Ptr<'w>>,
entity_table_rows: Option<ThinSlicePtr<'w, usize>>,

// T::Storage = SparseStorage
entities: Option<ThinSlicePtr<'w, Entity>>,
sparse_set: Option<&'w ComponentSparseSet>,
}

impl<'w> WorldQueryGats<'w> for &ComponentPtr {
type Item = Ptr<'w>;
type Fetch = ReadFetchSparse<'w>;
}

unsafe impl ReadOnlyWorldQuery for &ComponentPtr {}

unsafe impl WorldQuery for &ComponentPtr {
type Fetch<'w> = ReadFetchSparse<'w>;
type Item<'w> = Ptr<'w>;
type ReadOnly = Self;
type State = ComponentId;

Expand All @@ -47,7 +39,7 @@ unsafe impl WorldQuery for &ComponentPtr {
&component_id: &ComponentId,
_last_change_tick: u32,
_change_tick: u32,
) -> <Self as WorldQueryGats<'w>>::Fetch {
) -> ReadFetchSparse<'w> {
let component_info = world.components().get_info(component_id).unwrap();
let storage_type = component_info.storage_type();

Expand All @@ -56,85 +48,64 @@ unsafe impl WorldQuery for &ComponentPtr {
component_size: component_info.layout().size(),

table_components: None,
entity_table_rows: None,

entities: None,
sparse_set: (storage_type == StorageType::SparseSet)
.then(|| world.storages().sparse_sets.get(component_id).unwrap()),
}
}

unsafe fn clone_fetch<'w>(fetch: &Self::Fetch<'w>) -> Self::Fetch<'w> {
ReadFetchSparse {
storage_type: fetch.storage_type,
component_size: fetch.component_size,

table_components: fetch.table_components,
sparse_set: fetch.sparse_set,
}
}

const IS_DENSE: bool = false;
const IS_ARCHETYPAL: bool = true;

#[inline]
unsafe fn set_archetype<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
&component_id: &ComponentId,
archetype: &'w Archetype,
tables: &'w Tables,
fetch: &mut ReadFetchSparse<'w>,
component_id: &ComponentId,
_archetype: &'w Archetype,
table: &'w Table,
) {
match fetch.storage_type {
StorageType::Table => {
fetch.entity_table_rows = Some(archetype.entity_table_rows().into());
let column = tables[archetype.table_id()]
.get_column(component_id)
.unwrap();
fetch.table_components = Some(column.get_data_ptr());
}
StorageType::SparseSet => fetch.entities = Some(archetype.entities().into()),
if fetch.storage_type == StorageType::Table {
Self::set_table(fetch, component_id, table);
}
}

#[inline]
unsafe fn set_table<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
fetch: &mut ReadFetchSparse<'w>,
&component_id: &ComponentId,
table: &'w Table,
) {
fetch.table_components = Some(table.get_column(component_id).unwrap().get_data_ptr());
}

#[inline]
unsafe fn archetype_fetch<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
archetype_index: usize,
) -> <Self as WorldQueryGats<'w>>::Item {
#[inline(always)]
unsafe fn fetch<'w>(
fetch: &mut Self::Fetch<'w>,
entity: Entity,
table_row: usize,
) -> Self::Item<'w> {
match fetch.storage_type {
StorageType::Table => {
let (entity_table_rows, table_components) = fetch
.entity_table_rows
.zip(fetch.table_components)
.unwrap_or_else(|| debug_checked_unreachable());

let table_row = *entity_table_rows.get(archetype_index);
table_components.byte_add(table_row * fetch.component_size)
}
StorageType::SparseSet => {
let (entities, sparse_set) = fetch
.entities
.zip(fetch.sparse_set)
.unwrap_or_else(|| debug_checked_unreachable());

let entity = *entities.get(archetype_index);
sparse_set
.get(entity)
.unwrap_or_else(|| debug_checked_unreachable())
}
StorageType::Table => fetch
.table_components
.unwrap_or_else(|| debug_checked_unreachable())
.byte_add(table_row * fetch.component_size),
StorageType::SparseSet => fetch
.sparse_set
.unwrap_or_else(|| debug_checked_unreachable())
.get(entity)
.unwrap_or_else(|| debug_checked_unreachable()),
}
}

#[inline]
unsafe fn table_fetch<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row: usize,
) -> <Self as WorldQueryGats<'w>>::Item {
let components = fetch
.table_components
.unwrap_or_else(|| debug_checked_unreachable());
components.byte_add(table_row * fetch.component_size)
}

fn update_component_access(
&component_id: &ComponentId,
access: &mut FilteredAccess<ComponentId>,
Expand Down
71 changes: 22 additions & 49 deletions src/query/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ use bevy::{
ecs::{
archetype::{Archetype, ArchetypeComponentId},
component::ComponentId,
query::{
Access, FilteredAccess, QueryItem, ReadOnlyWorldQuery, WorldQuery, WorldQueryGats,
},
storage::{Table, Tables},
query::{Access, FilteredAccess, QueryItem, ReadOnlyWorldQuery, WorldQuery},
storage::Table,
},
prelude::*,
};
Expand All @@ -17,21 +15,15 @@ pub struct VecPtr<T> {
_phantom: PhantomData<T>,
}

impl<'w, T> WorldQueryGats<'w> for VecPtr<T>
where
T: WorldQueryGats<'w>,
{
type Item = Vec<T::Item>;
type Fetch = Vec<T::Fetch>;
}

/// SAFETY: each item in the vec is read only
unsafe impl<T> ReadOnlyWorldQuery for VecPtr<T> where T: ReadOnlyWorldQuery {}

unsafe impl<T> WorldQuery for VecPtr<T>
where
T: WorldQuery,
{
type Fetch<'w> = Vec<T::Fetch<'w>>;
type Item<'w> = Vec<T::Item<'w>>;
type ReadOnly = VecPtr<T::ReadOnly>;
type State = Vec<T::State>;

Expand All @@ -47,75 +39,56 @@ where
state: &Vec<T::State>,
last_change_tick: u32,
change_tick: u32,
) -> <Self as WorldQueryGats<'w>>::Fetch {
) -> Self::Fetch<'w> {
state
.iter()
.map(|state| T::init_fetch(world, state, last_change_tick, change_tick))
.collect()
}

unsafe fn clone_fetch<'w>(fetch: &Self::Fetch<'w>) -> Self::Fetch<'w> {
fetch.into_iter().map(|item| T::clone_fetch(item)).collect()
}

#[inline]
unsafe fn set_archetype<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
fetch: &mut Self::Fetch<'w>,
state: &Vec<T::State>,
archetype: &'w Archetype,
tables: &'w Tables,
table: &'w Table,
) {
for (fetch, state) in fetch.iter_mut().zip(state.iter()) {
T::set_archetype(fetch, state, archetype, tables)
T::set_archetype(fetch, state, archetype, table)
}
}

#[inline]
unsafe fn set_table<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
state: &Self::State,
table: &'w Table,
) {
unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
for (fetch, state) in fetch.iter_mut().zip(state.iter()) {
T::set_table(fetch, state, table)
}
}

#[inline]
unsafe fn archetype_fetch<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
archetype_index: usize,
) -> <Self as WorldQueryGats<'w>>::Item {
fetch
.iter_mut()
.map(|fetch| T::archetype_fetch(fetch, archetype_index))
.collect()
}

#[inline]
unsafe fn table_fetch<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
unsafe fn fetch<'w>(
fetch: &mut Self::Fetch<'w>,
entity: Entity,
table_row: usize,
) -> <Self as WorldQueryGats<'w>>::Item {
) -> Self::Item<'w> {
fetch
.iter_mut()
.map(|fetch| T::archetype_fetch(fetch, table_row))
.map(|fetch| T::fetch(fetch, entity, table_row))
.collect()
}

#[inline]
unsafe fn table_filter_fetch(
fetch: &mut <Self as WorldQueryGats<'_>>::Fetch,
unsafe fn filter_fetch<'w>(
fetch: &mut Self::Fetch<'w>,
entity: Entity,
table_row: usize,
) -> bool {
fetch.iter_mut().fold(true, |fold, fetch| {
fold && T::table_filter_fetch(fetch, table_row)
})
}

#[inline]
unsafe fn archetype_filter_fetch(
fetch: &mut <Self as WorldQueryGats<'_>>::Fetch,
archetype_index: usize,
) -> bool {
fetch.iter_mut().fold(true, |fold, fetch| {
fold && T::archetype_filter_fetch(fetch, archetype_index)
fold && T::filter_fetch(fetch, entity, table_row)
})
}

Expand Down

0 comments on commit e7012cb

Please sign in to comment.