Fix a painful amount of compiler warnings, and clippy warnings
This commit is contained in:
parent
09bba5b3b3
commit
10fc7842cf
|
@ -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();
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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(),
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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};
|
||||||
|
|
Loading…
Reference in New Issue