Skip to content

Commit a333b8e

Browse files
authored
Add lock button (#795)
* add lock command to package.json * building infrastructure for an unlocked button * refreshing GUI once user changes the locking state
1 parent e665855 commit a333b8e

5 files changed

Lines changed: 228 additions & 82 deletions

File tree

package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,18 @@
143143
"command": "vscode-cmsis-debugger.liveWatch.showInMemoryInspector",
144144
"title": "Show in Memory Inspector",
145145
"category": "Live Watch"
146+
},
147+
{
148+
"command": "vscode-cmsis-debugger.componentViewer.lockComponent",
149+
"title": "Lock Component",
150+
"icon": "$(unlock)",
151+
"category": "Component Viewer"
152+
},
153+
{
154+
"command": "vscode-cmsis-debugger.componentViewer.unlockComponent",
155+
"title": "Unlock Component",
156+
"icon": "$(lock)",
157+
"category": "Component Viewer"
146158
}
147159
],
148160
"menus": {
@@ -226,6 +238,14 @@
226238
{
227239
"command": "vscode-cmsis-debugger.liveWatch.showInMemoryInspector",
228240
"when": "false"
241+
},
242+
{
243+
"command": "vscode-cmsis-debugger.componentViewer.lockComponent",
244+
"when": "false"
245+
},
246+
{
247+
"command": "vscode-cmsis-debugger.componentViewer.unlockComponent",
248+
"when": "false"
229249
}
230250
],
231251
"view/title": [
@@ -302,6 +322,16 @@
302322
"command": "vscode-cmsis-debugger.liveWatch.showInMemoryInspector",
303323
"when": "view == cmsis-debugger.liveWatch",
304324
"group": "contextMenuG3@1"
325+
},
326+
{
327+
"command": "vscode-cmsis-debugger.componentViewer.lockComponent",
328+
"when": "view == cmsis-debugger.componentViewer && viewItem == parentInstance",
329+
"group": "inline@1"
330+
},
331+
{
332+
"command": "vscode-cmsis-debugger.componentViewer.unlockComponent",
333+
"when": "view == cmsis-debugger.componentViewer && viewItem == locked.parentInstance",
334+
"group": "inline@2"
305335
}
306336
]
307337
},

src/views/component-viewer/component-viewer-main.ts

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,15 @@ interface UpdateQueueItem {
2828
debugSession: GDBTargetDebugSession;
2929
updateReason: fifoUpdateReason;
3030
}
31+
32+
interface ComponentViewerInstancesWrapper {
33+
componentViewerInstance: ComponentViewerInstance;
34+
lockState: boolean;
35+
}
36+
3137
export class ComponentViewer {
3238
private _activeSession: GDBTargetDebugSession | undefined;
33-
private _instances: ComponentViewerInstance[] = [];
39+
private _instances: ComponentViewerInstancesWrapper[] = [];
3440
private _componentViewerTreeDataProvider: ComponentViewerTreeDataProvider | undefined;
3541
private _context: vscode.ExtensionContext;
3642
private _instanceUpdateCounter: number = 0;
@@ -47,11 +53,51 @@ export class ComponentViewer {
4753
}
4854

4955
public activate(tracker: GDBTargetDebugTracker): void {
56+
// Register Component Viewer tree view
57+
this.registerTreeView();
58+
// Subscribe to debug tracker events to update active session
59+
this.subscribetoDebugTrackerEvents(tracker);
60+
}
61+
62+
protected registerTreeView(): void {
5063
this._componentViewerTreeDataProvider = new ComponentViewerTreeDataProvider();
5164
const treeProviderDisposable = vscode.window.registerTreeDataProvider('cmsis-debugger.componentViewer', this._componentViewerTreeDataProvider);
52-
this._context.subscriptions.push(treeProviderDisposable);
53-
// Subscribe to debug tracker events to update active session
54-
this.subscribetoDebugTrackerEvents(this._context, tracker);
65+
const lockInstanceCommandDisposable = vscode.commands.registerCommand('vscode-cmsis-debugger.componentViewer.lockComponent', async (node) => {
66+
this.handleLockInstance(node);
67+
});
68+
const unlockInstanceCommandDisposable = vscode.commands.registerCommand('vscode-cmsis-debugger.componentViewer.unlockComponent', async (node) => {
69+
this.handleLockInstance(node);
70+
});
71+
this._context.subscriptions.push(
72+
treeProviderDisposable,
73+
lockInstanceCommandDisposable,
74+
unlockInstanceCommandDisposable
75+
);
76+
}
77+
78+
protected handleLockInstance(node: ScvdGuiInterface): void {
79+
const instance = this._instances.find((inst) => {
80+
const guiTree = inst.componentViewerInstance.getGuiTree();
81+
if (!guiTree) {
82+
return false;
83+
}
84+
// Check if the node belongs to this instance. We only care about parent nodes, as locking/unlocking a child node is not supported,
85+
// so we can skip checking the whole tree and just check if the node is one of the roots.
86+
return guiTree[0].getGuiId() === node.getGuiId();
87+
});
88+
if (!instance) {
89+
return;
90+
}
91+
instance.lockState = !instance.lockState;
92+
logger.info(`Component Viewer: Instance lock state changed to ${instance.lockState}`);
93+
// If instance is locked, set isLocked flag to true for root nodes
94+
const guiTree = instance.componentViewerInstance.getGuiTree();
95+
if (!guiTree) {
96+
return;
97+
}
98+
const rootNode: ScvdGuiInterface = guiTree[0];
99+
rootNode.isLocked = instance.lockState;
100+
this._componentViewerTreeDataProvider?.refresh();
55101
}
56102

57103
protected async readScvdFiles(tracker: GDBTargetDebugTracker,session?: GDBTargetDebugSession): Promise<void> {
@@ -76,7 +122,11 @@ export class ComponentViewer {
76122
cbuildRunInstances.push(instance);
77123
}
78124
}
79-
this._instances = cbuildRunInstances;
125+
// Store loaded instances, set default lock state to false
126+
this._instances.push(...cbuildRunInstances.map(instance => ({
127+
componentViewerInstance: instance,
128+
lockState: false
129+
})));
80130
}
81131

82132
private async loadCbuildRunInstances(session: GDBTargetDebugSession, tracker: GDBTargetDebugTracker) : Promise<void | undefined> {
@@ -90,7 +140,7 @@ export class ComponentViewer {
90140
}
91141
}
92142

93-
private subscribetoDebugTrackerEvents(context: vscode.ExtensionContext, tracker: GDBTargetDebugTracker): void {
143+
private subscribetoDebugTrackerEvents(tracker: GDBTargetDebugTracker): void {
94144
const onWillStopSessionDisposable = tracker.onWillStopSession(async (session) => {
95145
await this.handleOnWillStopSession(session);
96146
});
@@ -110,7 +160,7 @@ export class ComponentViewer {
110160
await this.handleOnWillStartSession(session);
111161
});
112162
// clear all disposables on extension deactivation
113-
context.subscriptions.push(
163+
this._context.subscriptions.push(
114164
onWillStopSessionDisposable,
115165
onConnectedDisposable,
116166
onDidChangeActiveDebugSessionDisposable,
@@ -170,7 +220,7 @@ export class ComponentViewer {
170220
return;
171221
}
172222
// update active debug session for all instances
173-
this._instances.forEach((instance) => instance.updateActiveSession(session));
223+
this._instances.forEach((instance) => instance.componentViewerInstance.updateActiveSession(session));
174224
this.schedulePendingUpdate('sessionChanged');
175225
}
176226

@@ -222,12 +272,21 @@ export class ComponentViewer {
222272
this._instanceUpdateCounter++;
223273
logger.debug(`Updating Component Viewer Instance #${this._instanceUpdateCounter} due to '${updateReason}' (queue position #${this._updateQueue.length})`);
224274
console.log(`Updating Component Viewer Instance #${this._instanceUpdateCounter}`);
225-
await instance.update();
226-
const guiTree = instance.getGuiTree();
275+
// Check instance's lock state, skip update if locked
276+
if (!instance.lockState) {
277+
await instance.componentViewerInstance.update();
278+
}
279+
const guiTree = instance.componentViewerInstance.getGuiTree();
227280
if (guiTree) {
228281
roots.push(...guiTree);
282+
// If instance is locked, set isLocked flag to true for root nodes
283+
roots[roots.length - 1].isLocked = instance.lockState;
229284
}
230285
}
286+
// Set isRootInstance flag for all roots to true
287+
roots.forEach((root) => {
288+
root.isRootInstance = true;
289+
});
231290
this._componentViewerTreeDataProvider?.setRoots(roots);
232291
}
233292
}

src/views/component-viewer/component-viewer-tree-view.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export class ComponentViewerTreeDataProvider implements vscode.TreeDataProvider<
3737
: vscode.TreeItemCollapsibleState.None;
3838
// Needs fixing, getGuiValue() for ScvdNode returns 0 when undefined
3939
treeItem.description = element.getGuiValue() ?? '';
40+
const intermediateContextValue = element.isRootInstance ? 'parentInstance' : 'child';
41+
treeItem.contextValue = element.isLocked ? `locked.${intermediateContextValue}` : intermediateContextValue;
4042
const guiId = element.getGuiId();
4143
if (guiId !== undefined) {
4244
treeItem.id = guiId;
@@ -80,7 +82,7 @@ export class ComponentViewerTreeDataProvider implements vscode.TreeDataProvider<
8082
this.refresh();
8183
}
8284

83-
private refresh(): void {
85+
public refresh(): void {
8486
this._onDidChangeTreeData.fire();
8587
}
8688

src/views/component-viewer/model/scvd-gui-interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,6 @@ export interface ScvdGuiInterface {
2323
getGuiConditionResult(): boolean;
2424
getGuiLineInfo(): string | undefined;
2525
hasGuiChildren(): boolean;
26+
isRootInstance?: boolean;
27+
isLocked?: boolean;
2628
}

0 commit comments

Comments
 (0)