Покритикуйте велосипед
От: Аноним  
Дата: 25.07.13 11:01
Оценка: -1
Общая часть
struct StateCallback { 
    typedef void (*cb_fn)(void*,int); cb_fn cb; void* ctx; 
    StateCallback(cb_fn cb=0,void *ctx=0) : cb(cb), ctx(ctx) {}
    void operator() (int s) { if (cb) cb(ctx,s); }
    operator bool() { return !!cb; }
};
struct ChangeStateCallback { 
    typedef void (*cb_fn)(void*,int,int); cb_fn cb; void* ctx; 
    ChangeStateCallback(cb_fn cb=0,void *ctx=0) : cb(cb), ctx(ctx) {}
    void operator() (int a,int b) { if (cb) cb(ctx,a,b); }
    operator bool() { return !!cb; }
};
template<class ST,class T> struct FSM : ST {
    FSM() { pstate=-1; state=0; for(int i=0;i<ST::stMAX;++i) vst[i]=nop; }
    void step() { 
        if (pstate!=state) {
            if (pstate>=0) {
                leave(pstate);
                change(pstate,state);
            }
            enter(state);
            pstate=state;
        }
        int saved_state=state;
        before(state);
        vst[state]((T*)this); 
        after(saved_state);
    }
    int  getState() { return state; }
    void setState(int s) { state=s; }
    ChangeStateCallback change;
    StateCallback leave, enter, before, after;
    ChangeStateCallback operator() (void (*cb)(T* p,int a,int b)) { 
        return ChangeStateCallback((ChangeStateCallback::cb_fn)cb,this); 
    }
    StateCallback operator() (void (*cb)(T* p,int a)) { 
        return StateCallback((StateCallback::cb_fn)cb,this); 
    }
protected:
    typedef void (*vst_fn)(T*);
    int pstate, state; vst_fn vst[ST::stMAX];
    static void nop(T*) {}
};


Пример объявления конкретной FSM
// header
struct States { enum { st_S0, st_S1, st_S2, stMAX }; };
struct FSM1 : FSM<States,FSM1> {
    int n0, n1, n2;
    FSM1();
    const char* getName(int s) { return names[s]; }
private:
    const char* names[stMAX];
};

// implementation
FSM1::FSM1() {
    struct A {
        static void S0(FSM1 *p) {
            p->n0++;
            int st=p->getState();
            p->setState(st_S2);
        }
        static void S1(FSM1 *p) {
            p->n1++;
            if (p->n1>3) p->setState(st_S0);
        }
        static void S2(FSM1 *p) {
            p->n2++;
            if (p->n2>2) p->setState(st_S1);
        }
    };
    n0=0; n1=0; n2=0;
    vst[st_S0]=A::S0; 
    vst[st_S1]=A::S1;
    vst[st_S2]=A::S2;
    for(int i=0;i<stMAX;++i) names[i]="unknown";
    names[st_S0]="S0";
    names[st_S1]="S1";
    names[st_S2]="S2";
}


Как используется:
#include <stdio.h>
int main(int argc,char** argv) {
    FSM1 sm;
    struct Hook {
        static void change(FSM1* p,int s1,int s2) {
            const char *n1, *n2;
            n1=p->getName(s1);
            n2=p->getName(s2);
            printf("%s->%s\n",n1,n2);
        }
        static void enter (FSM1* p,int s) { printf("\t%s{ ",p->getName(s)); }
        static void leave (FSM1* p,int s) { printf(" }%s\n",p->getName(s)); }
        static void before(FSM1* p,int s) { printf("(%s",p->getName(s)); }
        static void after (FSM1* p,int s) { printf(")"); }
    };
    sm.change=sm(Hook::change);
    sm.enter =sm(Hook::enter);
    sm.leave =sm(Hook::leave);
    sm.before=sm(Hook::before);
    sm.after =sm(Hook::after);
    for(int i=0;i<15;++i) sm.step();
    printf("\n");
    return 0;
}

Вобщем простенький конечный автомат. Жду критику
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.