This library is designed to create and run state graphs. It supports hierarchical states and parallel states execution.

utt_parallel_states_ud.h

Committer:
martin13
Date:
2019-02-12
Revision:
3:d4d69d0d8381
Parent:
0:f4fdca2c4c67

File content as of revision 3:d4d69d0d8381:

#ifndef __UTT_PARALLEL_STATES_UD_H__
#define __UTT_PARALLEL_STATES_UD_H__

#include "ParallelStateMachine.h"

class Foo : public State{

public:

    Foo(const char* uuid, UserData *ud):
        State(uuid),
        _count(0)
    {
        _data = ud->get<DataInt32*>("COUNT");
    }
    
    virtual void onEntry(){
        _count = _data->getData();
    }
    
    virtual const char* onExecute(){
        _count++;
        return "BAR";
    }
    
    virtual void onExit(){
        _data->setData(_count);
    }
        
private:
    int _count;
    DataInt32 *_data;
};

class Bar : public State{

public:

    Bar(const char* uuid, UserData *ud):
      State(uuid)
    {
        _data = ud->get<DataInt32*>("COUNT");
    }
    
    virtual void onEntry(){
    }
    
    virtual const char* onExecute(){
        
        printf("%s %i \n", getUUID(), _data->getData());
        
        if (_data->getData() >= 20){
            return SUCCEDED;    
        }
        
        return "FOO";
    }
    
    virtual void onExit(){    
    }
    
private:
    DataInt32 *_data;
};


class FooBar : public StateMachine{

public:

    FooBar(const char* uuid, UserData *ud):
        StateMachine(uuid, ud),
        foo(NULL), bar(NULL)
    {
        Foo *foo = this->Instance<Foo>("FOO");
        Bar *bar = this->Instance<Bar>("BAR");
        
        this->connect(STATE(foo), "BAR", STATE(bar));
        
        this->connect(STATE(bar), "FOO", STATE(foo));
        this->connect(STATE(bar), "SUCCEDED", "SUCCEDED");
        
        this->setInitialState(STATE(foo)); 
    }
    
private:
    Foo *foo;
    Bar *bar;
};

class ParallelFooBar : public ParallelStateMachine{

public:
      
    ParallelFooBar(const char* uuid, UserData* ud):
        ParallelStateMachine(uuid, ud){
        
        _data = new DataInt32(0);
        getUserData()->put("COUNT", _data);
        
        FooBar *foobar1 = Instance<FooBar>("FOO_BAR_1");
        FooBar *foobar2 = Instance<FooBar>("FOO_BAR_2");
        
        this->attachOutcomesResolver(this, &ParallelFooBar::resolveOutcomes);
    }
    
    
    virtual void onEntry(){
        _data->setData(0);
    }
    
    const char* resolveOutcomes(const char **outcomes, int nb_outcomes){
        
        for( int i=0; i < nb_outcomes; i++){
            
            if(strcmp(outcomes[i], "SUCCEDED") != 0){
                return "ABORTED";
            }
        }
        
        return "SUCCEDED";
    }
    
private:
    DataInt32* _data;
};

InterruptIn button(PC_13);
DigitalOut led(LED1);

void unit_test(){
    
    StateMachine root("ROOT");
    
    button.rise(&root, &StateMachine::preempt);
    
    ParallelFooBar* pfb = root.Instance<ParallelFooBar>("PARALLEL_FOOBAR");
    
    root.connect(STATE(pfb), "SUCCEDED", STATE(pfb));
    
    root.setInitialState(STATE(pfb));
    
    root.printGraph();
    
    printf("PARALLEL SM RETURN %s\n",root.execute());
    
}

#endif /* #ifndef __UTT_PARALLEL_STATES_UD_H__*/