Jump to content


Patterns for twosided classes


1 reply to this topic

#1 Wernaeh

    Senior Member

  • Members
  • PipPipPipPip
  • 368 posts

Posted 31 October 2005 - 04:52 PM

Hi there again !

I've run upon yet another design problem with my multithreaded application that I'd like to get some opinions on.

In my application, I have got several objects that are to be simultaneously used by the logic and the rendering thread.

To minimize the need to synchronize, I decided to have two sepearate copies of each member inside these objects. One is to be used by the logic thread, and one is dedicated to the renderer thread.

Once the renderer finishes a frame, I intend to lock all objects, and copy over all dirty members from the client side representation to the rendererside one.

This should actually work pretty well, but I'm currently pondering how to code this in a clean fashion.

The simplemost version would probably include two nameless structs in my shared object class with differently named members for both sides, and outside of these add some dirty flags. Yet, I don't like the idea of using different variable names from within the rendering and the logics thread.


class TwoSidedObject : public TwoSidedObjectBase

{

     // Logics side

     struct

     {

           CVector vLogicsPosition;

           CQuaternion qLogicsRotation;


           CString sLogicsString;

     };


     // Rendering thread side

     struct

     {

           CVector vRenderPosition;

           CQuaternion qRenderRotation;


           CString sRenderString;

     };


     // Dirty flags

     // Set by the logics thread

     bool bTransformsDirty;

     bool bStringDirty;


public:


    // Different accessor functions for renderer and logics, i.e.

    void SetLogicsPosition(const CVector &logicsposition);

    void SetRenderPosition(const CVector &renderposition);

    /* ... */


    // Single call to synch all dirty members on the renderer side,

    // and reset all dirty flags

    virtual void Synch()

    {

        if (bTransformsDirty)

        {

           vRenderPosition = vLogicsPosition;

           qRenderRotation = qLogicsRotation;


           bTransformsDirty = false;

        }


        if (bStringDirty)

        {

           sRenderString = sLogicsString;

           bStringDirty = false;

        }

    }

}


Another idea would be to add a pointer to each object, allowing to append another object of the same time. Cons here are that its not clear where to store the dirty flags, and I have to create two objects instead of one.
Pro is that I've essentially got exactly the same object twice, not different variables of the same type.

Does anybody know of a design pattern for such a situation ?
Any comments or maybe better ideas for what I want to accomplish ?

Thank you for your help,

Cheers,
- Wernaeh

#2 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 31 October 2005 - 07:43 PM

If the point is to have current data on each render, why not just fetch a thread local copy on each synch? You could still use the dirty flag idea for efficiency.

So, just make a normal class with its attributes and have a function for synchronizing the two instances. Have one instance for the logic thread and one for the render thread. When you need to synch just call your synch function to update the render instance with logic instance changes.

Out of curiousity, do you intend for the logic and rendering to run at different rates?





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users