+
+ Intermediate_tensors
+
+
+
+ This option cannot be with 'search delegate'
+
+
+
+
+
+ Show Operations
+
+
+
+ Print the log showing operations that mapped to the Edge TPU.
+
+
+
+
+
+ Search Delegate
+
+
+
+ Enable repeated search for a new compilation stopping point earlier in the graph, to avoid rare compiler failures when it encounters an unsupported operation.
+
+
+
+
+
+ Delegate Search Step
+
+
+
+ Specify a step size (the number of ops to move backward)
+ Default size is 1 and the mindest size is also 1.
+
+
+
+
+
+
+
+
+
+
diff --git a/media/EdgeTPUCfgEditor/displaycfg.js b/media/EdgeTPUCfgEditor/displaycfg.js
new file mode 100644
index 000000000..f0a0cf60c
--- /dev/null
+++ b/media/EdgeTPUCfgEditor/displaycfg.js
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function displayCfgToEditor(cfg) {
+ const edgeTPUCompiler = cfg["edgetpu-compiler"];
+ document.getElementById("checkboxEdgeTPUCompile").checked = cfgBoolean(
+ edgeTPUCompiler["edgetpu-compile"]
+ );
+ document.getElementById("checkboxEdgeTPUProfile").checked = cfgBoolean(
+ edgeTPUCompiler["edgetpu-profile"]
+ );
+
+ const edgeTPUCompile = cfg["edgetpu-compile"];
+ document.getElementById("EdgeTPUInputPath").value = cfgString(
+ edgeTPUCompile?.["input_path"]
+ );
+ document.getElementById("EdgeTPUOutputPath").value = cfgString(
+ edgeTPUCompile?.["output_path"]
+ );
+ document.getElementById("EdgeTPUIntermediateTensorsInputArrays").value =
+ cfgString(edgeTPUCompile?.["intermediate_tensors"]);
+ document.getElementById("EdgeTPUShowOperations").checked = cfgBoolean(
+ edgeTPUCompile?.["show_operations"]
+ );
+ document.getElementById("EdgeTPUSearchDelegate").checked = cfgBoolean(
+ edgeTPUCompile?.["search_delegate"]
+ );
+ document.getElementById("EdgeTPUDelegateSearchStep").value = cfgString(
+ edgeTPUCompile?.["delegate_search_step"],
+ "1"
+ );
+}
+
+function cfgString(str, defaultStr = "") {
+ if (str === null || str === undefined) {
+ return defaultStr;
+ }
+ return str.trim();
+}
+
+function cfgBoolean(str) {
+ if (str === null || str === undefined) {
+ return false;
+ }
+
+ if (str === "True") {
+ return true;
+ }
+
+ return false;
+}
diff --git a/media/EdgeTPUCfgEditor/index.js b/media/EdgeTPUCfgEditor/index.js
new file mode 100644
index 000000000..44cad82f2
--- /dev/null
+++ b/media/EdgeTPUCfgEditor/index.js
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { displayCfgToEditor } from "./displaycfg.js";
+import {
+ applyUpdates,
+ updateEdgeTPUStep,
+ updateEdgeTPUCompile,
+} from "./updateContent.js";
+import { updateStepUI } from "./updateUI.js";
+import { postMessageToVsCode } from "./vscodeapi.js";
+
+// Just like a regular webpage we need to wait for the webview
+// DOM to load before we can reference any of the HTML elements
+// or toolkit components
+window.addEventListener("load", main);
+
+// Main function that gets executed once the webview DOM loads
+function main() {
+ registerCompilerStep();
+ registerCompileOptions();
+ registerCodiconEvents();
+
+ // event from vscode extension
+ window.addEventListener("message", (event) => {
+ const message = event.data;
+ switch (message.type) {
+ case "displayCfgToEditor":
+ displayCfgToEditor(message.text);
+ break;
+ case "setDefaultEdgetpuValues":
+ setDefaultEdgetpuValues(message.name);
+ break;
+ case "applyDialogPath":
+ document.getElementById(message.elemID).value = message.path;
+ switch (message.step) {
+ case "EdgeTPUCompile":
+ updateEdgeTPUCompile();
+ break;
+ default:
+ break;
+ }
+ applyUpdates();
+ break;
+ default:
+ break;
+ }
+ });
+
+ postMessageToVsCode({ type: "requestDisplayCfg" });
+}
+
+function setDefaultEdgetpuValues(name) {
+ // EdgeTPu COmpiler steps
+ document.getElementById("checkboxEdgeTPUCompile").checked = true;
+
+ updateEdgeTPUStep();
+
+ // compile step
+ let compiledName = name + ".tflite";
+ let compiledExt = name + "_edgetpu.tflite";
+ document.getElementById("EdgeTPUInputPath").value = compiledName;
+ document.getElementById("EdgeTPUOutputPath").value = compiledExt;
+
+ updateEdgeTPUCompile();
+
+ // apply
+ applyUpdates();
+}
+
+function registerCompilerStep() {
+ const checkboxEdgeTPUCompile = document.getElementById(
+ "checkboxEdgeTPUCompile"
+ );
+ const checkboxEdgeTPUProfile = document.getElementById(
+ "checkboxEdgeTPUProfile"
+ );
+ const stepEdgeTPUCompile = document.getElementById("stepEdgeTPUCompile");
+ const stepEdgeTPUProfile = document.getElementById("stepEdgeTPUProfile");
+
+ checkboxEdgeTPUCompile.addEventListener("click", function () {
+ updateEdgeTPUStep();
+ applyUpdates();
+ });
+ checkboxEdgeTPUProfile.addEventListener("click", function () {
+ updateEdgeTPUStep();
+ applyUpdates();
+ });
+
+ stepEdgeTPUCompile.addEventListener("click", function () {
+ updateStepUI("EdgeTPUCompile");
+ });
+ stepEdgeTPUProfile.addEventListener("click", function () {
+ updateStepUI("EdgeTPUProfile");
+ });
+}
+
+function registerCompileOptions() {
+ const edgeTPUInputPath = document.getElementById("EdgeTPUInputPath");
+ const edgeTPUIntermediateTensors = document.getElementById(
+ "EdgeTPUIntermediateTensorsInputArrays"
+ );
+ const edgeTPUShowOperations = document.getElementById(
+ "EdgeTPUShowOperations"
+ );
+ const edgeTPUSearchDelegate = document.getElementById(
+ "EdgeTPUSearchDelegate"
+ );
+ const edgeTPUDelegateSearchStep = document.getElementById(
+ "EdgeTPUDelegateSearchStep"
+ );
+ const edgeTPUDelegateSearchStepDiv = document.getElementById(
+ "EdgeTPUDelegateSearchStepDiv"
+ );
+
+ edgeTPUInputPath.addEventListener("input", function () {
+ updateEdgeTPUCompile();
+ applyUpdates();
+ });
+ edgeTPUIntermediateTensors.addEventListener("input", function () {
+ if (edgeTPUSearchDelegate.checked) {
+ edgeTPUSearchDelegate.checked = false;
+ edgeTPUDelegateSearchStepDiv.style.display = "none";
+ }
+ updateEdgeTPUCompile();
+ applyUpdates();
+ });
+ edgeTPUShowOperations.addEventListener("click", function () {
+ updateEdgeTPUCompile();
+ applyUpdates();
+ });
+ edgeTPUSearchDelegate.addEventListener("click", function () {
+ if (edgeTPUSearchDelegate.checked) {
+ edgeTPUIntermediateTensors.value = "";
+ edgeTPUDelegateSearchStepDiv.style.display = "block";
+ } else {
+ edgeTPUDelegateSearchStepDiv.style.display = "none";
+ }
+ updateEdgeTPUCompile();
+ applyUpdates();
+ });
+ edgeTPUDelegateSearchStep.addEventListener("input", function () {
+ edgeTPUDelegateSearchStep.value =
+ edgeTPUDelegateSearchStep.value < 1
+ ? "1"
+ : edgeTPUDelegateSearchStep.value;
+ updateEdgeTPUCompile();
+ applyUpdates();
+ });
+}
+
+function registerCodiconEvents() {
+ document
+ .getElementById("EdgeTPUInputPathSearch")
+ .addEventListener("click", function () {
+ postMessageToVsCode({
+ type: "getPathByDialog",
+ isFolder: false,
+ ext: ["tflite"],
+ oldPath: document.getElementById("EdgeTPUInputPath").value,
+ postStep: "EdgeTPUCompile",
+ postElemID: "EdgeTPUInputPath",
+ });
+ });
+}
diff --git a/media/EdgeTPUCfgEditor/updateContent.js b/media/EdgeTPUCfgEditor/updateContent.js
new file mode 100644
index 000000000..f4dee5941
--- /dev/null
+++ b/media/EdgeTPUCfgEditor/updateContent.js
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { postMessageToVsCode } from "./vscodeapi.js";
+
+function iniKeyValueString(iniKey, iniValue, noEffectValue = undefined) {
+ if (iniValue === null || iniValue === undefined) {
+ return "";
+ }
+
+ if (iniValue === false) {
+ return "";
+ } else if (iniValue === true) {
+ return iniKey + "=True\n";
+ }
+
+ const trimmedValue = iniValue.trim();
+ if (trimmedValue === "" || trimmedValue === noEffectValue) {
+ return "";
+ }
+
+ return iniKey + "=" + trimmedValue + "\n";
+}
+
+export function applyUpdates() {
+ postMessageToVsCode({ type: "updateDocument" });
+}
+
+export function updateEdgeTPUStep() {
+ postMessageToVsCode({
+ type: "setParam",
+ section: "edgetpu-compiler",
+ param: "edgetpu-compile",
+ value: document.getElementById("checkboxEdgeTPUCompile").checked
+ ? "True"
+ : "False",
+ });
+ postMessageToVsCode({
+ type: "setParam",
+ section: "edgetpu-compiler",
+ param: "edgetpu-profile",
+ value: document.getElementById("checkboxEdgeTPUProfile").checked
+ ? "True"
+ : "False",
+ });
+}
+
+function addPostfixToFileName(filePath = "", postfix = "") {
+ if (filePath.trim() === "") {
+ return "";
+ }
+ const parts = filePath.split(".");
+ let newFilePath = "";
+ if (parts.length < 2) {
+ newFilePath = `${filePath}${postfix}`;
+ } else {
+ const fileName = parts.slice(0, -1).join(".");
+ const fileExtension = parts[parts.length - 1];
+ const newFileName = `${fileName}${postfix}`;
+ newFilePath = `${newFileName}.${fileExtension}`;
+ }
+
+ return newFilePath;
+}
+
+export function updateEdgeTPUCompile() {
+ let content = "";
+ content += iniKeyValueString(
+ "input_path",
+ document.getElementById("EdgeTPUInputPath").value
+ );
+ content += iniKeyValueString(
+ "output_path",
+ addPostfixToFileName(
+ document.getElementById("EdgeTPUInputPath").value,
+ "_edgetpu"
+ )
+ );
+ content += iniKeyValueString(
+ "intermediate_tensors",
+ document.getElementById("EdgeTPUIntermediateTensorsInputArrays").value
+ );
+ content += iniKeyValueString(
+ "show_operations",
+ document.getElementById("EdgeTPUShowOperations").checked
+ );
+ content += iniKeyValueString(
+ "search_delegate",
+ document.getElementById("EdgeTPUSearchDelegate").checked
+ );
+ content += iniKeyValueString(
+ "delegate_search_step",
+ document.getElementById("EdgeTPUSearchDelegate").checked
+ ? document.getElementById("EdgeTPUDelegateSearchStep").value < 1
+ ? "1"
+ : document.getElementById("EdgeTPUDelegateSearchStep").value
+ : undefined
+ );
+
+ postMessageToVsCode({
+ type: "setSection",
+ section: "edgetpu-compile",
+ param: content,
+ });
+}
+
+export function updateEdgeTPUProfile() {
+ let content = "";
+
+ postMessageToVsCode({
+ type: "setSection",
+ section: "edgetpu-profile",
+ param: content,
+ });
+}
diff --git a/media/EdgeTPUCfgEditor/updateUI.js b/media/EdgeTPUCfgEditor/updateUI.js
new file mode 100644
index 000000000..2f3f7e0a7
--- /dev/null
+++ b/media/EdgeTPUCfgEditor/updateUI.js
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function updateStepUI(step) {
+ const allOptionPanels = document.querySelectorAll(".optionPanel .options");
+ allOptionPanels.forEach(function (panel) {
+ panel.style.display = "none";
+ });
+
+ const optionPanel = document.getElementById("option" + step);
+ optionPanel.style.display = "block";
+
+ const edgeTPUSearchDelegate = document.getElementById(
+ "EdgeTPUSearchDelegate"
+ );
+ const edgeTPUDelegateSearchStepDiv = document.getElementById(
+ "EdgeTPUDelegateSearchStepDiv"
+ );
+ const edgeTPUIntermediateTensors = document.getElementById(
+ "EdgeTPUIntermediateTensors"
+ );
+
+ if (edgeTPUSearchDelegate.checked) {
+ edgeTPUIntermediateTensors.value = "";
+ edgeTPUDelegateSearchStepDiv.style.display = "block";
+ } else {
+ edgeTPUDelegateSearchStepDiv.style.display = "none";
+ }
+
+ const allSteps = document.querySelectorAll(".statusbar .steps .step");
+ allSteps.forEach(function (step) {
+ step.classList.remove("current");
+ });
+
+ const stepbar = document.getElementById("stepbar" + step);
+ stepbar.classList.add("current");
+}
+
+export function updateEdgeTPUCompileUI() {
+ const allOptionPanels = document.querySelectorAll(".optionPanel .options");
+ allOptionPanels.forEach(function (panel) {
+ panel.style.display = "none";
+ });
+
+ const edgeTPUBasicOptions = document.getElementById(
+ "optionImportEdgeTPUBasic"
+ );
+ const edgeTPUAdvancedOptions = document.getElementById(
+ "optionImportEdgeTPUAdvanced"
+ );
+ const edgeTPUSearchDelegate = document.getElementById(
+ "EdgeTPUSearchDelegate"
+ );
+ const edgeTPUDelegateSearchStepDiv = document.getElementById(
+ "EdgeTPUDelegateSearchStepDiv"
+ );
+
+ edgeTPUBasicOptions.style.display = "none";
+ edgeTPUAdvancedOptions.style.display = "none";
+
+ edgeTPUDelegateSearchStepDiv.style.display = edgeTPUSearchDelegate.checked
+ ? "block"
+ : "none";
+ edgeTPUBasicOptions.style.display = "block";
+ edgeTPUAdvancedOptions.style.display = "block";
+}
diff --git a/media/EdgeTPUCfgEditor/vscodeapi.js b/media/EdgeTPUCfgEditor/vscodeapi.js
new file mode 100644
index 000000000..6cdfaf356
--- /dev/null
+++ b/media/EdgeTPUCfgEditor/vscodeapi.js
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const vscode = acquireVsCodeApi();
+
+export function postMessageToVsCode(msg) {
+ vscode.postMessage(msg);
+}
diff --git a/package.json b/package.json
index fca3025a2..51a433d4d 100644
--- a/package.json
+++ b/package.json
@@ -59,6 +59,16 @@
],
"priority": "option"
},
+ {
+ "viewType": "one.editor.edgetpucfg",
+ "displayName": "Edge TPU Configuration Editor",
+ "selector": [
+ {
+ "filenamePattern": "*.edgetpucfg"
+ }
+ ],
+ "priority": "option"
+ },
{
"viewType": "one.viewer.mondrian",
"displayName": "Mondrian",
@@ -287,6 +297,11 @@
"title": "ONE: Set Default Values",
"category": "ONE"
},
+ {
+ "command": "one.editor.edgetpucfg.setDefaultValues",
+ "title": "ONE: Set Default EdgeTPU Compiler Values",
+ "category": "ONE"
+ },
{
"command": "one.editor.mpq.createFromDefaultExplorer",
"title": "ONE: Create Mixed Precision Quantization Configuration",
@@ -309,6 +324,11 @@
"key": "ctrl+shift+/",
"when": "activeCustomEditorId == one.editor.cfg"
},
+ {
+ "command": "one.cfgEditor.setDefaultEdgetpuValues",
+ "key": "ctrl+shift+/",
+ "when": "activeCustomEditorId == one.editor.edgetpucfg"
+ },
{
"command": "one.explorer.deleteOnShortcut",
"key": "delete",
diff --git a/src/CfgEditor/EdgeTPUCfgEditorPanel.ts b/src/CfgEditor/EdgeTPUCfgEditorPanel.ts
new file mode 100644
index 000000000..b96e9b2bb
--- /dev/null
+++ b/src/CfgEditor/EdgeTPUCfgEditorPanel.ts
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (c) Microsoft Corporation
+ *
+ * All rights reserved.
+ *
+ * MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+Some part of this code refers to
+https://github.com/microsoft/vscode-extension-samples/blob/2556c82cb333cf65d372bd01ac30c35ea1898a0e/custom-editor-sample/src/catScratchEditor.ts
+*/
+
+import * as path from "path";
+import * as vscode from "vscode";
+
+import { getNonce } from "../Utils/external/Nonce";
+import { getUri } from "../Utils/external/Uri";
+
+import { EdgeTPUCfgData } from "./EdgeTPUCfgData";
+
+/* istanbul ignore next */
+export class EdgeTPUCfgEditorPanel implements vscode.CustomTextEditorProvider {
+ private _disposables: vscode.Disposable[] = [];
+ private _oneConfigMap: any = {};
+ private _activeDocument: vscode.TextDocument | undefined;
+ private _activeWebviewPanel: vscode.WebviewPanel | undefined;
+
+ public static readonly viewType = "one.editor.edgetpucfg";
+
+ public static register(context: vscode.ExtensionContext): void {
+ const provider = new EdgeTPUCfgEditorPanel(context);
+
+ const registrations = [
+ vscode.window.registerCustomEditorProvider(
+ EdgeTPUCfgEditorPanel.viewType,
+ provider,
+ {
+ webviewOptions: {
+ retainContextWhenHidden: true,
+ },
+ }
+ ),
+ // Add command registration here
+ vscode.commands.registerCommand(
+ "one.cfgEditor.setDefaultEdgetpuValues",
+ () => {
+ if (!provider._activeWebviewPanel || !provider._activeDocument) {
+ return;
+ }
+
+ const cfgName = path.parse(provider._activeDocument!.fileName).name;
+
+ provider._activeWebviewPanel!.webview.postMessage({
+ type: "setDefaultEdgetpuValues",
+ name: cfgName,
+ });
+ }
+ ),
+ ];
+
+ registrations.forEach((disposable) =>
+ context.subscriptions.push(disposable)
+ );
+ }
+
+ constructor(private readonly context: vscode.ExtensionContext) {}
+
+ async resolveCustomTextEditor(
+ document: vscode.TextDocument,
+ webviewPanel: vscode.WebviewPanel,
+ _token: vscode.CancellationToken
+ ): Promise {
+ this._activeWebviewPanel = webviewPanel;
+ this._activeDocument = document;
+ this._oneConfigMap[document.uri.toString()] = new EdgeTPUCfgData();
+ await this.initWebview(document, webviewPanel.webview);
+ this.initWebviewPanel(document, webviewPanel);
+ this.updateWebview(document, webviewPanel.webview);
+ }
+
+ async initWebview(
+ document: vscode.TextDocument,
+ webview: vscode.Webview
+ ): Promise {
+ webview.options = {
+ enableScripts: true,
+ };
+
+ const nonce = getNonce();
+ const toolkitUri = getUri(webview, this.context.extensionUri, [
+ "node_modules",
+ "@vscode",
+ "webview-ui-toolkit",
+ "dist",
+ "toolkit.js",
+ ]);
+
+ const codiconUri = getUri(webview, this.context.extensionUri, [
+ "node_modules",
+ "@vscode",
+ "codicons",
+ "dist",
+ "codicon.css",
+ ]);
+
+ const jsUri = getUri(webview, this.context.extensionUri, [
+ "media",
+ "EdgeTPUCfgEditor",
+ "index.js",
+ ]);
+
+ const cssUri = getUri(webview, this.context.extensionUri, [
+ "media",
+ "EdgeTPUCfgEditor",
+ "cfgeditor.css",
+ ]);
+
+ const htmlUri = vscode.Uri.joinPath(
+ this.context.extensionUri,
+ "media/EdgeTPUCfgEditor/cfgeditor.html"
+ );
+
+ let html = Buffer.from(
+ await vscode.workspace.fs.readFile(htmlUri)
+ ).toString();
+ html = html.replace(/\${nonce}/g, `${nonce}`);
+ html = html.replace(/\${webview.cspSource}/g, `${webview.cspSource}`);
+ html = html.replace(/\${toolkitUri}/g, `${toolkitUri}`);
+ html = html.replace(/\${codiconUri}/g, `${codiconUri}`);
+ html = html.replace(/\${jsUri}/g, `${jsUri}`);
+ html = html.replace(/\${cssUri}/g, `${cssUri}`);
+ webview.html = html;
+
+ // Receive message from the webview.
+ webview.onDidReceiveMessage((e) => {
+ switch (e.type) {
+ case "requestDisplayCfg":
+ this.updateWebview(document, webview);
+ break;
+ case "setParam":
+ this._oneConfigMap[document.uri.toString()].updateSectionWithKeyValue(
+ e.section,
+ e.param,
+ e.value
+ );
+ break;
+ case "setSection":
+ this._oneConfigMap[document.uri.toString()].updateSectionWithValue(
+ e.section,
+ e.param
+ );
+ break;
+ case "updateDocument":
+ if (
+ this._oneConfigMap[document.uri.toString()].isSame(
+ document.getText()
+ ) === false
+ ) {
+ this._oneConfigMap[document.uri.toString()].sort();
+
+ // TODO Optimize this to modify only changed lines
+ const edit = new vscode.WorkspaceEdit();
+ edit.replace(
+ document.uri,
+ new vscode.Range(0, 0, document.lineCount, 0),
+ this._oneConfigMap[document.uri.toString()].getAsString()
+ );
+ vscode.workspace.applyEdit(edit);
+ }
+ break;
+ case "getPathByDialog": {
+ const dialogOptions = {
+ canSelectMany: false,
+ canSelectFolders: e.isFolder,
+ openLabel: "Open",
+ filters: { "target files": e.ext, "all files": ["*"] },
+ };
+ let newPath = e.oldPath;
+ vscode.window.showOpenDialog(dialogOptions).then((fileUri) => {
+ if (fileUri && fileUri[0]) {
+ newPath = fileUri[0].fsPath.toString();
+ webview.postMessage({
+ type: "applyDialogPath",
+ step: e.postStep,
+ elemID: e.postElemID,
+ path: newPath,
+ });
+ }
+ });
+ break;
+ }
+ default:
+ break;
+ }
+ });
+ }
+
+ initWebviewPanel(
+ document: vscode.TextDocument,
+ webviewPanel: vscode.WebviewPanel
+ ): void {
+ vscode.commands.executeCommand(
+ "setContext",
+ EdgeTPUCfgEditorPanel.viewType,
+ true
+ );
+
+ const changeDocumentSubscription = vscode.workspace.onDidChangeTextDocument(
+ (e) => {
+ if (
+ e.contentChanges.length > 0 &&
+ e.document.uri.toString() === document.uri.toString()
+ ) {
+ this.updateWebview(document, webviewPanel.webview);
+ }
+ }
+ );
+
+ webviewPanel.onDidChangeViewState(
+ () => {
+ if (webviewPanel.visible) {
+ this._activeWebviewPanel = webviewPanel;
+ this._activeDocument = document;
+ vscode.commands.executeCommand(
+ "one.explorer.revealInOneExplorer",
+ document.fileName
+ );
+ }
+ vscode.commands.executeCommand(
+ "setContext",
+ EdgeTPUCfgEditorPanel.viewType,
+ webviewPanel.visible
+ );
+ },
+ null,
+ this._disposables
+ );
+
+ webviewPanel.onDidDispose(() => {
+ changeDocumentSubscription.dispose();
+ while (this._disposables.length) {
+ const x = this._disposables.pop();
+ if (x) {
+ x.dispose();
+ }
+ }
+ vscode.commands.executeCommand(
+ "setContext",
+ EdgeTPUCfgEditorPanel.viewType,
+ false
+ );
+ });
+ }
+
+ updateWebview(document: vscode.TextDocument, webview: vscode.Webview): void {
+ this._oneConfigMap[document.uri.toString()].setWithString(
+ document.getText()
+ );
+ webview.postMessage({
+ type: "displayCfgToEditor",
+ text: this._oneConfigMap[document.uri.toString()].getAsConfig(),
+ });
+ }
+}
diff --git a/src/extension.ts b/src/extension.ts
index 28220ecda..80e8a6e9b 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -19,6 +19,7 @@ import * as vscode from "vscode";
import { API } from "./Backend/API";
import { OneToolchain } from "./Backend/One/OneToolchain";
import { CfgEditorPanel } from "./CfgEditor/CfgEditorPanel";
+import { EdgeTPUCfgEditorPanel } from "./CfgEditor/EdgeTPUCfgEditorPanel";
import { CircleEditorProvider } from "./CircleEditor/CircleEditorProvider";
import { CircleViewerProvider } from "./CircleGraph/CircleViewer";
import { DeviceViewProvider } from "./Execute/DeviceViewProvider";
@@ -65,6 +66,8 @@ export function activate(context: vscode.ExtensionContext) {
CfgEditorPanel.register(context);
+ EdgeTPUCfgEditorPanel.register(context);
+
JsonTracerViewerPanel.register(context);
MondrianEditorProvider.register(context);