ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
27 ноября
161719 Топик полностью
Vladimir Ljaschko (19.07.2009 21:26, просмотров: 142) ответил Vladimir Ljaschko на Вопрос по добавлению состояния в машину состояний. Состояние описывается номером stMY_STATE, обработчиком fMyState(), и именем nm_my_state="my state_name". Может кто видел макросы, чтобы препроцессором автоматически сгенерировались enum для номеров,
Итак, итоги. Проблема пива сильно преувеличена, все прозрачно.  Создание описаний состояний машины состояний с помощью макросов на языке С. 1. Преамбула. При реализации алгоритма функционирования прибора с помощью машины состояний существует проблема удобной записи параметров состояния. К параметрам обычно относятся: - Номер состояния - Вектор обработчика - Текстовая информация (например, текст выводимый на экран) - Вспомогательная информация (например, необходимость очистки экрана) Проблема заключается в том, что, с одной стороны, описания всех параметров состояния должны быть расположены рядом , с другой стороны, параметры должны быть включены в разнородные элементы программы, а с третьей стороны, добавление и удаление состояний и изменение порядка следования должно быть простым. Так, номер состояния должен включаться в перечисление enum для удобного добавления и удаления состояний, вектора функций обработки состояний должны включаться в массив указателей на функции, текстовая информация должна включаться в массив текстовых строк, вспомогательная информация обычно включается в массив целых значений. Количество состояний машины состояний зависит от сложности процесса и в среднем по функциональности приборе легко достигает сотни. Задача: не усложняя понимание и поиск ошибок при компиляции, не используя пиво для вхождения в режим прозрачности, выбрать наиболее оптимальный путь реализации. 2. Амбула. 2.1. Составляем список параметров состояния. Допустим, в нашей машине состояний требуется иметь: - Номер состояния - Обработчик состояния - Текст на английском языке - Текст на немецком языке 2.2. Выбираем название макроса и последовательность перечисления всех параметров UI_STATE (ui_state, ui_fun, ui_eng, ui_germ) 2.3. Записываем все состояния в одном отдельном файле ui_states.h в виде: UI_STATE (stRestart ,fRestart ,"Restart" ,"Neustart" ) UI_STATE (stSelfTest ,fSelfTest ,"Self-test" ,"Selbsttest" ) UI_STATE (stWaiting ,fWaiting ,"Ready" ,"Bereit" ) UI_STATE (stError ,fError , "Error" ,"Fehler" ) UI_STATE (stLowPower ,fLowPower , "Low power" ,"Unterspannung" ) UI_STATE (stUserMenu ,fUserMenu ,"extended funct" ,"erweit. Funkt." ) UI_STATE (stBacklight ,fBacklight ,"Backlight" ,"Displ.-Beleucht.") UI_STATE (stSound ,fSound , "Sound" ,"Signalton" ) UI_STATE (stStatistic ,fViewStat ,"Statistic" ,"Statistik" ) Как видно в предыдущей строке, исходя из некоторых соображений, используется раздельное определение номера состояния и функции обработчика. Второй вариант записи, с помощью единого названия состояния, приведен ниже: UI_STATE (Restart ,"Restart" ,"Neustart" ) UI_STATE (SelfTest ,"Self-test" ,"Selbsttest" ) UI_STATE (Waiting ,"Ready" ,"Bereit" ) 2.4. Далее в нужном месте программы (обычно это заголовочный файл машины состояний) включаем enum: enum { #define UI_STATE (ui_state, ui_fun, ui_eng, ui_germ) ui_state , #include "ui_states.h" #undef UI_STATE stQty }; Таким образом номера состояний определены. 2.5.Для формирования массива обработчиков используем запись: typedef void (*VECTORS)(); const VECTORS function[stQty] = { #define UI_STATE (ui_st, ui_fun, ui_eng, ui_germ) ui_fun , #include "ui_states.h" #undef UI_STATE }; 2.5. Для формирования двумерного массива текстовых строк используем запись: #define langQty 2 const char * const st_name[langQty][stQty]= { { #define UI_STATE (ui_state, ui_fun, ui_eng, ui_germ) ui_engl, #include "ui_states.h" #undef UI_STATE },{ #define UI_STATE (ui_state, ui_fun, ui_eng, ui_germ) ui_germ, #include "ui_states.h" #undef UI_STATE } }; 2.6. Ну и в варианте одного названия состояния и префиксов st и fn соответствующие строки выглядят так: #define UI_STATE (state, ui_eng, ui_germ) st##state , #define UI_STATE (state, ui_eng, ui_germ) fn##state,