[turbolizer] Selection broker explicit typing and speed up
Bug: v8:7327 Change-Id: I76317cd206d95584e77b6ece9860a551107154b3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3760456 Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Commit-Queue: Danylo Boiko <danielboyko02@gmail.com> Cr-Commit-Position: refs/heads/main@{#81822}
This commit is contained in:
parent
81bd4a559b
commit
eacdf120d9
@ -2,10 +2,10 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import { SourceResolver } from "../source-resolver";
|
||||
import { GenericPosition, SourceResolver } from "../source-resolver";
|
||||
import {
|
||||
ClearableHandler,
|
||||
SelectionHandler,
|
||||
SourcePositionSelectionHandler,
|
||||
NodeSelectionHandler,
|
||||
BlockSelectionHandler,
|
||||
InstructionSelectionHandler,
|
||||
@ -15,27 +15,22 @@ import {
|
||||
export class SelectionBroker {
|
||||
sourceResolver: SourceResolver;
|
||||
allHandlers: Array<ClearableHandler>;
|
||||
sourcePositionHandlers: Array<SelectionHandler>;
|
||||
nodeHandlers: Array<NodeSelectionHandler>;
|
||||
blockHandlers: Array<BlockSelectionHandler>;
|
||||
instructionHandlers: Array<InstructionSelectionHandler>;
|
||||
sourcePositionHandlers: Array<SourcePositionSelectionHandler>;
|
||||
registerAllocationHandlers: Array<RegisterAllocationSelectionHandler>;
|
||||
|
||||
constructor(sourceResolver: SourceResolver) {
|
||||
this.sourceResolver = sourceResolver;
|
||||
this.allHandlers = new Array<ClearableHandler>();
|
||||
this.sourcePositionHandlers = new Array<SelectionHandler>();
|
||||
this.nodeHandlers = new Array<NodeSelectionHandler>();
|
||||
this.blockHandlers = new Array<BlockSelectionHandler>();
|
||||
this.instructionHandlers = new Array<InstructionSelectionHandler>();
|
||||
this.sourcePositionHandlers = new Array<SourcePositionSelectionHandler>();
|
||||
this.registerAllocationHandlers = new Array<RegisterAllocationSelectionHandler>();
|
||||
}
|
||||
|
||||
public addSourcePositionHandler(handler: SelectionHandler & ClearableHandler): void {
|
||||
this.allHandlers.push(handler);
|
||||
this.sourcePositionHandlers.push(handler);
|
||||
}
|
||||
|
||||
public addNodeHandler(handler: NodeSelectionHandler & ClearableHandler): void {
|
||||
this.allHandlers.push(handler);
|
||||
this.nodeHandlers.push(handler);
|
||||
@ -61,12 +56,19 @@ export class SelectionBroker {
|
||||
this.instructionHandlers.push(handler);
|
||||
}
|
||||
|
||||
public addSourcePositionHandler(handler: SourcePositionSelectionHandler & ClearableHandler):
|
||||
void {
|
||||
this.allHandlers.push(handler);
|
||||
this.sourcePositionHandlers.push(handler);
|
||||
}
|
||||
|
||||
public addRegisterAllocatorHandler(handler: RegisterAllocationSelectionHandler
|
||||
& ClearableHandler): void {
|
||||
this.allHandlers.push(handler);
|
||||
this.registerAllocationHandlers.push(handler);
|
||||
}
|
||||
|
||||
// TODO (danylo boiko) Add instructionOffsets type
|
||||
public broadcastInstructionSelect(from, instructionOffsets, selected: boolean): void {
|
||||
// Select the lines from the disassembly (right panel)
|
||||
for (const handler of this.instructionHandlers) {
|
||||
@ -84,11 +86,11 @@ export class SelectionBroker {
|
||||
if (handler != from) handler.brokeredSourcePositionSelect(sourcePositions, selected);
|
||||
}
|
||||
}
|
||||
|
||||
// The middle panel lines have already been selected so there's no need to reselect them.
|
||||
}
|
||||
|
||||
public broadcastSourcePositionSelect(from, sourcePositions, selected: boolean): void {
|
||||
public broadcastSourcePositionSelect(from, sourcePositions: Array<GenericPosition>,
|
||||
selected: boolean): void {
|
||||
sourcePositions = sourcePositions.filter(sourcePosition => {
|
||||
if (!sourcePosition.isValid()) {
|
||||
console.warn("Invalid source position");
|
||||
@ -108,26 +110,10 @@ export class SelectionBroker {
|
||||
if (handler != from) handler.brokeredNodeSelect(nodes, selected);
|
||||
}
|
||||
|
||||
for (const node of nodes) {
|
||||
const instructionOffsets = this.sourceResolver.instructionsPhase
|
||||
.nodeIdToInstructionRange[node];
|
||||
|
||||
// Skip nodes which do not have an associated instruction range.
|
||||
if (instructionOffsets == undefined) continue;
|
||||
|
||||
// Select the lines from the disassembly (right panel)
|
||||
for (const handler of this.instructionHandlers) {
|
||||
if (handler != from) handler.brokeredInstructionSelect(instructionOffsets, selected);
|
||||
}
|
||||
|
||||
// Select the lines from the middle panel for the register allocation phase.
|
||||
for (const handler of this.registerAllocationHandlers) {
|
||||
if (handler != from) handler.brokeredRegisterAllocationSelect(instructionOffsets, selected);
|
||||
}
|
||||
}
|
||||
this.selectInstructionsAndRegisterAllocations(from, nodes, selected);
|
||||
}
|
||||
|
||||
public broadcastNodeSelect(from, nodes, selected: boolean): void {
|
||||
public broadcastNodeSelect(from, nodes: Set<string>, selected: boolean): void {
|
||||
// Select the nodes (middle panel)
|
||||
for (const handler of this.nodeHandlers) {
|
||||
if (handler != from) handler.brokeredNodeSelect(nodes, selected);
|
||||
@ -139,33 +125,41 @@ export class SelectionBroker {
|
||||
if (handler != from) handler.brokeredSourcePositionSelect(sourcePositions, selected);
|
||||
}
|
||||
|
||||
for (const node of nodes) {
|
||||
const instructionOffsets = this.sourceResolver.instructionsPhase
|
||||
.nodeIdToInstructionRange[node];
|
||||
|
||||
// Skip nodes which do not have an associated instruction range.
|
||||
if (instructionOffsets == undefined) continue;
|
||||
// Select the lines from the disassembly (right panel)
|
||||
for (const handler of this.instructionHandlers) {
|
||||
if (handler != from) handler.brokeredInstructionSelect(instructionOffsets, selected);
|
||||
}
|
||||
|
||||
// Select the lines from the middle panel for the register allocation phase.
|
||||
for (const handler of this.registerAllocationHandlers) {
|
||||
if (handler != from) handler.brokeredRegisterAllocationSelect(instructionOffsets, selected);
|
||||
}
|
||||
}
|
||||
this.selectInstructionsAndRegisterAllocations(from, nodes, selected);
|
||||
}
|
||||
|
||||
public broadcastBlockSelect(from, blocks, selected: boolean): void {
|
||||
public broadcastBlockSelect(from, blocksIds: Array<string>, selected: boolean): void {
|
||||
for (const handler of this.blockHandlers) {
|
||||
if (handler != from) handler.brokeredBlockSelect(blocks, selected);
|
||||
if (handler != from) handler.brokeredBlockSelect(blocksIds, selected);
|
||||
}
|
||||
}
|
||||
|
||||
public broadcastClear(from): void {
|
||||
this.allHandlers.forEach(handler => {
|
||||
for (const handler of this.allHandlers) {
|
||||
if (handler != from) handler.brokeredClear();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private selectInstructionsAndRegisterAllocations(from, nodes: Set<string>, selected: boolean):
|
||||
void {
|
||||
const instructionsOffsets = new Array<[number, number]>();
|
||||
for (const node of nodes) {
|
||||
const instructionRange = this.sourceResolver.instructionsPhase.nodeIdToInstructionRange[node];
|
||||
if (instructionRange) instructionsOffsets.push(instructionRange);
|
||||
}
|
||||
|
||||
if (instructionsOffsets.length > 0) {
|
||||
// Select the lines from the disassembly (right panel)
|
||||
for (const handler of this.instructionHandlers) {
|
||||
if (handler != from) handler.brokeredInstructionSelect(instructionsOffsets, selected);
|
||||
}
|
||||
|
||||
// Select the lines from the middle panel for the register allocation phase.
|
||||
for (const handler of this.registerAllocationHandlers) {
|
||||
if (handler != from) {
|
||||
handler.brokeredRegisterAllocationSelect(instructionsOffsets, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,37 +2,43 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import { TurboshaftGraphNode } from "../phases/turboshaft-graph-phase/turboshaft-graph-node";
|
||||
import { GraphNode } from "../phases/graph-phase/graph-node";
|
||||
import { TurboshaftGraphBlock } from "../phases/turboshaft-graph-phase/turboshaft-graph-block";
|
||||
import { GenericPosition } from "../source-resolver";
|
||||
|
||||
export interface ClearableHandler {
|
||||
brokeredClear(): void;
|
||||
}
|
||||
|
||||
export interface SelectionHandler {
|
||||
select(nodeIds: any, selected: any): void;
|
||||
clear(): void;
|
||||
brokeredSourcePositionSelect(sourcePositions: any, selected: any): void;
|
||||
}
|
||||
|
||||
export interface NodeSelectionHandler {
|
||||
select(nodeIds: any, selected: any): void;
|
||||
select(nodes: Iterable<TurboshaftGraphNode | GraphNode | string>, selected: boolean): void;
|
||||
clear(): void;
|
||||
brokeredNodeSelect(nodeIds: any, selected: any): void;
|
||||
brokeredNodeSelect(nodeIds: Set<string>, selected: boolean): void;
|
||||
}
|
||||
|
||||
export interface BlockSelectionHandler {
|
||||
select(nodeIds: any, selected: any): void;
|
||||
select(blocks: Iterable<TurboshaftGraphBlock | string>, selected: boolean): void;
|
||||
clear(): void;
|
||||
brokeredBlockSelect(blockIds: any, selected: any): void;
|
||||
brokeredBlockSelect(blockIds: Array<string>, selected: boolean): void;
|
||||
}
|
||||
|
||||
export interface InstructionSelectionHandler {
|
||||
select(instructionIds: any, selected: any): void;
|
||||
select(instructionIds: Array<string>, selected: boolean): void;
|
||||
clear(): void;
|
||||
brokeredInstructionSelect(instructionIds: any, selected: any): void;
|
||||
brokeredInstructionSelect(instructionsOffsets: Array<[number, number]>, selected: boolean): void;
|
||||
}
|
||||
|
||||
export interface SourcePositionSelectionHandler {
|
||||
select(sourcePositions: Array<GenericPosition>, selected: boolean): void;
|
||||
clear(): void;
|
||||
brokeredSourcePositionSelect(sourcePositions: Array<GenericPosition>, selected: boolean): void;
|
||||
}
|
||||
|
||||
export interface RegisterAllocationSelectionHandler {
|
||||
// These are called instructionIds since the class of the divs is "instruction-id"
|
||||
select(instructionIds: any, selected: any): void;
|
||||
select(instructionIds: Array<string>, selected: boolean): void;
|
||||
clear(): void;
|
||||
brokeredRegisterAllocationSelect(instructionIds: any, selected: any): void;
|
||||
brokeredRegisterAllocationSelect(instructionsOffsets: Array<[number, number]>, selected: boolean):
|
||||
void;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ export class SourceResolver {
|
||||
return nodeIds;
|
||||
}
|
||||
|
||||
public nodeIdsToSourcePositions(nodeIds: Array<string>): Array<GenericPosition> {
|
||||
public nodeIdsToSourcePositions(nodeIds: Iterable<string>): Array<GenericPosition> {
|
||||
const sourcePositions = new Map<string, GenericPosition>();
|
||||
for (const nodeId of nodeIds) {
|
||||
const position = this.nodePositionMap[nodeId];
|
||||
|
@ -8,7 +8,7 @@ import { SelectionBroker } from "../selection/selection-broker";
|
||||
import { View } from "./view";
|
||||
import { SelectionMap } from "../selection/selection-map";
|
||||
import { ViewElements } from "../common/view-elements";
|
||||
import { ClearableHandler, SelectionHandler } from "../selection/selection-handler";
|
||||
import { ClearableHandler, SourcePositionSelectionHandler } from "../selection/selection-handler";
|
||||
import { SourcePosition } from "../position";
|
||||
|
||||
interface PR {
|
||||
@ -31,8 +31,8 @@ export class CodeView extends View {
|
||||
codeMode: CodeMode;
|
||||
sourcePositionToHtmlElements: Map<string, Array<HTMLElement>>;
|
||||
showAdditionalInliningPosition: boolean;
|
||||
selection: SelectionMap;
|
||||
selectionHandler: SelectionHandler & ClearableHandler;
|
||||
sourcePositionSelection: SelectionMap;
|
||||
sourcePositionSelectionHandler: SourcePositionSelectionHandler & ClearableHandler;
|
||||
|
||||
constructor(parent: HTMLElement, broker: SelectionBroker, sourceFunction: Source,
|
||||
sourceResolver: SourceResolver, codeMode: CodeMode) {
|
||||
@ -44,9 +44,9 @@ export class CodeView extends View {
|
||||
this.sourcePositionToHtmlElements = new Map<string, Array<HTMLElement>>();
|
||||
this.showAdditionalInliningPosition = false;
|
||||
|
||||
this.selection = new SelectionMap((gp: GenericPosition) => gp.toString());
|
||||
this.selectionHandler = this.initializeSourcePositionHandler();
|
||||
broker.addSourcePositionHandler(this.selectionHandler);
|
||||
this.sourcePositionSelection = new SelectionMap((gp: GenericPosition) => gp.toString());
|
||||
this.sourcePositionSelectionHandler = this.initializeSourcePositionSelectionHandler();
|
||||
broker.addSourcePositionHandler(this.sourcePositionSelectionHandler);
|
||||
this.initializeCode();
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ export class CodeView extends View {
|
||||
view.onSelectLine(Number(targetDiv.dataset.lineNumber), !e.shiftKey);
|
||||
}
|
||||
} else {
|
||||
view.selectionHandler.clear();
|
||||
view.sourcePositionSelectionHandler.clear();
|
||||
}
|
||||
};
|
||||
|
||||
@ -148,7 +148,8 @@ export class CodeView extends View {
|
||||
}
|
||||
}
|
||||
|
||||
private initializeSourcePositionHandler(): SelectionHandler & ClearableHandler {
|
||||
private initializeSourcePositionSelectionHandler(): SourcePositionSelectionHandler
|
||||
& ClearableHandler {
|
||||
const view = this;
|
||||
const broker = this.broker;
|
||||
const sourceResolver = this.sourceResolver;
|
||||
@ -160,26 +161,26 @@ export class CodeView extends View {
|
||||
sourceResolver.addInliningPositions(sourcePosition, locations);
|
||||
}
|
||||
if (locations.length == 0) return;
|
||||
view.selection.select(locations, selected);
|
||||
view.sourcePositionSelection.select(locations, selected);
|
||||
view.updateSelection();
|
||||
broker.broadcastSourcePositionSelect(this, locations, selected);
|
||||
},
|
||||
clear: function () {
|
||||
view.selection.clear();
|
||||
view.sourcePositionSelection.clear();
|
||||
view.updateSelection();
|
||||
broker.broadcastClear(this);
|
||||
},
|
||||
brokeredSourcePositionSelect: function (locations: Array<SourcePosition>, selected: boolean) {
|
||||
const firstSelect = view.selection.isEmpty();
|
||||
const firstSelect = view.sourcePositionSelection.isEmpty();
|
||||
for (const location of locations) {
|
||||
const translated = sourceResolver.translateToSourceId(view.source.sourceId, location);
|
||||
if (!translated) continue;
|
||||
view.selection.select([translated], selected);
|
||||
view.sourcePositionSelection.select([translated], selected);
|
||||
}
|
||||
view.updateSelection(firstSelect);
|
||||
},
|
||||
brokeredClear: function () {
|
||||
view.selection.clear();
|
||||
view.sourcePositionSelection.clear();
|
||||
view.updateSelection();
|
||||
},
|
||||
};
|
||||
@ -196,7 +197,7 @@ export class CodeView extends View {
|
||||
private updateSelection(scrollIntoView: boolean = false): void {
|
||||
const mkVisible = new ViewElements(this.divNode.parentNode as HTMLElement);
|
||||
for (const [sp, els] of this.sourcePositionToHtmlElements.entries()) {
|
||||
const isSelected = this.selection.isKeySelected(sp);
|
||||
const isSelected = this.sourcePositionSelection.isKeySelected(sp);
|
||||
for (const el of els) {
|
||||
mkVisible.consider(el, isSelected);
|
||||
el.classList.toggle("selected", isSelected);
|
||||
@ -220,19 +221,19 @@ export class CodeView extends View {
|
||||
|
||||
private onSelectLine(lineNumber: number, doClear: boolean) {
|
||||
if (doClear) {
|
||||
this.selectionHandler.clear();
|
||||
this.sourcePositionSelectionHandler.clear();
|
||||
}
|
||||
const positions = this.sourceResolver.lineToSourcePositions(lineNumber - 1);
|
||||
if (positions !== undefined) {
|
||||
this.selectionHandler.select(positions, undefined);
|
||||
this.sourcePositionSelectionHandler.select(positions, undefined);
|
||||
}
|
||||
}
|
||||
|
||||
private onSelectSourcePosition(sourcePosition: SourcePosition, doClear: boolean) {
|
||||
if (doClear) {
|
||||
this.selectionHandler.clear();
|
||||
this.sourcePositionSelectionHandler.clear();
|
||||
}
|
||||
this.selectionHandler.select([sourcePosition], undefined);
|
||||
this.sourcePositionSelectionHandler.select([sourcePosition], undefined);
|
||||
}
|
||||
|
||||
private insertSourcePositions(currentSpan: HTMLSpanElement, lineNumber: number,
|
||||
|
@ -57,7 +57,7 @@ export class DisassemblyView extends TextView {
|
||||
|
||||
public updateSelection(scrollIntoView: boolean = false): void {
|
||||
super.updateSelection(scrollIntoView);
|
||||
const selectedKeys = this.selection.selectedKeys();
|
||||
const selectedKeys = this.nodeSelection.selectedKeys();
|
||||
const keyPcOffsets: Array<TurbolizerInstructionStartInfo | string> = [
|
||||
...this.sourceResolver.instructionsPhase.nodesToKeyPcOffsets(selectedKeys)
|
||||
];
|
||||
@ -186,7 +186,7 @@ export class DisassemblyView extends TextView {
|
||||
const view = this;
|
||||
const broker = this.broker;
|
||||
return {
|
||||
select: function (instructionIds: Array<number>, selected: boolean) {
|
||||
select: function (instructionIds: Array<string>, selected: boolean) {
|
||||
view.offsetSelection.select(instructionIds, selected);
|
||||
view.updateSelection();
|
||||
broker.broadcastBlockSelect(this, instructionIds, selected);
|
||||
@ -196,11 +196,14 @@ export class DisassemblyView extends TextView {
|
||||
view.updateSelection();
|
||||
broker.broadcastClear(this);
|
||||
},
|
||||
brokeredInstructionSelect: function (instructionIds: Array<number>, selected: boolean) {
|
||||
brokeredInstructionSelect: function (instructionsOffsets: Array<[number, number]>,
|
||||
selected: boolean) {
|
||||
const firstSelect = view.offsetSelection.isEmpty();
|
||||
const keyPcOffsets = view.sourceResolver.instructionsPhase
|
||||
.instructionsToKeyPcOffsets(instructionIds);
|
||||
view.offsetSelection.select(keyPcOffsets, selected);
|
||||
for (const instructionOffset of instructionsOffsets) {
|
||||
const keyPcOffsets = view.sourceResolver.instructionsPhase
|
||||
.instructionsToKeyPcOffsets(instructionOffset);
|
||||
view.offsetSelection.select(keyPcOffsets, selected);
|
||||
}
|
||||
view.updateSelection(firstSelect);
|
||||
},
|
||||
brokeredClear: function () {
|
||||
@ -221,8 +224,8 @@ export class DisassemblyView extends TextView {
|
||||
const nodes = this.sourceResolver.instructionsPhase.nodesForPCOffset(offset);
|
||||
if (nodes.length > 0) {
|
||||
e.stopPropagation();
|
||||
if (!e.shiftKey) this.selectionHandler.clear();
|
||||
this.selectionHandler.select(nodes, true);
|
||||
if (!e.shiftKey) this.nodeSelectionHandler.clear();
|
||||
this.nodeSelectionHandler.select(nodes, true);
|
||||
} else {
|
||||
this.updateSelection();
|
||||
}
|
||||
@ -235,7 +238,7 @@ export class DisassemblyView extends TextView {
|
||||
const blockId = spanBlockElement.dataset.blockId;
|
||||
if (blockId !== undefined) {
|
||||
const blockIds = blockId.split(",");
|
||||
if (!e.shiftKey) this.selectionHandler.clear();
|
||||
if (!e.shiftKey) this.nodeSelectionHandler.clear();
|
||||
this.blockSelectionHandler.select(blockIds, true);
|
||||
}
|
||||
}
|
||||
|
@ -412,10 +412,10 @@ export class GraphView extends MovableView<Graph> {
|
||||
view.broker.broadcastClear(this);
|
||||
view.updateGraphVisibility();
|
||||
},
|
||||
brokeredNodeSelect: function (locations, selected: boolean) {
|
||||
brokeredNodeSelect: function (nodeIds: Set<string>, selected: boolean) {
|
||||
if (!view.graph) return;
|
||||
const selection = view.graph.nodes(node =>
|
||||
locations.has(node.identifier()) && (!view.state.hideDead || node.isLive()));
|
||||
const selection = view.graph.nodes(node => nodeIds.has(node.identifier())
|
||||
&& (!view.state.hideDead || node.isLive()));
|
||||
view.state.selection.select(selection, selected);
|
||||
// Update edge visibility based on selection.
|
||||
for (const item of view.state.selection.selectedKeys()) {
|
||||
|
@ -24,14 +24,14 @@ export class ScheduleView extends TextView {
|
||||
|
||||
private attachSelection(adaptedSelection: SelectionStorage): void {
|
||||
if (!(adaptedSelection instanceof SelectionStorage)) return;
|
||||
this.selectionHandler.clear();
|
||||
this.nodeSelectionHandler.clear();
|
||||
this.blockSelectionHandler.clear();
|
||||
this.selectionHandler.select(adaptedSelection.adaptedNodes, true);
|
||||
this.nodeSelectionHandler.select(adaptedSelection.adaptedNodes, true);
|
||||
this.blockSelectionHandler.select(adaptedSelection.adaptedBocks, true);
|
||||
}
|
||||
|
||||
public detachSelection(): SelectionStorage {
|
||||
return new SelectionStorage(this.selection.detachSelection(),
|
||||
return new SelectionStorage(this.nodeSelection.detachSelection(),
|
||||
this.blockSelection.detachSelection());
|
||||
}
|
||||
|
||||
@ -71,9 +71,9 @@ export class ScheduleView extends TextView {
|
||||
return function (e) {
|
||||
e.stopPropagation();
|
||||
if (!e.shiftKey) {
|
||||
view.selectionHandler.clear();
|
||||
view.nodeSelectionHandler.clear();
|
||||
}
|
||||
view.selectionHandler.select([nodeId], true);
|
||||
view.nodeSelectionHandler.select([nodeId], true);
|
||||
};
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ export class ScheduleView extends TextView {
|
||||
|
||||
searchInputAction(searchBar, e, onlyVisible) {
|
||||
e.stopPropagation();
|
||||
this.selectionHandler.clear();
|
||||
this.nodeSelectionHandler.clear();
|
||||
const query = searchBar.value;
|
||||
if (query.length == 0) return;
|
||||
const select = [];
|
||||
@ -192,6 +192,6 @@ export class ScheduleView extends TextView {
|
||||
select.push(node.id);
|
||||
}
|
||||
}
|
||||
this.selectionHandler.select(select, true);
|
||||
this.nodeSelectionHandler.select(select, true);
|
||||
}
|
||||
}
|
||||
|
@ -40,14 +40,14 @@ export class SequenceView extends TextView {
|
||||
|
||||
private attachSelection(adaptedSelection: SelectionStorage): void {
|
||||
if (!(adaptedSelection instanceof SelectionStorage)) return;
|
||||
this.selectionHandler.clear();
|
||||
this.nodeSelectionHandler.clear();
|
||||
this.blockSelectionHandler.clear();
|
||||
this.selectionHandler.select(adaptedSelection.adaptedNodes, true);
|
||||
this.nodeSelectionHandler.select(adaptedSelection.adaptedNodes, true);
|
||||
this.blockSelectionHandler.select(adaptedSelection.adaptedBocks, true);
|
||||
}
|
||||
|
||||
public detachSelection(): SelectionStorage {
|
||||
return new SelectionStorage(this.selection.detachSelection(),
|
||||
return new SelectionStorage(this.nodeSelection.detachSelection(),
|
||||
this.blockSelection.detachSelection());
|
||||
}
|
||||
|
||||
@ -89,13 +89,6 @@ export class SequenceView extends TextView {
|
||||
this.divNode.innerHTML = '';
|
||||
this.sequence = sequence;
|
||||
this.searchInfo = [];
|
||||
this.divNode.onclick = (e: MouseEvent) => {
|
||||
if (!(e.target instanceof HTMLElement)) return;
|
||||
const instructionId = Number.parseInt(e.target.dataset.instructionId, 10);
|
||||
if (!instructionId) return;
|
||||
if (!e.shiftKey) this.broker.broadcastClear(null);
|
||||
this.broker.broadcastInstructionSelect(null, [instructionId], true);
|
||||
};
|
||||
this.phaseSelect = (document.getElementById('phase-select') as HTMLSelectElement);
|
||||
this.currentPhaseIndex = this.phaseSelect.selectedIndex;
|
||||
this.addBlocks(this.sequence.blocks);
|
||||
@ -131,7 +124,7 @@ export class SequenceView extends TextView {
|
||||
}
|
||||
|
||||
function mkOperandLinkHandler(text) {
|
||||
return mkLinkHandler(text, view.selectionHandler);
|
||||
return mkLinkHandler(text, view.nodeSelectionHandler);
|
||||
}
|
||||
|
||||
function elementForOperandWithSpan(span, text, searchInfo, isVirtual) {
|
||||
@ -367,7 +360,7 @@ export class SequenceView extends TextView {
|
||||
|
||||
searchInputAction(searchBar, e) {
|
||||
e.stopPropagation();
|
||||
this.selectionHandler.clear();
|
||||
this.nodeSelectionHandler.clear();
|
||||
const query = searchBar.value;
|
||||
if (query.length == 0) return;
|
||||
const select = [];
|
||||
@ -378,6 +371,6 @@ export class SequenceView extends TextView {
|
||||
select.push(item);
|
||||
}
|
||||
}
|
||||
this.selectionHandler.select(select, true);
|
||||
this.nodeSelectionHandler.select(select, true);
|
||||
}
|
||||
}
|
||||
|
@ -20,10 +20,12 @@ import {
|
||||
|
||||
type GenericTextPhase = DisassemblyPhase | SchedulePhase | SequencePhase;
|
||||
export abstract class TextView extends PhaseView {
|
||||
selectionHandler: NodeSelectionHandler & ClearableHandler;
|
||||
broker: SelectionBroker;
|
||||
sourceResolver: SourceResolver;
|
||||
nodeSelectionHandler: NodeSelectionHandler & ClearableHandler;
|
||||
blockSelectionHandler: BlockSelectionHandler & ClearableHandler;
|
||||
registerAllocationSelectionHandler: RegisterAllocationSelectionHandler & ClearableHandler;
|
||||
selection: SelectionMap;
|
||||
nodeSelection: SelectionMap;
|
||||
blockSelection: SelectionMap;
|
||||
registerAllocationSelection: SelectionMap;
|
||||
textListNode: HTMLUListElement;
|
||||
@ -33,8 +35,6 @@ export abstract class TextView extends PhaseView {
|
||||
blockIdToNodeIds: Map<string, Array<string>>;
|
||||
nodeIdToBlockId: Array<string>;
|
||||
patterns: Array<Array<any>>;
|
||||
sourceResolver: SourceResolver;
|
||||
broker: SelectionBroker;
|
||||
|
||||
constructor(parent: HTMLDivElement, broker: SelectionBroker) {
|
||||
super(parent);
|
||||
@ -47,21 +47,21 @@ export abstract class TextView extends PhaseView {
|
||||
this.blockIdToNodeIds = new Map<string, Array<string>>();
|
||||
this.nodeIdToBlockId = new Array<string>();
|
||||
|
||||
this.selection = new SelectionMap(node => String(node));
|
||||
this.nodeSelection = new SelectionMap(node => String(node));
|
||||
this.blockSelection = new SelectionMap(block => String(block));
|
||||
this.registerAllocationSelection = new SelectionMap(register => String(register));
|
||||
|
||||
this.selectionHandler = this.initializeNodeSelectionHandler();
|
||||
this.nodeSelectionHandler = this.initializeNodeSelectionHandler();
|
||||
this.blockSelectionHandler = this.initializeBlockSelectionHandler();
|
||||
this.registerAllocationSelectionHandler = this.initializeRegisterAllocationSelectionHandler();
|
||||
|
||||
broker.addNodeHandler(this.selectionHandler);
|
||||
broker.addNodeHandler(this.nodeSelectionHandler);
|
||||
broker.addBlockHandler(this.blockSelectionHandler);
|
||||
broker.addRegisterAllocatorHandler(this.registerAllocationSelectionHandler);
|
||||
|
||||
this.divNode.addEventListener("click", e => {
|
||||
if (!e.shiftKey) {
|
||||
this.selectionHandler.clear();
|
||||
this.nodeSelectionHandler.clear();
|
||||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
@ -110,7 +110,7 @@ export abstract class TextView extends PhaseView {
|
||||
element.classList.toggle("selected", false);
|
||||
}
|
||||
}
|
||||
for (const nodeId of this.selection.selectedKeys()) {
|
||||
for (const nodeId of this.nodeSelection.selectedKeys()) {
|
||||
const elements = this.nodeIdToHtmlElementsMap.get(nodeId);
|
||||
if (!elements) continue;
|
||||
for (const element of elements) {
|
||||
@ -208,22 +208,22 @@ export abstract class TextView extends PhaseView {
|
||||
const view = this;
|
||||
return {
|
||||
select: function (nodeIds: Array<string>, selected: boolean) {
|
||||
view.selection.select(nodeIds, selected);
|
||||
view.nodeSelection.select(nodeIds, selected);
|
||||
view.updateSelection();
|
||||
view.broker.broadcastNodeSelect(this, view.selection.selectedKeys(), selected);
|
||||
view.broker.broadcastNodeSelect(this, view.nodeSelection.selectedKeys(), selected);
|
||||
},
|
||||
clear: function () {
|
||||
view.selection.clear();
|
||||
view.nodeSelection.clear();
|
||||
view.updateSelection();
|
||||
view.broker.broadcastClear(this);
|
||||
},
|
||||
brokeredNodeSelect: function (nodeIds: Set<string>, selected: boolean) {
|
||||
const firstSelect = view.blockSelection.isEmpty();
|
||||
view.selection.select(nodeIds, selected);
|
||||
view.nodeSelection.select(nodeIds, selected);
|
||||
view.updateSelection(firstSelect);
|
||||
},
|
||||
brokeredClear: function () {
|
||||
view.selection.clear();
|
||||
view.nodeSelection.clear();
|
||||
view.updateSelection();
|
||||
}
|
||||
};
|
||||
@ -258,7 +258,7 @@ export abstract class TextView extends PhaseView {
|
||||
& ClearableHandler {
|
||||
const view = this;
|
||||
return {
|
||||
select: function (instructionIds: Array<number>, selected: boolean) {
|
||||
select: function (instructionIds: Array<string>, selected: boolean) {
|
||||
view.registerAllocationSelection.select(instructionIds, selected);
|
||||
view.updateSelection();
|
||||
view.broker.broadcastInstructionSelect(null, [instructionIds], selected);
|
||||
@ -268,10 +268,12 @@ export abstract class TextView extends PhaseView {
|
||||
view.updateSelection();
|
||||
view.broker.broadcastClear(this);
|
||||
},
|
||||
brokeredRegisterAllocationSelect: function (instructionIds: Array<number>,
|
||||
brokeredRegisterAllocationSelect: function (instructionsOffsets: Array<[number, number]>,
|
||||
selected: boolean) {
|
||||
const firstSelect = view.blockSelection.isEmpty();
|
||||
view.registerAllocationSelection.select(instructionIds, selected);
|
||||
for (const instructionOffset of instructionsOffsets) {
|
||||
view.registerAllocationSelection.select(instructionOffset, selected);
|
||||
}
|
||||
view.updateSelection(firstSelect);
|
||||
},
|
||||
brokeredClear: function () {
|
||||
|
Loading…
Reference in New Issue
Block a user