tags:

views:

50

answers:

3

I am writing a quasi-MVC-style application with a GUI, a controller and a backend that deals with all calculations and data accessing and stuff. This happened rather accidentally and I have no experience whatsoever with MVC, but want to understand it more thoroughly.

So, the model has to do some lengthy calculations. How would this be handled in a traditional MVC-approach? My approach is to spawn the long calculation in its own thread (to not block the GUI) and have the controller query it periodically about its current status to update the GUI. In another case, the model is playing and recording some audio. Does this belong in the model? Should the model actively tell the controller what it is doing or should it remain passive and be queried periodically?

Thank you for your comments!

+3  A: 

To my mind, polling should always be a solution of last resort. Why not have your model emit progress events and subscribe to them?

spender
I do not want to have too many dependencies to Qt in the model, as it might have to be ported to a DSP later on. Besides, I tried this and it got very complex very fast and soon exceeded my brains capacity to grasp all the interactions. Still, this is a valid answer to my question, so thank you ;-)
BastiBechtold
+1  A: 

My guess at what to do here (ported to a DSP? really? I suppose you mean the long-running process only) is that you should have the model be the data AND meta-data. Have one thread be a controller that is long-running, it updates the data and meta-data. Your gui threads are other controllers which when needed to construct a view, will look at the data and meta-data and wrangle this for the view. The meta-data could be the current state of the long-running transformation or process, or it could include the location of the play-head and record-head.

dlamblin
In fact, the whole thing should be running on the DSP. However, I won't need any cross-platform compatibility, arbitrary file-IO or abstracted audio hardware interface on the DSP, so many things will get significantly simpler.
BastiBechtold
+1  A: 

If you consider pure push oriented MVC approach, the information route should be :

C->M->V

between each component, you push a message that has a different semantic field:

typically in a GUI app:

  1. GUI event is captured and calls a Controller owned callback
  2. Controller transforms GUI event oriented semantics into Model Command with parameters
  3. Model command is performed asking related views to: 1) update() or 2) update(data)

using 1) The View has to pull the model for info (i don't recommend this if avoidable), this creates a tight-coupling on the view->model link

using 2) the view update method has a data parameter that is sufficient for the view to perform its update.

For me, the best solution is to:

Have your model instantiate the calculation thread based on controller event/message and the calculation thread notifies the model of its progress.indeed,The model may be interessed to do some processing depending on progress/state of your calculation thread.

When the model wants to notify its views (that may not be the same views depending on progress or other calculation state dependency),notify interested view(s) of whatever model info you need to send to views.

If your view(s) need to do some GUI rendering , depending on your GUI toolkit thread safety you may need to use delayed rendering method in your view update.

One convenient communication bus between model & view can be Observable/Observer but you can also perform direct calls (which creates tight-coupling between model->view link)

dweeves
could you comment on the Observable/Observer-thing you mentioned? I am sorry, but I am a complete newbie to this kind of thinking.
BastiBechtold
Rather than explicitely reference View instances in your model. you can use the Observable/Observer pattern . (see http://en.wikipedia.org/wiki/Observer_pattern) . Make the view inherit Observer class (or have an internal member declared as Observer with a public method getObserver() in order for the model to access it). When the view is added to the model, the model adds it (or the result of view's getObserver()) to its observer list.when model wants to notify its views, it has only to call notifyObservers(data) to transmit data to views. Not knowing anything on how view will process data
dweeves