ControlSystemStudio / cs-studio

Control System Studio is an Eclipse-based collections of tools to monitor and operate large scale control systems, such as the ones in the accelerator community.
https://controlsystemstudio.org/
Eclipse Public License 1.0
111 stars 96 forks source link

Template/Instance widget is not scriptable #2724

Closed exzombie closed 8 months ago

exzombie commented 9 months ago

I love the idea behind this widget, it can save a ton of fiddling when laying out embedded displays. However, all my attempts to increase the number of instances shown by the TemplateInstanceWidget from a Python script were met with errors. The simplest way to reproduce this is to add the following script to this widget:

for _ in range(10):
    widget.getProperty('instances').addElement()

When running the display, there are, in fact, additional instances of the embedded display created. And they appear to work. However, the console contains errors, and attempting to close the display doesn't work too well, resulting in more errors and requiring multiple attempts before the display actually closes.

These are the kinds of errors occurring when the script runs:

2023-10-12 13:27:42 SEVERE [org.csstudio.display.builder.model] Unknown listener org.csstudio.display.builder.representation.ToolkitRepresentation$$Lambda$849/0x00000008010a9cf8@7145f5c1
java.lang.Exception: Unknown listener
        at org.csstudio.display.builder.model.properties.PropertyChangeHandler.removePropertyListener(PropertyChangeHandler.java:119)
        at org.csstudio.display.builder.representation.ToolkitRepresentation.disposeWidget(ToolkitRepresentation.java:425)
        at org.csstudio.display.builder.representation.ToolkitRepresentation.disposeChildren(ToolkitRepresentation.java:410)
        at org.csstudio.display.builder.representation.ToolkitRepresentation.disposeRepresentation(ToolkitRepresentation.java:394)
        at org.csstudio.display.builder.representation.javafx.JFXRepresentation.disposeRepresentation(JFXRepresentation.java:663)
        at org.csstudio.display.builder.representation.javafx.JFXRepresentation.disposeRepresentation(JFXRepresentation.java:115)
        at org.csstudio.display.builder.representation.javafx.widgets.TemplateInstanceRepresentation.lambda$instantiateTemplateAndRepresent$1(TemplateInstanceRepresentation.java:399)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:316)
        at java.base/java.lang.Thread.run(Thread.java:833)
2023-10-12 13:27:42 WARNING [org.csstudio.display.builder.representation] Failed to instantiate template one row.bob
java.util.concurrent.ExecutionException: java.lang.NullPointerException
        at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:205)
        at org.csstudio.display.builder.representation.EmbeddedDisplayRepresentationUtil.checkCompletion(EmbeddedDisplayRepresentationUtil.java:238)
        at org.csstudio.display.builder.representation.javafx.widgets.TemplateInstanceRepresentation.instantiateTemplateAndRepresent(TemplateInstanceRepresentation.java:402)
        at org.csstudio.display.builder.representation.javafx.widgets.TemplateInstanceRepresentation.lambda$scheduleInstanceUpdate$0(TemplateInstanceRepresentation.java:251)
        at org.phoebus.framework.jobs.Job.execute(Job.java:50)
        at org.phoebus.framework.jobs.JobManager.execute(JobManager.java:54)
        at org.phoebus.framework.jobs.JobManager.lambda$schedule$0(JobManager.java:45)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NullPointerException
        at java.base/java.util.Objects.requireNonNull(Objects.java:208)
        at org.csstudio.display.builder.representation.ToolkitRepresentation.disposeRepresentation(ToolkitRepresentation.java:400)
        at org.csstudio.display.builder.representation.javafx.JFXRepresentation.disposeRepresentation(JFXRepresentation.java:663)
        at org.csstudio.display.builder.representation.javafx.JFXRepresentation.disposeRepresentation(JFXRepresentation.java:115)
        at org.csstudio.display.builder.representation.javafx.widgets.TemplateInstanceRepresentation.lambda$instantiateTemplateAndRepresent$1(TemplateInstanceRepresentation.java:399)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:316)
        ... 1 more

Attempting to close the display:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
        at java.base/java.util.Objects.requireNonNull(Objects.java:208)
        at org.csstudio.display.builder.representation.ToolkitRepresentation.disposeRepresentation(ToolkitRepresentation.java:400)
        at org.csstudio.display.builder.representation.javafx.JFXRepresentation.disposeRepresentation(JFXRepresentation.java:663)
        at org.csstudio.display.builder.representation.javafx.JFXRepresentation.disposeRepresentation(JFXRepresentation.java:115)
        at org.csstudio.display.builder.representation.javafx.widgets.TemplateInstanceRepresentation.dispose(TemplateInstanceRepresentation.java:488)
        at org.csstudio.display.builder.representation.WidgetRepresentation.destroy(WidgetRepresentation.java:88)
        at org.csstudio.display.builder.representation.ToolkitRepresentation.disposeWidget(ToolkitRepresentation.java:435)
        at org.csstudio.display.builder.representation.ToolkitRepresentation.disposeChildren(ToolkitRepresentation.java:410)
        at org.csstudio.display.builder.representation.ToolkitRepresentation.disposeRepresentation(ToolkitRepresentation.java:394)
        at org.csstudio.display.builder.representation.javafx.JFXRepresentation.disposeRepresentation(JFXRepresentation.java:663)
        at org.csstudio.display.builder.representation.javafx.JFXRepresentation.disposeRepresentation(JFXRepresentation.java:115)
        at org.csstudio.display.builder.runtime.ActionUtil.handleClose(ActionUtil.java:205)
        at org.csstudio.display.builder.runtime.app.DisplayRuntimeInstance.disposeModel(DisplayRuntimeInstance.java:452)
        at org.csstudio.display.builder.runtime.app.DisplayRuntimeInstance.onClosed(DisplayRuntimeInstance.java:505)
        at org.phoebus.ui.docking.DockItem.handleClosed(DockItem.java:685)
        at org.phoebus.ui.docking.DockItemWithInput.handleClosed(DockItemWithInput.java:450)
        at org.phoebus.ui.docking.DockItem.close(DockItem.java:720)
        at org.phoebus.ui.docking.DockItem.lambda$addCloseCheck$19(DockItem.java:607)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:316)
        at java.base/java.lang.Thread.run(Thread.java:833)

2023-10-12 13:29:28 WARNING [org.csstudio.display.builder.representation] Display representation still contains items on shutdown: [Pane@3f1d17a9]
kasemir commented 9 months ago

Might be more appropriate to file this under https://github.com/ControlSystemStudio/phoebus/issues, because the Eclipse/BOY display tool doesn't have a template/instance widget.

The template/instance widget doesn't support runtime modifications. Its strength is duplicating one template for a fixed number of instances known at startup. You could try to implement support for runtime changes, but not sure how involved that would be.

If you want to use a script to create displays, you have two options:

Write some plain python (or ruby, perl, shell, lua, ...) script that creates the display XML files outside of the runtime. You can simply "print" what you need based on some example displays that contain the essence of what you're looking for, or use some library like https://github.com/als-epics/phoebusgen. This is convenient for creating a vast number of displays based on for example some list of control system devices that you have for your system. The result is plain display files that open & run in no time.

If you think you need to dynamically create displays because your accelerator happens to add/remove components all the time (really?), then you can look at the example scripts in https://github.com/ControlSystemStudio/phoebus/tree/master/app/display/model/src/main/resources/examples/template_and_script But since you'll then be writing a display script, the usual caveats apply: If you need to ask how to implement a script, you better reconsider. If you implement it, you'll have to maintain it. Nobody guarantees that your script will function in the next update of the display tool. It certainly won't work in the web runtime, https://github.com/ornl-epics/dbwr/ Or check the list of new display tools at the ongoing ICALEPCS 2023 GUI workshop. Very likely, none of them will support your script.

exzombie commented 8 months ago

Might be more appropriate to file this under https://github.com/ControlSystemStudio/phoebus/issues, because the Eclipse/BOY display tool doesn't have a template/instance widget.

Ugh, sorry, didn't realize I'm in the wrong repo. Will open an issue there.