I like Wilhelm's suggestion to use the discussion around the plugin
mechanism as a way of starting brainstorming. While it is not entirely clear to me whether 'core plugins' and 'user plugins' (in the sense of the 'core' vs 'plugins' discussion earlier in this thread) can/should be submitted to the same structures and interfaces, discussing the plugin mechanism is a good way of laying down ideas on how we want the different parts of IJX to interact.
> * First it should be clear what the role of a plugin is. [..]
> Currently they serve multiple roles and this creates an uncontrolled
> mixture.
Good point, but it would be nice if plugins could 'naturally' be able of
other usage that the primary intended one. If we distinguish different
roles too early, and one has to e.g. revisit the source to make an
interactive plugin work non-interactively, we might loose some flexibility.
> * I wish plugins would be able to handle other arguments but images -
> for example graph structures, trees, etc. Also on multiple images (not
> necessarily stacks).
>
> * I always found referencing "the current" image (as common in a
> regular Plugin) rather brutal. I am not sure this is safe at all,
> considering that the user may click on another image in the meantime.
>
> * Return values: I often produce results in a plugin that might be
> passed on to another plugin. Currently there is no mechanism to return
> anything - statistics are a typical example. I usually store results
> in some repository (hash table) or attach to the image, which is
> unsatisfactory.
These points seem important, and mean that a simple
ImageProvider/ImageConsumer type interface is not sufficient. It would
indeed be nice if a plugin could expose the results in a flexible
manner, and likewise take input of various types. Is there any nice way
to do this ? (I am not a professional programmer in any way, and
unfamiliar with many modern programming concepts, but I suspect some ideas might already be out there)
Just to jot down a quick concrete example (apologize in advance if this is perceived as too detailed at this time, but I feel sketching things tentatively might help expose bad ideas), what about using something like essentially a hashtable with appropriate access methods as a container to tansmit input and output data ? E.g. declare the central run() method of Plugins as
run(DataContainer input, DataContainer output)
The DataContainer would be an interface allowing to get objects e.g. by a key or so:
interface DataContainer() {
/** Register a reference to the image under the given key. The image
object itself is not copied. If a reference to an object already
exists for this key it is overwritten.*/
putImage(String key, ImageData image);
/** Return Image by key. Returns null if container has no image object
or key is unknown. */
ImageData getImageByKey(String key);
... // similar methods for other basic object types,
// plus possibly generic getObjectByKey(...)
deleteRef(String key);// call this to explicitly free reference so that object may become eligible for garbage collection
deleteAll();
}
One could specify from the start a number of base objects (images,
tables, trees, hash-tables) that can be handed down this way, but not
restricting to these. The global contract would require that plugins document the keys and returned objects in the API. In the case of simple plugins (PlugInFilter) a keyword could be reserved for the image/stack to be processed (say "active", to please Wilhelm ;-)), so that these plugins can function almost as before with:
run(DataContainer input, DataContainer output) {
imp = input.getImageByKey("active");
// do the stuff to imp as before
output.putImage("active", imp); // assumes image was processed
in-place, otherwise register newimp
}
This kind of plugin could then be re-used and chained easily:
plugin1.setup(blabla)
tmpdata = new DataContainerImplementation();
plugin1.run(input, tmpdata);
plugin2.setup(blablo)
plugin2.run(tmpdata, output);
Then again, I am neither a professional, nor particularly experienced programmer, so this is maybe a poor design choice.
I agree to all other points made by Wilhelm, and in particular also vote
that the ImagePlus/ImageProcessor distinction is very confusing. Some
clean-up needed here.
> * Help support (as mentioned).
I just read that it is possible since Java 1.6 to launch the system
default browser on an arbitrary URL in a portable way (via
java.awt.Desktop.browse()). This could maybe be used to point to the
javadoc-generated API documentation, which would greatly encourage
documentation of plugins in the canonical way, and require little infrastructure in IJX.
Not sure my contributions so far are up to level with the others', but
would really like to see this project evolve.
--
Adrian
--
Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger01