<commit_before>﻿module BABYLON {
    export class ProceduralTexture extends Texture {
        @serialize()
        private _size: number;

        /** @hidden */
        @serialize()
        public _generateMipMaps: boolean;

        @serialize()
        public isEnabled = true;
        private _currentRefreshId = -1;
        private _refreshRate = 1;

        public onGenerated: () => void;

        private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
        private _indexBuffer: Nullable<WebGLBuffer>;
        private _effect: Effect;

        private _uniforms = new Array<string>();
        private _samplers = new Array<string>();
        private _fragment: any;

        /** @hidden */
        public _textures: { [key: string]: Texture } = {};
        private _floats: { [key: string]: number } = {};
        private _ints: { [key: string]: number } = {};
        private _floatsArrays: { [key: string]: number[] } = {};
        private _colors3: { [key: string]: Color3 } = {};
        private _colors4: { [key: string]: Color4 } = {};
        private _vectors2: { [key: string]: Vector2 } = {};
        private _vectors3: { [key: string]: Vector3 } = {};
        private _matrices: { [key: string]: Matrix } = {};

        private _fallbackTexture: Nullable<Texture>;

        private _fallbackTextureUsed = false;
        private _engine: Engine;

        constructor(name: string, size: any, fragment: any, scene: Nullable<Scene>, fallbackTexture: Nullable<Texture> = null, generateMipMaps = true, public isCube = false) {
            super(null, scene, !generateMipMaps);

            scene = this.getScene()!;

            scene.proceduralTextures.push(this);

            this._engine = scene.getEngine();

            this.name = name;
            this.isRenderTarget = true;
            this._size = size;
            this._generateMipMaps = generateMipMaps;

            this.setFragment(fragment);

            this._fallbackTexture = fallbackTexture;

            if (isCube) {
                this._texture = this._engine.createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps });
                this.setFloat("face", 0);
            }
            else {
                this._texture = this._engine.createRenderTargetTexture(size, generateMipMaps);
            }

            // VBO
            var vertices = [];
            vertices.push(1, 1);
            vertices.push(-1, 1);
            vertices.push(-1, -1);
            vertices.push(1, -1);

            this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(this._engine, vertices, VertexBuffer.PositionKind, false, false, 2);

            this._createIndexBuffer();
        }

        private _createIndexBuffer(): void {
            var engine = this._engine;

            // Indices
            var indices = [];
            indices.push(0);
            indices.push(1);
            indices.push(2);

            indices.push(0);
            indices.push(2);
            indices.push(3);

            this._indexBuffer = engine.createIndexBuffer(indices);
        }

        /** @hidden */
        public _rebuild(): void {
            let vb = this._vertexBuffers[VertexBuffer.PositionKind];

            if (vb) {
                vb._rebuild();
            }

            this._createIndexBuffer();

            if (this.refreshRate === RenderTargetTexture.REFRESHRATE_RENDER_ONCE) {
                this.refreshRate = RenderTargetTexture.REFRESHRATE_RENDER_ONCE;
            }
        }

        public reset(): void {
            if (this._effect === undefined) {
                return;
            }

            var engine = this._engine;
            engine._releaseEffect(this._effect);
        }

        protected _getDefines(): string {
            return "";
        }


        public isReady(): boolean {
            var engine = this._engine;
            var shaders;

            if (!this._fragment) {
                return false;
            }

            if (this._fallbackTextureUsed) {
                return true;
            }

            if (this._fragment.fragmentElement !== undefined) {
                shaders = { vertex: "procedural", fragmentElement: this._fragment.fragmentElement };
            }
            else {
                shaders = { vertex: "procedural", fragment: this._fragment };
            }

            let defines = this._getDefines();

            this._effect = engine.createEffect(shaders,
                [VertexBuffer.PositionKind],
                this._uniforms,
                this._samplers,
                defines, undefined, undefined, () => {
                    this.releaseInternalTexture();

                    if (this._fallbackTexture) {
                        this._texture = this._fallbackTexture._texture;

                        if (this._texture) {
                            this._texture.incrementReferences();
                        }
                    }

                    this._fallbackTextureUsed = true;
                });

            return this._effect.isReady();
        }

        public resetRefreshCounter(): void {
            this._currentRefreshId = -1;
        }

        public setFragment(fragment: any) {
            this._fragment = fragment;
        }

        @serialize()<commit_msg>Added cache for effect in procedurals<commit_after>﻿module BABYLON {
    export class ProceduralTexture extends Texture {
        @serialize()
        private _size: number;

        /** @hidden */
        @serialize()
        public _generateMipMaps: boolean;

        @serialize()
        public isEnabled = true;
        private _currentRefreshId = -1;
        private _refreshRate = 1;

        public onGenerated: () => void;

        private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
        private _indexBuffer: Nullable<WebGLBuffer>;
        private _effect: Effect;

        private _uniforms = new Array<string>();
        private _samplers = new Array<string>();
        private _fragment: any;

        /** @hidden */
        public _textures: { [key: string]: Texture } = {};
        private _floats: { [key: string]: number } = {};
        private _ints: { [key: string]: number } = {};
        private _floatsArrays: { [key: string]: number[] } = {};
        private _colors3: { [key: string]: Color3 } = {};
        private _colors4: { [key: string]: Color4 } = {};
        private _vectors2: { [key: string]: Vector2 } = {};
        private _vectors3: { [key: string]: Vector3 } = {};
        private _matrices: { [key: string]: Matrix } = {};

        private _fallbackTexture: Nullable<Texture>;

        private _fallbackTextureUsed = false;
        private _engine: Engine;

        private _cachedDefines = "";

        constructor(name: string, size: any, fragment: any, scene: Nullable<Scene>, fallbackTexture: Nullable<Texture> = null, generateMipMaps = true, public isCube = false) {
            super(null, scene, !generateMipMaps);

            scene = this.getScene()!;

            scene.proceduralTextures.push(this);

            this._engine = scene.getEngine();

            this.name = name;
            this.isRenderTarget = true;
            this._size = size;
            this._generateMipMaps = generateMipMaps;

            this.setFragment(fragment);

            this._fallbackTexture = fallbackTexture;

            if (isCube) {
                this._texture = this._engine.createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps });
                this.setFloat("face", 0);
            }
            else {
                this._texture = this._engine.createRenderTargetTexture(size, generateMipMaps);
            }

            // VBO
            var vertices = [];
            vertices.push(1, 1);
            vertices.push(-1, 1);
            vertices.push(-1, -1);
            vertices.push(1, -1);

            this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(this._engine, vertices, VertexBuffer.PositionKind, false, false, 2);

            this._createIndexBuffer();
        }

        private _createIndexBuffer(): void {
            var engine = this._engine;

            // Indices
            var indices = [];
            indices.push(0);
            indices.push(1);
            indices.push(2);

            indices.push(0);
            indices.push(2);
            indices.push(3);

            this._indexBuffer = engine.createIndexBuffer(indices);
        }

        /** @hidden */
        public _rebuild(): void {
            let vb = this._vertexBuffers[VertexBuffer.PositionKind];

            if (vb) {
                vb._rebuild();
            }

            this._createIndexBuffer();

            if (this.refreshRate === RenderTargetTexture.REFRESHRATE_RENDER_ONCE) {
                this.refreshRate = RenderTargetTexture.REFRESHRATE_RENDER_ONCE;
            }
        }

        public reset(): void {
            if (this._effect === undefined) {
                return;
            }

            var engine = this._engine;
            engine._releaseEffect(this._effect);
        }

        protected _getDefines(): string {
            return "";
        }


        public isReady(): boolean {
            var engine = this._engine;
            var shaders;

            if (!this._fragment) {
                return false;
            }

            if (this._fallbackTextureUsed) {
                return true;
            }

            let defines = this._getDefines();
            if (defines === this._cachedDefines && this._effect.isReady()) {
                return true;
            }

            if (this._fragment.fragmentElement !== undefined) {
                shaders = { vertex: "procedural", fragmentElement: this._fragment.fragmentElement };
            }
            else {
                shaders = { vertex: "procedural", fragment: this._fragment };
            }

            this._cachedDefines = defines;

            this._effect = engine.createEffect(shaders,
                [VertexBuffer.PositionKind],
                this._uniforms,
                this._samplers,
                defines, undefined, undefined, () => {
                    this.releaseInternalTexture();

                    if (this._fallbackTexture) {
                        this._texture = this._fallbackTexture._texture;

                        if (this._texture) {
                            this._texture.incrementReferences();
                        }
                    }

                    this._fallbackTextureUsed = true;
                });

            return this._effect.isReady();
        }

        public resetRefreshCounter(): void {
            this._currentRefreshId = -1;
        }

        public setFragment(fragment: any) {
            this._fragment = fragment;
        }

        @serialize()
{'fraction_non_alphanumeric': 0.10888725670216673, 'fraction_numerical': 0.004957767168564084, 'mean_word_length': 1.5929540585574864, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3749744', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2733, 'n_words': 584}