Ignore:
Timestamp:
05/23/12 17:02:12 (12 years ago)
Author:
tbretz
Message:
Removed the target state stuff the Configuration and Transition callback; added Wrapper functions for events without return code; added CreateService and Subscribe for subscribing to services as events.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/StateMachineImp.cc

    r13217 r13834  
    515515// --------------------------------------------------------------------------
    516516//
    517 //! Returns a pointer to a newly allocated object of base EventImp.
    518 //! It is meant to be overloaded by derived classes to create their
    519 //! own kind of events.
    520 //!
    521 //! @param targetstate
    522 //!    Defines the target state of the new transition. If \b must be
    523 //!    greater or equal zero. A negative target state is used to flag
    524 //!    commands which do not initiate a state transition. If this is
    525 //!    desired use AddEvent instead.
     517//! Calling this function, a new (named) event is added to the state
     518//! machine. Via a call to CreateEvent a new event is created with the
     519//! given targetstate, name and format.
     520//!
     521//! The allowed states are passed to the new event and a message
     522//! is written to the output-stream.
    526523//!
    527524//! @param name
     
    529526//!    will be constructed with the name given to the constructor and this
    530527//!    name, e.g. "DRIVE/CHANGE_STATE_TO_NEW_STATE"
     528//!
     529//! @param states
     530//!    A comma sepeareted list of ints, e.g. "1, 4, 5, 9" with states
     531//!    in which this new state transition is allowed and will be accepted.
    531532//!
    532533//! @param fmt
     
    536537//!    received commands is properly extracted. No check is done.
    537538//
    538 EventImp *StateMachineImp::CreateEvent(int targetstate, const char *, const char *)
    539 {
    540     return new EventImp(targetstate);
     539EventImp &StateMachineImp::AddEvent(const char *name, const char *states, const char *fmt)
     540{
     541    EventImp *evt = CreateEvent(name, fmt);
     542
     543    evt->AddAllowedStates(states);
     544
     545#ifdef DEBUG
     546    Out() << ":   " << Time().GetAsStr("%H:%M:%S.%f");
     547    Out() << " - Adding command " << evt->GetName();
     548    Out() << endl;
     549#endif
     550
     551    fListOfEvents.push_back(evt);
     552
     553    return *evt;
    541554}
    542555
     
    544557//
    545558//! Calling this function, a new (named) event is added to the state
    546 //! machine. Via a call to CreateEvent a new event is created with the
    547 //! given targetstate, name and format.
    548 //!
    549 //! The allowed states are passed to the new event and a message
    550 //! is written to the output-stream.
    551 //!
    552 //! @param targetstate
    553 //!    Defines the target state (or name) of the new event. If \b must be
    554 //!    greater or equal zero. A negative target state is used to flag
    555 //!    commands which do not initiate a state transition. If this is
    556 //!    desired use the unnamed version of AddEvent instead.
     559//! machine. Therefore an instance of type DimEvent is created and added
     560//! to the list of available commands fListOfEvents.
    557561//!
    558562//! @param name
     
    561565//!    name, e.g. "DRIVE/CHANGE_STATE_TO_NEW_STATE"
    562566//!
    563 //! @param states
    564 //!    A comma sepeareted list of ints, e.g. "1, 4, 5, 9" with states
    565 //!    in which this new state transition is allowed and will be accepted.
     567//! @param s1, s2, s3, s4, s5
     568//!    A list of states from which a transition to targetstate is allowed
     569//!    by this command.
     570//
     571EventImp &StateMachineImp::AddEvent(const char *name, int s1, int s2, int s3, int s4, int s5)
     572{
     573    ostringstream str;
     574    str << s1 << ' '  << s2 << ' ' << s3 << ' ' << s4 << ' ' << s5;
     575    return AddEvent(name, str.str().c_str(), "");
     576}
     577
     578// --------------------------------------------------------------------------
     579//
     580//! Calling this function, a new (named) event is added to the state
     581//! machine. Therefore an instance of type DimEvent is created and added
     582//! to the list of available commands fListOfEvents.
     583//!
     584//! @param name
     585//!    The command name which should initiate the transition. The DimCommand
     586//!    will be constructed with the name given to the constructor and this
     587//!    name, e.g. "DRIVE/CHANGE_STATE_TO_NEW_STATE"
    566588//!
    567589//! @param fmt
     
    570592//!    DimCommand object. However, the user must make sure that the data of
    571593//!    received commands is properly extracted. No check is done.
    572 //
    573 EventImp &StateMachineImp::AddEvent(int targetstate, const char *name, const char *states, const char *fmt)
    574 {
    575     EventImp *evt = CreateEvent(targetstate, name, fmt);
    576 
    577     evt->AddAllowedStates(states);
    578 
    579 #ifdef DEBUG
    580     Out() << ":   " << Time().GetAsStr("%H:%M:%S.%f");
    581     Out() << " - Adding command " << evt->GetName();
    582     if (evt->GetTargetState()>=0)
    583         Out() << " (transition to " << GetStateDescription(evt->GetTargetState()) << ")";
    584     Out() << endl;
    585 #endif
    586 
    587     fListOfEvents.push_back(evt);
    588 
    589     return *evt;
    590 }
    591 
    592 // --------------------------------------------------------------------------
    593 //
    594 //! Calling this function, a new (named) event is added to the state
    595 //! machine. Therefore an instance of type DimEvent is created and added
    596 //! to the list of available commands fListOfEvents.
    597 //!
    598 //! @param targetstate
    599 //!    Defines the target state (or name) of the new event. If \b must be
    600 //!    greater or equal zero. A negative target state is used to flag
    601 //!    commands which do not initiate a state transition. If this is
    602 //!    desired use the unnamed version of AddEvent instead.
    603 //!
    604 //! @param name
    605 //!    The command name which should initiate the transition. The DimCommand
    606 //!    will be constructed with the name given to the constructor and this
    607 //!    name, e.g. "DRIVE/CHANGE_STATE_TO_NEW_STATE"
    608594//!
    609595//! @param s1, s2, s3, s4, s5
     
    611597//!    by this command.
    612598//
    613 EventImp &StateMachineImp::AddEvent(int targetstate, const char *name, int s1, int s2, int s3, int s4, int s5)
     599EventImp &StateMachineImp::AddEvent(const char *name, const char *fmt, int s1, int s2, int s3, int s4, int s5)
    614600{
    615601    ostringstream str;
    616602    str << s1 << ' '  << s2 << ' ' << s3 << ' ' << s4 << ' ' << s5;
    617     return AddEvent(targetstate, name, str.str().c_str(), "");
    618 }
    619 
    620 // --------------------------------------------------------------------------
    621 //
    622 //! Calling this function, a new (named) event is added to the state
    623 //! machine. Therefore an instance of type DimEvent is created and added
    624 //! to the list of available commands fListOfEvents.
    625 //!
    626 //! @param targetstate
    627 //!    Defines the target state (or name) of the new event. If \b must be
    628 //!    greater or equal zero. A negative target state is used to flag
    629 //!    commands which do not initiate a state transition. If this is
    630 //!    desired use the unnamed version of AddEvent instead.
    631 //!
    632 //! @param name
    633 //!    The command name which should initiate the transition. The DimCommand
    634 //!    will be constructed with the name given to the constructor and this
    635 //!    name, e.g. "DRIVE/CHANGE_STATE_TO_NEW_STATE"
    636 //!
    637 //! @param fmt
    638 //!    A format as defined by the dim system can be given for the command.
    639 //!    However, it has no real meaning except that it is stored within the
    640 //!    DimCommand object. However, the user must make sure that the data of
    641 //!    received commands is properly extracted. No check is done.
    642 //!
    643 //! @param s1, s2, s3, s4, s5
    644 //!    A list of states from which a transition to targetstate is allowed
    645 //!    by this command.
    646 //
    647 EventImp &StateMachineImp::AddEvent(int targetstate, const char *name, const char *fmt, int s1, int s2, int s3, int s4, int s5)
    648 {
    649     ostringstream str;
    650     str << s1 << ' '  << s2 << ' ' << s3 << ' ' << s4 << ' ' << s5;
    651     return AddEvent(targetstate, name, str.str().c_str(), fmt);
    652 }
    653 
    654 // --------------------------------------------------------------------------
    655 //
    656 //! This function calls AddEvent with a target-state of -1 (unnamed
    657 //! event). This shell be used for configuration commands. As well as
    658 //! in AddEvent the states in which such a configuration command is
    659 //! accepted can be given.
    660 //!
    661 //! @param name
    662 //!    The command name which should initiate the transition. The DimCommand
    663 //!    will be constructed with the name given to the constructor and this
    664 //!    name, e.g. "DRIVE/CHANGE_STATE_TO_NEW_STATE"
    665 //!
    666 //! @param states
    667 //!    A comma sepeareted list of ints, e.g. "1, 4, 5, 9" with states
    668 //!    in which this new state transition is allowed and will be accepted.
    669 //!
    670 //! @param fmt
    671 //!    A format as defined by the dim system can be given for the command.
    672 //!    However, it has no real meaning except that it is stored within the
    673 //!    DimCommand object. However, the user must make sure that the data of
    674 //!    received commands is properly extracted. No check is done.
    675 //!
    676 EventImp &StateMachineImp::AddEvent(const char *name, const char *states, const char *fmt)
    677 {
    678     return AddEvent(-1, name, states, fmt);
    679 }
    680 
    681 // --------------------------------------------------------------------------
    682 //
    683 //! This function calls AddEvent with a target-state of -1 (unnamed
    684 //! event). This shell be used for configuration commands. As well as
    685 //! in AddEvent the states in which such a configuration command is
    686 //! accepted can be given.
    687 //!
    688 //! @param name
    689 //!    The command name which should initiate the transition. The DimCommand
    690 //!    will be constructed with the name given to the constructor and this
    691 //!    name, e.g. "DRIVE/CHANGE_STATE_TO_NEW_STATE"
    692 //!
    693 //! @param s1, s2, s3, s4, s5
    694 //!    A list of states from which a transition to targetstate is allowed
    695 //!    by this command.
    696 //
    697 EventImp &StateMachineImp::AddEvent(const char *name, int s1, int s2, int s3, int s4, int s5)
    698 {
    699     return AddEvent(-1, name, s1, s2, s3, s4, s5);
    700 }
    701 
    702 // --------------------------------------------------------------------------
    703 //
    704 //! This function calls AddEvent with a target-state of -1 (unnamed
    705 //! event). This shell be used for configuration commands. As well as
    706 //! in AddEvent the states in which such a configuration command is
    707 //! accepted can be given.
    708 //!
    709 //! @param name
    710 //!    The command name which should initiate the transition. The DimCommand
    711 //!    will be constructed with the name given to the constructor and this
    712 //!    name, e.g. "DRIVE/CHANGE_STATE_TO_NEW_STATE"
    713 //!
    714 //! @param fmt
    715 //!    A format as defined by the dim system can be given for the command.
    716 //!    However, it has no real meaning except that it is stored within the
    717 //!    DimCommand object. However, the user must make sure that the data of
    718 //!    received commands is properly extracted. No check is done.
    719 //!
    720 //! @param s1, s2, s3, s4, s5
    721 //!    A list of states from which a transition to targetstate is allowed
    722 //!    by this command.
    723 //
    724 EventImp &StateMachineImp::AddEvent(const char *name, const char *fmt, int s1, int s2, int s3, int s4, int s5)
    725 {
    726     return AddEvent(-1, name, fmt, s1, s2, s3, s4, s5);
     603    return AddEvent(name, str.str().c_str(), fmt);
     604}
     605
     606EventImp *StateMachineImp::CreateService(const char *)
     607{
     608    return new EventImp();
     609}
     610
     611// --------------------------------------------------------------------------
     612//
     613EventImp &StateMachineImp::Subscribe(const char *name)
     614{
     615    EventImp *evt = CreateService(name);
     616    fListOfEvents.push_back(evt);
     617    return *evt;
    727618}
    728619
     
    900791//
    901792bool StateMachineImp::HandleNewState(int newstate, const EventImp *evt,
    902                                      const char *txt, const char *alt)
     793                                     const char *txt)
    903794{
    904795    if (newstate==kSM_FatalError)
     
    908799        return true;
    909800
    910     if (!evt || !alt || newstate==evt->GetTargetState())
    911         SetCurrentState(newstate, txt, evt ? evt->GetName() : "");
    912     else
    913         SetCurrentState(newstate, alt, evt->GetName());
     801    SetCurrentState(newstate, txt, evt ? evt->GetName() : "");
    914802
    915803    return true;
     
    954842bool StateMachineImp::HandleEvent(const EventImp &evt)
    955843{
     844    if (!evt.HasFunc())
     845    {
     846        Warn(evt.GetName()+": No function assigned... ignored.");
     847        return true;
     848
     849    }
     850
     851#ifdef DEBUG
    956852    ostringstream out;
    957853    out << "Handle: " << evt.GetName() << "[" << evt.GetSize() << "]";
    958854    Debug(out);
    959 
    960     // Get the new state from the command
    961     const int commandstate = evt.GetTargetState();
     855#endif
    962856
    963857    // Check if the received command is allow in the current state
    964858    if (!evt.IsStateAllowed(fCurrentState))
    965859    {
    966         ostringstream msg;
    967         msg << evt.GetName() << ": Not allowed in state ";
    968         msg << GetStateDescription() << "... ignored.";
    969         Warn(msg);
     860        Warn(evt.GetName()+": Not allowed in state "+GetStateDescription()+"... ignored.");
    970861        return true;
    971862    }
    972863
    973     if (evt.HasFunc())
    974         return HandleNewState(evt.ExecFunc(), &evt,
    975                               "by ExecFunc function-call");
    976 
    977     // Check if this is a configuration command (a command which
    978     // intention is not to change the state of our state-machine
    979     if (commandstate<0)
    980         return HandleNewState(Configure(evt), &evt, "by Configure-command");
    981     else
    982         return HandleNewState(Transition(evt), &evt,
    983                               "by Transition-command (expected)",
    984                               "by Transition-command (unexpected)");
    985 
    986     // This is a fatal error, because it can never happen
    987     return false;
     864    return HandleNewState(evt.ExecFunc(), &evt,
     865                          "by ExecFunc function-call");
    988866}
    989867
     
    1095973
    1096974            // Execute a step in the current state of the state machine
    1097             if (!HandleNewState(Execute(), "by Execute-command"))
     975            if (!HandleNewState(Execute(), 0, "by Execute-command"))
    1098976                break;
    1099977
Note: See TracChangeset for help on using the changeset viewer.