SORU
25 EYLÜL 2008, PERŞEMBE


Tipik durum makinesi uygulaması bir desen var mı?

Basit bir devlet makinesi, hayata geçirmek için ihtiyacımız varC.< / ^ br . Standart bir switch deyimi en iyi yol nedir?< / ^ br . Geçerli bir eyalet (state) ve geçiş için bir tetikleyici var.


switch(state)
{
  case STATE_1:
     state = DoState1(transition);
     break;
  case STATE_2:
     state = DoState2(transition);
     break;
}
...
DoState2(int transition)
{
   // Do State Work
   ...
   if(transition == FROM_STATE_2) {
     // New state when doing STATE 2 -> STATE 2
   }
   if(transition == FROM_STATE_1) {
    // New State when moving STATE 1 -> STATE 2
   }
   return new_state;
}

Daha iyi bir yolu yokturbasit durum makineleri için

EDİT: C Statechart kütüphane gitmek için yol olabilir Artırma düşünüyorum. Ancak, öyledeğilC. yardım C kullanın davaya konsantre Sağlar.

CEVAP
25 EYLÜL 2008, PERŞEMBE


Çoğu durum makineleri için tablo odaklı bir yaklaşım kullanmayı tercih ederim:

typedef enum { STATE_INITIAL, STATE_FOO, STATE_BAR, NUM_STATES } state_t;
typedef struct instance_data instance_data_t;
typedef state_t state_func_t( instance_data_t *data );

state_t do_state_initial( instance_data_t *data );
state_t do_state_foo( instance_data_t *data );
state_t do_state_bar( instance_data_t *data );

state_func_t* const state_table[ NUM_STATES ] = {
    do_state_initial, do_state_foo, do_state_bar
};

state_t run_state( state_t cur_state, instance_data_t *data ) {
    return state_table[ cur_state ]( data );
};

int main( void ) {
    state_t cur_state = STATE_INITIAL;
    instance_data_t data;

    while ( 1 ) {
        cur_state = run_state( cur_state, &data );

        // do other program logic, run other state machines, etc
    }
}

Bu tabii ki durum makineleri, vb birden fazla desteklemek için uzatılabilir. Geçiş eylemleri olarak hizmet edilebilir:

typedef void transition_func_t( instance_data_t *data );

void do_initial_to_foo( instance_data_t *data );
void do_foo_to_bar( instance_data_t *data );
void do_bar_to_initial( instance_data_t *data );
void do_bar_to_foo( instance_data_t *data );
void do_bar_to_bar( instance_data_t *data );

transition_func_t * const transition_table[ NUM_STATES ][ NUM_STATES ] = {
    { NULL,              do_initial_to_foo, NULL },
    { NULL,              NULL,              do_foo_to_bar },
    { do_bar_to_initial, do_bar_to_foo,     do_bar_to_bar }
};

state_t run_state( state_t cur_state, instance_data_t *data ) {
    state_t new_state = state_table[ cur_state ]( data );
    transition_func_t *transition =
               transition_table[ cur_state ][ new_state ];

    if ( transition ) {
        transition( data );
    }

    return new_state;
};

Tablo yaklaşımıyla korumak ve genişletmek için daha kolay ve daha basit bir harita için durum diyagramları.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • DanceOn

    DanceOn

    6 Mayıs 2006
  • kndx

    kndx

    11 Mart 2006
  • Simon Hayter

    Simon Hayter

    20 HAZİRAN 2010