Skip to content

Commit

Permalink
add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
NianJi committed Mar 11, 2019
1 parent 4558f08 commit ec5ae3d
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 71 deletions.
133 changes: 87 additions & 46 deletions coobjc/coobjc.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#import <coobjc/COGenerator.h>
#import <coobjc/co_tuple.h>

#pragma mark - Basic operator

/**
Mark a function with `CO_ASYNC`, which means the function may suspend,
Expand Down Expand Up @@ -87,60 +88,25 @@ NS_INLINE COCoroutine * _Nonnull co_launch_onqueue(dispatch_queue_t _Nullable q
return [co resume];
}


/**
Create a sequence, make the coroutine be a Generator.
@param block the sequence task.
@return the Coroutine
*/
NS_INLINE COGenerator * _Nonnull co_sequence(void(^ _Nonnull block)(void)) {
COGenerator *co = [COGenerator coroutineWithBlock:block onQueue:nil];
return co;
}

/**
Create a sequence, make the coroutine be a Generator.
The code will run on specified queue.
@param block the code execute in the coroutine.
@param queue the queue which coroutine work on it.
@return the coroutine instance
*/
NS_INLINE COGenerator * _Nonnull co_sequence_onqueue(dispatch_queue_t _Nullable queue, void(^ _Nonnull block)(void)) {
COGenerator *co = [COGenerator coroutineWithBlock:block onQueue:queue];
return co;
}

/**
Create a actor.
Create a coroutine, then resume it asynchronous on the given queue.
@param block the sequence task.
@return the Coroutine
*/
NS_INLINE COActor * _Nonnull co_actor(void(^ _Nonnull block)(COActorChan* _Nonnull)) {
COActor *co = [COActor actorWithBlock:block onQueue:nil];
return (COActor*)[co resume];
}

/**
Create a actor and start it asynchronous on the given queue.
The stack size is 65536 by default, in case stackSize not enough, you can customize it.
Max 1M limit.
@param block the code execute in the coroutine.
@param queue the queue which coroutine work on it.
@param block the code execute in the coroutine
@return the coroutine instance
*/
NS_INLINE COActor * _Nonnull co_actor_onqueue(dispatch_queue_t _Nullable queue, void(^ _Nonnull block)(COActorChan* _Nonnull)) {
COActor *co = [COActor actorWithBlock:block onQueue:queue];
return (COActor*)[co resume];
NS_INLINE COCoroutine * _Nonnull co_launch_withStackSizeAndQueue(NSUInteger stackSize, dispatch_queue_t _Nullable queue, void(^ _Nonnull block)(void)) {
COCoroutine *co = [COCoroutine coroutineWithBlock:block onQueue:queue stackSize:stackSize];
return [co resume];
}


/**
await
@param _promiseOrChan the COPromise object, you can also pass a COChan object.
But we suggest use Promise first.
But we suggest use Promise first.
@return return the value, nullable. after, you can use co_getError() method to get the error.
*/
NS_INLINE id _Nullable await(id _Nonnull _promiseOrChan) {
Expand All @@ -160,8 +126,6 @@ NS_INLINE NSArray<id> *_Nullable batch_await(NSArray<id> * _Nonnull _promiseOrCh
return val;
}



/**
co_delay
Expand All @@ -187,3 +151,80 @@ NS_INLINE BOOL co_isCancelled() {
return [COCoroutine currentCoroutine].isCancelled;
}

#pragma mark - Generator

/**
Create a sequence, make the coroutine be a Generator.
@param block the sequence task.
@return the Coroutine
*/
NS_INLINE COGenerator * _Nonnull co_sequence(void(^ _Nonnull block)(void)) {
COGenerator *co = [COGenerator coroutineWithBlock:block onQueue:nil];
return co;
}

/**
Create a sequence, make the coroutine be a Generator.
The code will run on specified queue.
@param block the code execute in the coroutine.
@param queue the queue which coroutine work on it.
@return the coroutine instance
*/
NS_INLINE COGenerator * _Nonnull co_sequence_onqueue(dispatch_queue_t _Nullable queue, void(^ _Nonnull block)(void)) {
COGenerator *co = [COGenerator coroutineWithBlock:block onQueue:queue];
return co;
}

/**
yield with a COPromise
@discussion `yield` means pause the expression execution,
until Generator(coroutine) call `next`.
@param _promise the COPromise object.
*/
#define yield(_expr) \
{ \
COGenerator *__co__ = (COGenerator *)[COCoroutine currentCoroutine]; \
co_generator_yield_prepare(__co__); \
if (!__co__.isCancelled) { \
id __promiseOrChan__ = ({ _expr; }); \
co_generator_yield_do(__co__, __promiseOrChan__); \
} \
}

/**
yield with a value.
@param val the value.
*/
#define yield_val(val) yield(val)


#pragma mark - Actor

/**
Create a actor.
@param block the sequence task.
@return the Coroutine
*/
NS_INLINE COActor * _Nonnull co_actor(void(^ _Nonnull block)(COActorChan* _Nonnull)) {
COActor *co = [COActor actorWithBlock:block onQueue:nil];
return (COActor*)[co resume];
}

/**
Create a actor and start it asynchronous on the given queue.
@param block the code execute in the coroutine.
@param queue the queue which coroutine work on it.
@return the coroutine instance
*/
NS_INLINE COActor * _Nonnull co_actor_onqueue(dispatch_queue_t _Nullable queue, void(^ _Nonnull block)(COActorChan* _Nonnull)) {
COActor *co = [COActor actorWithBlock:block onQueue:queue];
return (COActor*)[co resume];
}

35 changes: 10 additions & 25 deletions coobjc/generator/COGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,28 @@
NS_ASSUME_NONNULL_BEGIN

@class COGenerator;
void co_generator_yield_prepare(COGenerator *co);
void co_generator_yield_do(COGenerator *co, id _Nonnull promiseOrChan);
void co_generator_yield_value(id value);

/**
yield with a COPromise
@discussion `yield` means pause the expression execution,
until Generator(coroutine) call `next`.
@param _promise the COPromise object.
This two method implement generator, you should not call this method directly,
Use `yield( xxx )`
*/
#define yield(_expr) \
{ \
COGenerator *__co__ = (COGenerator *)[COCoroutine currentCoroutine]; \
co_generator_yield_prepare(__co__); \
if (!__co__.isCancelled) { \
id __promiseOrChan__ = ({ _expr; }); \
co_generator_yield_do(__co__, __promiseOrChan__); \
} \
}
void co_generator_yield_prepare(COGenerator *co);
void co_generator_yield_do(COGenerator *co, id _Nonnull promiseOrChan);


/**
yield with a value.
@param val the value.
The Generator object.
*/
#define yield_val(val) yield(val)


@interface COGenerator : COCoroutine

/**
When COCoroutine as a Generator, this Channel use to yield a value.
The channel for yield.
*/
@property(nonatomic, strong, nullable) COChan *yieldChan;

/**
The channel for send value to the `next()` caller.
*/
@property(nonatomic, strong, nullable) COChan *valueChan;


Expand Down

0 comments on commit ec5ae3d

Please sign in to comment.