2017-01-31 3 views
2

주 상태 시스템에 의해 조정되고 실행중인 작업에 대해 다른 하위 상태 시스템이있는 시스템을 구축하려고합니다. 오랫동안 Qt를 사용해 왔던 Qt 5.8에서 새로운 SCXML 구현을 살펴 보았습니다. 그러나 하위 상태 머신을 제대로 구현하기 위해 5.8과 함께 제공된 API를 사용하는 방법을 알 수는 없습니다.Qt 5.8 하위 상태 머신에서 SCXML 프레임 워크를 사용하는 방법은 무엇입니까?

제 아이디어는 주 상태 시스템을 사용하고 주 상태 시스템의 상태에서 특정 하위 상태 시스템을 호출하는 것입니다. 하위 상태 머신을 호출하는 동안 최상위 상태 머신 오브젝트가 invokedServicesChanged(..)을 방출 한 후 액세스하는 방법을 알아 내지 못했습니다. 관련 컴퓨터에 대해서가 아니라 QScxmlInvokableService에 대한 포인터에 액세스 할 수 있습니다.

또한 최상위 상태 컴퓨터 개체는 상태 및 이벤트를 맨 위에서 만 노출하고 호출 된 상태 컴퓨터에서는 노출하지 않습니다. 예를 들어 topLevelStateMachine->activeStateNames()은 최상위 상태 만 나열합니다.

Qt의 소스 코드를 보면 QScxmlInvokableService이 실제로 관련 상태 머신에 대한 포인터를 포함하고있는 QScxmlScxmlService의 기본 클래스라는 것을 알았습니다. 불행히도 QScxmlScxmlServiceqscxmlinvokableservice_p.h에 정의되어 있으며, 이름에 _p이 표시되어 있으므로 비공개입니다. 그렇다면 공용 SCXML API를 어떻게 사용해야합니까? 내가 놓친 게 있니? IIRC SCXML 지원은 5.7의 기술적 미리보기 였지만 이제는 정규 분포의 일부로 5.8에 포함됩니다.

+1

저는 이것이 API의 감독이라고 말하고 싶습니다. 자유롭게'QT + = scxml_private'를 프로젝트에 추가하고 구현 세부 사항을 사용하여 필요한 작업을 수행하십시오. 그 Qt 모듈은 꽤 새롭고 예, 유용한 것으로 만들기 위해 필요한 비트가 부족합니다. –

+0

"하위 상태 머신"이라고 할 때'.scxml' 상태 머신을 분리하거나 [복합 상태] (https://www.w3.org/TR/scxml/#N10192)를 말하고 있습니까? 전자의 경우 왜 후자가 아닌가? – Phrogz

+0

상태 머신이 분리되어 있습니다. 하나의 XML 파일에 대형 스테이트 머신을 가지는 것이 좋은 생각은 아니지만 이론 상으로는 복합 상태로 해결할 수 있다고 생각합니다. SCXML과 Qt를 사용하여 많은 하위 상태가있는 대형 상태 차트를 구성하는 방법은 무엇입니까? – Nils

답변

0

예를 들어 지난 주 동안 예제를 연구하고 나 자신의 상태 시스템과 그에 응답하는 코드를 작성했습니다. 문서화가 가능한 한 명확하지 않기 때문에 시간이 걸렸습니다.

나는 activeStateNames이 상태 기계에 포함 된 모든 상태 (하위 상태 포함)를 검색한다는 것을 발견했습니다.

숫자를 얻으려면 traffic light example을 읽는 데 몇 달이 걸렸습니다. 핵심은 하위 상태 머신이 특정 상태에 포함되어 있다는 것입니다. 상태 머신의 그래픽보기는 여기에서 도움이됩니다.

예에서 오버 전체 최상위 시스템에는 두 가지 상태 (workingbroken) 만 있습니다. 전환은 이벤트 smashrepair에 의해 제어됩니다.

두 상태는 각각 작은 상태 시스템입니다. Broken는 두 상태의 상태 시스템 인 blinkingunblinking을 포함합니다. broken을 입력하면 해당 상태 시스템이 상태 blinking에서 시작됩니다. true로 호출 할 때 (부도) false 또는 blinkingbroken로 호출 될 경우

언제 서브 상태 brokenblinking에서 activeStateNames는 blinking를 리턴한다.

어떻게 사용하나요?

특정 상태에 따라 설정/해제하려는 항목이 있다면 컴퓨터에서 connectToState을 사용할 수 있습니다. 내가 연결하는 슬롯은 활성 및 비활성 사이에서 상태가 변경 될 때 호출되며 상태가 활성 상태인지 여부를 나타내는 부울 값을 수신합니다. 신호등 예에서 redredLight에 연결됩니다. redLightred 상태 일 때 켜져 있어야하며 그렇지 않은 경우에는 슬롯에 연결되어 부울을 가져옵니다. true이 켜지면 false이 꺼집니다.

좋아,하지만 내가 주에 들어갈 때 이벤트를보고 싶다면 어떻게해야합니까?

간단히 상태를 선택한 다음 onEntry -> send를 추가하고 이벤트 이름을 지정하십시오. 이렇게하면 상태에 들어갈 때 이벤트가 전송됩니다. 이 이벤트는 connectToEvent을 사용하여 슬롯 (Qt 5.8)로 라우팅 될 수 있습니다. [Qt 5.7 버전에는 슬롯에 보낼 수있는 신호가 일반 eventOccurred 밖에 없으므로 event.name()을 사용하여 어떤 이벤트를 쿼리 할 수 ​​있습니다.]