0

C#의 상태 비 저장 상태 머신을 사용하고 있지만 다른 주 기계 구현과 관련하여이 문제가 과거에 발생했습니다. 질문은 대부분 이론적인데, 더미 코드를 추가 할 수는 있습니다.발신자 상태로 돌아 가기?

저는 어떻게 해결해야 할 지 확신 할 수없는 상황이 있습니다. 두 가지 상태 (걷기와 달리기)가 있고 둘 다 세 번째 상태 (점프)로 전환 할 수 있다고 가정 해 보겠습니다. 세 번째 상태가 완료되면 발신자 상태로 돌아가고 싶습니다. 어떤면에서는 호출 수신자 트리거에 영향을 미칠 수 있어야하지만 이것은 상태 자체가 아닌 OnEntry 등으로 전달됩니다.

EntryFrom을 사용하면 "점프"상태 자체에 영향을 줄 수있는 방법이 없으므로 OnEntry 기능 만 작동합니다. PermitDynamic을 사용하면 "점프"상태가되어 어디에서 왔는지 모르기 때문에 어느 쪽도 작동하지 않는 것 같습니다.

일부 중복 코드를 최소화하기 위해 하나의 OnEntry 기능으로 2 개의 점프 상태 (jumpfromrun, jumpfromwalk)를 가질 수있었습니다. 이것은 내가 현재 사용하는 것입니다.

외부 변수에 이전 상태를 저장하고이를 내 상태 업데이트에 전달할 수 있습니다. 나는 이것을 (전혀)하고 싶지 않다.

이러한 종류의 문제를 해결할 수있는 알려진 기술이나 방법이 있습니까? 공유 상태가되면 발신자에게 다시 전환해야합니까? 감사합니다.

+1

"점프"상태에있는 유일한 방법은 아직 거기에 도착한 방법을 기억하는 것입니다. 상태 (걷기 점프와 뛰기 점프) 또는 다른 종류의 저장소 여분의 enum 변수 등) – Alexander

+0

질문에서 언급했듯이, 그것은 현재 내가 사용하는 것입니다.그러나 복사 - 붙여 넣기 코드가 많아서 큰 해결책은 아니며, 유일한 다른 행은 트리거 호출입니다./두 상태는 완전히 동일합니다. – scx

+1

붙여 넣은 코드를 너무 많이 복사하는 이유는 무엇입니까? OnEntry, OnExit 및 Permit을 복제해야하지만 '점프'코드 자체는 점프 유형 모두에 의해 호출되는 함수로 추출 될 수 있습니다 – Alexander

답변

1

문서를 읽는 것으로부터, 이것은 substates에 대한 꽤 좋은 유스 케이스 인 것처럼 보입니다.

stateMachine.Configure(State.Jumping) 
    .OnEntry(() => StartJump()) 
    .OnExit(() => EndJump()); 

두 개의 점프 하위 상태 :

당신은 점프 상태를 가질 수 있습니다. 하나는 걷기위한 것이고, 하나는 달리기를위한 것입니다 :

stateMachine.Configure(State.WalkJumping) 
    .SubstateOf(State.Jumping) 
    .Permit(Trigger.DoneJumping, State.Walking); 

stateMachine.Configure(State.RunJumping) 
    .SubstateOf(State.Jumping) 
    .Permit(Trigger.DoneJumping, State.Running); 

그런 다음 WalkJumping과 RunJumping으로가는 길을 걷습니다. 그냥 평범한 상태에 반대

stateMachine.Configure(State.Walking) 
    .OnEntry(() => StartWalking()) 
    .OnExit(() => EndWalking()); 
    .Permit(Trigger.Jump, State.WalkJumping); 


stateMachine.Configure(State.Running) 
    .OnEntry(() => StartRunning()) 
    .OnExit(() => EndRunning()); 
    .Permit(Trigger.Jump, State.RunJumping); 

사용하여 기판과 같이의 State.JumpingWalkJumpingEndJumping 모두에 의해 상속됩니다 같은 OnEntryOnExit를 정의 할 수있는 추가 혜택이있다.

또한 점프 중이라면 쉽게 확인할 수 있습니다. 대신에 :

var state = stateMachine.state; 
var isJumping = state == State.WalkJumping || state == RunJumping; 

당신은 간단하게 수행 할 수 있습니다 제대로 현재 WalkJumpingRunJumping 모든 하위 상태를 고려할 것

var isJumping = stateMachine.IsInState(State.Jumping); 

. 그러나 미래에 새로운 점프 하위 상태를 추가하면 DoubleJumping이면 isJumping 술어가 자동으로 해당 사례를 해결하므로 수정하지 않아도됩니다.

+0

이것은 제가 찾고있는 일종의 감사입니다! 이제 하위 상태와 함께 부모 "업데이트"도 호출됩니다. 그래서 당신이'OnEntry'와'TheUpdate'를 공유 할 수있을 것이라고 생각합니다. 'PermitDynamic','PermitDynamicIf' 또는'OnEntryFrom'을 사용하여 출구 점을 수정할 수 있습니다. 그래서 기본적으로 두 개의 다른 출구로 끝납니다. 나중에이 아이디어를 가지고 놀아 보겠다.하지만 이것은 확실히 우아하고 모델링 된 솔루션이다. – scx