├── .gitignore
├── Android
├── .gitignore
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── promiseprioritychain
│ │ │ ├── IPriorityElementCapable.java
│ │ │ ├── IPriorityPromise.java
│ │ │ ├── MainActivity.java
│ │ │ ├── PriorityElementImp.java
│ │ │ └── PriorityPromiseImp.java
│ │ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── Java-Example.md
├── Java
└── Priority
│ ├── Priority.iml
│ └── src
│ └── com
│ └── runs
│ └── www
│ ├── DelayComponentImp.java
│ ├── IDelayComponent.java
│ ├── IPriorityElementCapable.java
│ ├── IPriorityPromise.java
│ ├── Main.java
│ ├── PriorityElementImp.java
│ └── PriorityPromiseImp.java
├── LICENSE
├── OC-Example.md
├── Objective-C
├── PromisePriorityChain.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── PromisePriorityChain.xcscheme
├── PromisePriorityChain
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ ├── Priority
│ │ ├── PriorityElementProtocol.h
│ │ ├── PriorityPromise.h
│ │ ├── PriorityPromise.m
│ │ ├── PrioritySessionElement.h
│ │ └── PrioritySessionElement.m
│ ├── SceneDelegate.h
│ ├── SceneDelegate.m
│ ├── Test
│ │ ├── PriorityDemo.h
│ │ ├── PriorityDemo.m
│ │ ├── PrioritySessionCustomElement.h
│ │ └── PrioritySessionCustomElement.m
│ ├── ViewController.h
│ ├── ViewController.m
│ └── main.m
└── PromisePriorityChainTests
│ └── Info.plist
├── README.md
├── Swift-Example.md
└── Swift
└── PromisePriorityChain
├── PromisePriorityChain.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ ├── IDEWorkspaceChecks.plist
│ └── WorkspaceSettings.xcsettings
├── PromisePriorityChain
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
├── Base.lproj
│ └── LaunchScreen.storyboard
├── ContentView.swift
├── Info.plist
├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
├── Priority
│ ├── PriorityElement.swift
│ ├── PriorityError.swift
│ └── PriorityPromise.swift
├── SceneDelegate.swift
└── Test
│ ├── PriorityCustomElement.swift
│ └── PromisePriorityTest.swift
├── PromisePriorityChainTests
├── Info.plist
└── PromisePriorityChainTests.swift
└── TestModule
├── Info.plist
└── TestModule.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | xcuserdata/
26 | .idea/
27 | /build
--------------------------------------------------------------------------------
/Android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/Android/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/Android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | buildToolsVersion "29.0.3"
6 | defaultConfig {
7 | applicationId "com.example.promiseprioritychain"
8 | minSdkVersion 21
9 | targetSdkVersion 29
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | compileOptions {
21 | sourceCompatibility = 1.8
22 | targetCompatibility = 1.8
23 | }
24 | }
25 |
26 | dependencies {
27 | implementation fileTree(dir: 'libs', include: ['*.jar'])
28 | implementation 'androidx.appcompat:appcompat:1.0.2'
29 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
30 | testImplementation 'junit:junit:4.12'
31 | androidTestImplementation 'androidx.test:runner:1.1.1'
32 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
33 | }
34 |
--------------------------------------------------------------------------------
/Android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/Android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Android/app/src/main/java/com/example/promiseprioritychain/IPriorityElementCapable.java:
--------------------------------------------------------------------------------
1 | package com.example.promiseprioritychain;
2 |
3 | public interface IPriorityElementCapable {
4 | }
5 |
6 | @FunctionalInterface
7 | interface IPriorityElementSubscribeCallback {
8 | void subscribe(T t);
9 | }
10 |
11 | @FunctionalInterface
12 | interface IPriorityElementErrorCallback {
13 | void exception(Error error);
14 | }
15 |
16 | @FunctionalInterface
17 | interface IPriorityElementDisposeCallback {
18 | void dispose();
19 | }
20 |
21 | interface IPriorityElement {
22 |
23 | IPriorityElement then(IPriorityElement element);
24 | IPriorityElement next();
25 |
26 | void executeWithData(T input);
27 | void executeNextWithData(Object object);
28 | void breakWithError(Error error);
29 |
30 | void invalidate();
31 | }
32 |
--------------------------------------------------------------------------------
/Android/app/src/main/java/com/example/promiseprioritychain/IPriorityPromise.java:
--------------------------------------------------------------------------------
1 | package com.example.promiseprioritychain;
2 |
3 |
4 | import android.os.Handler;
5 | import android.os.Message;
6 | import android.util.Log;
7 | import androidx.annotation.NonNull;
8 |
9 | @FunctionalInterface
10 | interface IPriorityPromiseCallback {
11 |
12 | void run(IPriorityPromise promise);
13 |
14 | }
15 |
16 | public interface IPriorityPromise {
17 |
18 | static final int PROMISE_PROORITY_WHAT = 1 << 4;
19 | static final int LOOP_VALIDATED_MODE = 1 << 8;
20 | static final int CONDITION_DELAY_MODE = 1 << 16;
21 |
22 |
23 | String getId();
24 |
25 | void setInput(T t);
26 | T getInput();
27 |
28 | void setOutput(E o);
29 | E getOutput();
30 |
31 | IPriorityElement getPriorityElement();
32 | void notifyMainThreadByHandler(int mode, long delay);
33 |
34 | default void next(E o) {
35 | IPriorityElement e = getPriorityElement();
36 | if (null != e) {
37 | e.executeNextWithData(o);
38 | }
39 | }
40 |
41 | default void brake(Error error) {
42 | if (null == error) {
43 | error = new Error("NO Error Description");
44 | }
45 | getPriorityElement().breakWithError(error);
46 | }
47 |
48 | default void validated(boolean isValid) {
49 | if (isValid) {
50 | getPriorityElement().executeNextWithData(getOutput());
51 | return;
52 | }
53 | getPriorityElement().breakWithError(new Error("validated failure"));
54 | }
55 |
56 | default void loopValidated(boolean isValid, long interval) {
57 | Log.i("Priority", "0. thread name : " + Thread.currentThread().getName());
58 | if (isValid) {
59 | getPriorityElement().executeNextWithData(getOutput());
60 | return;
61 | }
62 |
63 | if (0 > interval) {
64 | Error error = new Error("interval must bigger than 0");
65 | getPriorityElement().breakWithError(error);
66 | return;
67 | }
68 | //
69 | notifyMainThreadByHandler(LOOP_VALIDATED_MODE, interval);
70 | }
71 |
72 | default void condition(boolean isOk, long delay) {
73 | if (!isOk || 0 >= delay) {
74 | getPriorityElement().executeNextWithData(getInput());
75 | return;
76 | }
77 | //
78 | notifyMainThreadByHandler(CONDITION_DELAY_MODE, delay);
79 | }
80 |
81 | void invalidate();
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/Android/app/src/main/java/com/example/promiseprioritychain/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.promiseprioritychain;
2 |
3 | import android.os.Handler;
4 | import android.util.Log;
5 | import androidx.appcompat.app.AppCompatActivity;
6 | import android.os.Bundle;
7 |
8 | public class MainActivity extends AppCompatActivity {
9 | public static int mCount = 0;
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_main);
15 |
16 | Log.i("MainActivity", "onCreate");
17 |
18 | PriorityElementImp element0 = testElement0();
19 | PriorityElementImp testElement5 = testElement5();
20 |
21 | testElement5.subscribe(s -> {
22 | System.out.println("testElement5 subscribe : " + s);
23 | }).exception(error -> {
24 | System.out.println("testElement5 exception : " + error.getMessage());
25 | }).dispose(() -> {
26 | System.out.println("testElement5 dispose");
27 | });
28 |
29 | element0
30 | .then(testElement1())
31 | .then(testElement2())
32 | .then(testElement3())
33 | .then(testElement4())
34 | .then(testElement5);
35 | element0.executeWithData(10);
36 |
37 | }
38 |
39 | public static PriorityElementImp testElement0() {
40 | return new PriorityElementImp(promise -> {
41 |
42 | Integer t = promise.getInput();
43 | System.out.println("t = " + t.toString());
44 | System.out.println("100ms查询一次,一共查询5次, 轮询 ");
45 | promise.next(100);
46 |
47 | }).subscribe(integer -> {
48 | System.out.println("element0 subscribe : " + integer);
49 | }).exception(error -> {
50 | System.out.println("element0 exception : " + error.getMessage());
51 | }).dispose(() -> {
52 | System.out.println("element0 dispose");
53 | });
54 | }
55 |
56 |
57 | public static PriorityElementImp testElement1() {
58 | return new PriorityElementImp(promise -> {
59 |
60 | mCount++;
61 | System.out.println(System.currentTimeMillis() + " mCount = " + mCount);
62 | promise.setOutput(mCount);
63 | promise.loopValidated(mCount >= 5, 100);
64 |
65 | }).subscribe(integer -> {
66 | System.out.println("testElement1 subscribe : " + integer);
67 | }).exception(error -> {
68 | System.out.println("testElement1 exception : " + error.getMessage());
69 | }).dispose(() -> {
70 | System.out.println("testElement1 dispose");
71 | });
72 | }
73 |
74 | public static PriorityElementImp testElement2() {
75 | return new PriorityElementImp(promise -> {
76 |
77 | Integer t = promise.getInput();
78 | System.out.println("t = " + t.toString());
79 | promise.next(10000);
80 |
81 | }).subscribe(integer -> {
82 | System.out.println("testElement2 subscribe : " + integer);
83 | }).exception(error -> {
84 | System.out.println("testElement2 exception : " + error.getMessage());
85 | }).dispose(() -> {
86 | System.out.println("testElement2 dispose");
87 | });
88 | }
89 |
90 | public static PriorityElementImp testElement3() {
91 | return new PriorityElementImp(promise -> {
92 |
93 | Integer t = promise.getInput();
94 | System.out.println("t = " + t.toString());
95 | promise.setOutput("即将延迟校验结束");
96 | promise.validated(t > 100);
97 |
98 | }).subscribe(s -> {
99 | System.out.println("testElement3 subscribe : " + s);
100 | }).exception(error -> {
101 | System.out.println("testElement3 exception : " + error.getMessage());
102 | }).dispose(() -> {
103 | System.out.println("testElement3 dispose");
104 | });
105 | }
106 |
107 | public static PriorityElementImp testElement4() {
108 | return new PriorityElementImp(promise -> {
109 |
110 | String s = promise.getInput();
111 | System.out.println(s);
112 | System.out.println(System.currentTimeMillis() + " begin 延迟1000ms校验结束");
113 | promise.setOutput("结束了");
114 | promise.condition(mCount >= 5, 1000);
115 |
116 | }).subscribe(s -> {
117 | System.out.println("testElement4 subscribe : " + s);
118 | }).exception(error -> {
119 | System.out.println("testElement4 exception : " + error.getMessage());
120 | }).dispose(() -> {
121 | System.out.println("testElement4 dispose");
122 | });
123 | }
124 |
125 | public static PriorityElementImp testElement5() {
126 | return new PriorityElementImp<>(promise -> {
127 | System.out.println(System.currentTimeMillis() + " end 延迟1000ms校验结束");
128 | String s = promise.getInput();
129 | System.out.println(s);
130 | // promise.next("game over");
131 | promise.brake(null);
132 | });
133 | }
134 |
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/Android/app/src/main/java/com/example/promiseprioritychain/PriorityElementImp.java:
--------------------------------------------------------------------------------
1 | package com.example.promiseprioritychain;
2 |
3 | public class PriorityElementImp implements IPriorityElement {
4 |
5 | private String id = "PriorityElementImp";
6 |
7 | private PriorityPromiseImp promise;
8 |
9 | private IPriorityPromiseCallback callback;
10 |
11 | private PriorityElementImp, ?> next;
12 |
13 | private IPriorityElementSubscribeCallback subscribeCallback;
14 |
15 | private IPriorityElementErrorCallback errorCallback;
16 |
17 | private IPriorityElementDisposeCallback disposeCallback;
18 |
19 |
20 | public PriorityElementImp(IPriorityPromiseCallback callback) {
21 | this.callback = callback;
22 | }
23 |
24 | public PriorityElementImp(String id, IPriorityPromiseCallback callback) {
25 | this.id = id;
26 | this.callback = callback;
27 | }
28 |
29 | @Override
30 | public IPriorityElement then(IPriorityElement element) {
31 | this.next = (PriorityElementImp, ?>) element;
32 | return element;
33 | }
34 |
35 | @Override
36 | public PriorityElementImp, ?> next() {
37 | return this.next;
38 | }
39 |
40 | @Override
41 | public void executeWithData(Object data) {
42 | promise = new PriorityPromiseImp<>("PriorityPromiseImp -> " + id, this);
43 | promise.setInput((T) data);
44 | callback.run(promise);
45 | }
46 |
47 | @Override
48 | public void executeNextWithData(Object data) {
49 | IPriorityElement nextElement = this.next();
50 | if (null != nextElement) {
51 | nextElement.executeWithData(data);
52 | }
53 | //
54 | handleCompletedWithOutput((E) data);
55 | }
56 |
57 | @Override
58 | public void breakWithError(Error error) {
59 | if (null != errorCallback) {
60 | errorCallback.exception(error);
61 | }
62 | releasePromise();
63 | }
64 |
65 | @Override
66 | public void invalidate() {
67 | if (null != promise) {
68 | promise.invalidate();
69 | }
70 | releasePromise();
71 | }
72 |
73 | private void handleCompletedWithOutput(E o) {
74 | if (null != subscribeCallback) {
75 | subscribeCallback.subscribe(o);
76 | }
77 | releasePromise();
78 | }
79 |
80 | private void releasePromise() {
81 | if (null != promise) {
82 | promise = null;
83 | }
84 | if (null != disposeCallback) {
85 | disposeCallback.dispose();
86 | }
87 | }
88 |
89 | public PriorityElementImp subscribe(IPriorityElementSubscribeCallback subscribeCallback) {
90 | this.subscribeCallback = subscribeCallback;
91 | return this;
92 | }
93 |
94 | public PriorityElementImp exception(IPriorityElementErrorCallback errorCallback) {
95 | this.errorCallback = errorCallback;
96 | return this;
97 | }
98 |
99 | public PriorityElementImp dispose(IPriorityElementDisposeCallback disposeCallback) {
100 | this.disposeCallback = disposeCallback;
101 | return this;
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/Android/app/src/main/java/com/example/promiseprioritychain/PriorityPromiseImp.java:
--------------------------------------------------------------------------------
1 | package com.example.promiseprioritychain;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 | import android.util.Log;
6 | import androidx.annotation.NonNull;
7 |
8 | public class PriorityPromiseImp implements IPriorityPromise {
9 |
10 | private String id = "PriorityPromiseImp";
11 |
12 | private T input = null;
13 | private E output = null;
14 | private Handler handler = null;
15 | private PriorityElementImp element = null;
16 |
17 | public PriorityPromiseImp(PriorityElementImp element) {
18 | this.element = element;
19 | }
20 |
21 | public PriorityPromiseImp(String id, PriorityElementImp element) {
22 | this.id = id;
23 | this.element = element;
24 | }
25 |
26 | @Override
27 | public String getId() {
28 | return id;
29 | }
30 |
31 | @Override
32 | public void setInput(Object i) {
33 | this.input = (T) i;
34 | }
35 |
36 | @Override
37 | public T getInput() {
38 | return this.input;
39 | }
40 |
41 | @Override
42 | public void setOutput(Object o) {
43 | this.output = (E) o;
44 | }
45 |
46 | @Override
47 | public E getOutput() {
48 | return this.output;
49 | }
50 |
51 | @Override
52 | public PriorityElementImp getPriorityElement() {
53 | return this.element;
54 | }
55 |
56 | @Override
57 | public void notifyMainThreadByHandler(int mode, long delay) {
58 | if (null != handler) {
59 | Message msg = handler.obtainMessage();
60 | msg.what = PROMISE_PROORITY_WHAT;
61 | msg.arg1 = mode;
62 | msg.obj = this;
63 | handler.sendMessageDelayed(msg, delay);
64 | return;
65 | }
66 |
67 | handler = new Handler(msg -> {
68 | Log.i("Priority", "1. thread name : " + Thread.currentThread().getName());
69 | //
70 | IPriorityPromise promise = (IPriorityPromise)msg.obj;
71 | if (LOOP_VALIDATED_MODE == msg.arg1) {
72 | promise.getPriorityElement().executeWithData(promise.getInput());
73 | return true;
74 | }
75 | promise.getPriorityElement().executeNextWithData(promise.getInput());
76 | return true;
77 | });
78 |
79 | }
80 |
81 | @Override
82 | public void invalidate() {
83 | handler.removeMessages(PROMISE_PROORITY_WHAT);
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/Android/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
22 |
24 |
26 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
44 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
68 |
70 |
72 |
74 |
75 |
--------------------------------------------------------------------------------
/Android/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RunsCode/PromisePriorityChain/ed03590a911a7598db96562c2c22de8238658a3e/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/Android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PromisePriorityChain
3 |
4 |
--------------------------------------------------------------------------------
/Android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.5.0'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 |
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/Android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 |
21 | android.injected.testOnly=false
22 |
--------------------------------------------------------------------------------
/Android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Mar 28 20:56:23 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/Android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/Android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/Android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | rootProject.name='PromisePriorityChain'
3 |
--------------------------------------------------------------------------------
/Java-Example.md:
--------------------------------------------------------------------------------
1 | ```java
2 | public static int mCount = 0;
3 |
4 | public static void main(String[] args) {
5 |
6 | PriorityElementImp element0 = testElement0();
7 | PriorityElementImp testElement5 = testElement5();
8 |
9 | testElement5.subscribe(s -> {
10 | System.out.println("testElement5 subscribe : " + s);
11 | }).exception(error -> {
12 | System.out.println("testElement5 exception : " + error.getMessage());
13 | }).dispose(() -> {
14 | System.out.println("testElement5 dispose");
15 | });
16 |
17 | element0
18 | .then(testElement1())
19 | .then(testElement2())
20 | .then(testElement3())
21 | .then(testElement4())
22 | .then(testElement5);
23 | element0.executeWithData(10);
24 |
25 | }
26 | ```
27 |
28 | #### Normal operation
29 |
30 |
31 | ```java
32 |
33 | public static PriorityElementImp testElement0() {
34 | return new PriorityElementImp( promise -> {
35 |
36 | Integer t = promise.getInput();
37 | System.out.println("t = " + t.toString());
38 | promise.next(100);
39 |
40 | }).subscribe(integer -> {
41 | System.out.println("element0 subscribe : " + integer);
42 | }).exception(error -> {
43 | System.out.println("element0 exception : " + error.getMessage());
44 | }).dispose(() -> {
45 | System.out.println("element0 dispose");
46 | });
47 | }
48 | ```
49 |
50 | #### Loop delay check operation (e.g. polling)
51 |
52 |
53 | ```java
54 |
55 | public static PriorityElementImp testElement1() {
56 | return new PriorityElementImp( promise -> {
57 |
58 | mCount++;
59 | System.out.println(System.currentTimeMillis() + " mCount = " + mCount);
60 | promise.setOutput(mCount);
61 | System.out.println("100ms查询一次,一共查询5次, 轮询 ");
62 | promise.loopValidated(mCount >= 5, 100);
63 |
64 | }).subscribe(integer -> {
65 | System.out.println("testElement1 subscribe : " + integer);
66 | }).exception(error -> {
67 | System.out.println("testElement1 exception : " + error.getMessage());
68 | }).dispose(() -> {
69 | System.out.println("testElement1 dispose");
70 | });
71 | }
72 | ```
73 |
74 | #### General asynchronous operations
75 |
76 |
77 | ```java
78 |
79 | public static PriorityElementImp testElement2() {
80 | return new PriorityElementImp( promise -> {
81 |
82 | Integer t = promise.getInput();
83 | System.out.println("t = " + t.toString());
84 | promise.next(10000);
85 |
86 | }).subscribe(integer -> {
87 | System.out.println("testElement2 subscribe : " + integer);
88 | }).exception(error -> {
89 | System.out.println("testElement2 exception : " + error.getMessage());
90 | }).dispose(() -> {
91 | System.out.println("testElement2 dispose");
92 | });
93 | }
94 | ```
95 |
96 | #### General check operation (if else nesting)
97 |
98 |
99 |
100 | ```java
101 |
102 | public static PriorityElementImp testElement3() {
103 | return new PriorityElementImp( promise -> {
104 |
105 | Integer t = promise.getInput();
106 | System.out.println("t = " + t.toString());
107 | promise.setOutput("即将延迟校验结束");
108 | promise.validated(t > 100);
109 |
110 | }).subscribe(s -> {
111 | System.out.println("testElement3 subscribe : " + s);
112 | }).exception(error -> {
113 | System.out.println("testElement3 exception : " + error.getMessage());
114 | }).dispose(() -> {
115 | System.out.println("testElement3 dispose");
116 | });
117 | }
118 | ```
119 |
120 | #### Condition check operation
121 |
122 |
123 | ```java
124 |
125 | public static PriorityElementImp testElement4() {
126 | return new PriorityElementImp(promise -> {
127 |
128 | String s = promise.getInput();
129 | System.out.println(s);
130 | System.out.println(System.currentTimeMillis() + " begin 延迟1000ms校验结束");
131 | promise.setOutput("结束了");
132 | promise.condition(mCount >= 5, 1000);
133 |
134 | }).subscribe(s -> {
135 | System.out.println("testElement4 subscribe : " + s);
136 | }).exception(error -> {
137 | System.out.println("testElement4 exception : " + error.getMessage());
138 | }).dispose(() -> {
139 | System.out.println("testElement4 dispose");
140 | });
141 | }
142 | ```
143 | ```java
144 |
145 | public static PriorityElementImp testElement5() {
146 | return new PriorityElementImp<>(promise -> {
147 | System.out.println(System.currentTimeMillis() + " end 延迟1000ms校验结束");
148 | String s = promise.getInput();
149 | System.out.println(s);
150 | // promise.next("game over");
151 | promise.brake(null);
152 | });
153 | }
154 |
155 | ```
156 |
--------------------------------------------------------------------------------
/Java/Priority/Priority.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Java/Priority/src/com/runs/www/DelayComponentImp.java:
--------------------------------------------------------------------------------
1 | package com.runs.www;
2 |
3 | import java.util.Timer;
4 | import java.util.TimerTask;
5 |
6 | public class DelayComponentImp implements IDelayComponent {
7 |
8 | private Timer timer = new Timer();
9 | private IDelayComponentCallback callback;
10 |
11 |
12 | private TimerTask timerTask = new TimerTask() {
13 | @Override
14 | public void run() {
15 | timer.cancel();
16 | callback.onFinish();
17 | }
18 | };
19 |
20 | @Override
21 | public void delay(long delay, IDelayComponentCallback callback) {
22 | this.callback = callback;
23 | timer.schedule(timerTask, delay);
24 | }
25 |
26 | @Override
27 | public void cancel() {
28 | if (null != timer) {
29 | timer.cancel();
30 | timer = null;
31 | }
32 |
33 | if (null != timerTask) {
34 | timerTask = null;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Java/Priority/src/com/runs/www/IDelayComponent.java:
--------------------------------------------------------------------------------
1 | package com.runs.www;
2 |
3 | public interface IDelayComponent {
4 |
5 | void delay(long delay, IDelayComponentCallback callback);
6 |
7 | void cancel();
8 |
9 | }
10 |
11 | @FunctionalInterface
12 | interface IDelayComponentCallback {
13 | void onFinish();
14 | }
15 |
--------------------------------------------------------------------------------
/Java/Priority/src/com/runs/www/IPriorityElementCapable.java:
--------------------------------------------------------------------------------
1 | package com.runs.www;
2 |
3 | public interface IPriorityElementCapable {
4 | }
5 |
6 | @FunctionalInterface
7 | interface IPriorityElementSubscribeCallback {
8 | void subscribe(T t);
9 | }
10 |
11 | @FunctionalInterface
12 | interface IPriorityElementErrorCallback {
13 | void exception(Error error);
14 | }
15 |
16 | @FunctionalInterface
17 | interface IPriorityElementDisposeCallback {
18 | void dispose();
19 | }
20 |
21 | interface IPriorityElement {
22 |
23 | IPriorityElement then(IPriorityElement element);
24 | IPriorityElement next();
25 |
26 | void executeWithData(T input);
27 | void executeNextWithData(Object object);
28 | void breakWithError(Error error);
29 |
30 | void invalidate();
31 | }
32 |
--------------------------------------------------------------------------------
/Java/Priority/src/com/runs/www/IPriorityPromise.java:
--------------------------------------------------------------------------------
1 | package com.runs.www;
2 |
3 | @FunctionalInterface
4 | interface IPriorityPromiseCallback {
5 |
6 | void run(IPriorityPromise promise);
7 |
8 | }
9 |
10 | public interface IPriorityPromise {
11 |
12 | String getId();
13 |
14 | void setInput(T t);
15 | T getInput();
16 |
17 | void setOutput(E o);
18 | E getOutput();
19 |
20 | IPriorityElement getPriorityElement();
21 | IDelayComponent getDelayComponent();
22 |
23 | default void next(E o) {
24 | IPriorityElement e = getPriorityElement();
25 | if (null != e) {
26 | e.executeNextWithData(o);
27 | }
28 | }
29 |
30 | default void brake(Error error) {
31 | if (null == error) {
32 | error = new Error("NO Error Description");
33 | }
34 | getPriorityElement().breakWithError(error);
35 | }
36 |
37 |
38 | default void validated(boolean isValid) {
39 | if (isValid) {
40 | getPriorityElement().executeNextWithData(getOutput());
41 | return;
42 | }
43 | getPriorityElement().breakWithError(new Error("validated failure"));
44 | }
45 |
46 | //TODO:There is a pain point here:
47 | // the action performed by the current thread is switched to another thread,
48 | // and this API is not recommended if it is a UI operation
49 | default void loopValidated(boolean isValid, long interval) {
50 | if (isValid) {
51 | getPriorityElement().executeNextWithData(getOutput());
52 | return;
53 | }
54 |
55 | if (0 > interval) {
56 | Error error = new Error("interval must bigger than 0");
57 | getPriorityElement().breakWithError(error);
58 | return;
59 | }
60 |
61 | getDelayComponent().delay(interval,() -> getPriorityElement().executeWithData(getInput()));
62 | }
63 |
64 | //TODO:There is a pain point here:
65 | // the action performed by the current thread is switched to another thread,
66 | // and this API is not recommended if it is a UI operation
67 | default void condition(boolean isOk, long delay) {
68 | if (!isOk || 0 >= delay) {
69 | getPriorityElement().executeNextWithData(getInput());
70 | return;
71 | }
72 |
73 | getDelayComponent().delay(delay, () -> getPriorityElement().executeNextWithData(getOutput()));
74 | }
75 |
76 | default void invalidate() {
77 | getDelayComponent().cancel();
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/Java/Priority/src/com/runs/www/Main.java:
--------------------------------------------------------------------------------
1 | package com.runs.www;
2 |
3 | public class Main {
4 |
5 | public static int mCount = 0;
6 |
7 | public static void main(String[] args) {
8 |
9 | PriorityElementImp element0 = testElement0();
10 | PriorityElementImp testElement5 = testElement5();
11 |
12 | testElement5.subscribe(s -> {
13 | System.out.println("testElement5 subscribe : " + s);
14 | }).exception(error -> {
15 | System.out.println("testElement5 exception : " + error.getMessage());
16 | }).dispose(() -> {
17 | System.out.println("testElement5 dispose");
18 | });
19 |
20 | element0
21 | .then(testElement1())
22 | .then(testElement2())
23 | .then(testElement3())
24 | .then(testElement4())
25 | .then(testElement5);
26 | element0.executeWithData(10);
27 |
28 | }
29 |
30 | public static PriorityElementImp testElement0() {
31 | return new PriorityElementImp( promise -> {
32 |
33 | Integer t = promise.getInput();
34 | System.out.println("t = " + t.toString());
35 | System.out.println("100ms查询一次,一共查询5次, 轮询 ");
36 | promise.next(100);
37 |
38 | }).subscribe(integer -> {
39 | System.out.println("element0 subscribe : " + integer);
40 | }).exception(error -> {
41 | System.out.println("element0 exception : " + error.getMessage());
42 | }).dispose(() -> {
43 | System.out.println("element0 dispose");
44 | });
45 | }
46 |
47 | public static PriorityElementImp testElement1() {
48 | return new PriorityElementImp( promise -> {
49 |
50 | mCount++;
51 | System.out.println(System.currentTimeMillis() + " mCount = " + mCount);
52 | promise.setOutput(mCount);
53 | promise.loopValidated(mCount >= 5, 100);
54 |
55 | }).subscribe(integer -> {
56 | System.out.println("testElement1 subscribe : " + integer);
57 | }).exception(error -> {
58 | System.out.println("testElement1 exception : " + error.getMessage());
59 | }).dispose(() -> {
60 | System.out.println("testElement1 dispose");
61 | });
62 | }
63 |
64 | public static PriorityElementImp testElement2() {
65 | return new PriorityElementImp( promise -> {
66 |
67 | Integer t = promise.getInput();
68 | System.out.println("t = " + t.toString());
69 | promise.next(10000);
70 |
71 | }).subscribe(integer -> {
72 | System.out.println("testElement2 subscribe : " + integer);
73 | }).exception(error -> {
74 | System.out.println("testElement2 exception : " + error.getMessage());
75 | }).dispose(() -> {
76 | System.out.println("testElement2 dispose");
77 | });
78 | }
79 |
80 | public static PriorityElementImp testElement3() {
81 | return new PriorityElementImp( promise -> {
82 |
83 | Integer t = promise.getInput();
84 | System.out.println("t = " + t.toString());
85 | promise.setOutput("即将延迟校验结束");
86 | promise.validated(t > 100);
87 |
88 | }).subscribe(s -> {
89 | System.out.println("testElement3 subscribe : " + s);
90 | }).exception(error -> {
91 | System.out.println("testElement3 exception : " + error.getMessage());
92 | }).dispose(() -> {
93 | System.out.println("testElement3 dispose");
94 | });
95 | }
96 |
97 | public static PriorityElementImp testElement4() {
98 | return new PriorityElementImp(promise -> {
99 |
100 | String s = promise.getInput();
101 | System.out.println(s);
102 | System.out.println(System.currentTimeMillis() + " begin 延迟1000ms校验结束");
103 | promise.setOutput("结束了");
104 | promise.condition(mCount >= 5, 1000);
105 |
106 | }).subscribe(s -> {
107 | System.out.println("testElement4 subscribe : " + s);
108 | }).exception(error -> {
109 | System.out.println("testElement4 exception : " + error.getMessage());
110 | }).dispose(() -> {
111 | System.out.println("testElement4 dispose");
112 | });
113 | }
114 |
115 | public static PriorityElementImp testElement5() {
116 | return new PriorityElementImp<>(promise -> {
117 | System.out.println(System.currentTimeMillis() + " end 延迟1000ms校验结束");
118 | String s = promise.getInput();
119 | System.out.println(s);
120 | // promise.next("game over");
121 | promise.brake(null);
122 | });
123 | }
124 |
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/Java/Priority/src/com/runs/www/PriorityElementImp.java:
--------------------------------------------------------------------------------
1 | package com.runs.www;
2 |
3 | public class PriorityElementImp implements IPriorityElement {
4 |
5 | private String id = "PriorityElementImp";
6 |
7 | private PriorityPromiseImp promise;
8 |
9 | private IPriorityPromiseCallback callback;
10 |
11 | private PriorityElementImp, ?> next;
12 |
13 | private IPriorityElementSubscribeCallback subscribeCallback;
14 |
15 | private IPriorityElementErrorCallback errorCallback;
16 |
17 | private IPriorityElementDisposeCallback disposeCallback;
18 |
19 |
20 | public PriorityElementImp() {}
21 |
22 | public PriorityElementImp(IPriorityPromiseCallback callback) {
23 | this.callback = callback;
24 | }
25 |
26 | public PriorityElementImp(String id, IPriorityPromiseCallback callback) {
27 | this.id = id;
28 | this.callback = callback;
29 | }
30 |
31 | @Override
32 | public IPriorityElement then(IPriorityElement element) {
33 | this.next = (PriorityElementImp, ?>) element;
34 | return element;
35 | }
36 |
37 | @Override
38 | public PriorityElementImp, ?> next() {
39 | return this.next;
40 | }
41 |
42 | @Override
43 | public void executeWithData(Object data) {
44 | promise = new PriorityPromiseImp<>("PriorityPromiseImp -> " + id, this);
45 | promise.setInput((T) data);
46 | callback.run(promise);
47 | }
48 |
49 | @Override
50 | public void executeNextWithData(Object data) {
51 | IPriorityElement nextElement = this.next();
52 | if (null != nextElement) {
53 | nextElement.executeWithData(data);
54 | }
55 | //
56 | handleCompletedWithOutput((E) data);
57 | }
58 |
59 | @Override
60 | public void breakWithError(Error error) {
61 | if (null != errorCallback) {
62 | errorCallback.exception(error);
63 | }
64 | releasePromise();
65 | }
66 |
67 | @Override
68 | public void invalidate() {
69 | if (null != promise) {
70 | promise.invalidate();
71 | }
72 | releasePromise();
73 | }
74 |
75 | private void handleCompletedWithOutput(E o) {
76 | if (null != subscribeCallback) {
77 | subscribeCallback.subscribe(o);
78 | }
79 | releasePromise();
80 | }
81 |
82 | private void releasePromise() {
83 | if (null != promise) {
84 | promise = null;
85 | }
86 | if (null != disposeCallback) {
87 | disposeCallback.dispose();
88 | }
89 | }
90 |
91 | public PriorityElementImp subscribe(IPriorityElementSubscribeCallback subscribeCallback) {
92 | this.subscribeCallback = subscribeCallback;
93 | return this;
94 | }
95 |
96 | public PriorityElementImp exception(IPriorityElementErrorCallback errorCallback) {
97 | this.errorCallback = errorCallback;
98 | return this;
99 | }
100 |
101 | public PriorityElementImp dispose(IPriorityElementDisposeCallback disposeCallback) {
102 | this.disposeCallback = disposeCallback;
103 | return this;
104 | }
105 |
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/Java/Priority/src/com/runs/www/PriorityPromiseImp.java:
--------------------------------------------------------------------------------
1 | package com.runs.www;
2 |
3 | public class PriorityPromiseImp implements IPriorityPromise {
4 |
5 | private String id = "PriorityPromiseImp";
6 | private PriorityElementImp element;
7 | private DelayComponentImp delayComponentImp;
8 |
9 | private T input = null;
10 | private E output = null;
11 |
12 | public PriorityPromiseImp(PriorityElementImp element) {
13 | this.element = element;
14 | }
15 |
16 | public PriorityPromiseImp(String id, PriorityElementImp element) {
17 | this.id = id;
18 | this.element = element;
19 | }
20 |
21 | @Override
22 | public String getId() {
23 | return id;
24 | }
25 |
26 | @Override
27 | public void setInput(Object i) {
28 | this.input = (T) i;
29 | }
30 |
31 | @Override
32 | public T getInput() {
33 | return this.input;
34 | }
35 |
36 | @Override
37 | public void setOutput(Object o) {
38 | this.output = (E) o;
39 | }
40 |
41 | @Override
42 | public E getOutput() {
43 | return this.output;
44 | }
45 |
46 | @Override
47 | public PriorityElementImp getPriorityElement() {
48 | return this.element;
49 | }
50 |
51 | @Override
52 | public void invalidate() {
53 | IPriorityPromise.super.invalidate();
54 | if (null != delayComponentImp) {
55 | delayComponentImp = null;
56 | }
57 | }
58 |
59 | @Override
60 | public IDelayComponent getDelayComponent() {
61 | if (null != delayComponentImp) {
62 | return delayComponentImp;
63 | }
64 | delayComponentImp = new DelayComponentImp();
65 | return delayComponentImp;
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 dev-wang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/OC-Example.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ```objectivec
4 |
5 | 无需强引用 自引用内存管理 只要保证每一个element 链路完整向下传递或打断即可 promise.xxx()
6 |
7 | PrioritySessionElement *headElement = [self customSession];
8 | PrioritySessionElement *normalAsyncElement = [self normalAsyncElement];
9 | PrioritySessionElement *testElement = [[PromisePriority(NSString *, id) {
10 | promise.next(@"11000");// promise.brake(error);
11 | } identifier:@"testElement"] dispose:^{ ... }];
12 |
13 | headElement
14 | .then(normalAsyncElement)
15 | .then(testElement)
16 | .then(self.loopValidatedElement)
17 | .then(self.conditionDelayElement)
18 | .then(self.validatedElement);
19 | ///
20 | [headElement executeWithData:@(-2)];
21 |
22 | ```
23 |
24 | * 常规校验操作 Element (if else 嵌套)
25 |
26 | ``` objectivec
27 | - (PrioritySessionElement *)validatedElement {
28 | return [[[[PromisePriority(NSString *, NSNumber *){
29 | promise.output = @10086;
30 | promise.validated(isValid);
31 | } identifier:@"validatedElement"] subscribe:^(NSNumber * _Nullable value) {
32 | NSLog(@"validatedElement subscribe data = %@", value);
33 | }] catch:^(NSError * _Nullable error) { ... }] dispose:^{ ...}];
34 | ```
35 |
36 | * 状态延迟校验Element
37 |
38 |
39 | ``` objectivec
40 | - (PrioritySessionElement *)conditionDelayElement {
41 | return [[[[PromisePriority(NSNumber *, NSString *) {
42 | promise.output = @"10098";
43 | promise.conditionDelay(conditionIsOK, 3.f);
44 | } identifier:@"conditionDelayElement"]];
45 | }
46 | ```
47 |
48 | * 循环延迟校验Element(轮询)
49 |
50 |
51 | ``` objectivec
52 | - (PrioritySessionElement *)loopValidatedElement {
53 | return [PromisePriority(NSString *, NSNumber *) {
54 | promise.output = @(1);
55 | promise.loopValidated(isValid, 1.f);
56 | }];
57 | }
58 | ```
59 |
60 | * 常规异步Element
61 |
62 |
63 | ``` objectivec
64 |
65 | - (PrioritySessionElement *)normalAsyncElement {
66 | return [PromisePriority(NSNumber *, NSString *) {...}];
67 | }
68 | ```
69 |
70 | * 自定义实现Element
71 |
72 | ``` objectivec
73 |
74 | - (PrioritySessionElement *)customSession {
75 | return [PrioritySessionCustomElement new];
76 | }
77 |
78 | ```
79 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4F103CB02425F79900429074 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CAF2425F79900429074 /* AppDelegate.m */; };
11 | 4F103CB32425F79900429074 /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CB22425F79900429074 /* SceneDelegate.m */; };
12 | 4F103CB62425F79900429074 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CB52425F79900429074 /* ViewController.m */; };
13 | 4F103CB92425F79900429074 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4F103CB72425F79900429074 /* Main.storyboard */; };
14 | 4F103CBB2425F79B00429074 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4F103CBA2425F79B00429074 /* Assets.xcassets */; };
15 | 4F103CBE2425F79B00429074 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4F103CBC2425F79B00429074 /* LaunchScreen.storyboard */; };
16 | 4F103CC12425F79B00429074 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CC02425F79B00429074 /* main.m */; };
17 | 4F103CCB2425F79B00429074 /* PromisePriorityChainTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CCA2425F79B00429074 /* PromisePriorityChainTests.m */; };
18 | 4F103CDE2425F7DB00429074 /* PrioritySessionElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CD92425F7DB00429074 /* PrioritySessionElement.m */; };
19 | 4F103CDF2425F7DB00429074 /* PrioritySessionElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CD92425F7DB00429074 /* PrioritySessionElement.m */; };
20 | 4F103CE02425F7DB00429074 /* PriorityPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CDA2425F7DB00429074 /* PriorityPromise.m */; };
21 | 4F103CE12425F7DB00429074 /* PriorityPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CDA2425F7DB00429074 /* PriorityPromise.m */; };
22 | 4F103CE22425F7DB00429074 /* PriorityDemo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CDC2425F7DB00429074 /* PriorityDemo.m */; };
23 | 4F103CE32425F7DB00429074 /* PriorityDemo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CDC2425F7DB00429074 /* PriorityDemo.m */; };
24 | 4F103CE62425F7EC00429074 /* PrioritySessionCustomElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CE42425F7EC00429074 /* PrioritySessionCustomElement.m */; };
25 | 4F103CE72425F7EC00429074 /* PrioritySessionCustomElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CE42425F7EC00429074 /* PrioritySessionCustomElement.m */; };
26 | /* End PBXBuildFile section */
27 |
28 | /* Begin PBXContainerItemProxy section */
29 | 4F103CC72425F79B00429074 /* PBXContainerItemProxy */ = {
30 | isa = PBXContainerItemProxy;
31 | containerPortal = 4F103CA32425F79900429074 /* Project object */;
32 | proxyType = 1;
33 | remoteGlobalIDString = 4F103CAA2425F79900429074;
34 | remoteInfo = PromisePriorityChain;
35 | };
36 | /* End PBXContainerItemProxy section */
37 |
38 | /* Begin PBXFileReference section */
39 | 4F103CAB2425F79900429074 /* PromisePriorityChain.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PromisePriorityChain.app; sourceTree = BUILT_PRODUCTS_DIR; };
40 | 4F103CAE2425F79900429074 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
41 | 4F103CAF2425F79900429074 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
42 | 4F103CB12425F79900429074 /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = ""; };
43 | 4F103CB22425F79900429074 /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = ""; };
44 | 4F103CB42425F79900429074 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
45 | 4F103CB52425F79900429074 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
46 | 4F103CB82425F79900429074 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
47 | 4F103CBA2425F79B00429074 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
48 | 4F103CBD2425F79B00429074 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
49 | 4F103CBF2425F79B00429074 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
50 | 4F103CC02425F79B00429074 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
51 | 4F103CC62425F79B00429074 /* PromisePriorityChainTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PromisePriorityChainTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 4F103CCA2425F79B00429074 /* PromisePriorityChainTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PromisePriorityChainTests.m; sourceTree = ""; };
53 | 4F103CCC2425F79B00429074 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
54 | 4F103CD62425F7DB00429074 /* PriorityElementProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PriorityElementProtocol.h; sourceTree = ""; };
55 | 4F103CD72425F7DB00429074 /* PrioritySessionElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrioritySessionElement.h; sourceTree = ""; };
56 | 4F103CD82425F7DB00429074 /* PriorityPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PriorityPromise.h; sourceTree = ""; };
57 | 4F103CD92425F7DB00429074 /* PrioritySessionElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrioritySessionElement.m; sourceTree = ""; };
58 | 4F103CDA2425F7DB00429074 /* PriorityPromise.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PriorityPromise.m; sourceTree = ""; };
59 | 4F103CDC2425F7DB00429074 /* PriorityDemo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PriorityDemo.m; sourceTree = ""; };
60 | 4F103CDD2425F7DB00429074 /* PriorityDemo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PriorityDemo.h; sourceTree = ""; };
61 | 4F103CE42425F7EC00429074 /* PrioritySessionCustomElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrioritySessionCustomElement.m; sourceTree = ""; };
62 | 4F103CE52425F7EC00429074 /* PrioritySessionCustomElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrioritySessionCustomElement.h; sourceTree = ""; };
63 | 4FE36FB324D2EDBA003DAB3B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
64 | /* End PBXFileReference section */
65 |
66 | /* Begin PBXFrameworksBuildPhase section */
67 | 4F103CA82425F79900429074 /* Frameworks */ = {
68 | isa = PBXFrameworksBuildPhase;
69 | buildActionMask = 2147483647;
70 | files = (
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | 4F103CC32425F79B00429074 /* Frameworks */ = {
75 | isa = PBXFrameworksBuildPhase;
76 | buildActionMask = 2147483647;
77 | files = (
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | /* End PBXFrameworksBuildPhase section */
82 |
83 | /* Begin PBXGroup section */
84 | 4F103CA22425F79900429074 = {
85 | isa = PBXGroup;
86 | children = (
87 | 4F103CAD2425F79900429074 /* PromisePriorityChain */,
88 | 4F103CC92425F79B00429074 /* PromisePriorityChainTests */,
89 | 4F103CAC2425F79900429074 /* Products */,
90 | 4FE36FB224D2EDBA003DAB3B /* Frameworks */,
91 | );
92 | sourceTree = "";
93 | };
94 | 4F103CAC2425F79900429074 /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 4F103CAB2425F79900429074 /* PromisePriorityChain.app */,
98 | 4F103CC62425F79B00429074 /* PromisePriorityChainTests.xctest */,
99 | );
100 | name = Products;
101 | sourceTree = "";
102 | };
103 | 4F103CAD2425F79900429074 /* PromisePriorityChain */ = {
104 | isa = PBXGroup;
105 | children = (
106 | 4F103CD52425F7DB00429074 /* Priority */,
107 | 4F103CDB2425F7DB00429074 /* Test */,
108 | 4F103CAE2425F79900429074 /* AppDelegate.h */,
109 | 4F103CAF2425F79900429074 /* AppDelegate.m */,
110 | 4F103CB12425F79900429074 /* SceneDelegate.h */,
111 | 4F103CB22425F79900429074 /* SceneDelegate.m */,
112 | 4F103CB42425F79900429074 /* ViewController.h */,
113 | 4F103CB52425F79900429074 /* ViewController.m */,
114 | 4F103CB72425F79900429074 /* Main.storyboard */,
115 | 4F103CBA2425F79B00429074 /* Assets.xcassets */,
116 | 4F103CBC2425F79B00429074 /* LaunchScreen.storyboard */,
117 | 4F103CBF2425F79B00429074 /* Info.plist */,
118 | 4F103CC02425F79B00429074 /* main.m */,
119 | );
120 | path = PromisePriorityChain;
121 | sourceTree = "";
122 | };
123 | 4F103CC92425F79B00429074 /* PromisePriorityChainTests */ = {
124 | isa = PBXGroup;
125 | children = (
126 | 4F103CCA2425F79B00429074 /* PromisePriorityChainTests.m */,
127 | 4F103CCC2425F79B00429074 /* Info.plist */,
128 | );
129 | path = PromisePriorityChainTests;
130 | sourceTree = "";
131 | };
132 | 4F103CD52425F7DB00429074 /* Priority */ = {
133 | isa = PBXGroup;
134 | children = (
135 | 4F103CD62425F7DB00429074 /* PriorityElementProtocol.h */,
136 | 4F103CD82425F7DB00429074 /* PriorityPromise.h */,
137 | 4F103CDA2425F7DB00429074 /* PriorityPromise.m */,
138 | 4F103CD72425F7DB00429074 /* PrioritySessionElement.h */,
139 | 4F103CD92425F7DB00429074 /* PrioritySessionElement.m */,
140 | );
141 | path = Priority;
142 | sourceTree = "";
143 | };
144 | 4F103CDB2425F7DB00429074 /* Test */ = {
145 | isa = PBXGroup;
146 | children = (
147 | 4F103CDD2425F7DB00429074 /* PriorityDemo.h */,
148 | 4F103CDC2425F7DB00429074 /* PriorityDemo.m */,
149 | 4F103CE52425F7EC00429074 /* PrioritySessionCustomElement.h */,
150 | 4F103CE42425F7EC00429074 /* PrioritySessionCustomElement.m */,
151 | );
152 | path = Test;
153 | sourceTree = "";
154 | };
155 | 4FE36FB224D2EDBA003DAB3B /* Frameworks */ = {
156 | isa = PBXGroup;
157 | children = (
158 | 4FE36FB324D2EDBA003DAB3B /* UIKit.framework */,
159 | );
160 | name = Frameworks;
161 | sourceTree = "";
162 | };
163 | /* End PBXGroup section */
164 |
165 | /* Begin PBXNativeTarget section */
166 | 4F103CAA2425F79900429074 /* PromisePriorityChain */ = {
167 | isa = PBXNativeTarget;
168 | buildConfigurationList = 4F103CCF2425F79B00429074 /* Build configuration list for PBXNativeTarget "PromisePriorityChain" */;
169 | buildPhases = (
170 | 4F103CA72425F79900429074 /* Sources */,
171 | 4F103CA82425F79900429074 /* Frameworks */,
172 | 4F103CA92425F79900429074 /* Resources */,
173 | );
174 | buildRules = (
175 | );
176 | dependencies = (
177 | );
178 | name = PromisePriorityChain;
179 | productName = PromisePriorityChain;
180 | productReference = 4F103CAB2425F79900429074 /* PromisePriorityChain.app */;
181 | productType = "com.apple.product-type.application";
182 | };
183 | 4F103CC52425F79B00429074 /* PromisePriorityChainTests */ = {
184 | isa = PBXNativeTarget;
185 | buildConfigurationList = 4F103CD22425F79B00429074 /* Build configuration list for PBXNativeTarget "PromisePriorityChainTests" */;
186 | buildPhases = (
187 | 4F103CC22425F79B00429074 /* Sources */,
188 | 4F103CC32425F79B00429074 /* Frameworks */,
189 | 4F103CC42425F79B00429074 /* Resources */,
190 | );
191 | buildRules = (
192 | );
193 | dependencies = (
194 | 4F103CC82425F79B00429074 /* PBXTargetDependency */,
195 | );
196 | name = PromisePriorityChainTests;
197 | productName = PromisePriorityChainTests;
198 | productReference = 4F103CC62425F79B00429074 /* PromisePriorityChainTests.xctest */;
199 | productType = "com.apple.product-type.bundle.unit-test";
200 | };
201 | /* End PBXNativeTarget section */
202 |
203 | /* Begin PBXProject section */
204 | 4F103CA32425F79900429074 /* Project object */ = {
205 | isa = PBXProject;
206 | attributes = {
207 | LastUpgradeCheck = 1110;
208 | ORGANIZATIONNAME = "王亚军";
209 | TargetAttributes = {
210 | 4F103CAA2425F79900429074 = {
211 | CreatedOnToolsVersion = 11.1;
212 | };
213 | 4F103CC52425F79B00429074 = {
214 | CreatedOnToolsVersion = 11.1;
215 | TestTargetID = 4F103CAA2425F79900429074;
216 | };
217 | };
218 | };
219 | buildConfigurationList = 4F103CA62425F79900429074 /* Build configuration list for PBXProject "PromisePriorityChain" */;
220 | compatibilityVersion = "Xcode 9.3";
221 | developmentRegion = en;
222 | hasScannedForEncodings = 0;
223 | knownRegions = (
224 | en,
225 | Base,
226 | );
227 | mainGroup = 4F103CA22425F79900429074;
228 | productRefGroup = 4F103CAC2425F79900429074 /* Products */;
229 | projectDirPath = "";
230 | projectRoot = "";
231 | targets = (
232 | 4F103CAA2425F79900429074 /* PromisePriorityChain */,
233 | 4F103CC52425F79B00429074 /* PromisePriorityChainTests */,
234 | );
235 | };
236 | /* End PBXProject section */
237 |
238 | /* Begin PBXResourcesBuildPhase section */
239 | 4F103CA92425F79900429074 /* Resources */ = {
240 | isa = PBXResourcesBuildPhase;
241 | buildActionMask = 2147483647;
242 | files = (
243 | 4F103CBE2425F79B00429074 /* LaunchScreen.storyboard in Resources */,
244 | 4F103CBB2425F79B00429074 /* Assets.xcassets in Resources */,
245 | 4F103CB92425F79900429074 /* Main.storyboard in Resources */,
246 | );
247 | runOnlyForDeploymentPostprocessing = 0;
248 | };
249 | 4F103CC42425F79B00429074 /* Resources */ = {
250 | isa = PBXResourcesBuildPhase;
251 | buildActionMask = 2147483647;
252 | files = (
253 | );
254 | runOnlyForDeploymentPostprocessing = 0;
255 | };
256 | /* End PBXResourcesBuildPhase section */
257 |
258 | /* Begin PBXSourcesBuildPhase section */
259 | 4F103CA72425F79900429074 /* Sources */ = {
260 | isa = PBXSourcesBuildPhase;
261 | buildActionMask = 2147483647;
262 | files = (
263 | 4F103CB62425F79900429074 /* ViewController.m in Sources */,
264 | 4F103CB02425F79900429074 /* AppDelegate.m in Sources */,
265 | 4F103CDE2425F7DB00429074 /* PrioritySessionElement.m in Sources */,
266 | 4F103CC12425F79B00429074 /* main.m in Sources */,
267 | 4F103CE62425F7EC00429074 /* PrioritySessionCustomElement.m in Sources */,
268 | 4F103CB32425F79900429074 /* SceneDelegate.m in Sources */,
269 | 4F103CE22425F7DB00429074 /* PriorityDemo.m in Sources */,
270 | 4F103CE02425F7DB00429074 /* PriorityPromise.m in Sources */,
271 | );
272 | runOnlyForDeploymentPostprocessing = 0;
273 | };
274 | 4F103CC22425F79B00429074 /* Sources */ = {
275 | isa = PBXSourcesBuildPhase;
276 | buildActionMask = 2147483647;
277 | files = (
278 | 4F103CE32425F7DB00429074 /* PriorityDemo.m in Sources */,
279 | 4F103CCB2425F79B00429074 /* PromisePriorityChainTests.m in Sources */,
280 | 4F103CDF2425F7DB00429074 /* PrioritySessionElement.m in Sources */,
281 | 4F103CE72425F7EC00429074 /* PrioritySessionCustomElement.m in Sources */,
282 | 4F103CE12425F7DB00429074 /* PriorityPromise.m in Sources */,
283 | );
284 | runOnlyForDeploymentPostprocessing = 0;
285 | };
286 | /* End PBXSourcesBuildPhase section */
287 |
288 | /* Begin PBXTargetDependency section */
289 | 4F103CC82425F79B00429074 /* PBXTargetDependency */ = {
290 | isa = PBXTargetDependency;
291 | target = 4F103CAA2425F79900429074 /* PromisePriorityChain */;
292 | targetProxy = 4F103CC72425F79B00429074 /* PBXContainerItemProxy */;
293 | };
294 | /* End PBXTargetDependency section */
295 |
296 | /* Begin PBXVariantGroup section */
297 | 4F103CB72425F79900429074 /* Main.storyboard */ = {
298 | isa = PBXVariantGroup;
299 | children = (
300 | 4F103CB82425F79900429074 /* Base */,
301 | );
302 | name = Main.storyboard;
303 | sourceTree = "";
304 | };
305 | 4F103CBC2425F79B00429074 /* LaunchScreen.storyboard */ = {
306 | isa = PBXVariantGroup;
307 | children = (
308 | 4F103CBD2425F79B00429074 /* Base */,
309 | );
310 | name = LaunchScreen.storyboard;
311 | sourceTree = "";
312 | };
313 | /* End PBXVariantGroup section */
314 |
315 | /* Begin XCBuildConfiguration section */
316 | 4F103CCD2425F79B00429074 /* Debug */ = {
317 | isa = XCBuildConfiguration;
318 | buildSettings = {
319 | ALWAYS_SEARCH_USER_PATHS = NO;
320 | CLANG_ANALYZER_NONNULL = YES;
321 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
322 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
323 | CLANG_CXX_LIBRARY = "libc++";
324 | CLANG_ENABLE_MODULES = YES;
325 | CLANG_ENABLE_OBJC_ARC = YES;
326 | CLANG_ENABLE_OBJC_WEAK = YES;
327 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
328 | CLANG_WARN_BOOL_CONVERSION = YES;
329 | CLANG_WARN_COMMA = YES;
330 | CLANG_WARN_CONSTANT_CONVERSION = YES;
331 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
333 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
334 | CLANG_WARN_EMPTY_BODY = YES;
335 | CLANG_WARN_ENUM_CONVERSION = YES;
336 | CLANG_WARN_INFINITE_RECURSION = YES;
337 | CLANG_WARN_INT_CONVERSION = YES;
338 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
339 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
340 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
341 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
342 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
343 | CLANG_WARN_STRICT_PROTOTYPES = YES;
344 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
345 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
346 | CLANG_WARN_UNREACHABLE_CODE = YES;
347 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
348 | COPY_PHASE_STRIP = NO;
349 | DEBUG_INFORMATION_FORMAT = dwarf;
350 | ENABLE_STRICT_OBJC_MSGSEND = YES;
351 | ENABLE_TESTABILITY = YES;
352 | GCC_C_LANGUAGE_STANDARD = gnu11;
353 | GCC_DYNAMIC_NO_PIC = NO;
354 | GCC_NO_COMMON_BLOCKS = YES;
355 | GCC_OPTIMIZATION_LEVEL = 0;
356 | GCC_PREPROCESSOR_DEFINITIONS = (
357 | "DEBUG=1",
358 | "$(inherited)",
359 | );
360 | GCC_VERSION = "";
361 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
362 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
363 | GCC_WARN_UNDECLARED_SELECTOR = YES;
364 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
365 | GCC_WARN_UNUSED_FUNCTION = YES;
366 | GCC_WARN_UNUSED_VARIABLE = YES;
367 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
368 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
369 | MTL_FAST_MATH = YES;
370 | ONLY_ACTIVE_ARCH = YES;
371 | OTHER_CFLAGS = "";
372 | SDKROOT = iphoneos;
373 | };
374 | name = Debug;
375 | };
376 | 4F103CCE2425F79B00429074 /* Release */ = {
377 | isa = XCBuildConfiguration;
378 | buildSettings = {
379 | ALWAYS_SEARCH_USER_PATHS = NO;
380 | CLANG_ANALYZER_NONNULL = YES;
381 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
382 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
383 | CLANG_CXX_LIBRARY = "libc++";
384 | CLANG_ENABLE_MODULES = YES;
385 | CLANG_ENABLE_OBJC_ARC = YES;
386 | CLANG_ENABLE_OBJC_WEAK = YES;
387 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
388 | CLANG_WARN_BOOL_CONVERSION = YES;
389 | CLANG_WARN_COMMA = YES;
390 | CLANG_WARN_CONSTANT_CONVERSION = YES;
391 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
392 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
393 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
394 | CLANG_WARN_EMPTY_BODY = YES;
395 | CLANG_WARN_ENUM_CONVERSION = YES;
396 | CLANG_WARN_INFINITE_RECURSION = YES;
397 | CLANG_WARN_INT_CONVERSION = YES;
398 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
399 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
400 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
401 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
402 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
403 | CLANG_WARN_STRICT_PROTOTYPES = YES;
404 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
405 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
406 | CLANG_WARN_UNREACHABLE_CODE = YES;
407 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
408 | COPY_PHASE_STRIP = NO;
409 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
410 | ENABLE_NS_ASSERTIONS = NO;
411 | ENABLE_STRICT_OBJC_MSGSEND = YES;
412 | GCC_C_LANGUAGE_STANDARD = gnu11;
413 | GCC_NO_COMMON_BLOCKS = YES;
414 | GCC_VERSION = "";
415 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
416 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
417 | GCC_WARN_UNDECLARED_SELECTOR = YES;
418 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
419 | GCC_WARN_UNUSED_FUNCTION = YES;
420 | GCC_WARN_UNUSED_VARIABLE = YES;
421 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
422 | MTL_ENABLE_DEBUG_INFO = NO;
423 | MTL_FAST_MATH = YES;
424 | OTHER_CFLAGS = "";
425 | SDKROOT = iphoneos;
426 | VALIDATE_PRODUCT = YES;
427 | };
428 | name = Release;
429 | };
430 | 4F103CD02425F79B00429074 /* Debug */ = {
431 | isa = XCBuildConfiguration;
432 | buildSettings = {
433 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
434 | CODE_SIGN_STYLE = Automatic;
435 | COMPILER_INDEX_STORE_ENABLE = YES;
436 | DEVELOPMENT_TEAM = KPSKY2677A;
437 | GCC_VERSION = "";
438 | INFOPLIST_FILE = PromisePriorityChain/Info.plist;
439 | LD_RUNPATH_SEARCH_PATHS = (
440 | "$(inherited)",
441 | "@executable_path/Frameworks",
442 | );
443 | PRODUCT_BUNDLE_IDENTIFIER = Runs.PromisePriorityChain;
444 | PRODUCT_NAME = "$(TARGET_NAME)";
445 | TARGETED_DEVICE_FAMILY = "1,2";
446 | };
447 | name = Debug;
448 | };
449 | 4F103CD12425F79B00429074 /* Release */ = {
450 | isa = XCBuildConfiguration;
451 | buildSettings = {
452 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
453 | CODE_SIGN_STYLE = Automatic;
454 | COMPILER_INDEX_STORE_ENABLE = YES;
455 | DEVELOPMENT_TEAM = KPSKY2677A;
456 | GCC_VERSION = "";
457 | INFOPLIST_FILE = PromisePriorityChain/Info.plist;
458 | LD_RUNPATH_SEARCH_PATHS = (
459 | "$(inherited)",
460 | "@executable_path/Frameworks",
461 | );
462 | PRODUCT_BUNDLE_IDENTIFIER = Runs.PromisePriorityChain;
463 | PRODUCT_NAME = "$(TARGET_NAME)";
464 | TARGETED_DEVICE_FAMILY = "1,2";
465 | };
466 | name = Release;
467 | };
468 | 4F103CD32425F79B00429074 /* Debug */ = {
469 | isa = XCBuildConfiguration;
470 | buildSettings = {
471 | BUNDLE_LOADER = "$(TEST_HOST)";
472 | CODE_SIGN_STYLE = Automatic;
473 | DEVELOPMENT_TEAM = KPSKY2677A;
474 | INFOPLIST_FILE = PromisePriorityChainTests/Info.plist;
475 | IPHONEOS_DEPLOYMENT_TARGET = 13.1;
476 | LD_RUNPATH_SEARCH_PATHS = (
477 | "$(inherited)",
478 | "@executable_path/Frameworks",
479 | "@loader_path/Frameworks",
480 | );
481 | PRODUCT_BUNDLE_IDENTIFIER = Runs.PromisePriorityChainTests;
482 | PRODUCT_NAME = "$(TARGET_NAME)";
483 | TARGETED_DEVICE_FAMILY = "1,2";
484 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PromisePriorityChain.app/PromisePriorityChain";
485 | };
486 | name = Debug;
487 | };
488 | 4F103CD42425F79B00429074 /* Release */ = {
489 | isa = XCBuildConfiguration;
490 | buildSettings = {
491 | BUNDLE_LOADER = "$(TEST_HOST)";
492 | CODE_SIGN_STYLE = Automatic;
493 | DEVELOPMENT_TEAM = KPSKY2677A;
494 | INFOPLIST_FILE = PromisePriorityChainTests/Info.plist;
495 | IPHONEOS_DEPLOYMENT_TARGET = 13.1;
496 | LD_RUNPATH_SEARCH_PATHS = (
497 | "$(inherited)",
498 | "@executable_path/Frameworks",
499 | "@loader_path/Frameworks",
500 | );
501 | PRODUCT_BUNDLE_IDENTIFIER = Runs.PromisePriorityChainTests;
502 | PRODUCT_NAME = "$(TARGET_NAME)";
503 | TARGETED_DEVICE_FAMILY = "1,2";
504 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PromisePriorityChain.app/PromisePriorityChain";
505 | };
506 | name = Release;
507 | };
508 | /* End XCBuildConfiguration section */
509 |
510 | /* Begin XCConfigurationList section */
511 | 4F103CA62425F79900429074 /* Build configuration list for PBXProject "PromisePriorityChain" */ = {
512 | isa = XCConfigurationList;
513 | buildConfigurations = (
514 | 4F103CCD2425F79B00429074 /* Debug */,
515 | 4F103CCE2425F79B00429074 /* Release */,
516 | );
517 | defaultConfigurationIsVisible = 0;
518 | defaultConfigurationName = Release;
519 | };
520 | 4F103CCF2425F79B00429074 /* Build configuration list for PBXNativeTarget "PromisePriorityChain" */ = {
521 | isa = XCConfigurationList;
522 | buildConfigurations = (
523 | 4F103CD02425F79B00429074 /* Debug */,
524 | 4F103CD12425F79B00429074 /* Release */,
525 | );
526 | defaultConfigurationIsVisible = 0;
527 | defaultConfigurationName = Release;
528 | };
529 | 4F103CD22425F79B00429074 /* Build configuration list for PBXNativeTarget "PromisePriorityChainTests" */ = {
530 | isa = XCConfigurationList;
531 | buildConfigurations = (
532 | 4F103CD32425F79B00429074 /* Debug */,
533 | 4F103CD42425F79B00429074 /* Release */,
534 | );
535 | defaultConfigurationIsVisible = 0;
536 | defaultConfigurationName = Release;
537 | };
538 | /* End XCConfigurationList section */
539 | };
540 | rootObject = 4F103CA32425F79900429074 /* Project object */;
541 | }
542 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain.xcodeproj/xcshareddata/xcschemes/PromisePriorityChain.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
34 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
71 |
73 |
79 |
80 |
81 |
82 |
84 |
85 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "PriorityDemo.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
20 | // Override point for customization after application launch.
21 | [PriorityDemo new];
22 | return YES;
23 | }
24 |
25 |
26 | #pragma mark - UISceneSession lifecycle
27 |
28 | //
29 | //- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
30 | // // Called when a new scene session is being created.
31 | // // Use this method to select a configuration to create the new scene with.
32 | // return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
33 | //}
34 | //
35 | //
36 | //- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions API_AVAILABLE(ios(13.0)){
37 | // // Called when the user discards a scene session.
38 | // // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
39 | // // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
40 | //}
41 |
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Priority/PriorityElementProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // PriorityElementProtocol.h
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2019/12/31.
6 | // Copyright © 2019 RunsCode. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class PriorityPromise;
12 |
13 | typedef NS_ENUM(NSUInteger, JYPriorityErrorEnum) {
14 | PriorityValidatedError = 100000,
15 | PriorityLoopValidatedError = 110000,
16 | };
17 |
18 |
19 | NS_ASSUME_NONNULL_BEGIN
20 |
21 | @protocol PriorityElementProtocol
22 |
23 | @required
24 | - (void)nextWithValue:(id _Nullable)value;
25 | - (void)breakProcess;
26 |
27 | - (void)onSubscribe:(id _Nullable)data;
28 | - (void)onCatch:(NSError *_Nullable)error;
29 |
30 | /// can not override by subclass
31 | - (void)execute;
32 | - (void)executeWithData:(id _Nullable)data;
33 |
34 | /// override by subclass
35 | - (void)executePromise:(PriorityPromise *)promise;
36 |
37 | @end
38 |
39 | NS_ASSUME_NONNULL_END
40 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Priority/PriorityPromise.h:
--------------------------------------------------------------------------------
1 | //
2 | // JYPriorityPromise.h
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2019/12/31.
6 | // Copyright © 2019 RunsCode. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @protocol PriorityElementProtocol;
15 |
16 | @interface PriorityPromise : NSObject
17 |
18 | typedef void(^PriorityPromiseNext)(Output _Nullable value);
19 | typedef void(^PriorityPromiseBreak)(NSError *_Nullable err);
20 | typedef void(^PriorityPromiseValidated)(BOOL isValid);
21 | typedef void(^PriorityPromiseLoopValidated)(BOOL isValid, NSTimeInterval interval);
22 | typedef void(^PriorityPromiseConditionDelay)(BOOL condition, NSTimeInterval interval);
23 |
24 | @property (nonatomic, copy) NSString *identifier;
25 |
26 | @property (nonatomic, strong) id element;
27 |
28 | /// Pipeline data delivery
29 | @property (nonatomic, strong) Input input;
30 | @property (nonatomic, strong) Output output;
31 |
32 | /// execute next element
33 | @property (nonatomic, strong, readonly) PriorityPromiseNext next;
34 |
35 | /// Check execution Check by executing the next or interrupting the current process
36 | /// validated(BOOL isValid)
37 | ///
38 | /// @parameter isValid Judge conditions for next
39 | /// Similar to if(isValid) next()
40 | /// isValid == false -> will call brake error and call catch block
41 | @property (nonatomic, strong, readonly) PriorityPromiseValidated validated;
42 |
43 | /// Cycle check until the check pass (isValid is true) to perform the next interval check interval default 0
44 | /// loopValidated(BOOL isValid, NSTimeInterval interval)
45 | ///
46 | /// @parameter isValid Judge conditions for polling
47 | /// if isValid is false,start loop self,
48 | /// if isValid is true, end loop and execute next element
49 | ///
50 | /// @parameter interval if interval < 0, will call brake error and call catch block
51 |
52 | @property (nonatomic, strong, readonly) PriorityPromiseLoopValidated loopValidated;
53 |
54 | /// Check whether the condition needs to delay the next step
55 | ///
56 | /// @parameter condition
57 | /// @parameter interval time interval
58 | ///
59 | /// (condition == true && interval > 0) -> delay interval execute next element
60 | /// (condition == false || interval <= 0) -> execute next element
61 | ///
62 | @property (nonatomic, strong, readonly) PriorityPromiseConditionDelay conditionDelay;
63 |
64 | /// Break the current process, release all objects after the list
65 | @property (nonatomic, strong, readonly) PriorityPromiseBreak brake;
66 |
67 | + (instancetype)promiseWithInput:(Input)data element:(id)ele;
68 | + (instancetype)promiseWithInput:(Input)data element:(id)ele identifier:(NSString *)identidier;
69 | - (void)breakLoop;
70 |
71 | @end
72 |
73 | NS_ASSUME_NONNULL_END
74 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Priority/PriorityPromise.m:
--------------------------------------------------------------------------------
1 | //
2 | // PriorityPromise.m
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2019/12/31.
6 | // Copyright © 2019 RunsCode. All rights reserved.
7 | //
8 |
9 | #import "PriorityPromise.h"
10 | #import "PriorityElementProtocol.h"
11 | #ifndef weakify
12 | #if DEBUG
13 | #if __has_feature(objc_arc)
14 | #define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
15 | #else
16 | #define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
17 | #endif
18 | #else
19 | #if __has_feature(objc_arc)
20 | #define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
21 | #else
22 | #define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
23 | #endif
24 | #endif
25 | #endif
26 |
27 | #ifndef strongify
28 | #if DEBUG
29 | #if __has_feature(objc_arc)
30 | #define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
31 | #else
32 | #define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
33 | #endif
34 | #else
35 | #if __has_feature(objc_arc)
36 | #define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
37 | #else
38 | #define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
39 | #endif
40 | #endif
41 | #endif
42 |
43 | @interface PriorityPromise ()
44 |
45 | @end
46 |
47 | @implementation PriorityPromise
48 |
49 | #ifdef DEBUG
50 | - (void)dealloc {
51 | NSLog(@"❤️❤️%s , id : %@❤️❤️", __PRETTY_FUNCTION__, _identifier);
52 | }
53 | #endif
54 |
55 | + (instancetype)promiseWithInput:(id)data element:(id)ele {
56 | PriorityPromise *p = [[PriorityPromise alloc] init];
57 | p.input = data;
58 | p.element = ele;
59 | return p;
60 | }
61 |
62 | + (instancetype)promiseWithInput:(id)data element:(id)ele identifier:(NSString *)identidier {
63 | PriorityPromise *p = [PriorityPromise promiseWithInput:data element:ele];
64 | p.identifier = identidier;
65 | return p;
66 | }
67 |
68 | - (PriorityPromiseBreak)brake {
69 | @weakify(self)
70 | return ^(NSError *_Nullable err) {
71 | @strongify(self)
72 | [self.element onCatch:err];
73 | };
74 | }
75 |
76 | - (PriorityPromiseNext)next {
77 | @weakify(self)
78 | return ^(id _Nullable data) {
79 | @strongify(self)
80 | [self.element onSubscribe:!self.output ? data : self.output];
81 | [self.element nextWithValue:data];
82 | };
83 | }
84 |
85 | - (PriorityPromiseValidated)validated {
86 | @weakify(self)
87 | return ^(BOOL bValue) {
88 | @strongify(self)
89 | if (bValue) {
90 | [self.element onSubscribe:self.output];
91 | [self.element nextWithValue:self.output];
92 | return;
93 | }
94 | NSError *err = [NSError errorWithDomain:@"validated failure" code:PriorityValidatedError userInfo:nil];
95 | [self.element onCatch:err];
96 | };
97 | }
98 |
99 | - (PriorityPromiseLoopValidated)loopValidated {
100 | @weakify(self)
101 | return ^(BOOL bValue, NSTimeInterval interval) {
102 | @strongify(self)
103 | if (bValue) {
104 | [self.element onSubscribe:self.output];
105 | [self.element nextWithValue:self.output];
106 | #ifdef DEBUG
107 | NSLog(@"2.priority promise %@ loop validates succed", self.identifier);
108 | #endif
109 | return;
110 | }
111 | if (interval < 0) {
112 | NSError *err = [NSError errorWithDomain:@"interval must bigger than 0" code:PriorityLoopValidatedError userInfo:nil];
113 | [self.element onCatch:err];
114 | #ifdef DEBUG
115 | NSLog(@"1.priority promise %@ loop validates failure", self.identifier);
116 | #endif
117 | return;
118 | }
119 |
120 | [(NSObject *)(self.element) performSelector:@selector(executeWithData:) withObject:self.input afterDelay:interval];
121 | #ifdef DEBUG
122 | NSLog(@"0. priority promise %@ loop validates", self.identifier);
123 | #endif
124 | };
125 | }
126 |
127 | - (PriorityPromiseConditionDelay)conditionDelay {
128 | @weakify(self)
129 | return ^(BOOL condition, NSTimeInterval interval) {
130 | @strongify(self)
131 | if (!condition || interval <= 0) {
132 | [self.element onSubscribe:self.input];
133 | [self.element nextWithValue:self.input];
134 | return;
135 | }
136 | [(NSObject *)(self.element) performSelector:@selector(nextWithValue:) withObject:self.output afterDelay:interval];
137 | };
138 | }
139 |
140 | - (void)breakLoop {
141 | [NSObject cancelPreviousPerformRequestsWithTarget:_element selector:@selector(executeWithData:) object:_input];
142 | [NSObject cancelPreviousPerformRequestsWithTarget:_element selector:@selector(nextWithValue:) object:_input];
143 | }
144 |
145 | @end
146 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Priority/PrioritySessionElement.h:
--------------------------------------------------------------------------------
1 | //
2 | // PrioritySessionElement.h
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2019/10/26.
6 | // Copyright © 2019 RunsCode. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "PriorityPromise.h"
11 | #import "PriorityElementProtocol.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | /// The correct way to use
16 | #define PromisePriority(T,V) PrioritySessionElement elementWithPromiseBlock:^(PriorityPromise *promise)
17 |
18 | /// Input: Input parameter type Output: Data type for the next element
19 | @interface PrioritySessionElement : NSObject
20 |
21 | typedef void(^ExecutePromiseBlock)(PriorityPromise *promise);
22 | typedef PrioritySessionElement *_Nonnull(^Then)(PrioritySessionElement *session);
23 |
24 | @property (nonatomic, weak) Input input;
25 |
26 | /// Element id
27 | @property (nonatomic, copy) NSString *identifier;
28 | /// link to the next Element
29 | @property (nonatomic, strong, readonly) Then then;
30 |
31 | @property (nonatomic, strong, readonly) PriorityPromise *promise;
32 |
33 | /// It is recommended to use macros$It is recommended to use macros `PromisePriority`
34 | + (instancetype)elementWithPromiseBlock:(ExecutePromiseBlock)block;
35 | + (instancetype)elementWithPromiseBlock:(ExecutePromiseBlock)block identifier:(NSString *_Nullable)identifier;
36 |
37 | /// Subscribe to the normal process and successfully process the result callback
38 | - (instancetype)subscribe:(void (^)(Output _Nullable value))subscribe;
39 | /// Process interrupt callback
40 | - (instancetype)catch:(void (^)(NSError *_Nullable error))catch;
41 | /// The process ends with a callback regardless of success
42 | - (instancetype)dispose:(dispatch_block_t)dispose;
43 | /// Manual interrupt link list and release self-promise
44 | - (void)breakPromiseLoop;
45 |
46 | @end
47 |
48 |
49 | NS_ASSUME_NONNULL_END
50 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Priority/PrioritySessionElement.m:
--------------------------------------------------------------------------------
1 | //
2 | // PrioritySessionElement.m
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2019/10/26.
6 | // Copyright © 2019 RunsCode. All rights reserved.
7 | //
8 |
9 | #import "PrioritySessionElement.h"
10 |
11 | @interface PrioritySessionElement ()
12 |
13 | @property (nonatomic, strong) ExecutePromiseBlock executePromiseBlock;
14 | @property (nonatomic, strong) PrioritySessionElement *next;
15 |
16 | @property (nonatomic, strong) void(^subscribe)(id _Nullable valve);
17 | @property (nonatomic, strong) void(^catch)(NSError *_Nullable error);
18 | @property (nonatomic, strong) dispatch_block_t dispose;
19 |
20 | @property (nonatomic, strong) PriorityPromise *promise;
21 |
22 | @end
23 |
24 | @implementation PrioritySessionElement
25 |
26 | #ifdef DEBUG
27 | - (void)dealloc {
28 | NSLog(@"❤️❤️❤️%s, id : %@ ❤️❤️❤️", __PRETTY_FUNCTION__, self.identifier);
29 | }
30 | #endif
31 |
32 | + (instancetype)elementWithPromiseBlock:(ExecutePromiseBlock)block {
33 | return [self elementWithPromiseBlock:block identifier:nil];
34 | }
35 |
36 | + (instancetype)elementWithPromiseBlock:(ExecutePromiseBlock)block identifier:(NSString *_Nullable)identifier {
37 | PrioritySessionElement *ele = [[self.class alloc] initWithIdentifer:identifier];
38 | ele.executePromiseBlock = block;
39 | return ele;
40 | }
41 |
42 | - (instancetype)initWithIdentifer:(NSString *)identifier {
43 | self = [super init];
44 | if (self) {
45 | _identifier = identifier;
46 | }
47 | return self;
48 | }
49 |
50 | - (instancetype)subscribe:(void (^)(id _Nullable))subscribe {
51 | _subscribe = subscribe;
52 | return self;
53 | }
54 |
55 | - (instancetype)catch:(void (^)(NSError * _Nullable))catch {
56 | _catch = catch;
57 | return self;
58 | }
59 |
60 | - (instancetype)dispose:(dispatch_block_t)dispose {
61 | _dispose = dispose;
62 | return self;
63 | }
64 |
65 | - (Then)then {
66 | return ^(PrioritySessionElement *ele) {
67 | self.next = ele;
68 | return ele;
69 | };
70 | }
71 |
72 | - (void)breakPromiseLoop {
73 | [_promise breakLoop];
74 | _promise = nil;
75 | }
76 |
77 |
78 | #pragma mark -- JYPriorityElementProtocol
79 |
80 | - (void)execute {
81 | [self executeWithData:nil];
82 | }
83 |
84 | - (void)executeWithData:(id)data {
85 | _input = data;
86 | //
87 | if (!_promise) {
88 | _promise = [PriorityPromise promiseWithInput:data element:self identifier:_identifier];
89 | } else {
90 | _promise.input = data;
91 | }
92 | [self executePromise:_promise];
93 | }
94 |
95 | - (void)executePromise:(PriorityPromise *)promise {
96 | !_executePromiseBlock ?: _executePromiseBlock(promise);
97 | }
98 |
99 | - (void)onSubscribe:(id _Nullable)data {
100 | [self breakPromiseLoop];
101 | //
102 | !_subscribe ?: _subscribe(data);
103 | !_dispose ?: _dispose();
104 | }
105 |
106 | - (void)onCatch:(NSError * _Nullable)error {
107 | [self breakPromiseLoop];
108 | //
109 | !_catch ?: _catch(error);
110 | !_dispose ?: _dispose();
111 | }
112 |
113 | - (void)nextWithValue:(id _Nullable)value {
114 | _promise = nil;
115 | //
116 | [self tryNextWithValue:value];
117 | }
118 |
119 | #pragma mark -- Private
120 |
121 | - (void)tryNextWithValue:(id)value {
122 | if (!_next) return;
123 | [self.next executeWithData:value];
124 | }
125 |
126 | - (void)releaseChain {
127 | __auto_type next = self.next;
128 | while (next) {
129 | __auto_type obj = next;
130 | next = obj.next;
131 | obj = nil;
132 | }
133 | }
134 |
135 | - (void)breakProcess {
136 | _promise = nil;
137 | //
138 | [self releaseChain];
139 | }
140 | @end
141 |
142 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/SceneDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.h
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SceneDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow * window;
14 |
15 | @end
16 |
17 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/SceneDelegate.m:
--------------------------------------------------------------------------------
1 | #import "SceneDelegate.h"
2 |
3 | @interface SceneDelegate ()
4 |
5 | @end
6 |
7 | @implementation SceneDelegate
8 |
9 |
10 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
11 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
12 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
13 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
14 | }
15 |
16 |
17 | - (void)sceneDidDisconnect:(UIScene *)scene {
18 | // Called as the scene is being released by the system.
19 | // This occurs shortly after the scene enters the background, or when its session is discarded.
20 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
21 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
22 | }
23 |
24 |
25 | - (void)sceneDidBecomeActive:(UIScene *)scene {
26 | // Called when the scene has moved from an inactive state to an active state.
27 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
28 | }
29 |
30 |
31 | - (void)sceneWillResignActive:(UIScene *)scene {
32 | // Called when the scene will move from an active state to an inactive state.
33 | // This may occur due to temporary interruptions (ex. an incoming phone call).
34 | }
35 |
36 |
37 | - (void)sceneWillEnterForeground:(UIScene *)scene {
38 | // Called as the scene transitions from the background to the foreground.
39 | // Use this method to undo the changes made on entering the background.
40 | }
41 |
42 |
43 | - (void)sceneDidEnterBackground:(UIScene *)scene {
44 | // Called as the scene transitions from the foreground to the background.
45 | // Use this method to save data, release shared resources, and store enough scene-specific state information
46 | // to restore the scene back to its current state.
47 | }
48 |
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Test/PriorityDemo.h:
--------------------------------------------------------------------------------
1 | //
2 | // PriorityDemo.h
3 | // PromisePriorityChian
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PriorityDemo : NSObject
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Test/PriorityDemo.m:
--------------------------------------------------------------------------------
1 | //
2 | // PriorityDemo.m
3 | // PromisePriorityChian
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | #import "PriorityDemo.h"
10 | #import "PrioritySessionElement.h"
11 | #import "PrioritySessionCustomElement.h"
12 |
13 | @interface PriorityDemo ()
14 |
15 | @property (nonatomic, assign) NSUInteger testCount;
16 |
17 |
18 | @end
19 |
20 | @implementation PriorityDemo
21 |
22 | #ifdef DEBUG
23 | - (void)dealloc {
24 | NSLog(@"%s", __PRETTY_FUNCTION__);
25 | }
26 | #endif
27 |
28 |
29 | - (instancetype)init {
30 | self = [super init];
31 | if (self) {
32 | [self testExample];
33 | }
34 | return self;
35 | }
36 |
37 | - (void)testCustom {
38 | PrioritySessionElement *normalAsyncElement = [self normalAsyncElement];
39 | PrioritySessionElement *headElement = [self customSession];
40 | PrioritySessionElement *testElement = [[PromisePriority(NSString *, id) {
41 | NSLog(@"testElement promise data = %@", promise.input);
42 | promise.next(@"11000");
43 | } identifier:@"testElement"] dispose:^{
44 | NSLog(@"❤️testElement dispose❤️");
45 | }];
46 | normalAsyncElement.then(headElement).then(testElement);
47 | [normalAsyncElement executeWithData:@(-2)];
48 | }
49 |
50 |
51 | - (void)testExample {
52 |
53 | PrioritySessionElement *headElement = [[self customSession] dispose:^{
54 | NSLog(@"❤️headElement custom dispose❤️");
55 | }];
56 | PrioritySessionElement *normalAsyncElement = [[self normalAsyncElement] dispose:^{
57 | NSLog(@"❤️normalAsyncElement dispose❤️");
58 | }];
59 | PrioritySessionElement *testElement = [[PromisePriority(NSString *, id) {
60 | NSLog(@"testElement promise data = %@", promise.input);
61 | promise.next(@(1100));
62 | } identifier:@"testElement"] dispose:^{
63 | NSLog(@"❤️testElement dispose❤️");
64 | }];
65 |
66 |
67 | testElement
68 | .then(normalAsyncElement)
69 | .then(headElement)
70 | .then(self.loopValidatedElement)
71 | .then(self.conditionDelayElement)
72 | .then(self.validatedElement);
73 |
74 | [testElement executeWithData:@(-2)];
75 | }
76 |
77 | - (PrioritySessionElement *)validatedElement {
78 | return [[[[PromisePriority(NSString *, NSNumber *){
79 |
80 | promise.output = @10086;
81 | promise.validated(self.testCount >= 5);
82 | NSLog(@"validatedElement promise data = %@", promise.input);
83 |
84 | } identifier:@"validatedElement"] subscribe:^(NSNumber * _Nullable value) {
85 | NSLog(@"validatedElement subscribe data = %@", value);
86 | }] catch:^(NSError * _Nullable error) {
87 |
88 | }] dispose:^{
89 | NSLog(@"❤️validatedElement dispose❤️");
90 | }];
91 | }
92 |
93 | - (PrioritySessionElement *)conditionDelayElement {
94 | return [[[[PromisePriority(NSNumber *, NSString *) {
95 |
96 | promise.output = @"10098";
97 | promise.conditionDelay(self.testCount >= 5, 3.f);
98 |
99 | } identifier:@"conditionDelayElement"] subscribe:^(NSString * _Nullable value) {
100 |
101 | NSLog(@"conditionDelayElement subscribe value = %@", value);
102 |
103 | }] catch:^(NSError * _Nullable error) {
104 | NSLog(@"💥 conditionDelayElement catch error = %@", error.domain);
105 | }] dispose:^{
106 | NSLog(@"❤️conditionDelayElement dispose❤️");
107 | }];
108 | }
109 |
110 | - (PrioritySessionElement *)loopValidatedElement {
111 | return [[[[PromisePriority(NSString *, NSNumber *) {
112 |
113 | self.testCount++;
114 | promise.output = @(1);
115 | NSLog(@"testCount = %lu", (unsigned long)self.testCount);
116 | promise.loopValidated(self.testCount > 5, 1);
117 |
118 | } identifier:@"loopValidatedElement"] subscribe:^(NSNumber * _Nullable value) {
119 | NSLog(@"loopValidatedElement subscribe value = %@", value.stringValue);
120 | }] catch:^(NSError * _Nullable error) {
121 | NSLog(@"💥 loopValidatedElement catch error = %@", error.domain);
122 | }] dispose:^{
123 | NSLog(@"❤️loopValidatedElement dispose❤️");
124 | }];
125 | }
126 |
127 | - (PrioritySessionElement *)normalAsyncElement {
128 | return [[[PromisePriority(NSNumber *, NSString *) {
129 | [self dealy:3 completed:^{
130 | NSLog(@"normalAsyncElement promise data = %@", promise.input.stringValue);
131 | promise.output = @"output";
132 | promise.next(@"session1");
133 | // promise.brake(nil);
134 | }];
135 | } identifier:@"normalAsyncElement"] subscribe:^(NSString * _Nullable value) {
136 | NSLog(@"normalAsyncElement subscribe value = %@", value);
137 | }] catch:^(NSError * _Nullable error) {
138 | NSLog(@"💥 normalAsyncElement catch error = %@", error.domain);
139 | }];
140 | }
141 |
142 | - (PrioritySessionElement *)customSession {
143 | PrioritySessionElement *element = [PrioritySessionCustomElement new];
144 | return [[element subscribe:^(NSString * _Nullable value) {
145 |
146 | NSLog(@"customSession subscribe value = %@", value);
147 |
148 | }] catch:^(NSError * _Nullable error) {
149 | NSLog(@"💥 customSession catch error = %@", error.domain);
150 | }];
151 | }
152 |
153 |
154 | - (void)dealy:(CGFloat)second completed:(dispatch_block_t)completed {
155 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(second * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
156 | completed();
157 | });
158 | }
159 |
160 | @end
161 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Test/PrioritySessionCustomElement.h:
--------------------------------------------------------------------------------
1 | //
2 | // PrioritySessionCustomElement.h
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2019/10/28.
6 | // Copyright © 2019 RunsCode. All rights reserved.
7 | //
8 |
9 | #import "PrioritySessionElement.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PrioritySessionCustomElement : PrioritySessionElement
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/Test/PrioritySessionCustomElement.m:
--------------------------------------------------------------------------------
1 | //
2 | // PrioritySessionCustomElement.m
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2019/10/28.
6 | // Copyright © 2019 RunsCode. All rights reserved.
7 | //
8 | #import "AppDelegate.h"
9 |
10 | #import "PrioritySessionCustomElement.h"
11 |
12 | @implementation PrioritySessionCustomElement
13 |
14 | //- (void)dealloc {
15 | // NSLog(@"%s", __PRETTY_FUNCTION__);
16 | //}
17 |
18 | //- (void)executeWithData:(id)data {
19 | // NSLog(@"sub Class execute data : %@", data);
20 | //// __weak typeof(self) weakSelf = self;
21 | //// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
22 | //// __strong typeof(self) strongSelf = weakSelf;
23 | // // Custom events are passed down. Two steps are indispensable
24 | //// [self onSubscribe:@-1];
25 | //// [self nextWithValue:@(-1)];
26 | //
27 | // // Custom event interrupt. Two steps are indispensable
28 | // [self onCatch:[NSError errorWithDomain:@"自定义Error" code:-1 userInfo:nil]];
29 | // [self breakProcess];
30 | //// });
31 | //}
32 |
33 | - (void)executePromise:(PriorityPromise *)promise {
34 | // promise.next(@(-100000896));
35 | // promise.brake(nil);
36 | [self onSubscribe:@(-100000896)];
37 | }
38 |
39 | - (NSString *)identifier {
40 | return @"I'm custom subclass";
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @interface ViewController ()
12 |
13 | @end
14 |
15 | @implementation ViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do any additional setup after loading the view.
20 | }
21 |
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChain/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | NSString * appDelegateClassName;
14 | @autoreleasepool {
15 | // Setup code that might create autoreleased objects goes here.
16 | appDelegateClassName = NSStringFromClass([AppDelegate class]);
17 | }
18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName);
19 | }
20 |
--------------------------------------------------------------------------------
/Objective-C/PromisePriorityChainTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PromisePriorityChain
2 |
3 | 
4 | 
5 | 
6 |
7 | 
8 | 
9 | 
10 |
11 |
12 | 
13 |
14 | ###### 轻量级优先级处理类,采用单向链表设计, 自动内存管理无需外部强引用。
15 | ###### Lightweight priority processing class with LinkedList design that automates memory management without strong external references.
16 |
17 |
18 | 可以解决如下问题:
19 | * 优先级逻辑处理
20 | * 嵌套逻辑展开铺平
21 | * 异步嵌套逻辑展开至同步的书写方式
22 | * 检验逻辑抽象包装
23 | * 轮询逻辑抽象包装
24 | * 状态延迟抽象包装
25 |
26 | The following issues can be resolved:
27 | * Priority logic processing
28 | * Nested logic spread
29 | * Asynchronous nesting logic expands to synchronous writing
30 | * Testing logic abstract packaging
31 | * Poll logic abstract wrapping
32 | * Transition delay abstract packaging
33 |
34 |
35 | ## Example
36 |
37 |
38 | >[Example For Swift](https://github.com/RunsCode/PromisePriorityChain/blob/master/Swift-Example.md)
39 |
40 | >[Example For Object-C](https://github.com/RunsCode/PromisePriorityChain/blob/master/OC-Example.md)
41 |
42 | >[Example For Java](https://github.com/RunsCode/PromisePriorityChain/blob/master/Java-Example.md)
43 |
44 | >[Example For Android](https://github.com/RunsCode/PromisePriorityChain/blob/master/Java-Example.md)
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | If you believe you have identified a security vulnerability with PromisePriorityChain, you should report it as soon as possible via email to runs.wang.dev@gmail.com. Please do not post it to a public issue tracker.
54 |
55 | License
56 | PromisePriorityChain is released under the MIT license. See LICENSE for details.
57 |
--------------------------------------------------------------------------------
/Swift-Example.md:
--------------------------------------------------------------------------------
1 |
2 | [toc]
3 |
4 | ```swift
5 | private var count: Int = 0
6 |
7 | let head: PriorityElement = self.head()
8 | head.then(neck())
9 | .then(lung())
10 | .then(heart())
11 | .then(liver())
12 | .then(over())
13 | //head.execute(with: "head->")
14 | // nil also default value()
15 | head.execute()
16 | ```
17 |
18 | #### General asynchronous operations
19 |
20 |
21 | ```swift
22 | // This is a complete way to create element
23 | private func head() -> PriorityElement {
24 | return PriorityElement(id: "Head") { (promise: PriorityPromise) in
25 | Println("head input : \(promise.input ?? "")")
26 | self.delay(1) {
27 | promise.next(1)
28 | }
29 | }.subscribe { i in
30 | Println("head subscribe : \(i ?? -1)")
31 | }.catch { err in
32 | Println("head catch : \(String(describing: err))")
33 | }.dispose {
34 | Println("head dispose")
35 | }
36 | }
37 | ```
38 |
39 | #### General check operation (if else nesting)
40 |
41 | ```swift
42 | // This is a minimalist way to create element,
43 | // using anonymous closure parameters and initializing default parameters
44 | private func neck() -> PriorityElement {
45 | return PriorityElement {
46 | Println("neck input : \($0.input ?? -1)")
47 | $0.output = "I am Neck"
48 | $0.validated($0.input == 1)
49 | }.subscribe { ... }.catch { err in ... }.dispose { ... }
50 | }
51 | ```
52 |
53 | #### Loop delay check operation (e.g. polling)
54 |
55 |
56 | ```swift
57 | // This is a recommended way to create element, providing an ID for debugging
58 | private func lung() -> PriorityElement {
59 | return PriorityElement(id: "Lung") {
60 | Println("lung input : \($0.input ?? "-1")")
61 | self.count += 1
62 | //
63 | $0.output = "I am Lung"
64 | $0.loop(validated: self.count >= 5, t: 1)
65 | }.subscribe { ... }.catch { err in ... }.dispose { ... }
66 | }
67 | ```
68 |
69 | #### Condition check operation
70 |
71 | ```swift
72 | private func heart() -> PriorityElement {
73 | return PriorityElement(id: "Heart") {
74 | Println("lung input : \($0.input ?? "-1")")
75 | self.count += 1
76 | //
77 | $0.output = "I am Lung"
78 | $0.condition(self.count > 5, delay: 1)
79 | }.subscribe { ... }.catch { err in ... }.dispose { ... }
80 | }
81 | ```
82 |
83 | #### Normal operation
84 |
85 | ```swift
86 | private func liver() -> PriorityElement {
87 | return PriorityElement(id: "Liver") { (promise: PriorityPromise) in
88 | Println("liver input : \(promise.input ?? "-1")")
89 | //
90 | self.delay(1) {
91 | promise.break(nil)
92 | }
93 | }.subscribe { ... }.catch { err in ... }.dispose { ... }
94 | }
95 | ```
96 |
97 | ```swift
98 | private func over() -> PriorityElement {
99 | return PriorityElement(id: "Over") { (promise: PriorityPromise) in
100 | Println("over input : \(promise.input ?? "-1")")
101 | //
102 | self.delay(1) {
103 | promise.next("Finished Release")
104 | }
105 | }.subscribe { ... }.catch { err in ... }.dispose { ... }
106 | }
107 | ```
108 |
109 | ```swift
110 | func delay(_ interval: TimeInterval, _ block: @escaping () -> Void) {
111 | DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
112 | block()
113 | }
114 | }
115 | ```
116 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4F103CF524263DB300429074 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CF424263DB300429074 /* AppDelegate.swift */; };
11 | 4F103CF724263DB300429074 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CF624263DB300429074 /* SceneDelegate.swift */; };
12 | 4F103CF924263DB300429074 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103CF824263DB300429074 /* ContentView.swift */; };
13 | 4F103CFB24263DB400429074 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4F103CFA24263DB400429074 /* Assets.xcassets */; };
14 | 4F103CFE24263DB400429074 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4F103CFD24263DB400429074 /* Preview Assets.xcassets */; };
15 | 4F103D0124263DB400429074 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4F103CFF24263DB400429074 /* LaunchScreen.storyboard */; };
16 | 4F103D0C24263DB400429074 /* PromisePriorityChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D0B24263DB400429074 /* PromisePriorityChainTests.swift */; };
17 | 4F103D1824263FB900429074 /* PriorityElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D1724263FB900429074 /* PriorityElement.swift */; };
18 | 4F103D1924263FB900429074 /* PriorityElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D1724263FB900429074 /* PriorityElement.swift */; };
19 | 4F103D1B2426418800429074 /* PriorityPromise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D1A2426418800429074 /* PriorityPromise.swift */; };
20 | 4F103D1C2426418800429074 /* PriorityPromise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D1A2426418800429074 /* PriorityPromise.swift */; };
21 | 4F103D1E2426482000429074 /* PriorityError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D1D2426482000429074 /* PriorityError.swift */; };
22 | 4F103D1F2426482000429074 /* PriorityError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D1D2426482000429074 /* PriorityError.swift */; };
23 | 4F103D2224279C9500429074 /* PromisePriorityTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D2124279C9500429074 /* PromisePriorityTest.swift */; };
24 | 4F103D2324279C9500429074 /* PromisePriorityTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F103D2124279C9500429074 /* PromisePriorityTest.swift */; };
25 | 4F54B16024D00C410007A743 /* PriorityCustomElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F54B15F24D00C410007A743 /* PriorityCustomElement.swift */; };
26 | /* End PBXBuildFile section */
27 |
28 | /* Begin PBXContainerItemProxy section */
29 | 4F103D0824263DB400429074 /* PBXContainerItemProxy */ = {
30 | isa = PBXContainerItemProxy;
31 | containerPortal = 4F103CE924263DB300429074 /* Project object */;
32 | proxyType = 1;
33 | remoteGlobalIDString = 4F103CF024263DB300429074;
34 | remoteInfo = PromisePriorityChain;
35 | };
36 | /* End PBXContainerItemProxy section */
37 |
38 | /* Begin PBXCopyFilesBuildPhase section */
39 | 4FBCF77524D1201200AB2721 /* Embed Frameworks */ = {
40 | isa = PBXCopyFilesBuildPhase;
41 | buildActionMask = 2147483647;
42 | dstPath = "";
43 | dstSubfolderSpec = 10;
44 | files = (
45 | );
46 | name = "Embed Frameworks";
47 | runOnlyForDeploymentPostprocessing = 0;
48 | };
49 | /* End PBXCopyFilesBuildPhase section */
50 |
51 | /* Begin PBXFileReference section */
52 | 4F103CF124263DB300429074 /* PromisePriorityChain.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PromisePriorityChain.app; sourceTree = BUILT_PRODUCTS_DIR; };
53 | 4F103CF424263DB300429074 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
54 | 4F103CF624263DB300429074 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
55 | 4F103CF824263DB300429074 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
56 | 4F103CFA24263DB400429074 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
57 | 4F103CFD24263DB400429074 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
58 | 4F103D0024263DB400429074 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
59 | 4F103D0224263DB400429074 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
60 | 4F103D0724263DB400429074 /* PromisePriorityChainTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PromisePriorityChainTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
61 | 4F103D0B24263DB400429074 /* PromisePriorityChainTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromisePriorityChainTests.swift; sourceTree = ""; };
62 | 4F103D0D24263DB400429074 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
63 | 4F103D1724263FB900429074 /* PriorityElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriorityElement.swift; sourceTree = ""; };
64 | 4F103D1A2426418800429074 /* PriorityPromise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriorityPromise.swift; sourceTree = ""; };
65 | 4F103D1D2426482000429074 /* PriorityError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriorityError.swift; sourceTree = ""; };
66 | 4F103D2124279C9500429074 /* PromisePriorityTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromisePriorityTest.swift; sourceTree = ""; };
67 | 4F54B15F24D00C410007A743 /* PriorityCustomElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriorityCustomElement.swift; sourceTree = ""; };
68 | 4FBCF76E24D1201200AB2721 /* TestModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestModule.h; sourceTree = ""; };
69 | 4FBCF76F24D1201200AB2721 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
70 | /* End PBXFileReference section */
71 |
72 | /* Begin PBXFrameworksBuildPhase section */
73 | 4F103CEE24263DB300429074 /* Frameworks */ = {
74 | isa = PBXFrameworksBuildPhase;
75 | buildActionMask = 2147483647;
76 | files = (
77 | );
78 | runOnlyForDeploymentPostprocessing = 0;
79 | };
80 | 4F103D0424263DB400429074 /* Frameworks */ = {
81 | isa = PBXFrameworksBuildPhase;
82 | buildActionMask = 2147483647;
83 | files = (
84 | );
85 | runOnlyForDeploymentPostprocessing = 0;
86 | };
87 | /* End PBXFrameworksBuildPhase section */
88 |
89 | /* Begin PBXGroup section */
90 | 4F103CE824263DB300429074 = {
91 | isa = PBXGroup;
92 | children = (
93 | 4F103CF324263DB300429074 /* PromisePriorityChain */,
94 | 4F103D0A24263DB400429074 /* PromisePriorityChainTests */,
95 | 4FBCF76D24D1201200AB2721 /* TestModule */,
96 | 4F103CF224263DB300429074 /* Products */,
97 | );
98 | sourceTree = "";
99 | };
100 | 4F103CF224263DB300429074 /* Products */ = {
101 | isa = PBXGroup;
102 | children = (
103 | 4F103CF124263DB300429074 /* PromisePriorityChain.app */,
104 | 4F103D0724263DB400429074 /* PromisePriorityChainTests.xctest */,
105 | );
106 | name = Products;
107 | sourceTree = "";
108 | };
109 | 4F103CF324263DB300429074 /* PromisePriorityChain */ = {
110 | isa = PBXGroup;
111 | children = (
112 | 4F103D2024279C6E00429074 /* Test */,
113 | 4F103D1624263DCA00429074 /* Priority */,
114 | 4F103CF424263DB300429074 /* AppDelegate.swift */,
115 | 4F103CF624263DB300429074 /* SceneDelegate.swift */,
116 | 4F103CF824263DB300429074 /* ContentView.swift */,
117 | 4F103CFA24263DB400429074 /* Assets.xcassets */,
118 | 4F103CFF24263DB400429074 /* LaunchScreen.storyboard */,
119 | 4F103D0224263DB400429074 /* Info.plist */,
120 | 4F103CFC24263DB400429074 /* Preview Content */,
121 | );
122 | path = PromisePriorityChain;
123 | sourceTree = "";
124 | };
125 | 4F103CFC24263DB400429074 /* Preview Content */ = {
126 | isa = PBXGroup;
127 | children = (
128 | 4F103CFD24263DB400429074 /* Preview Assets.xcassets */,
129 | );
130 | path = "Preview Content";
131 | sourceTree = "";
132 | };
133 | 4F103D0A24263DB400429074 /* PromisePriorityChainTests */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 4F103D0B24263DB400429074 /* PromisePriorityChainTests.swift */,
137 | 4F103D0D24263DB400429074 /* Info.plist */,
138 | );
139 | path = PromisePriorityChainTests;
140 | sourceTree = "";
141 | };
142 | 4F103D1624263DCA00429074 /* Priority */ = {
143 | isa = PBXGroup;
144 | children = (
145 | 4F103D1724263FB900429074 /* PriorityElement.swift */,
146 | 4F103D1A2426418800429074 /* PriorityPromise.swift */,
147 | 4F103D1D2426482000429074 /* PriorityError.swift */,
148 | );
149 | path = Priority;
150 | sourceTree = "";
151 | };
152 | 4F103D2024279C6E00429074 /* Test */ = {
153 | isa = PBXGroup;
154 | children = (
155 | 4F103D2124279C9500429074 /* PromisePriorityTest.swift */,
156 | 4F54B15F24D00C410007A743 /* PriorityCustomElement.swift */,
157 | );
158 | path = Test;
159 | sourceTree = "";
160 | };
161 | 4FBCF76D24D1201200AB2721 /* TestModule */ = {
162 | isa = PBXGroup;
163 | children = (
164 | 4FBCF76E24D1201200AB2721 /* TestModule.h */,
165 | 4FBCF76F24D1201200AB2721 /* Info.plist */,
166 | );
167 | path = TestModule;
168 | sourceTree = "";
169 | };
170 | /* End PBXGroup section */
171 |
172 | /* Begin PBXNativeTarget section */
173 | 4F103CF024263DB300429074 /* PromisePriorityChain */ = {
174 | isa = PBXNativeTarget;
175 | buildConfigurationList = 4F103D1024263DB400429074 /* Build configuration list for PBXNativeTarget "PromisePriorityChain" */;
176 | buildPhases = (
177 | 4F103CED24263DB300429074 /* Sources */,
178 | 4F103CEE24263DB300429074 /* Frameworks */,
179 | 4F103CEF24263DB300429074 /* Resources */,
180 | 4FBCF77524D1201200AB2721 /* Embed Frameworks */,
181 | );
182 | buildRules = (
183 | );
184 | dependencies = (
185 | );
186 | name = PromisePriorityChain;
187 | productName = PromisePriorityChain;
188 | productReference = 4F103CF124263DB300429074 /* PromisePriorityChain.app */;
189 | productType = "com.apple.product-type.application";
190 | };
191 | 4F103D0624263DB400429074 /* PromisePriorityChainTests */ = {
192 | isa = PBXNativeTarget;
193 | buildConfigurationList = 4F103D1324263DB400429074 /* Build configuration list for PBXNativeTarget "PromisePriorityChainTests" */;
194 | buildPhases = (
195 | 4F103D0324263DB400429074 /* Sources */,
196 | 4F103D0424263DB400429074 /* Frameworks */,
197 | 4F103D0524263DB400429074 /* Resources */,
198 | );
199 | buildRules = (
200 | );
201 | dependencies = (
202 | 4F103D0924263DB400429074 /* PBXTargetDependency */,
203 | );
204 | name = PromisePriorityChainTests;
205 | productName = PromisePriorityChainTests;
206 | productReference = 4F103D0724263DB400429074 /* PromisePriorityChainTests.xctest */;
207 | productType = "com.apple.product-type.bundle.unit-test";
208 | };
209 | /* End PBXNativeTarget section */
210 |
211 | /* Begin PBXProject section */
212 | 4F103CE924263DB300429074 /* Project object */ = {
213 | isa = PBXProject;
214 | attributes = {
215 | LastSwiftUpdateCheck = 1110;
216 | LastUpgradeCheck = 1110;
217 | ORGANIZATIONNAME = Runs;
218 | TargetAttributes = {
219 | 4F103CF024263DB300429074 = {
220 | CreatedOnToolsVersion = 11.1;
221 | };
222 | 4F103D0624263DB400429074 = {
223 | CreatedOnToolsVersion = 11.1;
224 | TestTargetID = 4F103CF024263DB300429074;
225 | };
226 | };
227 | };
228 | buildConfigurationList = 4F103CEC24263DB300429074 /* Build configuration list for PBXProject "PromisePriorityChain" */;
229 | compatibilityVersion = "Xcode 9.3";
230 | developmentRegion = en;
231 | hasScannedForEncodings = 0;
232 | knownRegions = (
233 | en,
234 | Base,
235 | );
236 | mainGroup = 4F103CE824263DB300429074;
237 | productRefGroup = 4F103CF224263DB300429074 /* Products */;
238 | projectDirPath = "";
239 | projectRoot = "";
240 | targets = (
241 | 4F103CF024263DB300429074 /* PromisePriorityChain */,
242 | 4F103D0624263DB400429074 /* PromisePriorityChainTests */,
243 | );
244 | };
245 | /* End PBXProject section */
246 |
247 | /* Begin PBXResourcesBuildPhase section */
248 | 4F103CEF24263DB300429074 /* Resources */ = {
249 | isa = PBXResourcesBuildPhase;
250 | buildActionMask = 2147483647;
251 | files = (
252 | 4F103D0124263DB400429074 /* LaunchScreen.storyboard in Resources */,
253 | 4F103CFE24263DB400429074 /* Preview Assets.xcassets in Resources */,
254 | 4F103CFB24263DB400429074 /* Assets.xcassets in Resources */,
255 | );
256 | runOnlyForDeploymentPostprocessing = 0;
257 | };
258 | 4F103D0524263DB400429074 /* Resources */ = {
259 | isa = PBXResourcesBuildPhase;
260 | buildActionMask = 2147483647;
261 | files = (
262 | );
263 | runOnlyForDeploymentPostprocessing = 0;
264 | };
265 | /* End PBXResourcesBuildPhase section */
266 |
267 | /* Begin PBXSourcesBuildPhase section */
268 | 4F103CED24263DB300429074 /* Sources */ = {
269 | isa = PBXSourcesBuildPhase;
270 | buildActionMask = 2147483647;
271 | files = (
272 | 4F103D1E2426482000429074 /* PriorityError.swift in Sources */,
273 | 4F103D1B2426418800429074 /* PriorityPromise.swift in Sources */,
274 | 4F103CF524263DB300429074 /* AppDelegate.swift in Sources */,
275 | 4F103D2224279C9500429074 /* PromisePriorityTest.swift in Sources */,
276 | 4F103CF724263DB300429074 /* SceneDelegate.swift in Sources */,
277 | 4F54B16024D00C410007A743 /* PriorityCustomElement.swift in Sources */,
278 | 4F103D1824263FB900429074 /* PriorityElement.swift in Sources */,
279 | 4F103CF924263DB300429074 /* ContentView.swift in Sources */,
280 | );
281 | runOnlyForDeploymentPostprocessing = 0;
282 | };
283 | 4F103D0324263DB400429074 /* Sources */ = {
284 | isa = PBXSourcesBuildPhase;
285 | buildActionMask = 2147483647;
286 | files = (
287 | 4F103D1924263FB900429074 /* PriorityElement.swift in Sources */,
288 | 4F103D2324279C9500429074 /* PromisePriorityTest.swift in Sources */,
289 | 4F103D0C24263DB400429074 /* PromisePriorityChainTests.swift in Sources */,
290 | 4F103D1F2426482000429074 /* PriorityError.swift in Sources */,
291 | 4F103D1C2426418800429074 /* PriorityPromise.swift in Sources */,
292 | );
293 | runOnlyForDeploymentPostprocessing = 0;
294 | };
295 | /* End PBXSourcesBuildPhase section */
296 |
297 | /* Begin PBXTargetDependency section */
298 | 4F103D0924263DB400429074 /* PBXTargetDependency */ = {
299 | isa = PBXTargetDependency;
300 | target = 4F103CF024263DB300429074 /* PromisePriorityChain */;
301 | targetProxy = 4F103D0824263DB400429074 /* PBXContainerItemProxy */;
302 | };
303 | /* End PBXTargetDependency section */
304 |
305 | /* Begin PBXVariantGroup section */
306 | 4F103CFF24263DB400429074 /* LaunchScreen.storyboard */ = {
307 | isa = PBXVariantGroup;
308 | children = (
309 | 4F103D0024263DB400429074 /* Base */,
310 | );
311 | name = LaunchScreen.storyboard;
312 | sourceTree = "";
313 | };
314 | /* End PBXVariantGroup section */
315 |
316 | /* Begin XCBuildConfiguration section */
317 | 4F103D0E24263DB400429074 /* Debug */ = {
318 | isa = XCBuildConfiguration;
319 | buildSettings = {
320 | ALWAYS_SEARCH_USER_PATHS = NO;
321 | CLANG_ANALYZER_NONNULL = YES;
322 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
323 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
324 | CLANG_CXX_LIBRARY = "libc++";
325 | CLANG_ENABLE_MODULES = YES;
326 | CLANG_ENABLE_OBJC_ARC = YES;
327 | CLANG_ENABLE_OBJC_WEAK = YES;
328 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
329 | CLANG_WARN_BOOL_CONVERSION = YES;
330 | CLANG_WARN_COMMA = YES;
331 | CLANG_WARN_CONSTANT_CONVERSION = YES;
332 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
333 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
334 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
335 | CLANG_WARN_EMPTY_BODY = YES;
336 | CLANG_WARN_ENUM_CONVERSION = YES;
337 | CLANG_WARN_INFINITE_RECURSION = YES;
338 | CLANG_WARN_INT_CONVERSION = YES;
339 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
340 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
341 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
343 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
344 | CLANG_WARN_STRICT_PROTOTYPES = YES;
345 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
346 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
347 | CLANG_WARN_UNREACHABLE_CODE = YES;
348 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
349 | COPY_PHASE_STRIP = NO;
350 | DEBUG_INFORMATION_FORMAT = dwarf;
351 | ENABLE_STRICT_OBJC_MSGSEND = YES;
352 | ENABLE_TESTABILITY = YES;
353 | GCC_C_LANGUAGE_STANDARD = gnu11;
354 | GCC_DYNAMIC_NO_PIC = NO;
355 | GCC_NO_COMMON_BLOCKS = YES;
356 | GCC_OPTIMIZATION_LEVEL = 0;
357 | GCC_PREPROCESSOR_DEFINITIONS = (
358 | "DEBUG=1",
359 | "$(inherited)",
360 | );
361 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
362 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
363 | GCC_WARN_UNDECLARED_SELECTOR = YES;
364 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
365 | GCC_WARN_UNUSED_FUNCTION = YES;
366 | GCC_WARN_UNUSED_VARIABLE = YES;
367 | IPHONEOS_DEPLOYMENT_TARGET = 13.1;
368 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
369 | MTL_FAST_MATH = YES;
370 | ONLY_ACTIVE_ARCH = YES;
371 | SDKROOT = iphoneos;
372 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
373 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
374 | };
375 | name = Debug;
376 | };
377 | 4F103D0F24263DB400429074 /* Release */ = {
378 | isa = XCBuildConfiguration;
379 | buildSettings = {
380 | ALWAYS_SEARCH_USER_PATHS = NO;
381 | CLANG_ANALYZER_NONNULL = YES;
382 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
383 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
384 | CLANG_CXX_LIBRARY = "libc++";
385 | CLANG_ENABLE_MODULES = YES;
386 | CLANG_ENABLE_OBJC_ARC = YES;
387 | CLANG_ENABLE_OBJC_WEAK = YES;
388 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
389 | CLANG_WARN_BOOL_CONVERSION = YES;
390 | CLANG_WARN_COMMA = YES;
391 | CLANG_WARN_CONSTANT_CONVERSION = YES;
392 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
393 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
394 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
395 | CLANG_WARN_EMPTY_BODY = YES;
396 | CLANG_WARN_ENUM_CONVERSION = YES;
397 | CLANG_WARN_INFINITE_RECURSION = YES;
398 | CLANG_WARN_INT_CONVERSION = YES;
399 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
400 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
401 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
402 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
403 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
404 | CLANG_WARN_STRICT_PROTOTYPES = YES;
405 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
406 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
407 | CLANG_WARN_UNREACHABLE_CODE = YES;
408 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
409 | COPY_PHASE_STRIP = NO;
410 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
411 | ENABLE_NS_ASSERTIONS = NO;
412 | ENABLE_STRICT_OBJC_MSGSEND = YES;
413 | GCC_C_LANGUAGE_STANDARD = gnu11;
414 | GCC_NO_COMMON_BLOCKS = YES;
415 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
416 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
417 | GCC_WARN_UNDECLARED_SELECTOR = YES;
418 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
419 | GCC_WARN_UNUSED_FUNCTION = YES;
420 | GCC_WARN_UNUSED_VARIABLE = YES;
421 | IPHONEOS_DEPLOYMENT_TARGET = 13.1;
422 | MTL_ENABLE_DEBUG_INFO = NO;
423 | MTL_FAST_MATH = YES;
424 | SDKROOT = iphoneos;
425 | SWIFT_COMPILATION_MODE = wholemodule;
426 | SWIFT_OPTIMIZATION_LEVEL = "-O";
427 | VALIDATE_PRODUCT = YES;
428 | };
429 | name = Release;
430 | };
431 | 4F103D1124263DB400429074 /* Debug */ = {
432 | isa = XCBuildConfiguration;
433 | buildSettings = {
434 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
435 | CODE_SIGN_STYLE = Automatic;
436 | DEVELOPMENT_ASSET_PATHS = "\"PromisePriorityChain/Preview Content\"";
437 | DEVELOPMENT_TEAM = KPSKY2677A;
438 | ENABLE_PREVIEWS = YES;
439 | INFOPLIST_FILE = PromisePriorityChain/Info.plist;
440 | LD_RUNPATH_SEARCH_PATHS = (
441 | "$(inherited)",
442 | "@executable_path/Frameworks",
443 | );
444 | PRODUCT_BUNDLE_IDENTIFIER = Runs.PromisePriorityChain;
445 | PRODUCT_NAME = "$(TARGET_NAME)";
446 | SWIFT_VERSION = 5.0;
447 | TARGETED_DEVICE_FAMILY = "1,2";
448 | };
449 | name = Debug;
450 | };
451 | 4F103D1224263DB400429074 /* Release */ = {
452 | isa = XCBuildConfiguration;
453 | buildSettings = {
454 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
455 | CODE_SIGN_STYLE = Automatic;
456 | DEVELOPMENT_ASSET_PATHS = "\"PromisePriorityChain/Preview Content\"";
457 | DEVELOPMENT_TEAM = KPSKY2677A;
458 | ENABLE_PREVIEWS = YES;
459 | INFOPLIST_FILE = PromisePriorityChain/Info.plist;
460 | LD_RUNPATH_SEARCH_PATHS = (
461 | "$(inherited)",
462 | "@executable_path/Frameworks",
463 | );
464 | PRODUCT_BUNDLE_IDENTIFIER = Runs.PromisePriorityChain;
465 | PRODUCT_NAME = "$(TARGET_NAME)";
466 | SWIFT_VERSION = 5.0;
467 | TARGETED_DEVICE_FAMILY = "1,2";
468 | };
469 | name = Release;
470 | };
471 | 4F103D1424263DB400429074 /* Debug */ = {
472 | isa = XCBuildConfiguration;
473 | buildSettings = {
474 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
475 | BUNDLE_LOADER = "$(TEST_HOST)";
476 | CODE_SIGN_STYLE = Automatic;
477 | DEVELOPMENT_TEAM = KPSKY2677A;
478 | INFOPLIST_FILE = PromisePriorityChainTests/Info.plist;
479 | IPHONEOS_DEPLOYMENT_TARGET = 13.1;
480 | LD_RUNPATH_SEARCH_PATHS = (
481 | "$(inherited)",
482 | "@executable_path/Frameworks",
483 | "@loader_path/Frameworks",
484 | );
485 | PRODUCT_BUNDLE_IDENTIFIER = Runs.PromisePriorityChainTests;
486 | PRODUCT_NAME = "$(TARGET_NAME)";
487 | SWIFT_VERSION = 5.0;
488 | TARGETED_DEVICE_FAMILY = "1,2";
489 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PromisePriorityChain.app/PromisePriorityChain";
490 | };
491 | name = Debug;
492 | };
493 | 4F103D1524263DB400429074 /* Release */ = {
494 | isa = XCBuildConfiguration;
495 | buildSettings = {
496 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
497 | BUNDLE_LOADER = "$(TEST_HOST)";
498 | CODE_SIGN_STYLE = Automatic;
499 | DEVELOPMENT_TEAM = KPSKY2677A;
500 | INFOPLIST_FILE = PromisePriorityChainTests/Info.plist;
501 | IPHONEOS_DEPLOYMENT_TARGET = 13.1;
502 | LD_RUNPATH_SEARCH_PATHS = (
503 | "$(inherited)",
504 | "@executable_path/Frameworks",
505 | "@loader_path/Frameworks",
506 | );
507 | PRODUCT_BUNDLE_IDENTIFIER = Runs.PromisePriorityChainTests;
508 | PRODUCT_NAME = "$(TARGET_NAME)";
509 | SWIFT_VERSION = 5.0;
510 | TARGETED_DEVICE_FAMILY = "1,2";
511 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PromisePriorityChain.app/PromisePriorityChain";
512 | };
513 | name = Release;
514 | };
515 | /* End XCBuildConfiguration section */
516 |
517 | /* Begin XCConfigurationList section */
518 | 4F103CEC24263DB300429074 /* Build configuration list for PBXProject "PromisePriorityChain" */ = {
519 | isa = XCConfigurationList;
520 | buildConfigurations = (
521 | 4F103D0E24263DB400429074 /* Debug */,
522 | 4F103D0F24263DB400429074 /* Release */,
523 | );
524 | defaultConfigurationIsVisible = 0;
525 | defaultConfigurationName = Release;
526 | };
527 | 4F103D1024263DB400429074 /* Build configuration list for PBXNativeTarget "PromisePriorityChain" */ = {
528 | isa = XCConfigurationList;
529 | buildConfigurations = (
530 | 4F103D1124263DB400429074 /* Debug */,
531 | 4F103D1224263DB400429074 /* Release */,
532 | );
533 | defaultConfigurationIsVisible = 0;
534 | defaultConfigurationName = Release;
535 | };
536 | 4F103D1324263DB400429074 /* Build configuration list for PBXNativeTarget "PromisePriorityChainTests" */ = {
537 | isa = XCConfigurationList;
538 | buildConfigurations = (
539 | 4F103D1424263DB400429074 /* Debug */,
540 | 4F103D1524263DB400429074 /* Release */,
541 | );
542 | defaultConfigurationIsVisible = 0;
543 | defaultConfigurationName = Release;
544 | };
545 | /* End XCConfigurationList section */
546 | };
547 | rootObject = 4F103CE924263DB300429074 /* Project object */;
548 | }
549 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 | PreviewsEnabled
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | _ = PromisePriorityTest()
19 | return true
20 | }
21 |
22 | // MARK: UISceneSession Lifecycle
23 |
24 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
25 | // Called when a new scene session is being created.
26 | // Use this method to select a configuration to create the new scene with.
27 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
28 | }
29 |
30 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
31 | // Called when the user discards a scene session.
32 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
33 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
34 | }
35 |
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 |
13 | public let priority: PromisePriorityTest = {
14 | return PromisePriorityTest()
15 | }()
16 |
17 | fileprivate func priorityTestButton(_ title: String) -> some View {
18 | return Button(action: {
19 | self.priority.test()
20 | }) {
21 | Text(title)
22 | .foregroundColor(Color.white)
23 | }
24 | .padding()
25 | .background(Color.blue)
26 | .cornerRadius(10)
27 | }
28 |
29 | var body: some View {
30 | VStack {
31 | Text("Hello World")
32 | .font(.title)
33 | .multilineTextAlignment(.center)
34 | .animation(.easeInOut)
35 |
36 | Spacer()
37 | priorityTestButton("PromisePriorityTest")
38 | Spacer()
39 | priorityTestButton("PromisePriorityTest0")
40 | Spacer()
41 |
42 | }
43 | }
44 | }
45 |
46 | struct ContentView_Previews: PreviewProvider {
47 | static var previews: some View {
48 | ContentView()
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Priority/PriorityElement.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PriorityElementProtocol.swift
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol PublicPriorityChainProtocol : class {
12 |
13 | var next: PublicPriorityChainProtocol? { get set }
14 | func execute(with data: Any?)
15 |
16 | @discardableResult
17 | func then(_ ele: PublicPriorityChainProtocol) -> PublicPriorityChainProtocol
18 | }
19 |
20 | extension PublicPriorityChainProtocol {
21 |
22 | @discardableResult
23 | public func then(_ ele: PublicPriorityChainProtocol) -> PublicPriorityChainProtocol {
24 | next = ele
25 | return ele
26 | }
27 | }
28 |
29 | protocol PublicPriorityPromiseProtocol :class {
30 | associatedtype Input
31 | associatedtype Output
32 |
33 | var promise: PriorityPromise? { get set }
34 | func invalidate()
35 | }
36 |
37 | extension PublicPriorityPromiseProtocol {
38 | func invalidate() {
39 | promise?.invalidate()
40 | promise = nil
41 | }
42 | }
43 |
44 | protocol PriorityElementProtocol : class {
45 |
46 | var id: String? { get set }
47 | var subscribeClosure: ((Any?)->())? { get set }
48 | var catchClosure: ((Error?) -> Void)? { get set }
49 | var disposeClosure: (() -> Void)? { get set }
50 |
51 | func execute()
52 | func execute(with data: Any?)
53 | func execute(next data: Any?)
54 |
55 | func onSubscribe(_ data: Any?)
56 | func onCatch(_ err: PriorityError?)
57 | func invalidate()
58 | }
59 |
60 | extension PriorityElementProtocol {
61 |
62 | public func onSubscribe(_ data: Any?) {
63 | invalidate()
64 | //
65 | subscribeClosure?(data)
66 | disposeClosure?()
67 | }
68 |
69 | public func onCatch(_ err: PriorityError?) {
70 | invalidate()
71 | //
72 | catchClosure?(err)
73 | disposeClosure?()
74 | }
75 | }
76 |
77 | public protocol PublicPriorityElementProtocol : class {
78 | associatedtype Input
79 | associatedtype Output
80 |
81 | /// Implementation of subclass for external module customization
82 | /// - Parameter promise: promise
83 | func execute(promise: PriorityPromise)
84 | }
85 |
86 |
87 | typealias IPriorityElement = PriorityElementProtocol & PublicPriorityChainProtocol & PublicPriorityElementProtocol & PublicPriorityPromiseProtocol
88 |
89 | open class PriorityElement : IPriorityElement {
90 |
91 | typealias ExecuteClosure = (PriorityPromise) -> Void
92 |
93 | public var id: String?
94 |
95 | public var next: PublicPriorityChainProtocol?
96 |
97 | var promise: PriorityPromise?
98 |
99 | var executeClosure: ExecuteClosure?
100 |
101 | var subscribeClosure: ((Any?) -> ())?
102 |
103 | var catchClosure: ((Error?) -> Void)?
104 |
105 | var disposeClosure: (() -> Void)?
106 |
107 |
108 | #if DEBUG
109 | deinit {
110 | Println("PriorityElement \(#function) id : \(id ?? "PriorityElement-id")")
111 | }
112 | #endif
113 |
114 | init(id: String? = "", _ closure: ExecuteClosure? = nil) {
115 | self.id = id
116 | self.executeClosure = closure
117 | }
118 |
119 | public func identifier(_ identifier: String) -> Self {
120 | self.id = identifier
121 | return self
122 | }
123 |
124 | public final func execute(with data: Any?) {
125 | if !(promise != nil) {
126 | promise = PriorityPromise(input: data , ele: self)
127 | } else {
128 | promise?.input = data as? Input
129 | }
130 | execute(promise: promise!)
131 | }
132 |
133 | /// Implementation of subclass for external module customization
134 | open func execute(promise: PriorityPromise) {
135 | // maybe implementation by customized subclass
136 | executeClosure?(promise)
137 | }
138 |
139 | }
140 |
141 | extension PriorityElement {
142 |
143 | @discardableResult
144 | public final func subscribe(_ closure: @escaping (Any?) -> Void) -> Self {
145 | subscribeClosure = closure
146 | return self
147 | }
148 |
149 | @discardableResult
150 | public final func `catch`(_ closure: @escaping (Error?) -> Void) -> Self {
151 | catchClosure = closure
152 | return self
153 | }
154 |
155 | @discardableResult
156 | public final func dispose(_ closure: @escaping () -> Void) -> Self {
157 | disposeClosure = closure
158 | return self
159 | }
160 |
161 | public final func execute(next data: Any?) {
162 | next?.execute(with: data)
163 | }
164 |
165 | public final func execute() {
166 | self.execute(with: nil)
167 | }
168 |
169 | }
170 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Priority/PriorityError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PPCError.swift
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | var dateFormatter: DateFormatter = {
12 | let fromatter = DateFormatter()
13 | fromatter.dateFormat = "yyyy-MM-dd HH:mm:ss SSS"
14 | return fromatter
15 | }()
16 |
17 | public func Println(_ string: String?) {
18 | let time = dateFormatter.string(from: Date())
19 | print("\(time) \(string ?? "")")
20 | }
21 |
22 | public struct PriorityError : Error {
23 |
24 | enum PriorityErrorEnum : Int {
25 | case validated = 100000
26 | case loopValidated = 110000
27 | }
28 |
29 | let kind: PriorityErrorEnum
30 | let desc: String
31 | }
32 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Priority/PriorityPromise.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PriorityPromise.swift
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol PriorityPromiseProtocol : AnyObject {
12 | associatedtype Input
13 | associatedtype Output
14 |
15 | var id: String? { get set }
16 | var input: Input? { get set }
17 | var output: Output? { get set }
18 | var timer: Timer? { get set }
19 |
20 | var element: PriorityElementProtocol { get }
21 |
22 | func invalidate()
23 | }
24 |
25 | extension PriorityPromiseProtocol {
26 |
27 | private func delay(_ interval: TimeInterval, block: @escaping (Timer) -> Void) {
28 | timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: false, block: block)
29 | RunLoop.current.add(timer!, forMode: .common)
30 | }
31 |
32 | public func invalidate() {
33 | timer?.invalidate()
34 | timer = nil
35 | }
36 | }
37 |
38 | extension PriorityPromiseProtocol {
39 |
40 | public func `break`(_ err: PriorityError?) {
41 | element.onCatch(err)
42 | }
43 |
44 | public func next(_ o: Output?) {
45 | element.onSubscribe(o)
46 | element.execute(next: o)
47 | }
48 |
49 | public func validated(_ isValid: Bool) {
50 | if isValid {
51 | next(output)
52 | return
53 | }
54 |
55 | let err = PriorityError(kind: .validated, desc: "validated failure")
56 | element.onCatch(err)
57 | }
58 |
59 | public func loop(validated isValid: Bool, t interval: TimeInterval) {
60 | if isValid {
61 | next(output)
62 | return
63 | }
64 |
65 | if 0 > interval {
66 | let err = PriorityError(kind: .loopValidated, desc: "loop validated failure")
67 | element.onCatch(err)
68 | return
69 | }
70 |
71 | self.delay(interval) { _ in
72 | self.next(self.output)
73 | }
74 | }
75 |
76 | public func condition(_ isOk: Bool, delay interval: TimeInterval) {
77 | guard isOk else {
78 | next(output)
79 | return
80 | }
81 |
82 | self.delay(interval) { _ in
83 | self.next(self.output)
84 | }
85 | }
86 | }
87 |
88 | open class PriorityPromise : PriorityPromiseProtocol {
89 |
90 | var id: String?
91 |
92 | var input: Input?
93 |
94 | var output: Output?
95 |
96 | var timer: Timer?
97 |
98 | var element: PriorityElementProtocol
99 |
100 | #if DEBUG
101 | deinit {
102 | Println("PriorityPromise \(#function) id : \(id ?? "PriorityPromise-id"), element : \(element.id ?? "unknown")")
103 | }
104 | #endif
105 |
106 | init(id: String? = "PriorityPromise", input: Any? = nil, ele: PriorityElementProtocol) {
107 | self.id = id ?? ele.id
108 | self.input = input as? Input
109 | self.element = ele
110 | #if DEBUG
111 | Println("create promise id: \(String(describing: id))")
112 | #endif
113 | }
114 |
115 | open func identifier(_ identifier: String) -> Self {
116 | id = identifier
117 | return self
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
66 | struct SceneDelegate_Previews: PreviewProvider {
67 | static var previews: some View {
68 | ContentView()
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Test/PriorityCustomElement.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PriorityCustomElement.swift
3 | // PromisePriorityChain
4 | //
5 | // Created by WangYajun on 2020/7/28.
6 | // Copyright © 2020 Runs. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PriorityCustomElement: PriorityElement {
12 |
13 | #if DEBUG
14 | deinit {
15 | Println("PriorityCustomElement \(#function) id : \(id ?? "PriorityCustomElement-id")")
16 | }
17 | #endif
18 |
19 | override var id: String? {
20 | set { }
21 | get {
22 | return "PriorityCustomElement"
23 | }
24 | }
25 |
26 |
27 | override func execute(promise: PriorityPromise) {
28 | DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
29 | Println("PriorityCustomElement execute ss")
30 | promise.break(nil)
31 | // promise.next("HELLO NEW")
32 | }
33 | }
34 |
35 |
36 | }
37 |
38 | struct AccountModel {
39 | init(_ json: Any) {
40 |
41 | }
42 | }
43 |
44 | extension PriorityCustomElement {
45 |
46 | func loadUser() -> AccountModel? {
47 | guard let json = UserDefaults.standard.object(forKey: "user_key_id") else { return nil }
48 | return AccountModel(json)
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChain/Test/PromisePriorityTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PromisePriorityTest.swift
3 | // PromisePriorityChain
4 | //
5 | // Created by RunsCode on 2020/3/22.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class PromisePriorityTest {
12 |
13 | private var count: Int = 0
14 |
15 | init() {
16 |
17 |
18 | }
19 |
20 | func test() {
21 | let head: PriorityElement = self.head()
22 | head.then(neck())
23 | .then(custom())
24 | .then(lung())
25 | .then(heart())
26 | .then(liver())
27 | .then(over())
28 | // head.execute(with: "head->")
29 | head.execute()
30 | }
31 |
32 | func delay(_ interval: TimeInterval, _ block: @escaping () -> Void) {
33 | DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
34 | block()
35 | }
36 | }
37 |
38 | private func custom() -> PriorityElement {
39 | return PriorityCustomElement().identifier("custom")
40 | }
41 |
42 | private func head() -> PriorityElement {
43 | return PriorityElement(id: "Head") { (_ promise: PriorityPromise) in
44 |
45 | Println("head input : \(promise.input ?? "")")
46 | self.delay(1) {
47 | promise.next(1)
48 | }
49 |
50 | }.subscribe { i in
51 |
52 | Println("head subscribe : \(i ?? -1)")
53 |
54 | }.catch { err in
55 |
56 | Println("head catch : \(String(describing: err))")
57 |
58 | }.dispose { Println("head dispose") }.identifier("head")
59 | }
60 |
61 | private func neck() -> PriorityElement {
62 | return PriorityElement {
63 |
64 | Println("neck input : \($0.input ?? -1)")
65 | $0.output = "I am Neck"
66 | $0.validated($0.input == 1)
67 |
68 | }.subscribe { i in
69 |
70 | Println("neck subscribe : \(i ?? "-1")")
71 |
72 | }.catch { err in
73 |
74 | Println("neck catch : \(String(describing: err))")
75 |
76 | }.dispose { Println("neck dispose") }.identifier("neck")
77 | }
78 |
79 | private func lung() -> PriorityElement {
80 | return PriorityElement {
81 |
82 | Println("lung input : \($0.input ?? "-1")")
83 | self.count += 1
84 | //
85 | $0.output = "I am Lung"
86 | $0.loop(validated: self.count >= 5, t: 1)
87 |
88 | }.subscribe { i in
89 |
90 | Println("lung subscribe : \(i ?? "-1")")
91 |
92 | }.catch { err in
93 |
94 | Println("lung catch : \(String(describing: err))")
95 |
96 | }.dispose { Println("lung dispose") }.identifier("lung")
97 | }
98 |
99 | private func heart() -> PriorityElement {
100 | return PriorityElement {
101 |
102 | Println("heart input : \($0.input ?? "-1")")
103 | //
104 | $0.output = "I am Heart"
105 | $0.condition(self.count > 5, delay: 2)
106 |
107 | }.subscribe { i in
108 |
109 | Println("heart subscribe : \(i ?? "-1")")
110 |
111 | }.catch { err in
112 |
113 | Println("heart catch : \(String(describing: err))")
114 |
115 | }.dispose { Println("heart dispose") }.identifier("heart")
116 | }
117 |
118 |
119 | private func liver() -> PriorityElement {
120 | return PriorityElement { promise in
121 |
122 | Println("liver input : \(promise.input ?? "-1")")
123 | //
124 | self.delay(1) {
125 | promise.next("over")
126 | }
127 |
128 | }.subscribe { i in
129 |
130 | Println("liver subscribe : \(i ?? "-1")")
131 |
132 | }.catch { err in
133 |
134 | Println("liver catch : \(String(describing: err))")
135 |
136 | }.dispose { Println("liver dispose") }.identifier("liver")
137 | }
138 |
139 | private func over() -> PriorityElement {
140 | return PriorityElement {
141 |
142 | Println("over input : \($0.input ?? "-1")")
143 | $0.next("Finished Release")
144 |
145 | }.subscribe { i in
146 |
147 | Println("over subscribe : \(i ?? "-1")")
148 |
149 | }.catch { err in
150 |
151 | Println("over catch : \(String(describing: err))")
152 |
153 | }.dispose { Println("over dispose") }.identifier("over")
154 | }
155 |
156 | }
157 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChainTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/PromisePriorityChainTests/PromisePriorityChainTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PromisePriorityChainTests.swift
3 | // PromisePriorityChainTests
4 | //
5 | // Created by RunsCode on 2020/3/21.
6 | // Copyright © 2020 RunsCode. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import PromisePriorityChain
11 |
12 | class PromisePriorityChainTests: XCTestCase {
13 |
14 | override func setUp() {
15 | // Put setup code here. This method is called before the invocation of each test method in the class.
16 | }
17 |
18 | override func tearDown() {
19 | // Put teardown code here. This method is called after the invocation of each test method in the class.
20 | }
21 |
22 | func testExample() {
23 | // This is an example of a functional test case.
24 | func heart() -> PriorityElement {
25 | return PriorityElement {
26 |
27 | Println("heart input : \($0.input ?? "-1")")
28 | //
29 | $0.output = "I am Heart"
30 | // $0.condition(self.count > 5, delay: 2)
31 |
32 | }.subscribe { i in
33 |
34 | Println("heart subscribe : \(i ?? "-1")")
35 |
36 | }.catch { err in
37 |
38 | Println("heart catch : \(String(describing: err))")
39 |
40 | }.dispose { Println("heart dispose") }.identifier("heart")
41 | }
42 |
43 | }
44 |
45 | func testPerformanceExample() {
46 | // This is an example of a performance test case.
47 | self.measure {
48 | // Put the code you want to measure the time of here.
49 | }
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/TestModule/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Swift/PromisePriorityChain/TestModule/TestModule.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestModule.h
3 | // TestModule
4 | //
5 | // Created by WangYajun on 2020/7/29.
6 | // Copyright © 2020 Runs. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for TestModule.
12 | FOUNDATION_EXPORT double TestModuleVersionNumber;
13 |
14 | //! Project version string for TestModule.
15 | FOUNDATION_EXPORT const unsigned char TestModuleVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------