fix: Don't repeatedly recreate the last marker block during a drag. (#6875)

* fix: Don't repeatedly recreate the last marker block during a drag.

* refactor: Reorganize insertion marker initialization and disposal.
This commit is contained in:
Aaron Dodson
2023-03-01 15:52:37 -08:00
committed by GitHub
parent bb6124a7c3
commit 3a7ac3be1b

View File

@@ -133,6 +133,11 @@ export class InsertionMarkerManager {
this.firstMarker = this.createMarkerBlock(this.topBlock);
this.availableConnections = this.initAvailableConnections();
if (this.lastOnStack) {
this.lastMarker =
this.createMarkerBlock(this.lastOnStack.getSourceBlock());
}
}
/**
@@ -142,18 +147,8 @@ export class InsertionMarkerManager {
*/
dispose() {
this.availableConnections.length = 0;
eventUtils.disable();
try {
if (this.firstMarker) {
this.firstMarker.dispose();
}
if (this.lastMarker) {
this.lastMarker.dispose();
}
} finally {
eventUtils.enable();
}
this.disposeInsertionMarker(this.firstMarker);
this.disposeInsertionMarker(this.lastMarker);
}
/**
@@ -289,10 +284,8 @@ export class InsertionMarkerManager {
}
/**
* Populate the list of available connections on this block stack. This
* should only be called once, at the beginning of a drag. If the stack has
* more than one block, this function will populate lastOnStack and create
* the corresponding insertion marker.
* Populate the list of available connections on this block stack. If the
* stack has more than one block, this function will also update lastOnStack.
*
* @returns A list of available connections.
*/
@@ -303,15 +296,6 @@ export class InsertionMarkerManager {
if (lastOnStack && lastOnStack !== this.topBlock.nextConnection) {
available.push(lastOnStack);
this.lastOnStack = lastOnStack;
if (this.lastMarker) {
eventUtils.disable();
try {
this.lastMarker.dispose();
} finally {
eventUtils.enable();
}
}
this.lastMarker = this.createMarkerBlock(lastOnStack.getSourceBlock());
}
return available;
}
@@ -561,8 +545,17 @@ export class InsertionMarkerManager {
// probably recreate the marker block (e.g. in getCandidate_), which is
// called more often during the drag, but creating a block that often
// might be too slow, so we only do it if necessary.
this.firstMarker = this.createMarkerBlock(this.topBlock);
insertionMarker = isLastInStack ? this.lastMarker : this.firstMarker;
if (isLastInStack && this.lastOnStack) {
this.disposeInsertionMarker(this.lastMarker);
this.lastMarker =
this.createMarkerBlock(this.lastOnStack.getSourceBlock());
insertionMarker = this.lastMarker;
} else {
this.disposeInsertionMarker(this.firstMarker);
this.firstMarker = this.createMarkerBlock(this.topBlock);
insertionMarker = this.firstMarker;
}
if (!insertionMarker) {
throw new Error(
'Cannot show the insertion marker because there is no insertion ' +
@@ -728,6 +721,20 @@ export class InsertionMarkerManager {
}
return result;
}
/**
* Safely disposes of an insertion marker.
*/
private disposeInsertionMarker(marker: BlockSvg|null) {
if (marker) {
eventUtils.disable();
try {
marker.dispose();
} finally {
eventUtils.enable();
}
}
}
}
export namespace InsertionMarkerManager {