//效果
node.gif
//今天看到一篇文章試著寫了下哄褒。https://blog.csdn.net/u014626094/article/details/101697305
#import <Foundation/Foundation.h>
typedef void (^Block)(NSInteger note_id) ;
NS_ASSUME_NONNULL_BEGIN
@protocol Node <NSObject>
- (NSInteger)getId;
- (void)onCompleted:(NSInteger)note_id;
@end
@interface WorkNode : NSObject<Node>
@property (nonatomic, assign) BOOL isWorking; //!<
@property (nonatomic, strong) id data;
@property (nonatomic, assign) NSInteger nodeID; //!<
//@property (nonatomic, strong) Work *work; //!<
/**
* 當前任務完成
*/
@property (nonatomic, copy) Block onWorkCompleted; //!<
//+(WorkNode *)BuildNodeId:(NSInteger)nodeId WithWork:(Work *)work;
- (instancetype)initNodeId:(NSInteger)nodeId WithWorkHandle:(void(^)(id <Node>))block;
- (void)doWork:(Block)block;
@end
@interface MKWorkFlowManager : NSObject
- (instancetype)initWithWorks:(NSMutableArray *)works ;
- (void)addNode:(id<Node>)node;
- (void)startWorking;
- (void)pauseExecuteAction;
- (void)startExecuteAction:(NSInteger)node_id;
@end
NS_ASSUME_NONNULL_END
////////////////////////////////////////////
#import "MKWorkFlowManager.h"
@interface WorkNode ()
@property (nonatomic, copy) void (^workBlock)(id <Node>); //!<
@end
@implementation WorkNode
//+(WorkNode *)BuildNodeId:(NSInteger)nodeId WithWork:(Work *)work {
// return [[WorkNode alloc] initNodeId:nodeId WithWork:work];
//}
//
//- (instancetype)initNodeId:(NSInteger)nodeId WithWork:(Work *)work {
// if (self = [super init]) {
//
// self.nodeID = nodeId;
// self.work = work;
// }
//
// return self;
//}
- (instancetype)initNodeId:(NSInteger)nodeId WithWorkHandle:(void(^)(id <Node>))block {
if (self = [super init]) {
self.nodeID = nodeId;
self.workBlock = block;
}
return self;
}
- (void)doWork:(Block)block {
_onWorkCompleted = block;
// [self.work doWork:self];
if (_workBlock) {
_workBlock(self);
}
}
- (NSInteger)getId {
return _nodeID;
}
- (void)onCompleted:(NSInteger)note_id {
if (_onWorkCompleted) {
_onWorkCompleted(note_id);
}
}
@end
@interface MKWorkFlowManager ()
@property (nonatomic, strong) NSMutableArray *nodes; //!<
@property (nonatomic, assign) BOOL isExecuteAction; //!<
@property (nonatomic, assign) BOOL canExecute; //!<
@end
@implementation MKWorkFlowManager
- (instancetype)init {
if (self = [super init]) {
_canExecute = YES;
NSLog(@"initmethond");
}
return self;
}
//看情況可以設計成單例,但是也可以把初始化寫到基類里面
- (instancetype)initWithWorks:(NSMutableArray *)works {
if (self = [super init]) {
self.nodes = works;
NSLog(@"initmethond1");
_canExecute = YES;
}
return self;
}
- (void)addNode:(WorkNode *)node {
[self.nodes addObject:node];
// if (_canExecute == YES) {
// if (self.nodes.count == 1) {
// [self findAndExecuteNextNode];
// }else{
// if (!_isExecuteAction && self.nodes.count> 0) {
// [self executeNextNodeWithNodeId:node.nodeID];
// }else{
// [self findAndExecuteNextNode];
// }
// }
// }
}
- (void)hasStartNode {
// NSLog(@">>>node----%zd",self.nodes.count);
_isExecuteAction = YES;
}
- (void)pauseExecuteAction {
_canExecute = NO;
}
- (void)startExecuteAction:(NSInteger)node_id {
if (!_canExecute) {
_canExecute = YES;
}
if (node_id == 0) {
[self findAndExecuteNextNode];
}else{
[self executeNextNodeWithNodeId:node_id];
}
}
- (void)startWorking {
[self findAndExecuteNextNode];
}
- (void)findAndExecuteNextNode {
if ([self hasWorkingNode]) {
NSLog(@"還有任務在執(zhí)行");
return;
}
if (self.nodes.count >0 && self.canExecute == YES) {
WorkNode *worknode = self.nodes.firstObject;
worknode.isWorking = YES;
[worknode doWork:^(NSInteger note_id){
[self.nodes removeObject:worknode];
if (note_id == 0) {
[self findAndExecuteNextNode];
}else{
[self executeNextNodeWithNodeId:note_id];
}
}];
// [self hasStartNode];
}
}
//這個方法優(yōu)先級高點煌张,即時被中斷也執(zhí)行
- (void)executeNextNodeWithNodeId:(NSInteger)node_id {
if ([self hasWorkingNode]) {
NSLog(@"還有任務在執(zhí)行");
return;
}
if (self.nodes.count >0) {
BOOL hasFind = NO;
for (WorkNode *node in self.nodes) {
if (node.nodeID == node_id) {
WorkNode *worknode = node;
node.isWorking = YES;
kWeakSelf;
[worknode doWork:^(NSInteger note_id){
kStrongSelf;
[strongSelf.nodes removeObject:worknode];
if (strongSelf.canExecute) {
if (note_id == 0) {
[strongSelf findAndExecuteNextNode];
}else{
[strongSelf executeNextNodeWithNodeId:note_id];
}
}
}];
hasFind = YES;
// [self hasStartNode];
break;
}
}
if (hasFind != YES) {
[self findAndExecuteNextNode];
}
}
}
- (BOOL)hasWorkingNode{
BOOL hasWoringNode = NO;
for (WorkNode *node in self.nodes) {
if (node.isWorking) {
hasWoringNode = YES;
break;
}
}
return hasWoringNode;
}
- (NSMutableArray *)nodes {
if(!_nodes){
_nodes = [NSMutableArray array];
}
return _nodes;
}
@end