@@ -5,6 +5,7 @@ use std::any::{Any, TypeId};
55use std:: cell:: UnsafeCell ;
66use std:: collections:: HashMap ;
77use std:: fmt:: { Display , Formatter } ;
8+ use std:: io:: Read ;
89use std:: sync:: Arc ;
910
1011#[ derive( Clone , PartialEq , Eq , Hash , Debug , PartialOrd , Ord ) ]
@@ -18,6 +19,10 @@ impl ReflectAllocationId {
1819 pub ( crate ) fn new ( id : usize ) -> Self {
1920 Self ( Arc :: new ( id) )
2021 }
22+
23+ pub fn strong_count ( & self ) -> usize {
24+ Arc :: strong_count ( & self . 0 )
25+ }
2126}
2227
2328/// Pointer which owns the value it points to, and will deallocate it when dropped
@@ -45,29 +50,28 @@ impl<T: ?Sized> Drop for OwningPtr<T> {
4550}
4651
4752// yikes, the indirection. I need this to store boxed values too though
48- #[ derive( Clone , Debug ) ]
49- pub enum ReflectAllocation {
50- Double ( Arc < OwningPtr < dyn PartialReflect > > ) ,
51- Single ( Arc < UnsafeCell < dyn PartialReflect > > ) ,
52- }
53+ #[ derive( Debug ) ]
54+ pub struct ReflectAllocation ( Box < UnsafeCell < dyn PartialReflect > > ) ;
5355
54- unsafe impl Send for ReflectAllocation { }
56+ // unsafe impl Send for ReflectAllocation {}
5557unsafe impl Sync for ReflectAllocation { }
5658
5759impl ReflectAllocation {
5860 pub fn get_ptr ( & self ) -> * mut dyn PartialReflect {
59- match self {
60- ReflectAllocation :: Double ( v) => v. ptr ,
61- ReflectAllocation :: Single ( v) => v. get ( ) ,
62- }
61+ self . 0 . as_ref ( ) . get ( )
6362 }
64- pub fn new ( value : Arc < UnsafeCell < dyn PartialReflect > > ) -> Self {
65- Self :: Single ( value)
63+
64+ pub fn new ( value : Box < dyn PartialReflect > ) -> Self {
65+ let value: Box < UnsafeCell < dyn PartialReflect > > = unsafe { std:: mem:: transmute ( value) } ;
66+ Self ( value)
6667 }
6768
68- pub fn new_boxed ( value : Box < dyn PartialReflect > ) -> Self {
69- let ptr = Box :: leak :: < ' static > ( value) ;
70- Self :: Double ( Arc :: new ( unsafe { OwningPtr :: new ( ptr) } ) )
69+ /// Takes the value out of the allocation.
70+ ///
71+ /// # Safety
72+ /// - Must only be done if no other references to this allocation exist at the same time
73+ pub unsafe fn take ( self ) -> Box < dyn PartialReflect > {
74+ std:: mem:: transmute ( self . 0 )
7175 }
7276}
7377
@@ -113,36 +117,21 @@ pub struct ReflectAllocator {
113117impl ReflectAllocator {
114118 /// Allocates a new [`Reflect`] value and returns an [`AllocationId`] which can be used to access it later.
115119 /// Use [`Self::allocate_boxed`] if you already have an allocated boxed value.
116- pub fn allocate < T : PartialReflect > (
117- & mut self ,
118- value : T ,
119- ) -> ( ReflectAllocationId , ReflectAllocation ) {
120- let type_id = value. get_represented_type_info ( ) . map ( |i| i. type_id ( ) ) ;
121-
122- let id = ReflectAllocationId :: new ( self . allocations . len ( ) ) ;
123- let index = id. id ( ) ;
124- let value = ReflectAllocation :: new ( Arc :: new ( UnsafeCell :: new ( value) ) ) ;
125- self . allocations . insert ( id. clone ( ) , value. clone ( ) ) ;
126- if let Some ( type_id) = type_id {
127- self . types . insert ( index, type_id) ;
128- }
129- ( id, value)
120+ pub fn allocate < T : PartialReflect > ( & mut self , value : T ) -> ReflectAllocationId {
121+ self . allocate_boxed ( Box :: new ( value) )
130122 }
131123
132- pub fn allocate_boxed (
133- & mut self ,
134- value : Box < dyn PartialReflect > ,
135- ) -> ( ReflectAllocationId , ReflectAllocation ) {
124+ pub fn allocate_boxed ( & mut self , value : Box < dyn PartialReflect > ) -> ReflectAllocationId {
136125 let type_id = value. get_represented_type_info ( ) . map ( |i| i. type_id ( ) ) ;
137126
138127 let id = ReflectAllocationId :: new ( self . allocations . len ( ) ) ;
139128 let index = id. id ( ) ;
140- let value = ReflectAllocation :: new_boxed ( value) ;
141- self . allocations . insert ( id. clone ( ) , value. clone ( ) ) ;
129+ let value = ReflectAllocation :: new ( value) ;
130+ self . allocations . insert ( id. clone ( ) , value) ;
142131 if let Some ( type_id) = type_id {
143132 self . types . insert ( index, type_id) ;
144133 }
145- ( id , value )
134+ id
146135 }
147136
148137 // /// Moves the given boxed [`PartialReflect`] value into the allocator, returning an [`AllocationId`] which can be used to access it later
@@ -168,16 +157,33 @@ impl ReflectAllocator {
168157 // (id, allocation)
169158 // }
170159
171- pub fn get ( & self , id : & ReflectAllocationId ) -> Option < ReflectAllocation > {
172- self . allocations . get ( id) . cloned ( )
160+ // pub fn get(&self, id: &ReflectAllocationId) -> Option<ReflectAllocation> {
161+ // self.allocations.get(id).cloned()
162+ // }
163+
164+ pub fn insert (
165+ & mut self ,
166+ id : ReflectAllocationId ,
167+ value : ReflectAllocation ,
168+ ) -> Option < ReflectAllocation > {
169+ self . allocations . insert ( id, value)
170+ }
171+
172+ pub fn remove ( & mut self , id : & ReflectAllocationId ) -> Option < ReflectAllocation > {
173+ println ! ( "removing {:?}" , id) ;
174+ self . allocations . remove ( id)
173175 }
174176
175177 pub fn get_type_id ( & self , id : & ReflectAllocationId ) -> Option < TypeId > {
176178 self . types . get ( & id. id ( ) ) . cloned ( )
177179 }
178180
179- pub fn get_mut ( & self , id : & ReflectAllocationId ) -> Option < ReflectAllocation > {
180- self . allocations . get ( id) . cloned ( )
181+ pub fn get_mut ( & mut self , id : & ReflectAllocationId ) -> Option < & mut ReflectAllocation > {
182+ self . allocations . get_mut ( id)
183+ }
184+
185+ pub fn get ( & self , id : & ReflectAllocationId ) -> Option < & ReflectAllocation > {
186+ self . allocations . get ( id)
181187 }
182188
183189 /// Deallocates the [`PartialReflect`] value with the given [`AllocationId`]
@@ -199,7 +205,7 @@ mod test {
199205 #[ test]
200206 fn test_reflect_allocator_garbage_clean ( ) {
201207 let mut allocator = ReflectAllocator :: default ( ) ;
202- let ( id , _ ) = allocator. allocate ( 0 ) ;
208+ let id = allocator. allocate ( 0 ) ;
203209 assert_eq ! ( allocator. allocations. len( ) , 1 ) ;
204210 drop ( id) ;
205211 allocator. clean_garbage_allocations ( ) ;
@@ -209,7 +215,7 @@ mod test {
209215 #[ test]
210216 fn test_reflect_allocator_garbage_clean_no_garbage ( ) {
211217 let mut allocator = ReflectAllocator :: default ( ) ;
212- let ( _id, _ ) = allocator. allocate ( 0 ) ;
218+ let _id = allocator. allocate ( 0 ) ;
213219 assert_eq ! ( allocator. allocations. len( ) , 1 ) ;
214220 allocator. clean_garbage_allocations ( ) ;
215221 assert_eq ! ( allocator. allocations. len( ) , 1 ) ;
0 commit comments