Skip to content

Commit

Permalink
Clean up and enable DSE feature (#140)
Browse files Browse the repository at this point in the history
Enable the DSE feature globally. Clean it up so the entry points are
non-obtrusive, they're behind a DSE submenu in the context menus

Also cleaning up of the DSE feature interface:
- Axis ticks use SI prefix instead of the 1e9 mess
- Adding a first objective / search space no longer brings up a
(nonfatal) IDE error - using .lastOption instead of .last
- Gate unproven objective behind the feature enable config
- Add DSE objective insert on port parameters - it should be possible to
do the example purely graphically
  • Loading branch information
ducky64 authored Mar 29, 2024
1 parent f6b025b commit 9e31bf4
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 37 deletions.
2 changes: 1 addition & 1 deletion PolymorphicBlocks
Submodule PolymorphicBlocks updated 257 files
3 changes: 1 addition & 2 deletions src/main/scala/edg_ide/dse/DseFeature.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package edg_ide.dse

object DseFeature {
// feature flag to hide the feature while it's still in development
val kEnabled = false
val kEnabled = true
}
3 changes: 2 additions & 1 deletion src/main/scala/edg_ide/swing/dse/JDsePlot.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edg_ide.swing.dse

import com.intellij.ui.JBColor
import edg_ide.util.SiPrefixUtil

import java.awt.Color
import scala.collection.mutable
Expand Down Expand Up @@ -86,7 +87,7 @@ object JDsePlot {
var tickPos = (math.floor(range._1 / tickSpacing) * tickSpacing).toFloat
val ticksBuilder = mutable.ArrayBuffer[(Float, String)]()
while (tickPos <= range._2) {
ticksBuilder.append((tickPos, f"$tickPos%.02g"))
ticksBuilder.append((tickPos, SiPrefixUtil.unitsToString(tickPos, "")))
tickPos = (tickPos + tickSpacing).toFloat
}
ticksBuilder.toSeq
Expand Down
28 changes: 16 additions & 12 deletions src/main/scala/edg_ide/ui/DetailPanel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import edgrpc.hdl.{hdl => edgrpc}
import java.awt.datatransfer.StringSelection
import java.awt.event.{KeyAdapter, KeyEvent, MouseAdapter, MouseEvent}
import java.awt.{BorderLayout, Toolkit}
import javax.swing.{JPanel, JPopupMenu, KeyStroke, SwingUtilities}
import javax.swing.{JMenu, JPanel, JPopupMenu, KeyStroke, SwingUtilities}

class DetailParamPopupMenu(
path: IndirectDesignPath,
Expand Down Expand Up @@ -92,9 +92,16 @@ class DetailParamPopupMenu(
)
)

addSeparator()
val hotkeyModifier = Toolkit.getDefaultToolkit.getMenuShortcutKeyMaskEx
val copyValueItem = add(ContextMenuUtils.MenuItemFromErrorable(copyAction, s"Copy value"))
copyValueItem.setMnemonic(KeyEvent.VK_C)
copyValueItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, hotkeyModifier))

if (DseFeature.kEnabled) {
addSeparator()
add(
val dseMenu = new JMenu("Design Space Exploration")

dseMenu.add(
ContextMenuUtils.MenuItemFromErrorable(
exceptable {
val directPath = DesignPath.fromIndirectOption(path).exceptNone("not a direct param")
Expand All @@ -114,7 +121,7 @@ class DetailParamPopupMenu(
)
)

add(
dseMenu.add(
ContextMenuUtils.MenuItemNamedFromErrorable(
exceptable {
val (paramDefiningClass, postfix) = paramDefiningClassPostfix.exceptError
Expand All @@ -137,8 +144,8 @@ class DetailParamPopupMenu(
)
)

addSeparator()
add(
dseMenu.addSeparator()
dseMenu.add(
ContextMenuUtils.MenuItemFromErrorable(
exceptable {
val objective = compiler.getParamType(path) match {
Expand All @@ -155,13 +162,10 @@ class DetailParamPopupMenu(
"Add objective"
)
)
}

addSeparator()
val hotkeyModifier = Toolkit.getDefaultToolkit.getMenuShortcutKeyMaskEx
val copyValueItem = add(ContextMenuUtils.MenuItemFromErrorable(copyAction, s"Copy value"))
copyValueItem.setMnemonic(KeyEvent.VK_C)
copyValueItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, hotkeyModifier))
addSeparator()
add(dseMenu)
}
}

// TODO: remove initCompiler, it's counterintuitive
Expand Down
12 changes: 8 additions & 4 deletions src/main/scala/edg_ide/ui/DsePanel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,10 @@ class DsePanel(project: Project) extends JPanel {
val nodePath = new TreePath(treeRoot).pathByAddingChild(treeRoot.searchConfigNode)
configTree.getTree.expandPath(nodePath)
if (scrollToLast) {
val lastNodePath = nodePath.pathByAddingChild(treeRoot.searchConfigNode.children.last)
configTree.scrollRectToVisible(configTree.getTree.getPathBounds(lastNodePath))
treeRoot.searchConfigNode.children.lastOption.foreach { last =>
val lastNodePath = nodePath.pathByAddingChild(last)
configTree.scrollRectToVisible(configTree.getTree.getPathBounds(lastNodePath))
}
}
tabbedPane.setSelectedIndex(kTabConfig)
})
Expand All @@ -403,8 +405,10 @@ class DsePanel(project: Project) extends JPanel {
val nodePath = new TreePath(treeRoot).pathByAddingChild(treeRoot.objectivesNode)
configTree.getTree.expandPath(nodePath)
if (scrollToLast) {
val lastNodePath = nodePath.pathByAddingChild(treeRoot.objectivesNode.children.last)
configTree.scrollRectToVisible(configTree.getTree.getPathBounds(lastNodePath))
treeRoot.objectivesNode.children.lastOption.foreach { last =>
val lastNodePath = nodePath.pathByAddingChild(last)
configTree.scrollRectToVisible(configTree.getTree.getPathBounds(lastNodePath))
}
}
tabbedPane.setSelectedIndex(kTabConfig)
})
Expand Down
67 changes: 50 additions & 17 deletions src/main/scala/edg_ide/ui/tools/DefaultTool.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.intellij.openapi.project.Project
import com.intellij.util.concurrency.AppExecutorUtil
import com.jetbrains.python.psi.search.PyClassInheritorsSearch
import edg.EdgirUtils.SimpleLibraryPath
import edg.compiler.FloatValue
import edg.util.Errorable
import edg.wir.DesignPath
import edg.wir.ProtoUtil.ParamProtoToSeqMap
Expand All @@ -19,7 +20,7 @@ import edgir.schema.schema

import java.awt.event.MouseEvent
import java.util.concurrent.Callable
import javax.swing.{JLabel, JPopupMenu, SwingUtilities}
import javax.swing.{JLabel, JMenu, JPopupMenu, SwingUtilities}
import scala.jdk.CollectionConverters.CollectionHasAsScala

trait NavigationPopupMenu extends JPopupMenu {
Expand Down Expand Up @@ -119,14 +120,14 @@ class DesignBlockPopupMenu(path: DesignPath, interface: ToolInterface)
addGotoDefinitionItem(blockClass, project)

if (DseFeature.kEnabled) {
addSeparator()
val dseMenu = new JMenu("Design Space Exploration")

val rootClass = interface.getDesign.getContents.getSelfClass
val refinementClass = block.prerefineClass.getOrElse(block.getSelfClass)
add(
dseMenu.add(
ContextMenuUtils.MenuItemFromErrorable(
exceptable {
val blockPyClass = DesignAnalysisUtils.pyClassOf(refinementClass, project).get
val blockPyClass = DesignAnalysisUtils.pyClassOf(refinementClass, project).exceptError
() => {
ReadAction
.nonBlocking((() => {
Expand Down Expand Up @@ -162,7 +163,7 @@ class DesignBlockPopupMenu(path: DesignPath, interface: ToolInterface)
f"Search subclasses of ${refinementClass.toSimpleString}"
)
)
add(
dseMenu.add(
ContextMenuUtils.MenuItemFromErrorable(
exceptable {
requireExcept(block.params.toSeqMap.contains("matching_parts"), "block must have matching_parts")
Expand All @@ -176,7 +177,7 @@ class DesignBlockPopupMenu(path: DesignPath, interface: ToolInterface)
)
)

add(
dseMenu.add(
ContextMenuUtils.MenuItem(
() => {
val config = DseService(project).getOrCreateRunConfiguration(rootClass, this)
Expand All @@ -186,7 +187,7 @@ class DesignBlockPopupMenu(path: DesignPath, interface: ToolInterface)
s"Add objective area"
)
)
add(
dseMenu.add(
ContextMenuUtils.MenuItem(
() => {
val config = DseService(project).getOrCreateRunConfiguration(rootClass, this)
Expand All @@ -197,7 +198,7 @@ class DesignBlockPopupMenu(path: DesignPath, interface: ToolInterface)
)
)
if (path == DesignPath()) { // price only supported at top level for now
add(
dseMenu.add(
ContextMenuUtils.MenuItem(
() => {
val config = DseService(project).getOrCreateRunConfiguration(rootClass, this)
Expand All @@ -208,16 +209,21 @@ class DesignBlockPopupMenu(path: DesignPath, interface: ToolInterface)
)
)
}
add(
ContextMenuUtils.MenuItem(
() => {
val config = DseService(project).getOrCreateRunConfiguration(rootClass, this)
config.options.objectives = config.options.objectives ++ Seq(DseObjectiveUnprovenCount(path))
DseService(project).onObjectiveConfigChanged(config, true)
},
"Add unproven count"
if (EdgSettingsState.getInstance().showProvenStatus) {
dseMenu.add(
ContextMenuUtils.MenuItem(
() => {
val config = DseService(project).getOrCreateRunConfiguration(rootClass, this)
config.options.objectives = config.options.objectives ++ Seq(DseObjectiveUnprovenCount(path))
DseService(project).onObjectiveConfigChanged(config, true)
},
"Add unproven count"
)
)
)
}

addSeparator()
add(dseMenu)
}
}

Expand Down Expand Up @@ -289,6 +295,33 @@ class DesignPortPopupMenu(path: DesignPath, interface: ToolInterface)
addGotoDefinitionItem(portClass, project)
addGotoConnectItems(path, interface.getDesign, project)

if (DseFeature.kEnabled) {
val dseMenu = new JMenu("Design Space Exploration")

val params = port match {
case port: elem.Port => port.params
case bundle: elem.Bundle => bundle.params
case _ => Seq() // including arrays, not supported
}
params.toSeqMap.foreach { case (paramName, paramValue) =>
dseMenu.add(ContextMenuUtils.MenuItemFromErrorable(
exceptable {
val objective =
DseObjectiveParameter(path.asIndirect + paramName, edg.compiler.ExprValue.classFromValInit(paramValue))
() => {
val config =
DseService(project).getOrCreateRunConfiguration(interface.getDesign.getContents.getSelfClass, this)
config.options.objectives = config.options.objectives :+ objective
DseService(project).onObjectiveConfigChanged(config, true)
}
},
f"Add objective $paramName"
))
}

addSeparator()
add(dseMenu)
}
}

class DefaultTool(val interface: ToolInterface) extends BaseTool {
Expand Down

0 comments on commit 9e31bf4

Please sign in to comment.