mirror of
https://github.com/google/blockly.git
synced 2026-01-07 17:10:11 +01:00
fix: dispose performance (#6894)
* fix: improve dispose performance * chore: cleanup dispose functions * chore: split dispose into dispose and disposeInternal * chore: remove unnecessary node removal * fix: remove unnecessary unbinding of event listeners * fix: readd skipping event construction * chore: work on fixing tests * chore: fix remaining test failures * chore: format * chore: typo * fix: first pass of PR comments * chore: remove TODO
This commit is contained in:
@@ -312,44 +312,45 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
* @suppress {checkTypes}
|
||||
*/
|
||||
dispose(healStack: boolean) {
|
||||
if (this.isDeadOrDying()) {
|
||||
return;
|
||||
}
|
||||
// Terminate onchange event calls.
|
||||
if (this.isDeadOrDying()) return;
|
||||
|
||||
// Dispose of this change listener before unplugging.
|
||||
// Technically not necessary due to the event firing delay.
|
||||
// But future-proofing.
|
||||
if (this.onchangeWrapper_) {
|
||||
this.workspace.removeChangeListener(this.onchangeWrapper_);
|
||||
}
|
||||
|
||||
this.unplug(healStack);
|
||||
if (eventUtils.isEnabled()) {
|
||||
// Constructing the delete event is costly. Only perform if necessary.
|
||||
eventUtils.fire(new (eventUtils.get(eventUtils.BLOCK_DELETE))(this));
|
||||
}
|
||||
eventUtils.disable();
|
||||
this.workspace.removeTopBlock(this);
|
||||
this.disposeInternal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes of this block without doing things required by the top block.
|
||||
* E.g. does not fire events, unplug the block, etc.
|
||||
*/
|
||||
protected disposeInternal() {
|
||||
if (this.isDeadOrDying()) return;
|
||||
|
||||
if (this.onchangeWrapper_) {
|
||||
this.workspace.removeChangeListener(this.onchangeWrapper_);
|
||||
}
|
||||
|
||||
eventUtils.disable();
|
||||
try {
|
||||
// This block is now at the top of the workspace.
|
||||
// Remove this block from the workspace's list of top-most blocks.
|
||||
this.workspace.removeTopBlock(this);
|
||||
this.workspace.removeTypedBlock(this);
|
||||
// Remove from block database.
|
||||
this.workspace.removeBlockById(this.id);
|
||||
this.disposing = true;
|
||||
|
||||
// First, dispose of all my children.
|
||||
for (let i = this.childBlocks_.length - 1; i >= 0; i--) {
|
||||
this.childBlocks_[i].dispose(false);
|
||||
}
|
||||
// Then dispose of myself.
|
||||
// Dispose of all inputs and their fields.
|
||||
for (let i = 0, input; input = this.inputList[i]; i++) {
|
||||
input.dispose();
|
||||
}
|
||||
this.childBlocks_.forEach((c) => c.disposeInternal());
|
||||
this.inputList.forEach((i) => i.dispose());
|
||||
this.inputList.length = 0;
|
||||
// Dispose of any remaining connections (next/previous/output).
|
||||
const connections = this.getConnections_(true);
|
||||
for (let i = 0, connection; connection = connections[i]; i++) {
|
||||
connection.dispose();
|
||||
}
|
||||
this.getConnections_(true).forEach((c) => c.dispose());
|
||||
} finally {
|
||||
eventUtils.enable();
|
||||
if (typeof this.destroy === 'function') {
|
||||
|
||||
Reference in New Issue
Block a user