├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── example ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── renesanse │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── flutter_export_environment.sh │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ └── main.dart ├── pubspec.lock ├── pubspec.yaml └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png │ ├── index.html │ └── manifest.json ├── lib ├── src │ ├── cancelable │ │ └── cancelable.dart │ ├── number_of_processors │ │ ├── processors_io.dart │ │ └── processors_web.dart │ ├── port │ │ ├── send_port.dart │ │ ├── send_port_io.dart │ │ └── send_port_web.dart │ ├── scheduling │ │ ├── executor.dart │ │ ├── executor_logger.dart │ │ ├── task.dart │ │ └── work_priority.dart │ └── worker │ │ ├── cancel_request.dart │ │ ├── result.dart │ │ ├── worker.dart │ │ ├── worker_io.dart │ │ └── worker_web.dart └── worker_manager.dart ├── pubspec.lock ├── pubspec.yaml └── test ├── cancel_gentle_test.dart ├── cancel_gentle_test2.dart ├── canceling_test.dart ├── chaining_test.dart ├── error_handling_test.dart ├── performance_test.dart ├── port_communication_test.dart ├── pressure_test.dart └── work_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | - **7.2.5** - linter and links 3 | - **7.2.2** - bug fix 4 | - **7.2.1** - docs upd 5 | - **7.2.0** - executeNow method 6 | - **7.1.1** - .now priority and canceling capability 7 | - **7.0.3** - WASM Support 8 | - **7.0.1** - Code clean up 9 | - **7.0.0** - Performance impove, dynamicSpawn 10 | - **6.3.1** - Code clean up 11 | - **6.2.0** - Gentle execution with port feature and bug fixes 12 | - **6.1.0** - Introduced gentle execution feature 13 | - **6.0.5** - Logger fix 14 | - **6.0.4** - Dart version bump and library declaration refactor 15 | - **6.0.3** - Readme fix 16 | - **6.0.2** - Fix for port communication in the new Dart version 17 | - **6.0.1** - Export fix for web 18 | - **6.0.0** - Introduced Dart 3 features, optimizations, and code refactoring 19 | - **5.0.3** - Version bump and bug fix for notifications 20 | - **5.0.0** - Implemented messages communication between isolates (tasks) 21 | - **4.5.0** - Reverted to old async for Flutter tests 22 | - **4.4.8** - Web fix with initialized getter 23 | - **4.4.7** - Fixed bug with cancelling the first task during cold start 24 | - **4.4.6** - TypeSendPort placeholder for fake execution 25 | - **4.4.2** - Introduced web support with SendPort's new API 26 | - **4.4.0** - Notification from isolate via SendPort 27 | - **4.3.1** - Cold start fix 28 | - **4.3.0** - Introduced pause and resume capabilities for cancelable and Executors pool 29 | - **4.2.6** - Fixed all errors case bug and improved testing 30 | - **4.2.4** - Readme update and example fix 31 | - **4.1.1** - Fake isolate fix 32 | - **4.1.0** - Removed onNext 33 | - **4.0.0** - Introduced null safety 34 | - **3.2.6** - Added Cancelable.fromFuture constructor 35 | - **3.2.4** - Fixed onNext value null calling 36 | - **3.2.0** - Introduced static mergeAll method 37 | - **3.1.9** - Added mergeAll method 38 | - **3.1.7** - Readme fix 39 | - **3.1.6** - Readme update with explanation of how to use onValue and onNext callback and why 40 | - **2.8.4** - Edited cancelable to be more like then callback 41 | - **2.8.3** - Introduced fake execute method 42 | - **2.6.6** - Added "next" method to chain result with next Cancelable 43 | - **2.6.0** - Reverted value 44 | - **2.5.9** - Removed value from Cancelable 45 | - **2.5.4** - Cancelable now implements Future 46 | - **2.5.3** - Changed cancelableOperation to Cancelable 47 | - **2.5.0** - Warm up required 48 | - **2.4.1** - Readme update and removed unnecessary wrappers 49 | - **2.4.1** - Introduced cancelable operation 50 | - **2.3.6** - Changed return type in addTask. (Still possible to wrap as Stream from future) 51 | - **2.3.0** - Introduced runnable 52 | - **2.1.4** - Optimized task removal 53 | - **2.0.9** - Introduced task types 54 | - **2.0.7** - Readme update and dependencies 55 | - **2.0.5** - Implemented FIFO adding 56 | - **2.0.4** - Code clean up 57 | - **2.0.1** - Removed ghost -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Daniil Surnin 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Worker Manager 2 | 3 | Worker Manager is a powerful and easy-to-use library that helps you efficiently manage CPU-intensive tasks in your Flutter applications. It offers several advantages over traditional async programming or the built-in compute method. Note that the functions you are passing should either be static methods, globally defined functions or lambdas to ensure they are accessible from other isolates. 4 | 5 | # New Feature - dynamicSpawn flag in init 6 | By using this flag, worker_manager changes its behavior regarding isolate management. If this flag is set to true, new isolates will be spawned only if necessary and killed when they are no longer needed. 7 | 8 | # Advantages 9 | 10 | ## Efficient Scheduling 11 | This library schedules CPU-intensive functions to avoid skipping frames or freezes in your Flutter application. It ensures that your app runs smoothly, even when dealing with heavy computations. 12 | 13 | ## Reusable Isolates 14 | Unlike the [compute](https://api.flutter.dev/flutter/foundation/compute-constant.html) method, which always creates a new Dart isolate, Worker Manager reuses existing isolates. This approach is more efficient and prevents overloading the CPU. When resources are not freed up, using the compute method may cause freezes and skipped frames. 15 | 16 | ## Cancelable Tasks 17 | Worker Manager provides a cancellation functionality through the Cancelable class and its `cancel` method. This feature allows developers to free up resources when they are no longer needed, improving the app's performance and responsiveness. 18 | 19 | ## Gentle Cancellation 20 | In addition to the standard cancellation method, Worker Manager offers a more gentle approach to cancellation. This new feature, `executeGentle`, does not immediately terminate the Dart isolate but instead provides a lambda function that can be called periodically within the task to check if it should be cancelled. This allows tasks to clean up and terminate gracefully. 21 | 22 | ## Inter-Isolate Communication 23 | The library supports communication between isolates with the `executeWithPort` method. This feature enables sending progress messages or other updates between isolates, providing more control over your tasks. 24 | 25 | ## Gentle Cancellation with Port 26 | The `executeGentleWithPort` method is another valuable feature of Worker Manager that combines gentle cancellation and inter-isolate communication. It accepts two arguments: a port for inter-isolate communication and a getter function `isCancelled` for gentle cancellation. This offers more flexibility and control, allowing tasks to communicate with other isolates while also providing an opportunity for graceful termination. 27 | 28 | # Usage 29 | 30 | ## Execute the task 31 | ```dart 32 | Cancelable cancelable = workerManager.execute( 33 | () async { 34 | // Your CPU-intensive function here 35 | }, 36 | priority: WorkPriority.immediately, 37 | ); 38 | ``` 39 | ## Execute a Task with Gentle Cancellation 40 | ```dart 41 | Cancelable cancelable = workerManager.executeGentle( 42 | (isCanceled) async { 43 | while (!isCanceled()) { 44 | // Your CPU-intensive function here 45 | // Check isCanceled() periodically to decide whether to continue or break the loop 46 | } 47 | }, 48 | priority: WorkPriority.immediately, 49 | ); 50 | ``` 51 | ## Execute a Task with Inter-Isolate Communication 52 | ```dart 53 | Cancelable cancelable = workerManager.executeWithPort( 54 | (SendPort sendPort) async { 55 | // Your CPU-intensive function here 56 | // Use sendPort.send(message) to communicate with the main isolate 57 | }, 58 | onMessage: (MessageType message) { 59 | // Handle the received message in the main isolate 60 | }, 61 | ); 62 | ``` 63 | 64 | ## Execute a Task with Gentle Cancellation and Inter-Isolate Communication 65 | ```dart 66 | Cancelable cancelable = workerManager.executeGentleWithPort( 67 | (SendPort sendPort, IsCanceled isCanceled) async { 68 | while (!isCanceled()) { 69 | // Your CPU-intensive function here 70 | // Use sendPort.send(message) to communicate with the main isolate 71 | // Check isCanceled() periodically to decide whether to continue or break the loop 72 | } 73 | }, 74 | onMessage: (MessageType message) { 75 | // Handle the received message in the main isolate 76 | }, 77 | priority: WorkPriority.immediately, 78 | ); 79 | ``` 80 | 81 | ## Cancel a Task 82 | ```dart 83 | cancelable.cancel(); 84 | ``` 85 | 86 | ## Dispose Worker Manager 87 | ```dart 88 | await workerManager.dispose(); 89 | ``` 90 | 91 | # Notice 92 | Before isolates support in wasm, implementation of execution of task same as compute method from foundation 93 | 94 | # Conclusion 95 | By using Worker Manager, you can enjoy the benefits of efficient task scheduling, reusable isolates, cancellable tasks, and inter-isolate communication. It provides a clear advantage over traditional async programming and the built-in compute method, ensuring that your Flutter applications remain performant and responsive even when handling CPU-intensive tasks. The additional `executeGentleWithPort` feature provides both gentle cancellation and inter-isolate communication for your tasks, offering further control and efficiency. 96 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "4cf269e36de2573851eaef3c763994f8f9be494d" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 4cf269e36de2573851eaef3c763994f8f9be494d 17 | base_revision: 4cf269e36de2573851eaef3c763994f8f9be494d 18 | - platform: web 19 | create_revision: 4cf269e36de2573851eaef3c763994f8f9be494d 20 | base_revision: 4cf269e36de2573851eaef3c763994f8f9be494d 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | #example 2 | ``` 3 | // Copyright Daniil Surnin. All rights reserved. 4 | // Use of this source code is governed by a Apache license that can be 5 | // found in the LICENSE file. 6 | 7 | import 'dart:async'; 8 | 9 | import 'package:flutter/foundation.dart'; 10 | import 'package:flutter/material.dart'; 11 | import 'package:http/http.dart'; 12 | import 'package:worker_manager/worker_manager.dart'; 13 | 14 | void main() async { 15 | /* this is not necessary, this code will spawn 16 | before your awesome widgets will build, 17 | to avoid micro freezes 18 | if you don't want to spawn free of calculation isolates, 19 | just don't write this code : 20 | ```WorkerManager().initManager()```*/ 21 | await WorkerManager().initManager(); 22 | runApp(MyApp()); 23 | } 24 | 25 | class MyApp extends StatelessWidget { 26 | @override 27 | Widget build(BuildContext context) { 28 | return MaterialApp( 29 | showPerformanceOverlay: true, 30 | home: MyHomePage(), 31 | ); 32 | } 33 | } 34 | 35 | class MyHomePage extends StatefulWidget { 36 | MyHomePage({Key key}) : super(key: key); 37 | @override 38 | _MyHomePageState createState() => _MyHomePageState(); 39 | } 40 | 41 | class _MyHomePageState extends State { 42 | /*WorkerManager is Singleton. Just create link it everywhere you want*/ 43 | WorkerManager workerManager = WorkerManager(); 44 | int clicks = 0; 45 | List results = []; 46 | DateTime time; 47 | 48 | /* 49 | creating task for workerManager with global function and Bundle class for your function. 50 | bundle and timeout is optional parameters. 51 | */ 52 | final task = Task(function: fib, bundle: 40, timeout: Duration(days: 78)); 53 | 54 | /*remember, that you global function must have only one parameter, like int, String or your 55 | bundle class . 56 | For example: 57 | Class Bundle { 58 | final int age; 59 | final String name; 60 | Bundle(this.age, this.name); 61 | } 62 | optional parameters is ok, just be ready to avoid NPE 63 | */ 64 | @override 65 | Widget build(BuildContext context) { 66 | return Scaffold( 67 | body: Center( 68 | child: Container( 69 | height: 350, 70 | width: 200, 71 | color: Colors.cyan, 72 | child: Column( 73 | children: [ 74 | RaisedButton( 75 | child: Text('fib(40)'), 76 | onPressed: () async { 77 | if (time == null) time = DateTime.now(); 78 | //manageWork function working with your task and returning stream which 79 | //return result of your global function in listen callback 80 | // also Stream from manage work handling errors 81 | workerManager.manageWork(task: task).listen((sr) { 82 | setState(() { 83 | results.add(sr); 84 | }); 85 | if (results.length == 3) { 86 | print(DateTime.now().difference(time)); 87 | } 88 | }).onError((error) { 89 | print(error); 90 | }); 91 | setState(() { 92 | clicks++; 93 | }); 94 | }, 95 | ), 96 | RaisedButton( 97 | child: Text('kill'), 98 | onPressed: () { 99 | // killing task, stream will return nothing 100 | workerManager.killTask(task: task); 101 | }, 102 | ), 103 | Row( 104 | children: [ 105 | Text(clicks.toString()), 106 | CircularProgressIndicator(), 107 | Text(results.length.toString()) 108 | ], 109 | ) 110 | ], 111 | ), 112 | ), 113 | ), 114 | ); 115 | } 116 | 117 | @override 118 | void dispose() { 119 | // Good case when you want to end your hard calculations in dispose method 120 | workerManager.killTask(task: task); 121 | super.dispose(); 122 | } 123 | } 124 | 125 | int fib(int n) { 126 | if (n < 2) { 127 | return n; 128 | } 129 | return fib(n - 2) + fib(n - 1); 130 | } 131 | 132 | Future getData(String kek) async => (await get(kek)).body.toString(); 133 | ``` 134 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:lints/recommended.yaml -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | id "dev.flutter.flutter-gradle-plugin" 5 | } 6 | 7 | def localProperties = new Properties() 8 | def localPropertiesFile = rootProject.file('local.properties') 9 | if (localPropertiesFile.exists()) { 10 | localPropertiesFile.withReader('UTF-8') { reader -> 11 | localProperties.load(reader) 12 | } 13 | } 14 | 15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 16 | if (flutterVersionCode == null) { 17 | flutterVersionCode = '1' 18 | } 19 | 20 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 21 | if (flutterVersionName == null) { 22 | flutterVersionName = '1.0' 23 | } 24 | 25 | android { 26 | namespace "com.renesanse.example" 27 | compileSdkVersion flutter.compileSdkVersion 28 | ndkVersion flutter.ndkVersion 29 | 30 | compileOptions { 31 | sourceCompatibility JavaVersion.VERSION_1_8 32 | targetCompatibility JavaVersion.VERSION_1_8 33 | } 34 | 35 | kotlinOptions { 36 | jvmTarget = '1.8' 37 | } 38 | 39 | sourceSets { 40 | main.java.srcDirs += 'src/main/kotlin' 41 | } 42 | 43 | lintOptions { 44 | disable 'InvalidPackage' 45 | } 46 | 47 | defaultConfig { 48 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 49 | applicationId "com.renesanse.example" 50 | // You can update the following values to match your application needs. 51 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 52 | minSdkVersion flutter.minSdkVersion 53 | targetSdkVersion flutter.targetSdkVersion 54 | versionCode flutterVersionCode.toInteger() 55 | versionName flutterVersionName 56 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 57 | } 58 | 59 | buildTypes { 60 | release { 61 | // TODO: Add your own signing config for the release build. 62 | // Signing with the debug keys for now, so `flutter run --release` works. 63 | signingConfig signingConfigs.debug 64 | } 65 | } 66 | } 67 | 68 | flutter { 69 | source '../..' 70 | } 71 | 72 | dependencies { 73 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 74 | testImplementation 'junit:junit:4.12' 75 | androidTestImplementation 'androidx.test:runner:1.1.1' 76 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 77 | } 78 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 14 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/renesanse/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.renesanse.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | import io.flutter.embedding.engine.FlutterEngine 5 | import io.flutter.plugins.GeneratedPluginRegistrant 6 | 7 | class MainActivity: FlutterActivity() { 8 | override fun configureFlutterEngine(flutterEngine: FlutterEngine) { 9 | GeneratedPluginRegistrant.registerWith(flutterEngine) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 | } 11 | } 12 | 13 | allprojects { 14 | repositories { 15 | google() 16 | mavenCentral() 17 | } 18 | } 19 | 20 | rootProject.buildDir = '../build' 21 | subprojects { 22 | project.buildDir = "${rootProject.buildDir}/${project.name}" 23 | } 24 | subprojects { 25 | project.evaluationDependsOn(':app') 26 | } 27 | 28 | tasks.register("clean", Delete) { 29 | delete rootProject.buildDir 30 | } 31 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | android.enableR8=true 6 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 6 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | } 9 | settings.ext.flutterSdkPath = flutterSdkPath() 10 | 11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") 12 | 13 | repositories { 14 | google() 15 | mavenCentral() 16 | gradlePluginPortal() 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false 21 | } 22 | } 23 | 24 | plugins { 25 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 26 | id "com.android.application" version "7.3.0" apply false 27 | } 28 | 29 | include ':app' 30 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=/Users/daizen37/flutter" 4 | export "FLUTTER_APPLICATION_PATH=/Users/daizen37/worker_manager/example" 5 | export "COCOAPODS_PARALLEL_CODE_SIGN=true" 6 | export "FLUTTER_TARGET=/Users/daizen37/worker_manager/example/lib/main.dart" 7 | export "FLUTTER_BUILD_DIR=build" 8 | export "FLUTTER_BUILD_NAME=1.0.0" 9 | export "FLUTTER_BUILD_NUMBER=1" 10 | export "DART_OBFUSCATION=false" 11 | export "TRACK_WIDGET_CREATION=true" 12 | export "TREE_SHAKE_ICONS=false" 13 | export "PACKAGE_CONFIG=/Users/daizen37/worker_manager/example/.dart_tool/package_config.json" 14 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 34 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 35 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 36 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 37 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 38 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 39 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 40 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 41 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 43 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 44 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 45 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | /* End PBXFileReference section */ 47 | 48 | /* Begin PBXFrameworksBuildPhase section */ 49 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | 9740EEB11CF90186004384FC /* Flutter */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 63 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 64 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 65 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 66 | ); 67 | name = Flutter; 68 | sourceTree = ""; 69 | }; 70 | 97C146E51CF9000F007C117D = { 71 | isa = PBXGroup; 72 | children = ( 73 | 9740EEB11CF90186004384FC /* Flutter */, 74 | 97C146F01CF9000F007C117D /* Runner */, 75 | 97C146EF1CF9000F007C117D /* Products */, 76 | ); 77 | sourceTree = ""; 78 | }; 79 | 97C146EF1CF9000F007C117D /* Products */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 97C146EE1CF9000F007C117D /* Runner.app */, 83 | ); 84 | name = Products; 85 | sourceTree = ""; 86 | }; 87 | 97C146F01CF9000F007C117D /* Runner */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 91 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 92 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 93 | 97C147021CF9000F007C117D /* Info.plist */, 94 | 97C146F11CF9000F007C117D /* Supporting Files */, 95 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 96 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 97 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 98 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 99 | ); 100 | path = Runner; 101 | sourceTree = ""; 102 | }; 103 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | ); 107 | name = "Supporting Files"; 108 | sourceTree = ""; 109 | }; 110 | /* End PBXGroup section */ 111 | 112 | /* Begin PBXNativeTarget section */ 113 | 97C146ED1CF9000F007C117D /* Runner */ = { 114 | isa = PBXNativeTarget; 115 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 116 | buildPhases = ( 117 | 9740EEB61CF901F6004384FC /* Run Script */, 118 | 97C146EA1CF9000F007C117D /* Sources */, 119 | 97C146EB1CF9000F007C117D /* Frameworks */, 120 | 97C146EC1CF9000F007C117D /* Resources */, 121 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 122 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 123 | ); 124 | buildRules = ( 125 | ); 126 | dependencies = ( 127 | ); 128 | name = Runner; 129 | productName = Runner; 130 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 131 | productType = "com.apple.product-type.application"; 132 | }; 133 | /* End PBXNativeTarget section */ 134 | 135 | /* Begin PBXProject section */ 136 | 97C146E61CF9000F007C117D /* Project object */ = { 137 | isa = PBXProject; 138 | attributes = { 139 | LastUpgradeCheck = 1510; 140 | ORGANIZATIONNAME = "The Chromium Authors"; 141 | TargetAttributes = { 142 | 97C146ED1CF9000F007C117D = { 143 | CreatedOnToolsVersion = 7.3.1; 144 | LastSwiftMigration = 0910; 145 | }; 146 | }; 147 | }; 148 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 149 | compatibilityVersion = "Xcode 3.2"; 150 | developmentRegion = en; 151 | hasScannedForEncodings = 0; 152 | knownRegions = ( 153 | en, 154 | Base, 155 | ); 156 | mainGroup = 97C146E51CF9000F007C117D; 157 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 158 | projectDirPath = ""; 159 | projectRoot = ""; 160 | targets = ( 161 | 97C146ED1CF9000F007C117D /* Runner */, 162 | ); 163 | }; 164 | /* End PBXProject section */ 165 | 166 | /* Begin PBXResourcesBuildPhase section */ 167 | 97C146EC1CF9000F007C117D /* Resources */ = { 168 | isa = PBXResourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 172 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 173 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 174 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 175 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXResourcesBuildPhase section */ 180 | 181 | /* Begin PBXShellScriptBuildPhase section */ 182 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 183 | isa = PBXShellScriptBuildPhase; 184 | alwaysOutOfDate = 1; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | ); 188 | inputPaths = ( 189 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 190 | ); 191 | name = "Thin Binary"; 192 | outputPaths = ( 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | shellPath = /bin/sh; 196 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 197 | }; 198 | 9740EEB61CF901F6004384FC /* Run Script */ = { 199 | isa = PBXShellScriptBuildPhase; 200 | alwaysOutOfDate = 1; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | ); 204 | inputPaths = ( 205 | ); 206 | name = "Run Script"; 207 | outputPaths = ( 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | shellPath = /bin/sh; 211 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 212 | }; 213 | /* End PBXShellScriptBuildPhase section */ 214 | 215 | /* Begin PBXSourcesBuildPhase section */ 216 | 97C146EA1CF9000F007C117D /* Sources */ = { 217 | isa = PBXSourcesBuildPhase; 218 | buildActionMask = 2147483647; 219 | files = ( 220 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 221 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | }; 225 | /* End PBXSourcesBuildPhase section */ 226 | 227 | /* Begin PBXVariantGroup section */ 228 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 229 | isa = PBXVariantGroup; 230 | children = ( 231 | 97C146FB1CF9000F007C117D /* Base */, 232 | ); 233 | name = Main.storyboard; 234 | sourceTree = ""; 235 | }; 236 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 237 | isa = PBXVariantGroup; 238 | children = ( 239 | 97C147001CF9000F007C117D /* Base */, 240 | ); 241 | name = LaunchScreen.storyboard; 242 | sourceTree = ""; 243 | }; 244 | /* End PBXVariantGroup section */ 245 | 246 | /* Begin XCBuildConfiguration section */ 247 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | ALWAYS_SEARCH_USER_PATHS = NO; 251 | CLANG_ANALYZER_NONNULL = YES; 252 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 253 | CLANG_CXX_LIBRARY = "libc++"; 254 | CLANG_ENABLE_MODULES = YES; 255 | CLANG_ENABLE_OBJC_ARC = YES; 256 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 257 | CLANG_WARN_BOOL_CONVERSION = YES; 258 | CLANG_WARN_COMMA = YES; 259 | CLANG_WARN_CONSTANT_CONVERSION = YES; 260 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 261 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 262 | CLANG_WARN_EMPTY_BODY = YES; 263 | CLANG_WARN_ENUM_CONVERSION = YES; 264 | CLANG_WARN_INFINITE_RECURSION = YES; 265 | CLANG_WARN_INT_CONVERSION = YES; 266 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 267 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 268 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 269 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 270 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 271 | CLANG_WARN_STRICT_PROTOTYPES = YES; 272 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 273 | CLANG_WARN_UNREACHABLE_CODE = YES; 274 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 275 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 276 | COPY_PHASE_STRIP = NO; 277 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 278 | ENABLE_NS_ASSERTIONS = NO; 279 | ENABLE_STRICT_OBJC_MSGSEND = YES; 280 | GCC_C_LANGUAGE_STANDARD = gnu99; 281 | GCC_NO_COMMON_BLOCKS = YES; 282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 284 | GCC_WARN_UNDECLARED_SELECTOR = YES; 285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 286 | GCC_WARN_UNUSED_FUNCTION = YES; 287 | GCC_WARN_UNUSED_VARIABLE = YES; 288 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 289 | MTL_ENABLE_DEBUG_INFO = NO; 290 | SDKROOT = iphoneos; 291 | TARGETED_DEVICE_FAMILY = "1,2"; 292 | VALIDATE_PRODUCT = YES; 293 | }; 294 | name = Profile; 295 | }; 296 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 297 | isa = XCBuildConfiguration; 298 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 299 | buildSettings = { 300 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 301 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 302 | DEVELOPMENT_TEAM = 83DC5BF22F; 303 | ENABLE_BITCODE = NO; 304 | FRAMEWORK_SEARCH_PATHS = ( 305 | "$(inherited)", 306 | "$(PROJECT_DIR)/Flutter", 307 | ); 308 | INFOPLIST_FILE = Runner/Info.plist; 309 | LD_RUNPATH_SEARCH_PATHS = ( 310 | "$(inherited)", 311 | "@executable_path/Frameworks", 312 | ); 313 | LIBRARY_SEARCH_PATHS = ( 314 | "$(inherited)", 315 | "$(PROJECT_DIR)/Flutter", 316 | ); 317 | PRODUCT_BUNDLE_IDENTIFIER = com.renesanse.example; 318 | PRODUCT_NAME = "$(TARGET_NAME)"; 319 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 320 | SWIFT_VERSION = 4.0; 321 | VERSIONING_SYSTEM = "apple-generic"; 322 | }; 323 | name = Profile; 324 | }; 325 | 97C147031CF9000F007C117D /* Debug */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | ALWAYS_SEARCH_USER_PATHS = NO; 329 | CLANG_ANALYZER_NONNULL = YES; 330 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 331 | CLANG_CXX_LIBRARY = "libc++"; 332 | CLANG_ENABLE_MODULES = YES; 333 | CLANG_ENABLE_OBJC_ARC = YES; 334 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 335 | CLANG_WARN_BOOL_CONVERSION = YES; 336 | CLANG_WARN_COMMA = YES; 337 | CLANG_WARN_CONSTANT_CONVERSION = YES; 338 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 339 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 340 | CLANG_WARN_EMPTY_BODY = YES; 341 | CLANG_WARN_ENUM_CONVERSION = YES; 342 | CLANG_WARN_INFINITE_RECURSION = YES; 343 | CLANG_WARN_INT_CONVERSION = YES; 344 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 345 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 346 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 347 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 348 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 349 | CLANG_WARN_STRICT_PROTOTYPES = YES; 350 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 351 | CLANG_WARN_UNREACHABLE_CODE = YES; 352 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 353 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 354 | COPY_PHASE_STRIP = NO; 355 | DEBUG_INFORMATION_FORMAT = dwarf; 356 | ENABLE_STRICT_OBJC_MSGSEND = YES; 357 | ENABLE_TESTABILITY = YES; 358 | GCC_C_LANGUAGE_STANDARD = gnu99; 359 | GCC_DYNAMIC_NO_PIC = NO; 360 | GCC_NO_COMMON_BLOCKS = YES; 361 | GCC_OPTIMIZATION_LEVEL = 0; 362 | GCC_PREPROCESSOR_DEFINITIONS = ( 363 | "DEBUG=1", 364 | "$(inherited)", 365 | ); 366 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 367 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 368 | GCC_WARN_UNDECLARED_SELECTOR = YES; 369 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 370 | GCC_WARN_UNUSED_FUNCTION = YES; 371 | GCC_WARN_UNUSED_VARIABLE = YES; 372 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 373 | MTL_ENABLE_DEBUG_INFO = YES; 374 | ONLY_ACTIVE_ARCH = YES; 375 | SDKROOT = iphoneos; 376 | TARGETED_DEVICE_FAMILY = "1,2"; 377 | }; 378 | name = Debug; 379 | }; 380 | 97C147041CF9000F007C117D /* Release */ = { 381 | isa = XCBuildConfiguration; 382 | buildSettings = { 383 | ALWAYS_SEARCH_USER_PATHS = NO; 384 | CLANG_ANALYZER_NONNULL = YES; 385 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 386 | CLANG_CXX_LIBRARY = "libc++"; 387 | CLANG_ENABLE_MODULES = YES; 388 | CLANG_ENABLE_OBJC_ARC = YES; 389 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 390 | CLANG_WARN_BOOL_CONVERSION = YES; 391 | CLANG_WARN_COMMA = YES; 392 | CLANG_WARN_CONSTANT_CONVERSION = YES; 393 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 394 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 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_UNREACHABLE_CODE = YES; 407 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 408 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 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 = gnu99; 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 = 12.0; 422 | MTL_ENABLE_DEBUG_INFO = NO; 423 | SDKROOT = iphoneos; 424 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 425 | TARGETED_DEVICE_FAMILY = "1,2"; 426 | VALIDATE_PRODUCT = YES; 427 | }; 428 | name = Release; 429 | }; 430 | 97C147061CF9000F007C117D /* Debug */ = { 431 | isa = XCBuildConfiguration; 432 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 433 | buildSettings = { 434 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 435 | CLANG_ENABLE_MODULES = YES; 436 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 437 | DEVELOPMENT_TEAM = 83DC5BF22F; 438 | ENABLE_BITCODE = NO; 439 | FRAMEWORK_SEARCH_PATHS = ( 440 | "$(inherited)", 441 | "$(PROJECT_DIR)/Flutter", 442 | ); 443 | INFOPLIST_FILE = Runner/Info.plist; 444 | LD_RUNPATH_SEARCH_PATHS = ( 445 | "$(inherited)", 446 | "@executable_path/Frameworks", 447 | ); 448 | LIBRARY_SEARCH_PATHS = ( 449 | "$(inherited)", 450 | "$(PROJECT_DIR)/Flutter", 451 | ); 452 | PRODUCT_BUNDLE_IDENTIFIER = com.renesanse.example; 453 | PRODUCT_NAME = "$(TARGET_NAME)"; 454 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 455 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 456 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 457 | SWIFT_VERSION = 4.0; 458 | VERSIONING_SYSTEM = "apple-generic"; 459 | }; 460 | name = Debug; 461 | }; 462 | 97C147071CF9000F007C117D /* Release */ = { 463 | isa = XCBuildConfiguration; 464 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 465 | buildSettings = { 466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 467 | CLANG_ENABLE_MODULES = YES; 468 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 469 | DEVELOPMENT_TEAM = 83DC5BF22F; 470 | ENABLE_BITCODE = NO; 471 | FRAMEWORK_SEARCH_PATHS = ( 472 | "$(inherited)", 473 | "$(PROJECT_DIR)/Flutter", 474 | ); 475 | INFOPLIST_FILE = Runner/Info.plist; 476 | LD_RUNPATH_SEARCH_PATHS = ( 477 | "$(inherited)", 478 | "@executable_path/Frameworks", 479 | ); 480 | LIBRARY_SEARCH_PATHS = ( 481 | "$(inherited)", 482 | "$(PROJECT_DIR)/Flutter", 483 | ); 484 | PRODUCT_BUNDLE_IDENTIFIER = com.renesanse.example; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 487 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 488 | SWIFT_VERSION = 4.0; 489 | VERSIONING_SYSTEM = "apple-generic"; 490 | }; 491 | name = Release; 492 | }; 493 | /* End XCBuildConfiguration section */ 494 | 495 | /* Begin XCConfigurationList section */ 496 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 497 | isa = XCConfigurationList; 498 | buildConfigurations = ( 499 | 97C147031CF9000F007C117D /* Debug */, 500 | 97C147041CF9000F007C117D /* Release */, 501 | 249021D3217E4FDB00AE95B9 /* Profile */, 502 | ); 503 | defaultConfigurationIsVisible = 0; 504 | defaultConfigurationName = Release; 505 | }; 506 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 507 | isa = XCConfigurationList; 508 | buildConfigurations = ( 509 | 97C147061CF9000F007C117D /* Debug */, 510 | 97C147071CF9000F007C117D /* Release */, 511 | 249021D4217E4FDB00AE95B9 /* Profile */, 512 | ); 513 | defaultConfigurationIsVisible = 0; 514 | defaultConfigurationName = Release; 515 | }; 516 | /* End XCConfigurationList section */ 517 | }; 518 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 519 | } 520 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/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 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/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 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /example/ios/Runner/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 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | // Copyright Daniil Surnin. All rights reserved. 2 | // Use of this source code is governed by a Apache license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/cupertino.dart'; 6 | import 'package:flutter/foundation.dart'; 7 | import 'package:flutter/material.dart'; 8 | import 'package:worker_manager/worker_manager.dart'; 9 | 10 | void main() async { 11 | workerManager.log = true; 12 | await workerManager.init(); 13 | runApp(MyApp()); 14 | } 15 | 16 | class MyApp extends StatelessWidget { 17 | @override 18 | Widget build(BuildContext context) { 19 | return const MaterialApp( 20 | showPerformanceOverlay: !kIsWeb, 21 | home: MyHomePage(), 22 | ); 23 | } 24 | } 25 | 26 | class MyHomePage extends StatefulWidget { 27 | const MyHomePage({Key? key}) : super(key: key); 28 | 29 | @override 30 | State createState() => _MyHomePageState(); 31 | } 32 | 33 | class _MyHomePageState extends State { 34 | final computeResults = []; 35 | final executorResults = []; 36 | var computeTaskRun = 0; 37 | var executorTaskRun = 0; 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | return Scaffold( 42 | body: Center( 43 | child: Column( 44 | mainAxisAlignment: MainAxisAlignment.center, 45 | children: [ 46 | Text("Fibonacci calculation of 43 "), 47 | const CircularProgressIndicator(), 48 | Row( 49 | children: [ 50 | Text(computeTaskRun.toString()), 51 | Spacer(), 52 | Text(executorTaskRun.toString()), 53 | ], 54 | ), 55 | const SizedBox( 56 | height: 200, 57 | ), 58 | Text('Results'), 59 | Row( 60 | children: [ 61 | Text(computeResults.length.toString()), 62 | Spacer(), 63 | Text(executorResults.length.toString()), 64 | ], 65 | ), 66 | Row( 67 | children: [ 68 | CupertinoButton( 69 | child: Text('run compute'), 70 | onPressed: () { 71 | for (var i = 0; i < 1; i++) { 72 | compute(fibCompute, 43).then((value) { 73 | setState(() { 74 | computeResults.add(value); 75 | }); 76 | }); 77 | } 78 | }, 79 | ), 80 | Spacer(), 81 | CupertinoButton( 82 | child: Text('run executor'), 83 | onPressed: () { 84 | for (var i = 0; i < 1; i++) { 85 | workerManager.execute(() => fib(43)).then((value) { 86 | setState(() { 87 | executorResults.add(value); 88 | }); 89 | }); 90 | } 91 | }, 92 | ) 93 | ], 94 | ), 95 | ], 96 | ), 97 | ), 98 | ); 99 | } 100 | } 101 | 102 | int fib(int n) { 103 | if (n < 2) { 104 | return n; 105 | } 106 | return fib(n - 2) + fib(n - 1); 107 | } 108 | 109 | int fibCompute(int n) { 110 | if (n < 2) { 111 | return n; 112 | } 113 | return fibCompute(n - 2) + fibCompute(n - 1); 114 | } 115 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | characters: 13 | dependency: transitive 14 | description: 15 | name: characters 16 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "1.4.0" 20 | collection: 21 | dependency: transitive 22 | description: 23 | name: collection 24 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.19.1" 28 | flutter: 29 | dependency: "direct main" 30 | description: flutter 31 | source: sdk 32 | version: "0.0.0" 33 | lints: 34 | dependency: "direct dev" 35 | description: 36 | name: lints 37 | sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" 38 | url: "https://pub.dev" 39 | source: hosted 40 | version: "2.1.1" 41 | material_color_utilities: 42 | dependency: transitive 43 | description: 44 | name: material_color_utilities 45 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 46 | url: "https://pub.dev" 47 | source: hosted 48 | version: "0.11.1" 49 | meta: 50 | dependency: transitive 51 | description: 52 | name: meta 53 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c 54 | url: "https://pub.dev" 55 | source: hosted 56 | version: "1.16.0" 57 | sky_engine: 58 | dependency: transitive 59 | description: flutter 60 | source: sdk 61 | version: "0.0.0" 62 | vector_math: 63 | dependency: transitive 64 | description: 65 | name: vector_math 66 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 67 | url: "https://pub.dev" 68 | source: hosted 69 | version: "2.1.4" 70 | web: 71 | dependency: transitive 72 | description: 73 | name: web 74 | sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" 75 | url: "https://pub.dev" 76 | source: hosted 77 | version: "1.1.1" 78 | worker_manager: 79 | dependency: "direct main" 80 | description: 81 | path: ".." 82 | relative: true 83 | source: path 84 | version: "7.2.2" 85 | sdks: 86 | dart: ">=3.7.0-0 <4.0.0" 87 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | publish_to: none 16 | 17 | environment: 18 | sdk: ">=2.12.0 <4.0.0" 19 | 20 | dependencies: 21 | flutter: 22 | sdk: flutter 23 | 24 | # The following adds the Cupertino Icons font to your application. 25 | # Use with the CupertinoIcons class for iOS style icons. 26 | worker_manager: 27 | path: ../ 28 | 29 | dev_dependencies: 30 | lints: ^2.0.0 31 | 32 | 33 | # For information on the generic Dart part of this file, see the 34 | # following page: https://dart.dev/tools/pub/pubspec 35 | 36 | # The following section is specific to Flutter. 37 | flutter: 38 | 39 | # The following line ensures that the Material Icons font is 40 | # included with your application, so that you can use the icons in 41 | # the material Icons class. 42 | uses-material-design: true 43 | 44 | # To add assets to your application, add an assets section, like this: 45 | # assets: 46 | # - images/a_dot_burr.jpeg 47 | # - images/a_dot_ham.jpeg 48 | 49 | # An image asset can refer to one or more resolution-specific "variants", see 50 | # https://flutter.dev/assets-and-images/#resolution-aware. 51 | 52 | # For details regarding adding assets from package dependencies, see 53 | # https://flutter.dev/assets-and-images/#from-packages 54 | 55 | # To add custom fonts to your application, add a fonts section here, 56 | # in this "flutter" section. Each entry in this list should have a 57 | # "family" key with the font family name, and a "fonts" key with a 58 | # list giving the asset and other descriptors for the font. For 59 | # example: 60 | # fonts: 61 | # - family: Schyler 62 | # fonts: 63 | # - asset: fonts/Schyler-Regular.ttf 64 | # - asset: fonts/Schyler-Italic.ttf 65 | # style: italic 66 | # - family: Trajan Pro 67 | # fonts: 68 | # - asset: fonts/TrajanPro.ttf 69 | # - asset: fonts/TrajanPro_Bold.ttf 70 | # weight: 700 71 | # 72 | # For details regarding fonts from package dependencies, 73 | # see https://flutter.dev/custom-fonts/#from-packages 74 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsrenesanse/worker_manager/38982b46e7c04eec76314ec898b7b2c018272bed/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | example 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/src/cancelable/cancelable.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:meta/meta.dart'; 3 | 4 | class CanceledError implements Exception {} 5 | 6 | class Cancelable implements Future { 7 | final Completer _completer; 8 | final void Function()? _onCancel; 9 | var _canceled = false; 10 | 11 | Cancelable({ 12 | required Completer completer, 13 | void Function()? onCancel, 14 | }) : _completer = completer, 15 | _onCancel = onCancel; 16 | 17 | factory Cancelable.fromFuture(Future future) { 18 | final completer = Completer(); 19 | future.then( 20 | (value) => completer.complete(value), 21 | onError: (Object e, StackTrace s) { 22 | _completeError(completer: completer, error: e, stackTrace: s); 23 | }, 24 | ); 25 | return Cancelable( 26 | completer: completer, 27 | onCancel: () { 28 | _completeError(completer: completer, error: CanceledError()); 29 | }, 30 | ); 31 | } 32 | 33 | Future get future => _completer.future; 34 | 35 | static void _completeError({ 36 | required Completer completer, 37 | required Object error, 38 | StackTrace? stackTrace, 39 | FutureOr Function(Object error)? onError, 40 | }) { 41 | if (onError != null) { 42 | completer.complete(onError(error)); 43 | } else { 44 | completer.completeError(error, stackTrace); 45 | } 46 | } 47 | 48 | void cancel() { 49 | if (!_canceled) { 50 | _canceled = true; 51 | _onCancel?.call(); 52 | } 53 | } 54 | 55 | Cancelable thenNext(FutureOr Function(R value) onValue, 56 | [FutureOr Function(Object error)? onError]) { 57 | final resultCompleter = Completer(); 58 | _completer.future.then((value) { 59 | try { 60 | resultCompleter.complete(onValue(value)); 61 | } catch (error) { 62 | _completeError( 63 | completer: resultCompleter, 64 | onError: onError, 65 | error: error, 66 | ); 67 | } 68 | }, onError: (Object error) { 69 | _completeError( 70 | completer: resultCompleter, 71 | onError: onError, 72 | error: error, 73 | ); 74 | }); 75 | return Cancelable( 76 | completer: resultCompleter, 77 | onCancel: _onCancel, 78 | ); 79 | } 80 | 81 | @experimental 82 | static Cancelable> mergeAll( 83 | Iterable> cancelables, 84 | ) { 85 | final resultCompleter = Completer>(); 86 | Future.wait(cancelables).then((value) { 87 | resultCompleter.complete(value); 88 | }, onError: (Object error) { 89 | _completeError( 90 | completer: resultCompleter, 91 | error: error, 92 | ); 93 | }); 94 | return Cancelable( 95 | completer: resultCompleter, 96 | onCancel: () { 97 | for (final cancelable in cancelables) { 98 | cancelable.cancel(); 99 | } 100 | }, 101 | ); 102 | } 103 | 104 | @override 105 | Stream asStream() => future.asStream(); 106 | 107 | @override 108 | Future catchError( 109 | Function onError, { 110 | bool Function(Object error)? test, 111 | }) { 112 | return future.catchError(onError, test: test); 113 | } 114 | 115 | @override 116 | Future timeout( 117 | Duration timeLimit, { 118 | FutureOr Function()? onTimeout, 119 | }) { 120 | return future.timeout(timeLimit); 121 | } 122 | 123 | @override 124 | Future whenComplete(FutureOr Function() action) { 125 | return future.whenComplete(action); 126 | } 127 | 128 | @override 129 | Future then( 130 | FutureOr Function(R value) onValue, { 131 | Function? onError, 132 | }) { 133 | return future.then(onValue, onError: onError); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/src/number_of_processors/processors_io.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | int get numberOfProcessors => Platform.numberOfProcessors - 1; 4 | -------------------------------------------------------------------------------- /lib/src/number_of_processors/processors_web.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:web/web.dart' as web; 3 | 4 | /// Returns the number of available processors for concurrent execution. 5 | /// 6 | /// This function uses the `navigator.hardwareConcurrency` API to determine 7 | /// the number of available threads. It returns n - 1 threads, where n is 8 | /// the number of available threads, with one thread reserved for the main 9 | /// thread to avoid skipping frames. 10 | 11 | int get numberOfProcessors { 12 | // Get the hardware concurrency, defaulting to 1 if not available 13 | final concurrency = web.window.navigator.hardwareConcurrency; 14 | 15 | // Subtract 1 and ensure the result is at least 1 16 | return max(concurrency - 1, 1); 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/port/send_port.dart: -------------------------------------------------------------------------------- 1 | export 'send_port_io.dart' 2 | if (dart.library.html) 'send_port_web.dart' 3 | if (dart.library.js_interop) 'send_port_web.dart'; 4 | -------------------------------------------------------------------------------- /lib/src/port/send_port_io.dart: -------------------------------------------------------------------------------- 1 | export 'dart:isolate' show SendPort; 2 | -------------------------------------------------------------------------------- /lib/src/port/send_port_web.dart: -------------------------------------------------------------------------------- 1 | class SendPort { 2 | void send(Object? message) {} 3 | } 4 | -------------------------------------------------------------------------------- /lib/src/scheduling/executor.dart: -------------------------------------------------------------------------------- 1 | part of '../../worker_manager.dart'; 2 | 3 | final workerManager = _Executor(); 4 | 5 | // [-2^54; 2^53] is compatible with dart2js, see core.int doc 6 | const _minId = -9007199254740992; 7 | const _maxId = 9007199254740992; 8 | 9 | class _Executor extends Mixinable<_Executor> with _ExecutorLogger { 10 | final _queue = PriorityQueue(); 11 | final _pool = []; 12 | var _nextTaskId = _minId; 13 | var _dynamicSpawning = false; 14 | var _isolatesCount = numberOfProcessors; 15 | 16 | @override 17 | Future init({int? isolatesCount, bool? dynamicSpawning}) async { 18 | if (_pool.isNotEmpty) { 19 | print( 20 | "worker_manager already warmed up, init is ignored. Dispose before init", 21 | ); 22 | return; 23 | } 24 | if (isolatesCount != null) { 25 | if (isolatesCount < 0) { 26 | throw Exception("isolatesCount must be greater than 0"); 27 | } 28 | if (isolatesCount < numberOfProcessors) { 29 | _isolatesCount = isolatesCount; 30 | } 31 | } 32 | _dynamicSpawning = dynamicSpawning ?? false; 33 | await _ensureWorkersInitialized(); 34 | super.init(); 35 | } 36 | 37 | @override 38 | Future dispose() async { 39 | _queue.clear(); 40 | for (final worker in _pool) { 41 | worker.kill(); 42 | } 43 | _pool.clear(); 44 | super.dispose(); 45 | } 46 | 47 | Cancelable execute( 48 | Execute execution, { 49 | WorkPriority priority = WorkPriority.immediately, 50 | }) { 51 | return _createCancelable( 52 | execution: execution, 53 | priority: priority, 54 | ); 55 | } 56 | 57 | Cancelable executeNow(ExecuteGentle execution) { 58 | final task = TaskGentle( 59 | id: "", 60 | workPriority: WorkPriority.immediately, 61 | execution: execution, 62 | completer: Completer(), 63 | ); 64 | 65 | Future run() async { 66 | try { 67 | final result = await execution(() => task.canceled); 68 | task.complete(result, null, null); 69 | } catch (error, st) { 70 | task.complete(null, error, st); 71 | } 72 | } 73 | 74 | run(); 75 | return Cancelable( 76 | completer: task.completer, 77 | onCancel: () => _cancel(task), 78 | ); 79 | } 80 | 81 | Cancelable executeWithPort( 82 | ExecuteWithPort execution, { 83 | WorkPriority priority = WorkPriority.immediately, 84 | required void Function(T value) onMessage, 85 | }) { 86 | return _createCancelable( 87 | execution: execution, 88 | priority: priority, 89 | onMessage: (message) => onMessage(message as T), 90 | ); 91 | } 92 | 93 | Cancelable executeGentle( 94 | ExecuteGentle execution, { 95 | WorkPriority priority = WorkPriority.immediately, 96 | }) { 97 | return _createCancelable( 98 | execution: execution, 99 | priority: priority, 100 | ); 101 | } 102 | 103 | Cancelable executeGentleWithPort( 104 | ExecuteGentleWithPort execution, { 105 | WorkPriority priority = WorkPriority.immediately, 106 | required void Function(T value) onMessage, 107 | }) { 108 | return _createCancelable( 109 | execution: execution, 110 | priority: priority, 111 | onMessage: (message) => onMessage(message as T), 112 | ); 113 | } 114 | 115 | void _createWorkers() { 116 | for (var i = 0; i < _isolatesCount; i++) { 117 | _pool.add(Worker()); 118 | } 119 | } 120 | 121 | Future _initializeWorkers() async { 122 | await Future.wait(_pool.map((e) => e.initialize())); 123 | } 124 | 125 | Cancelable _createCancelable({ 126 | required Function execution, 127 | WorkPriority priority = WorkPriority.immediately, 128 | void Function(Object value)? onMessage, 129 | }) { 130 | if (_nextTaskId + 1 == _maxId) { 131 | _nextTaskId = _minId; 132 | } 133 | final id = _nextTaskId.toString(); 134 | _nextTaskId++; 135 | late final Task task; 136 | final completer = Completer(); 137 | if (execution is Execute) { 138 | task = TaskRegular( 139 | id: id, 140 | workPriority: priority, 141 | execution: execution, 142 | completer: completer, 143 | ); 144 | } else if (execution is ExecuteWithPort) { 145 | task = TaskWithPort( 146 | id: id, 147 | workPriority: priority, 148 | execution: execution, 149 | completer: completer, 150 | onMessage: onMessage!, 151 | ); 152 | } else if (execution is ExecuteGentle) { 153 | task = TaskGentle( 154 | id: id, 155 | workPriority: priority, 156 | execution: execution, 157 | completer: completer, 158 | ); 159 | } else if (execution is ExecuteGentleWithPort) { 160 | task = TaskGentleWithPort( 161 | id: id, 162 | workPriority: priority, 163 | execution: execution, 164 | completer: completer, 165 | onMessage: onMessage!, 166 | ); 167 | } 168 | _queue.add(task); 169 | _schedule(); 170 | logTaskAdded(task.id); 171 | return Cancelable( 172 | completer: task.completer, 173 | onCancel: () => _cancel(task), 174 | ); 175 | } 176 | 177 | Future _ensureWorkersInitialized() async { 178 | if (_pool.isEmpty) { 179 | _createWorkers(); 180 | if (!_dynamicSpawning) { 181 | await _initializeWorkers(); 182 | final poolSize = _pool.length; 183 | final queueSize = _queue.length; 184 | for (int i = 0; i <= min(poolSize, queueSize); i++) { 185 | _schedule(); 186 | } 187 | } 188 | } 189 | if (_pool.every((worker) => worker.taskId != null)) { 190 | return; 191 | } 192 | if (_dynamicSpawning) { 193 | final freeWorker = _pool.firstWhereOrNull( 194 | (worker) => 195 | worker.taskId == null && 196 | !worker.initialized && 197 | !worker.initializing, 198 | ); 199 | await freeWorker?.initialize(); 200 | _schedule(); 201 | } 202 | } 203 | 204 | void _schedule() { 205 | final availableWorker = _pool.firstWhereOrNull( 206 | (worker) => worker.taskId == null && worker.initialized, 207 | ); 208 | if (availableWorker == null) { 209 | _ensureWorkersInitialized(); 210 | return; 211 | } 212 | if (_queue.isEmpty) return; 213 | final task = _queue.removeFirst(); 214 | 215 | availableWorker.work(task).then((value) { 216 | //could be completed already by cancel and it is normal. 217 | //Assuming that worker finished with error and cleaned gracefully 218 | task.complete(value, null, null); 219 | }, onError: (error, st) { 220 | task.complete(null, error, st); 221 | }).whenComplete(() { 222 | if (_dynamicSpawning && _queue.isEmpty) availableWorker.kill(); 223 | _schedule(); 224 | }); 225 | } 226 | 227 | @override 228 | void _cancel(Task task) { 229 | task.cancel(); 230 | _queue.remove(task); 231 | final targetWorker = 232 | _pool.firstWhereOrNull((worker) => worker.taskId == task.id); 233 | if (task is Gentle) { 234 | targetWorker?.cancelGentle(); 235 | } else { 236 | targetWorker?.kill(); 237 | if (!_dynamicSpawning) targetWorker?.initialize(); 238 | } 239 | super._cancel(task); 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /lib/src/scheduling/executor_logger.dart: -------------------------------------------------------------------------------- 1 | part of '../../worker_manager.dart'; 2 | 3 | class Mixinable { 4 | late final itSelf = this as T; 5 | } 6 | 7 | mixin _ExecutorLogger on Mixinable<_Executor> { 8 | var log = false; 9 | 10 | @mustCallSuper 11 | void init() { 12 | logMessage( 13 | "${itSelf._isolatesCount} workers have been spawned and initialized", 14 | ); 15 | } 16 | 17 | void logTaskAdded(String uid) { 18 | logMessage("added task with number $uid"); 19 | } 20 | 21 | @mustCallSuper 22 | void dispose() { 23 | logMessage("worker_manager have been disposed"); 24 | } 25 | 26 | @mustCallSuper 27 | void _cancel(Task task) { 28 | logMessage("Task ${task.id} have been canceled"); 29 | } 30 | 31 | void logMessage(String message) { 32 | if (log) print(message); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/src/scheduling/task.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | typedef Execute = FutureOr Function(); 5 | typedef ExecuteWithPort = FutureOr Function(SendPort port); 6 | typedef ExecuteGentle = FutureOr Function(bool Function()); 7 | typedef ExecuteGentleWithPort = FutureOr Function( 8 | SendPort port, 9 | bool Function(), 10 | ); 11 | 12 | abstract class Task implements Comparable> { 13 | final String id; 14 | final Completer completer; 15 | final WorkPriority workPriority; 16 | 17 | var _canceled = false; 18 | 19 | Task({ 20 | required this.id, 21 | required this.completer, 22 | this.workPriority = WorkPriority.high, 23 | }); 24 | 25 | @override 26 | int compareTo(covariant Task other) { 27 | final index = WorkPriority.values.indexOf; 28 | return index(workPriority) - index(other.workPriority); 29 | } 30 | 31 | @override 32 | bool operator ==(covariant Task other) { 33 | return other.id == id; 34 | } 35 | 36 | @override 37 | int get hashCode => id.hashCode; 38 | //todo: could be Execute ? 39 | Function get execution; 40 | 41 | bool get canceled => _canceled; 42 | 43 | void cancel() { 44 | if (!completer.isCompleted) { 45 | _canceled = true; 46 | completer.completeError(CanceledError()); 47 | } 48 | } 49 | 50 | void complete(R? value, Object? error, StackTrace? st) { 51 | if (completer.isCompleted) return; 52 | if (error != null) { 53 | completer.completeError(error, st); 54 | return; 55 | } 56 | completer.complete(value); 57 | } 58 | } 59 | 60 | class TaskRegular extends Task { 61 | @override 62 | final Execute execution; 63 | 64 | TaskRegular({ 65 | required super.id, 66 | required super.completer, 67 | required super.workPriority, 68 | required this.execution, 69 | }); 70 | } 71 | 72 | abstract class WithPort { 73 | Function(Object value) get onMessage; 74 | } 75 | 76 | class TaskWithPort extends Task implements WithPort { 77 | @override 78 | final ExecuteWithPort execution; 79 | @override 80 | final void Function(Object value) onMessage; 81 | 82 | TaskWithPort({ 83 | required super.id, 84 | required super.completer, 85 | required super.workPriority, 86 | required this.execution, 87 | required this.onMessage, 88 | }); 89 | } 90 | 91 | abstract class Gentle {} 92 | 93 | class TaskGentle extends Task implements Gentle { 94 | @override 95 | final ExecuteGentle execution; 96 | 97 | TaskGentle({ 98 | required super.id, 99 | required super.completer, 100 | required super.workPriority, 101 | required this.execution, 102 | }); 103 | } 104 | 105 | class TaskGentleWithPort extends Task implements WithPort, Gentle { 106 | @override 107 | final ExecuteGentleWithPort execution; 108 | @override 109 | final void Function(Object value) onMessage; 110 | 111 | TaskGentleWithPort({ 112 | required super.id, 113 | required super.completer, 114 | required super.workPriority, 115 | required this.execution, 116 | required this.onMessage, 117 | }); 118 | } 119 | -------------------------------------------------------------------------------- /lib/src/scheduling/work_priority.dart: -------------------------------------------------------------------------------- 1 | enum WorkPriority { 2 | immediately, 3 | veryHigh, 4 | high, 5 | highRegular, 6 | regular, 7 | almostLow, 8 | low, 9 | } 10 | -------------------------------------------------------------------------------- /lib/src/worker/cancel_request.dart: -------------------------------------------------------------------------------- 1 | class CancelRequest {} 2 | -------------------------------------------------------------------------------- /lib/src/worker/result.dart: -------------------------------------------------------------------------------- 1 | class Result {} 2 | 3 | class ResultSuccess extends Result { 4 | final R value; 5 | 6 | ResultSuccess(this.value); 7 | } 8 | 9 | class ResultError extends Result { 10 | final Object error; 11 | final StackTrace stackTrace; 12 | 13 | ResultError(this.error, this.stackTrace); 14 | } 15 | -------------------------------------------------------------------------------- /lib/src/worker/worker.dart: -------------------------------------------------------------------------------- 1 | import 'package:worker_manager/src/scheduling/task.dart'; 2 | import 'package:worker_manager/src/worker/worker_web.dart' 3 | if (dart.library.io) 'package:worker_manager/src/worker/worker_io.dart'; 4 | 5 | abstract class Worker { 6 | String? get taskId; 7 | bool get initialized; 8 | bool get initializing; 9 | Future initialize(); 10 | void kill(); 11 | 12 | Future work(Task task); 13 | 14 | void cancelGentle(); 15 | 16 | factory Worker() => WorkerImpl(); 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/worker/worker_io.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:isolate'; 3 | import 'package:worker_manager/src/cancelable/cancelable.dart'; 4 | import 'package:worker_manager/src/scheduling/task.dart'; 5 | import 'package:worker_manager/src/worker/cancel_request.dart'; 6 | import 'package:worker_manager/src/worker/result.dart'; 7 | import 'package:worker_manager/src/worker/worker.dart'; 8 | 9 | class WorkerImpl implements Worker { 10 | WorkerImpl(); 11 | 12 | late Isolate _isolate; 13 | late RawReceivePort _receivePort; 14 | late SendPort _sendPort; 15 | Completer? _sendPortReceived; 16 | 17 | Completer? _result; 18 | void Function(Object value)? onMessage; 19 | 20 | @override 21 | bool get initialized => _sendPortReceived?.isCompleted ?? false; 22 | 23 | @override 24 | String? taskId; 25 | 26 | @override 27 | bool get initializing { 28 | final sendPortReceived = _sendPortReceived; 29 | if (sendPortReceived != null) { 30 | return !sendPortReceived.isCompleted; 31 | } 32 | return false; 33 | } 34 | 35 | @override 36 | Future initialize() async { 37 | _sendPortReceived = Completer(); 38 | _receivePort = RawReceivePort(); 39 | _receivePort.handler = (Object result) { 40 | if (result is SendPort) { 41 | _sendPort = result; 42 | _sendPortReceived!.complete(); 43 | } else if (result is ResultSuccess) { 44 | _result!.complete(result.value); 45 | _cleanUp(); 46 | } else if (result is ResultError) { 47 | _result!.completeError(result.error, result.stackTrace); 48 | _cleanUp(); 49 | } else { 50 | onMessage?.call(result); 51 | } 52 | }; 53 | _isolate = await Isolate.spawn( 54 | _anotherIsolate, 55 | _receivePort.sendPort, 56 | errorsAreFatal: false, 57 | paused: false, 58 | ); 59 | await _sendPortReceived!.future; 60 | } 61 | 62 | @override 63 | Future work(Task task) async { 64 | taskId = task.id; 65 | _result = Completer(); 66 | _sendPort.send(task.execution); 67 | if (task is WithPort) { 68 | onMessage = (task as WithPort).onMessage; 69 | } 70 | final resultValue = await (_result!.future as Future); 71 | return resultValue; 72 | } 73 | 74 | @override 75 | void cancelGentle() { 76 | _sendPort.send(CancelRequest()); 77 | } 78 | 79 | @override 80 | void kill() { 81 | _cleanUp(); 82 | _sendPortReceived = null; 83 | _receivePort.close(); 84 | _isolate.kill(priority: Isolate.immediate); 85 | } 86 | 87 | void _cleanUp() { 88 | onMessage = null; 89 | taskId = null; 90 | _result = null; 91 | } 92 | 93 | static void _anotherIsolate(SendPort sendPort) { 94 | final receivePort = RawReceivePort(); 95 | sendPort.send(receivePort.sendPort); 96 | var canceled = false; 97 | receivePort.handler = (message) async { 98 | try { 99 | late final dynamic result; 100 | canceled = false; 101 | if (message is Execute) { 102 | result = await message(); 103 | } else if (message is ExecuteWithPort) { 104 | result = await message(sendPort); 105 | } else if (message is ExecuteGentle) { 106 | result = await message(() => canceled); 107 | } else if (message is ExecuteGentleWithPort) { 108 | result = await message(sendPort, () => canceled); 109 | } else if (message is CancelRequest) { 110 | canceled = true; 111 | throw CanceledError(); 112 | } 113 | if (!canceled) { 114 | sendPort.send(ResultSuccess(result)); 115 | } 116 | } catch (error, stackTrace) { 117 | sendPort.send(ResultError(error, stackTrace)); 118 | } 119 | }; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /lib/src/worker/worker_web.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:worker_manager/src/scheduling/task.dart'; 3 | import 'package:worker_manager/src/worker/worker.dart'; 4 | 5 | class WorkerImpl implements Worker { 6 | WorkerImpl(); 7 | 8 | @override 9 | var initialized = false; 10 | 11 | @override 12 | String? taskId; 13 | 14 | void Function(Object value)? onMessage; 15 | 16 | @override 17 | Future initialize() async { 18 | initialized = true; 19 | } 20 | 21 | @override 22 | Future work(Task task) async { 23 | Future run() async { 24 | return await task.execution(); 25 | } 26 | 27 | taskId = task.id; 28 | if (task is TaskWithPort) { 29 | onMessage = (task as TaskWithPort).onMessage; 30 | } 31 | final resultValue = await run().whenComplete(() { 32 | _cleanUp(); 33 | }); 34 | return resultValue; 35 | } 36 | 37 | @override 38 | void cancelGentle() { 39 | _cleanUp(); 40 | } 41 | 42 | @override 43 | void kill() { 44 | _cleanUp(); 45 | initialized = false; 46 | } 47 | 48 | void _cleanUp() { 49 | onMessage = null; 50 | taskId = null; 51 | } 52 | 53 | @override 54 | bool get initializing => false; 55 | } 56 | -------------------------------------------------------------------------------- /lib/worker_manager.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'src/scheduling/task.dart'; 4 | export 'src/scheduling/work_priority.dart'; 5 | export 'src/port/send_port.dart'; 6 | export 'src/cancelable/cancelable.dart'; 7 | 8 | import 'dart:async'; 9 | import 'dart:math'; 10 | import 'package:collection/collection.dart'; 11 | import 'package:meta/meta.dart'; 12 | import 'package:worker_manager/src/cancelable/cancelable.dart'; 13 | import 'package:worker_manager/src/number_of_processors/processors_io.dart' 14 | if (dart.library.js_interop) 'package:worker_manager/src/number_of_processors/processors_web.dart' 15 | if (dart.library.html) 'package:worker_manager/src/number_of_processors/processors_web.dart'; 16 | import 'package:worker_manager/src/scheduling/task.dart'; 17 | import 'package:worker_manager/src/scheduling/work_priority.dart'; 18 | import 'package:worker_manager/src/worker/worker.dart'; 19 | 20 | part 'src/scheduling/executor.dart'; 21 | 22 | part 'src/scheduling/executor_logger.dart'; 23 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "61.0.0" 12 | analyzer: 13 | dependency: transitive 14 | description: 15 | name: analyzer 16 | sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "5.13.0" 20 | args: 21 | dependency: transitive 22 | description: 23 | name: args 24 | sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.4.2" 28 | async: 29 | dependency: "direct main" 30 | description: 31 | name: async 32 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "2.11.0" 36 | boolean_selector: 37 | dependency: transitive 38 | description: 39 | name: boolean_selector 40 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "2.1.1" 44 | collection: 45 | dependency: "direct main" 46 | description: 47 | name: collection 48 | sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.17.2" 52 | convert: 53 | dependency: transitive 54 | description: 55 | name: convert 56 | sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "3.1.1" 60 | coverage: 61 | dependency: transitive 62 | description: 63 | name: coverage 64 | sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "1.6.3" 68 | crypto: 69 | dependency: transitive 70 | description: 71 | name: crypto 72 | sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "3.0.3" 76 | file: 77 | dependency: transitive 78 | description: 79 | name: file 80 | sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "7.0.0" 84 | frontend_server_client: 85 | dependency: transitive 86 | description: 87 | name: frontend_server_client 88 | sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "3.2.0" 92 | glob: 93 | dependency: transitive 94 | description: 95 | name: glob 96 | sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "2.1.2" 100 | http_multi_server: 101 | dependency: transitive 102 | description: 103 | name: http_multi_server 104 | sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "3.2.1" 108 | http_parser: 109 | dependency: transitive 110 | description: 111 | name: http_parser 112 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "4.0.2" 116 | io: 117 | dependency: transitive 118 | description: 119 | name: io 120 | sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "1.0.4" 124 | js: 125 | dependency: transitive 126 | description: 127 | name: js 128 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "0.6.7" 132 | logging: 133 | dependency: transitive 134 | description: 135 | name: logging 136 | sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "1.2.0" 140 | matcher: 141 | dependency: transitive 142 | description: 143 | name: matcher 144 | sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "0.12.16" 148 | meta: 149 | dependency: "direct main" 150 | description: 151 | name: meta 152 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "1.9.1" 156 | mime: 157 | dependency: transitive 158 | description: 159 | name: mime 160 | sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "1.0.4" 164 | node_preamble: 165 | dependency: transitive 166 | description: 167 | name: node_preamble 168 | sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "2.0.2" 172 | package_config: 173 | dependency: transitive 174 | description: 175 | name: package_config 176 | sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "2.1.0" 180 | path: 181 | dependency: transitive 182 | description: 183 | name: path 184 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" 185 | url: "https://pub.dev" 186 | source: hosted 187 | version: "1.8.3" 188 | pool: 189 | dependency: transitive 190 | description: 191 | name: pool 192 | sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" 193 | url: "https://pub.dev" 194 | source: hosted 195 | version: "1.5.1" 196 | pub_semver: 197 | dependency: transitive 198 | description: 199 | name: pub_semver 200 | sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" 201 | url: "https://pub.dev" 202 | source: hosted 203 | version: "2.1.4" 204 | shelf: 205 | dependency: transitive 206 | description: 207 | name: shelf 208 | sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 209 | url: "https://pub.dev" 210 | source: hosted 211 | version: "1.4.1" 212 | shelf_packages_handler: 213 | dependency: transitive 214 | description: 215 | name: shelf_packages_handler 216 | sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" 217 | url: "https://pub.dev" 218 | source: hosted 219 | version: "3.0.2" 220 | shelf_static: 221 | dependency: transitive 222 | description: 223 | name: shelf_static 224 | sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e 225 | url: "https://pub.dev" 226 | source: hosted 227 | version: "1.1.2" 228 | shelf_web_socket: 229 | dependency: transitive 230 | description: 231 | name: shelf_web_socket 232 | sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" 233 | url: "https://pub.dev" 234 | source: hosted 235 | version: "1.0.4" 236 | source_map_stack_trace: 237 | dependency: transitive 238 | description: 239 | name: source_map_stack_trace 240 | sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" 241 | url: "https://pub.dev" 242 | source: hosted 243 | version: "2.1.1" 244 | source_maps: 245 | dependency: transitive 246 | description: 247 | name: source_maps 248 | sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" 249 | url: "https://pub.dev" 250 | source: hosted 251 | version: "0.10.12" 252 | source_span: 253 | dependency: transitive 254 | description: 255 | name: source_span 256 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 257 | url: "https://pub.dev" 258 | source: hosted 259 | version: "1.10.0" 260 | stack_trace: 261 | dependency: transitive 262 | description: 263 | name: stack_trace 264 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 265 | url: "https://pub.dev" 266 | source: hosted 267 | version: "1.11.0" 268 | stream_channel: 269 | dependency: transitive 270 | description: 271 | name: stream_channel 272 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 273 | url: "https://pub.dev" 274 | source: hosted 275 | version: "2.1.1" 276 | string_scanner: 277 | dependency: transitive 278 | description: 279 | name: string_scanner 280 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 281 | url: "https://pub.dev" 282 | source: hosted 283 | version: "1.2.0" 284 | term_glyph: 285 | dependency: transitive 286 | description: 287 | name: term_glyph 288 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 289 | url: "https://pub.dev" 290 | source: hosted 291 | version: "1.2.1" 292 | test: 293 | dependency: "direct dev" 294 | description: 295 | name: test 296 | sha256: "13b41f318e2a5751c3169137103b60c584297353d4b1761b66029bae6411fe46" 297 | url: "https://pub.dev" 298 | source: hosted 299 | version: "1.24.3" 300 | test_api: 301 | dependency: transitive 302 | description: 303 | name: test_api 304 | sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" 305 | url: "https://pub.dev" 306 | source: hosted 307 | version: "0.6.0" 308 | test_core: 309 | dependency: transitive 310 | description: 311 | name: test_core 312 | sha256: "99806e9e6d95c7b059b7a0fc08f07fc53fabe54a829497f0d9676299f1e8637e" 313 | url: "https://pub.dev" 314 | source: hosted 315 | version: "0.5.3" 316 | typed_data: 317 | dependency: transitive 318 | description: 319 | name: typed_data 320 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 321 | url: "https://pub.dev" 322 | source: hosted 323 | version: "1.3.2" 324 | vm_service: 325 | dependency: transitive 326 | description: 327 | name: vm_service 328 | sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f 329 | url: "https://pub.dev" 330 | source: hosted 331 | version: "11.7.1" 332 | watcher: 333 | dependency: transitive 334 | description: 335 | name: watcher 336 | sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" 337 | url: "https://pub.dev" 338 | source: hosted 339 | version: "1.1.0" 340 | web: 341 | dependency: "direct main" 342 | description: 343 | name: web 344 | sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" 345 | url: "https://pub.dev" 346 | source: hosted 347 | version: "1.1.1" 348 | web_socket_channel: 349 | dependency: transitive 350 | description: 351 | name: web_socket_channel 352 | sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b 353 | url: "https://pub.dev" 354 | source: hosted 355 | version: "2.4.0" 356 | webkit_inspection_protocol: 357 | dependency: transitive 358 | description: 359 | name: webkit_inspection_protocol 360 | sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d" 361 | url: "https://pub.dev" 362 | source: hosted 363 | version: "1.2.0" 364 | yaml: 365 | dependency: transitive 366 | description: 367 | name: yaml 368 | sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" 369 | url: "https://pub.dev" 370 | source: hosted 371 | version: "3.1.2" 372 | sdks: 373 | dart: ">=3.4.0 <4.0.0" 374 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: worker_manager 2 | version: 7.2.6 3 | description: The worker_manager allows you to manage CPU-intensive calculations across isolates 4 | homepage: "https://github.com/dsrenesanse/worker_manager" 5 | repository: "https://github.com/dsrenesanse/worker_manager" 6 | 7 | environment: 8 | sdk: '>=2.19.0 <4.0.0' 9 | 10 | dependencies: 11 | async: ^2.11.0 12 | collection: ^1.17.1 13 | meta: ^1.9.1 14 | web: ^1.1.1 15 | 16 | dev_dependencies: 17 | test: ^1.24.3 18 | 19 | -------------------------------------------------------------------------------- /test/cancel_gentle_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | void main() { 5 | test("cancel task gentle", () async { 6 | var canceledCaught = false; 7 | final task = 8 | workerManager.executeGentle((isCanceled) => forTest(isCanceled)); 9 | await Future.delayed(Duration(milliseconds: 50)); 10 | task.cancel(); 11 | await task.catchError((_) { 12 | canceledCaught = true; 13 | return null; 14 | }); 15 | expect(canceledCaught, true); 16 | }); 17 | } 18 | 19 | Future forTest(bool Function() isCancelled) async { 20 | await Future.delayed(Duration(milliseconds: 100)); 21 | if (isCancelled()) { 22 | return null; 23 | } 24 | return false; 25 | } 26 | -------------------------------------------------------------------------------- /test/cancel_gentle_test2.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | void main() { 5 | test("https://github.com/machinescream/worker_manager/issues/105", () async { 6 | final task = workerManager.executeGentle((isCanceled) { 7 | print("work started"); 8 | Future.delayed(Duration(seconds: 1)); 9 | if (!isCanceled()) { 10 | print("Finished grasefully"); 11 | } else { 12 | throw Exception("somethign went wrong"); 13 | } 14 | }); 15 | //allowing task to be scheduled from queue, but not removed from queue 16 | await Future.delayed(Duration(milliseconds: 500)); 17 | task.cancel(); 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /test/canceling_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | void main() { 5 | test("cancel task with regular catch", () async { 6 | final task = workerManager.execute(() => 0); 7 | 8 | final task3 = workerManager 9 | .execute(() => 0) 10 | .thenNext((value) => value, (error) => -1) 11 | .thenNext((value) => value); 12 | 13 | task.cancel(); 14 | task3.cancel(); 15 | 16 | final result = await task.catchError((_) => -1); 17 | final result3 = await task3; 18 | 19 | expect(result, -1); 20 | expect(result3, -1); 21 | }); 22 | 23 | test("2", () async { 24 | final task2 = workerManager.execute(() => 0).thenNext((value) { 25 | return value; 26 | }, (error) { 27 | return -1; 28 | }); 29 | task2.cancel(); 30 | final result2 = await task2; 31 | expect(result2, -1); 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /test/chaining_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | void main() { 5 | test("chaining", () async { 6 | final result = await workerManager 7 | .execute(() => 0) 8 | .thenNext((value) => value + 1) 9 | .thenNext((value) => value + 1) 10 | .thenNext((value) => value + 1); 11 | expect(result, 3); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /test/error_handling_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | void main() { 5 | test("error handling from 0 to 1 level", () async { 6 | final result = await workerManager 7 | .execute(() => throw Error()) 8 | .thenNext((value) => 0, (error) => error); 9 | expect(result is Error, true); 10 | }); 11 | 12 | test("error handling from 0 to 2 level", () async { 13 | final result = await workerManager 14 | .execute(() => throw Error()) 15 | .thenNext((value) => value) 16 | .thenNext((value) => value, (error) => error); 17 | expect(result is Error, true); 18 | }); 19 | 20 | test("error handling from 1 to 1 level immediately", () async { 21 | final result = await workerManager 22 | .execute(() => 0) 23 | .thenNext((value) => throw Error(), (error) => error); 24 | expect(result is Error, true); 25 | }); 26 | 27 | test("error handling from 1 to 2 level", () async { 28 | final result = await workerManager 29 | .execute(() => 0) 30 | .thenNext((value) => throw Error()) 31 | .thenNext((value) => value, (error) => error); 32 | expect(result is Error, true); 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /test/performance_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:test/test.dart'; 3 | import 'package:worker_manager/worker_manager.dart'; 4 | 5 | Future main() async { 6 | test("_fibonacci calculation", () async { 7 | final time1 = DateTime.now(); 8 | final _ = [_fib(40), _fib(40), _fib(40), _fib(40)]; 9 | final timeSpend1 = DateTime.now().difference(time1).inMilliseconds; 10 | final time2 = DateTime.now(); 11 | final results = [ 12 | workerManager.execute(() => _fib(40)), 13 | workerManager.execute(() => _fib(40)), 14 | workerManager.execute(() => _fib(40)), 15 | workerManager.execute(() => _fib(40)), 16 | ]; 17 | await Future.wait(results); 18 | final timeSpend2 = DateTime.now().difference(time2).inMilliseconds; 19 | expect(timeSpend1 > timeSpend2, true); 20 | }); 21 | 22 | test("matrix multiplication", () async { 23 | final time1 = DateTime.now(); 24 | _multiplyMatrix(); 25 | _multiplyMatrix(); 26 | _multiplyMatrix(); 27 | final timeSpend1 = DateTime.now().difference(time1).inMilliseconds; 28 | 29 | final time2 = DateTime.now(); 30 | final results = [ 31 | workerManager.execute(() => _multiplyMatrix()), 32 | workerManager.execute(() => _multiplyMatrix()), 33 | workerManager.execute(() => _multiplyMatrix()), 34 | ]; 35 | await Future.wait(results); 36 | final timeSpend2 = DateTime.now().difference(time2).inMilliseconds; 37 | expect(timeSpend1 > timeSpend2, true); 38 | }); 39 | } 40 | 41 | int _fib(int n) { 42 | if (n < 2) { 43 | return n; 44 | } 45 | return _fib(n - 2) + _fib(n - 1); 46 | } 47 | 48 | void _multiplyMatrix() { 49 | int size = 1000; 50 | final random = Random(); 51 | 52 | List> matrix1 = List.generate( 53 | size, 54 | (_) => List.generate(size, (_) => random.nextDouble()), 55 | ); 56 | List> matrix2 = List.generate( 57 | size, 58 | (_) => List.generate(size, (_) => random.nextDouble()), 59 | ); 60 | 61 | final result = List.generate(size, (_) => List.filled(size, 0.0)); 62 | for (int i = 0; i < size; i++) { 63 | for (int j = 0; j < size; j++) { 64 | double sum = 0.0; 65 | for (int k = 0; k < size; k++) { 66 | sum += matrix1[i][k] * matrix2[k][j]; 67 | } 68 | result[i][j] = sum; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /test/port_communication_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | void main() { 5 | test("port communication", () async { 6 | late int message; 7 | await workerManager.executeWithPort( 8 | (port) => port.send(1), 9 | onMessage: (m) { 10 | message = m; 11 | }, 12 | ); 13 | expect(message, 1); 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /test/pressure_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | Future main() async { 5 | test("_fibonacci calculation 100 times", () async { 6 | final time1 = DateTime.now(); 7 | await Future.wait(List.generate(100, (_) { 8 | return workerManager.execute(() => _fib(40)); 9 | })); 10 | final timeSpend1 = DateTime.now().difference(time1).inMilliseconds; 11 | print(timeSpend1); 12 | expect(true, true); 13 | }); 14 | } 15 | 16 | int _fib(int n) { 17 | if (n < 2) { 18 | return n; 19 | } 20 | return _fib(n - 2) + _fib(n - 1); 21 | } 22 | -------------------------------------------------------------------------------- /test/work_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:worker_manager/worker_manager.dart'; 3 | 4 | void main() { 5 | test("get value", () async { 6 | final result = await workerManager.execute(() => 0); 7 | expect(result, 0); 8 | }); 9 | 10 | test("get value twice sync", () async { 11 | final results = [ 12 | await workerManager.execute(() => true), 13 | await workerManager.execute(() => true) 14 | ]; 15 | expect(results.first, results.last); 16 | }); 17 | 18 | test("get value twice in parallel", () async { 19 | final results = [ 20 | workerManager.execute(() => true), 21 | workerManager.execute(() => true) 22 | ]; 23 | final result1 = await results.first; 24 | final result2 = await results.last; 25 | 26 | expect(result1, result2); 27 | }); 28 | } 29 | --------------------------------------------------------------------------------