Fix a painful amount of compiler warnings, and clippy warnings

This commit is contained in:
SeanOMik 2023-12-27 22:53:58 -05:00
parent 09bba5b3b3
commit 10fc7842cf
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
33 changed files with 206 additions and 233 deletions

View File

@ -29,6 +29,7 @@ impl Default for FreeFlyCamera {
} }
impl FreeFlyCamera { impl FreeFlyCamera {
#[allow(dead_code)]
pub fn new(speed: f32, slow_speed_factor: f32, look_speed: f32, mouse_sensitivity: f32, look_with_keys: bool) -> Self { pub fn new(speed: f32, slow_speed_factor: f32, look_speed: f32, mouse_sensitivity: f32, look_with_keys: bool) -> Self {
Self { Self {
speed, speed,
@ -83,8 +84,8 @@ impl System for FreeFlyCameraPlugin {
} }
} }
for (mut cam, mut fly) in world for (mut cam, fly) in world
.view_iter::<(&mut CameraComponent, &mut FreeFlyCamera)>() .view_iter::<(&mut CameraComponent, &FreeFlyCamera)>()
{ {
let forward = cam.transform.forward(); let forward = cam.transform.forward();
let left = cam.transform.left(); let left = cam.transform.left();

View File

@ -1,6 +1,6 @@
use std::ptr::NonNull; use std::ptr::NonNull;
use lyra_engine::{math::{self, Vec3}, math::Transform, input::{KeyCode, InputButtons, MouseMotion, ActionHandler, Layout, Action, ActionKind, LayoutId, ActionMapping, Binding, ActionSource, ActionMappingId, InputActionPlugin, ActionState}, game::Game, plugin::Plugin, render::{window::{CursorGrabMode, WindowOptions}, light::{PointLight, directional::DirectionalLight, SpotLight}}, change_tracker::Ct, ecs::{system::{Criteria, CriteriaSchedule, BatchedSystem, IntoSystem}, world::World, Component}, DeltaTime, scene::{TransformComponent, ModelComponent, CameraComponent}}; use lyra_engine::{math::{self, Vec3}, math::Transform, input::{KeyCode, ActionHandler, Action, ActionKind, LayoutId, ActionMapping, ActionSource, ActionMappingId, InputActionPlugin}, game::Game, render::{window::{CursorGrabMode, WindowOptions}, light::{PointLight, directional::DirectionalLight, SpotLight}}, change_tracker::Ct, ecs::{system::{Criteria, CriteriaSchedule, BatchedSystem, IntoSystem}, world::World, Component}, DeltaTime, scene::{TransformComponent, ModelComponent, CameraComponent}};
use lyra_engine::assets::{ResourceManager, Model}; use lyra_engine::assets::{ResourceManager, Model};
mod free_fly_camera; mod free_fly_camera;
@ -86,7 +86,7 @@ async fn main() {
)); ));
{ {
let mut cube_tran = Transform::from_xyz(-3.5, 0.0, -8.0); let cube_tran = Transform::from_xyz(-3.5, 0.0, -8.0);
//cube_tran.rotate_y(math::Angle::Degrees(180.0)); //cube_tran.rotate_y(math::Angle::Degrees(180.0));
world.spawn(( world.spawn((
TransformComponent::from(cube_tran), TransformComponent::from(cube_tran),

View File

@ -28,17 +28,6 @@ impl Drop for ComponentColumn {
#[allow(dead_code)] #[allow(dead_code)]
impl ComponentColumn { impl ComponentColumn {
/// Creates an invalid component column. Do not attempt to use it.
/* pub unsafe fn dangling() -> Self {
ComponentColumn {
data: RefCell::
capacity: 0,
info: ComponentInfo::new::<()>(),
entry_size: 0,
len: 0,
}
} */
pub unsafe fn alloc(component_layout: Layout, capacity: usize) -> NonNull<u8> { pub unsafe fn alloc(component_layout: Layout, capacity: usize) -> NonNull<u8> {
let new_layout = Layout::from_size_align( let new_layout = Layout::from_size_align(
component_layout.size().checked_mul(capacity).unwrap(), component_layout.size().checked_mul(capacity).unwrap(),
@ -53,7 +42,7 @@ impl ComponentColumn {
} }
pub unsafe fn new(info: ComponentInfo, capacity: usize) -> Self { pub unsafe fn new(info: ComponentInfo, capacity: usize) -> Self {
let data = ComponentColumn::alloc(info.layout.into_layout_unchecked(), capacity); let data = ComponentColumn::alloc(info.layout.into_layout().unwrap(), capacity);
Self { Self {
data: RefCell::new(data), data: RefCell::new(data),
@ -69,7 +58,7 @@ impl ComponentColumn {
/// # Safety /// # Safety
/// ///
/// This column must have space to fit the component, if it does not have room it will panic. /// This column must have space to fit the component, if it does not have room it will panic.
pub unsafe fn set_at(&mut self, entity_index: usize, comp_src: NonNull<u8>, tick: Tick) { pub unsafe fn set_at(&mut self, entity_index: usize, comp_src: NonNull<u8>, is_dynamic: bool, tick: Tick) {
assert!(entity_index < self.capacity); assert!(entity_index < self.capacity);
let mut data = self.data.borrow_mut(); let mut data = self.data.borrow_mut();
@ -78,9 +67,11 @@ impl ComponentColumn {
let dest = NonNull::new_unchecked(data.as_ptr().add(entity_index * self.info.layout.size)); let dest = NonNull::new_unchecked(data.as_ptr().add(entity_index * self.info.layout.size));
ptr::copy_nonoverlapping(comp_src.as_ptr(), dest.as_ptr(), self.info.layout.size); ptr::copy_nonoverlapping(comp_src.as_ptr(), dest.as_ptr(), self.info.layout.size);
unsafe { if is_dynamic {
let layout = self.info.layout.into_layout_unchecked(); unsafe {
//std::alloc::dealloc(comp_src.as_ptr(), layout); let layout = self.info.layout.into_layout().unwrap();
std::alloc::dealloc(comp_src.as_ptr(), layout);
}
} }
// check if a component spot is being set twice and that the entity's tick is // check if a component spot is being set twice and that the entity's tick is
@ -113,7 +104,7 @@ impl ComponentColumn {
/// ///
/// This column must have the entity. /// This column must have the entity.
pub unsafe fn get_mut<T>(&mut self, entity_index: usize, tick: &Tick) -> &mut T { pub unsafe fn get_mut<T>(&mut self, entity_index: usize, tick: &Tick) -> &mut T {
self.entity_ticks[entity_index].tick_to(&tick); self.entity_ticks[entity_index].tick_to(tick);
let mut data = self.data.borrow_mut(); let mut data = self.data.borrow_mut();
let data = data.deref_mut(); let data = data.deref_mut();
@ -139,7 +130,7 @@ impl ComponentColumn {
let mut data = self.data.borrow_mut(); let mut data = self.data.borrow_mut();
let mut new_ptr = Self::alloc(self.info.layout.into_layout_unchecked(), new_capacity); let mut new_ptr = Self::alloc(self.info.layout.into_layout().unwrap(), new_capacity);
if self.len > 0 { if self.len > 0 {
ptr::copy_nonoverlapping(data.as_ptr(), new_ptr.as_ptr(), self.len * self.info.layout.size); ptr::copy_nonoverlapping(data.as_ptr(), new_ptr.as_ptr(), self.len * self.info.layout.size);
@ -163,7 +154,7 @@ impl ComponentColumn {
/// Removes a component from the column, freeing it, and returning the old index of the entity that took its place in the column. /// Removes a component from the column, freeing it, and returning the old index of the entity that took its place in the column.
pub unsafe fn remove_component(&mut self, entity_index: usize, tick: &Tick) -> Option<usize> { pub unsafe fn remove_component(&mut self, entity_index: usize, tick: &Tick) -> Option<usize> {
//self.entity_ticks[entity_index].tick_to(&tick); let _ = tick; // may be used at some point
let mut data = self.data.borrow_mut(); let mut data = self.data.borrow_mut();
let data = data.deref_mut(); let data = data.deref_mut();
@ -192,19 +183,19 @@ impl ComponentColumn {
moved_index moved_index
} }
pub fn borrow_ptr<'a>(&'a self) -> Ref<'a, NonNull<u8>> { pub fn borrow_ptr(&self) -> Ref<NonNull<u8>> {
self.data.borrow() self.data.borrow()
} }
pub fn borrow_mut_ptr<'a>(&'a self) -> RefMut<'a, NonNull<u8>> { pub fn borrow_mut_ptr(&self) -> RefMut<NonNull<u8>> {
self.data.borrow_mut() self.data.borrow_mut()
} }
pub fn try_borrow_ptr<'a>(&'a self) -> Result<Ref<'a, NonNull<u8>>, BorrowError> { pub fn try_borrow_ptr(&self) -> Result<Ref<NonNull<u8>>, BorrowError> {
self.data.try_borrow() self.data.try_borrow()
} }
pub fn try_borrow_mut_ptr<'a>(&'a self) -> Result<RefMut<'a, NonNull<u8>>, BorrowMutError> { pub fn try_borrow_mut_ptr(&self) -> Result<RefMut<NonNull<u8>>, BorrowMutError> {
self.data.try_borrow_mut() self.data.try_borrow_mut()
} }
} }
@ -264,10 +255,11 @@ impl Archetype {
let entity_index = self.entities.len(); let entity_index = self.entities.len();
self.entities.insert(entity, ArchetypeEntityId(entity_index as u64)); self.entities.insert(entity, ArchetypeEntityId(entity_index as u64));
let is_dynamic = bundle.is_dynamic();
bundle.take(|data, type_id, _size| { bundle.take(|data, type_id, _size| {
let col = self.get_column_mut(type_id).unwrap(); let col = self.get_column_mut(type_id).unwrap();
unsafe { col.set_at(entity_index, data, tick.clone()); } unsafe { col.set_at(entity_index, data, is_dynamic, *tick); }
col.len += 1; col.len += 1;
}); });
@ -425,7 +417,7 @@ mod tests {
use rand::Rng; use rand::Rng;
use crate::{ArchetypeId, tests::{Vec2, Vec3}, world::{Entity, EntityId}, bundle::Bundle, ComponentInfo, MemoryLayout, DynTypeId, DynamicBundle, Tick}; use crate::{tests::{Vec2, Vec3}, world::{Entity, EntityId}, bundle::Bundle, ComponentInfo, MemoryLayout, DynTypeId, DynamicBundle, Tick};
use super::Archetype; use super::Archetype;

View File

@ -1,4 +1,4 @@
use std::{any::{TypeId, Any}, ptr::NonNull, mem::size_of, alloc::Layout}; use std::{ptr::NonNull, mem::size_of, alloc::Layout};
use crate::{component::Component, component_info::ComponentInfo, DynTypeId}; use crate::{component::Component, component_info::ComponentInfo, DynTypeId};
@ -12,6 +12,9 @@ pub trait Bundle {
/// Take the bundle by calling the closure with pointers to each component, its type and size. /// Take the bundle by calling the closure with pointers to each component, its type and size.
/// The closure is expected to take ownership of the pointer. /// The closure is expected to take ownership of the pointer.
fn take(self, f: impl FnMut(NonNull<u8>, DynTypeId, usize)); fn take(self, f: impl FnMut(NonNull<u8>, DynTypeId, usize));
/// Returns a boolean indicating if this Bundle is dynamic. See [`DynamicBundle`]
fn is_dynamic(&self) -> bool;
} }
// The macro below can implement this for us, but this is here for development // The macro below can implement this for us, but this is here for development
@ -29,6 +32,10 @@ impl<C1: Component> Bundle for (C1,) {
f(NonNull::from(&c1).cast(), DynTypeId::of::<C1>(), size_of::<C1>()); f(NonNull::from(&c1).cast(), DynTypeId::of::<C1>(), size_of::<C1>());
} }
fn is_dynamic(&self) -> bool {
false
}
} }
macro_rules! impl_bundle_tuple { macro_rules! impl_bundle_tuple {
@ -50,6 +57,10 @@ macro_rules! impl_bundle_tuple {
$(f(NonNull::from(&$name).cast(), DynTypeId::of::<$name>(), size_of::<$name>());)+ $(f(NonNull::from(&$name).cast(), DynTypeId::of::<$name>(), size_of::<$name>());)+
} }
fn is_dynamic(&self) -> bool {
false
}
} }
); );
} }
@ -87,6 +98,10 @@ impl DynamicBundle {
Self::default() Self::default()
} }
pub fn is_empty(&self) -> bool {
self.bundle.len() == 0
}
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.bundle.len() self.bundle.len()
} }
@ -125,12 +140,16 @@ impl Bundle for DynamicBundle {
} }
fn info(&self) -> Vec<ComponentInfo> { fn info(&self) -> Vec<ComponentInfo> {
self.bundle.iter().map(|b| b.1.clone()).collect() self.bundle.iter().map(|b| b.1).collect()
} }
fn take(self, mut f: impl FnMut(NonNull<u8>, DynTypeId, usize)) { fn take(self, mut f: impl FnMut(NonNull<u8>, DynTypeId, usize)) {
for (data, info) in self.bundle.iter() { for (data, info) in self.bundle.iter() {
f(data.clone(), info.type_id, info.layout.size); f(*data, info.type_id, info.layout.size);
} }
} }
fn is_dynamic(&self) -> bool {
true
}
} }

View File

@ -1,4 +1,4 @@
use std::{any::{TypeId, type_name}, alloc::{Layout, LayoutError}}; use std::{any::TypeId, alloc::{Layout, LayoutError}};
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MemoryLayout { pub struct MemoryLayout {
@ -31,8 +31,9 @@ impl MemoryLayout {
} }
} }
pub unsafe fn into_layout_unchecked(self) -> Layout { /// Converts self into a Layout.
Layout::from_size_align_unchecked(self.size, self.alignment) pub fn into_layout(self) -> Result<Layout, LayoutError> {
Layout::from_size_align(self.size, self.alignment)
} }
} }
@ -43,15 +44,15 @@ pub enum DynTypeId {
Unknown(u128), Unknown(u128),
} }
impl Into<DynTypeId> for u128 { impl From<u128> for DynTypeId {
fn into(self) -> DynTypeId { fn from(val: u128) -> Self {
DynTypeId::Unknown(self) DynTypeId::Unknown(val)
} }
} }
impl Into<DynTypeId> for TypeId { impl From<TypeId> for DynTypeId {
fn into(self) -> DynTypeId { fn from(val: TypeId) -> Self {
DynTypeId::Rust(self) DynTypeId::Rust(val)
} }
} }
@ -68,7 +69,7 @@ impl DynTypeId {
pub fn is<T: 'static>(&self) -> bool { pub fn is<T: 'static>(&self) -> bool {
match self { match self {
DynTypeId::Rust(tyid) => tyid.clone() == TypeId::of::<T>(), DynTypeId::Rust(tyid) => *tyid == TypeId::of::<T>(),
DynTypeId::Unknown(_) => false, DynTypeId::Unknown(_) => false,
} }
} }
@ -81,7 +82,7 @@ impl DynTypeId {
/// Force self into a rust TypeId, will panic if this type is not a Rust type. /// Force self into a rust TypeId, will panic if this type is not a Rust type.
pub fn as_rust(&self) -> TypeId { pub fn as_rust(&self) -> TypeId {
match self { match self {
DynTypeId::Rust(t) => t.clone(), DynTypeId::Rust(t) => *t,
DynTypeId::Unknown(_) => panic!("This type is unknown to rust, cannot construct a TypeId from it!"), DynTypeId::Unknown(_) => panic!("This type is unknown to rust, cannot construct a TypeId from it!"),
} }
} }
@ -108,6 +109,7 @@ impl ComponentInfo {
where where
D: Into<DynTypeId>, D: Into<DynTypeId>,
{ {
let _ = name; // would be used at some point
Self { Self {
type_id: type_id.into(), type_id: type_id.into(),
//name: name.to_string(), //name: name.to_string(),

View File

@ -1,8 +1,6 @@
use crate::world::World;
extern crate self as lyra_ecs; extern crate self as lyra_ecs;
//mod lyra_ecs { pub use super::*; }
#[allow(unused_imports)]
pub(crate) mod lyra_engine { pub(crate) mod lyra_engine {
pub(crate) mod ecs { pub(crate) mod ecs {
pub use super::super::*; pub use super::super::*;

View File

@ -1,4 +1,4 @@
use std::{marker::PhantomData, any::TypeId, ptr::NonNull, cell::{Ref, RefCell, RefMut}}; use std::{marker::PhantomData, ptr::NonNull, cell::{Ref, RefMut}};
use crate::{world::World, ComponentColumn, DynTypeId, Tick}; use crate::{world::World, ComponentColumn, DynTypeId, Tick};
@ -45,6 +45,15 @@ pub struct QueryBorrow<T> {
_phantom: PhantomData<T> _phantom: PhantomData<T>
} }
impl<T: 'static> Default for QueryBorrow<T> {
fn default() -> Self {
Self {
type_id: DynTypeId::of::<T>(),
_phantom: PhantomData,
}
}
}
impl<T> Copy for QueryBorrow<T> {} impl<T> Copy for QueryBorrow<T> {}
impl<T> Clone for QueryBorrow<T> { impl<T> Clone for QueryBorrow<T> {
@ -55,10 +64,7 @@ impl<T> Clone for QueryBorrow<T> {
impl<T: 'static> QueryBorrow<T> { impl<T: 'static> QueryBorrow<T> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
type_id: DynTypeId::of::<T>(),
_phantom: PhantomData,
}
} }
} }
@ -79,6 +85,7 @@ where
} }
unsafe fn fetch<'a>(&self, _world: &'a World, archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> { unsafe fn fetch<'a>(&self, _world: &'a World, archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
let _ = tick;
let col = archetype.columns.iter().find(|c| c.info.type_id == self.type_id) let col = archetype.columns.iter().find(|c| c.info.type_id == self.type_id)
.expect("You ignored 'can_visit_archetype'!"); .expect("You ignored 'can_visit_archetype'!");
@ -143,6 +150,15 @@ pub struct QueryBorrowMut<T> {
_phantom: PhantomData<T> _phantom: PhantomData<T>
} }
impl<T: 'static> Default for QueryBorrowMut<T> {
fn default() -> Self {
Self {
type_id: DynTypeId::of::<T>(),
_phantom: PhantomData,
}
}
}
impl<T> Copy for QueryBorrowMut<T> {} impl<T> Copy for QueryBorrowMut<T> {}
impl<T> Clone for QueryBorrowMut<T> { impl<T> Clone for QueryBorrowMut<T> {
@ -153,10 +169,7 @@ impl<T> Clone for QueryBorrowMut<T> {
impl<T: 'static> QueryBorrowMut<T> { impl<T: 'static> QueryBorrowMut<T> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
type_id: DynTypeId::of::<T>(),
_phantom: PhantomData,
}
} }
} }
@ -182,13 +195,13 @@ where
let col = archetype.columns.iter().find(|c| c.info.type_id == self.type_id) let col = archetype.columns.iter().find(|c| c.info.type_id == self.type_id)
.expect("You ignored 'can_visit_archetype'!"); .expect("You ignored 'can_visit_archetype'!");
let layout_size = col.info.layout.size; let layout_size = col.info.layout.size;
let mut col = NonNull::from(col); let col = NonNull::from(col);
// TODO: find a way to get the component column mutable with a borrowed archetype so its tick can be updated. // TODO: find a way to get the component column mutable with a borrowed archetype so its tick can be updated.
// the fetcher needs to tick the entities tick in the archetype // the fetcher needs to tick the entities tick in the archetype
FetchBorrowMut { FetchBorrowMut {
col: NonNull::from(col), col,
size: layout_size, size: layout_size,
tick, tick,
_phantom: PhantomData, _phantom: PhantomData,
@ -206,7 +219,7 @@ impl<T: 'static> AsQuery for &mut T {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{any::TypeId, mem::size_of, marker::PhantomData, ptr::NonNull}; use std::{mem::size_of, marker::PhantomData, ptr::NonNull};
use crate::{world::{World, Entity, EntityId}, archetype::{Archetype, ArchetypeId}, query::{View, Fetch}, tests::Vec2, bundle::Bundle, DynTypeId, Tick}; use crate::{world::{World, Entity, EntityId}, archetype::{Archetype, ArchetypeId}, query::{View, Fetch}, tests::Vec2, bundle::Bundle, DynTypeId, Tick};

View File

@ -1,4 +1,4 @@
use std::{ptr::NonNull, cell::Ref}; use std::ptr::NonNull;
use crate::{world::World, ComponentColumn, ComponentInfo}; use crate::{world::World, ComponentColumn, ComponentInfo};

View File

@ -83,7 +83,7 @@ impl<'a> Iterator for DynamicViewIter<'a> {
self.next_archetype += 1; self.next_archetype += 1;
let arch = unsafe { self.archetypes.get_unchecked(arch_id) }; let arch = unsafe { self.archetypes.get_unchecked(arch_id) };
if arch.entities.len() == 0 { if arch.entities.is_empty() {
continue; continue;
} }

View File

@ -1,4 +1,4 @@
use crate::{world::{Entity, World}, archetype::{Archetype, ArchetypeId}}; use crate::{world::{Entity, World}, archetype::Archetype};
use super::{Fetch, Query, AsQuery}; use super::{Fetch, Query, AsQuery};

View File

@ -1,4 +1,4 @@
use crate::{archetype::{Archetype, ArchetypeId}, world::{ArchetypeEntityId, World}, Tick}; use crate::{archetype::Archetype, world::{ArchetypeEntityId, World}, Tick};
pub mod view; pub mod view;
pub use view::*; pub use view::*;
@ -66,9 +66,7 @@ pub trait Query: Copy {
unsafe fn fetch<'a>(&self, world: &'a World, archetype: &'a Archetype, tick: Tick) -> Self::Fetch<'a>; unsafe fn fetch<'a>(&self, world: &'a World, archetype: &'a Archetype, tick: Tick) -> Self::Fetch<'a>;
/// Attempt to fetch only from the world. /// Returns a fetcher that doesn't fetch from an archetype.
///
/// This is used in [`QueryResource`].
unsafe fn fetch_world<'a>(&self, world: &'a World) -> Option<Self::Fetch<'a>> { unsafe fn fetch_world<'a>(&self, world: &'a World) -> Option<Self::Fetch<'a>> {
let _ = world; let _ = world;
None None

View File

@ -1,4 +1,4 @@
use std::{marker::PhantomData, any::TypeId, ptr::NonNull, cell::{Ref, RefMut}}; use std::{marker::PhantomData, cell::{Ref, RefMut}};
use crate::{world::World, resource::ResourceObject}; use crate::{world::World, resource::ResourceObject};
@ -62,6 +62,7 @@ impl<T: ResourceObject + 'static> Query for QueryResource<T> {
} }
unsafe fn fetch<'a>(&self, world: &'a World, _archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> { unsafe fn fetch<'a>(&self, world: &'a World, _archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
let _ = tick;
self.fetch_world(world).unwrap() self.fetch_world(world).unwrap()
} }
@ -136,6 +137,7 @@ impl<T: ResourceObject + 'static> Query for QueryResourceMut<T> {
} }
unsafe fn fetch<'a>(&self, world: &'a World, _archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> { unsafe fn fetch<'a>(&self, world: &'a World, _archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
let _ = tick;
self.fetch_world(world).unwrap() self.fetch_world(world).unwrap()
} }

View File

@ -52,6 +52,15 @@ pub struct QueryTickOf<T> {
_phantom: PhantomData<T> _phantom: PhantomData<T>
} }
impl<T: 'static> Default for QueryTickOf<T> {
fn default() -> Self {
Self {
type_id: DynTypeId::of::<T>(),
_phantom: PhantomData,
}
}
}
// manually implemented to avoid a Copy bound on T // manually implemented to avoid a Copy bound on T
impl<T> Copy for QueryTickOf<T> {} impl<T> Copy for QueryTickOf<T> {}
@ -64,10 +73,7 @@ impl<T> Clone for QueryTickOf<T> {
impl<T: 'static> QueryTickOf<T> { impl<T: 'static> QueryTickOf<T> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
type_id: DynTypeId::of::<T>(),
_phantom: PhantomData,
}
} }
} }

View File

@ -1,6 +1,6 @@
use std::ops::Range; use std::ops::Range;
use crate::{archetype::{Archetype, ArchetypeId}, world::{ArchetypeEntityId, World}, EntityId, TickTracker, Tick}; use crate::{archetype::Archetype, world::{ArchetypeEntityId, World}, EntityId, Tick};
use super::{Query, Fetch}; use super::{Query, Fetch};
@ -96,7 +96,7 @@ where
self.next_archetype += 1; self.next_archetype += 1;
let arch = unsafe { self.archetypes.get_unchecked(arch_id) }; let arch = unsafe { self.archetypes.get_unchecked(arch_id) };
if arch.entities.len() == 0 { if arch.entities.is_empty() {
continue; continue;
} }

View File

@ -1,4 +1,4 @@
use std::{any::{TypeId, Any}, alloc::Layout, cell::{RefCell, Ref, RefMut}, ptr::NonNull, alloc}; use std::{any::{TypeId, Any}, cell::{RefCell, Ref, RefMut}};
/// Shorthand for `Send + Sync + 'static`, so it never needs to be implemented manually. /// Shorthand for `Send + Sync + 'static`, so it never needs to be implemented manually.
pub trait ResourceObject: Send + Sync + 'static {} pub trait ResourceObject: Send + Sync + 'static {}
@ -30,7 +30,7 @@ impl ResourceData {
/// ///
/// * If the data is already borrowed mutably, this will panic. /// * If the data is already borrowed mutably, this will panic.
/// * If the type of `T` is not the same as the resource type. /// * If the type of `T` is not the same as the resource type.
pub fn get<'a, T: 'static>(&'a self) -> Ref<'a, T> { pub fn get<T: 'static>(&self) -> Ref<T> {
Ref::map(self.data.borrow(), |a| a.downcast_ref().unwrap()) Ref::map(self.data.borrow(), |a| a.downcast_ref().unwrap())
} }
@ -40,7 +40,7 @@ impl ResourceData {
/// ///
/// * If the data is already borrowed mutably, this will panic. /// * If the data is already borrowed mutably, this will panic.
/// * If the type of `T` is not the same as the resource type. /// * If the type of `T` is not the same as the resource type.
pub fn get_mut<'a, T: 'static>(&'a self) -> RefMut<'a, T> { pub fn get_mut<T: 'static>(&self) -> RefMut<T> {
RefMut::map(self.data.borrow_mut(), |a| a.downcast_mut().unwrap()) RefMut::map(self.data.borrow_mut(), |a| a.downcast_mut().unwrap())
} }
@ -49,7 +49,7 @@ impl ResourceData {
/// # Panics /// # Panics
/// ///
/// * If the type of `T` is not the same as the resource type. /// * If the type of `T` is not the same as the resource type.
pub fn try_get<'a, T: 'static>(&'a self) -> Option<Ref<'a, T>> { pub fn try_get<T: 'static>(&self) -> Option<Ref<T>> {
self.data.try_borrow() self.data.try_borrow()
.map(|r| Ref::map(r, |a| a.downcast_ref().unwrap())) .map(|r| Ref::map(r, |a| a.downcast_ref().unwrap()))
@ -61,7 +61,7 @@ impl ResourceData {
/// # Panics /// # Panics
/// ///
/// * If the type of `T` is not the same as the resource type. /// * If the type of `T` is not the same as the resource type.
pub fn try_get_mut<'a, T: 'static>(&'a self) -> Option<RefMut<'a, T>> { pub fn try_get_mut<T: 'static>(&self) -> Option<RefMut<T>> {
self.data.try_borrow_mut() self.data.try_borrow_mut()
.map(|r| RefMut::map(r, |a| a.downcast_mut().unwrap())) .map(|r| RefMut::map(r, |a| a.downcast_mut().unwrap()))
.ok() .ok()

View File

@ -7,6 +7,7 @@ use super::{System, Criteria};
/// A system that executes a batch of systems in order that they were given. /// A system that executes a batch of systems in order that they were given.
/// You can optionally add criteria that must pass before the systems are /// You can optionally add criteria that must pass before the systems are
/// executed. /// executed.
#[derive(Default)]
pub struct BatchedSystem { pub struct BatchedSystem {
systems: Vec<Box<dyn System>>, systems: Vec<Box<dyn System>>,
criteria: Vec<Box<dyn Criteria>>, criteria: Vec<Box<dyn Criteria>>,
@ -16,11 +17,7 @@ pub struct BatchedSystem {
impl BatchedSystem { impl BatchedSystem {
/// Create a new BatchedSystem /// Create a new BatchedSystem
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
systems: Vec::new(),
criteria: Vec::new(),
criteria_checks: 0,
}
} }
pub fn with_system<S>(&mut self, system: S) -> &mut Self pub fn with_system<S>(&mut self, system: S) -> &mut Self
@ -55,11 +52,10 @@ impl System for BatchedSystem {
for criteria in self.criteria.iter_mut() { for criteria in self.criteria.iter_mut() {
match criteria.can_run(world, self.criteria_checks) { match criteria.can_run(world, self.criteria_checks) {
super::CriteriaSchedule::Yes => can_run = can_run && true, super::CriteriaSchedule::Yes => {},
super::CriteriaSchedule::No => can_run = false, super::CriteriaSchedule::No => can_run = false,
super::CriteriaSchedule::YesAndLoop => { super::CriteriaSchedule::YesAndLoop => {
can_run = can_run && true; check_again = can_run;
check_again = can_run && true;
}, },
super::CriteriaSchedule::NoAndLoop => { super::CriteriaSchedule::NoAndLoop => {
can_run = false; can_run = false;

View File

@ -28,15 +28,14 @@ pub struct GraphSystem {
/// A system executor that represents the systems in a graph to handle dependencies. /// A system executor that represents the systems in a graph to handle dependencies.
/// ///
/// The graph uses an adjacency list. /// The graph uses an adjacency list.
#[derive(Default)]
pub struct GraphExecutor { pub struct GraphExecutor {
systems: HashMap<String, GraphSystem>, systems: HashMap<String, GraphSystem>,
} }
impl GraphExecutor { impl GraphExecutor {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
systems: HashMap::new(),
}
} }
/// Inserts a system into the Graph. /// Inserts a system into the Graph.
@ -84,7 +83,7 @@ impl GraphExecutor {
Ok(possible_errors) Ok(possible_errors)
} }
fn topological_sort<'a, 'b>(&'a self, stack: &'b mut VecDeque<String>, visited: &mut HashSet<&'a str>, node: &'a GraphSystem) -> Result<(), GraphExecutorError> { fn topological_sort<'a>(&'a self, stack: &mut VecDeque<String>, visited: &mut HashSet<&'a str>, node: &'a GraphSystem) -> Result<(), GraphExecutorError> {
if !visited.contains(node.name.as_str()) { if !visited.contains(node.name.as_str()) {
visited.insert(&node.name); visited.insert(&node.name);

View File

@ -21,6 +21,7 @@ pub trait System {
/// A setup step of the System, called before `execute` ever runs. /// A setup step of the System, called before `execute` ever runs.
fn setup(&self, world: NonNull<World>) -> anyhow::Result<()> { fn setup(&self, world: NonNull<World>) -> anyhow::Result<()> {
let _ = world;
Ok(()) Ok(())
} }
} }
@ -39,10 +40,14 @@ pub trait FnArgFetcher {
/// Return the appropriate world access if this fetcher gets the world directly. /// Return the appropriate world access if this fetcher gets the world directly.
/// Return [`Access::None`] if you're only fetching components, or resources. /// Return [`Access::None`] if you're only fetching components, or resources.
fn world_access(&self) -> Access { fn world_access(&self) -> Access {
Access::None Access::Read
} }
/// Get the arg from the world /// Get the arg from the world
///
/// # Safety
/// The system executor must ensure that on execution of the system, it will be safe to
/// borrow the world.
unsafe fn get<'a>(&mut self, world: NonNull<World>) -> Self::Arg<'a>; unsafe fn get<'a>(&mut self, world: NonNull<World>) -> Self::Arg<'a>;
} }
@ -52,6 +57,7 @@ pub trait FnArg {
pub struct FnSystem<F, Args> { pub struct FnSystem<F, Args> {
inner: F, inner: F,
#[allow(dead_code)]
args: Args, args: Args,
} }
@ -356,6 +362,7 @@ mod tests {
test_system.into_system().execute(NonNull::from(&world)).unwrap(); test_system.into_system().execute(NonNull::from(&world)).unwrap();
#[allow(dead_code)]
fn test_system(world: &mut World) -> anyhow::Result<()> { fn test_system(world: &mut World) -> anyhow::Result<()> {
let mut counter = world.get_resource_mut::<SomeCounter>(); let mut counter = world.get_resource_mut::<SomeCounter>();
counter.0 += 10; counter.0 += 10;

View File

@ -1,6 +1,6 @@
use std::{collections::{HashMap, VecDeque}, any::TypeId, cell::{Ref, RefMut}, ptr::NonNull}; use std::{collections::{HashMap, VecDeque}, any::TypeId, cell::{Ref, RefMut}, ptr::NonNull};
use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, component::Component, query::{Query, ViewIter, View, AsQuery}, resource::ResourceData, query::{dynamic::{DynamicViewIter, QueryDynamicType, DynamicView}, ViewOne}, ComponentInfo, DynTypeId, TickTracker, Tick}; use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, query::{Query, ViewIter, View, AsQuery}, resource::ResourceData, query::{dynamic::DynamicView, ViewOne}, ComponentInfo, DynTypeId, TickTracker, Tick};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct EntityId(pub u64); pub struct EntityId(pub u64);
@ -157,28 +157,29 @@ impl World {
let mut col_types: Vec<DynTypeId> = current_arch.columns.iter().map(|c| c.info.type_id).collect(); let mut col_types: Vec<DynTypeId> = current_arch.columns.iter().map(|c| c.info.type_id).collect();
let orig_col = col_types.clone(); let orig_col = col_types.clone();
col_types.extend(bundle.type_ids().into_iter()); col_types.extend(bundle.type_ids());
let mut col_infos: Vec<ComponentInfo> = current_arch.columns.iter().map(|c| c.info).collect(); let mut col_infos: Vec<ComponentInfo> = current_arch.columns.iter().map(|c| c.info).collect();
col_infos.extend(bundle.info().into_iter()); col_infos.extend(bundle.info());
let col_ptrs: Vec<(NonNull<u8>, ComponentInfo)> = current_arch.columns.iter().map(|c| unsafe { (NonNull::new_unchecked(c.borrow_ptr().as_ptr()), c.info) }).collect(); let col_ptrs: Vec<(NonNull<u8>, ComponentInfo)> = current_arch.columns.iter().map(|c| unsafe { (NonNull::new_unchecked(c.borrow_ptr().as_ptr()), c.info) }).collect();
if let Some(arch) = self.archetypes.values_mut().find(|a| a.is_archetype_for(&col_types)) { if let Some(arch) = self.archetypes.values_mut().find(|a| a.is_archetype_for(&col_types)) {
let res_index = arch.reserve_one(entity); let res_index = arch.reserve_one(entity);
let is_dynamic = bundle.is_dynamic();
for (col_type, (col_ptr, col_info)) in orig_col.into_iter().zip(col_ptrs.into_iter()) { for (col_type, (col_ptr, col_info)) in orig_col.into_iter().zip(col_ptrs.into_iter()) {
unsafe { unsafe {
let ptr = NonNull::new_unchecked(col_ptr.as_ptr() let ptr = NonNull::new_unchecked(col_ptr.as_ptr()
.add(res_index.0 as usize * col_info.layout.size)); .add(res_index.0 as usize * col_info.layout.size));
let col = arch.get_column_mut(col_type).unwrap(); let col = arch.get_column_mut(col_type).unwrap();
col.set_at(res_index.0 as _, ptr, tick); col.set_at(res_index.0 as _, ptr, is_dynamic, tick);
} }
} }
bundle.take(|data, type_id, _size| { bundle.take(|data, type_id, _size| {
let col = arch.get_column_mut(type_id).unwrap(); let col = arch.get_column_mut(type_id).unwrap();
unsafe { col.set_at(res_index.0 as _, data, tick); } unsafe { col.set_at(res_index.0 as _, data, is_dynamic, tick); }
col.len += 1; col.len += 1;
}); });
@ -210,7 +211,7 @@ impl World {
} }
/// View into the world for a set of entities that satisfy the queries. /// View into the world for a set of entities that satisfy the queries.
pub fn view_iter<'a, T: 'static + AsQuery>(&'a self) -> ViewIter<'a, T::Query> { pub fn view_iter<T: 'static + AsQuery>(&self) -> ViewIter<T::Query> {
let archetypes = self.archetypes.values().collect(); let archetypes = self.archetypes.values().collect();
let v = View::new(self, T::Query::new(), archetypes); let v = View::new(self, T::Query::new(), archetypes);
v.into_iter() v.into_iter()
@ -220,7 +221,7 @@ impl World {
DynamicView::new(self) DynamicView::new(self)
} }
pub fn view_one<'a, T: 'static + AsQuery>(&'a self, entity: Entity) -> ViewOne<'a, T::Query> { pub fn view_one<T: 'static + AsQuery>(&self, entity: Entity) -> ViewOne<T::Query> {
ViewOne::new(self, entity.id, T::Query::new()) ViewOne::new(self, entity.id, T::Query::new())
} }
@ -245,7 +246,7 @@ impl World {
/// ///
/// Will panic if the resource is not in the world. See [`try_get_resource`] for /// Will panic if the resource is not in the world. See [`try_get_resource`] for
/// a function that returns an option. /// a function that returns an option.
pub fn get_resource<'a, T: 'static>(&'a self) -> Ref<'a, T> { pub fn get_resource<T: 'static>(&self) -> Ref<T> {
self.resources.get(&TypeId::of::<T>()).unwrap() self.resources.get(&TypeId::of::<T>()).unwrap()
.get() .get()
} }
@ -253,17 +254,16 @@ impl World {
/// Attempts to get a resource from the World. /// Attempts to get a resource from the World.
/// ///
/// Returns `None` if the resource was not found. /// Returns `None` if the resource was not found.
pub fn try_get_resource<'a, T: 'static>(&'a self) -> Option<Ref<'a, T>> { pub fn try_get_resource<T: 'static>(&self) -> Option<Ref<T>> {
self.resources.get(&TypeId::of::<T>()) self.resources.get(&TypeId::of::<T>())
.map(|r| r.try_get()) .and_then(|r| r.try_get())
.flatten()
} }
/// Gets a mutable borrow of a resource from the World. /// Gets a mutable borrow of a resource from the World.
/// ///
/// Will panic if the resource is not in the world. See [`try_get_resource_mut`] for /// Will panic if the resource is not in the world. See [`try_get_resource_mut`] for
/// a function that returns an option. /// a function that returns an option.
pub fn get_resource_mut<'a, T: 'static>(&'a self) -> RefMut<'a, T> { pub fn get_resource_mut<T: 'static>(&self) -> RefMut<T> {
self.resources.get(&TypeId::of::<T>()).unwrap() self.resources.get(&TypeId::of::<T>()).unwrap()
.get_mut() .get_mut()
} }
@ -271,10 +271,9 @@ impl World {
/// Attempts to get a mutable borrow of a resource from the World. /// Attempts to get a mutable borrow of a resource from the World.
/// ///
/// Returns `None` if the resource was not found. /// Returns `None` if the resource was not found.
pub fn try_get_resource_mut<'a, T: 'static>(&'a self) -> Option<RefMut<'a, T>> { pub fn try_get_resource_mut<T: 'static>(&self) -> Option<RefMut<T>> {
self.resources.get(&TypeId::of::<T>()) self.resources.get(&TypeId::of::<T>())
.map(|r| r.try_get_mut()) .and_then(|r| r.try_get_mut())
.flatten()
} }
/// Increments the TickTracker which is used for tracking changes to components. /// Increments the TickTracker which is used for tracking changes to components.
@ -298,8 +297,6 @@ impl World {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::ops::Deref;
use crate::{tests::{Vec2, Vec3}, query::TickOf}; use crate::{tests::{Vec2, Vec3}, query::TickOf};
use super::World; use super::World;

View File

@ -60,7 +60,7 @@ impl ModelLoader {
} }
} */ } */
fn process_node(&self, buffers: &Vec<Vec<u8>>, materials: &Vec<Material>, node: gltf::Node<'_>) -> Vec<Mesh> { fn process_node(buffers: &Vec<Vec<u8>>, materials: &Vec<Material>, node: gltf::Node<'_>) -> Vec<Mesh> {
let mut meshes = vec![]; let mut meshes = vec![];
if let Some(mesh) = node.mesh() { if let Some(mesh) = node.mesh() {
for prim in mesh.primitives() { for prim in mesh.primitives() {
@ -110,14 +110,13 @@ impl ModelLoader {
let mat = materials.get(prim.material().index().unwrap()).unwrap(); let mat = materials.get(prim.material().index().unwrap()).unwrap();
new_mesh.set_material(mat.clone()); new_mesh.set_material(mat.clone());
//prim.material().
meshes.push(new_mesh); meshes.push(new_mesh);
} }
} }
for child in node.children() { for child in node.children() {
let mut child_meshes = self.process_node(buffers, materials, child); let mut child_meshes = ModelLoader::process_node(buffers, materials, child);
meshes.append(&mut child_meshes); meshes.append(&mut child_meshes);
} }
@ -186,7 +185,7 @@ impl ResourceLoader for ModelLoader {
.map(|mat| Material::from_gltf(&mut context, mat)).collect(); .map(|mat| Material::from_gltf(&mut context, mat)).collect();
let meshes: Vec<Mesh> = scene.nodes() let meshes: Vec<Mesh> = scene.nodes()
.flat_map(|node| self.process_node(&buffers, &materials, node)) .flat_map(|node| ModelLoader::process_node(&buffers, &materials, node))
.collect(); .collect();
debug!("Loaded {} meshes, and {} materials from '{}'", meshes.len(), materials.len(), path); debug!("Loaded {} meshes, and {} materials from '{}'", meshes.len(), materials.len(), path);

View File

@ -1,6 +1,4 @@
use std::{collections::{hash_map::DefaultHasher, HashMap}, hash::{Hash, Hasher}}; use std::{collections::hash_map::DefaultHasher, hash::{Hash, Hasher}};
use tracing::debug;
use crate::{Texture, ResHandle, util, loader::model::GltfLoadContext}; use crate::{Texture, ResHandle, util, loader::model::GltfLoadContext};
@ -112,7 +110,7 @@ pub struct Specular {
} }
impl Specular { impl Specular {
pub fn from_gltf(context: &mut GltfLoadContext, value: gltf::material::Specular) -> Self { pub(crate) fn from_gltf(context: &mut GltfLoadContext, value: gltf::material::Specular) -> Self {
let color_texture = value.specular_color_texture() let color_texture = value.specular_color_texture()
.map(|t| Material::load_texture(context, t)); .map(|t| Material::load_texture(context, t));

View File

@ -1,5 +1,3 @@
use std::borrow::BorrowMut;
use instant::Instant; use instant::Instant;
use lyra_ecs::{Component, world::World, system::IntoSystem}; use lyra_ecs::{Component, world::World, system::IntoSystem};

View File

@ -3,7 +3,7 @@ use std::{sync::Arc, collections::VecDeque, ptr::NonNull};
use async_std::task::block_on; use async_std::task::block_on;
use lyra_ecs::{world::World, system::{GraphExecutor, System}}; use lyra_ecs::{world::World, system::{GraphExecutor, System}};
use tracing::{info, error, Level, debug}; use tracing::{info, error, Level};
use tracing_appender::non_blocking; use tracing_appender::non_blocking;
use tracing_subscriber::{ use tracing_subscriber::{
layer::SubscriberExt, layer::SubscriberExt,
@ -290,7 +290,7 @@ impl Game {
plugin.as_ref().setup(self); plugin.as_ref().setup(self);
} }
let mut world = self.world.take().unwrap_or_default(); let world = self.world.take().unwrap_or_default();
// run startup systems // run startup systems
while let Some(mut startup) = self.startup_systems.pop_front() { while let Some(mut startup) = self.startup_systems.pop_front() {

View File

@ -1,19 +1,21 @@
use std::{collections::HashMap, cell::RefCell, borrow::BorrowMut, ops::Deref}; use std::{collections::HashMap, ops::Deref};
use lyra_ecs::{world::World, system::IntoSystem}; use lyra_ecs::{world::World, system::IntoSystem};
use crate::{castable_any::CastableAny, plugin::Plugin}; use crate::plugin::Plugin;
use super::{Button, KeyCode, InputButtons}; use super::{Button, KeyCode, InputButtons};
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
enum GamepadFormat { pub enum GamepadFormat {
DualAxis, DualAxis,
Joystick, Joystick,
} }
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
enum GamepadButton { pub enum GamepadButton {
FaceBottom, FaceBottom,
FaceLeft, FaceLeft,
FaceRight, FaceRight,
@ -35,8 +37,9 @@ enum GamepadButton {
RSpecial, RSpecial,
} }
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
enum GamepadAxis { pub enum GamepadAxis {
LThumbstickX, LThumbstickX,
LThumbstickY, LThumbstickY,
RThumbstickX, RThumbstickX,
@ -45,12 +48,14 @@ enum GamepadAxis {
RTrigger, RTrigger,
} }
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
enum GamepadInput { pub enum GamepadInput {
Button(GamepadButton), Button(GamepadButton),
Axis(GamepadAxis), Axis(GamepadAxis),
} }
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum ActionSource { pub enum ActionSource {
Keyboard(KeyCode), Keyboard(KeyCode),
@ -132,7 +137,7 @@ impl Action {
} }
} }
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct LayoutId(u32); pub struct LayoutId(u32);
impl From<u32> for LayoutId { impl From<u32> for LayoutId {
@ -141,13 +146,7 @@ impl From<u32> for LayoutId {
} }
} }
impl Default for LayoutId { #[derive(Clone, Default)]
fn default() -> Self {
Self(0)
}
}
#[derive(Clone)]
pub struct Layout { pub struct Layout {
mappings: HashMap<ActionMappingId, ActionMapping>, mappings: HashMap<ActionMappingId, ActionMapping>,
active_mapping: ActionMappingId, active_mapping: ActionMappingId,
@ -155,10 +154,7 @@ pub struct Layout {
impl Layout { impl Layout {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
mappings: HashMap::new(),
active_mapping: Default::default(),
}
} }
pub fn add_mapping(&mut self, mapping: ActionMapping) -> &mut Self { pub fn add_mapping(&mut self, mapping: ActionMapping) -> &mut Self {
@ -168,7 +164,7 @@ impl Layout {
} }
} }
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ActionMappingId(u32); pub struct ActionMappingId(u32);
impl From<u32> for ActionMappingId { impl From<u32> for ActionMappingId {
@ -177,12 +173,6 @@ impl From<u32> for ActionMappingId {
} }
} }
impl Default for ActionMappingId {
fn default() -> Self {
Self(0)
}
}
#[derive(Clone)] #[derive(Clone)]
pub struct ActionMapping { pub struct ActionMapping {
layout: LayoutId, layout: LayoutId,
@ -209,8 +199,7 @@ impl ActionMapping {
pub fn bind(mut self, action_label: &str, bindings: &[Binding]) -> Self { pub fn bind(mut self, action_label: &str, bindings: &[Binding]) -> Self {
let mut bindings = bindings.to_vec(); let mut bindings = bindings.to_vec();
let action_binds = self.action_binds.entry(action_label.to_string()) let action_binds = self.action_binds.entry(action_label.to_string()).or_default();
.or_insert_with(|| Vec::new());
action_binds.append(&mut bindings); action_binds.append(&mut bindings);
self self
@ -226,7 +215,7 @@ impl ActionMapping {
/* pub fn add_bindings(&mut self, action_label: String, bindings: &[Binding]) -> &mut Self { /* pub fn add_bindings(&mut self, action_label: String, bindings: &[Binding]) -> &mut Self {
let mut bindings = bindings.to_vec(); let mut bindings = bindings.to_vec();
let action_binds = self.action_binds.entry(action_label) let action_binds = self.action_binds.entry(action_label)
.or_insert_with(|| Vec::new()); .or_insert_with(Vec::new);
action_binds.append(&mut bindings); action_binds.append(&mut bindings);
self self
@ -237,7 +226,7 @@ impl ActionMapping {
} }
} }
#[derive(Clone)] #[derive(Clone, Default)]
pub struct ActionHandler { pub struct ActionHandler {
pub actions: HashMap<String, Action>, pub actions: HashMap<String, Action>,
pub layouts: HashMap<LayoutId, Layout>, pub layouts: HashMap<LayoutId, Layout>,
@ -247,12 +236,7 @@ pub struct ActionHandler {
impl ActionHandler { impl ActionHandler {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
actions: HashMap::new(),
layouts: HashMap::new(),
current_layout: LayoutId::default(),
current_mapping: ActionMappingId::default(),
}
} }
pub fn add_layout(mut self, id: LayoutId) -> Self { pub fn add_layout(mut self, id: LayoutId) -> Self {
@ -262,8 +246,6 @@ impl ActionHandler {
} }
pub fn add_action(mut self, label: &str, action: Action) -> Self { pub fn add_action(mut self, label: &str, action: Action) -> Self {
/* let layout = self.layouts.get_mut(&layout_id).unwrap();
layout.actions.insert(label.to_string(), action); */
self.actions.insert(label.to_string(), action); self.actions.insert(label.to_string(), action);
self self
@ -281,12 +263,9 @@ impl ActionHandler {
/// This will panic if the action name does not correspond to an action. /// This will panic if the action name does not correspond to an action.
pub fn is_action_pressed(&self, action_name: &str) -> bool { pub fn is_action_pressed(&self, action_name: &str) -> bool {
let action = self.actions.get(action_name) let action = self.actions.get(action_name)
.expect(&format!("Action {action_name} was not found")); .unwrap_or_else(|| panic!("Action {action_name} was not found"));
match action.state { matches!(action.state, ActionState::Pressed(_) | ActionState::JustPressed(_))
ActionState::Pressed(_) | ActionState::JustPressed(_) => true,
_ => false
}
} }
/// Returns true if the action was just pressed. /// Returns true if the action was just pressed.
@ -294,12 +273,9 @@ impl ActionHandler {
/// This will panic if the action name does not correspond to an action. /// This will panic if the action name does not correspond to an action.
pub fn was_action_just_pressed(&self, action_name: &str) -> bool { pub fn was_action_just_pressed(&self, action_name: &str) -> bool {
let action = self.actions.get(action_name) let action = self.actions.get(action_name)
.expect(&format!("Action {action_name} was not found")); .unwrap_or_else(|| panic!("Action {action_name} was not found"));
match action.state { matches!(action.state, ActionState::JustPressed(_))
ActionState::JustPressed(_) => true,
_ => false
}
} }
/// Returns true if the action was just released. /// Returns true if the action was just released.
@ -307,12 +283,9 @@ impl ActionHandler {
/// This will panic if the action name does not correspond to an action. /// This will panic if the action name does not correspond to an action.
pub fn was_action_just_released(&self, action_name: &str) -> bool { pub fn was_action_just_released(&self, action_name: &str) -> bool {
let action = self.actions.get(action_name) let action = self.actions.get(action_name)
.expect(&format!("Action {action_name} was not found")); .unwrap_or_else(|| panic!("Action {action_name} was not found"));
match action.state { matches!(action.state, ActionState::JustReleased)
ActionState::JustReleased => true,
_ => false
}
} }
/// Returns an action's state. /// Returns an action's state.
@ -320,7 +293,7 @@ impl ActionHandler {
/// This will panic if the action name does not correspond to an action. /// This will panic if the action name does not correspond to an action.
pub fn get_action_state(&self, action_name: &str) -> ActionState { pub fn get_action_state(&self, action_name: &str) -> ActionState {
let action = self.actions.get(action_name) let action = self.actions.get(action_name)
.expect(&format!("Action {action_name} was not found")); .unwrap_or_else(|| panic!("Action {action_name} was not found"));
action.state action.state
} }
@ -331,7 +304,7 @@ impl ActionHandler {
/// This will panic if the action name does not correspond to an action. /// This will panic if the action name does not correspond to an action.
pub fn get_pressed_modifier(&self, action_name: &str) -> Option<f32> { pub fn get_pressed_modifier(&self, action_name: &str) -> Option<f32> {
let action = self.actions.get(action_name) let action = self.actions.get(action_name)
.expect(&format!("Action {action_name} was not found")); .unwrap_or_else(|| panic!("Action {action_name} was not found"));
match action.state { match action.state {
ActionState::Pressed(v) | ActionState::JustPressed(v) => Some(v), ActionState::Pressed(v) | ActionState::JustPressed(v) => Some(v),
@ -345,7 +318,7 @@ impl ActionHandler {
/// This will panic if the action name does not correspond to an action. /// This will panic if the action name does not correspond to an action.
pub fn get_just_pressed_modifier(&self, action_name: &str) -> Option<f32> { pub fn get_just_pressed_modifier(&self, action_name: &str) -> Option<f32> {
let action = self.actions.get(action_name) let action = self.actions.get(action_name)
.expect(&format!("Action {action_name} was not found")); .unwrap_or_else(|| panic!("Action {action_name} was not found"));
match action.state { match action.state {
ActionState::JustPressed(v) => Some(v), ActionState::JustPressed(v) => Some(v),
@ -359,7 +332,7 @@ impl ActionHandler {
/// This will panic if the action name does not correspond to an action. /// This will panic if the action name does not correspond to an action.
pub fn get_axis_modifier(&self, action_name: &str) -> Option<f32> { pub fn get_axis_modifier(&self, action_name: &str) -> Option<f32> {
let action = self.actions.get(action_name) let action = self.actions.get(action_name)
.expect(&format!("Action {action_name} was not found")); .unwrap_or_else(|| panic!("Action {action_name} was not found"));
match action.state { match action.state {
ActionState::Axis(v) => Some(v), ActionState::Axis(v) => Some(v),
@ -376,7 +349,6 @@ fn actions_system(world: &mut World) -> anyhow::Result<()> {
let mut handler = world.try_get_resource_mut::<ActionHandler>() let mut handler = world.try_get_resource_mut::<ActionHandler>()
.expect("No Input Action handler was created in the world!"); .expect("No Input Action handler was created in the world!");
//handler
let layout = handler.layouts.get(&handler.current_layout).expect("No active layout"); let layout = handler.layouts.get(&handler.current_layout).expect("No active layout");
let mapping = layout.mappings.get(&layout.active_mapping).expect("No active mapping"); let mapping = layout.mappings.get(&layout.active_mapping).expect("No active mapping");
@ -405,13 +377,9 @@ fn actions_system(world: &mut World) -> anyhow::Result<()> {
} else { } else {
match action.state { match action.state {
ActionState::Idle => {}, ActionState::Idle => {},
//ActionState::Pressed(_) => todo!(),
//ActionState::JustPressed(_) => todo!(),
ActionState::JustReleased => action.state = ActionState::Idle, ActionState::JustReleased => action.state = ActionState::Idle,
//ActionState::Released => action.state = ActionState::I,
_ => action.state = ActionState::JustReleased, _ => action.state = ActionState::JustReleased,
} }
//action.state = ActionState::JustReleased;
} }
} }
} }

View File

@ -94,16 +94,14 @@ impl Transform {
pub fn lerp(&self, rhs: Transform, alpha: f32) -> Self { pub fn lerp(&self, rhs: Transform, alpha: f32) -> Self {
if alpha.is_finite() { if alpha.is_finite() {
let mut res = self.clone(); let mut res = *self;
res.translation = self.translation.lerp(rhs.translation, alpha); res.translation = self.translation.lerp(rhs.translation, alpha);
// normalize rotation here to avoid panics // normalize rotation here to avoid panics
res.rotation = self.rotation.lerp(rhs.rotation.normalize(), alpha); res.rotation = self.rotation.lerp(rhs.rotation.normalize(), alpha);
res.scale = self.scale.lerp(rhs.scale, alpha); res.scale = self.scale.lerp(rhs.scale, alpha);
res res
} else { } else {
self.clone() *self
} }
} }
} }

View File

@ -4,14 +4,11 @@ pub mod spotlight;
use lyra_ecs::{Entity, Tick, world::World, query::{Entities, TickOf}}; use lyra_ecs::{Entity, Tick, world::World, query::{Entities, TickOf}};
pub use point::*; pub use point::*;
pub use directional::*;
pub use spotlight::*; pub use spotlight::*;
use std::{collections::{VecDeque, HashMap}, num::{NonZeroU64, NonZeroU32}, marker::PhantomData}; use std::{collections::{VecDeque, HashMap}, marker::PhantomData};
pub use point::*; use tracing::debug;
use tracing::{debug, Instrument};
use wgpu::util::DeviceExt;
use std::mem; use std::mem;
@ -39,9 +36,9 @@ pub struct LightBuffer<U: Default + bytemuck::Pod + bytemuck::Zeroable> {
} }
impl<U: Default + bytemuck::Pod + bytemuck::Zeroable> LightBuffer<U> { impl<U: Default + bytemuck::Pod + bytemuck::Zeroable> LightBuffer<U> {
pub fn new(layout: &wgpu::BindGroupLayout, max_count: usize) -> Self { pub fn new(max_count: usize) -> Self {
Self { Self {
_phantom: PhantomData::default(), _phantom: PhantomData,
max_count, max_count,
buffer_count: 0, buffer_count: 0,
used_indexes: HashMap::new(), used_indexes: HashMap::new(),
@ -104,7 +101,7 @@ impl<U: Default + bytemuck::Pod + bytemuck::Zeroable> LightBuffer<U> {
} }
} }
pub struct LightUniformBuffers { pub(crate) struct LightUniformBuffers {
pub buffer: wgpu::Buffer, pub buffer: wgpu::Buffer,
pub bindgroup_layout: wgpu::BindGroupLayout, pub bindgroup_layout: wgpu::BindGroupLayout,
pub bindgroup: wgpu::BindGroup, pub bindgroup: wgpu::BindGroup,
@ -157,8 +154,8 @@ impl LightUniformBuffers {
label: Some("BG_Lights"), label: Some("BG_Lights"),
}); });
let point_lights = LightBuffer::new(&bindgroup_layout, MAX_LIGHT_COUNT); let point_lights = LightBuffer::new(MAX_LIGHT_COUNT);
let spot_lights = LightBuffer::new(&bindgroup_layout, MAX_LIGHT_COUNT); let spot_lights = LightBuffer::new(MAX_LIGHT_COUNT);
Self { Self {
buffer, buffer,
@ -310,7 +307,7 @@ impl DirectionalLightUniform {
#[repr(C)] #[repr(C)]
#[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
struct SpotLightUniform { pub(crate) struct SpotLightUniform {
pub position: glam::Vec3, pub position: glam::Vec3,
pub _padding: u32, pub _padding: u32,
pub direction: glam::Vec3, pub direction: glam::Vec3,

View File

@ -42,7 +42,7 @@ impl Material {
let diffuse_texture = value.base_color_texture.as_ref().map(|t| &t.data.as_ref().unwrap().image) let diffuse_texture = value.base_color_texture.as_ref().map(|t| &t.data.as_ref().unwrap().image)
.map(|i| RenderTexture::from_image(device, queue, bg_layout.clone(), i, None).unwrap()); .map(|i| RenderTexture::from_image(device, queue, bg_layout.clone(), i, None).unwrap());
let specular = value.specular.as_ref().map(|s| MaterialSpecular::from_resource(device, queue, bg_layout.clone(), &s)); let specular = value.specular.as_ref().map(|s| MaterialSpecular::from_resource(device, queue, bg_layout.clone(), s));
Self { Self {
shader_id: value.shader_uuid.unwrap_or(0), shader_id: value.shader_uuid.unwrap_or(0),

View File

@ -133,10 +133,7 @@ impl BufferWrapperBuilder {
} }
fn format_label(&self, prefix: &str) -> Option<String> { fn format_label(&self, prefix: &str) -> Option<String> {
match self.label_prefix.as_ref() { self.label_prefix.as_ref().map(|v| format!("{}{}", prefix, v))
Some(v) => Some(format!("{}{}", prefix, v)),
None => None
}
} }
/// Finish building the BufferWrapper /// Finish building the BufferWrapper

View File

@ -1,10 +1,7 @@
use lyra_ecs::Entity; use lyra_ecs::Entity;
use crate::math::Transform; use crate::math::Transform;
use super::material::Material;
pub struct RenderJob { pub struct RenderJob {
pub entity: Entity, pub entity: Entity,
pub shader_id: u64, pub shader_id: u64,

View File

@ -1,6 +1,4 @@
use std::collections::{HashMap, VecDeque, HashSet}; use std::collections::{HashMap, VecDeque, HashSet};
use std::mem;
use std::num::NonZeroU64;
use std::sync::Arc; use std::sync::Arc;
use std::borrow::Cow; use std::borrow::Cow;
@ -11,23 +9,22 @@ use lyra_ecs::Entity;
use lyra_ecs::query::{Entities, TickOf}; use lyra_ecs::query::{Entities, TickOf};
use lyra_ecs::world::World; use lyra_ecs::world::World;
use tracing::{debug, warn}; use tracing::{debug, warn};
use wgpu::{BindGroup, BindGroupLayout, Limits}; use wgpu::{BindGroupLayout, Limits};
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use winit::window::Window; use winit::window::Window;
use crate::math::{Transform, self}; use crate::math::Transform;
use crate::render::light::PointLightUniform;
use crate::render::material::MaterialUniform; use crate::render::material::MaterialUniform;
use crate::render::render_buffer::{BufferWrapperBuilder, BindGroupPair}; use crate::render::render_buffer::BufferWrapperBuilder;
use crate::scene::{ModelComponent, TransformComponent, CameraComponent}; use crate::scene::{ModelComponent, TransformComponent, CameraComponent};
use super::camera::{RenderCamera, CameraUniform}; use super::camera::{RenderCamera, CameraUniform};
use super::desc_buf_lay::DescVertexBufferLayout; use super::desc_buf_lay::DescVertexBufferLayout;
use super::light::{PointLight, LightUniformBuffers}; use super::light::LightUniformBuffers;
use super::material::Material; use super::material::Material;
use super::render_buffer::BufferWrapper; use super::render_buffer::BufferWrapper;
use super::texture::RenderTexture; use super::texture::RenderTexture;
use super::transform_buffer_storage::{TransformBufferIndices, TransformBuffers}; use super::transform_buffer_storage::TransformBuffers;
use super::vertex::Vertex; use super::vertex::Vertex;
use super::{render_pipeline::FullRenderPipeline, render_buffer::BufferStorage, render_job::RenderJob}; use super::{render_pipeline::FullRenderPipeline, render_buffer::BufferStorage, render_job::RenderJob};
@ -49,7 +46,6 @@ struct MeshBufferStorage {
//#[allow(dead_code)] //#[allow(dead_code)]
//render_texture: Option<RenderTexture>, //render_texture: Option<RenderTexture>,
material: Option<Material>, material: Option<Material>,
diffuse_texture: Option<RenderTexture>,
// The index of the transform for this entity. // The index of the transform for this entity.
// The tuple is structured like this: (transform index, index of transform inside the buffer) // The tuple is structured like this: (transform index, index of transform inside the buffer)
@ -128,9 +124,10 @@ impl BasicRenderer {
limits: if cfg!(target_arch = "wasm32") { limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults() wgpu::Limits::downlevel_webgl2_defaults()
} else { } else {
let mut v = wgpu::Limits::default(); wgpu::Limits {
v.max_bind_groups = 8; max_bind_groups: 8,
v ..Default::default()
}
}, },
label: None, label: None,
}, },
@ -354,7 +351,7 @@ impl BasicRenderer {
( vertex_buffer, indices ) ( vertex_buffer, indices )
} }
fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> MeshBufferStorage { fn create_mesh_buffers(&mut self, mesh: &Mesh) -> MeshBufferStorage {
let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh); let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh);
let material = Material::from_resource(&self.device, &self.queue, self.bgl_texture.clone(), &mesh.material()); let material = Material::from_resource(&self.device, &self.queue, self.bgl_texture.clone(), &mesh.material());
@ -366,7 +363,6 @@ impl BasicRenderer {
buffer_vertex: vertex_buffer, buffer_vertex: vertex_buffer,
buffer_indices, buffer_indices,
material: Some(material), material: Some(material),
diffuse_texture: None,
} }
} }
@ -376,13 +372,13 @@ impl BasicRenderer {
self.transform_buffers.expand_buffers(&self.device); self.transform_buffers.expand_buffers(&self.device);
} }
let indices = self.transform_buffers.update_or_insert(&self.queue, &self.render_limits, self.transform_buffers.update_or_insert(&self.queue, &self.render_limits,
entity, || ( transform.calculate_mat4(), glam::Mat3::from_quat(transform.rotation) )); entity, || ( transform.calculate_mat4(), glam::Mat3::from_quat(transform.rotation) ));
#[allow(clippy::map_entry)] #[allow(clippy::map_entry)]
if !self.mesh_buffers.contains_key(&mesh.uuid) { if !self.mesh_buffers.contains_key(&mesh.uuid) {
// create the mesh's buffers // create the mesh's buffers
let buffers = self.create_mesh_buffers(mesh, indices); let buffers = self.create_mesh_buffers(mesh);
self.mesh_buffers.insert(mesh.uuid, buffers); self.mesh_buffers.insert(mesh.uuid, buffers);
self.entity_meshes.insert(entity, mesh.uuid); self.entity_meshes.insert(entity, mesh.uuid);
@ -475,7 +471,7 @@ impl Renderer for BasicRenderer {
warn!("Missing camera!"); warn!("Missing camera!");
} }
self.light_buffers.update_lights(&self.queue, last_epoch, &main_world); self.light_buffers.update_lights(&self.queue, last_epoch, main_world);
} }
fn render(&mut self) -> Result<(), wgpu::SurfaceError> { fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
@ -524,15 +520,15 @@ impl Renderer for BasicRenderer {
.and_then(|m| m.diffuse_texture.as_ref()) { .and_then(|m| m.diffuse_texture.as_ref()) {
render_pass.set_bind_group(0, tex.bind_group(), &[]); render_pass.set_bind_group(0, tex.bind_group(), &[]);
} else { } else {
render_pass.set_bind_group(0, &self.default_texture.bind_group(), &[]); render_pass.set_bind_group(0, self.default_texture.bind_group(), &[]);
} }
if let Some(tex) = buffers.material.as_ref() if let Some(tex) = buffers.material.as_ref()
.and_then(|m| m.specular.as_ref()) .and_then(|m| m.specular.as_ref())
.and_then(|s| s.texture.as_ref().or_else(|| s.color_texture.as_ref())) { .and_then(|s| s.texture.as_ref().or(s.color_texture.as_ref())) {
render_pass.set_bind_group(5, tex.bind_group(), &[]); render_pass.set_bind_group(5, tex.bind_group(), &[]);
} else { } else {
render_pass.set_bind_group(5, &self.default_texture.bind_group(), &[]); render_pass.set_bind_group(5, self.default_texture.bind_group(), &[]);
} }
// Get the bindgroup for job's transform and bind to it using an offset. // Get the bindgroup for job's transform and bind to it using an offset.

View File

@ -147,8 +147,8 @@ impl RenderTexture {
Ok(Self { Ok(Self {
inner_texture: texture, inner_texture: texture,
view: view, view,
sampler: sampler, sampler,
bindgroup_pair: Some(bgp), bindgroup_pair: Some(bgp),
}) })
} }
@ -217,8 +217,8 @@ impl RenderTexture {
Self { Self {
inner_texture: texture, inner_texture: texture,
view: view, view,
sampler: sampler, sampler,
bindgroup_pair: None, bindgroup_pair: None,
} }
} }

View File

@ -1,7 +1,6 @@
use std::{collections::{VecDeque, HashMap}, num::NonZeroU64}; use std::{collections::{VecDeque, HashMap}, num::NonZeroU64};
use lyra_ecs::Entity; use lyra_ecs::Entity;
use tracing::debug;
use wgpu::Limits; use wgpu::Limits;
use std::mem; use std::mem;
@ -165,10 +164,6 @@ impl TransformBuffers {
.map(|entry| &entry.bindgroup) .map(|entry| &entry.bindgroup)
} }
pub fn entity_bind_group(&self, entity: Entity) -> Option<&wgpu::BindGroup> {
self.entity_indices(entity).and_then(|i| self.bind_group(*i))
}
/// Expand the Transform buffers by adding another uniform buffer binding /// Expand the Transform buffers by adding another uniform buffer binding
pub fn expand_buffers(&mut self, device: &wgpu::Device) { pub fn expand_buffers(&mut self, device: &wgpu::Device) {
let limits = device.limits(); let limits = device.limits();

View File

@ -1,4 +1,4 @@
use std::{sync::Arc, collections::VecDeque}; use std::sync::Arc;
use glam::{Vec2, IVec2}; use glam::{Vec2, IVec2};
use lyra_ecs::{world::World, system::IntoSystem}; use lyra_ecs::{world::World, system::IntoSystem};