реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Embedded GUI, Что поизучать?
haker_fox
сообщение Sep 11 2012, 01:54
Сообщение #16


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (dxp @ Sep 10 2012, 23:43) *
Если это вопрос о передаче информации объектам GUI, то нет, там используется иной механизм (могу рассказать подбробнее). А OS::channel можно использовать для передчи сообщений в главный цикл GUI из других процессов и обработчиков прерываний.

Если можно, расскажите, пожалуйста, подробнее. В чем отличие. Для меня это все пока одинаково выглядит.

На данном этапе развития ГУИ я планирую сделать так.

Завести структуру сообщения в виде
CODE
enum FMessageType
{
    FMsgFromKbd,
    FMsgFromTouch,
    FMsgFromADC
    // и т.д. по мере необходимости
};

struct FMessage
{
    FMessageType msg; // тип сообщения (от кого пришло)
    // Здесь надо подумать, как унифицировать данные от клавиатуры и других объектов, т.к. типы передаваемых данных разные

}


Ну и отправлять сообщения из любого потока ОС, которое что-то хочет отправить ГУИ. А последняя пусть сама разбиарается, что с этим сообщением делать (игнорировать, построить очередную точку на диаграмме, "нажать" кнопку...)...


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 11 2012, 02:51
Сообщение #17


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Подумайте сразу о параметрах сообщения. Ну, типа координат нажатия на экран, кода нажатой клавиши, значения АЦП...


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Sep 11 2012, 03:25
Сообщение #18


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (AHTOXA @ Sep 11 2012, 10:51) *
Подумайте сразу о параметрах сообщения. Ну, типа координат нажатия на экран, кода нажатой клавиши, значения АЦП...

Совершенно верно! rolleyes.gif Поскольку очередь сообщений OS::channel предназначена для передачи данных конкретного типа (а это ее преимущество, чтобы не плодить сущности с указателями void*), необходимо как-то унифицировать тип сообщения. Пока думаю...


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 11 2012, 03:48
Сообщение #19


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (mdmitry @ Sep 11 2012, 04:15) *
Весьма интересно узнать, какие идеи заложены в Вашем решении.

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

Вообще, задача похожа на такие, где на больших машинах применяют RTTI, но механизм RTTI слишком тяжёл - там идёт полноценная проверка имени типа, сигнатуры. Нам бы тут чего попроще. Самое то было бы, если бы просто сравнивать целочисленные идентификаторы, но так, чтобы гарантировано у каждого типа было свое уникальное значение. И чтобы не следить за этим руками. Чтобы в точке передачи сообщения мы его создали, а в точке (точках) приёма проверили на соответствие типа, и если тип соответствует, обработали, иначе передали дальше или проигнорировали.

Реализация механизма следующая. Сразу приведу весь код, ниже будет дано пояснение:

CODE
//------------------------------------------------------------------------------
inline uint16_t generate_id() { static uint16_t id; return ++id; }

class TBaseMsgWrapper
{
public:
    virtual uint16_t get_id() = 0;
};

template<typename T> class msg_wrapper : public TBaseMsgWrapper
{
public:
    msg_wrapper(T *msg) : body(msg), TBaseMsgWrapper() { }
    
    static  uint16_t get_class_id() { static const uint16_t id = generate_id(); return id; }
    virtual uint16_t get_id()       { return get_class_id(); }
    
    T *get_msg() const { return body; }
    
private:
    T *body;
};

template<typename T> T *check_msg(TBaseMsgWrapper *msg_wrp)
{
    if( msg_wrp->get_id() == msg_wrapper<T>::get_class_id() )
    {
        return (static_cast<msg_wrapper<T> *>(msg_wrp))->get_msg();
    }
    else
    {    
        return 0;
    }
}

template<typename T> bool send_message(T *msg, gui::TObject *dst)
{
    msg_wrapper<T> msg_wrp(msg);
    dst->on_message(&msg_wrp);
    
    return true;
}
//------------------------------------------------------------------------------

Ключевыми частями являются функция generate_id() и шаблон msg_wrapper. Функция generate_id() при каждом вызове возвращает целое с новым значением (увеличенным на 1 в данном случае), и служит, как ясно из названия, для генерации уникальных идентификаторов. Внутри шаблона msg_wrapper есть механизм получения и предъявления уникального (для каждого типа) идентификатора. Реализован с помощью пары функций get_class_id() и get_id().

Функция get_class_id(), собственно, и производит получение уникального идентификатора и его хранение. Сделано это на основе свойства статических локальных переменных инициализироваться "по месту":
CODE
static  uint16_t get_class_id() { static const uint16_t id = generate_id(); return id; }

При первом входе в функцию, внутренняя статическая константа id получает значение, которое затем возвращается. В дальнейшем при вызове этой функции только возвращается это единыжды полученное значение. Таким образом, каждый тип сообщения, передаваемый через msg_wrapper, получает автоматом свой уникальный целочисленный идентификатор.

Функция get_id() является интерфейсом для доступа к этому идентификатору. Поскольку сообщения могут передаваться произвольными, нельзя при передаче указывать конкретный тип. Вместо этого передаётся указатель на базовый класс всех типов сообщений, и получение уникального идентификатора производится через виртуальную функцию, чтобы получить для каждого конкретного типа именно своё значение.

Ну, далее пара функций - передачи и приёма. Передача:

CODE
template<typename T> bool send_message(T *msg, gui::TObject *dst)
{
    msg_wrapper<T> msg_wrp(msg);
    dst->on_message(&msg_wrp);
    
    return true;
}

Тут всё просто. Функция принимает указатель на тело сообщения и адрес объекта назначения. Поскольку у нас назначением является любой объект из иерархии виджетов, то в качестве типа объекта взят самый главный предок всей этой иерархии. Передаётся при вызове, разумеется, адрес конкретного объекта, в вышеописанной схеме GUI - адрес виджета под фокусом. Далее, внутри функции передачи конструируется собственно сообщение на основе обёртки msg_wrapper (ничего особенного тут не делается, просто инициализируется указатель на тело сообщения, накладные расходы минимальны) и посылается по указанному адресу - вызов той самой важной функций on_message(). В коде такая передач выглядит так:
CODE
    .... //
    if( ... )
    {
        TMessageBody Msg = ...;
        send_message<TMessageBody>(&Msg, Focus);
    }
    ... //



Приём выглядит так (пример приводился выше, повторяю для связности изложения):

CODE
void gui::TWidget::on_message(TBaseMsgWrapper *msg_wrp)
{
    gui::TInputMessage *msg = check_msg<gui::TInputMessage>(msg_wrp);
    
    if(msg)
    {
        switch(*msg)
        {
        case gui::imENTER : enter(); break;
        case gui::imBACK  : back();  break;
        case gui::imHELP  : help();  break;
        case gui::imNEXT  : next();  break;
        case gui::imPREV  : prev();  break;
        default           : print("error: unknown message");
        }
    }
}

Здесь на входе проверяется соответствие типа сообщения ожидаемому; если соответствует, то дальше производится обработка тела сообщения. Соответствие выражается в значении возвращаемого указателя функции check_msg(). Если сообщение соответствует ожидаемому, то возвращается указатель на тело сообщения, если не соответствует, то возвращается ноль:

CODE
template<typename T> T *check_msg(TBaseMsgWrapper *msg_wrp)
{
    if( msg_wrp->get_id() == msg_wrapper<T>::get_class_id() )
    {
        return (static_cast<msg_wrapper<T> *>(msg_wrp))->get_msg();
    }
    else
    {    
        return 0;
    }
}

Здесь производится сравнение целочисленных идентификаторов, один из них извлекается из сообщения, второй - из типа ожидаемого сообщения. Если они совпадают, то тип сообщения соответствует ожидаемому, далее тип указателя на базовый класс сообщений приводится к типу указателя на сообщение ожидаемого типа (тут это безопасно, т.к. произведена проверка) и далее возвращается указатель на тело сообщения.

Таким образом осуществляется фильтрация сообщений. Это позволяет выстроить систему передачи сообщений, не "привязываясь" к конкретным типам, и в дальнейшем расширять сколько угодно перечень передаваемых сообщений, ничего не переделывая в этом коде. В примере выше при приёме ожидается сообщение от устройств ввода (в данном случае ими являются кнопки прибора и энкодер). Это поведение по умолчанию для всех виджетов. Если нужно для какого-то виджета изменить поведение, достаточно, как уже говорилось, для него переопределить функцию on_message(). Вот пример, как в одном из виджетов обрабатываются свои сообщения:

CODE
void gui::TModeControl::on_message(TBaseMsgWrapper *msg_wrp)
{
    gui::TTimeIntervals *TimeMsg = check_msg<gui::TTimeIntervals>(msg_wrp);   // сообщения о временнЫх метках
    gui::TModeContolMsg *MCMsg   = check_msg<gui::TModeContolMsg>(msg_wrp);   // "проприетарные" сообщения для данного виджета

    if(TimeMsg)
    {
        switch(*TimeMsg)
        {
              ... //
        }
    }
    else if(MCMsg)
    {
        switch(*MCMsg)
        {
        case gui::mcmCONTACT_LOST:
            {
                 ... //
            }
            break;

        case gui::mcmELECTRODE_OFF:
            {
                ... //
                print("Electrode is off\r\n");
            }
        ... //
        default:
            print("error: unknown mode control message\r\n");
        }
        
    }
    else
    {
        TWidget::on_message(msg_wrp);    // переслать необработанные сообщения дальше
    }
}
//------------------------------------------------------------------------------

Очень важный момент - последняя ветка else. Если этого не сделать, то все сообщения, которые не обработаны, дальше не пойдут, когда данный виджет под фокусом. Внешне это будет выражаться так, что данный виджет не будет реагировать на устройства ввода (т.к. в вышеприведённой функции on_message() сообщения от устройств ввода не обрабатываются). Если их переслать дальше, то сообщения попадут в TWidget::on_message() (показанную выше) и там будут обработаны. Если требуется какая-то иная их обработка, то можно её реализовать в этой же функции, не передавая дальше. Словом, тут полная свобода действий, расширяемость, хорошая управляемость и очень небольшие накладные расходы.

Напоследок замечание (это больше для haker_fox). Не следует путать сообщения, передаваемые по вышеописанной схеме, с сообщениями, передаваемыми через средства межпроцессного взаимодействия (типа OS::channel), механизмы реализации и назначение совершенно разные. Вариант send_message/check_msg - это передача сообщения в главном цикле GUI от источников к виджетам. Передача эта синхронная - в момент передачи сообщение и принимается, и обрабатывается - это всё одна и та же цепочка вызовов функций. А передача сообщений через OS::message или OS::channel - это передача асинхронная, потокобезопасная и через промежуточный объект, в котором хранится тело сообщения. Передавать через send_message() из другого процесса можно, но это небезопасно с точки зрения межпроцессного взаимодействия.

Собственно, GUI и OS - вещи несколько ортогональные. GUI - это, как правило один из процессов (потоков, задач), крутится в своём цикле. Если требуется передавать ему сообщения из других процессов программы, то это логично сделать, например, через OS::channel, организовав очередь сообщений, и уже в процессе, в котором крутится GUI, извлекать сообщения из очереди, преобразовывать их и передавать по вышеописанной схеме виджетам.

Вообще, сам способ генерации и проверки уникальных идентификаторов типов, описанный выше, достаточно универсален и может применяться везде, где требуется подобная проверка на рантайме. В некоторых случаях может вполне успешно заменять RTTI. Прикручивал этот механизм к объектам QEvent, легло вообще отлично благодаря сходности базы объектов событий пакета Qt. Там им только не хватало автоматической генерации идентификаторов и проверки, а сами типы событий там идентифицируются тоже на основе целочисленных переменных.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Sep 11 2012, 05:16
Сообщение #20


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



dxp, спасибо большое за подробнейшее разъяснение! Вникаю sm.gif


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
_pv
сообщение Sep 11 2012, 07:37
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(dxp @ Sep 11 2012, 10:48) *
По условиям задачи требуется передавать разнокачественную информацию объектам, тип которых, вообще говоря, на этапе компиляции не известен.

возможно я не до конца осознал всю радость от знания типа объёктов, но чем хуже использовать просто int в качестве сообщений, у самого базового класса Widget сделать виртуальный handle(int event), за который и дергать потом все виджеты подряд.
а уже в этом обработчике доставать откуда надо необходимые данные, если нужно:
int handle(int event){
switch (event){
case EVENT_KEYBOARD: int key = get_key(); ...
...
}
так, насколько я понимаю, в FLTK сделано.
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 11 2012, 08:40
Сообщение #22


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (_pv @ Sep 11 2012, 14:37) *
возможно я не до конца осознал всю радость от знания типа объёктов, но чем хуже использовать просто int в качестве сообщений, у самого базового класса Widget сделать виртуальный handle(int event), за который и дергать потом все виджеты подряд.
а уже в этом обработчике доставать откуда надо необходимые данные, если нужно:
int handle(int event){
switch (event){
case EVENT_KEYBOARD: int key = get_key(); ...
...
}
так, насколько я понимаю, в FLTK сделано.

А если сообщения совсем разные? В одном случае мы передаём паттерн, который содержит карту нажатых кнопок (например, допускается и требуется одновременное нажатие нескольких кнопок), в другом случае передаём временную метку, в третьем команда от терминала, в четвёртом информация от АЦП (нужно выводить на экран данные) и т.п. И как в этом случае обойтись одним интом? Информация не только разнокачественная, но и разная по размеру - от 8-битного целого до целой структуры.

К тому же, как сделать фильтрацию? Вот дёрнули handle() для текущего виджета - так эта функция должна уметь обрабатывать все события. Можно, конечно, завести систему кодирования на основе этого передаваемого инта и анализировать значения. Но это будет "закат Солнца вручную" - как раз примерно то, что делает схема передачи сообщений из предыдущего моего поста.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Sep 11 2012, 12:23
Сообщение #23


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(dxp @ Sep 11 2012, 12:40) *
К тому же, как сделать фильтрацию? Вот дёрнули handle() для текущего виджета - так эта функция должна уметь обрабатывать все события. Можно, конечно, завести систему кодирования на основе этого передаваемого инта и анализировать значения. Но это будет "закат Солнца вручную" - как раз примерно то, что делает схема передачи сообщений из предыдущего моего поста.

Уважаемый dxp, правильно ли я понял, что на этой же идее у Вас реализована передача информации меджу элементами GUI. Имеется в виду следующее: выбор какого-то пункта меню может блокировать доступ к другим элементам.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 11 2012, 15:31
Сообщение #24


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (mdmitry @ Sep 11 2012, 19:23) *
Уважаемый dxp, правильно ли я понял, что на этой же идее у Вас реализована передача информации меджу элементами GUI. Имеется в виду следующее: выбор какого-то пункта меню может блокировать доступ к другим элементам.

Это как напишете. У меня в примере информация от устройств ввода передаётся виджету под фокусом, он и является получателем. Можно и другие схемы реализовывать - например, сделать несколько фокусов и метать сообщения, фильтруя на передающем конце, тогда блокировки не будет. Например, можно сообщения от кнопок слать элементам меню, диалогам, а от таймера - виджету часов, а от АЦП - виждету, отображающему уровень заряда батареи, и т.д. Всё в руках программиста. А механизм передачи один и тот же.

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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Sep 11 2012, 18:33
Сообщение #25


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(dxp @ Sep 11 2012, 18:31) *
Это как напишете. У меня в примере информация от устройств ввода передаётся виджету под фокусом, он и является получателем. Можно и другие схемы реализовывать - например, сделать несколько фокусов и метать сообщения, фильтруя на передающем конце, тогда блокировки не будет. Например, можно сообщения от кнопок слать элементам меню, диалогам, а от таймера - виджету часов, а от АЦП - виждету, отображающему уровень заряда батареи, и т.д. Всё в руках программиста. А механизм передачи один и тот же.

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


Не очевидная логика.
Подвергать GUI потоку событий от реалтайм задач это значит перегрузить процессор лишней работой либо принудить задачи подстраиваться под GUI и все время беспокоиться о профайлинге GUI.
Надежней в самой задаче GUI планировать обращение за информацией к другим задачам.
Тогда и ивентов становиться гораздо меньше, упрощается их парсинг и поддержка GUI проще.
Вон в uc/GUI всего 32 базовых сообщения.
И хватает за глаза, это учитывая, что там развитый оконный движок наподобие Windows.
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Sep 11 2012, 21:40
Сообщение #26


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(dxp @ Sep 11 2012, 19:31) *
Говорить, что передаётся информация между виджетами тут нельзя - этого нет. Информация передаётся от входных сигналов виджетам, задача которых адекватно реагировать и отображать реакцию на устройстве визуализации.

Спасибо, dxp.
Поясните, пожалуйста, как Вы делаете именно связь между элементами GUI для управления. По нажатию кнопки выбран элемент из списка №1 (режимы работы). Есть связанный со списком №1 список №2 (специфические (уникальные) для данного режима подрежимы). Как в этом случае делается переключение на нужный список №2.
Как-то так:
Код
режим1
    подрежим11
    подрежим12
    подрежим13
режим2
    подрежим21
    подрежим22
режим3
    подрежим31
    подрежим32
    подрежим33


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 12 2012, 01:20
Сообщение #27


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (mdmitry @ Sep 12 2012, 04:40) *
Поясните, пожалуйста, как Вы делаете именно связь между элементами GUI для управления. По нажатию кнопки выбран элемент из списка №1 (режимы работы). Есть связанный со списком №1 список №2 (специфические (уникальные) для данного режима подрежимы). Как в этом случае делается переключение на нужный список №2.

Ну, т.е. что-то вроде системы меню? Это несколько другая тема, чем передача сообщений. Тут тоже может быть несколько реализаций. Я делаю связь через промежуточный объект Target. При создании пункта меню ему присваивается объект Target, который представляет собой простой объект из иерархии таржетов. Все их объединяет метод (виртуальная функция) exec(), которая и вызывается внутри метода объекта пункта меню, отвечающего за реакцию на нажатие соответсвующей кнопки. Схема действий проста: внутри переключается фокус и вызывается перерисовка, а также выполняются все сопутствующие действия.

Если приводить аналогию из С, то этот способ похож на связть через указатель на функцию, которая и выполняет действия. Тут просто эта функция "завёрнута" в объект Target, что делает использование более безопасным и удобным (можно хранить внутри этого объекта какие-то служебные переменные). Использование промежуточных объектов позволяет гибко настроить целевые действия при активации виджета. Если не очень понятно описано, скажите, пример приведу (сейчас его нет под рукой).

AlexandrY, именно так и делается, см самый первый мой пост в этой теме - главный цикл GUI. Все сообщения посылаются из него с его темпом.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Sep 12 2012, 06:33
Сообщение #28


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(dxp @ Sep 12 2012, 04:20) *
AlexandrY, именно так и делается, см самый первый мой пост в этой теме - главный цикл GUI. Все сообщения посылаются из него с его темпом.


Цикл в первом посте выглядит совсем плохо.
Получается искусственно созданный задержкой затор.
В это время в очереди может накопиться куча сообщений которые GUI должно быть выполнить все одним рывком.
Это как минимум будет выглядеть некрасиво на экране.
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 12 2012, 08:50
Сообщение #29


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (AlexandrY @ Sep 12 2012, 13:33) *
Цикл в первом посте выглядит совсем плохо.
Получается искусственно созданный задержкой затор.
В это время в очереди может накопиться куча сообщений которые GUI должно быть выполнить все одним рывком.
Это как минимум будет выглядеть некрасиво на экране.

Да, давайте обсудим недостатки простых примеров, приведённых для упрощения понимания. Ясно, что ничего не мешает этот цикл сделать так, как хочется - например, создать очередь сообщений от других процессов. К тому же, даже в том примере цикл составляет 40 мс, этого вполне достаточно для комфортной реакции GUI на события - врядли вы успеете заметить торможение при обновлении информации, если, конечно, не рубитесь в Unreal Tournament.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Sep 12 2012, 13:42
Сообщение #30


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(dxp @ Sep 12 2012, 11:50) *
Да, давайте обсудим недостатки простых примеров, приведённых для упрощения понимания.
...цикл составляет 40 мс, этого вполне достаточно для комфортной реакции GUI на события - врядли вы успеете заметить торможение при обновлении информации...


Я думаю задержка там концептуально поставлена, а не для простоты.
Она именно дает GUI передохнуть.
Скорее всего жертвуется событиями от клиентских для GUI задач.

Для маленьких монохромных экранов 40 мс скорее всего будет незаметно.
Но для больших цветных панелей с тачскрином где весь цикл прорисовки занимает больше 40 мс последствия задержки сразу будут заметны.

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

Вообщем преимущества продемонстрированной реализации весьма спорны, либо она уж очень упрощена wink.gif
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 02:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01532 секунд с 7
ELECTRONIX ©2004-2016