Results 1 to 11 of 11

Thread: Best way to design a simulation class?

  1. #1
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Best way to design a simulation class?

    I have a Qt window application that runs a simulation which should be "unknowing" about any details of the application. That is, it shouldn't have any idea whether it's communicating with a Qt application, any other type of application, or if it's just communicating with a wall. The simulation class should be stand-alone from the rest of the application and should be easily plugged in to any other application. However, it should also be able to provide the application with any information it could possibly need – for example information to the user. It should also not block the application from doing other things it may need to do.

    My question is: How is this simulation class best designed? Is there some standard way to do this when writing Qt applications (or any other kind of toolkit application for that matter)?

    I see basically three different ways in which the simulation class can be designed:

    1. The simulation has it's own main loop but is created in a separate thread, and the main thread that still maintains the application keeps querying the simulation for events that has happened, for example things the user should be informed of.
      .
    2. No separate thread is created for the simulation, but the simulation "hijacks" the application until it has finished. When the simulation for some reason needs to communicate back to the application, for example to just let it process its events, a function pointer relevant to the task is called and the application is free to do whatever it needs to do.
      .
    3. The simulation doesn't have a main loop at all, but relies on to continuously be prompted by the application to do more and more loops of the simulation. Between the simulation loops, the application is free to do whatever it wants to do.

    I see benefits and drawbacks with all these different ways.

    Way 1 is quite easy to understand and doesn't need to be designed in any specifically complicated way. On the other hand, the thread the simulation is running in has to compete with another thread for CPU power and will hence run more slowly (right?).

    In way 2, the simulation is provided with function pointers which it calls whenever it wants to communicate back to the application. It now gets a responsibility to call these functions in the right moments. It is also tricky to design these functions in the right way. For example, the function pointers must not point to non-static member functions, since they have a hidden parameter corresponding to the this pointer which the simulation class is not provided with. This can be problematic if the application wishes to write output data in a text browser in the main window, since the text browser is probably a non-static member of the window and must be accessed from a non-static member function, unless the function is provided with some additional information about where to find the text browser object.

    Now, there will probably only be one instance of the main window, so it would be possible to create it as a singleton making it possible to access the non-static members from a static member function, but that should be up to the designer of the application.

    In way 3, the application gets full control of the simulation, it can for example pause the simulation whenever it wants to by just ceasing to call it for a while. The only problem here is that the simulation mustn't do any loop that is longer than, say, a tenth of a second, because that would create noticeable lagging in the application. This makes it very challenging to program longer operations, such as writing a large amount of data to a file, since they have to be divided into small steps which are then executed one at a time from a public function.

    Alternatively, this method can be combined with way 2 in order to not have to divide all operations into small steps, but that kind of removes the purpose of dividing all other long operations into small steps to begin with since we're back struggling with the functions and the function pointers.


    I would be grateful for any comments on these ideas. Are they right or wrong? How would you have done this?
    Last edited by Yes; 26th November 2011 at 19:25.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Best way to design a simulation class?

    When I have been faced with a similar issue, I have generally chosen the 2nd architecture. We have a large C++ library of methods for scientific computations, some of which can take time and need to communicate status back to the controller so it can post a progress bar, allow for aborting the operation, etc. This library is used in Qt apps, MFC apps, and headless apps on embedded linux systems so it is vanilla C++.

    In most cases, the computation (simulation, in your case) has a set of well-defined callbacks for which the controller can supply pointers to callback functions. At appropriate points in the simulation loop, the simulation will invoke the callback if a pointer has been supplied.

    To interface this to the Qt world, I construct a Facade which maps the callbacks into Qt signals and translates C++ types into Qt types (e.g. std::wstring -> QString) if desired. Translation gives the option of using simulation-specific objects to talk to the facade class, but these can be hidden behind the "facade" (hence the name of the design pattern). The facade class could be a GUI, or simply be a QObject for use by other Qt objects. This gives some ability to disconnect the Qt world from the simulation world - the Qt class could have a "stop" button that simply sets a flag in the facade class. Next time the simulation asks, "OK to keep going?", the facade supplies the value of the flag.

    Note that in the main application, unless you put the simulation into its own thread, you will still have to service the event loop (i.e. call processEvents()) in order to keep the GUI "live". The facade class can do this for you by calling processEvents() in each callback function, but unless the callback is invoked frequently, the GUI will be doggy.

  3. #3
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Best way to design a simulation class?

    That's the way I have taken until now. Except I have no facade for my simulation class, but just a function pointer directly in the simulation class that is called whenever the application should process its events.

    It was when I had to print output from the simulation into a text browser I have in my main window that I ran into problems. Since the text browser is a member of the window class, I can't access it from any function I can access from the simulation class.

    I guess a facade will do the job. If I have a facade class for the simulation class, I can derive another class from it in my Qt application, which in turn contains a pointer to the window object. In the simulation class, I store a pointer to a facade object in which I call a virtual function whenever I want to provide the application with output. If the derived facade wants to write to the text browser, it will simply use the window pointer and access the text browser that way. Nice.

    Thank you for the help. A facade it will be!

    P.S. I like vanilla

    Edit: Forget what I said about a virtual function, I just realized that it can't make up for the hidden argument corresponding to the this pointer that has to be provided if it's supposed to be able to access non-static members...

    Edit 2: Never mind, I realized it's not the virtual function that is supposed to make up for the this pointer, but the pointer to the facade object that is stored in the simulation class ... a brain fart. :P
    Last edited by Yes; 26th November 2011 at 21:35.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Best way to design a simulation class?

    In the simulation class, I store a pointer to a facade object in which I call a virtual function whenever I want to provide the application with output.
    Actually, I would try to make it more generic than this. The simulation class doesn't really need to know about external classes; it simply needs callback function pointers. These could all belong to the same facade class, could be multiple classes, could be standalone C++ functions, could be function objects (each of which implements a single callback method). The simulation shouldn't know or care, if you want to make things as decoupled as possible.

    But if you have control over both ends of the code (simulation and controller), you can make whatever level of dependence you want. If you are interfacing to a third-party library where you have no ability to change the simulation code, then you are forced to decouple in one of the ways above.

  5. #5
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Best way to design a simulation class?

    Okay, let's assume that we are using a third party library and can only provide it with a function pointer for each callback. What would such a callback function look like if it needs to access an object that can't be accessed globally?

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Best way to design a simulation class?

    What would such a callback function look like if it needs to access an object that can't be accessed globally?
    Once upon a time I solved this problem, but I can't remember at the moment. Something to do with a function object class that stored a pointer to another class, but the mapping from a static method (the callback) to a non-static member escapes me.

  7. #7
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Best way to design a simulation class?

    And you didn't use a singleton?

  8. #8
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Best way to design a simulation class?

    I took a look at an SDL function (SDL_AddTimer) that has to be provided with a callback function, and apparently it takes an extra parameter except from the function pointer, and that parameter is a void pointer. This extra argument is probably intended to be used (if necessary) as a pointer to an object in order to make it possible for the callback function work with more than just static member variables. You can at least bake in as much information as you possibly want into this pointer since it can point to any kind of object.

    Now, SDL is written in C, and I don't know if there is any better way to do this in if you use C++, but at least this is one way in which it can be done.

    Edit: Apparently, this way isn't typesafe, which is explained pretty nicely here. That is why the concept of a slot is introduced, which is already a part of Qt. I started to wonder if there is any way to use Qt to make a slot in some way, which I can then pass to my simulation class in order to make the programming typesafe?
    Last edited by Yes; 27th November 2011 at 01:35.

  9. #9
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Best way to design a simulation class?

    If you are going down a non-Qt callback route then you should look at the Boost bind library. Call free functions, static members, member functions, flexible argument handling etc.

  10. #10
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Best way to design a simulation class?

    I'm sure Boost bind is great; I have previously been looking at a few other Boost classes and even worked with one of them, and they all seem to be really useful. It's just that – if Boost is used in a project, it becomes yet another large library that you need to have installed on your every computer you want to compile the project on... It seems unnecessarily large if you are only going to use one of its classes in your project, why I would rather use some other signal/slot library instead, like sigslot or libsigc++ (although I have never used these two in particular before), that doesn't take up so much space on you hard disc. Or is there some way to download only the header and source files needed for Boost bind and use them in your project?

  11. #11
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Best way to design a simulation class?

    Boost bind is header only. No extra library needs to be shipped with your program. If you want to avoid Boost then look at how much of TR1 is implemented by your compiler: std::tr1:: function and bind.

Similar Threads

  1. alt enter simulation in qstring
    By Dilshad in forum Newbie
    Replies: 6
    Last Post: 29th December 2010, 06:59
  2. Multilotek - simulation of lottery game
    By Fazer in forum Qt-based Software
    Replies: 0
    Last Post: 8th September 2009, 15:19
  3. physics simulation
    By scrasun in forum General Programming
    Replies: 6
    Last Post: 11th June 2009, 03:19
  4. Replies: 1
    Last Post: 16th April 2008, 00:15
  5. QTimer or recursive calls for simulation?
    By Morea in forum Qt Programming
    Replies: 3
    Last Post: 12th May 2006, 01:19

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.