Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.06.2013, 07:47   #1
intmain
Играюсь с Python
Форумчанин
 
Аватар для intmain
 
Регистрация: 12.12.2012
Сообщений: 340
Лампочка Класс слушатель

Продумываю пути отступления и образовался вопрос.

Допустим у меня есть класс слушателя сообщений (клавы, мыши...)
От него порождены такие классы как кнопка, текстовое поле для ввода, галочка и другая гуй-фигня.

Сообщениями рулит менеджер сообщений )

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

Так вот.
Допустим один контролс выяснил что это сообщение предназначается ему. Ну, там мыша на него навели или кликнули.

Внимание вопрос: какова дальнейшая судьба сообщения кто его должен уничтожать и нужно ли это? тут я в ступор попал.
Что ел то - в долг, что жил то - зря.
Для избранных. ))
Секретные разработки
intmain вне форума Ответить с цитированием
Старый 17.06.2013, 08:03   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Никто его не должен уничтожать, всмысле пользователя. Его просто нужно выбрать из очереди сообщений и как-то обработать. Как обрабатывать ты уже написал. Остается только стандартный выбор сообщений (PeekMessage() кажись) и все.

Поправочка. Студия со мной не согласна:
Код:
	// Цикл основного сообщения:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
I'm learning to live...

Последний раз редактировалось Stilet; 17.06.2013 в 08:06.
Stilet вне форума Ответить с цитированием
Старый 17.06.2013, 09:39   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

сообщение умирает после всех обработок связанных с ним.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 17.06.2013, 09:40   #4
intmain
Играюсь с Python
Форумчанин
 
Аватар для intmain
 
Регистрация: 12.12.2012
Сообщений: 340
По умолчанию

Цитата:
Цикл основного сообщения:
да это понятно, я про другое.
ну как бы тут где-то сообщения будут передаваться менеджеру, а тот подписчикам.
подписчик - получил и сделал какую-то работу. И далее он наверно менеджеру должен как-то сигнализировать что дальше посылать данное сообщений другим подписчикам не нужно или просто делать выход из цикла в менеджере сообщений?
Что ел то - в долг, что жил то - зря.
Для избранных. ))
Секретные разработки
intmain вне форума Ответить с цитированием
Старый 17.06.2013, 10:16   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

А-а-а ну собственно сделай функцию, которую менеджер будет вызывать по приему сообщения, с передачей онного. Если функа возвращает true то менеджер завершает цикл с удалением сообщения из очереди.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 17.06.2013, 12:49   #6
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от intmain Посмотреть сообщение
Продумываю пути отступления и образовался вопрос.

Допустим у меня есть класс слушателя сообщений (клавы, мыши...)
От него порождены такие классы как кнопка, текстовое поле для ввода, галочка и другая гуй-фигня.

Сообщениями рулит менеджер сообщений )

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

Так вот.
Допустим один контролс выяснил что это сообщение предназначается ему. Ну, там мыша на него навели или кликнули.

Внимание вопрос: какова дальнейшая судьба сообщения кто его должен уничтожать и нужно ли это? тут я в ступор попал.
Объясните пожалуйста, а накой вообще было вот так все усложнять?

У меня гуй состоит из объектов ядра (добавальщики данных. Например один из добывальщиков возвращает координаты крысы, и состояния её кнопок).

И из контролов. Та же кнопка, которая ни болта ни о каких добывальщиках ничего не знает. Вся связь с добывальщиками - через коннекторы:

Код:
//класс ядра, который умеет добывать данные:
struct MouseCapture
{
   ...
   //крысоловка возвращает некую собственную структуру данных
   //с исчерпывающим описанием курсора
   CaptionMouse Live()const; 

   ...
};

//технически можно подключить нестандартную крысоловку, 
//но тогда придется писать адаптер, 
//который будет заполнять структуру CaptionMouse

...

//класс кнопки ничего не знает о крысоловке
//но знает о движковой структуре CaptionMouse
struct Button
{
    //через коннектор откуда то извне будут приходить данные 
    TConnector<CaptionMouse()> mTakeData;

    //если кнопку кликнут, она испустит событие по этому коннектору
    //о том, что на неё нажали
    TConnetor<void()> mClick();

    ...

    //бизнес-логика кнопки
    void Live() { ... }
};

...

//в точке программы (например в main.cpp)
//где создается объект кнопки, её заряжают коннекторами:

void Foo() { cout<<на кнопку нажали!\n";

int main()
{
   //создаем добывальщика данных 
   MouseCapture mc;

   Button button;
   button.mTakeData.Connect(mc, &MouseCapture::Live);
   button.mClick.Connect(&Foo);

   //теперь каждый раз, когда кнопка решит, что её кликнули
   //она через делегат будет вызывать функцию Foo
   while(1) button.Live();

}
Приложение можно разбить на состояния:

Например: стартовое меню, игра, показ рекордов, и тп.

В разных состояниях нас интересуют только отдельно взятые контролы.
И поэтому, имхо, проще самому делать Live интересующим нас контролам.

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

Ещё один важный плюс такого подхода: вся бизнес-логика кнопки сосредоточена только внутри кнопки. Кнопка не имеет внешних зависимостей. И её поведение целиком зависит только от фантазии программиста, но никак ни от ядра.

Например, при желании можно научить кнопку анимироваться, перемещаться, и проговаривать через динамики: "да, мастер! Выполняю мастер! На нас напаааалииии!!!"
_Bers вне форума Ответить с цитированием
Старый 17.06.2013, 13:25   #7
intmain
Играюсь с Python
Форумчанин
 
Аватар для intmain
 
Регистрация: 12.12.2012
Сообщений: 340
По умолчанию

Цитата:
Объясните пожалуйста, а накой вообще было вот так все усложнять?
Почему-то напротив думал такая логика самая примитивная и не искал сложностей.

И как у тебя TConnector выглядит ?
Что ел то - в долг, что жил то - зря.
Для избранных. ))
Секретные разработки
intmain вне форума Ответить с цитированием
Старый 17.06.2013, 13:56   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

делегатная система?
примерно как в Qt.

ток помоему кнопка ровно так же получает эти события из ядра? ток реакция уже идет от нее самой, верно же?
клик->ядро->компонент по кому кликнули->обработчик.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 17.06.2013, 13:56   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от intmain Посмотреть сообщение
Почему-то напротив думал такая логика самая примитивная и не искал сложностей.

И как у тебя TConnector выглядит ?
Проще: это когда конечному программисту пользователю не нужно знать подробностей и нюансов работы движка.

Система сообщений аля как в виндовс - пример усложнения на ровном месте.

Намного проще было бы, если бы в структуре класса окна указывались коллбэки на нужные случаи: "эту функцию запустить при перирисовке окна, эту..." в общем, тот же глют намного проще в использовании сделан.

Простота использования компонентов - вот мерило, коим можно измерять сложность архитектуры приложения в целом.

--------------------------------------------------------
Ближайшим аналогом TConnetor является std::function.

Только TConnetor ещё проще в использовании. А в некоторых ситуациях быстрее работает.

Умеет нацеливаться на свободные функции, методы классов, и на объекты-функторы.

Исходные коды открыты и доступны:
https://code.google.com/p/denis-library/

Я не слишком часто обновляю репозиторий. Там может быть более устаревшая версия библиотеки. Но она должна быть полностью рабочая.

Работоспособность гарантируюется юнит-тестами.
Тестируется работоспособность механизмов, и их внутренняя система безопасности.

Если интересно: то я развиваю библиотеку. Планируется выпуск под 11 стандарт тоже, а так же некоторые улучшения назрели.
_Bers вне форума Ответить с цитированием
Старый 17.06.2013, 14:12   #10
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
делегатная система?
примерно как в Qt.

ток помоему кнопка ровно так же получает эти события из ядра? ток реакция уже идет от нее самой, верно же?
клик->ядро->компонент по кому кликнули->обработчик.
Да, делегатная система. Только делегаты использую собственного производства. Не зависят ни от каких фреймворков, и они значительно превосходят по скорости кютешные.

По поводу добытчика данных - можно сделать и из ядра, а можно через коннектор.

Я делал так:

Button::Live через статический метод пинал сингелтон-крысоловку, ну и получал данные.

Плюсы: кнопка самостоятельно связывается с объектом ядра.
Минусы: жесткая связь.

Например, надо протестировать реакции кнопки на те, или иные ситуации.
Если кнопка добывает данные через делегат, все просто - можно нацелить кнопку на наш тестовый класс, и кормить кнопку любыми нужными нам данными. А потом просто проверять, что кнопка реагирует, как нам нужно.

Но если кнопка хардкорно тащит за собой ядро, то изолировать её от основного движка уже будет сложнее.

То есть, сложность проекта увеличиться.

Захочется тестировать: придется всякие костыли мастерить, воссоздавая некое фейковое окружение движка.

Последний раз редактировалось _Bers; 17.06.2013 в 14:15.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Cоздать класс жидкость. определить конструкторы деструкторы и функцию печати. создать публик производный класс. (С++) Динар Габбасов Помощь студентам 0 28.05.2012 18:44
Добавить класс в проект2,похожий на класс из проекта1!оба проекта есть! xeops C# (си шарп) 0 15.05.2012 20:31
Класс запускает поток, который заполняет этот класс. Обмен класс <=> поток. Человек_Борща Общие вопросы Delphi 8 27.02.2012 23:24
Слушатель мышки и Graphics g kir_rik Общие вопросы по Java, Java SE, Kotlin 2 10.11.2011 08:30
Форма-Добавить объект-Назначить слушатель события tolikman Microsoft Office Excel 6 10.09.2008 16:18