RFC Name : Event Handling |
Editor(s): Sarah Killcoyne, Mike Smoot, Allan Kuchinsky |
Date: October 23, 2007 |
Status: open for comment |
<<TableOfContents: execution failed [Argument "maxdepth" must be an integer value, not "[2]"] (see also the log)>>
Proposal
Organize the event handling in Cytoscape to make it clear and consistent for core developers and plugin developers. As part of the rearchitecting of Cytoscape we can create a coherent event system that will simplify core development, and define the events that plugins can have access to as well as trying to run those events in a manner that prevents plugins from tripping over each other. This will also allow us to fairly easily create a command layer for macros and scripting.
Background
The event handling in the current implementation of Cytoscape has become difficult for even core developers to follow. This means that plugins developers who are interested in doing specific event-driven tasks are in a worse position. It is also easy for multiple plugins to perform event-driven operations that are inconsistent with each other, which can result in system errors and unexpected results. This RFC along with the relayering (46) address these issues.
Use Cases
Three main cases (examples, not comprehensive lists):
- Core code event usage
- Views being created in response to network creation
- Views modifying in response to network modification
VizMapper modifying a node’s visual appearance in response to attribute creation/modification
- Plugin event usage
- Adding an action to a popup on a right-click of a node
- Expanding or navigating subnetwork based on a double-click of a node
- Spawning a new viewer based upon a double-click of a node
- Adding nodes and edges to a network by dragging and dropping them from another window, possibly from another application, onto the current network view.
- Creating/applying a particular visual style in response to a network creation
- Changing a node’s visual appearance in response to switching the current visual style.
- Command layer
- macros
- scripting
Implementation Plan
This plan is a sub-part of the relayering process ((46) Cytoscape Relayering). Based on that there are two or three areas for events to be spawned:
- Model - creation/modification/deletion of a model object such as a network or attribute.
- Application - actions (used by menus or macros), mouse events, keyboard shortcut events
- Views - depending on how the view and the application are separated there may be space for events about the creation/modification/deletion of a particular view.
All of these events may be integration points for plugins. At the application and view levels an event queue for plugins would be added. Plugins would register for events and be added to the queue then run in whatever order they were registered. The model layer could also use a queue, but it would be less necessary since these events are not gui related.
Model Events Package Structure
Note, this is the same as proposed in the relayering RFC:
Application/View Events Package Structure
This is greatly dependent on how the Application and View packages are separated. However, Views can have an event structure similar to the model (create/modify/select/destroy events) and the Application events will be the basic swing gui events.
Potential integration points for plugins in these packages include:
- Mouse clicks
- Keyboard actions
- Views created/modified/selected/destroyed
- Popup menus on nodes/edges/attributes
- Drag/drop
- Cut/paste
- others...
Project Management
Project Timeline
The creation of an event handling system would be part of a re-architecting. As part of the relayering of Cytoscape (RFC 46) the event handling can be restructured during the refactor of packages (Milestone 1). This may add some time (est. 8 weeks) to the initial refactor in order to untangle the current event system and add a queue system.
Tasks and Milestones
See the Tasks and Milestones section of RFC 46.
Project Dependencies
Plugin rearchitecting - After Milestone 1 in the relayering
Issues
Mouse event handling has been a particular source of conflict. It would be useful if there were a better way to arbitrate between listeners of a mouse event. In some cases plugin developers attempt to isolate specific actions in their plugins by defining modifiers for mouse events, e.g. the Cytoscape editor uses control-click as a shortcut for adding nodes and/or edges. Modifiers can’t be relied upon for arbitration, though. For example, a plugin that associates an action with the modifiers control- and alt- on mousedown will not be isolated from the editor addition of nodes and edges because the editor only checks for control- modifier, so it will catch control-, alt-click events as well. For the application code to be isolated, the Cytoscape editor would have to check that control- modifier is on and alt-modifier is not on. Some sort of conventional scheme for masking event modifiers might make sense.
Comments
MikeSmoot - 10/24/07
Even though this is going to get complicated, I think we should strive to keep things as simple as possible. I've been thinking of something along the lines of a single CytoscapeEvent class which is typed using an enum, similar to what we're doing with visual properties. CytoscapeEvent would have a simple interface, similar to PropertyChange event. Users would register a listener for a specific event type and then handle as they see fit. We could get creative with this if we want (i.e. each event type could return an object of a specific type) to provide more clearly defined functionality. The separation of different event types into classes is what GINY tried to do initially and (I feel) has contributed to the current confusion because each event has it's own event, it's own listener, and own set of methods. In addition, much of the event handling is channeled through methods in listener interfaces, which makes the interface inflexible and hard to change. By defining one or two interfaces that can be extended and adapted for different needs, we should avoid some of this difficulty.
I like the separation of Application/View events from Model events. My only question is whether we want the Application/View events to include things like mouse click events or menu selection events. It seems to me that if plugins are limited to "adding a panel" to a gui, then that panel would be in charge of its own internal click events and any other interaction with the Application/View would be through defined events. I'm thinking along the lines of how ContextMenus now work. Instead of users listening for right clicks on nodes, they would listen for a CytoscapeEvent with type NodeSelection. Or something along those lines.
ScooterMorris - 10/24/07
I really like the idea of "keeping it simple", but I'm wondering if there might be value in having three event classes: CyViewEvent, CyModelEvent, and CyAppEvent or something like that. There sort of seems to be different levels of granularity between the three which might benefit from some different semantics. App events should be moderately rare, Model events could be pretty common and there might be some benefit of handling these differently (as lists?). I see some efficiencies in batching model events together. View events might fall somewhere in between, but I suspect that they would be closer to the app semantics, so maybe they could be merged.
How to Comment
Edit the page and add your comments under the provided header. By adding your ideas to the Wiki directly, we can more easily organize everyone's ideas, and keep clear records. Be sure to include today's date and your name for each comment. Try to keep your comments as concrete and constructive as possible. For example, if you find a part of the RFC makes no sense, please say so, but don't stop there. Take the extra step and propose alternatives.