Start using rust 1.86 features
This commit is contained in:
parent
0e5f8202b0
commit
bdaedab819
9 changed files with 53 additions and 205 deletions
|
@ -1,7 +1,7 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
members = ["ecs", "scene_update_macros"]
|
members = ["ecs", "update_macros"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||||
|
|
|
@ -12,7 +12,7 @@ paste.workspace = true
|
||||||
ron.workspace = true
|
ron.workspace = true
|
||||||
utilities.workspace = true
|
utilities.workspace = true
|
||||||
|
|
||||||
scene_update_macros = { path = "../scene_update_macros" }
|
update_macros = { path = "../update_macros" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
timings = []
|
timings = []
|
||||||
|
|
|
@ -7,7 +7,7 @@ use anyhow::Result;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{ComponentDebug, ComponentNotFoundError, EntityComponent, MultiMut, TypeMap};
|
use crate::{ComponentDebug, ComponentNotFoundError, EntityComponent, TypeMap};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EntityNotFoundError {
|
pub struct EntityNotFoundError {
|
||||||
|
@ -89,10 +89,6 @@ impl EntityObject {
|
||||||
self.gltf_file.as_ref()
|
self.gltf_file.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multi_mut(&mut self) -> MultiMut<'_> {
|
|
||||||
self.components.multi_mut()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_component<T: EntityComponent + ComponentDebug>(
|
pub fn insert_component<T: EntityComponent + ComponentDebug>(
|
||||||
&mut self,
|
&mut self,
|
||||||
component: T,
|
component: T,
|
||||||
|
|
|
@ -9,9 +9,9 @@ mod world;
|
||||||
|
|
||||||
pub use crate::entity::{Entity, EntityMultiMut, EntityNotFoundError, EntityObject};
|
pub use crate::entity::{Entity, EntityMultiMut, EntityNotFoundError, EntityObject};
|
||||||
pub use crate::events::Events;
|
pub use crate::events::Events;
|
||||||
pub use crate::resources::{ResourceMultiMut, Resources};
|
pub use crate::resources::Resources;
|
||||||
pub use crate::type_map::{
|
pub use crate::type_map::{
|
||||||
ComponentCreateInfo, ComponentDebug, ComponentNotFoundError, EntityComponent, MultiMut, TypeMap,
|
ComponentCreateInfo, ComponentDebug, ComponentNotFoundError, EntityComponent, TypeMap,
|
||||||
};
|
};
|
||||||
pub use crate::unsafe_component_store::UnsafeComponentStore;
|
pub use crate::unsafe_component_store::UnsafeComponentStore;
|
||||||
pub use crate::updates::*;
|
pub use crate::updates::*;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
mem::transmute,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use utilities::prelude::{remove_life_time, remove_life_time_mut};
|
use utilities::prelude::{remove_life_time, remove_life_time_mut};
|
||||||
|
@ -91,88 +90,7 @@ impl Resources {
|
||||||
self.map.get_mut(&type_id).map(|any| any.as_mut())
|
self.map.get_mut(&type_id).map(|any| any.as_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multi_mut(&mut self) -> ResourceMultiMut<'_> {
|
|
||||||
ResourceMultiMut::new(&mut self.map)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contains<T: Any + Send + Sync>(&self) -> bool {
|
pub fn contains<T: Any + Send + Sync>(&self) -> bool {
|
||||||
self.map.contains_key(&TypeId::of::<T>())
|
self.map.contains_key(&TypeId::of::<T>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper
|
|
||||||
impl Resources {
|
|
||||||
fn downcast_unchecked<T: Any + Send + Sync>(boxed: Box<Untyped>) -> Box<T> {
|
|
||||||
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn downcast_ref_unchecked<T: Any + Send + Sync>(boxed_ref: &Box<Untyped>) -> &T {
|
|
||||||
unsafe {
|
|
||||||
let ptr_to_ptr: *const *const T =
|
|
||||||
transmute(destructure_traitobject::data(boxed_ref as *const _));
|
|
||||||
|
|
||||||
&**ptr_to_ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn downcast_mut_unchecked<T: Any + Send + Sync>(boxed_ref: &mut Box<Untyped>) -> &mut T {
|
|
||||||
unsafe {
|
|
||||||
let ptr_to_ptr: *mut *mut T =
|
|
||||||
transmute(destructure_traitobject::data(boxed_ref as *mut _));
|
|
||||||
|
|
||||||
&mut **ptr_to_ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Allows mutable access to multiple components at once
|
|
||||||
pub struct ResourceMultiMut<'a> {
|
|
||||||
map: &'a mut HashMap<TypeId, Box<dyn Any + Send + Sync>>,
|
|
||||||
buffer: Vec<*mut Box<dyn Any + Send + Sync>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ResourceMultiMut<'a> {
|
|
||||||
fn new(map: &'a mut HashMap<TypeId, Box<dyn Any + Send + Sync>>) -> Self {
|
|
||||||
ResourceMultiMut {
|
|
||||||
map,
|
|
||||||
buffer: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns requested type on success
|
|
||||||
pub fn get<T: Any + Send + Sync>(&mut self) -> &'a mut T {
|
|
||||||
self.get_by_type_id(&TypeId::of::<T>())
|
|
||||||
.map(|component| Resources::downcast_mut_unchecked(component))
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns requested type behind this type id on success
|
|
||||||
pub fn get_by_type_id(
|
|
||||||
&mut self,
|
|
||||||
type_id: &TypeId,
|
|
||||||
) -> Option<&'a mut Box<dyn Any + Send + Sync>> {
|
|
||||||
self.map.get_mut(type_id).map(|v| {
|
|
||||||
let ptr = v as *mut _;
|
|
||||||
|
|
||||||
match self.buffer.iter().find(|v| **v == ptr) {
|
|
||||||
Some(_) => {
|
|
||||||
panic!("This key has already been borrowed!");
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.buffer.push(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let t: Option<&'a mut Box<dyn Any + Send + Sync>> = unsafe { transmute(ptr) };
|
|
||||||
|
|
||||||
t.unwrap()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// use this only when there are no references left
|
|
||||||
pub unsafe fn clear_all_usages(&mut self) {
|
|
||||||
self.buffer.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::mem::transmute;
|
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
collections::{
|
collections::{
|
||||||
|
@ -26,11 +25,16 @@ pub trait EntityComponent: Any + Send + Sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl dyn EntityComponent {
|
impl dyn EntityComponent {
|
||||||
pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
|
pub fn downcast_owned<T: EntityComponent + 'static>(mut self: Box<Self>) -> Option<T> {
|
||||||
|
self.downcast_mut()
|
||||||
|
.map(|raw| unsafe { *Box::from_raw(raw as *mut T) })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn downcast_ref<T: EntityComponent + 'static>(&self) -> Option<&T> {
|
||||||
(self as &dyn Any).downcast_ref()
|
(self as &dyn Any).downcast_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
|
pub fn downcast_mut<T: EntityComponent + 'static>(&mut self) -> Option<&mut T> {
|
||||||
(self as &mut dyn Any).downcast_mut()
|
(self as &mut dyn Any).downcast_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +76,8 @@ impl TypeMap {
|
||||||
pub fn insert<T: EntityComponent + ComponentDebug>(&mut self, value: T) -> Option<T> {
|
pub fn insert<T: EntityComponent + ComponentDebug>(&mut self, value: T) -> Option<T> {
|
||||||
self.map
|
self.map
|
||||||
.insert(TypeId::of::<T>(), Box::new(value))
|
.insert(TypeId::of::<T>(), Box::new(value))
|
||||||
.map(|any| *Self::downcast_unchecked(any))
|
.map(|any| any.downcast_owned())
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_type(
|
pub fn insert_type(
|
||||||
|
@ -85,7 +90,8 @@ impl TypeMap {
|
||||||
|
|
||||||
pub fn remove<T: EntityComponent>(&mut self) -> Option<T> {
|
pub fn remove<T: EntityComponent>(&mut self) -> Option<T> {
|
||||||
self.remove_by_type_id(&TypeId::of::<T>())
|
self.remove_by_type_id(&TypeId::of::<T>())
|
||||||
.map(|any| *Self::downcast_unchecked(any))
|
.map(|any| any.downcast_owned())
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_by_type_id(&mut self, type_id: &TypeId) -> Option<Box<dyn EntityComponent>> {
|
pub fn remove_by_type_id(&mut self, type_id: &TypeId) -> Option<Box<dyn EntityComponent>> {
|
||||||
|
@ -136,10 +142,6 @@ impl TypeMap {
|
||||||
self.map.contains_key(type_id)
|
self.map.contains_key(type_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multi_mut(&mut self) -> MultiMut<'_> {
|
|
||||||
MultiMut::new(&mut self.map)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> Iter<'_, TypeId, Box<dyn EntityComponent>> {
|
pub fn iter(&self) -> Iter<'_, TypeId, Box<dyn EntityComponent>> {
|
||||||
self.map.iter()
|
self.map.iter()
|
||||||
}
|
}
|
||||||
|
@ -147,41 +149,17 @@ impl TypeMap {
|
||||||
pub fn iter_mut(&mut self) -> IterMut<'_, TypeId, Box<dyn EntityComponent>> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, TypeId, Box<dyn EntityComponent>> {
|
||||||
self.map.iter_mut()
|
self.map.iter_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn downcast_unchecked<T: EntityComponent>(boxed: Box<dyn EntityComponent>) -> Box<T> {
|
|
||||||
// unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn downcast_ref_unchecked<T: EntityComponent>(boxed_ref: &Box<dyn EntityComponent>) -> &T {
|
|
||||||
// unsafe {
|
|
||||||
// let ptr_to_ptr: *const *const T =
|
|
||||||
// transmute(destructure_traitobject::data(boxed_ref as *const _));
|
|
||||||
|
|
||||||
// &**ptr_to_ptr
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn downcast_mut_unchecked<T: EntityComponent>(
|
|
||||||
// boxed_ref: &mut Box<dyn EntityComponent>,
|
|
||||||
// ) -> &mut T {
|
|
||||||
// unsafe {
|
|
||||||
// let ptr_to_ptr: *mut *mut T =
|
|
||||||
// transmute(destructure_traitobject::data(boxed_ref as *mut _));
|
|
||||||
|
|
||||||
// &mut **ptr_to_ptr
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GetTypeMap<T> {
|
pub trait GetTypeMap<'a, T: 'a> {
|
||||||
fn get_mut(&mut self) -> std::result::Result<&mut T, ComponentNotFoundError>;
|
fn get_mut(&'a mut self) -> std::result::Result<T, ComponentNotFoundError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> GetTypeMap<T> for TypeMap
|
impl<'a, T> GetTypeMap<'a, &'a mut T> for TypeMap
|
||||||
where
|
where
|
||||||
T: EntityComponent + ComponentDebug,
|
T: EntityComponent + ComponentDebug,
|
||||||
{
|
{
|
||||||
fn get_mut(&mut self) -> std::result::Result<&mut T, ComponentNotFoundError> {
|
fn get_mut(&'a mut self) -> std::result::Result<&'a mut T, ComponentNotFoundError> {
|
||||||
self.map
|
self.map
|
||||||
.get_mut(&TypeId::of::<T>())
|
.get_mut(&TypeId::of::<T>())
|
||||||
.map(|any| any.downcast_mut().unwrap())
|
.map(|any| any.downcast_mut().unwrap())
|
||||||
|
@ -190,75 +168,37 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_get_type_map {
|
macro_rules! impl_get_type_map {
|
||||||
([$(t:ident,)+]) => {
|
(<$($t:ident$(,)?)+>) => {
|
||||||
impl<($(t,)+)> GetTypeMap<$(t,)+> for TypeMap {
|
impl<'a, $($t,)+> GetTypeMap<'a, ($(&'a mut $t,)+)> for TypeMap
|
||||||
fn get_mut(&mut self) -> std::result::Result<($(&mut t,)+), ComponentNotFoundError> {
|
where
|
||||||
self.map
|
$(
|
||||||
.get_disjoint_mut(
|
$t: EntityComponent + ComponentDebug + 'static,
|
||||||
[$(&TypeId::of::<t>(),)])
|
)+
|
||||||
|
{
|
||||||
|
fn get_mut(&'a mut self) -> std::result::Result<($(&'a mut $t,)+), ComponentNotFoundError> {
|
||||||
|
let mut types: std::collections::VecDeque<_>
|
||||||
|
= self.map.get_disjoint_mut([$(&TypeId::of::<$t>(),)+]).into_iter().collect();
|
||||||
|
|
||||||
|
Ok(($(
|
||||||
|
types
|
||||||
|
.pop_front()
|
||||||
|
.flatten()
|
||||||
.map(|any| any.downcast_mut().unwrap())
|
.map(|any| any.downcast_mut().unwrap())
|
||||||
.ok_or_else(ComponentNotFoundError::component::<T>)
|
.ok_or_else(ComponentNotFoundError::component::<$t>)?,
|
||||||
|
)+))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allows mutable access to multiple components at once
|
impl_get_type_map!(<T, U>);
|
||||||
pub struct MultiMut<'a> {
|
impl_get_type_map!(<T, U, V>);
|
||||||
map: &'a mut HashMap<TypeId, Box<dyn EntityComponent>>,
|
impl_get_type_map!(<T, U, V, W>);
|
||||||
buffer: Vec<*mut Box<dyn EntityComponent>>,
|
impl_get_type_map!(<T, U, V, W, X>);
|
||||||
}
|
impl_get_type_map!(<T, U, V, W, X, Y>);
|
||||||
|
impl_get_type_map!(<T, U, V, W, X, Y, Z>);
|
||||||
impl<'a> MultiMut<'a> {
|
impl_get_type_map!(<T, U, V, W, X, Y, Z, A>);
|
||||||
fn new(map: &'a mut HashMap<TypeId, Box<dyn EntityComponent>>) -> Self {
|
impl_get_type_map!(<T, U, V, W, X, Y, Z, A, B>);
|
||||||
MultiMut {
|
|
||||||
map,
|
|
||||||
buffer: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns requested type on success
|
|
||||||
pub fn get<T: EntityComponent + ComponentDebug>(
|
|
||||||
&mut self,
|
|
||||||
) -> std::result::Result<&'a mut T, ComponentNotFoundError> {
|
|
||||||
self.get_by_type_id(&TypeId::of::<T>())
|
|
||||||
.map(|component| TypeMap::downcast_mut_unchecked(component))
|
|
||||||
.map_err(|_| ComponentNotFoundError::component::<T>())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns requested type behind this type id on success
|
|
||||||
pub fn get_by_type_id(
|
|
||||||
&mut self,
|
|
||||||
type_id: &TypeId,
|
|
||||||
) -> std::result::Result<&'a mut Box<dyn EntityComponent>, ComponentNotFoundError> {
|
|
||||||
match self.map.get_mut(type_id) {
|
|
||||||
Some(v) => {
|
|
||||||
let ptr = v as *mut _;
|
|
||||||
|
|
||||||
match self.buffer.iter().find(|v| **v == ptr) {
|
|
||||||
Some(_) => {
|
|
||||||
panic!("This key has already been borrowed!");
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.buffer.push(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let t: Option<&'a mut Box<dyn EntityComponent>> = unsafe { transmute(ptr) };
|
|
||||||
|
|
||||||
t.ok_or_else(|| ComponentNotFoundError::type_id(*type_id))
|
|
||||||
}
|
|
||||||
None => Err(ComponentNotFoundError::type_id(*type_id)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// use this only when there are no references left
|
|
||||||
pub unsafe fn clear_all_usages(&mut self) {
|
|
||||||
self.buffer.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ComponentRequestType {
|
pub enum ComponentRequestType {
|
||||||
|
@ -319,21 +259,15 @@ impl PartialEq for Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_multi_mut() {
|
fn verify_disjoint_get() {
|
||||||
let mut map = TypeMap::default();
|
let mut map = TypeMap::default();
|
||||||
|
|
||||||
map.insert(Test::default());
|
let reference = Test { x: 5, y: 20, z: 30 };
|
||||||
|
|
||||||
// test it multiple times, just for sanity
|
map.insert(reference.clone());
|
||||||
for _ in 0..10 {
|
let old: &mut Test = map.get_mut().unwrap();
|
||||||
let test = map.get::<Test>().unwrap().clone();
|
|
||||||
|
|
||||||
let mut multi_mut = map.multi_mut();
|
assert_eq!(*old, reference);
|
||||||
|
|
||||||
let multi_mut_test = multi_mut.get::<Test>().unwrap().clone();
|
|
||||||
|
|
||||||
assert_eq!(test, multi_mut_test);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -14,7 +14,7 @@ use indexmap::IndexMap;
|
||||||
use super::super::timings::Timings;
|
use super::super::timings::Timings;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use scene_update_macros::implement_pair_update;
|
use update_macros::implement_pair_update;
|
||||||
|
|
||||||
macro_rules! impl_singleton_update {
|
macro_rules! impl_singleton_update {
|
||||||
( $name: ident, $([$var: ident]$(,)?)+ ) => {
|
( $name: ident, $([$var: ident]$(,)?)+ ) => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "scene_update_macros"
|
name = "update_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2024"
|
edition = "2024"
|
Loading…
Reference in a new issue