8000 fix: updating connections in the db multiple times by BeksOmega · Pull Request #6859 · google/blockly · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix: updating connections in the db multiple times #6859

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

Merged
merged 2 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
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
49 changes: 48 additions & 1 deletion core/block_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@ export class BlockSvg extends Block implements IASTNodeLocationSvg,

private translation = '';

/**
* The location of the top left of this block (in workspace coordinates)
* relative to either its parent block, or the workspace origin if it has no
* parent.
*
* @internal
*/
relativeCoords = new Coordinate(0, 0);

/**
* @param workspace The block's workspace.
* @param prototypeName Name of the language object containing type-specific
Expand Down Expand Up @@ -382,6 +391,7 @@ export class BlockSvg extends Block implements IASTNodeLocationSvg,
*/
translate(x: number, y: number) {
this.translation = `translate(${x}, ${y})`;
this.relativeCoords = new Coordinate(x, y);
this.getSvgRoot().setAttribute('transform', this.getTranslation());
}

Expand Down Expand Up @@ -1339,7 +1349,7 @@ export class BlockSvg extends Block implements IASTNodeLocationSvg,
*
* @param all If true, return all connections even hidden ones.
* Otherwise, for a non-rendered block return an empty list, and for a
* collapsed block don't return inputs connections.
* collapsed block don't return inputs connections.
* @returns Array of connections.
* @internal
*/
Expand Down Expand Up @@ -1586,6 +1596,43 @@ export class BlockSvg extends Block implements IASTNodeLocationSvg,
}
}

/**
* Renders this block in a way that's compatible with the more efficient
* render management system.
*
* @internal
*/
renderEfficiently() {
this.rendered = true;
dom.startTextWidthCache();

if (this.isCollapsed()) {
this.updateCollapsed_();
}
this.workspace.getRenderer().render(this);
this.tightenChildrenEfficiently();

dom.stopTextWidthCache();
this.updateMarkers_();
}

/**
* Tightens all children of this block so they are snuggly rendered against
* their parent connections.
*
* Does not update connection locations, so that they can be updated more
* efficiently by the render management system.
*
* @internal
*/
tightenChildrenEfficiently() {
for (const input of this.inputList) {
const conn = input.connection as RenderedConnection;
if (conn) conn.tightenEfficiently();
}
if (this.nextConnection) this.nextConnection.tightenEfficiently();
}

/** Redraw any attached marker or cursor svgs if needed. */
protected updateMarkers_() {
if (this.workspace.keyboardAccessibilityMode && this.pathObject.cursorSvg) {
Expand Down
45 changes: 37 additions & 8 deletions core/render_management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {BlockSvg} from './block_svg';
import {BlockSvg} from './block_svg.js';
import {Coordinate} from './utils/coordinate.js';


const rootBlocks = new Set<BlockSvg>();
const dirtyBlocks = new WeakSet<BlockSvg>();
let dirtyBlocks = new WeakSet<BlockSvg>();
let pid = 0;

/**
Expand Down Expand Up @@ -43,11 +44,24 @@ function queueBlock(block: BlockSvg) {
* Rerenders all of the blocks in the queue.
*/
function doRenders() {
const workspaces = new Set([...rootBlocks].map((block) => block.workspace));
for (const block of rootBlocks) {
// No need to render a dead block.
if (block.isDisposed()) continue;
// A render for this block may have been queued, and then the block was
// connected to a parent, so it is no longer a root block.
// Rendering will be triggered through the real root block.
if (block.getParent()) continue;

renderBlock(block);
updateConnectionLocations(block, block.getRelativeToSurfaceXY());
}
for (const workspace of workspaces) {
workspace.resizeContents();
}

rootBlocks.clear();
dirtyBlocks = new Set();
pid = 0;
}

Expand All @@ -58,14 +72,29 @@ function doRenders() {
* @param block The block to rerender.
*/
function renderBlock(block: BlockSvg) {
if (!dirtyBlocks.has(block)) return;
for (const child of block.getChildren(false)) {
renderBlock(child);
}
if (dirtyBlocks.has(block)) {
dirtyBlocks.delete(block);
rootBlocks.delete(block);
block.render(false);
} else {
block.updateConnectionLocations();
block.renderEfficiently();
}

/**
* Updates the connection database with the new locations of all of the
* connections that are children of the given block.
*
* @param block The block to update the connection locations of.
* @param blockOrigin The top left of the given block in workspace coordinates.
*/
function updateConnectionLocations(block: BlockSvg, blockOrigin: Coordinate) {
for (const conn of block.getConnections_(false)) {
const moved = conn.moveToOffset(blockOrigin);
const target = conn.targetBlock();
if (!conn.isSuperior()) continue;
if (!target) continue;
if (moved || dirtyBlocks.has(target)) {
updateConnectionLocations(
target, Coordinate.sum(blockOrigin, target.relativeCoords));
}
}
}
40 changes: 33 additions & 7 deletions core/rendered_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,33 +183,43 @@ export class RenderedConnection extends Connection {
*
* @param x New absolute x coordinate, in workspace coordinates.
* @param y New absolute y coordinate, in workspace coordinates.
* @return True if the position of the connection in the connection db
* was updated.
*/
moveTo(x: number, y: number) {
moveTo(x: number, y: number): boolean {
const dx = this.x - x;
const dy = this.y - y;

let moved = false;

if (this.trackedState_ === RenderedConnection.TrackedState.WILL_TRACK) {
this.db_.addConnection(this, y);
this.trackedState_ = RenderedConnection.TrackedState.TRACKED;
moved = true;
} else if (
this.trackedState_ === RenderedConnection.TrackedState.TRACKED &&
(dx !== 0 || dy !== 0)) {
this.db_.removeConnection(this, this.y);
this.db_.addConnection(this, y);
moved = true;
}

this.x = x;
this.y = y;

return moved;
}

/**
* Change the connection's coordinates.
*
* @param dx Change to x coordinate, in workspace units.
* @param dy Change to y coordinate, in workspace units.
* @return True if the position of the connection in the connection db
* was updated.
*/
moveBy(dx: number, dy: number) {
this.moveTo(this.x + dx, this.y + dy);
moveBy(dx: number, dy: number): boolean {
return this.moveTo(this.x + dx, this.y + dy);
}

/**
Expand All @@ -218,9 +228,11 @@ export class RenderedConnection extends Connection {
*
* @param blockTL The location of the top left corner of the block, in
* workspace coordinates.
* @return True if the position of the connection in the connection db
* was updated.
*/
moveToOffset(blockTL: Coordinate) {
this.moveTo(
moveToOffset(blockTL: Coordinate): boolean {
return this.moveTo(
blockTL.x + this.offsetInBlock_.x, blockTL.y + this.offsetInBlock_.y);
}

Expand Down Expand Up @@ -261,12 +273,26 @@ export class RenderedConnection extends Connection {
}
// Workspace coordinates.
const xy = svgMath.getRelativeXY(svgRoot);
block!.getSvgRoot().setAttribute(
'transform', 'translate(' + (xy.x - dx) + ',' + (xy.y - dy) + ')');
block!.translate(xy.x - dx, xy.y - dy);
block!.moveConnections(-dx, -dy);
}
}

/**
* Moves the blocks on either side of this connection right next to
* each other, based on their local offsets, not global positions.
*
* @internal
*/
tightenEfficiently() {
const target = this.targetConnection;
const block = this.targetBlock();
if (!target || !block) return;
const offset =
Coordinate.difference(this.offsetInBlock_, target.offsetInBlock_);
block.translate(offset.x, offset.y);
}

/**
* Find the closest compatible connection to this connection.
* All parameters are in workspace units.
Expand Down
0