Mediator Pattern

Started by
1 comment, last by exOfde 10 years, 5 months ago

Hello,

few days ago i start to try to implement/learn in general the mediator pattern. Now I am at a point where i need help!

The problem is my Compiler (G++) say i would use something that not in that form exist. But that's wrong. To be more specific:

I have 3 classes:

  • Mediator ( as singleton implemented + templated )
  • ColleagueEvent ( templated )
  • ColleagueInterface ( Interface, obviously )

If i try now to create an instance of ColleagueEvent<TestColleague>. The compiler means then that Mediator<TestColleague> would be first incomplete and second used in nested name specifier. Okay, i thought include the specific header and the problem

should be resolved... pustekuchen

Suddenly the compiler means the class mediator would not has a static member >instance< and from here my problem starts. I cannot understand why the compiler don't see that >instance< is static. So that you can me follow a bit better here the code i use:

Perhaps i cannot see the wood for the trees but it would be nice if you suggest ideas why that so is or how could try to fix it.

The ColleagueEvent class:


#include "ColleagueInterface.h"
#include "Mediator.h"

namespace utilities
{
    template<typename EventArgType>
    class Mediator;
    
    template<typename EventArgType>
    class ColleagueEvent
    {
        protected:
        typedef void (*ColleagueEventHandler)(interfaces::ColleagueInterface *source,EventArgType eventArg, interfaces::ColleagueInterface* context);
        
        private:
            
        interfaces::ColleagueInterface * eventContext; //Context colleague who fires the event
        ColleagueEventHandler handlerProc; //Event handler function pointer
        public:
        /*
         * Constructor receives the event source context and the EventHandler
         * function pointer. Also register this object with the Mediator<> -
         * to join the community.
         */
        ColleagueEvent(interfaces::ColleagueInterface *source, ColleagueEventHandler eventProc) :
            eventContext(source), handlerProc(eventProc)
        {
            //Register with mediator
            Mediator<EventArgType>::GetInstance().RegisterColleague(this);
        }
        /*
         * Destructor - unregister the object from community.
         */
        virtual ~ColleagueEvent()
        {
            Mediator<EventArgType>::GetInstance().UnregisterColleague(this);
        }
        /*
         * FireEvent - Inform the Mediator<> that the event object is triggered.
         * The Mediator<> then will broadcast this to other ColleagueEvents -
         * in this community.
         */
        void FireEvent(EventArgType eventArg)
        {
            Mediator<EventArgType>::GetInstance().FireEvent(this, eventArg);
        }
        friend class Mediator<EventArgType> ;
    };
}

The Mediator


namespace utilities
{
    template<typename EventArgType>
    class ColleagueEvent;
    
    template<typename EventArgType>
    class Mediator
    {
        typedef std::vector<ColleagueEvent<EventArgType>* > EventList;
    private:
        EventList                       m_colleagues;
        
        static Mediator<EventArgType>*  m_instance;
        static Mediator<EventArgType>&  GetInstance()
        {
            if(!m_instance)
            {
                m_instance = new Mediator();
            }
            return *m_instance;
        }
        
        void RegisterColleague(ColleagueEvent<EventArgType>* colEvent)
        {
            m_colleagues.push_back(colEvent);
        }
        
        void FireEvent(ColleagueEvent<EventArgType>* source, EventArgType eventArg)
        {
            for(unsigned i = 0; i < m_colleagues.size(); i++)
            {
                if(m_colleagues[i] != source)
                {
                    m_colleagues[i]->handlerProc(source->eventContext,eventArg,m_colleagues[i]->eventContext);
                }
            }
        }
        
        void UnregisterColleague(ColleagueEvent<EventArgType>* colEvent)
        {
            typename EventList::iterator itr = std::find(m_colleagues.begin(),m_colleagues.end(), colEvent);
            if (itr != m_colleagues.end())
            {
                m_colleagues.erase(itr);
            }
        }
        
        friend class ColleagueEvent<EventArgType> ;
    protected:
    public:
    };
    
    //Define the static member of Mediator<> class
    template<typename EventArgType>
    Mediator<EventArgType>* Mediator<EventArgType>::instance = 0;
}
Advertisement

What is the error?

You don't want to define the static member in a header file that would be an error if the file is included in multiple translation units, put it in a cpp file?

You could also make instance a static variable in your GetInstance() function which is normally how singletons are defined (i.e. move it from static class member to static inside the function).

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

jupp that was my mistake... really sometimes you can't see the wood for the trees

thank you a lot :D

This topic is closed to new replies.

Advertisement