使用 Objective-C 编写的非常简单的状态机。
特性
//Create structure
SMStateMachine *sm = [[SMStateMachine alloc] init];
sm.globalExecuteIn = self; //execute all selectors on self object
SMState *opened = [sm createState:@"open"];
SMState *closed = [sm createState:@"closed"];
sm.initialState = closed;
[opened setEntrySelector:@selector(greenLightOn)];
[closed setEntrySelector:@selector(redLightOn)];
[sm transitionFrom:closed to:opened forEvent:@"coin"];
[sm transitionFrom:opened to:closed forEvent:@"pass"];
[sm transitionFrom:opened to:closed forEvent:@"timeout"];
[sm transitionFrom:opened to:opened forEvent:@"coin" withSel:@selector(returnCoin)];
//Usage
[sm validate];
[sm post:@"coin"];
[sm post:@"pass"];
//Create structure
__weak id weakSelf = self;
SMStateMachine *sm = [[SMStateMachine alloc] init];
sm.globalExecuteIn = self; //execute all selectors on self object
SMState *opened = [sm createState:@"open"];
SMState *closed = [sm createState:@"closed"];
SMDecision *isWorkTime = [sm createDecision:@"isWorkTime" withPredicateBoolBlock:^(){
return [weakSelf isWorkTime];
}];
sm.initialState = closed;
[opened setEntrySelector:@selector(greenLightOn)];
[closed setEntrySelector:@selector(redLightOn)];
[sm transitionFrom:closed to:isWorkTime forEvent:@"coin"];
[sm trueTransitionFrom:isWorkTime to:opened];
[sm falseTransitionFrom:isWorkTime to:closed withSel:@selector(returnCoin)];
[sm transitionFrom:opened to:closed forEvent:@"pass"];
[sm transitionFrom:opened to:closed forEvent:@"timeout"];
[sm transitionFrom:opened to:opened forEvent:@"coin" withSel:@selector(returnCoin)];
[sm validate];
//Usage
self.isWorkTime = NO;
self.returnCoinsCounter = 0;
[sm post:@"coin"];
STAssertEquals(1, self.returnCoinsCounter, nil);
self.isWorkTime = YES;
[sm post:@"coin"];
STAssertEquals(1, self.returnCoinsCounter, nil);
[sm post:@"coin"];
STAssertEquals(2, self.returnCoinsCounter, nil);`
要启用日志记录,您需要将 fsm 对象的 monitor 属性设置为 SMMonitorDelegate 协议实现。
您可以使用默认的 SMMonitorNSLog 实现,或编写您自己的实现。
注意! 您需要保留对监视对象的强引用,因为 fsm 监视属性被描述为 @property(nonatomic, weak) id <SMMonitorDelegate> monitor;
//strong ref to monitor object
SMMonitorNSLog *nsLogMonitor =[[SMMonitorNSLog alloc] initWithSmName:@"Turnstile"];
SMStateMachine *sm = [[SMStateMachine alloc] init];
//log to NSLog
sm.monitor = nsLogMonitor;
...
PS 随时欢迎与我联系:)