├── .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 | ![](https://img.shields.io/badge/language-Swift-orange.svg) 4 | ![](https://img.shields.io/badge/language-Java-blue.svg) 5 | ![](https://img.shields.io/badge/language-Objectivec-red.svg) 6 | 7 | ![](https://img.shields.io/badge/platform-iOS-lightgrey.svg) 8 | ![](https://img.shields.io/badge/platform-Android-green.svg) 9 | ![](https://img.shields.io/badge/platform-JavaWeb-red.svg) 10 | 11 | 12 | ![](https://img.shields.io/badge/License-MIT-red.svg) 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 | --------------------------------------------------------------------------------