Skip to content

Commit

Permalink
feat(COGenerator): add generator nextWithParam
Browse files Browse the repository at this point in the history
add generator nextWithParam and co_getYieldParam

fix alibaba#50
  • Loading branch information
pengyutang125 committed Mar 15, 2019
1 parent 74ee77f commit 7fe2e25
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1827C5AB219BC9C30004CE59"
BuildableName = "coobjcBaseExampleTests.xctest"
BlueprintName = "coobjcBaseExampleTests"
ReferencedContainer = "container:coobjcBaseExample.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,37 @@
});
});

it(@"yield value return param", ^{
COGenerator *co1 = co_sequence(^{
int index = 0;
while(co_isActive()){
NSLog(@"==== before yield val %d", index);

int param = [co_getYieldParam() intValue];
expect(param == 5).beTruthy();
yield_val(@(index));

NSLog(@"==== after yield val %d", index);
index++;
}
});
__block int val = 0;
co_launch(^{
for(int i = 0; i < 10; i++){
NSLog(@"==== before next val %d", i);
val = [[co1 nextWithParam:@(5)] intValue];
NSLog(@"==== after next val %d", val);
}
[co1 cancel];
});
waitUntilTimeout(2.0, ^(DoneCallback done) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
XCTAssert(val == 9);
done();
});
});
});

it(@"yield value chain", ^{
COGenerator *co1 = co_sequence(^{
int index = 0;
Expand Down Expand Up @@ -136,6 +167,34 @@
});
});

it(@"yield promise return param", ^{
__block int count = 0;
COGenerator *co1 = co_sequence(^{
while(co_isActive()){
int param = [co_getYieldParam() intValue];
expect(param == 10).beTruthy();
yield( count++; co_downloadWithURL(@"http://pytstore.oss-cn-shanghai.aliyuncs.com/GalileoShellApp.ipa"));
}
});
int filebytes = 248564;
__block int val = 0;
co_launch(^{
for(int i = 0; i < 10; i++){
NSData *data = [co1 nextWithParam:@(10)];
val += data.length;
//val = [[co1 next] intValue];
}
[co1 cancel];
});
waitUntilTimeout(5.0, ^(DoneCallback done) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
expect(val == filebytes * 10).beTruthy();
expect(count).equal(10);
done();
});
});
});

it(@"yield promise chain", ^{
__block int count = 0;
COGenerator *co2 = co_sequence(^{
Expand Down
33 changes: 33 additions & 0 deletions coobjc/generator/COGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ void co_generator_yield_prepare(COGenerator *co);
void co_generator_yield_do(COGenerator *co, id _Nonnull promiseOrChan);


/**
This method can get the param setted by nextWithParam,
gen = co_generator(^{
id param = co_getYieldParam();
yield(handleParam(param));
//param will be @(1), it was the value passed by nextWithValue
});
co_launch(^{
id value = [gen nextWithValue:@(1)];
});
*/
id _Nullable co_getYieldParam(void);

/**
The Generator object.
*/
Expand All @@ -36,13 +50,32 @@ void co_generator_yield_do(COGenerator *co, id _Nonnull promiseOrChan);
@property(nonatomic, strong, nullable) COChan *valueChan;



/**
The designed for Generator, used as yield/next.
@return The value yiled by the Generator.
*/
- (id _Nullable )next;


/**
The designed for Generator, used as yield/nextWithParam.
@param param is the value will pass to yield, can use like this
gen = co_generator(^{
id param = co_getYieldParam();
yield(handleParam(param));
//param will be @(1), it was the value passed by nextWithValue
});
co_launch(^{
id value = [gen nextWithValue:@(1)];
});
@return The value yiled by the Generator.
*/
- (id _Nullable )nextWithParam:(id)param;

@end

NS_ASSUME_NONNULL_END
21 changes: 21 additions & 0 deletions coobjc/generator/COGenerator.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ void co_generator_yield_do(COGenerator *co, id _Nonnull promiseOrChanOrElse) {
}


@interface COGenerator ()

@property(strong) id nextParamValue;

@end

id _Nullable co_getYieldParam(){
COGenerator *gen = (COGenerator*)[COCoroutine currentCoroutine];
if ([gen isKindOfClass:[COGenerator class]]) {
return gen.nextParamValue;
}
return nil;
}



@implementation COGenerator

- (instancetype)initWithBlock:(void (^)(void))block onQueue:(dispatch_queue_t)queue stackSize:(NSUInteger)stackSize {
Expand Down Expand Up @@ -68,4 +84,9 @@ - (id)next {
return [self.valueChan receive];
}

- (id)nextWithParam:(id)param{
self.nextParamValue = param;
return [self next];
}

@end

0 comments on commit 7fe2e25

Please sign in to comment.