![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 2 Всего: 261 |
Есть ГУЙ, использующий Qt. Есть модули, написанные на стандартном С++, модули оформлены как namespace (классов нет).
Задача в том, что ГУЙ должен реагировать (изменять информацию в таблице), в зависимости от работы модуля. Т.е. в модуле есть долгоработающая функция, в данный момент без потока, но потом и он будет реализован. В процессе выполнения обрабатывается std::vector<struct AAA>. Пусть в структуре есть поле status, которое характеризует состояние объекта. Что я хочу. Чтобы в процесс обработке этого вектра в зависимости от установления статуса объекта генерировался сигнал, который ловился бы функцией в ГУЕ, передавая параметр - номер элемента стека. Грубо говоря, хочу получить: connect(nsModul, SIGNAL(signal1(int)), guiClass, SLOT(slot1(int)); Но, не хочу вставлять в модуль части Qt, чтоб через Qt реализовывать события... Решения нужна как для Linux'a так и для Windows. Посмотрел WinAPI, там есть SetEvent, но что-то я не нашел как там привязать функции друг к другу. Второй вариант над котором думаю - сделать с помощью mutex'ов, через WinSock2/pthread, но как они работают не догоняю и как применить их для моей задачи не соображу. Куда копать? СУВ. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Задача решается callback'ом. Вариантов много.
1 можно на каждое событие регистрировать прокси функцию (функтор) 2. можно каждому событию назначить номер (если нужно передавать только состояние) 3. можно сделать прокси класс - базовый интерфейс будет известен модулю, а реализацию наследника выполнить в части где есть qt 4. можно описать для каждого события свой класс от обшего наследника и управлять потком событий на основе перегрузки функций и патерна визитер. 5.. чтоб посоветовать вариант нужно хорошо представлять что именно Вам необходимо Добавлено через 11 минут и 25 секунд http://dobrokot.nm.ru/cpp/CppMethodsCallback.html |
|||
|
||||
| Mal Hack |
|
||||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 2 Всего: 261 |
Попробую описать задачу так:
При этом, msModul находится в отдельном файле и вставлять туда gui.h я не хочу. По сути, есть какой-то фреймворк, который в определеных случаях должен генерировать сигнал, мол такой-то элемент изменил свое состояние. Гуй, должен при необходимости получать этот сигнал и обрабатывать. Не знаю, на сколько правильно, но я представляю себе это так: есть класс или namespace, который отвечает за связь событий модуля и слотов Гуя, при этом он не должен быть привязан к конкретному модулю или Гую. в нем должен быть std::vector указателей на фукнции сигнала и слота, и как-то он должен ловит сигнал и по нему вызывать слот, причем идальный вариантом было бы как в Qt (на подобии, скажем так), сигнал описывается как функция, но ее реализации - нет, но при emit func() поисхдит вызов события и вызывается слот, котороый связвн с сигналом через connect. Спасибо. Сижу осмысливаю... Можно чутьподробнее... |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот пример на основе closure
|
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 2 Всего: 261 |
mes, у класса А public обязателен? На private работать будет?
closure не стандартное средство С++, как я понимаю? Это совершенно стороння либа? |
|||
|
||||
| Mal Hack |
|
||||||||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 2 Всего: 261 |
Сейчас имею вот такие наметки (в качестве сигнала - std::string, т.е. модуль вызывает ssEmit("SOME_STRING")):
Заголовочный файл.
CPP:
В Qt модуле пытаюсь соединить:
Компилятор ругается, мол не может привести типы:
Обозвать static'ом frmManualCommandsImpl::tblCommandsSetRow нельзя, т.к. метод становится вне класса qt, и не видит того, что надо. Сделать ssConnect шаблоном, что приводить к void(__thiscall T:: *ssFnc)() тоже не могу, класс находится в другом модуле, следовательно шаблоны не работают. Вот как данный сабж обойти и передать имя класса еще... Можно ли вообще так сделать? |
||||||||
|
|||||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
будет если класс сам будет добавлять слоты к сигналам. [quote=Mal Hack, 3.8.2008, 20:17, post1600051]closure не стандартное средство С++, как я понимаю? Это совершенно стороння либа? да стороняя либа (размером в два .h файла примерно 7 кб.. скачать можно по ссылке приведенной в первом ответе) нужна для того чтоб легко превратить метод объекта в делегат метод и функция две разные веши
оно и понятно иначе бы и вопроса не стояло бы метод без объекта смысла приводить к функции нет, ну а если вместе то эта и делает closure P.S не советую использовать в коде чистую строку , лучше заменить ее на строковую константу.. позволит избежать кучи головной боли полученной при случайной опечатке Это сообщение отредактировал(а) mes - 3.8.2008, 22:45 |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 2 Всего: 261 |
А как у нее с кроссплатформенностью?
Почему? То, что char* будет меньше памяти кущать - понятно... |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
на разных компиляторах не тестил.. может не которые откажутся прогалатить шаблоны.. а от платформы ИМХО код не зависим.. буст предоставляет более гибкое решение, но она громадная либа можно пойти иначе: надо будет описать абстрактный класс в модуле, как интерфейс событий а реализовать его в гуишной части 1. и уже реализацию связывать qt шными сигналами 2. сделать прокси класс, для вливания (делегации) команд главному классу, но тогда нужно организовывать цепочку обязаностей 3. использовать двойное наследие
да нет. дело совершено не в размере... Например ты сразу определишь на глаз результат действия ? "PRINTER_СОMMАND_EXECUTED" == "PRINTER_COMMAND_EXECUTED" или "PRINTER_COMMAND_EXECUTED" == "PRINTER_COMMAND_EXECUTED " в обоих случаях результат сравнения false. A компилятор даже не пошевелится, чтоб подказать об опечатке.. поэтому желательно использовать так const string PRINTER_COMMAND_EXECUTED ( "PRINTER_COMMAND_EXECUTED"); а чтоб не подключать хидер можно писать extern const string PRINTER_COMMAND_EXECUTED; и тогда компилятор завопит в случае опечатки, строка будет описана в одном месте, а доступна везде да и самому легче будет Это сообщение отредактировал(а) mes - 4.8.2008, 21:34 |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 2 Всего: 261 |
Все, понял о чем ты. Приму к сведению. Думал я над этими вариантами. Тут у меня опять-таки возникат вопрос, то же, только с другой стороны, как в этот класс nsModul::signal запихнуть... |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
опиши что должен отдавать модуль, какие типы сигналов, сколько их примерно , связаны ли некоторые между собой в логические группы ? как должен быть осушествлен прием? цепочкой обязоностей? то есть каждое сообшение должно пройти по (условно) всему гуи ? или обработка точечная ? обьект гуи получает единичные сигналы или обрабатывает значительную группу ? |
|||
|
||||
| Mal Hack |
|
||||||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 2 Всего: 261 |
Тип сигнала - строка, т.к. это наиболее оптимальный вариант чтобы использовать несколько модулей. Кол-во - разное, ничем не ограничено, ну т.е. внутри модуля оно фиксированное, но чтобы потом эту либу (сигналов) можно было бы использовать в другом приложении нельзя его жестко привзывать к текущему модулю.
Принцип такой. Есть событие - вызывается определенная функция (в данном случае GUI), при этом модуль не ждет ее выполнения, а продолжает работать дальше. Точечная. Т.е. надо назначить на каждый сигнал четко определенную функцию.
Как модуль сгенерирует сигналы так они и должна обрабатываться. |
||||||
|
|||||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
строка - это ключ/имя сигнала.. а тип сигнала - это данные какого типа он несет. в первых примерах было упомянуто что сигнал передает int-value , но учитавая масштабность затеи я засомневался, что этим ограничится а вот нужна ли либа если у вас и так все средства есть ? Вам ведь всего лишь не хочется связывать модуль с гуи ? кстати а кам Вам то что теперь модуль будет видеть вашу библиотеку ?
чем дальше в лес тем больше дров.. )) Для начала упростим все избавимся от зависимостей модуля и посмотрим что нам нужно для этого определим "ответный"(callback) интерфейс . Если длл - то нам придется использовать абстрактный класс, иначе можно обойтись просто связыванием.
теперь осталось, реализовать наследника Modul::ICallback и зарегистрировать его в модуле.. Ну теперь вроде ничего не мешает использовать QSignal ? Это сообщение отредактировал(а) mes - 6.8.2008, 01:01 |
||||||
|
|||||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |