Skip to content

Commit

Permalink
Merge pull request #704 from Domiii/issue#702
Browse files Browse the repository at this point in the history
misc fixes
  • Loading branch information
Domiii authored Mar 23, 2022
2 parents c799898 + 25cad2b commit 85a6496
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 37 deletions.
28 changes: 21 additions & 7 deletions dbux-code/src/codeUtil/treeView/BaseTreeViewNodeProvider.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TreeItemCollapsibleState, EventEmitter, window, TreeView } from 'vscode';
import TriggerablePromise from '@dbux/common/src/util/TriggerablePromise';
import EmptyObject from '@dbux/common/src/util/EmptyObject';
import { newLogger } from '@dbux/common/src/log/logger';
import NestedError from '@dbux/common/src/NestedError';
Expand Down Expand Up @@ -50,6 +51,7 @@ export default class BaseTreeViewNodeProvider {
constructor(viewName, options = {}) {
this.treeViewName = viewName;
this.logger = newLogger(this.constructor.name);
this.refreshPromise = new TriggerablePromise(500);
const { showCollapseAll = false, createTreeView = true } = options;

// NOTE: view creation inside the data provider is not ideal,
Expand Down Expand Up @@ -113,6 +115,8 @@ export default class BaseTreeViewNodeProvider {

// NOTE: if we only want to update subtree, pass root of subtree to `fire`
this.repaint();

this.refreshPromise.startIfNotStarted();
}
catch (err) {
throw new NestedError(`${this.constructor.name}.refresh() failed`, err);
Expand Down Expand Up @@ -385,6 +389,12 @@ export default class BaseTreeViewNodeProvider {
}

getChildren = async (node) => {
const children = await this._getChildren(node);
this.refreshPromise.resolve(children);
return children;
}

_getChildren = async (node) => {
try {
if (node) {
this.handleBeforeChildren(node);
Expand Down Expand Up @@ -418,15 +428,19 @@ export default class BaseTreeViewNodeProvider {
/**
* Find a chlid node of given class from parent, or from roots if parent is `undefined`.
* @param {*} clazz A node class that extends `BaseTreeViewNode`
* @param {BaseTreeViewNode} parent
* @param {BaseTreeViewNode} parent
* @return {BaseTreeViewNode}
*/
getNodeByClass(clazz, parent = null) {
let children = this.rootNodes;
if (parent) {
children = parent.children;
}
getChildByClass(clazz, parent) {
return parent.children.find(node => node instanceof clazz);
}

return children.find(node => node instanceof clazz);
/**
* Find root of given class.
* @param {*} clazz A node class that extends `BaseTreeViewNode`
* @return {BaseTreeViewNode}
*/
getRootByClass(clazz) {
return this.rootNodes.find(node => node instanceof clazz);
}
}
19 changes: 15 additions & 4 deletions dbux-code/src/globalAnalysisView/GlobalAnalysisViewController.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { newLogger } from '@dbux/common/src/log/logger';
import NestedError from '@dbux/common/src/NestedError';
import allApplications from '@dbux/data/src/applications/allApplications';
import traceSelection from '@dbux/data/src/traceSelection';
import searchController from '../search/searchController';
Expand Down Expand Up @@ -49,8 +50,18 @@ export default class GlobalAnalysisViewController {
* #########################################################################*/

async focusOnSearchResult() {
const searchResultNode = this.treeDataProvider.getNodeByClass(GlobalSearchNode);
await this.treeView.reveal(searchResultNode, { select: false, expand: 1 });
const searchResultNode = this.treeDataProvider.getRootByClass(GlobalSearchNode);
try {
/**
* NOTE: VSCode sometimes failed to reveal if `refresh` is executing simultaneously, which causes an error:
* `Error: TreeError [dbuxTraceDetailsView] Data tree node not found: [object Object]`.
* But currently VSCode API does not support thenable `refresh`.
*/
await this.treeView.reveal(searchResultNode, { select: false, expand: 1 });
}
catch (err) {
warn(new NestedError(`Failed to focus on search result`, err));
}
}

/** ###########################################################################
Expand All @@ -64,10 +75,10 @@ export default class GlobalAnalysisViewController {

async revealSelectedError() {
if (!this.children) {
const errorNode = this.treeDataProvider.getNodeByClass(GlobalErrorsNode);
const errorNode = this.treeDataProvider.getRootByClass(GlobalErrorsNode);
await this.treeView.reveal(errorNode, { select: false, expand: true });
}
const errorNode = this.treeDataProvider.getNodeByClass(GlobalErrorsNode);
const errorNode = this.treeDataProvider.getRootByClass(GlobalErrorsNode);
const selectedErrorNode = errorNode.getSelectedChild();
if (selectedErrorNode) {
await this.treeView.reveal(selectedErrorNode);
Expand Down
15 changes: 8 additions & 7 deletions dbux-code/src/search/searchController.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class SearchController {

constructor() {
this._emitter = new NanoEvents();
this.reset();
this.mode = SearchMode.None;
this.resetSearch();

allApplications.selection.onApplicationsChanged(this.handleApplicationSelectionChanged);
}
Expand Down Expand Up @@ -54,6 +55,11 @@ class SearchController {
return this.matches;
}

clearSearch(fromUser = false) {
this.resetSearch();
this._notifySearch(fromUser);
}

nextSearchMode() {
let nextMode = SearchMode.nextValue(this.mode);
if (nextMode === SearchMode.None) {
Expand All @@ -69,17 +75,12 @@ class SearchController {
return SearchTools[this.mode].getContext(dp, match);
}

clearSearch() {
resetSearch() {
this.searchTerm = '';
this.matches = EmptyArray;
this.contexts = EmptyArray;
}

reset() {
this.mode = SearchMode.None;
this.clearSearch();
}

/** ###########################################################################
* event handling
* #########################################################################*/
Expand Down
55 changes: 55 additions & 0 deletions dbux-common/src/util/TriggerablePromise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import sleep from './sleep';

export default class TriggerablePromise {
promise;

_resolve;
_reject;

constructor(timeout) {
this.timeout = timeout;
}

startIfNotStarted() {
if (!this.promise) {
this.start();
}
return this.promise;
}

start() {
const promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});

if (this.timeout) {
this.promise = Promise.race([promise, sleep(this.timeout).then(() => this.resolve())]);
}
else {
this.promise = promise;
}
}

resolve(arg) {
if (this.promise) {
this._handleFinish();
this._resolve(arg);
}
}

reject(arg) {
if (this.promise) {
this._handleFinish();
this._reject(arg);
}
}

wait() {
return this.promise;
}

_handleFinish() {
this.promise = null;
}
}
16 changes: 9 additions & 7 deletions dbux-graph-host/src/componentLib/HostComponentEndpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ class HostComponentEndpoint extends ComponentEndpoint {
await sleep(0);
}

if (this._updatePromise) {
await (this._updatePromise = this._updatePromise.then(noop));
while (this._updatePromise) {
await this._updatePromise;
}
}

Expand Down Expand Up @@ -263,15 +263,17 @@ class HostComponentEndpoint extends ComponentEndpoint {
}
}

_executeUpdate = async () => {
/**
* @returns {Promise}
*/
_executeUpdate = () => {
// debounce mechanism
this._waitingForUpdate = true;
await sleep(0);

// push out new update
const promise = Promise.resolve(
this._performUpdate() // 1. host: update
).
const promise = sleep(0).then(() => {
return this._performUpdate(); // 1. host: update
}).
then(() => {
return this._remoteInternal.updateClient(this.state); // 2. client: update
}).
Expand Down
11 changes: 8 additions & 3 deletions dbux-graph-host/src/graph/SearchBar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import SearchMode from '@dbux/graph-common/src/shared/SearchMode';
import allApplications from '@dbux/data/src/applications/allApplications';
import UserActionType from '@dbux/data/src/pathways/UserActionType';
import traceSelection from '@dbux/data/src/traceSelection/index';
import HostComponentEndpoint from '../componentLib/HostComponentEndpoint';
import { SelectorType } from './controllers/ContextNodeManager';
Expand Down Expand Up @@ -45,8 +44,14 @@ class SearchBar extends HostComponentEndpoint {
}

search = (searchTerm) => {
Verbose && this.logger.log(`.search() with searchTerm=${searchTerm}`);
this.searchController.search(searchTerm, true);
if (searchTerm) {
Verbose && this.logger.log(`.search() with searchTerm=${searchTerm}`);
this.searchController.search(searchTerm, true);
}
else {
Verbose && this.logger.log(`clear search`);
this.searchController.clearSearch();
}
}

handleSearchModeChanged = (mode) => {
Expand Down
32 changes: 24 additions & 8 deletions dbux-graph-host/src/graph/SyncGraphBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,12 @@ class CallGraphNodes {
context,
});
this.contextNodesByContext.set(context, node);

node.addDisposable(() => {
this._handleContextNodeDisposed(context, node);
});
}

node.addDisposable(() => {
this._handleContextNodeDisposed(node);
});

return node;
}

Expand Down Expand Up @@ -403,10 +403,26 @@ class CallGraphNodes {
* dispose, delete, clear
* ##########################################################################*/

_handleContextNodeDisposed = (context, contextNode) => {
if (this.getContextNodeByContext(context) === contextNode) {
// actual removal of node
this.contextNodesByContext.delete(context);
/**
* remove disposed node from `this.contextNodesByContext`
* @param {ContextNode | HoleNode} node
*/
_handleContextNodeDisposed = (node) => {
let contexts;
if (node instanceof ContextNode) {
contexts = [node.state.context];
}
else if (node instanceof HoleNode) {
contexts = node.group.contexts;
}
else {
throw new Error(`Calling "_handleContextNodeDisposed" with non-ContextNode parameter`);
}

for (const context of contexts) {
if (this.getContextNodeByContext(context) === node) {
this.contextNodesByContext.delete(context);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion dbux-graph-host/src/graph/controllers/FocusController.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default class FocusController extends HostComponentEndpoint {
}

await targetNode.reveal?.();
this.remote.slideToNode(targetNode);
await this.remote.slideToNode(targetNode);
}

clearFocus() {
Expand Down

0 comments on commit 85a6496

Please sign in to comment.