ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C++] Boost MSM(Meta State Machine) 이란?
    C++ 2024. 5. 24. 11:38

    BOOST란?

    C++ 기반의 템플릿 라이브러리의 집합.

    오픈소스로 MIT 라이선스와 비슷하게 독자적인 라이선스를 따른다.

    간단히 얘기해서 C++에서 쓰이는 검증된 오픈 소스 라이브러리의 집합.

    C++ 개발자는 거의 필수적으로 설치해야됨.

     

    #include<boost/msm/back/state_machine.hpp>

     

    이런식으로 헤더 파일을 선언하여 사용

     

    BOOST MSM 이란?

    Boost.MSM(Meta State Machine) 의 줄임말

    C++에서 상태 기계를 구현하기 위한 라이브러리.

    상태 기계(State Machine)이란 다양한 상태와 상태 간의 전이(transition)를 정의하고 관리하는데 사용됨.

    복잡한 상태 기계의 구현을 쉽게 하게 도와주고 코드의 가독성과 유지보수성을 높혀줌.

     

    쉬운말로 정리하자면, 

    현실에서 어떤 기계가 있고 그 기계를 C++ 코드로 제어할 때,

    boost.msm 라이브러리를 이용해서그 기계가 동작하는 일련의 과정들을

    상태, 이벤트, 전이, 동작으로 구분해서 코드를 짠다는 이야기다.

     

    상태(State)

    상태기계의 각 상태를 정의.

    ex) 자동 판매기의 상태로는 "Idle", "Waiting for Coin", "Dispensing Item" 등이 있을 수 있다.

     

    사건(Event)

    상태 간의 전이를 유발하는 사건.

    외부로부터 발생할 수도 있고, 시스템 내부에서 발생할 수도 있다.

    ex) 사용자가 자동 판매기에 동전을 넣는다.

     

    전이(Transition)

    하나의 상태에서 상태로의 변화를 정의.

    특정 이벤트에 의해서 발생함.

    ex) "Idle" 상태에서 "Coin Inserted" 이벤트가 발생하고 "Waiting for Coin" 상태로 전이

     

    동작(Action)

    상태 전이 중에 실행되는 작업

    ex) "Coin Inserted" 이벤트가 발생하면 "동전 감지" 동작이 실행

     

    기본적으로

    BOOST_MSM_EUML_EVENT // 이벤트
    BOOST_MSM_EUML_STATE // 상태
    BOOST_MSM_EUML_ACTION // 동작
    BOOST_MSM_EUML_TRANSITION_TABLE // 전이 테이블
    BOOST_MSM_EUML_DECLARE_STATE_MACHINE // 상태 기계

    다섯 가지를 정의해서 예시를 작성해보려고 한다.

    그리고 이벤트, 상태, 동작은 전이 테이블이 만들어지기 전에 

    먼저 선언해줘야 전이테이블은 작성하여 상태가 전이를 설정할 수 있다.

     

     

    자동 판매기 예시 코드,

    #include <boost/msm/front/euml/euml.hpp>
    #include <boost/msm/front/state_machine_def.hpp>
    #include <boost/msm/back/state_machine.hpp>
    #include <iostream>
    
    namespace msm = boost::msm;
    namespace mpl = boost::mpl;
    using namespace msm::front::euml;
    
    // 이벤트(EVENT) 정의
    BOOST_MSM_EUML_EVENT(SelectItem)
    BOOST_MSM_EUML_EVENT(InsertMoney)
    BOOST_MSM_EUML_EVENT(DispenseComplete)
    
    // 상태(STATE) 정의
    BOOST_MSM_EUML_STATE((Idle), IdleState)
    BOOST_MSM_EUML_STATE((WaitingForMoney), WaitingForMoneyState)
    BOOST_MSM_EUML_STATE((DispensingItem), DispensingItemState)
    
    // 동작(ACTION) 정의
    BOOST_MSM_EUML_ACTION(LogSelectItem) {
        template <class Event, class FSM, class STATE>
        void operator()(Event const&, FSM&, STATE&) {
            std::cout << "Action: Item Selected" << std::endl;
        }
    };
    
    BOOST_MSM_EUML_ACTION(LogInsertMoney) {
        template <class Event, class FSM, class STATE>
        void operator()(Event const&, FSM&, STATE&) {
            std::cout << "Action: Money Inserted" << std::endl;
        }
    };
    
    BOOST_MSM_EUML_ACTION(LogDispenseComplete) {
        template <class Event, class FSM, class STATE>
        void operator()(Event const&, FSM&, STATE&) {
            std::cout << "Action: Dispense Complete" << std::endl;
        }
    };
    
    BOOST_MSM_EUML_ACTION(AdditionalAction) {
        template <class Event, class FSM, class STATE>
        void operator()(Event const&, FSM&, STATE&) {
            std::cout << "Additional Action Executed" << std::endl;
        }
    };
    
    // 전이 테이블 정의
    BOOST_MSM_EUML_TRANSITION_TABLE((
        IdleState + SelectItem / (LogSelectItem, AdditionalAction) == WaitingForMoneyState,
        WaitingForMoneyState + InsertMoney / LogInsertMoney == DispensingItemState,
        DispensingItemState + DispenseComplete / (LogDispenseComplete, AdditionalAction) == IdleState
    ), transition_table)
    
    // 상태 기계 정의
    BOOST_MSM_EUML_DECLARE_STATE_MACHINE((
        transition_table, 
        init_ << IdleState, 
        no_action, 
        no_action
    ), VendingMachineFSM_def)
    
    typedef msm::back::state_machine<VendingMachineFSM_def> VendingMachine;
    
    // 메인 함수
    int main() {
        VendingMachine vm;
        vm.start();
    
        // 상태 전이
        vm.process_event(SelectItem());        // 상태: Idle -> WaitingForMoney
        vm.process_event(InsertMoney());       // 상태: WaitingForMoney -> DispensingItem
        vm.process_event(DispenseComplete());  // 상태: DispensingItem -> Idle
    
        return 0;
    }

     

     

    전이 테이블(BOOST_MSM_EMUL_TRANSITION_TABLE)

    IdleState + SelectItem / (LogSelectItem, AdditionalAction) == WaitingForMoneyState

    이건

    현재 상태가 'IdleState' 일 때 'SelectItem' 이벤트가 발생하면 'LogSelectItem'과 'AdditionalAction'을 실행하고 'WaitingForMoneyState' 로 전이한다는 의미이다.

     

    WaitingForMoneyState + InsertMoney / LogInsertMoney == DispensingItemState

    이건

    현재 상태가 'WaitingForMoneyState' 일 때 'InsertMoney' 이벤트가 발생하면 'LogInsertMoney'를 실행하고 'DispensingItemState' 로 전이한다는 의미이다.

     

    DispensingItemState + DispenseComplete / (LogDispenseComplete, AdditionalAction) == IdleState

    이건

    현재 상태가 'DispensingItemState' 일 때 'DispenseComplete' 이벤트가 발생하면 'LogDispenseComplete' 와 'AdditionalAction'을 실행하고 'IdleState'로 전이한다는 의미이다.

     

    마지막의 transition_table은 테이블의 이름으로 Boost.MSM의 표준이다.

    이후 상태 기계를 정의할 때 전이 테이블을 참조할 수 있게 해줌

     

    상태 기계 정의(BOOST_MSM_EUML_DECLARE_STATE_MACHINE)

    transition_table // 전이 테이블을 참조

    init_ << IdleState // 초기 상태를 IdleState로 설정
    no_action // 전이 전 동작
    no_action // 전이 후 동작
    VendingMachineFSM_def // 상태 기계 정의 이름. 상태 기계 인스턴스화할 때 사용

    typedef msm::back::state_machine<VendingMachineFSM_def> VendingMachine; // 상태 기계 인스턴스화

    Boost.MSM의 'back' 네임스페이스에 있는 'state_machine' 클래스를 사용하여 인스턴스화

     

    EUML 이란?

    Boost.MSM의 Embedded UML(Unified Modeling Language).

    상태 기계를 정의하고 구현하는 과정을 단순화하고 구현하는 과정을 단순화하고 더 직관적으로 만들기 위한 도구

    BOOST_MSM_EUML_STATE 같은 다양한 매크로를 사양할 수 있게 함

     

    'C++' 카테고리의 다른 글

    [C++] __attribute__ 에 대해서  (0) 2024.06.27
    [C++] #pragma 란?  (0) 2024.06.27
Designed by Tistory.