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

add methods for batch updating sibling indices for issue #17644 . #18135

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions cocos/scene-graph/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@
protected static _findChildComponents (children: Node[], constructor, components): void {
for (let i = 0; i < children.length; ++i) {
const node = children[i];
Node._findComponents(node, constructor, components);

Check failure on line 338 in cocos/scene-graph/node.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `Constructor<Component> | AbstractedConstructor<Component>`

Check failure on line 338 in cocos/scene-graph/node.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `Component[]`
if (node._children.length > 0) {
Node._findChildComponents(node._children, constructor, components);
}
Expand Down Expand Up @@ -652,6 +652,104 @@
this._eventProcessor.onUpdatingSiblingIndex();
}

/**
* @en Batch update the children's sibling index to the index of in children, and emit events.
* @zh 批量更新当前节点子节点的sibling index为其在children数组中的下标,并触发事件。
*/
private batchUpdateSiblingIndices (): void {
const changed: number[] = [];
for (let i = 0; i < this._children.length; ++i) {
const node = this._children[i];
if (node._siblingIndex !== i) {
node._siblingIndex = i;
changed.push(i);
}
}
if (changed.length > 0) {
this.emit(NodeEventType.CHILDREN_ORDER_CHANGED);
for (const i of changed) {
const node = this._children[i];
if (node._onSiblingIndexChanged) {
node._onSiblingIndexChanged(i);
}
node._eventProcessor.onUpdatingSiblingIndex();
}
}
}

/**
* @en Set the children's sibling index in a batch.
* @zh 批量设置当前节点子节点的sibling index。
* @param indices @en New sibling indeces for all children.
* @zh 所有子节点的新索引值。
* @return True if indices set, false if parameter not valid.
*/
public setChildrenIndices (indices: number[]): boolean {
if (this._objFlags & Deactivating) {
errorID(3821);
return false;
}
//check indices length
const length = indices.length;
if (length !== this._children.length) {
return false;
}
//check if indices contains all value in [0,length)
const checks: boolean[] = [];
for (let i = 0; i < length; i++) {
checks.push(false);
}
for (const ni of indices) {
if (ni >= 0 && ni < length) {
checks[ni] = true;
}
}
let valid = true;
for (const check of checks) {
if (!check) {
valid = false;
break;
}
}
if (!valid) {
return false;
}
//set the indeces
let i = 0;
while (i < indices.length) {
const ni = indices[i];
if (ni === i) {
i++;
} else {
//swap indices
indices[i] = indices[ni];
indices[ni] = ni;
//swap node
const node = this._children[i];
this._children[i] = this._children[ni];
this.children[ni] = node;
}
}
this.batchUpdateSiblingIndices();
return true;
}

/**
* @en Sort the children according to the comparator.
* @zh 根据比较器对当前节点的子节点全排序
* @param comp @en A comparator that return negtive value / 0 value / positive value
* when the first node is less than / equals to / greater than the second node.
* @zh 一个比较器,当第一个节点小于/等于/大于第二个节点时,返回负值/0值/正值。
*/
public sortChildren (comp: (n1: Node, n2: Node) => number): void {
if (this._objFlags & Deactivating) {
errorID(3821);
return;
}
this._children.sort(comp);
this.batchUpdateSiblingIndices();
}

/**
* @en Walk though the sub children tree of the current node.
* Each node, including the current node, in the sub tree will be visited two times,
Expand Down Expand Up @@ -1011,8 +1109,8 @@
if (Array.isArray(reqComps)) {
for (let i = 0; i < reqComps.length; i++) {
const reqComp = reqComps[i];
if (!this.getComponent(reqComp)) {

Check failure on line 1112 in cocos/scene-graph/node.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `Constructor<Component> | AbstractedConstructor<Component>`
this.addComponent(reqComp);

Check failure on line 1113 in cocos/scene-graph/node.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `Constructor<Component>`
}
}
} else {
Expand Down Expand Up @@ -1097,7 +1195,7 @@
if (component instanceof Component) {
componentInstance = component;
} else {
componentInstance = this.getComponent(component);

Check failure on line 1198 in cocos/scene-graph/node.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `Constructor<Component> | AbstractedConstructor<Component>`
}
if (componentInstance) {
componentInstance.destroy();
Expand Down Expand Up @@ -1252,7 +1350,7 @@
* @zh 移除目标上的所有注册事件。
* @param target - The target to be searched for all related callbacks
*/
public targetOff (target: string | unknown): void {

Check failure on line 1353 in cocos/scene-graph/node.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

'unknown' overrides all other types in this union type
this._eventProcessor.targetOff(target);
// Check for event mask reset
if ((this._eventMask & TRANSFORM_ON) && !this._eventProcessor.hasEventListener(NodeEventType.TRANSFORM_CHANGED)) {
Expand Down Expand Up @@ -1328,7 +1426,7 @@
if (EDITOR && newPrefabInfo) {
if (cloned === newPrefabInfo.root) {
// when instantiate prefab in Editor,should add prefab instance info for root node
EditorExtends.PrefabUtils.addPrefabInstance?.(cloned);

Check failure on line 1429 in cocos/scene-graph/node.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `Node`
// newPrefabInfo.fileId = '';
} else {
// var PrefabUtils = Editor.require('scene://utils/prefab');
Expand Down
Loading