Following a discussion on the maintainers mailing list that was partly about improving the implementation of the event_manager class in Octave, I’ve been thinking about how to allow a single message (for example, “directory_changed”) to be associated with more than one action and also how to simplify subscribing to events.
One solution would be to use Qt signals and slots directly in Octave, but I would prefer to avoid that because I’d like to allow non-Qt projects to also subscribe to messages emitted by the Octave interpreter.
Another solution I came up with uses templates and an enumerated list of message IDs. A simple prototype is here: message-queue.cc (5.7 KB) . This approach has some advantages of type safety (the type signature of action functions must match the type declared for the message ID) but requires some work to add a new message (you must add a new global enum value and declare the type signature used by the associated action function).
Another possibility is to have each action function declared as one of
void FCN (const octave_value_list& args); void FCN (interpreter& interp, const octave_value_list& args);
similar to the DEFUN or DEFMETHOD functions in the interpreter, except that these action function would not return values. If all action functions are required to be of a pre-defined set of types, then we can dynamically add messages instead of having a fixed set of message IDs, but we give up compile time checking to ensure that an action function matches the type signature of the corresponding message.
Edit: What I mean by “but we give up compile time checking to ensure that an action function matches the type signature of the corresponding message” isn’t that we can’t check that the matches one of the signatures void(const octave_value_list&) or void(interpreter&, const octave_value_list&) but that when we emit a message, we can’t check at compile time that the number and types of the variables in the octave_value_list argument match what the action function expects.
A prototype implementation of this idea is here: ovl-message-queue.cc (4.9 KB) .
Thoughts? At the moment I’m leaning toward the latter solution because of the additional flexibility it offers even though it may require storing C++ values in octave_value_list objects for the calls to the action functions and then extracting values inside the action functions. At least this is a pattern that anyone who writes Octave extensions should be familiar with.