@@ -22,7 +22,7 @@ use std::{
22
22
} ;
23
23
24
24
use bevy_ecs:: {
25
- prelude:: { Component , Entity , EntityRef , EntityWorldMut , Commands , Mut , World } ,
25
+ prelude:: { Entity , EntityRef , EntityWorldMut , Commands , Mut , World } ,
26
26
system:: SystemState ,
27
27
} ;
28
28
@@ -36,17 +36,27 @@ use crate::{
36
36
37
37
/// A [`Buffer`] whose type has been anonymized. Joining with this buffer type
38
38
/// will yield an [`AnyMessage`].
39
- #[ derive( Clone , Copy , Debug ) ]
39
+ #[ derive( Clone , Copy ) ]
40
40
pub struct AnyBuffer {
41
41
pub ( crate ) scope : Entity ,
42
42
pub ( crate ) source : Entity ,
43
- pub ( crate ) type_id : TypeId ,
43
+ pub ( crate ) interface : & ' static ( dyn AnyBufferStorageAccessInterface + Send + Sync )
44
+ }
45
+
46
+ impl std:: fmt:: Debug for AnyBuffer {
47
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
48
+ f. debug_struct ( "AnyBuffer" )
49
+ . field ( "scope" , & self . scope )
50
+ . field ( "source" , & self . source )
51
+ . field ( "message_type_name" , & self . interface . message_type_name ( ) )
52
+ . finish ( )
53
+ }
44
54
}
45
55
46
56
impl AnyBuffer {
47
57
/// Downcast this into a concrete [`Buffer`] type.
48
58
pub fn into_buffer < T : ' static > ( & self ) -> Option < Buffer < T > > {
49
- if TypeId :: of :: < T > ( ) == self . type_id {
59
+ if TypeId :: of :: < T > ( ) == self . interface . message_type_id ( ) {
50
60
Some ( Buffer {
51
61
scope : self . scope ,
52
62
source : self . source ,
@@ -58,13 +68,13 @@ impl AnyBuffer {
58
68
}
59
69
}
60
70
61
- impl < T : ' static > From < Buffer < T > > for AnyBuffer {
71
+ impl < T : ' static + Send + Sync + Any > From < Buffer < T > > for AnyBuffer {
62
72
fn from ( value : Buffer < T > ) -> Self {
63
- let type_id = TypeId :: of :: < T > ( ) ;
73
+ let interface = AnyBufferStorageAccessImpl :: < T > :: get_interface ( ) ;
64
74
AnyBuffer {
65
75
scope : value. scope ,
66
76
source : value. source ,
67
- type_id ,
77
+ interface ,
68
78
}
69
79
}
70
80
}
@@ -80,7 +90,7 @@ pub struct AnyBufferKey {
80
90
session : Entity ,
81
91
accessor : Entity ,
82
92
lifecycle : Option < Arc < BufferAccessLifecycle > > ,
83
- type_id : TypeId ,
93
+ interface : & ' static ( dyn AnyBufferStorageAccessInterface + Send + Sync ) ,
84
94
}
85
95
86
96
impl std:: fmt:: Debug for AnyBufferKey {
@@ -91,15 +101,15 @@ impl std::fmt::Debug for AnyBufferKey {
91
101
. field ( "session" , & self . session )
92
102
. field ( "accessor" , & self . accessor )
93
103
. field ( "in_use" , & self . lifecycle . as_ref ( ) . is_some_and ( |l| l. is_in_use ( ) ) )
94
- . field ( "type_id " , & self . type_id )
104
+ . field ( "message_type_name " , & self . interface . message_type_name ( ) )
95
105
. finish ( )
96
106
}
97
107
}
98
108
99
109
impl AnyBufferKey {
100
110
/// Downcast this into a concrete [`BufferKey`] type.
101
111
pub fn into_buffer_key < T : ' static > ( & self ) -> Option < BufferKey < T > > {
102
- if TypeId :: of :: < T > ( ) == self . type_id {
112
+ if TypeId :: of :: < T > ( ) == self . interface . message_type_id ( ) {
103
113
Some ( BufferKey {
104
114
buffer : self . buffer ,
105
115
session : self . session ,
@@ -113,15 +123,15 @@ impl AnyBufferKey {
113
123
}
114
124
}
115
125
116
- impl < T : ' static > From < BufferKey < T > > for AnyBufferKey {
126
+ impl < T : ' static + Send + Sync + Any > From < BufferKey < T > > for AnyBufferKey {
117
127
fn from ( value : BufferKey < T > ) -> Self {
118
- let type_id = TypeId :: of :: < T > ( ) ;
128
+ let interface = AnyBufferStorageAccessImpl :: < T > :: get_interface ( ) ;
119
129
AnyBufferKey {
120
130
buffer : value. buffer ,
121
131
session : value. session ,
122
132
accessor : value. accessor ,
123
133
lifecycle : value. lifecycle . clone ( ) ,
124
- type_id ,
134
+ interface ,
125
135
}
126
136
}
127
137
}
@@ -360,10 +370,7 @@ impl AnyBufferWorldAccess for World {
360
370
key : & AnyBufferKey ,
361
371
f : impl FnOnce ( AnyBufferMut ) -> U ,
362
372
) -> Result < U , AnyBufferError > {
363
- let interface = self . get :: < AnyBufferStorageAccess > ( key. buffer )
364
- . ok_or ( AnyBufferError :: BufferMissing ) ?
365
- . interface ;
366
-
373
+ let interface = key. interface ;
367
374
let mut state = interface. create_any_buffer_access_mut_state ( self ) ;
368
375
let mut access = state. get_buffer_access_mut ( self ) ;
369
376
let buffer_mut = access. as_any_buffer_mut ( key) ?;
@@ -582,25 +589,11 @@ impl<'w, 's, T: 'static + Send + Sync + Any> AnyBufferAccessMut<'w, 's> for Buff
582
589
}
583
590
}
584
591
585
- /// A component that lets us inspect buffer properties without knowing the
586
- /// message type of the buffer.
587
- #[ derive( Component , Clone , Copy ) ]
588
- pub ( crate ) struct AnyBufferStorageAccess {
589
- pub ( crate ) interface : & ' static ( dyn AnyBufferStorageAccessInterface + Send + Sync ) ,
590
- }
591
-
592
- impl AnyBufferStorageAccess {
593
- pub ( crate ) fn new < T : ' static + Send + Sync + Any > ( ) -> Self {
594
- let once: OnceLock < & ' static AnyBufferStorageAccessImpl < T > > = OnceLock :: new ( ) ;
595
- let interface = * once. get_or_init ( || {
596
- Box :: leak ( Box :: new ( AnyBufferStorageAccessImpl ( Default :: default ( ) ) ) )
597
- } ) ;
592
+ pub ( crate ) trait AnyBufferStorageAccessInterface {
593
+ fn message_type_id ( & self ) -> TypeId ;
598
594
599
- Self { interface }
600
- }
601
- }
595
+ fn message_type_name ( & self ) -> & ' static str ;
602
596
603
- pub ( crate ) trait AnyBufferStorageAccessInterface {
604
597
fn buffered_count (
605
598
& self ,
606
599
entity : & EntityRef ,
@@ -621,7 +614,24 @@ pub(crate) trait AnyBufferStorageAccessInterface {
621
614
622
615
struct AnyBufferStorageAccessImpl < T > ( std:: marker:: PhantomData < T > ) ;
623
616
617
+ impl < T : ' static + Send + Sync + Any > AnyBufferStorageAccessImpl < T > {
618
+ fn get_interface ( ) -> & ' static ( dyn AnyBufferStorageAccessInterface + Send + Sync ) {
619
+ let once: OnceLock < & ' static AnyBufferStorageAccessImpl < T > > = OnceLock :: new ( ) ;
620
+ * once. get_or_init ( || {
621
+ Box :: leak ( Box :: new ( AnyBufferStorageAccessImpl ( Default :: default ( ) ) ) )
622
+ } )
623
+ }
624
+ }
625
+
624
626
impl < T : ' static + Send + Sync + Any > AnyBufferStorageAccessInterface for AnyBufferStorageAccessImpl < T > {
627
+ fn message_type_id ( & self ) -> TypeId {
628
+ TypeId :: of :: < T > ( )
629
+ }
630
+
631
+ fn message_type_name ( & self ) -> & ' static str {
632
+ std:: any:: type_name :: < T > ( )
633
+ }
634
+
625
635
fn buffered_count (
626
636
& self ,
627
637
entity : & EntityRef ,
0 commit comments