Last active
June 29, 2016 09:23
-
-
Save NikolayShubenkovProgSchool/6c458413ec3e91796fa964c36a0f6648 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef NS_ENUM(NSInteger, MDSUpdateTaskType) { | |
MDSUpdateTaskTypePrices, | |
MDSUpdateTaskTypeEditorials | |
}; | |
typedef NS_ENUM(NSInteger, MDSUpdateTaskState) { | |
MDSUpdateTaskStateWaitingToStart, | |
MDSUpdateTaskStateUpdating, | |
MDSUpdateTaskStateSucceed, | |
MDSUpdateTaskStateFailed | |
}; | |
@class MDSUpdateTask; | |
typedef void(^MDSTaskExcecuteBlock)(MDSUpdateTask *task); | |
/** | |
* Task which updates itself. On Success it calls next task; | |
*/ | |
@interface MDSUpdateTask : NSObject | |
@property (nonatomic, copy) MDSTaskExcecuteBlock succeedBlock; | |
@property (nonatomic, copy) MDSTaskExcecuteBlock failBlock; | |
@property (nonatomic, copy) MDSTaskExcecuteBlock excecuteBlock; | |
@property (nonatomic, strong) MDSUpdateTask *nextTask; | |
@property (nonatomic, readonly) MDSUpdateTaskType type; | |
@property (nonatomic, readonly) MDSUpdateTaskState currentState; | |
// | |
@property (nonatomic, readonly) BOOL tasksChainSucceded; | |
+ (instancetype)taskOfType:(MDSUpdateTaskType)type withExcecuteBlock:(MDSTaskExcecuteBlock)excecuteBlock; | |
//runs only from fail or wailting to start state | |
- (void)excecuteChain; | |
//in run block caller can specifie transitions to states | |
- (void)moveToState:(MDSUpdateTaskState)state; | |
@end | |
@interface MDSUpdateTask() | |
@property (nonatomic, readwrite) MDSUpdateTaskType type; | |
@property (nonatomic, readwrite) MDSUpdateTaskState currentState; | |
@end | |
@implementation MDSUpdateTask | |
#pragma mark - Properties Overload | |
- (BOOL)tasksChainSucceded | |
{ | |
if (self.currentState != MDSUpdateTaskStateSucceed){ | |
return NO; | |
} | |
if (self.nextTask == nil){ | |
return YES; | |
} | |
return self.nextTask.tasksChainSucceded; | |
} | |
- (void)setCurrentState:(MDSUpdateTaskState)currentState | |
{ | |
if (currentState == _currentState){ | |
return; | |
} | |
_currentState = currentState; | |
switch (_currentState) | |
{ | |
case MDSUpdateTaskStateSucceed: | |
{ | |
if (self.succeedBlock){ | |
__typeof__(self) __weak weakSelf = self; | |
self.succeedBlock(weakSelf); | |
} | |
[self.nextTask excecuteChain]; | |
break; | |
} | |
case MDSUpdateTaskStateFailed: | |
{ | |
if (self.failBlock){ | |
__typeof__(self) __weak weakSelf = self; | |
self.failBlock(weakSelf); | |
} | |
} | |
default: | |
break; | |
} | |
} | |
#pragma mark - Public | |
+ (instancetype)taskOfType:(MDSUpdateTaskType)type withExcecuteBlock:(MDSTaskExcecuteBlock)excecuteBlock | |
{ | |
MDSUpdateTask *task = [MDSUpdateTask new]; | |
task.type = type; | |
task.excecuteBlock = excecuteBlock; | |
return task; | |
} | |
- (void)excecuteChain | |
{ | |
//will not excecute successfully chaned tasks | |
if (self.tasksChainSucceded){ | |
return; | |
} | |
switch (self.currentState) { | |
case MDSUpdateTaskStateFailed: | |
case MDSUpdateTaskStateWaitingToStart: { | |
[self excecuteChain]; | |
break; | |
} | |
case MDSUpdateTaskStateSucceed:{ | |
[self.nextTask excecuteChain]; | |
} | |
case MDSUpdateTaskStateUpdating: | |
//just do nothing | |
break; | |
} | |
} | |
- (void)excecute | |
{ | |
self.currentState = MDSUpdateTaskStateUpdating; | |
__typeof__(self) __weak weakSelf = self; | |
self.excecuteBlock(weakSelf); | |
} | |
- (void)moveToState:(MDSUpdateTaskState)state | |
{ | |
self.currentState = state; | |
} | |
@end | |
///////////////////// | |
///////Builder/////// | |
///////////////////// | |
@class MediastoDataController; | |
@interface MDSUpdateTask (Build) | |
+ (NSArray <MDSUpdateTask *> *)buildTasksForController:(MediastoDataController *)controller completion:(void ((^)(BOOL success)))completion; | |
+ (instancetype)taskOfType:(MDSUpdateTaskType)type forDataController:(MediastoDataController *)controller; | |
@end | |
@implementation MDSUpdateTask (Build) | |
+ (NSArray<MDSUpdateTask *> *)buildTasksForController:(MediastoDataController *)controller completion:(void ((^)(BOOL)))completion | |
{ | |
MDSUpdateTask *editorials = [self taskOfType:MDSUpdateTaskTypeEditorials forDataController:controller]; | |
MDSUpdateTask *prices = [self taskOfType:MDSUpdateTaskTypePrices forDataController:controller]; | |
editorials.nextTask = prices; | |
[prices setSucceedBlock:^(MDSUpdateTask *task){ | |
if (completion){ | |
completion(YES); | |
} | |
}]; | |
NSArray *tasks = @[editorials,prices]; | |
MDSTaskExcecuteBlock fail = ^(MDSUpdateTask *task){ | |
if (completion){ | |
completion(NO); | |
} | |
}; | |
for (MDSUpdateTask *task in tasks){ | |
task.failBlock = fail; | |
} | |
return tasks; | |
} | |
+ (instancetype)taskOfType:(MDSUpdateTaskType)type forDataController:(MediastoDataController *)controller | |
{ | |
switch (type) { | |
case MDSUpdateTaskTypePrices: | |
{ | |
return [self p_pricesTaskForController:controller]; | |
} | |
case MDSUpdateTaskTypeEditorials: | |
{ | |
return [self p_editorialsTaskForController:controller]; | |
} | |
default: | |
NSParameterAssert(NO); | |
} | |
} | |
+ (instancetype)p_pricesTaskForController:(MediastoDataController *)controller | |
{ | |
return [MDSUpdateTask taskOfType:MDSUpdateTaskTypePrices | |
withExcecuteBlock:^(MDSUpdateTask *task) { | |
[controller requestMaterialPricesWithCompletion:[self p_finishForListBlockAndTask:task]]; | |
}]; | |
} | |
+ (instancetype)p_editorialsTaskForController:(MediastoDataController *)controller | |
{ | |
return [MDSUpdateTask taskOfType:MDSUpdateTaskTypeEditorials | |
withExcecuteBlock:^(MDSUpdateTask *task) { | |
[controller getEditorialOfficesWithCompletion:[self p_finishForListBlockAndTask:task]]; | |
}]; | |
} | |
+ (RequrestListCompletionBlock)p_finishForListBlockAndTask:(MDSUpdateTask *)task | |
{ | |
return ^(NSArray *list, NSError *error) { | |
if (error){ | |
[task moveToState:MDSUpdateTaskStateFailed]; | |
return ; | |
} | |
[task moveToState:MDSUpdateTaskStateSucceed]; | |
}; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment