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

 
 
> Как бы организовать в Сях аналог 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, 05:13
Сообщение #2


Гуру
******

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



Код
ui.led[0].mode = UI_LED_MODE_FLSH_SHRT;

А по таймеру смотреть состояния всех led и включать/выключать/мигать нужными.
Так не устроит? Что должна делать set()?
Go to the top of the page
 
+Quote Post
Tahoe
сообщение Jul 4 2015, 05:51
Сообщение #3


Местный
***

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



Цитата(adnega @ Jul 4 2015, 08:13) *
Что должна делать set()?

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

Код
void    SysTick_Handler(                    void                            )
{
    ....
    app.event.ui_key    =    ui_key_systick_hook(    &ui.key        );
    app.event.ui_led    =    ui_led_systick_hook(    &ui.led        );
    ....
}


Так выглядит hook:

Код
bool    ui_led_systick_hook(                ui_led_t *            p            )
{
    bool            resp    =    false;

    if( p->tick > 0 )
    {
        if( --(p->tick) == 0 )
        {
            ui_led_toggle();
            resp    =    true;
        }
    }

    return( resp );
}


Ну и, собственно, сам метод:

Код
void    ui_led_set(                            ui_led_t *            p,
                                    const    ui_led_mode_t        mode        )
{
    switch( mode )
    {
        case    UI_LED_MODE_OFF:
            bsp_led_set( false );
            break;

        case    UI_LED_MODE_ON:
            bsp_led_set( true );
            break;

        case    UI_LED_MODE_TOGGLE:
            ui_led_toggle();
            break;

        case    UI_LED_MODE_FLSH_LONG:
            if( p->tick == 0 )
            {
                ui_led_toggle();
            }
            p->tick        =    UI_LED_FLSH_LONG_TCKS;
            break;

        case    UI_LED_MODE_FLSH_SHRT:
            if( p->tick == 0 )
            {
                ui_led_toggle();
            }
            p->tick        =    UI_LED_FLSH_SHRT_TCKS;
            break;

        default:
            break;
    }
}


Хочу избавиться от передачи в функцию аргумента ui_led_t * p. Вместо этого, получать его локально, в зависимости от того, откуда пришел вызов функции. Т.е. вместо существующего сейчас:

Код
ui_led_set(  &ui.led0, UI_LED_MODE_FLSH_SHRT );
ui_led_set(  &ui.led[0], UI_LED_MODE_FLSH_SHRT );


вызывать, как написал в первом посте:

Код
ui.led[ 0 ].set(    UI_LED_MODE_FLSH_SHRT                    );


Но что-то мне подсказывает, что средствами языка, без хаков и извратов, сделать это не получится. Тогда, видимо, остается только вариант, описаный мною выше - добавить в структуру переменную n. Ну либо совсем чернуха, в духе ui_led_set_0(), ui_led_set_1()... sm.gif
Go to the top of the page
 
+Quote Post



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

 


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


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