实现基于分层状态机的Objective-C程序的最简单方法。
直接克隆或下载源代码,或使用 CocoaPods。
pod 'SDDKit'
以下列出的类提供了 SDDKit 的主要功能。
但作为‘客户端’,其中两个需要您关注。
SDDState 包含激活和去激活块,执行进入和退出操作。
每个 SDDStateMachine 的实例代表一个独立的状态机对象。每个对象都描述状态层次结构和转换。
事件分发类。重要的是要知道,在状态机通过传入事件驱动之前,必须将状态机添加为事件池的订阅者。一些应用拥有多个事件池以避免信号名重复。
基于字符串解析的 SDDStateMachine 构建器。它提供了生成和管理多个状态机的最简单方法。
SDDBuilder *builder = [SDDBuilder alloc] initWithLogger:nil epool:[SDDEventsPool sharedPool];
[builder addStateMachineWithContext:nil dsl:SDDOCLanguage(
// Every statemachine can and must have one topstate
[TopState
// Two substates
[A]
[B]
]
// Since TopState has two descendants, a $Default transition have to be provided to avoid ambiguity.
// Another choice is using $Initial transition from outter state [.] such as:
// [.] -> [A]: $Initial
[TopState] -> [A]: $Default
// If [A] is the current state and signal 'E1' occurs, it will transit to state [B]
[A]->[B]: E1
)];
[[SDDEventsPool sharedPool] scheduleEvent:SDDLiteral(E1)];
// Now we are in state [B]
带有 nil 上下文的状态机毫无帮助。必须做些事情,使我们能够区分一个状态和另一个状态。那不就是我们要使用状态机的理由吗?
@interface Charles
@end
@implementation Charles
- (void)wakeup {
NSLog(@"Good morning.")
}
- (void)sayGoodbye {
NSLog(@"Bye, see ya.");
}
- (void)goToBed {
NSLog(@"Good night.")
}
@end
int main() {
Charles *charles = [[Charles alloc] init];
SDDBuilder *builder = [SDDBuilder alloc] initWithLogger:nil epool:[SDDEventsPool sharedPool];
[builder addStateMachineWithContext:charles dsl:SDDOCLanguage(
[Me
[Awake
e: wakeup // 'e' is short for entering
x: sayGoodbye // 'x' is short for exiting
]
[Asleep e: goToBed]
]
[.] -> [Awake] : $Initial
[Awake] -> [Asleep] : Sunset
[Asleep] -> [Awake] : Sunrise
)];
// Outputs 'Good morning.' for entering initial state [Awake]
[[SDDEventsPool sharedPool] scheduleEvent:SDDLiteral(Sunset)];
// Outputs 'Bye, see ya.' for exiting state [Awake]
// Outputs 'Good night' for entering state [Asleep]
[[SDDEventsPool sharedPool] scheduleEvent:SDDLiteral(Sunrise)];
// Outputs 'Good morning.' for entering state [Awake]
return 0;
)