Troika: Peringatan "Sejumlah besar permintaan WorkerModule terbuka, beberapa mungkin tidak kembali"

Dibuat pada 30 Mar 2021  ·  14Komentar  ·  Sumber: protectwise/troika

Halo, Saya melihat sejumlah besar peringatan datang dari troika-worker.utils.esm.js dengan pesan ini.

Screen Shot 2021-03-29 at 8 19 42 PM

Semuanya tampaknya berfungsi dengan baik

ada ide?

Semua 14 komentar

Hmm, peringatan itu tidak terpicu hingga ada >1000 permintaan pekerja terbuka. Apakah Anda memiliki banyak sekali contoh teks?

Ya, tapi tidak lebih dari 1000 (setidaknya tidak sengaja)

lebih seperti beberapa ratus

Inilah yang saya render

Screen Shot 2021-03-30 at 11 03 39 AM

Tapi jadi apa yang Anda katakan bahwa mungkin ada bug di pihak saya di mana saya membuat lebih banyak contoh daripada yang sebenarnya saya butuhkan dan setelah saya melewati 1000 hitungan itu mulai menimbulkan kesalahan?

Saya telah menyetel instance yang tidak memiliki konten ke .visible = false

tapi saya kira itu masih berarti instance itu ada

apakah Anda akan merekomendasikan daripada menggunakan prop .visible untuk menghapus instance yang tidak digunakan sepenuhnya?

Ahh, itu bisa menjelaskannya. Panggilan apa pun ke .sync() akan tetap dilakukan kepada pekerja di latar belakang meskipun visible:false , dan panggilan tersebut akan menumpuk.

Saya pikir saya pribadi akan memilih untuk membuat/membuang label sesuai permintaan, atau setidaknya mencegah panggilan .sync() untuk yang tersembunyi. Semua permintaan pekerja itu menggunakan pekerja yang sama, jadi jika sibuk memproses label tersembunyi, itu bisa menunda pemrosesan label yang terlihat.

Namun, saya membuat beberapa asumsi, karena tidak melihat kode LabelView Anda yang sebenarnya. Mungkin masih ada bug di pihak saya, jadi LMK apa yang Anda temukan.

Baru saja mencoba memanggil .sync() ketika .visible === true

tapi tetap mendapat peringatan

jika sebaliknya saya hanya membuat instance untuk objek yang terlihat dan menghancurkan yang tidak digunakan maka peringatannya hilang

Hmm, Text sendiri hanya memanggil sync() di onBeforeRender, yang _seharusnya tidak_ terpicu jika visible=false.

Apakah kode pembungkus LabelView Anda tersedia di mana saja saya bisa mengintip?

Itu bagian dari proyek sumber tertutup

tapi di sini adalah kelas yang relevan, yang mungkin cukup

import {Mesh, MeshBasicMaterial} from "three";
import R from "../../../../../../../../../../resources/Namespace";
import BaseView, {ViewType} from "./BaseView";
import {Text} from "troika-three-text";
import {GeometryInstances} from "../instances/GeometryInstances";
import {MaterialInstances} from "../instances/MaterialInstances";

export enum TextAlign {
    left = "left",
    right = "right",
    center = "center",
    justify = "justify",
}

export enum HorizontalAlign {
    left = "left",
    right = "right",
    center = "center",
}

export enum VerticalAlign {
    top = "top",
    topBaseline = "top-baseline",
    middle = "middle",
    bottomBaseline = "bottom-baseline",
    bottom = "bottom",
}

export interface ILabelData {
    content: string;
    fontFace?: string;
    fontSize?: number;
    alignment?: TextAlign;
    horizontalAlign?: HorizontalAlign;
    verticalAlign?: VerticalAlign;
    color?: string;
    opacity?: number;
    backgroundColor?: string;
    highlightable: boolean;
}

export default class LabelView extends BaseView {
    get viewObject() {
        return this._viewObject as any;
    }

    get content() {
        return this.textMesh.text;
    }

    set content(content: string) {
        if (content !== this.textMesh.text) {
            this.textMesh.text = content;
            this.textMesh.visible = !!content;

            this.syncIfVisible();
        }
    }

    private syncIfVisible() {
        // Better for perf: https://github.com/protectwise/troika/issues/112
        if (this.textMesh?.text && this.textMesh?.visible && this._isVisible) {
            this.textMesh.sync();
        }
    }

    set textAlign(alignment: TextAlign) {
        this.textMesh.textAlign = alignment;
        this.syncIfVisible();
    }

    set horizontalAlign(alignment: HorizontalAlign) {
        this.textMesh.anchorX = alignment;
        this.syncIfVisible();
    }

    set verticalAlign(alignment: VerticalAlign) {
        this.textMesh.anchorY = alignment;
        this.syncIfVisible();
    }

    private backgroundMesh: Mesh | undefined;
    private readonly textMesh: any;
    private readonly foregroundColor: string;
    private highlightable: boolean;

    constructor(labelData: ILabelData) {
        super(ViewType.Label);

        this.foregroundColor = labelData.color || R.colors.elements.labels.foreground;

        this.highlightable = labelData.highlightable;

        if (labelData.backgroundColor) {
            this.textMesh = this.createTextMesh(
                labelData.content,
                labelData.fontFace,
                labelData.fontSize,
                labelData.alignment,
                labelData.horizontalAlign,
                labelData.verticalAlign,
                this.foregroundColor,
                labelData.opacity,
                1);

            this.textMesh.addEventListener("synccomplete", () => {
                if (this.backgroundMesh) {
                    this._viewObject.remove(this.backgroundMesh);
                }

                if (this.textMesh.text) {
                    const bounds = this.textMesh.textRenderInfo.blockBounds;
                    this.backgroundMesh =
                        this.createBackgroundBox(bounds[0], bounds[1], bounds[2], bounds[3], 0);
                    this._viewObject.add(this.backgroundMesh);
                }
            });

        } else {
            this.textMesh = this.createTextMesh(
                labelData.content,
                labelData.fontFace,
                labelData.fontSize,
                labelData.alignment,
                labelData.horizontalAlign,
                labelData.verticalAlign,
                this.foregroundColor,
                labelData.opacity,
                0);
        }

        this.syncIfVisible();

        this._viewObject.add(this.textMesh);
    }

    public onFrameRendered(elapsedTime: number) {
        if (this.highlightable) {
            this.setLabelHighlightState();
        }
    }

    private setLabelHighlightState() {
        const labelMaterial = this.textMesh.material as MeshBasicMaterial;
        if (this._isHighlighted) {
            labelMaterial.color.set(R.colors.elements.labels.highlighted);
        } else {
            labelMaterial.color.set(this.foregroundColor);
        }
    }

    private createTextMesh(content: string,
                           fontFace = R.layout.labels.font_face.regular,
                           fontSize = R.layout.labels.font_size,
                           textAlign = TextAlign.center,
                           horizontalAlign = HorizontalAlign.center,
                           verticalAlign = VerticalAlign.middle,
                           color: string,
                           opacity = 1,
                           zLevel: number) {
        const labelMesh = new Text();

        labelMesh.font = fontFace;
        labelMesh.text = content || "";
        labelMesh.fontSize = fontSize;
        labelMesh.position.z = zLevel;
        labelMesh.color = color;
        labelMesh.textAlign = textAlign;
        labelMesh.anchorX = horizontalAlign;
        labelMesh.anchorY = verticalAlign;

        labelMesh.material.opacity = opacity;
        labelMesh.name = "LabelView";

        return labelMesh;
    }

    private createBackgroundBox(startX: number, startY: number, endX: number, endY: number, zLevel: number) {
        const paddingLeft = 1;
        const paddingRight = 2;
        const paddingTop = 1;
        const paddingBottom = 0;

        const width = Math.abs(startX) + Math.abs(endX) + paddingLeft + paddingRight;
        const height = Math.abs(startY) + Math.abs(endY) + (paddingTop + paddingBottom);

        const geometry = GeometryInstances.getInstance().getPlaneGeometryInstance(width, height);
        const material = MaterialInstances.getInstance().backgroundColorMaterial;
        const mesh = new Mesh(geometry, material);

        const posX = ((startX + endX) / 2) + (paddingLeft / 4);
        const posY = ((startY + endY) / 2) - (paddingBottom);

        // The z level of element in accordance with standards defined in resources
        mesh.position.set(posX, posY, zLevel);
        mesh.name = "LabelBackgroundBox";

        return mesh;
    }
}

Hmm, firasat saya adalah syncIfVisible() dipanggil sebelum .visible disetel ke false, tetapi sulit untuk mengatakan dengan pasti tanpa mengetahui cara kerja sistem tampilan Anda.

Hal lain yang saya perhatikan adalah Anda mengeluarkan panggilan syncIfVisible setelah setiap perubahan properti individu (konten, textAlign, horizontalAlign, dll.) yang akan mengeluarkan lebih banyak panggilan ke pekerja daripada yang diperlukan. Jika sistem tampilan Anda memiliki siklus hidup di mana Anda dapat mengeluarkan satu panggilan sinkronisasi setelah semua properti individual disetel, itu akan jauh lebih baik.

Dari apa yang Anda jelaskan, saya pikir peringatan ini berperilaku seperti yang diharapkan; itu dengan benar menyoroti masalah kinerja. Saya menutup masalah ini; jangan ragu untuk membukanya kembali jika Anda percaya secara berbeda. Terima kasih!

Baru kembali ke ini

Jadi ternyata saya dengan mudah memiliki lebih dari 1000 contoh teks dalam adegan saya. Tapi ada tidak semua terlihat pada saat yang sama

Banyak dari mereka hanya muncul di mouse-over dari objek tertentu

Jadi saya bertanya-tanya apa cara terbaik untuk maju di sini:

  1. buat instance hanya untuk teks yang terlihat dan kemudian lepaskan segera setelah menjadi tidak terlihat?
  2. gunakan objek CSS ThreeJS saja?

Secara pribadi saya akan memilih opsi pertama. Saya bisa saja salah, tetapi saya rasa tidak ada gunanya memiliki semua objek label tersembunyi yang ada di grafik adegan.

Mengerti

Saya harus bisa menunjukkannya dengan cepat di mouse hover objek

Apakah Anda merekomendasikan untuk menghancurkannya setelah digunakan dan membuat yang baru saat melayang atau hanya menghapusnya dari adegan threeJs saja?

Sejujurnya saya tidak berpikir akan ada perbedaan yang mencolok. Saya akan mulai dengan apa pun yang paling sederhana untuk dikelola dan dioptimalkan hanya jika Anda melihat ada masalah.

Secara pribadi saya telah banyak melakukan pendekatan buat/hancurkan, dan itu selalu sangat cepat bagi saya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

lojjic picture lojjic  ·  11Komentar

arpu picture arpu  ·  43Komentar

Ocelyn picture Ocelyn  ·  13Komentar

stephencorwin picture stephencorwin  ·  39Komentar

asbjornlystrup picture asbjornlystrup  ·  7Komentar