Skip to content

Commit

Permalink
- optimise remove child
Browse files Browse the repository at this point in the history
- change the way render group is stored
- added parentRenderGroup
- renderGroup now the owned render group
  • Loading branch information
GoodBoyDigital committed May 1, 2024
1 parent e60413a commit 4e53f30
Show file tree
Hide file tree
Showing 20 changed files with 251 additions and 139 deletions.
117 changes: 63 additions & 54 deletions src/scene/container/Container.ts
Expand Up @@ -360,13 +360,15 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
/** @private */
public _updateFlags = 0b1111;

// is this container the root of a renderGroup?
// TODO implement this in a few more places
/** @private */
public isRenderGroupRoot = false;
// the render group this container belongs to OR owns
// the render group this container owns
/** @private */
public renderGroup: RenderGroup = null;
// the render group this container belongs to
/** @private */
public parentRenderGroup: RenderGroup = null;
// the index of the container in the render group
/** @private */
public parentRenderGroupIndex: number = 0;

// set to true if the container has changed. It is reset once the changes have been applied
// by the transform system
Expand Down Expand Up @@ -622,9 +624,9 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
this.children.splice(this.children.indexOf(child), 1);
this.children.push(child);

if (this.renderGroup && !this.isRenderGroupRoot)
if (this.parentRenderGroup)// && !this.isRenderGroupRoot)
{
this.renderGroup.structureDidChange = true;
this.parentRenderGroup.structureDidChange = true;
}

return child;
Expand All @@ -648,9 +650,11 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
// TODO - OPtimise this? could check what the parent has set?
child._updateFlags = 0b1111;

if (this.renderGroup)
const renderGroup = this.renderGroup || this.parentRenderGroup;

if (renderGroup)
{
this.renderGroup.addChild(child);
renderGroup.addChild(child);
}

this.emit('childAdded', child, this, this.children.length - 1);
Expand Down Expand Up @@ -695,6 +699,10 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
{
this.renderGroup.removeChild(child);
}
else if (this.parentRenderGroup)
{
this.parentRenderGroup.removeChild(child);
}

child.parent = null;
this.emit('childRemoved', child, this, index);
Expand Down Expand Up @@ -722,7 +730,7 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
if (this.didChange) return;
this.didChange = true;

if (this.isRenderGroupRoot)
if (this.renderGroup)
{
const renderGroupParent = this.renderGroup.renderGroupParent;
// lets update its parent..
Expand All @@ -732,15 +740,15 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
renderGroupParent.onChildUpdate(this);
}
}
else if (this.renderGroup)
else if (this.parentRenderGroup)
{
this.renderGroup.onChildUpdate(this);
this.parentRenderGroup.onChildUpdate(this);
}
}

set isRenderGroup(value: boolean)
{
if (this.isRenderGroupRoot && value === false)
if (this.renderGroup && value === false)
{
throw new Error('[Pixi] cannot undo a render group just yet');
}
Expand All @@ -757,18 +765,16 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
*/
get isRenderGroup(): boolean
{
return this.isRenderGroupRoot;
return !!this.renderGroup;
}

/** This enables the container to be rendered as a render group. */
public enableRenderGroup()
{
// does it OWN the render group..
if (this.renderGroup && this.renderGroup.root === this) return;
if (this.renderGroup) return;

this.isRenderGroupRoot = true;

const parentRenderGroup = this.renderGroup;
const parentRenderGroup = this.parentRenderGroup;

if (parentRenderGroup)
{
Expand All @@ -777,29 +783,35 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>

this.renderGroup = new RenderGroup(this);

// find children render groups and move them out..
if (parentRenderGroup)
{
for (let i = 0; i < parentRenderGroup.renderGroupChildren.length; i++)
{
const childRenderGroup = parentRenderGroup.renderGroupChildren[i];
let parent = childRenderGroup.root;

while (parent)
{
if (parent === this)
{
this.renderGroup.addRenderGroupChild(childRenderGroup);

break;
}
parent = parent.parent;
}
}

parentRenderGroup.addRenderGroupChild(this.renderGroup);
parentRenderGroup.addChild(this);
}

// find children render groups and move them out..
// if (parentRenderGroup)
// {
// for (let i = 0; i < parentRenderGroup.renderGroupChildren.length; i++)
// {
// const childRenderGroup = parentRenderGroup.renderGroupChildren[i];
// let parent = childRenderGroup.root;

// while (parent)
// {
// if (parent === this)
// {
// this.renderGroup.addRenderGroupChild(childRenderGroup);

// break;
// }
// parent = parent.parent;
// }
// }

// parentRenderGroup.addRenderGroupChild(this.renderGroup);
// }

// parentRenderGroup.removeChild(this);
this._updateIsSimple();

// this group matrix will now forever be an identity matrix,
Expand All @@ -810,7 +822,7 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
/** @ignore */
public _updateIsSimple()
{
this.isSimple = !(this.isRenderGroupRoot) && (this.effects.length === 0);
this.isSimple = !(this.renderGroup) && (this.effects.length === 0);
}

/**
Expand All @@ -823,14 +835,11 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>

if (this.renderGroup)
{
if (this.isRenderGroupRoot)
{
this._worldTransform.copyFrom(this.renderGroup.worldTransform);
}
else
{
this._worldTransform.appendFrom(this.relativeGroupTransform, this.renderGroup.worldTransform);
}
this._worldTransform.copyFrom(this.renderGroup.worldTransform);
}
else if (this.parentRenderGroup)
{
this._worldTransform.appendFrom(this.relativeGroupTransform, this.parentRenderGroup.worldTransform);
}

return this._worldTransform;
Expand Down Expand Up @@ -1216,9 +1225,9 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
set blendMode(value: BLEND_MODES)
{
if (this.localBlendMode === value) return;
if (this.renderGroup && !this.isRenderGroupRoot)
if (this.parentRenderGroup)
{
this.renderGroup.structureDidChange = true;
this.parentRenderGroup.structureDidChange = true;
}

this._updateFlags |= UPDATE_BLEND;
Expand Down Expand Up @@ -1251,9 +1260,9 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>

if ((this.localDisplayStatus & 0b010) >> 1 === valueNumber) return;

if (this.renderGroup && !this.isRenderGroupRoot)
if (this.parentRenderGroup)
{
this.renderGroup.structureDidChange = true;
this.parentRenderGroup.structureDidChange = true;
}

this._updateFlags |= UPDATE_VISIBLE;
Expand All @@ -1276,9 +1285,9 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>

if ((this.localDisplayStatus & 0b100) >> 2 === valueNumber) return;

if (this.renderGroup && !this.isRenderGroupRoot)
if (this.parentRenderGroup)
{
this.renderGroup.structureDidChange = true;
this.parentRenderGroup.structureDidChange = true;
}

this._updateFlags |= UPDATE_VISIBLE;
Expand All @@ -1302,9 +1311,9 @@ export class Container extends EventEmitter<ContainerEvents & AnyEvent>
this._updateFlags |= UPDATE_VISIBLE;
this.localDisplayStatus ^= 0b001;

if (this.renderGroup && !this.isRenderGroupRoot)
if (this.parentRenderGroup)
{
this.renderGroup.structureDidChange = true;
this.parentRenderGroup.structureDidChange = true;
}

this._onUpdate();
Expand Down
98 changes: 80 additions & 18 deletions src/scene/container/RenderGroup.ts
Expand Up @@ -91,14 +91,15 @@ export class RenderGroup implements Instruction
if (child !== this.root)
{
this._children.push(child);
child.parentRenderGroupIndex = this._children.length - 1;
child.parentRenderGroup = this;

child.updateTick = -1;

if (child.parent === this.root)
{
child.relativeRenderGroupDepth = 1;
}

else
{
child.relativeRenderGroupDepth = child.parent.relativeRenderGroupDepth + 1;
Expand All @@ -112,23 +113,20 @@ export class RenderGroup implements Instruction

if (child.renderGroup)
{
if (child.renderGroup.root === child)
{
// its already its own render group..
this.addRenderGroupChild(child.renderGroup);
// its already its own render group..
this.addRenderGroupChild(child.renderGroup);

return;
}
}
else
{
child.renderGroup = this;
child.didChange = true;
return;
}

// child.parentRenderGroup = this;

// child.renderGroup = this;
child.didChange = true;

const children = child.children;

if (!child.isRenderGroupRoot)
if (!child.renderGroup)
{
this.onChildUpdate(child);
}
Expand All @@ -149,7 +147,7 @@ export class RenderGroup implements Instruction
this.removeOnRender(child);
}

if (child.renderGroup.root !== child)
if (!child.renderGroup)
{
const children = child.children;

Expand All @@ -160,17 +158,17 @@ export class RenderGroup implements Instruction

if (child.didChange)
{
child.renderGroup._removeChildFromUpdate(child);
child.parentRenderGroup._removeChildFromUpdate(child);
}

child.renderGroup = null;
// child.renderGroup = null;
}

else
{
this._removeRenderGroupChild(child.renderGroup);
}

child.parentRenderGroup = null;

const index = this._children.indexOf(child);

if (index > -1)
Expand All @@ -179,6 +177,70 @@ export class RenderGroup implements Instruction
}
}

public collectChildrenIndexes(children: Container[], indexes: number[], index: number)
{
for (let i = 0; i < children.length; i++)
{
const child = children[i];

indexes[index++] = child.parentRenderGroupIndex;

if (child.children.length)
{
index = this.collectChildrenIndexes(child.children, indexes, index);
}
}

return index;
}

public removeChildren(children: Container[])
{
// remove all the children...
this.structureDidChange = true;

const indexes: number[] = [];

this.collectChildrenIndexes(children, indexes, 0);

const renderGroupChildren = this._children;

let shift = 0;
const start = indexes[0];
let index = 0;

for (let i = start; i < renderGroupChildren.length; i++)
{
if (i === indexes[index])
{
const child = renderGroupChildren[indexes[index]];

if (child._onRender)
{
this.removeOnRender(child);
}

if (child.parentRenderGroup)
{
child.parentRenderGroup = null;
child.updateTick = this.updateTick;
}
else
{
this._removeRenderGroupChild(child.renderGroup);
}

index++;

shift++;
}

renderGroupChildren[i] = renderGroupChildren[i + shift];
}

renderGroupChildren.length = renderGroupChildren.length - shift;
}

public onChildUpdate(child: Container)
{
let childrenToUpdate = this.childrenToUpdate[child.relativeRenderGroupDepth];
Expand Down

0 comments on commit 4e53f30

Please sign in to comment.