@@ -8,38 +8,26 @@ import {
88 ActorComponent ,
99 ActorTree
1010} from "../actor/index.ts" ;
11+ import type { WorldDefaultContext } from "./World.ts" ;
1112import type { Component } from "../components/types.ts" ;
1213
1314export type SceneEvents = {
1415 awake : [ ] ;
1516} ;
1617
17- export interface SceneContract {
18- readonly tree : ActorTree < any > ;
19-
20- componentsToBeStarted : Component [ ] ;
21- componentsToBeDestroyed : Component [ ] ;
22-
23- getSource ( ) : THREE . Scene ;
24- awake ( ) : void ;
25- beginFrame ( ) : void ;
26- update ( deltaTime : number ) : void ;
27- fixedUpdate ( deltaTime : number ) : void ;
28- endFrame ( ) : void ;
29- destroyActor ( actor : Actor < any > ) : void ;
30- }
31-
32- export class SceneManager extends EventEmitter <
33- SceneEvents
34- > implements SceneContract {
18+ export class SceneManager <
19+ TContext = WorldDefaultContext
20+ > extends EventEmitter < SceneEvents > {
3521 default : THREE . Scene ;
3622
3723 componentsToBeStarted : Component [ ] = [ ] ;
3824 componentsToBeDestroyed : Component [ ] = [ ] ;
3925
40- #cachedActors: Actor < any > [ ] = [ ] ;
26+ #registeredActors: Set < Actor < TContext > > = new Set ( ) ;
27+ #actorsByName: Map < string , Actor < TContext > [ ] > = new Map ( ) ;
28+ #cachedActors: Actor < TContext > [ ] = [ ] ;
4129
42- readonly tree = new ActorTree < any > ( {
30+ readonly tree = new ActorTree < TContext > ( {
4331 addCallback : ( actor ) => this . default . add ( actor . object3D ) ,
4432 removeCallback : ( actor ) => this . default . remove ( actor . object3D )
4533 } ) ;
@@ -66,20 +54,15 @@ export class SceneManager extends EventEmitter<
6654 }
6755
6856 beginFrame ( ) {
69- this . #cachedActors. length = 0 ;
70- for ( const { actor } of this . tree . walk ( ) ) {
71- this . #cachedActors. push ( actor ) ;
72- }
73-
74- const cachedActors = this . #cachedActors;
57+ this . #cachedActors = Array . from ( this . #registeredActors) ;
7558
7659 let i = 0 ;
7760 while ( i < this . componentsToBeStarted . length ) {
7861 const component = this . componentsToBeStarted [ i ] ;
7962
8063 // If the component to be started is part of an actor
8164 // which will not be updated, skip it until next loop
82- if ( cachedActors . indexOf ( component . actor ) === - 1 ) {
65+ if ( ! this . #registeredActors . has ( component . actor ) ) {
8366 i ++ ;
8467 continue ;
8568 }
@@ -111,7 +94,7 @@ export class SceneManager extends EventEmitter<
11194 } ) ;
11295 this . componentsToBeDestroyed . length = 0 ;
11396
114- const actorToBeDestroyed : Actor < any > [ ] = [ ] ;
97+ const actorToBeDestroyed : Actor < TContext > [ ] = [ ] ;
11598 this . #cachedActors. forEach ( ( actor ) => {
11699 if ( actor . pendingForDestruction || actor . isDestroyed ( ) ) {
117100 actorToBeDestroyed . push ( actor ) ;
@@ -124,26 +107,71 @@ export class SceneManager extends EventEmitter<
124107 }
125108
126109 destroyActor (
127- actor : Actor < any >
110+ actor : Actor < TContext >
128111 ) {
129112 const childrenToDestroy = [ ...actor . children ] ;
130113
131114 childrenToDestroy . forEach ( ( child ) => {
132115 this . destroyActor ( child ) ;
133116 } ) ;
134117
135- const cachedIndex = this . #cachedActors. indexOf ( actor ) ;
136- if ( cachedIndex !== - 1 ) {
137- this . #cachedActors. splice ( cachedIndex , 1 ) ;
138- }
118+ this . unregisterActor ( actor ) ;
139119
140120 // NOTE: make sure to remove deeply into the tree
141121 this . tree . remove ( actor ) ;
142122 actor . destroy ( ) ;
143123 }
144124
125+ registerActor (
126+ actor : Actor < TContext >
127+ ) {
128+ this . #registeredActors. add ( actor ) ;
129+
130+ const actors = this . #actorsByName. get ( actor . name ) ;
131+ if ( actors ) {
132+ actors . push ( actor ) ;
133+ }
134+ else {
135+ this . #actorsByName. set ( actor . name , [ actor ] ) ;
136+ }
137+ }
138+
139+ unregisterActor (
140+ actor : Actor < TContext >
141+ ) {
142+ this . #registeredActors. delete ( actor ) ;
143+
144+ const actors = this . #actorsByName. get ( actor . name ) ;
145+ if ( actors ) {
146+ const index = actors . indexOf ( actor ) ;
147+ if ( index !== - 1 ) {
148+ actors . splice ( index , 1 ) ;
149+ }
150+ if ( actors . length === 0 ) {
151+ this . #actorsByName. delete ( actor . name ) ;
152+ }
153+ }
154+ }
155+
156+ getActor (
157+ name : string
158+ ) : Actor < TContext > | null {
159+ const actors = this . #actorsByName. get ( name ) ;
160+ if ( ! actors ) {
161+ return null ;
162+ }
163+
164+ for ( const actor of actors ) {
165+ if ( ! actor . pendingForDestruction ) {
166+ return actor ;
167+ }
168+ }
169+
170+ return null ;
171+ }
172+
145173 destroyComponent (
146- component : ActorComponent < any >
174+ component : ActorComponent < TContext >
147175 ) {
148176 if ( component . pendingForDestruction ) {
149177 return ;
0 commit comments