17
17
18
18
use std:: {
19
19
any:: { Any , TypeId } ,
20
+ collections:: HashMap ,
20
21
ops:: RangeBounds ,
21
- sync:: { Arc , OnceLock } ,
22
+ sync:: { Arc , OnceLock , Mutex } ,
22
23
} ;
23
24
24
25
use bevy_ecs:: {
@@ -40,7 +41,7 @@ use crate::{
40
41
pub struct AnyBuffer {
41
42
pub ( crate ) scope : Entity ,
42
43
pub ( crate ) source : Entity ,
43
- pub ( crate ) interface : & ' static ( dyn AnyBufferStorageAccessInterface + Send + Sync )
44
+ pub ( crate ) interface : & ' static ( dyn AnyBufferAccessInterface + Send + Sync )
44
45
}
45
46
46
47
impl std:: fmt:: Debug for AnyBuffer {
@@ -70,7 +71,7 @@ impl AnyBuffer {
70
71
71
72
impl < T : ' static + Send + Sync + Any > From < Buffer < T > > for AnyBuffer {
72
73
fn from ( value : Buffer < T > ) -> Self {
73
- let interface = AnyBufferStorageAccessImpl :: < T > :: get_interface ( ) ;
74
+ let interface = AnyBufferAccessImpl :: < T > :: get_interface ( ) ;
74
75
AnyBuffer {
75
76
scope : value. scope ,
76
77
source : value. source ,
@@ -90,7 +91,7 @@ pub struct AnyBufferKey {
90
91
session : Entity ,
91
92
accessor : Entity ,
92
93
lifecycle : Option < Arc < BufferAccessLifecycle > > ,
93
- interface : & ' static ( dyn AnyBufferStorageAccessInterface + Send + Sync ) ,
94
+ interface : & ' static ( dyn AnyBufferAccessInterface + Send + Sync ) ,
94
95
}
95
96
96
97
impl std:: fmt:: Debug for AnyBufferKey {
@@ -125,7 +126,7 @@ impl AnyBufferKey {
125
126
126
127
impl < T : ' static + Send + Sync + Any > From < BufferKey < T > > for AnyBufferKey {
127
128
fn from ( value : BufferKey < T > ) -> Self {
128
- let interface = AnyBufferStorageAccessImpl :: < T > :: get_interface ( ) ;
129
+ let interface = AnyBufferAccessImpl :: < T > :: get_interface ( ) ;
129
130
AnyBufferKey {
130
131
buffer : value. buffer ,
131
132
session : value. session ,
@@ -589,7 +590,7 @@ impl<'w, 's, T: 'static + Send + Sync + Any> AnyBufferAccessMut<'w, 's> for Buff
589
590
}
590
591
}
591
592
592
- pub ( crate ) trait AnyBufferStorageAccessInterface {
593
+ pub ( crate ) trait AnyBufferAccessInterface {
593
594
fn message_type_id ( & self ) -> TypeId ;
594
595
595
596
fn message_type_name ( & self ) -> & ' static str ;
@@ -612,18 +613,26 @@ pub(crate) trait AnyBufferStorageAccessInterface {
612
613
) -> Box < dyn AnyBufferAccessMutState > ;
613
614
}
614
615
615
- struct AnyBufferStorageAccessImpl < T > ( std:: marker:: PhantomData < T > ) ;
616
+ struct AnyBufferAccessImpl < T > ( std:: marker:: PhantomData < T > ) ;
616
617
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 ( ) ) ) )
618
+ impl < T : ' static + Send + Sync + Any > AnyBufferAccessImpl < T > {
619
+ fn get_interface ( ) -> & ' static ( dyn AnyBufferAccessInterface + Send + Sync ) {
620
+ const INTERFACE_MAP : OnceLock < Mutex < HashMap <
621
+ TypeId ,
622
+ & ' static ( dyn AnyBufferAccessInterface + Send + Sync )
623
+ > > > = OnceLock :: new ( ) ;
624
+ let binding = INTERFACE_MAP ;
625
+
626
+ let interfaces = binding. get_or_init ( || Mutex :: default ( ) ) ;
627
+
628
+ let mut interfaces_mut = interfaces. lock ( ) . unwrap ( ) ;
629
+ * interfaces_mut. entry ( TypeId :: of :: < T > ( ) ) . or_insert_with ( || {
630
+ Box :: leak ( Box :: new ( AnyBufferAccessImpl :: < T > ( Default :: default ( ) ) ) )
622
631
} )
623
632
}
624
633
}
625
634
626
- impl < T : ' static + Send + Sync + Any > AnyBufferStorageAccessInterface for AnyBufferStorageAccessImpl < T > {
635
+ impl < T : ' static + Send + Sync + Any > AnyBufferAccessInterface for AnyBufferAccessImpl < T > {
627
636
fn message_type_id ( & self ) -> TypeId {
628
637
TypeId :: of :: < T > ( )
629
638
}
0 commit comments