Troika: تحذير "عدد كبير من طلبات WorkerModule المفتوحة ، قد لا يعود بعضها"

تم إنشاؤها على ٣٠ مارس ٢٠٢١  ·  14تعليقات  ·  مصدر: protectwise/troika

مرحبًا ، أرى قدرًا كبيرًا من التحذيرات القادمة من troika-worker.utils.esm.js مع هذه الرسالة.

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

يبدو أن كل شيء يعمل بشكل جيد

اي فكرة؟

ال 14 كومينتر

حسنًا ، لا يتم تشغيل هذا التحذير حتى يكون هناك> 1000 طلب عامل مفتوح. هل لديك عدد كبير جدًا من مثيلات النص؟

أنا أفعل ، لكن ليس أكثر من 1000 (على الأقل ليس عن قصد)

مثل بضع مئات

إليكم ما أقوم بتقديمه

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

ولكن ما تقوله أنه ربما يكون هناك خطأ في جانبي حيث أقوم بإنشاء حالات أكثر مما أحتاجه بالفعل وبمجرد تجاوز عدد الألف ، يبدأ في إلقاء خطأ؟

لقد قمت بتعيين الحالات التي ليس لها محتوى على .visible = false

لكنني أعتقد أن هذا لا يزال يعني وجود المثيل

هل تقترح بدلاً من استخدام الخاصية .visible لإزالة المثيلات غير المستخدمة بالكامل؟

آه ، هذا يمكن أن يفسر ذلك. سيستمر إصدار أي مكالمات إلى .sync () إلى العامل في الخلفية حتى لو كانت مرئية: خطأ ، وسوف تتراكم.

أعتقد أنني سأختار شخصيًا إنشاء / التخلص من الملصقات عند الطلب ، أو على الأقل منع استدعاءات .sync () للتسميات المخفية. يطلب هؤلاء العاملون جميعًا استخدام نفس العامل ، لذا إذا كان مشغولًا بمعالجة التسميات المخفية ، فقد يؤدي ذلك إلى تأخير معالجة العلامات المرئية.

أنا أفترض بعض الافتراضات ، على الرغم من أنني لم أر كود LabelView الدقيق الخاص بك. لا يزال من المحتمل أن يكون هناك خطأ من طرفي ، لذا ما وجدته LMK.

حاولت فقط استدعاء .sync () عندما .visible === true

ولكن لا يزال يتلقى التحذيرات

إذا قمت بدلاً من ذلك بإنشاء حالات للأشياء المرئية وتدمير العناصر غير المستخدمة ، فستختفي التحذيرات

حسنًا ، يستدعي Text نفسه فقط sync () في onBeforeRender ، والتي _لا ينبغي_ تشغيلها إذا كانت مرئية = خطأ.

هل يتوفر رمز غلاف LabelView الخاص بك في أي مكان يمكنني فيه إلقاء نظرة خاطفة؟

إنه جزء من مشروع مغلق المصدر

ولكن ها هي الفئة ذات الصلة ، والتي قد تكون كافية

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;
    }
}

حسنًا ، سيكون حدسي syncIfVisible () يتم استدعاؤه قبل تعيين .visible على خطأ ، ولكن من الصعب الجزم بذلك دون معرفة كيفية عمل نظام العرض لديك.

هناك شيء آخر ألاحظه وهو أنك تقوم بإصدار مكالمات syncIfVisible بعد كل تغيير للخاصية الفردية (المحتوى ، محاذاة النص ، الأفقي ، وما إلى ذلك) والتي ستصدر المزيد من المكالمات إلى العامل أكثر من اللازم. إذا كان نظام العرض الخاص بك يحتوي على دورة حياة حيث يمكنك إصدار مكالمة مزامنة واحدة بعد تعيين جميع الخصائص الفردية ، فسيكون ذلك أفضل بكثير.

مما وصفته ، أعتقد أن هذا التحذير يتصرف كما هو متوقع ؛ سلطت الضوء بشكل صحيح على مشكلة في الأداء. أنا أغلق هذه القضية. لا تتردد في إعادة فتحه إذا كنت تعتقد بشكل مختلف. شكرا!

فقط أعود إلى هذا

لذلك اتضح أن لدي أكثر من 1000 مثيل نصي في المشهد الخاص بي بسهولة. ولكن ليس كل شيء مرئيًا في نفس الوقت

يظهر العديد منها عند تمرير الماوس فوق كائنات معينة

لذلك أتساءل ما هي أفضل طريقة للمضي قدمًا هنا:

  1. إنشاء مثيلات للنص المرئي فقط ثم إلغاء تحميله بمجرد أن يصبح غير مرئي؟
  2. استخدام كائنات ThreeJS CSS بدلاً من ذلك؟

أنا شخصياً سأختار الخيار الأول. قد أكون مخطئًا ولكن لا أعتقد أن هناك أي فائدة لوجود كل كائنات التسمية المخفية في الرسم البياني للمشهد.

فهمتك

أحتاج إلى أن أكون قادرًا على إظهارها بسرعة عند تمرير الماوس فوق الكائنات

هل توصي فقط بإتلافها بعد الاستخدام وإنشاء أخرى جديدة عند المرور فوقها أو إزالتها فقط من مشهد threeJs بدلاً من ذلك؟

بصراحة لا أعتقد أنه سيكون هناك فرق ملحوظ في كلتا الحالتين. سأبدأ بكل ما هو أبسط لإدارة وتحسين فقط إذا لاحظت مشكلة.

شخصياً ، لقد انتهيت من نهج الإنشاء / التدمير كثيرًا ، ودائمًا ما يكون ذلك سريعًا جدًا بالنسبة لي.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

arpu picture arpu  ·  43تعليقات

stephencorwin picture stephencorwin  ·  39تعليقات

Ocelyn picture Ocelyn  ·  13تعليقات

drcmda picture drcmda  ·  11تعليقات

lojjic picture lojjic  ·  11تعليقات