import { Game } from '../core'; import { Entity } from './entity'; import { EntityManagerConfig } from './entity.manager.config'; /** * Abstract core EntityManager; implementing the generic and abstractable behaviour for the management, updating and rendering of Entities * * Three concrete EntityManagers are utilised by the core Game to manage World objects, UI objects and Font objects; separating processing * and utility for the three distince use-cases for Entities. These are then broken down into 2D and 3D variants for the type correction * of their consumer APIs * * Works to optimise Entity management and rendering by grouping Entities, precompiling vertex lists, handling VBOs and caching Entity * filter/search results * * VBOs are provisioned on a per-shader+model combination basis. This is because Entities that share both a Shader and a Model can be * rendered in batches, and thereby their vertices buffered to the GPU and drawn from as a single set * * Receives and works with a single TextureAtlas, thereby allowing for texture sources per Entity use-case * * The concrete EntityManagers are available on the Game instance at `game.[world|ui|font]` * * @typeparam TConfig the configuration object type, extending the core EntityManagerConfig, used by concrete extensions * * @see Game * @see World * @see Font * @see UI */ export declare abstract class EntityManager { protected readonly config: TConfig & { name: string; }; /** Flat list of all Entities currently in play, used for efficiently executing frame ticks and in filtering */ private entities; /** Entities with Shaders and Models, grouped by the same, used for optimising vertex compilation and gl API call handling */ private readonly renderableEntities; /** Flat list of Entities to be added on the next frame */ private addList; /** Flat list of Entities to be removed on the next frame */ private removeList; /** Map of VBOs constructed and used in rendering, used to reduce the number of vertex compilations for Entities and gl buffer calls */ private readonly vbos; /** Cached Entity filters, used in optimising filters */ private readonly entityFilterCache; /** * Cached specific-source Entity filters, used in optimising filters from specific sources * * Separated from regular filters so as not to produce conflicts between similar filters of all Entities and subsets */ private readonly sourcedEntityFilterCache; /** * Constructor. Take and store the EntityManager's config, and initialise the Texture Atlas if provided * * @param renderer the renderer */ constructor(config: TConfig & { name: string; }); /** * Getter for the number of active Entities * * @returns the number of active Entities */ get entityCount(): number; /** * Add an Entity to the addList, to be added to the game on the next frame * * @param entity the Entity to add */ addEntity(entity: Entity): void; /** * Add a list of Entities to the addList, to be added to the game on the next frame * * @param entities the Entities to add */ addEntities(...entities: Array): void; /** * Add an Entity to the removeList, to be removed from the game on the next frame * * @param entity the Entity to remove */ removeEntity(entity: Entity): void; /** * Add a list of Entities to the removeList, to be removed from the game on the next frame * * @param entities the Entities to remove */ removeEntities(...entities: Array): void; /** * Purge all active Entities immediately */ clearEntities(): void; /** * Frame update method. Augment the Entity list by processing the addList and removeList, then update all active Entities * * @param frameDelta the time between the last frame and the current, for normalizing time-dependent operations */ tick(game: Game, frameDelta: number): void; /** * Frame render method, called after tick so as to render all renderable active Entities * * Processes Entities grouped by given shader+model combinations so as to reduce the amount of GL buffering required and render all * technically-similar Entities from a single vertex source * * // TODO draw order problem: since Entities are grouped, batches of same-shader+model Entities are rendered in the order new * // new combinations were added to the game, instead of the order the Entities were added to the game. Tricky problem; want for a * // way of defining a draw order from the outside maybe, but without undoing the optimisation that shader+model grouping represents */ render(): void; /** * Filter the active Entities by a given Component name. Filter results are cached to optimise frame-to-frame filters * * @param component the name of the Component to filter by * * @returns the list of Entities with the Component */ filterEntitiesByComponentName(component: string): Array; /** * Filter the active Entities by a given list of Component names. Filter results are cached to optimise frame-to-frame filters * * @param components the names of the Components to filter by * * @returns the list of Entities with the Components */ filterEntitiesByComponentNames(...components: Array): Array; /** * Filter the Entities in a given source by a given list of Component names. Filter results are cached to optimise frame-to-frame * filters * * @param source the Entity list to treat as the filter source * @param filterId an identifier for the filter result, used to avoid conflicts for similar filters across disparate sources * @param components the names of the Components to filter by * * @returns the list of Entities from the source with the Components */ filterEntitiesByComponentNamesFromSource(source: Array, filterId: string, ...components: Array): Array; /** * Filter the active Entities by a given tag. Filter results are cached to optimise frame-to-frame filters * * @param tag the tag to filter by * * @returns the list of Entities with the tag */ filterEntitiesByTag(tag: string): Array; /** * Filter the active Entities by a given list of tags. Filter results are cached to optimise frame-to-frame filters * * @param tags the tags to filter by * * @returns the list of Entities with the tags */ filterEntitiesByTags(...tags: Array): Array; /** * Process the addList by adding Entities both to the grouped store and the flat store, facilitating both fast filters and efficient * rendering * * @returns a boolean indicating whether or not the Entity lists were changed, signalling the need to invalidate cached filters */ private loadEntities; /** * Clean the list of active Entities by removing all those in the removeList * * @returns a boolean indicating whether or not the Entity lists were changed, signalling the need to invalidate cached filters */ private cleanEntities; /** * Compile any vertex lists and update relevant VBOs for a given set of shader+model combinations altered in Entity list changes * * // TODO entity change detection: further optimise vertex compilation and buffering by recompiling and buffering on a per * // Entity basis * * @param changes the list of Shader+Model combinations that were altered and require compiling */ private compileVertices; /** * Retrieve a set of Entities by filtering Entities by the given predicate, caching the result to reduce frame-to-frame filtering * operations * * Support filtering from a specific source as well as from all Entities so as to facilitate multiple use cases * * Separate regular filters from sourced filters so as to avoid conflicts between similar filters of all Entities and subsets * * Further separate sourced filters from each other with a filterId so as to avoid conflicts between similar filters from disparate * sources * * // TODO would be nice if we could detect and invalidate only those filter caches which will change based on add/remove * // work relevant alongside Entity change detection optimisation for vertex compilation and buffering * * @param filter a string representation of the Entity filter, to be used as a cache key * @param predicate the filter predicate for matching Entities * @param filterId (optional) a filter ID for sourced filters, to be used as a cache key extension. Must be provided for sourced filters * @param source the source to filter from; defaulting to the flat list of all Entities * * @returns the array of Entities matching the filter */ private memoizeFilter; /** * Clear all filter caches in the event of an Entity list change by way of loadEntities or cleanEntities, ensuring that filters do not * become out of date * * // TODO would be nice if we could detect and invalidate only those filter caches which will change based on add/remove * // work relevant alongside Entity change detection optimisation for vertex compilation and buffering */ private invalidateFilterCaches; }