@@ -38,8 +38,23 @@ export const getGlobalSize = () => globalSize;
38
38
39
39
// removed eids should also be global to prevent memory leaks
40
40
const removed : number [ ] = [ ] ;
41
+ const removedOut : number [ ] = [ ] ;
41
42
const recycled : number [ ] = [ ] ;
42
43
44
+ const dequeuFromRemoved = ( ) => {
45
+ if ( removedOut . length === 0 ) {
46
+ while ( removed . length > 0 ) {
47
+ removedOut . push ( removed . pop ( ) ! ) ;
48
+ }
49
+ }
50
+ if ( removedOut . length === 0 ) {
51
+ throw new Error ( 'Queue is empty' ) ;
52
+ }
53
+ return removedOut . pop ( ) ! ;
54
+ } ;
55
+
56
+ const getRemovedLength = ( ) => removed . length + removedOut . length ;
57
+
43
58
const defaultRemovedReuseThreshold = 0.01 ;
44
59
let removedReuseThreshold = defaultRemovedReuseThreshold ;
45
60
@@ -48,6 +63,7 @@ export const resetGlobals = () => {
48
63
globalEntityCursor = 0 ;
49
64
removedReuseThreshold = defaultRemovedReuseThreshold ;
50
65
removed . length = 0 ;
66
+ removedOut . length = 0 ;
51
67
recycled . length = 0 ;
52
68
queries . length = 0 ;
53
69
worlds . length = 0 ;
@@ -104,13 +120,17 @@ export const Prefab = defineComponent();
104
120
* @returns {number } eid
105
121
*/
106
122
export const addEntity = ( world : World ) : number => {
107
- const eid : number = world [ $manualEntityRecycling ]
108
- ? removed . length
109
- ? removed . shift ( ) !
110
- : globalEntityCursor ++
111
- : removed . length > Math . round ( globalSize * removedReuseThreshold )
112
- ? removed . shift ( ) !
113
- : globalEntityCursor ++ ;
123
+ let eid : number ;
124
+
125
+ if (
126
+ ( world [ $manualEntityRecycling ] && getRemovedLength ( ) > 0 ) ||
127
+ ( ! world [ $manualEntityRecycling ] &&
128
+ getRemovedLength ( ) > Math . round ( globalSize * removedReuseThreshold ) )
129
+ ) {
130
+ eid = dequeuFromRemoved ( ) ;
131
+ } else {
132
+ eid = globalEntityCursor ++ ;
133
+ }
114
134
115
135
if ( world [ $entitySparseSet ] . dense . length >= world [ $size ] ) {
116
136
throw new Error ( 'bitECS - max entities reached' ) ;
@@ -177,9 +197,9 @@ export const removeEntity = (world: World, eid: number) => {
177
197
178
198
// Remove entity from all queries
179
199
// TODO: archetype graph
180
- world [ $queries ] . forEach ( ( q ) => {
181
- queryRemoveEntity ( world , q , eid ) ;
182
- } ) ;
200
+ for ( const query of world [ $queries ] ) {
201
+ queryRemoveEntity ( world , query , eid ) ;
202
+ }
183
203
184
204
// Free the entity
185
205
if ( world [ $manualEntityRecycling ] ) recycled . push ( eid ) ;
0 commit comments