Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Диспетчер сообщений


Автор: bel_nikita 12.11.2004, 19:51
Может у кого есть готовый диспетчер сообщений с базовым классом? Динамический. smile
Т.е. в некоторый момент времени нужно создавать до 1500 объектов и все должны обмениваться между собой сообщениями. Писать самому не то, что лень, а просто не хватит сил отладить его. Т.к. надо придумывать алгоритмы генерации уникальных ID объектов, критические секции и ....

З.Ы.: я то написал, но никак не могу толково его отладить...

Автор: Mad 13.11.2004, 13:34
bel_nikita
Каких именно сообщений ?

Автор: bel_nikita 13.11.2004, 14:45
Mad
Своих smile Какие придумаю. Дело такое, есть некая работающая система из объектов. Допустим один объект принимает вызовы от абонентов, т.е. детектирует DTMF последовательность. Второй генерирует. Третий работает с сетевой картой, т.е. с таким же софтом на другой машине, четвертый работает по RS, пятый .... и т.д. Типа RTOS такой. И вот, эти все объекты должны обмениваться информацией и сообщениями между собой.
Например, первый объект детектировал, что абонент поднял трубку и начал набирать номер, он должен дать сигнал другому объекту, который отвечает за детекцию номера. Этот второй, когда детектировал номер, должен разослать его по другим объектам и дать комманду объекту, отвечаещему, за сетевуху, чтобы он отослал эти данные(номер и время) на сервер и т.д....


Типа Boost/signal, Chain of Responsibility. Но что-то не пойму как-там все завязано....

Автор: Mad 13.11.2004, 15:10
bel_nikita
Проблемма, по моему мнению, заключается в том, что все эти сообщения надо обрабатывать не скопом, а по видам

У меня примерно такаяже задача недавно была.
Решил так:
Каждый вид сообщения выделил в отдельный диспетчер. Тогда отладка стала не такой гиморной.

Например:
Сообщение о поднятии трубки. Его, допустим, надо доставить тока обьектам детектирования номера. Вот и делаеш отдельный диспетчер, который понимает тока это сообщение. Каждый обьект слежения за положением трубки smile при создании регится в нем как источник сообщения, а каждый обьект детектирования номера регится как приемник. Такой диспетчер не представляет ни каких сложностей ни в реализации, ни в отладке.
И так далее, скорей всего часть сообщений вообще вывалиться (получится что у них всегда тока один источник и тока один приемник, зачем же тогда диспетчер smile ).

Автор: bel_nikita 13.11.2004, 18:16
Mad
не совсем то. а если у меня 1000 типов собщений? тогда получается создавать тысячи диспетчеров?
Диспетчер мне кажется должен быть один для всех. Мне надо каркас, чтобы в любой момент я мог добавить или удалить класс при проектировании софта.

А можно пример какой-нить smile А то не совсем правильно мысль понял. Ну, если не сложно smile

З.Ы.: Я уже написал, что-то подобное и похожее на диспетчер, но вот еще хочу класс сообщения сделать более менее нормальный, чтобы можно было данные прикреплять/откреплять при посылке и получении
Как-нить выложу на критику и поиск недочетов smile

Автор: Mad 13.11.2004, 18:56
bel_nikita
Это конечно не готовый код, а только чтоб проэлюстрировать мысль.

Код

class IMessage // базовый класс для сообщения
{
}

class ISender // базовый класс для источника сообщений
{
   virtual void AddDispatcher(CDispather *pDisp);
}

class IReceiver
{
    virtual BOOL ProcessMessage(IMessage *pMessage);
}

class CDispather
{
    virtual BOOL IsMessageTypeSuplied(DWORD dwMessageType);

    virtual BOOL RegisterSender(ISender *pSender);
    virtual BOOL ConnectReceiver(IPeceiver *pReceiver);

    virtual BOOL ProcessMessage(IMessage *pMessage);
}

CDispather *g_pDispPool[MAX_MESSAGE_TYPE];



теперь пример реализации

Код

#define MSG_DIALNUMBER   0x00000001
#define MSG_NUMBER_HANDLED 0x00000002

class CDialMessage : IMessage
{
}

class CDialNumberMessage : IMessage
{
}

class CDialWatcher : public ISender
{
   CDispList m_pDispatchers; // ну класс списка любой

   CDialWatcher()
   {
        for (i=0; i<MAX_MESSAGE_TYPE; i++)
        {
           if (g_pDispatchers[i]->IsMessageTypeSuplied(MSG_DIALNUMBER))
               g_pDispatcher[i]->RegisterSender(this);
        }
   }
   
   virtual void AddDispatcher(CDispatcher *pDisp)
   {
       m_pDispatchers.Add(pDisp);
   }

   void SendMessage(void)
   {
       m_pDipatchers[].ProcessMessage(new CDialMessage); // тут просто перебор всех обьектов из списка
   }
}

class CAON : public ISender, IReceiver
{
   CAON()
   {
        for (i=0; i<MAX_MESSAGE_TYPE; i++)
        {
           if (g_pDispatchers[i]->IsMessageTypeSuplied(MSG_DIALNUMBER))
               g_pDispatcher[i]->ConnectReceiver(this);
           if (g_pDispatchers[i]->IsMessageTypeSuplied(MSG_NUMBER_HANDLED))
               g_pDispatcher[i]->RegisterSender(this);
        }
   }

   virtual BOOL ProcessMessage(IMessage *pMessage)
   {
        CDialMessage *pMsg = (CDialMessage*)pMessage;
        HandleDialNumber();
        SendMessage(new CDialNumberHandled);
   }
}

class CDialDispatcher : CDispatcher
{
   static void Create(void)
   {
        if (!g_pDispatchers[MSG_DIALNUMBER])
             g_pDispatchers[MSG_DIALNUMBER] = new CDialDispatcher();
   }

   virtual BOOL IsMessageTypeSuplied(DWORD dwMessageType)
   {
        return dwMessageType == MSG_NUMBER_HANDLED;
   }

   virtual BOOL RegisterSender(ISender *pSender)
   {
        pSender->AddDispatcher(this);
   }

   virtual BOOL ConnectReceiver(IReceiver *pRecv)
   {
       m_pClients.Add(pRecv);
   }

   virtual BOOL ProcessMessage(IMessage *pMsg)
   {
      m_pClients[]->ProcessMessage(pMsg);
   }
}


Самое удобное в такой схеме, что потом (если конечно реализовать глобальный пул диспетчеров динамическим), ты сможеш добавлять новые сообщения (и соответственно диспетчеров под них) уже в готовый проект (хоть в виде дллекок) не миняя имеющийся код smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)