Replace Contexts with Resources #7

Merged
reo merged 5 commits from 2025-10-15-resources into master 2025-10-19 14:24:22 +00:00
2 changed files with 408 additions and 31 deletions
Showing only changes of commit 1a48e58a1c - Show all commits

View file

@ -7,9 +7,7 @@ macro_rules! define_typemap {
impl $name {
pub fn new() -> Self {
Self {
map: std::collections::HashMap::new(),
}
Self { map: std::collections::HashMap::new() }
}
pub fn insert<T>(&mut self, value: T) -> Option<Box<T>>
@ -17,49 +15,33 @@ macro_rules! define_typemap {
T: std::any::Any + 'static + $($trait_bound)*,
{
let type_id = std::any::TypeId::of::<T>();
self.map
.insert(type_id, Box::new(value))
.and_then(|boxed| boxed.downcast().ok())
self.map.insert(type_id, Box::new(value)).and_then(|b| b.downcast().ok())
}
pub fn get<T>(&self) -> Option<&T>
where
T: std::any::Any + 'static + $($trait_bound)*,
{
self.map
.get(&std::any::TypeId::of::<T>())
.and_then(|any| any.downcast_ref::<T>())
self.map.get(&std::any::TypeId::of::<T>())?.downcast_ref::<T>()
}
pub fn get_mut<T>(&mut self) -> Option<&mut T>
where
T: std::any::Any + 'static + $($trait_bound)*,
{
self.map
.get_mut(&std::any::TypeId::of::<T>())
.and_then(|any| any.downcast_mut::<T>())
self.map.get_mut(&std::any::TypeId::of::<T>())?.downcast_mut::<T>()
}
pub fn remove<T>(&mut self) -> Option<Box<T>>
where
T: std::any::Any + 'static + $($trait_bound)*,
{
self.map
.remove(&std::any::TypeId::of::<T>())
.and_then(|boxed| boxed.downcast().ok())
self.map.remove(&std::any::TypeId::of::<T>())?.downcast().ok()
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn clear(&mut self) {
self.map.clear();
}
pub fn len(&self) -> usize { self.map.len() }
pub fn is_empty(&self) -> bool { self.map.is_empty() }
pub fn clear(&mut self) { self.map.clear(); }
pub fn contains<T>(&self) -> bool
where
@ -67,11 +49,407 @@ macro_rules! define_typemap {
{
self.map.contains_key(&std::any::TypeId::of::<T>())
}
// --- tuple-based multi-get API ---
pub fn get_many<'a, T>(&'a self) -> Option<<T as __tm_get::GetTuple>::Output<'a>>
where
T: __tm_get::GetTuple,
{
<T as __tm_get::GetTuple>::get_from(&self.map)
}
impl Default for $name {
fn default() -> Self {
Self::new()
pub fn get_many_mut<'a, T>(&'a mut self) -> Option<<T as __tm_get::GetTupleMut>::Output<'a>>
where
T: __tm_get::GetTupleMut,
{
<T as __tm_get::GetTupleMut>::get_from_mut(&mut self.map)
}
}
impl Default for $name { fn default() -> Self { Self::new() } }
// Put helper traits/impls in a private module to avoid name clashes.
mod __tm_get {
use std::any::{Any, TypeId};
use std::collections::HashMap;
pub trait GetTuple {
type Output<'a>;
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>>;
}
pub trait GetTupleMut {
type Output<'a>;
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>>;
}
// Manual implementations for arities 1..=8.
impl<A> GetTuple for (A,)
where
A: Any + 'static,
{
type Output<'a> = (&'a A,);
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let a = map.get(&TypeId::of::<A>())?.downcast_ref::<A>()?;
Some((a,))
}
}
impl<A> GetTupleMut for (A,)
where
A: Any + 'static,
{
type Output<'a> = (&'a mut A,);
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ptr_a = { map.get_mut(&TypeId::of::<A>()).map(|v| v as *mut dyn Any) }?;
unsafe {
let a = (&mut *ptr_a).downcast_mut::<A>()?;
Some((a,))
}
}
}
impl<A, B> GetTuple for (A, B)
where
A: Any + 'static,
B: Any + 'static,
{
type Output<'a> = (&'a A, &'a B);
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>()];
if ids[0] == ids[1] { return None; }
let a = map.get(&TypeId::of::<A>())?.downcast_ref::<A>()?;
let b = map.get(&TypeId::of::<B>())?.downcast_ref::<B>()?;
Some((a, b))
}
}
impl<A, B> GetTupleMut for (A, B)
where
A: Any + 'static,
B: Any + 'static,
{
type Output<'a> = (&'a mut A, &'a mut B);
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>()];
if ids[0] == ids[1] { return None; }
let ptr_a = { map.get_mut(&TypeId::of::<A>()).map(|v| v as *mut dyn Any) }?;
let ptr_b = { map.get_mut(&TypeId::of::<B>()).map(|v| v as *mut dyn Any) }?;
unsafe {
let a = (&mut *ptr_a).downcast_mut::<A>()?;
let b = (&mut *ptr_b).downcast_mut::<B>()?;
Some((a, b))
}
}
}
impl<A, B, C> GetTuple for (A, B, C)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
{
type Output<'a> = (&'a A, &'a B, &'a C);
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
if ids[0] == ids[1] || ids[0] == ids[2] || ids[1] == ids[2] { return None; }
let a = map.get(&TypeId::of::<A>())?.downcast_ref::<A>()?;
let b = map.get(&TypeId::of::<B>())?.downcast_ref::<B>()?;
let c = map.get(&TypeId::of::<C>())?.downcast_ref::<C>()?;
Some((a, b, c))
}
}
impl<A, B, C> GetTupleMut for (A, B, C)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
{
type Output<'a> = (&'a mut A, &'a mut B, &'a mut C);
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
if ids[0] == ids[1] || ids[0] == ids[2] || ids[1] == ids[2] { return None; }
let ptr_a = { map.get_mut(&TypeId::of::<A>()).map(|v| v as *mut dyn Any) }?;
let ptr_b = { map.get_mut(&TypeId::of::<B>()).map(|v| v as *mut dyn Any) }?;
let ptr_c = { map.get_mut(&TypeId::of::<C>()).map(|v| v as *mut dyn Any) }?;
unsafe {
let a = (&mut *ptr_a).downcast_mut::<A>()?;
let b = (&mut *ptr_b).downcast_mut::<B>()?;
let c = (&mut *ptr_c).downcast_mut::<C>()?;
Some((a, b, c))
}
}
}
impl<A, B, C, D> GetTuple for (A, B, C, D)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
{
type Output<'a> = (&'a A, &'a B, &'a C, &'a D);
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let a = map.get(&TypeId::of::<A>())?.downcast_ref::<A>()?;
let b = map.get(&TypeId::of::<B>())?.downcast_ref::<B>()?;
let c = map.get(&TypeId::of::<C>())?.downcast_ref::<C>()?;
let d = map.get(&TypeId::of::<D>())?.downcast_ref::<D>()?;
Some((a, b, c, d))
}
}
impl<A, B, C, D> GetTupleMut for (A, B, C, D)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
{
type Output<'a> = (&'a mut A, &'a mut B, &'a mut C, &'a mut D);
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let ptr_a = { map.get_mut(&TypeId::of::<A>()).map(|v| v as *mut dyn Any) }?;
let ptr_b = { map.get_mut(&TypeId::of::<B>()).map(|v| v as *mut dyn Any) }?;
let ptr_c = { map.get_mut(&TypeId::of::<C>()).map(|v| v as *mut dyn Any) }?;
let ptr_d = { map.get_mut(&TypeId::of::<D>()).map(|v| v as *mut dyn Any) }?;
unsafe {
let a = (&mut *ptr_a).downcast_mut::<A>()?;
let b = (&mut *ptr_b).downcast_mut::<B>()?;
let c = (&mut *ptr_c).downcast_mut::<C>()?;
let d = (&mut *ptr_d).downcast_mut::<D>()?;
Some((a, b, c, d))
}
}
}
impl<A, B, C, D, E> GetTuple for (A, B, C, D, E)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
E: Any + 'static,
{
type Output<'a> = (&'a A, &'a B, &'a C, &'a D, &'a E);
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>(), TypeId::of::<E>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let a = map.get(&TypeId::of::<A>())?.downcast_ref::<A>()?;
let b = map.get(&TypeId::of::<B>())?.downcast_ref::<B>()?;
let c = map.get(&TypeId::of::<C>())?.downcast_ref::<C>()?;
let d = map.get(&TypeId::of::<D>())?.downcast_ref::<D>()?;
let e = map.get(&TypeId::of::<E>())?.downcast_ref::<E>()?;
Some((a, b, c, d, e))
}
}
impl<A, B, C, D, E> GetTupleMut for (A, B, C, D, E)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
E: Any + 'static,
{
type Output<'a> = (&'a mut A, &'a mut B, &'a mut C, &'a mut D, &'a mut E);
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>(), TypeId::of::<E>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let ptr_a = { map.get_mut(&TypeId::of::<A>()).map(|v| v as *mut dyn Any) }?;
let ptr_b = { map.get_mut(&TypeId::of::<B>()).map(|v| v as *mut dyn Any) }?;
let ptr_c = { map.get_mut(&TypeId::of::<C>()).map(|v| v as *mut dyn Any) }?;
let ptr_d = { map.get_mut(&TypeId::of::<D>()).map(|v| v as *mut dyn Any) }?;
let ptr_e = { map.get_mut(&TypeId::of::<E>()).map(|v| v as *mut dyn Any) }?;
unsafe {
let a = (&mut *ptr_a).downcast_mut::<A>()?;
let b = (&mut *ptr_b).downcast_mut::<B>()?;
let c = (&mut *ptr_c).downcast_mut::<C>()?;
let d = (&mut *ptr_d).downcast_mut::<D>()?;
let e = (&mut *ptr_e).downcast_mut::<E>()?;
Some((a, b, c, d, e))
}
}
}
impl<A, B, C, D, E, F> GetTuple for (A, B, C, D, E, F)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
E: Any + 'static,
F: Any + 'static,
{
type Output<'a> = (&'a A, &'a B, &'a C, &'a D, &'a E, &'a F);
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>(), TypeId::of::<E>(), TypeId::of::<F>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let a = map.get(&TypeId::of::<A>())?.downcast_ref::<A>()?;
let b = map.get(&TypeId::of::<B>())?.downcast_ref::<B>()?;
let c = map.get(&TypeId::of::<C>())?.downcast_ref::<C>()?;
let d = map.get(&TypeId::of::<D>())?.downcast_ref::<D>()?;
let e = map.get(&TypeId::of::<E>())?.downcast_ref::<E>()?;
let f = map.get(&TypeId::of::<F>())?.downcast_ref::<F>()?;
Some((a, b, c, d, e, f))
}
}
impl<A, B, C, D, E, F> GetTupleMut for (A, B, C, D, E, F)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
E: Any + 'static,
F: Any + 'static,
{
type Output<'a> = (&'a mut A, &'a mut B, &'a mut C, &'a mut D, &'a mut E, &'a mut F);
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>(), TypeId::of::<E>(), TypeId::of::<F>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let ptr_a = { map.get_mut(&TypeId::of::<A>()).map(|v| v as *mut dyn Any) }?;
let ptr_b = { map.get_mut(&TypeId::of::<B>()).map(|v| v as *mut dyn Any) }?;
let ptr_c = { map.get_mut(&TypeId::of::<C>()).map(|v| v as *mut dyn Any) }?;
let ptr_d = { map.get_mut(&TypeId::of::<D>()).map(|v| v as *mut dyn Any) }?;
let ptr_e = { map.get_mut(&TypeId::of::<E>()).map(|v| v as *mut dyn Any) }?;
let ptr_f = { map.get_mut(&TypeId::of::<F>()).map(|v| v as *mut dyn Any) }?;
unsafe {
let a = (&mut *ptr_a).downcast_mut::<A>()?;
let b = (&mut *ptr_b).downcast_mut::<B>()?;
let c = (&mut *ptr_c).downcast_mut::<C>()?;
let d = (&mut *ptr_d).downcast_mut::<D>()?;
let e = (&mut *ptr_e).downcast_mut::<E>()?;
let f = (&mut *ptr_f).downcast_mut::<F>()?;
Some((a, b, c, d, e, f))
}
}
}
impl<A, B, C, D, E, F, G> GetTuple for (A, B, C, D, E, F, G)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
E: Any + 'static,
F: Any + 'static,
G: Any + 'static,
{
type Output<'a> = (&'a A, &'a B, &'a C, &'a D, &'a E, &'a F, &'a G);
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>(), TypeId::of::<E>(), TypeId::of::<F>(), TypeId::of::<G>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let a = map.get(&TypeId::of::<A>())?.downcast_ref::<A>()?;
let b = map.get(&TypeId::of::<B>())?.downcast_ref::<B>()?;
let c = map.get(&TypeId::of::<C>())?.downcast_ref::<C>()?;
let d = map.get(&TypeId::of::<D>())?.downcast_ref::<D>()?;
let e = map.get(&TypeId::of::<E>())?.downcast_ref::<E>()?;
let f = map.get(&TypeId::of::<F>())?.downcast_ref::<F>()?;
let g = map.get(&TypeId::of::<G>())?.downcast_ref::<G>()?;
Some((a, b, c, d, e, f, g))
}
}
impl<A, B, C, D, E, F, G> GetTupleMut for (A, B, C, D, E, F, G)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
E: Any + 'static,
F: Any + 'static,
G: Any + 'static,
{
type Output<'a> = (&'a mut A, &'a mut B, &'a mut C, &'a mut D, &'a mut E, &'a mut F, &'a mut G);
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>(), TypeId::of::<E>(), TypeId::of::<F>(), TypeId::of::<G>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let ptr_a = { map.get_mut(&TypeId::of::<A>()).map(|v| v as *mut dyn Any) }?;
let ptr_b = { map.get_mut(&TypeId::of::<B>()).map(|v| v as *mut dyn Any) }?;
let ptr_c = { map.get_mut(&TypeId::of::<C>()).map(|v| v as *mut dyn Any) }?;
let ptr_d = { map.get_mut(&TypeId::of::<D>()).map(|v| v as *mut dyn Any) }?;
let ptr_e = { map.get_mut(&TypeId::of::<E>()).map(|v| v as *mut dyn Any) }?;
let ptr_f = { map.get_mut(&TypeId::of::<F>()).map(|v| v as *mut dyn Any) }?;
let ptr_g = { map.get_mut(&TypeId::of::<G>()).map(|v| v as *mut dyn Any) }?;
unsafe {
let a = (&mut *ptr_a).downcast_mut::<A>()?;
let b = (&mut *ptr_b).downcast_mut::<B>()?;
let c = (&mut *ptr_c).downcast_mut::<C>()?;
let d = (&mut *ptr_d).downcast_mut::<D>()?;
let e = (&mut *ptr_e).downcast_mut::<E>()?;
let f = (&mut *ptr_f).downcast_mut::<F>()?;
let g = (&mut *ptr_g).downcast_mut::<G>()?;
Some((a, b, c, d, e, f, g))
}
}
}
impl<A, B, C, D, E, F, G, H> GetTuple for (A, B, C, D, E, F, G, H)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
E: Any + 'static,
F: Any + 'static,
G: Any + 'static,
H: Any + 'static,
{
type Output<'a> = (&'a A, &'a B, &'a C, &'a D, &'a E, &'a F, &'a G, &'a H);
fn get_from<'a>(map: &'a HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>(), TypeId::of::<E>(), TypeId::of::<F>(), TypeId::of::<G>(), TypeId::of::<H>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let a = map.get(&TypeId::of::<A>())?.downcast_ref::<A>()?;
let b = map.get(&TypeId::of::<B>())?.downcast_ref::<B>()?;
let c = map.get(&TypeId::of::<C>())?.downcast_ref::<C>()?;
let d = map.get(&TypeId::of::<D>())?.downcast_ref::<D>()?;
let e = map.get(&TypeId::of::<E>())?.downcast_ref::<E>()?;
let f = map.get(&TypeId::of::<F>())?.downcast_ref::<F>()?;
let g = map.get(&TypeId::of::<G>())?.downcast_ref::<G>()?;
let h = map.get(&TypeId::of::<H>())?.downcast_ref::<H>()?;
Some((a, b, c, d, e, f, g, h))
}
}
impl<A, B, C, D, E, F, G, H> GetTupleMut for (A, B, C, D, E, F, G, H)
where
A: Any + 'static,
B: Any + 'static,
C: Any + 'static,
D: Any + 'static,
E: Any + 'static,
F: Any + 'static,
G: Any + 'static,
H: Any + 'static,
{
type Output<'a> = (&'a mut A, &'a mut B, &'a mut C, &'a mut D, &'a mut E, &'a mut F, &'a mut G, &'a mut H);
fn get_from_mut<'a>(map: &'a mut HashMap<TypeId, Box<dyn Any>>) -> Option<Self::Output<'a>> {
let ids = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>(), TypeId::of::<D>(), TypeId::of::<E>(), TypeId::of::<F>(), TypeId::of::<G>(), TypeId::of::<H>()];
for i in 0..ids.len() { for j in (i+1)..ids.len() { if ids[i] == ids[j] { return None; } } }
let ptr_a = { map.get_mut(&TypeId::of::<A>()).map(|v| v as *mut dyn Any) }?;
let ptr_b = { map.get_mut(&TypeId::of::<B>()).map(|v| v as *mut dyn Any) }?;
let ptr_c = { map.get_mut(&TypeId::of::<C>()).map(|v| v as *mut dyn Any) }?;
let ptr_d = { map.get_mut(&TypeId::of::<D>()).map(|v| v as *mut dyn Any) }?;
let ptr_e = { map.get_mut(&TypeId::of::<E>()).map(|v| v as *mut dyn Any) }?;
let ptr_f = { map.get_mut(&TypeId::of::<F>()).map(|v| v as *mut dyn Any) }?;
let ptr_g = { map.get_mut(&TypeId::of::<G>()).map(|v| v as *mut dyn Any) }?;
let ptr_h = { map.get_mut(&TypeId::of::<H>()).map(|v| v as *mut dyn Any) }?;
unsafe {
let a = (&mut *ptr_a).downcast_mut::<A>()?;
let b = (&mut *ptr_b).downcast_mut::<B>()?;
let c = (&mut *ptr_c).downcast_mut::<C>()?;
let d = (&mut *ptr_d).downcast_mut::<D>()?;
let e = (&mut *ptr_e).downcast_mut::<E>()?;
let f = (&mut *ptr_f).downcast_mut::<F>()?;
let g = (&mut *ptr_g).downcast_mut::<G>()?;
let h = (&mut *ptr_h).downcast_mut::<H>()?;
Some((a, b, c, d, e, f, g, h))
}
}
}
}
};

View file

@ -92,8 +92,7 @@ impl System for FPSDebugCameraSystem {
}
fn frame_update(&mut self, res: &mut EngineResources, scene: &mut Scene) {
let pctx = res.get::<PlatformContext>().unwrap();
let input = res.get::<InputState>().unwrap();
let (pctx, input) = res.get_many::<(PlatformContext, InputState)>().unwrap();
if self.mouse_enabled {
self.yaw += self.mouse_delta.0 as f32 * self.sensitivity;