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

 
 
> Как бы организовать в Сях аналог self/this?
Tahoe
сообщение Jul 4 2015, 04:56
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Суть вопроса, на примере управления светодиодом. Декларация структуры, с "методом" set:

Код
typedef    enum    ui_led_mode_e
{
    UI_LED_MODE_OFF,
    UI_LED_MODE_ON,
    UI_LED_MODE_TOGGLE,
    UI_LED_MODE_FLSH_LONG,
    UI_LED_MODE_FLSH_SHRT,
}    ui_led_mode_t;

typedef    void    ( * ui_led_set_t )(            ui_led_mode_t        mode        );

typedef    struct    ui_led_s
{
    ui_led_set_t      set;
    size_t            tick;
}    ui_led_t;

typedef    struct    ui_s
{
    ui_led_t            led[ 2 ];
}    ui_t;


Использование:

Код
ui_t        ui;

void    main(                                void                            )
{
    ui_init();

    while( 1 )
    {
        ui.led[ 0 ].set(    UI_LED_MODE_FLSH_SHRT                    );
        delay_msec( 500 );
    }
}


Проблема возникает при реализации ui_led_set(). А именно, как ui_led_set() узнать, откуда пришел вызов? Из ui.led[0].set() или из ui.led[1].set?

Тупое:

ui.led[ 0 ].set( 0, UI_LED_MODE_FLSH_SHRT );
ui.led[ 1 ].set( 1, UI_LED_MODE_FLSH_SHRT );

сколь очевидно, столь и не интересно, поскольку суть вопроса в аналоге self/this, а не передавать каждый раз извне. В голове крутится, как-то сыграть на том, что ui это глобальная/статическая переменная. Но как именно - не соображу.

Можно, конечно, добавить в структуру поле "n" и при инициализации, ручками, пронумеровать все стркутуры в массиве:

Код
typedef    struct    ui_led_s
{
    size_t            n;
    ui_led_set_t      set;
    size_t            tick;
}    ui_led_t;


Но может есть какой-то более элегантный способ?

Речь о чистых Сях. Варианты в духе "написать на плюсах" или "не париться" известны и не интересны - заранее привет от К.О. sm.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
adnega
сообщение Jul 4 2015, 06:34
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Может, я не прав, но стараюсь в отношении Си придерживаться принципа: управляй данными, а не кодом.
Т.е. минимизирую число функций, а структуры данных использую по максимуму.
В структурах данных могу хранить адреса callback-функций, когда это важно.

Обработку кнопок и светодиодов провожу в системном таймере. Изменение состояний светодиодов
произвожу через данные структуры. Считывание состояний кнопок можно проводить через данные структуры,
а можно через callback-функции.

Вы же рассматриваете светодиоды и кнопки как объекты (т.е. данные и код для обработки этих данных) - вам прямой путь в плюсы.
Или делать по аналогии .set(&led[0], NEW_STATE) передавая явно указатель на объект (а не его номер).
Причем, сегодня вам не хватает this, а завтра захочется наследования и полиморфизма)
Go to the top of the page
 
+Quote Post
Tahoe
сообщение Jul 4 2015, 07:22
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(adnega @ Jul 4 2015, 09:34) *
Обработку кнопок и светодиодов провожу в системном таймере.

Аналогично. Hook вызывается из SysTick_Handler(), это системный таймер.

Цитата(adnega @ Jul 4 2015, 09:34) *
Изменение состояний светодиодов
произвожу через данные структуры.

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

Цитата(adnega @ Jul 4 2015, 09:34) *
Вы же рассматриваете светодиоды и кнопки как объекты (т.е. данные и код для обработки этих данных) - вам прямой путь в плюсы.

Такие вещи, как светодиоды/кнопки и еще много других, используются в 9 проектах из 10. Какие-то проекты допустимо исполнить на плюсах, но в основном, заказчики хотят чистый Си. Делать по две реализации каждого драйвера, каждого сервиса - совсем не хочется. Да и почему бы не выжать из Сей максимум его возможностей? sm.gif

Цитата(adnega @ Jul 4 2015, 09:34) *
Причем, сегодня вам не хватает this, а завтра захочется наследования и полиморфизма)

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

Цитата(adnega @ Jul 4 2015, 09:34) *
Или делать по аналогии .set(&led[0], NEW_STATE) передавая явно указатель на объект (а не его номер).

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

Если посмотреть, то у set() есть два аргумента, первый константа, причем известная на этапе компиляции, второй переменная. Т.е. задача, выходит, сводится к тому, что бы подпихнуть эту константу и полностью скрыть первый аргумент. Выходит, что это должно быть две функции, собственно метод и его обертка.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 11:36
Рейтинг@Mail.ru


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