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

 
 
> Как бы организовать в Сях аналог 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
adnega
сообщение Jul 4 2015, 07:30
Сообщение #4


Гуру
******

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



Цитата(Tahoe @ Jul 4 2015, 10:22) *
Т.е. задача, выходит, сводится к тому, что бы подпихнуть эту константу и полностью скрыть первый аргумент. Выходит, что это должно быть две функции, собственно метод и его обертка.

К сожалению я тоже не смог найти способа передавать аналог this, поэтому везде приходится таскать первый параметр в функциях (в тех же callback-ах).
Идеально было бы иметь аналог __LINE__, __FILE__, например, __THIS__ который бы заполнялся адресом вызывавшей структуры.
Но нигде такого не встречал. Может, знатоки знают про потайные места gcc?... на уровне компилятора это не сложно сделать.
Кста, это вряд ли будет стандарт Си, скорее какая-нить надстройка компилятора. Вам под компилятор какой если что?
Go to the top of the page
 
+Quote Post



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

 


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


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