Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

希望能提供一个更高效的 节点批量排序 的方法. #17644

Open
finscn opened this issue Sep 17, 2024 · 2 comments
Open

希望能提供一个更高效的 节点批量排序 的方法. #17644

finscn opened this issue Sep 17, 2024 · 2 comments
Labels
Feature Request Needs Triage Needs to be assigned by the team

Comments

@finscn
Copy link
Contributor

finscn commented Sep 17, 2024

Use Case

目前 cocos 中 如果要实现 node的排序 要基于 setSiblingIndex() 方法.
这个方法 每次交换 节点 都要 执行很多复杂的操作. 偶尔改变一两个节点的顺序 还能接受.
但是如果要大批量大范围的改动 就很低效率.

    public setSiblingIndex (index: number): void {
        if (!this._parent) {
            return;
        }
        if (this._parent._objFlags & Deactivating) {
            errorID(3821);
            return;
        }
        const siblings = this._parent._children;
        index = index !== -1 ? index : siblings.length - 1;
        const oldIndex = siblings.indexOf(this);
        if (index !== oldIndex) {
            siblings.splice(oldIndex, 1);
            if (index < siblings.length) {
                siblings.splice(index, 0, this);
            } else {
                siblings.push(this);
            }
            this._parent._updateSiblingIndex();
            if (this._onSiblingIndexChanged) {
                this._onSiblingIndexChanged(index);
            }
            this._eventProcessor.onUpdatingSiblingIndex();
        }
    }

改变任何一个node的顺序, 都会执行 splice/push, _updateSiblingIndex, _onSiblingIndexChanged, onUpdatingSiblingIndex.

但是当批量排序时, 通常我们只需要 在排序后, 统一执行一次这些方法.

逻辑可能是这样的:

  • 批量修改所有节点的 _siblingIndex 值 , 但是不会调用 前面提到的那些方法
  • 执行 node.children.sort((a, b) => a._siblingIndex- b._siblingIndex) 对所有children 进行一次性批量排序.
  • 排序后再调用一些 排序后的 后置方法和事件.

按照上述逻辑来实现批量排序 性能会更好. 希望官方能够提供类似方法.

Problem Description

如上所述

Proposed Solution

No response

How it works

No response

Alternatives Considered

Additional Information

No response

@finscn finscn added Feature Request Needs Triage Needs to be assigned by the team labels Sep 17, 2024
@finscn
Copy link
Contributor Author

finscn commented Sep 17, 2024

补充下, 在正常游戏里, 玩家可能要按照不同的逻辑进行排序, 比如按照 y轴 或者更复杂的逻辑.
这部分引擎没法介入, 也不应该介入.
重要的是 引擎已经提供一个 对 children排序后, 需要调用的方法, 供开发者使用.

比如, 给 node 增加一个方法, 让开发者手动调用.

public onSortChildren (): void {
        const children = this.children;
        for (let i = children.length - 1; i >= 0; --i) {
            (children[i] as any)._siblingIndex = i;
        }
         NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.MARK_LIST_DIRTY);
        this.emit(cc.NodeEventType.CHILDREN_ORDER_CHANGED);
}

顺便问一下, 其实我不太懂这个 NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.MARK_LIST_DIRTY) 是做什么的.
但是每次改变一个 子节点的 siblingIndex, 内部都会执行这行代码.
这行代码是 因为没有和某个node绑定,理论上也是 批量修改所有children后, 执行一次就行的吧?

@whaqzhzd
Copy link
Contributor

关注,2D游戏这个需求很常见

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request Needs Triage Needs to be assigned by the team
Projects
None yet
Development

No branches or pull requests

2 participants