карта сообщений (надоумте)
От: nen777w  
Дата: 15.02.08 10:03
Оценка:
Захотелось мне сделать что то вроде карты сообщений для моих контролов и окон. Оговорюсь сразу речь не про Windows.
В приложении есть главный цикл, который получает от операционки сообщения от периферийных устройств, мышь клавиатура и т.п.

Сейчас сделано так:
— есть базовый класс имеющий список виртуальных методов типа on_draw, on_mouse_move,...
— есть объект контейнер который унаследован от этого интерфейса, который переопределяет эти методы у себя
— есть объекты контролы которые собственно тоже унаследованы от этого базового класса

Работает это так:
— главный цикл приложения, выгребает меседж из очереди, вызывает соответствующую функцию у объекта контейнера а тот в свою очередь вызывает эту же фуенкцию у списка своих контролов.
Нужно ещё подумать как получить в этом объекте контейнере сообщения от контролов, например от кнопки которую нажали. (Каждый контрол имеет ID)

Хотелось бы сделать это как карты сообщений например в MFC. Кто какую концепцию может предложить?
Re: карта сообщений (надоумте)
От: zaufi Земля  
Дата: 15.02.08 10:18
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Хотелось бы сделать это как карты сообщений например в MFC. Кто какую концепцию может предложить?


забей на карты -- луче юзать сигналы и солоты (см. boost::signals, QT или на крайняк libsigc++)
Re[2]: карта сообщений (надоумте)
От: nen777w  
Дата: 15.02.08 10:24
Оценка:
N>>Хотелось бы сделать это как карты сообщений например в MFC. Кто какую концепцию может предложить?
Z>забей на карты -- луче юзать сигналы и солоты (см. boost::signals, QT или на крайняк libsigc++)

Я как то поюзал сигнал слоты, как раз бустовские, скорость работы меня не впечатлала, даже наоборот.
Так что имхо карты будут быстрее.
Re: карта сообщений (надоумте)
От: Stormblast http://www.myspace.com/stormblastblack
Дата: 15.02.08 10:48
Оценка:
Здравствуйте, nen777w, Вы писали:

Если не можешь использовать Qt, boost ...

то сделай сам через делегирование т.е. например по нажатию(или любое другое действие которые ты сам определишь) на кнопку(или любой другой контрол) будет происходить вызов нужной функции ...

например класс

BaseListener {

//вызов фун-ии с одним параметром
typedef Delegate<ControlEvent*> ObjectDelegate;

//, где Delegate это механизм делегирования ... тут лучше почитай про это ибо много писанины ... но это того стоит, очень удобная весч.

//, где например класс ControlEvent {
//имеет конструктор
ControlEvent(BaseControl* control){
        this->control = control;
    };

//, где 
BaseControl {// базовый для всех контрол  

    virtual void addListener(EventType eventType, BaseListener* listener);
//, где EventType это тип сообщения например KeyUp, FocusIn etc...
// а лучше в конкретных контролах сразу писать следующие методы
        addMouseDown(BaseListener* listener){
        // а уже тут присваивать правильный тип ...
        }
 }
    BaseControl* getControl(){
        return control;
    };
    
    void* getData(){
        return control->getObject();
// а контрол например может иметь какое то хранилище данных
    };
 }
}

ObjectDelegate objectDelegate;

}
Re[3]: карта сообщений (надоумте)
От: zaufi Земля  
Дата: 15.02.08 11:08
Оценка: +1
Здравствуйте, nen777w, Вы писали:

N>>>Хотелось бы сделать это как карты сообщений например в MFC. Кто какую концепцию может предложить?

Z>>забей на карты -- луче юзать сигналы и солоты (см. boost::signals, QT или на крайняк libsigc++)

N>Я как то поюзал сигнал слоты, как раз бустовские, скорость работы меня не впечатлала, даже наоборот.

N>Так что имхо карты будут быстрее.

а куда ты торопишся?? -- юзер твоей оконной системы всяко тормознее boost::signals
anyway, концепт signal slotов ме лична нравится больше убогих карт...
anyway2, можешь написать чонить свое, сильна быстрее работающее чем boost/qt...
Re: карта сообщений (надоумте)
От: Кодт Россия  
Дата: 15.02.08 11:12
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Хотелось бы сделать это как карты сообщений например в MFC. Кто какую концепцию может предложить?


Ну так и сделай примерно в этом же роде.
#define BEGIN_EVENT_MAP()             virtual bool ProcessEvent(Event const& event) {
#define CHAIN_EVENTS( _superclass_ )  if( _superclass_::ProcessEvent(event) ) return true;
#define END_EVENT_MAP()               return false; }

#define ON_EVENT( _type_, _handler_ ) if(event.type == _type_) { _handler_(event); return true; }
#define ON_COMMAND( _id_, _handler_ ) if(event.type == COMMAND && event.id == _id_) { _handler_(); return true; }


Можно отдельно сделать диспетчеризацию по событиям вообще, и пусть самый базовый класс вызывает все твои виртуальные методы on_blablabla; один из методов — on_command — тоже сделать таким же диспетчером.
#define BEGIN_COMMAND_MAP()                 virtual bool on_command(Event const& event) {
#define END_COMMAND_MAP()                   return false; }

#define ON_ID( _id_, _handler_ )            if(event.id == _id_) { _handler_(); return true; }
#define ON_RANGE( _id1_, _id2_, _handler_ ) if(event.id >= _id1_ && event.id <= _id2_ && _handler_(id)) return true;
#define ON_ANY( _handler_ )                 if(_handler_(event.id)) return true;
#define CHAIN_COMMANDS( _superclass_ )      if(_superclass_::on_command(event)) return true;
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: карта сообщений (надоумте)
От: Stormblast http://www.myspace.com/stormblastblack
Дата: 15.02.08 11:51
Оценка: +1
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, nen777w, Вы писали:


N>>Хотелось бы сделать это как карты сообщений например в MFC. Кто какую концепцию может предложить?


К>Ну так и сделай примерно в этом же роде.


Вот чего не стоить делать так это подражать MFC ... а лучше реализовать механизм обратного вызова.
Re[4]: карта сообщений (надоумте)
От: Stormblast http://www.myspace.com/stormblastblack
Дата: 15.02.08 12:03
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>а куда ты торопишся?? -- юзер твоей оконной системы всяко тормознее boost::signals


Да уж это точно !!!
Re[5]: карта сообщений (надоумте)
От: nen777w  
Дата: 15.02.08 12:27
Оценка:
Здравствуйте, Stormblast, Вы писали:

Z>>а куда ты торопишся?? -- юзер твоей оконной системы всяко тормознее boost::signals

S>Да уж это точно !!!

Как на счёт on_draw() сообщений?
Когда контрол например имеет некторую анимацию например когда на него мышкой наводят он подсвечивается.
Re[6]: карта сообщений (надоумте)
От: zaufi Земля  
Дата: 15.02.08 12:38
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Здравствуйте, Stormblast, Вы писали:


Z>>>а куда ты торопишся?? -- юзер твоей оконной системы всяко тормознее boost::signals

S>>Да уж это точно !!!

N>Как на счёт on_draw() сообщений?

N>Когда контрол например имеет некторую анимацию например когда на него мышкой наводят он подсвечивается.

и что в этом такого нириального? человеческий глаз воспринимает движуху с FPS около 25-30 кадров в секу -- я думаю бустерыне слоты не настолько тормозные чтоб не обеспечить тебе такой rate... думаю у тя в запасе как минимум еще один порядок... -- ну если твой on_draw конечно не буит аццки тормозить
Re[3]: карта сообщений (надоумте)
От: Кодт Россия  
Дата: 15.02.08 12:44
Оценка:
Здравствуйте, Stormblast, Вы писали:

S>Вот чего не стоить делать так это подражать MFC ... а лучше реализовать механизм обратного вызова.


Ну не обязательно MFC, ещё есть WTL. Кстати, в WTL это реализовано удобнее и прозрачнее.

А что ты имеешь в виду под обратным вызовом? Чтобы карта сообщений порождала структуру наподобие vtable, с указателями на функции-члены, а диспетчер сканировал/напрямую обращался к элементам этой структуры?
Такой вариант тоже возможен, и теоретически позволит добиться большей скорости.

Однако линейный поиск по карте даёт большую гибкость. Например, можно одно сообщение раздать нескольким разным обработчикам, вместо того, чтобы в каждом обработчике писать вызов следующего (например, из базового класса).

Опять же, паттерн-матчинг. На фиксированном формате реестра обработчиков — будет ограниченное количество предикатов (сравнение с кодом сообщения; сравнение с идентификатором контрола). А в исполняемой карте — каждый элемент может использовать какой угодно рукодельный предикат.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[4]: карта сообщений (надоумте)
От: Stormblast http://www.myspace.com/stormblastblack
Дата: 15.02.08 13:36
Оценка:
Здравствуйте, Кодт, Вы писали:

К>А что ты имеешь в виду под обратным вызовом?


Например в Qt механизм обратного вызова, основанном на передаче сигналов и их приеме слотами (Slots).
Эта система является основным механизмом связи между объектами. Сигнал может передавать любое число аргументов .. это очень удобно.
Подключаешь необходимые сигналы к соответствующим слотам, так что в итоге всегда знаешь, что происходит. Число сигналов, передаваемых классом, обычно невелико. Этот процесс находится под полным контролем. Механизм использования сигналов и слотов приближенно напоминает Java listener, но он более легковесен и универсален.
Re[5]: карта сообщений (надоумте)
От: Кодт Россия  
Дата: 15.02.08 14:44
Оценка:
Здравствуйте, Stormblast, Вы писали:

S>Например в Qt механизм обратного вызова, основанном на передаче сигналов и их приеме слотами (Slots).

S>Эта система является основным механизмом связи между объектами. Сигнал может передавать любое число аргументов .. это очень удобно.
S>Подключаешь необходимые сигналы к соответствующим слотам, так что в итоге всегда знаешь, что происходит. Число сигналов, передаваемых классом, обычно невелико. Этот процесс находится под полным контролем. Механизм использования сигналов и слотов приближенно напоминает Java listener, но он более легковесен и универсален.

Два немножко разных подхода к жизни.
В одном случае (MFC/WTL/...) развёртывается сеть для классов (мультиметод Обработчик(Получатель,Сообщение)).
В другом — для отдельных объектов.

Понятно, что
(+) Связи между экземплярами — это более общий и гибкий способ, нежели связи между классами
(-) Необходимость развёртывать эти связи каждый раз, когда создаётся семейство объектов (окно с контролами) — (+) компенсируется тем, что не так уж много этих объектов. Зачастую — по одному объекту (окну) на каждый класс

Но кстати, QT не отказывается и от классической обработки сообщений — это мультиметод virtual bool QObject::event(QEvent*).
И это правильно: иначе на каждую сущность внешнего мира (посторонние окна, клава, мышь и т.д.) пришлось бы заводить объекты-источники соответствующих сигналов. Плюс встал бы вопрос о доставке сигналов только сфокусированным объектам, а не широковещательно.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.