From 85f2e492becc09b38b289b722070072aefd33ba7 Mon Sep 17 00:00:00 2001 From: escamoteur Date: Wed, 4 Apr 2018 16:30:38 +0200 Subject: [PATCH] initial import --- .gitignore | 7 + .vscode/launch.json | 13 + CHANGELOG.md | 3 + LICENSE | 1 + README.md | 9 + ios/Flutter/Generated.xcconfig | 8 + ios/Runner/GeneratedPluginRegistrant.h | 14 + ios/Runner/GeneratedPluginRegistrant.m | 12 + lib/rx_command.dart | 220 ++++++++++++++ pubspec.lock | 398 +++++++++++++++++++++++++ pubspec.yaml | 52 ++++ rx_command.iml | 18 ++ sample/flutter_weather_demo | 1 + test/rx_command_test.dart | 93 ++++++ 14 files changed, 849 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 ios/Flutter/Generated.xcconfig create mode 100644 ios/Runner/GeneratedPluginRegistrant.h create mode 100644 ios/Runner/GeneratedPluginRegistrant.m create mode 100644 lib/rx_command.dart create mode 100644 pubspec.lock create mode 100644 pubspec.yaml create mode 100644 rx_command.iml create mode 160000 sample/flutter_weather_demo create mode 100644 test/rx_command_test.dart diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d7926f --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.atom/ +.dart_tool/ +.idea +.packages +.pub/ +packages diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..40d684b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,13 @@ +{ + // Verwendet IntelliSense zum Ermitteln möglicher Attribute. + // Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen. + // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Flutter", + "request": "launch", + "type": "dart" + } + ] +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1909ca1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## [0.0.1] - TODO: Add release date. + +* TODO: Describe initial release. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..97cfb48 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/README.md b/README.md new file mode 100644 index 0000000..873f66b --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# rx_command + +A new flutter package project. + +## Getting Started + +For help getting started with Flutter, view our online [documentation](https://flutter.io/). + +For help on editing package code, view the [documentation](https://flutter.io/developing-packages/). diff --git a/ios/Flutter/Generated.xcconfig b/ios/Flutter/Generated.xcconfig new file mode 100644 index 0000000..ee1b87d --- /dev/null +++ b/ios/Flutter/Generated.xcconfig @@ -0,0 +1,8 @@ +// This is a generated file; do not edit or check into version control. +FLUTTER_ROOT=C:\Entwicklung\Flutter +FLUTTER_APPLICATION_PATH=c:\Entwicklung\FlutterApps\packages\rx_command +FLUTTER_TARGET=lib/main.dart +FLUTTER_BUILD_MODE=debug +FLUTTER_BUILD_DIR=build +SYMROOT=${SOURCE_ROOT}/../build\ios +FLUTTER_FRAMEWORK_DIR=C:\Entwicklung\Flutter\bin\cache\artifacts\engine\ios diff --git a/ios/Runner/GeneratedPluginRegistrant.h b/ios/Runner/GeneratedPluginRegistrant.h new file mode 100644 index 0000000..3b700eb --- /dev/null +++ b/ios/Runner/GeneratedPluginRegistrant.h @@ -0,0 +1,14 @@ +// +// Generated file. Do not edit. +// + +#ifndef GeneratedPluginRegistrant_h +#define GeneratedPluginRegistrant_h + +#import + +@interface GeneratedPluginRegistrant : NSObject ++ (void)registerWithRegistry:(NSObject*)registry; +@end + +#endif /* GeneratedPluginRegistrant_h */ diff --git a/ios/Runner/GeneratedPluginRegistrant.m b/ios/Runner/GeneratedPluginRegistrant.m new file mode 100644 index 0000000..60dfa42 --- /dev/null +++ b/ios/Runner/GeneratedPluginRegistrant.m @@ -0,0 +1,12 @@ +// +// Generated file. Do not edit. +// + +#import "GeneratedPluginRegistrant.h" + +@implementation GeneratedPluginRegistrant + ++ (void)registerWithRegistry:(NSObject*)registry { +} + +@end diff --git a/lib/rx_command.dart b/lib/rx_command.dart new file mode 100644 index 0000000..6d5079d --- /dev/null +++ b/lib/rx_command.dart @@ -0,0 +1,220 @@ +library rx_command; + +import 'dart:async'; + +import 'package:rxdart/rxdart.dart'; + +/* +typedef TResult Func(TParam param); + + + +abstract class RxCommandFactory +{ + + static RxCommand createSync(Func func) + { + return new RxCommandSync(func); + } + + +} +*/ + +typedef void Action(); +typedef void Action1(TParam param); + + +typedef TResult Func(); +typedef TResult Func1(TParam param); + +typedef Future AsyncAction(); +typedef Future AsyncAction1(TParam param); + + +typedef Future AsyncFunc(); +typedef Future AsyncFunc1(TParam param); + + +abstract class RxCommandFactory +{ + + static RxCommand createSync(Action action) + { + return new RxCommandSync((_) {action(); return Unit.Default;}); + } + + static RxCommand createSync1(Action1 action) + { + return new RxCommandSync((x) {action(x); return Unit.Default;}); + } + + static RxCommand createSync2(Func func) + { + return new RxCommandSync((_) => func()); + } + + static RxCommand createSync4(Func1 func) + { + return new RxCommandSync((x) => func(x)); + } + +} + + + +abstract class RxCommand +{ + + void execute([TParam param]); + + Observable get results => _resultsSubject.observable; + BehaviorSubject _resultsSubject = new BehaviorSubject(); + + + Observable get isExecuting => _isExecutingSubject.observable.startWith(false).distinct(); + Observable canExecute; + Observable get thrownExceptions => _thrownExceptionsSubject.observable; + + ReplaySubject _isExecutingSubject = new ReplaySubject(maxSize: 1); + ReplaySubject _canExcuteubject = new ReplaySubject(maxSize: 1); + ReplaySubject _thrownExceptionsSubject = new ReplaySubject(maxSize: 1); + +} + + +class RxCommandSync extends RxCommand +{ + + + Func1 _func; + + RxCommandSync(Func1 func, [Observable canExecute] ) + { + + _func = func; + + var canExecuteParam = canExecute == null ? new Observable.just(true) + : canExecute.handleError((error) + { + if (error is Exception) + { + _thrownExceptionsSubject.add(error); + } + return false; + }) + .startWith(false); + + + this.canExecute = new Observable(Observable + .combineLatest2(isExecuting, canExecuteParam, (isEx, canEx) => canEx && !isEx) + .distinct().asBroadcastStream()); + + } + + @override + void execute([TParam param]) + { + canExecute + .where( (can) => can == true) + .doOnEach((_){ + + _isExecutingSubject.add(true); + var result = _func(param); + _isExecutingSubject.add(false); + + if (TResult is Unit ) + { + _resultsSubject.add(Unit.Default as TResult); + } + _resultsSubject.add(result); + + }) + .handleError((error) + { + if (error is Exception) + { + _thrownExceptionsSubject.add(error); + } + print(error.toString()); + + }) + .first; + + } +} + +/* +class RxCommandAsync extends RxCommand +{ + + + AsyncFunc1 _func; + + RxCommandSync(AsyncFunc1 func, [Observable canExecute] ) + { + + _func = func; + + var canExecuteParam = canExecute == null ? new Observable.just(true) + : canExecute.handleError((error) + { + if (error is Exception) + { + _thrownExceptionsSubject.add(error); + } + return false; + }) + .startWith(false); + + + this.canExecute = new Observable(Observable + .combineLatest2(isExecuting, canExecuteParam, (isEx, canEx) => canEx && !isEx) + .distinct().asBroadcastStream()); + + } + + @override + void execute([TParam param]) + { + canExecute + .where( (can) => can == true) + .doOnEach((_){ + + _isExecutingSubject.add(true); + var result = _func(param); + _isExecutingSubject.add(false); + + if (TResult is Unit ) + { + _resultsSubject.add(Unit.Default as TResult); + } + _resultsSubject.add(result); + + }) + .handleError((error) + { + if (error is Exception) + { + _thrownExceptionsSubject.add(error); + } + print(error.toString()); + + }) + .first; + + } +} + +*/ + +/// If you don't want to pass one of the generic parameters e.g. if you passed function has no parameter, just use Unit as Type +class Unit +{ + static Unit get Default => new Unit(); + + bool operator == (o) => o is Unit; + +} + + diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..7c215e2 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,398 @@ +# Generated by pub +# See https://www.dartlang.org/tools/pub/glossary#lockfile +packages: + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "0.31.1" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.1" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + barback: + dependency: transitive + description: + name: barback + url: "https://pub.dartlang.org" + source: hosted + version: "0.15.2+14" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2+1" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.6" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2+1" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + front_end: + dependency: transitive + description: + name: front_end + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0-alpha.9" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.5" + html: + dependency: transitive + description: + name: html + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.3" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.3+16" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.2+1" + isolate: + dependency: transitive + description: + name: isolate + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.1" + kernel: + dependency: transitive + description: + name: kernel + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0-alpha.9" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.3+1" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.1+4" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.6" + mockito: + dependency: transitive + description: + name: mockito + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" + multi_server_socket: + dependency: transitive + description: + name: multi_server_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + node_preamble: + dependency: transitive + description: + name: node_preamble + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + package_resolver: + dependency: transitive + description: + name: package_resolver + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.1" + plugin: + dependency: transitive + description: + name: plugin + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+2" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.4" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "0.28.0" + rxdart: + dependency: "direct main" + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.6" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.7" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.4" + source_maps: + dependency: transitive + description: + name: source_maps + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.4" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.2" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + test: + dependency: transitive + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.32+1" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.5" + utf: + dependency: transitive + description: + name: utf + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.0+4" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7+7" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.7" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.13" +sdks: + dart: ">=2.0.0-dev.23.0 <=2.0.0-edge.3c4dccbd46f152be9e1b6ca95c57357e8e48057c" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..a13ec65 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,52 @@ +name: rx_command +description: A new flutter package project. +version: 0.0.1 +author: +homepage: + +dependencies: + flutter: + sdk: flutter + + rxdart : any + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.io/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.io/custom-fonts/#from-packages \ No newline at end of file diff --git a/rx_command.iml b/rx_command.iml new file mode 100644 index 0000000..22a129e --- /dev/null +++ b/rx_command.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sample/flutter_weather_demo b/sample/flutter_weather_demo new file mode 160000 index 0000000..e3d02d0 --- /dev/null +++ b/sample/flutter_weather_demo @@ -0,0 +1 @@ +Subproject commit e3d02d0c78140986b5b74915e586962cbd297522 diff --git a/test/rx_command_test.dart b/test/rx_command_test.dart new file mode 100644 index 0000000..263e9a2 --- /dev/null +++ b/test/rx_command_test.dart @@ -0,0 +1,93 @@ +import 'package:test/test.dart'; + +import 'package:rx_command/rx_command.dart'; + +void main() { + + + test('Execute simple sync action', () { + final command = RxCommandFactory.createSync( () => print("action")); + + + expect(command.canExecute, emits(true)); + expect(command.isExecuting, emits(false)); + + + expect(command.results, emits(Unit.Default)); + + command.execute(null); + + expect(command.canExecute, emits(true)); + expect(command.isExecuting, emits(false)); + }); + + + + test('Execute simple sync action with parameter', () { + + final command = RxCommandFactory.createSync1((x) { + print("action: " + x.toString() ); + return Unit.Default; + }); + + expect(command.canExecute, emits(true)); + expect(command.isExecuting, emits(false)); + + expect(command.results, emits(Unit.Default)); + + command.execute( "Parameter"); + + + expect(command.canExecute, emits(true)); + expect(command.isExecuting, emits(false)); + }); + + + + + test('Execute simple sync function without parameter', () { + + final command = RxCommandFactory.createSync2(() { + print("action: "); + return "4711"; + }); + + expect(command.canExecute, emits(true)); + expect(command.isExecuting, emits(false)); + + expect(command.results, emits("4711")); + + command.execute(); + + + expect(command.canExecute, emits(true)); + expect(command.isExecuting, emits(false)); + }); + + + + test('Execute simple sync function with parameter', () { + + final command = RxCommandFactory.createSync3((s) { + print("action: " + s); + return s + s; + }); + + expect(command.canExecute, emits(true)); + expect(command.isExecuting, emits(false)); + + expect(command.results, emits("47114711")); + + command.execute("4711"); + + + expect(command.canExecute, emits(true)); + expect(command.isExecuting, emits(false)); + }); + + + + + + +}