'use strict'; var Color = require('../../../../color/Color.js'); var autoDetectEnvironment = require('../../../../environment/autoDetectEnvironment.js'); var Container = require('../../../../scene/container/Container.js'); var unsafeEvalSupported = require('../../../../utils/browser/unsafeEvalSupported.js'); var deprecation = require('../../../../utils/logging/deprecation.js'); require('../../../../utils/utils.js'); var _const = require('../../gl/const.js'); var SystemRunner = require('./SystemRunner.js'); var EventEmitter = require('eventemitter3'); "use strict"; const defaultRunners = [ "init", "destroy", "contextChange", "resolutionChange", "reset", "renderEnd", "renderStart", "render", "update", "postrender", "prerender" ]; const _AbstractRenderer = class _AbstractRenderer extends EventEmitter { /** * Set up a system with a collection of SystemClasses and runners. * Systems are attached dynamically to this class when added. * @param config - the config for the system manager */ constructor(config) { super(); this.runners = /* @__PURE__ */ Object.create(null); this.renderPipes = /* @__PURE__ */ Object.create(null); this._initOptions = {}; this._systemsHash = /* @__PURE__ */ Object.create(null); this.type = config.type; this.name = config.name; this.config = config; const combinedRunners = [...defaultRunners, ...this.config.runners ?? []]; this._addRunners(...combinedRunners); this._unsafeEvalCheck(); } /** * Initialize the renderer. * @param options - The options to use to create the renderer. */ async init(options = {}) { const skip = options.skipExtensionImports === true ? true : options.manageImports === false; await autoDetectEnvironment.loadEnvironmentExtensions(skip); this._addSystems(this.config.systems); this._addPipes(this.config.renderPipes, this.config.renderPipeAdaptors); for (const systemName in this._systemsHash) { const system = this._systemsHash[systemName]; const defaultSystemOptions = system.constructor.defaultOptions; options = { ...defaultSystemOptions, ...options }; } options = { ..._AbstractRenderer.defaultOptions, ...options }; this._roundPixels = options.roundPixels ? 1 : 0; for (let i = 0; i < this.runners.init.items.length; i++) { await this.runners.init.items[i].init(options); } this._initOptions = options; } render(args, deprecated) { let options = args; if (options instanceof Container.Container) { options = { container: options }; if (deprecated) { deprecation.deprecation(deprecation.v8_0_0, "passing a second argument is deprecated, please use render options instead"); options.target = deprecated.renderTexture; } } options.target || (options.target = this.view.renderTarget); if (options.target === this.view.renderTarget) { this._lastObjectRendered = options.container; options.clearColor = this.background.colorRgba; } if (options.clearColor) { const isRGBAArray = Array.isArray(options.clearColor) && options.clearColor.length === 4; options.clearColor = isRGBAArray ? options.clearColor : Color.Color.shared.setValue(options.clearColor).toArray(); } if (!options.transform) { options.container.updateLocalTransform(); options.transform = options.container.localTransform; } this.runners.prerender.emit(options); this.runners.renderStart.emit(options); this.runners.render.emit(options); this.runners.renderEnd.emit(options); this.runners.postrender.emit(options); } /** * Resizes the WebGL view to the specified width and height. * @param desiredScreenWidth - The desired width of the screen. * @param desiredScreenHeight - The desired height of the screen. * @param resolution - The resolution / device pixel ratio of the renderer. */ resize(desiredScreenWidth, desiredScreenHeight, resolution) { const previousResolution = this.view.resolution; this.view.resize(desiredScreenWidth, desiredScreenHeight, resolution); this.emit("resize", this.view.screen.width, this.view.screen.height, this.view.resolution); if (resolution !== void 0 && resolution !== previousResolution) { this.runners.resolutionChange.emit(resolution); } } clear(options = {}) { const renderer = this; options.target || (options.target = renderer.renderTarget.renderTarget); options.clearColor || (options.clearColor = this.background.colorRgba); options.clear ?? (options.clear = _const.CLEAR.ALL); const { clear, clearColor, target } = options; Color.Color.shared.setValue(clearColor ?? this.background.colorRgba); renderer.renderTarget.clear(target, clear, Color.Color.shared.toArray()); } /** The resolution / device pixel ratio of the renderer. */ get resolution() { return this.view.resolution; } set resolution(value) { this.view.resolution = value; this.runners.resolutionChange.emit(value); } /** * Same as view.width, actual number of pixels in the canvas by horizontal. * @member {number} * @readonly * @default 800 */ get width() { return this.view.texture.frame.width; } /** * Same as view.height, actual number of pixels in the canvas by vertical. * @default 600 */ get height() { return this.view.texture.frame.height; } // NOTE: this was `view` in v7 /** * The canvas element that everything is drawn to. * @type {environment.ICanvas} */ get canvas() { return this.view.canvas; } /** * the last object rendered by the renderer. Useful for other plugins like interaction managers * @readonly */ get lastObjectRendered() { return this._lastObjectRendered; } /** * Flag if we are rendering to the screen vs renderTexture * @readonly * @default true */ get renderingToScreen() { const renderer = this; return renderer.renderTarget.renderingToScreen; } /** * Measurements of the screen. (0, 0, screenWidth, screenHeight). * * Its safe to use as filterArea or hitArea for the whole stage. */ get screen() { return this.view.screen; } /** * Create a bunch of runners based of a collection of ids * @param runnerIds - the runner ids to add */ _addRunners(...runnerIds) { runnerIds.forEach((runnerId) => { this.runners[runnerId] = new SystemRunner.SystemRunner(runnerId); }); } _addSystems(systems) { let i; for (i in systems) { const val = systems[i]; this._addSystem(val.value, val.name); } } /** * Add a new system to the renderer. * @param ClassRef - Class reference * @param name - Property name for system, if not specified * will use a static `name` property on the class itself. This * name will be assigned as s property on the Renderer so make * sure it doesn't collide with properties on Renderer. * @returns Return instance of renderer */ _addSystem(ClassRef, name) { const system = new ClassRef(this); if (this[name]) { throw new Error(`Whoops! The name "${name}" is already in use`); } this[name] = system; this._systemsHash[name] = system; for (const i in this.runners) { this.runners[i].add(system); } return this; } _addPipes(pipes, pipeAdaptors) { const adaptors = pipeAdaptors.reduce((acc, adaptor) => { acc[adaptor.name] = adaptor.value; return acc; }, {}); pipes.forEach((pipe) => { const PipeClass = pipe.value; const name = pipe.name; const Adaptor = adaptors[name]; this.renderPipes[name] = new PipeClass( this, Adaptor ? new Adaptor() : null ); }); } destroy(options = false) { this.runners.destroy.items.reverse(); this.runners.destroy.emit(options); Object.values(this.runners).forEach((runner) => { runner.destroy(); }); this._systemsHash = null; this.renderPipes = null; } /** * Generate a texture from a container. * @param options - options or container target to use when generating the texture * @returns a texture */ generateTexture(options) { return this.textureGenerator.generateTexture(options); } /** * Whether the renderer will round coordinates to whole pixels when rendering. * Can be overridden on a per scene item basis. */ get roundPixels() { return !!this._roundPixels; } /** * Overridable function by `pixi.js/unsafe-eval` to silence * throwing an error if platform doesn't support unsafe-evals. * @private * @ignore */ _unsafeEvalCheck() { if (!unsafeEvalSupported.unsafeEvalSupported()) { throw new Error("Current environment does not allow unsafe-eval, please use pixi.js/unsafe-eval module to enable support."); } } }; /** The default options for the renderer. */ _AbstractRenderer.defaultOptions = { /** * Default resolution / device pixel ratio of the renderer. * @default 1 */ resolution: 1, /** * Should the `failIfMajorPerformanceCaveat` flag be enabled as a context option used in the `isWebGLSupported` * function. If set to true, a WebGL renderer can fail to be created if the browser thinks there could be * performance issues when using WebGL. * * In PixiJS v6 this has changed from true to false by default, to allow WebGL to work in as many * scenarios as possible. However, some users may have a poor experience, for example, if a user has a gpu or * driver version blacklisted by the * browser. * * If your application requires high performance rendering, you may wish to set this to false. * We recommend one of two options if you decide to set this flag to false: * * 1: Use the Canvas renderer as a fallback in case high performance WebGL is * not supported. * * 2: Call `isWebGLSupported` (which if found in the utils package) in your code before attempting to create a * PixiJS renderer, and show an error message to the user if the function returns false, explaining that their * device & browser combination does not support high performance WebGL. * This is a much better strategy than trying to create a PixiJS renderer and finding it then fails. * @default false */ failIfMajorPerformanceCaveat: false, /** * Should round pixels be forced when rendering? * @default false */ roundPixels: false }; let AbstractRenderer = _AbstractRenderer; exports.AbstractRenderer = AbstractRenderer; //# sourceMappingURL=AbstractRenderer.js.map