ReAl (17.07.2009 13:30, просмотров: 189) ответил Vladimir Ljaschko на Вопрос по добавлению состояния в машину состояний. Состояние описывается номером stMY_STATE, обработчиком fMyState(), и именем nm_my_state="my state_name". Может кто видел макросы, чтобы препроцессором автоматически сгенерировались enum для номеров,
Я в, похоже, таком направлении начинал двигаться, но решил, что если вдруг пиво пить перестану - то потом сам не разберусь (т.к. для разбирательства нужна будет та же доза пива, что при написании была). Поскольку пиво я уже скоро десять лет как не пью - решение было правильным :-) Я предпочитаю более "локальные" генерирующие макросы в духе
#define GENERATE_ACCESS(T) \
uint8_t ee_read_##T( T##_t *dst) { return ee_read_check( dst, &ee_##T , sizeof(ee_##T##_t)); } \
uint8_t ee_write_##T( const T##_t *src) { return ee_upd_write( src, &ee_##T , sizeof(ee_##T##_t)); }
GENERATE_ACCESS(record1)
GENERATE_ACCESS(record2)
GENERATE_ACCESS(record3)и внутри явно написанного switch() как вхождения тоже макросы-строки. Писанины немного больше, но обозримее структура.
Внимание, вопрос - уже имея в арсенале такое, как было приведено, почему не реализовать что-то около такое
#define STATE_PROLOG(mach) typedef enum {
#define STATE_ENTRY(mach, code, str) mach##_##code,
#define STATE_EPILOG(mach) mach##_states } mach##_state_t;
#include "machine1_state_impl.c"
#undef STATE_PROLOG
#undef STATE_ENTRY
#undef STATE_EPILOG
#define STATE_PROLOG(mach)
#define STATE_ENTRY(mach, code, str) __flash char mach##_##code##_name[] = str ;
#define STATE_EPILOG(mach)
#include "machine1_state_impl.c"
#undef STATE_PROLOG
#undef STATE_ENTRY
#undef STATE_EPILOG
#define STATE_PROLOG(mach) __flash state_struct_t mach##_table[mach##_states] = {
#define STATE_ENTRY(mach, code, str) { do_##mach##_##code, mach##_##code##_name},
#define STATE_EPILOG(mach) };
#include "machine1_state_impl.c"
#undef STATE_PROLOG
#undef STATE_ENTRY
#undef STATE_EPILOGКажется, ничего не забыл. enum кодов состояний формируется, строки имён тоже, массив структур { указатель_на_функцию, указатель_на_строку_имени } тоже. Порядок в enum и в массиве структур совпадает, зависит от порядка в machine1_state_impl.c
C99 не нужен.
Ну и дальше для поддержки
// ну возвращаться что-то может и стандартные аргументы могут быть, естественно
#define STATE_FUNCTION(mach,code) void do_##mach##_##code (void)
STATE_FUNCTION(machine1,state1)
{
// тута что надо
}
У меня до необходимости такого не доходило ещё, по мелочам шлёпаю врукопашную, на "если что" - давно ссылка cog припасена.