scijava-common
scijava-common copied to clipboard
Support an easy way for disabling specific post/pre-processors for Commands
@ctrueden on ImageJ-devel:
I am guessing what you want is all pre- and post-processing to occur except for the final display of outputs? I agree it would be nice to have a super-easy way to do this, though I'm not totally sure what the API would look like for it.
Currently, there is no fine-grained, easy-to-use possibility to tweak which pre/post-processors are executed for a Command
. The work-around is to use the ModuleService
and provide a complete list or processors when executing the run
method.
we probably would want to:
- Create a
ProcessingService
to encapsulate pre/post processing actions and control state, moving related logic out of theModuleService
- Add
enable(Class)
anddisable(Class)
methods to this service to control a blacklist - Add built-in convenience methods for SciJava pre and post processors
I like the idea of a ProcessingService
, and the convenience methods for all built-in processors. This would be a type-safe convenience layer similar to the ImageJ
gateway, and built-in methods of OpEnvironment
for ImageJ Ops.
However, I don't think we need to add global pre/post-processing toggles—at least not yet. It wouldn't help with the intended use case, and it could result in potentially mystifying behavior when one consumer changes the global behavior for its own needs, which then infects the rest of the system. A way to avoid that would be to create something like OpEnvironment
but for modules in general (an "execution environment" for them), but it would complicate the system. I'd like to wait until it seems necessary before going that route.
It wouldn't help with the intended use case
I feel like I missed something.. why wouldn't it help?
In the shorter term we could add processing toggle keywords to the ScriptEditor
. They could be harvested like @Parameters
right now. When the script's module is being built it gets the list of all preprocessors and postprocessors, then removes from this list based on what keywords it finds, and passes the final list to the ModuleService.run
method. For example, add #NODISPLAY
to your script and the display postprocessor won't run on it.
I feel like I missed something.. why wouldn't it help?
IIUC, the goal is to suppress the display of outputs for a specific module execution, not globally for the context. So we wouldn't want global toggles at the context level. But we could have local toggles on some local object which you spawn, use then trash when done—an execution environment context. This is one of the use cases of OpEnvironment
.
In the shorter term we could add processing toggle keywords to the
ScriptEditor
.
I'd prefer a way to invoke ModuleService.run
in a customizable way with succinct syntax. A module execution environment might actually be best. Otherwise, the proliferation of run
signatures would probably be too much.
IIUC, the goal is to suppress the display of outputs for a specific module execution, not globally for the context.
That's true, @ctrueden.
I like the idea of a ProcessingService [...]
That would make most sense to me. A somewhat connected question is, how custom pre/post-processors can be announced and utilized by other Module
s.
IIUC, the goal is to suppress the display of outputs for a specific module execution, not globally for the context.
For the sake of clarity and complete discussion of options here: at the moment the list of pre/post-processors are effectively global state. Using the ProcessingService
as I proposed would require you to:
- Alter global state
- Run your modules/commands/scripts of interest
- Restore global state
So I think it would allow the problem to be solved, but is not ideal due to being error prone and not threadsafe, at the least... although if we are interested in pursuing controls through a ProcessingService
we could discuss how to mitigate the drawbacks, e.g. through locks or ThreadLocal
environments..
I like the idea of a ProcessingService [...]
That would make most sense to me
Actually, a ProcessingService
may only be useful if we maintain pre/post-processors as global state - and I think we don't want to do that. Using a ProcessorEnvironment
as @ctrueden suggests would build execution state each time a module is executed. In this case the workflow would be:
- Build a
ProcessorEnvironment
representing your desired state (i.e. no display postprocessor) - Pass the
ProcessorEnvironment
as a parameter toModuleService.run
Then you could reuse an instance of a ProcessorEnvironment
, and the ModuleService
would have an immutable default environment consisting of all the pre/post-processor plugins which it would fall back on if no environment was explicitly provided.
We can then add convenience methods to the ProcessorEnvironment
for enabling/disabling core processors. We would also need to propagate a run signature accepting a ProcessorEnvironment
to the CommandService
.
This would still be incomplete, as we would also need to consider places where Modules are created implicitly and add some custom solution (i.e. as I described above for scripts).
how custom pre/post-processors can be announced and utilized by other Modules.
All plugins of a given type can be queried at runtime using the PluginService.
ImageJ-Ops introduces some more robust options in that you can get usage for all Ops of a particular type by name, without having to reference an actual Java class... so that may be worth generalizing.
I think maybe the ModuleService
would be a good place to ask about what processors are available and how to enable/disable them..?
This issue has been mentioned on Image.sc Forum. There might be relevant details there:
https://forum.image.sc/t/a-way-to-disable-macro-recording-selectwindow-title-for-output-images/37235/4