Skip to content

Instantly share code, notes, and snippets.

@kyontan
Last active December 22, 2015 12:23
Show Gist options
  • Save kyontan/b3e2d7b26fd1b6364419 to your computer and use it in GitHub Desktop.
Save kyontan/b3e2d7b26fd1b6364419 to your computer and use it in GitHub Desktop.
Too Simple StatusManager in Objective-C (CC0)
//
// StatusManager.h
//
// Created by kyontan on 2015/12/22.
// Licensed under CC0
//
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, Status) {
StatusNotValid = 0,
StatusInitial = 1,
StatusA,
StatusB
};
typedef NS_ENUM(NSInteger, Action) {
ActionFoo,
ActionBar,
ActionNyan,
};
@interface StatusManager : NSObject
@property (assign, nonatomic, readonly) Status status;
- (instancetype)init;
- (void)addTransition:(Action)action
from:(NSSet *)from
to:(Status)to
with:(void (^)(id))transition;
- (Status)transit:(Action)action;
- (Status)transit:(Action)action
withUserData:(id)userData;
@end
//
// StatusManager.m
//
// Created by kyontan on 2015/12/22.
// Licensed under CC0
//
#import "StatusManager.h"
@interface StatusManager ()
// Action -> NSSet<@(Status)>
@property (strong, nonatomic) NSMutableDictionary *fromSetOfAction;
// Action -> @(Status)
@property (strong, nonatomic) NSMutableDictionary *toOfAction;
// Action -> (void (^)(void))
@property (strong, nonatomic) NSMutableDictionary *transitions;
@property (assign, nonatomic) Status status;
@end
@implementation StatusManager
- (instancetype)init {
self = [super init];
if (self) {
_status = StatusInitial;
_fromSetOfAction = [NSMutableDictionary dictionary];
_toOfAction = [NSMutableDictionary dictionary];
_transitions = [NSMutableDictionary dictionary];
}
return self;
}
- (void)addTransition:(Action)action
from:(NSSet *)from
to:(Status)to
with:(void (^)(id))transition {
NSNumber *naction = @(action);
_fromSetOfAction[naction] = from;
_toOfAction[naction] = @(to);
_transitions[naction] = transition;
}
- (Status)transit:(Action)action {
return [self transit:action withUserData:nil];
}
- (Status)transit:(Action)action
withUserData:(id)userData {
NSNumber *naction = @(action);
Status old = _status, ret;
if ([_fromSetOfAction[naction] containsObject:@(_status)]) {
void (^action)(id) = _transitions[naction];
action(userData);
_status = [_toOfAction[naction] integerValue];
ret = _status;
} else {
ret = StatusNotValid;
}
NSLog(@"Status transit: %ld - (%ld) -> %ld ", (long)old, (long)action, (long)ret);
return ret;
}
@interface ViewController : UIViewController
@property (nonatomic, strong) StatusManager *status_manager;
@end
@implementation ViewController
- (void)viewDidLoad {
_status_manager = [StatusManager new];
__weak __block typeof(self) weakSelf = self;
[_status_manager addTransition:ActionFoo
from:[NSSet setWithArray:@[@(StatusInitial), @(StatusA)]]
to:StatusB
with:^(id userdata) {
[weakSelf displayEverything];
}];
[_status_manager addTransition:ActionBar
from:[NSSet setWithArray:@[@(StatusB)]]
to:StatusA
with:^(id userdata) {
// do something
}];
[_status_manager addTransition:ActionNyan
from:[NSSet setWithArray:@[@(StatusA), @(StatusB)]]
to:StatusB
with:^(id userdata) {
// do something
}];
}
@end
- (IBAction)pushSomeButton:(id)sender {
[_status_manager transit:ActionFoo];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment