Getting the controller out of Go’s MVC

Hi there. Long time reader, first time caller… ( =

We’re trying to incorporate Go into an existing event infrastructure
and, at the same time, have a complex controller snuggle up next to the
GoView. The controller receives the user’s input through this event
mechanism and decides what to do about it. Mouse-clicks could be
selects, or the beginnings of drags, etc., etc.

I know overriding the GoView and providing our own DefaultTool is a
good first step, but now I’m beginning to get the sensation that I’m
ice-skating up hill. My initial idea was to subclass most (if not all)
of the GoTools (GoToolContext, GoToolPanning, etc) and replace them in
the MouseDownTools-like properties. These subclassed tools fire an
event into our infrastructure; the controller would catch this event
and, if it’s allowed, programmatically ask the view to carry out the
action.

Is that a good approach, do you think? Anyone done anything similar and have ideas/horror stories?

I’m not looking for events at the granular level of MouseMove and Click… more at the level of ObjectSelected, ObjectMoved.

The intention is that we could fire these events from anywhere in the
program (maybe from an undo manager or a demo reel) and the view would
respond to them.

My first idea was to subscribe to GoView.ObjectGotSelection and all
those… but that sets up an infinite loop where the view does a thing
because of user input -> view fires event to controller ->
controller says, “Yes, this can happen,” and tells view to do the thing
-> view does thing -> view fires event… on and on.

My first impression while reading your message is that instead of overriding methods in all of the tools, you just override the corresponding methods in GoView.
Yes, with any event handling mechanism, you need to be careful not to modify the sender in a way that causes infinite event recursion. Unfortunately I don’t know enough about your situation to provide a meaningful/insightful answer, though.

I would do that but then I can’t trigger the view from the events anymore. What I want is this:

someone fires SelectObject -> controller receives event and selects object in view

Not this:

user selects object in view -> view fires SelectObject event.

The complication is that I also want this:

user selects object in view -> this causes a SelectObject event to
fire -> controller receives event and selects object in view

…because that way the view is agnostic about what caused something to happen and I don’t have to repeat myself.

Does that make sense?

Well, selecting or de-selecting an object can be an idempotent operation–it shouldn’t matter if you try selecting the same object more than once. So the code that you implement to “bind” the selection between the GoView and your controller control should make sure it doesn’t do anything unless it needs to.
But maybe that’s already obvious to you and I am misunderstanding the situation.

I decided to just bite the bullet and have two events: ObjectSelected,
which is fired by the View when an object is selected and a
SelectObject which causes the view to select the object.

Given your track record, Walter, the fault probably lies with my inability to explain myself. ( =

Essentially, I wanted to have a separate, pluggable controller that
could decide what the view should do based on user input… what I’ll
probably end up doing is setting some sort of strategy on my nodes that
will do that (setting Selectable or Deletable at runtime based on the
strategy) instead.

All in all, not a big deal… just frustrating because what I want seems very possible.