@pixi/core
Version:
Core PixiJS
1 lines • 6.25 kB
Source Map (JSON)
{"version":3,"file":"SystemManager.mjs","sources":["../../src/system/SystemManager.ts"],"sourcesContent":["import { Runner } from '@pixi/runner';\nimport { EventEmitter } from '@pixi/utils';\n\nimport type { IRenderer } from '../IRenderer';\nimport type { ISystem, ISystemConstructor } from './ISystem';\n\ninterface ISystemConfig<R>\n{\n runners: string[],\n systems: Record<string, ISystemConstructor<R>>\n priority: string[];\n}\n\n/**\n * The SystemManager is a class that provides functions for managing a set of systems\n * This is a base class, that is generic (no render code or knowledge at all)\n * @memberof PIXI\n */\nexport class SystemManager<R=IRenderer> extends EventEmitter\n{\n /** a collection of runners defined by the user */\n readonly runners: {[key: string]: Runner} = {};\n\n private _systemsHash: Record<string, ISystem> = {};\n\n /**\n * Set up a system with a collection of SystemClasses and runners.\n * Systems are attached dynamically to this class when added.\n * @param config - the config for the system manager\n */\n setup(config: ISystemConfig<R>): void\n {\n this.addRunners(...config.runners);\n\n // Remove keys that aren't available\n const priority = (config.priority ?? []).filter((key) => config.systems[key]);\n\n // Order the systems by priority\n const orderByPriority = [\n ...priority,\n ...Object.keys(config.systems)\n .filter((key) => !priority.includes(key))\n ];\n\n for (const i of orderByPriority)\n {\n this.addSystem(config.systems[i], i);\n }\n }\n\n /**\n * Create a bunch of runners based of a collection of ids\n * @param runnerIds - the runner ids to add\n */\n addRunners(...runnerIds: string[]): void\n {\n runnerIds.forEach((runnerId) =>\n {\n this.runners[runnerId] = new Runner(runnerId);\n });\n }\n\n /**\n * Add a new system to the renderer.\n * @param ClassRef - Class reference\n * @param name - Property name for system, if not specified\n * will use a static `name` property on the class itself. This\n * name will be assigned as s property on the Renderer so make\n * sure it doesn't collide with properties on Renderer.\n * @returns Return instance of renderer\n */\n addSystem(ClassRef: ISystemConstructor<R>, name: string): this\n {\n const system = new ClassRef(this as any as R);\n\n if ((this as any)[name])\n {\n throw new Error(`Whoops! The name \"${name}\" is already in use`);\n }\n\n (this as any)[name] = system;\n\n this._systemsHash[name] = system;\n\n for (const i in this.runners)\n {\n this.runners[i].add(system);\n }\n\n /**\n * Fired after rendering finishes.\n * @event PIXI.Renderer#postrender\n */\n\n /**\n * Fired before rendering starts.\n * @event PIXI.Renderer#prerender\n */\n\n /**\n * Fired when the WebGL context is set.\n * @event PIXI.Renderer#context\n * @param {WebGLRenderingContext} gl - WebGL context.\n */\n\n return this;\n }\n\n /**\n * A function that will run a runner and call the runners function but pass in different options\n * to each system based on there name.\n *\n * E.g. If you have two systems added called `systemA` and `systemB` you could call do the following:\n *\n * ```js\n * system.emitWithCustomOptions(init, {\n * systemA: {...optionsForA},\n * systemB: {...optionsForB},\n * });\n * ```\n *\n * `init` would be called on system A passing `optionsForA` and on system B passing `optionsForB`.\n * @param runner - the runner to target\n * @param options - key value options for each system\n */\n emitWithCustomOptions(runner: Runner, options: Record<string, unknown>): void\n {\n const systemHashKeys = Object.keys(this._systemsHash);\n\n runner.items.forEach((system) =>\n {\n // I know this does not need to be a performant function so it.. isn't!\n // its only used for init and destroy.. we can refactor if required..\n const systemName = systemHashKeys.find((systemId) => this._systemsHash[systemId] === system);\n\n system[runner.name](options[systemName]);\n });\n }\n\n /** destroy the all runners and systems. Its apps job to */\n destroy(): void\n {\n Object.values(this.runners).forEach((runner) =>\n {\n runner.destroy();\n });\n\n this._systemsHash = {};\n }\n\n // TODO implement!\n // removeSystem(ClassRef: ISystemConstructor, name: string): void\n // {\n\n // }\n}\n"],"names":[],"mappings":";;AAkBO,MAAM,sBAAmC,aAChD;AAAA,EADO,cAAA;AAAA,UAAA,GAAA,SAAA,GAGH,KAAS,UAAmC,IAE5C,KAAQ,eAAwC;EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjD,MAAM,QACN;AACS,SAAA,WAAW,GAAG,OAAO,OAAO;AAGjC,UAAM,YAAY,OAAO,YAAY,CAAI,GAAA,OAAO,CAAC,QAAQ,OAAO,QAAQ,GAAG,CAAC,GAGtE,kBAAkB;AAAA,MACpB,GAAG;AAAA,MACH,GAAG,OAAO,KAAK,OAAO,OAAO,EACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,SAAS,GAAG,CAAC;AAAA,IAAA;AAGhD,eAAW,KAAK;AAEZ,WAAK,UAAU,OAAO,QAAQ,CAAC,GAAG,CAAC;AAAA,EAE3C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,WACd;AACc,cAAA,QAAQ,CAAC,aACnB;AACI,WAAK,QAAQ,QAAQ,IAAI,IAAI,OAAO,QAAQ;AAAA,IAAA,CAC/C;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,UAAU,UAAiC,MAC3C;AACU,UAAA,SAAS,IAAI,SAAS,IAAgB;AAE5C,QAAK,KAAa,IAAI;AAElB,YAAM,IAAI,MAAM,qBAAqB,IAAI,qBAAqB;AAGjE,SAAa,IAAI,IAAI,QAEtB,KAAK,aAAa,IAAI,IAAI;AAE1B,eAAW,KAAK,KAAK;AAEjB,WAAK,QAAQ,CAAC,EAAE,IAAI,MAAM;AAmBvB,WAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,sBAAsB,QAAgB,SACtC;AACI,UAAM,iBAAiB,OAAO,KAAK,KAAK,YAAY;AAE7C,WAAA,MAAM,QAAQ,CAAC,WACtB;AAGU,YAAA,aAAa,eAAe,KAAK,CAAC,aAAa,KAAK,aAAa,QAAQ,MAAM,MAAM;AAE3F,aAAO,OAAO,IAAI,EAAE,QAAQ,UAAU,CAAC;AAAA,IAAA,CAC1C;AAAA,EACL;AAAA;AAAA,EAGA,UACA;AACI,WAAO,OAAO,KAAK,OAAO,EAAE,QAAQ,CAAC,WACrC;AACI,aAAO,QAAQ;AAAA,IAAA,CAClB,GAED,KAAK,eAAe;EACxB;AAAA;AAAA;AAAA;AAAA;AAOJ;"}