├── .bazelrc
├── .github
└── workflows
│ └── android.yml
├── .gitignore
├── BUILD.bazel
├── CHANGELOG.md
├── README.md
├── RELEASING.md
├── WORKSPACE
├── app
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── stepango
│ │ └── example
│ │ └── MainActivity.kt
│ └── res
│ ├── layout
│ └── activity_main.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-w820dp
│ └── dimens.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── lib
├── .gitignore
├── BUILD.bazel
├── VERSION
├── build.gradle
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── com
│ │ └── stepango
│ │ └── rxdatabindings
│ │ ├── DataBindingScheduler.kt
│ │ ├── DatabindingsExt.kt
│ │ ├── FlowableExt.kt
│ │ ├── MaybeExt.kt
│ │ ├── ObservableExt.kt
│ │ ├── ObservableNumber.kt
│ │ ├── ObservableSpanned.kt
│ │ ├── ObservableString.kt
│ │ └── SingleExt.kt
│ └── test
│ └── java
│ └── com
│ └── stepango
│ └── test
│ ├── NullStringGetter.java
│ └── ObservableStringTest.kt
└── settings.gradle
/.bazelrc:
--------------------------------------------------------------------------------
1 | build --disk_cache=./bazel-cache
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v1
12 | - name: set up JDK 1.8
13 | uses: actions/setup-java@v1
14 | with:
15 | java-version: 1.8
16 | - name: Build with Gradle
17 | run: ./gradlew build test
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 | *.patch
11 | /bazel-*
12 |
--------------------------------------------------------------------------------
/BUILD.bazel:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stepango/RxDatabindings/538909f9ff936948f6f1a390a52241fd83379939/BUILD.bazel
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Change Log
2 | ==========
3 |
4 | Version 2.0.0 *(2019-09-23)*
5 |
6 | * AndroidX Migration
7 | * Default scheduler is now IO
8 | * Bintray publishing setup
9 |
10 | Version 1.9.0 *()*
11 |
12 | * Explicit return types
13 |
14 | Version 1.8.0 *(2019-06-19)*
15 |
16 | * Default scheduler in now Computation
17 | * safeObserve extension added
18 |
19 | Version 1.7.0 *(2019-06-14)*
20 |
21 | * Specialised extensions for ObservableString, ObservableSpanned, ObservableNumber
22 | * ObservableSpannableString removed
23 | * Dependencies updated
24 |
25 | Version 1.6.0 *(2018-12-06)*
26 |
27 | * Added ObservableSpanned
28 | * ObservableSpannableString - deprecated
29 |
30 | Version 1.5.0 *(2018-10-26)*
31 |
32 | * Added ObservableSpannableString
33 |
34 | Version 1.4.0 *(2018-07-18)*
35 | ----------------------------
36 |
37 | * Make ObservableString setter null safe
38 |
39 | Version 1.3.0 *(2018-07-13)*
40 | ----------------------------
41 |
42 | * Removed kOptional
43 |
44 | Version 1.1.1 *(2017-06-01)*
45 | ----------------------------
46 |
47 | * Fixed kotlin parcelable serialization for ObservableString
48 | * rxJava updated to 2.1.0
49 | * Kotlin updated to 1.1.2-3
50 | * Example updated for orientation changes support
51 | * Gradle updated to v3.3
52 |
53 | Version 1.1.0 *(2017-04-24)*
54 | ----------------------------
55 |
56 | * `StringObservable` parcelable implementation now compatible with Kotlin 1.1
57 | * `fireInitialValue` flag added
58 | * `invoke` methods removed, breaking change
59 |
60 | Version 1.0.0 *(2017-03-16)*
61 | ----------------------------
62 |
63 | * `Kotlin` updated to v1.1.1
64 | * `rxJava` updated to v2.0.7
65 | * `Flowable` support added
66 | * `Single` support added
67 | * `Maybe` support added
68 | * `Default` scheduler support added
69 |
70 | Version 0.6.0 *(2017-02-15)*
71 | ----------------------------
72 |
73 | * `ObservableString` implements Parcelable
74 | * `observeOption` is now `observeOptional`
75 |
76 | Version 0.5.0 *(2017-01-13)*
77 | ----------------------------
78 |
79 | * `safeSetTo` methods added
80 | * documentation added
81 | * `rxJava` updated to 2.0.4
82 |
83 | Version 0.4.0 *(2016-12-29)*
84 | ----------------------------
85 |
86 | * setTo(Observable*, transformer) methods added
87 | * `kOptional` updated to v1.1.0
88 | * `Kotlin` updated to v1.0.6
89 |
90 | Version 0.3.0 *(2016-12-21)*
91 | ----------------------------
92 |
93 | * setTo(Observable*) methods added
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RxDatabindings
2 | [ ](https://bintray.com/step-89-g/stepango/rxDataBindings/_latestVersion)
3 | 
4 |
5 | RxJava 2 & 3 extensions for Android Databindings library
6 |
7 | Add RxDataBindings to your build.gradle
8 | ```groovy
9 | implementation "com.stepango.rxdatabindings:rxdatabindings:3.0.0"
10 | ```
11 |
12 | Basic example of usage:
13 | ```kotlin
14 | interface ViewModelState : Parcelable {
15 | val text: ObservableString
16 | val counter: ObservableInt
17 | }
18 |
19 | @Parcelize
20 | data class ViewModelStateImpl(
21 | override val text: ObservableString = ObservableString(),
22 | override val counter: ObservableInt = ObservableInt()
23 | ) : ViewModelState
24 |
25 | class ViewModel(val state: ViewModelState) : ViewModelState by state {
26 |
27 | init {
28 | counter.observe()
29 | .setTo(text) { "Wow! You count till $it" }
30 | .doOnNext { Log.d("THREAD", Thread.currentThread().name) }
31 | .subscribe()
32 | }
33 |
34 | fun incCounter() = counter.inc(10)
35 | fun decCounter() = counter.dec(0)
36 |
37 | }
38 | ```
39 |
--------------------------------------------------------------------------------
/RELEASING.md:
--------------------------------------------------------------------------------
1 | ```
2 | cd lib
3 | ../gradlew clean build generateRelease
4 | ```
5 |
6 | Then zip/compress the `com` folder and upload to jcenter.
7 |
--------------------------------------------------------------------------------
/WORKSPACE:
--------------------------------------------------------------------------------
1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2 |
3 | RULES_JVM_EXTERNAL_TAG = "3.0"
4 | RULES_JVM_EXTERNAL_SHA = "62133c125bf4109dfd9d2af64830208356ce4ef8b165a6ef15bbff7460b35c3a"
5 |
6 | http_archive(
7 | name = "rules_jvm_external",
8 | strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
9 | sha256 = RULES_JVM_EXTERNAL_SHA,
10 | url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
11 | )
12 |
13 | load("@rules_jvm_external//:defs.bzl", "maven_install")
14 |
15 | android_plugin_version = "3.6.1"
16 | rx_java_version = "3.0.0"
17 | junit_version = "4.12"
18 |
19 | maven_install(
20 | artifacts = [
21 | "io.reactivex.rxjava3:rxjava:" + rx_java_version,
22 | "androidx.databinding:databinding-common:" + android_plugin_version,
23 | "androidx.databinding:databinding-runtime:" + android_plugin_version ,
24 | "junit:junit:" + junit_version,
25 | ],
26 | repositories = [
27 | "https://jcenter.bintray.com/",
28 | "https://maven.google.com",
29 | "https://repo1.maven.org/maven2",
30 | ],
31 | )
32 |
33 | # Configure Android SDK Path
34 |
35 | http_archive(
36 | name = "build_bazel_rules_android",
37 | urls = ["https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"],
38 | sha256 = "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
39 | strip_prefix = "rules_android-0.1.1",
40 | )
41 |
42 | load("@build_bazel_rules_android//android:rules.bzl", "android_sdk_repository")
43 |
44 | android_sdk_repository(
45 | name = "androidsdk",
46 | )
47 |
48 | # Kotlin rules
49 |
50 | rules_kotlin_version = "legacy-1.3.0"
51 | rules_kotlin_sha = "4fd769fb0db5d3c6240df8a9500515775101964eebdf85a3f9f0511130885fde"
52 | http_archive(
53 | name = "io_bazel_rules_kotlin",
54 | urls = ["https://github.com/cgruber/rules_kotlin/archive/%s.zip" % rules_kotlin_version],
55 | type = "zip",
56 | strip_prefix = "rules_kotlin-%s" % rules_kotlin_version,
57 | sha256 = rules_kotlin_sha,
58 | )
59 |
60 | load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains")
61 | kotlin_repositories() # if you want the default. Otherwise see custom kotlinc distribution below
62 | kt_register_toolchains() # to use the default toolchain, otherwise see toolchains below
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'kotlin-android'
4 | id 'kotlin-android-extensions'
5 | id 'kotlin-kapt'
6 | }
7 |
8 | android {
9 |
10 | compileSdkVersion 29
11 |
12 | defaultConfig {
13 | applicationId "com.stepango.example"
14 |
15 | minSdkVersion 16
16 | targetSdkVersion 29
17 |
18 | versionCode 1
19 | versionName "1.0"
20 | }
21 |
22 | buildTypes {
23 | release {
24 | minifyEnabled false
25 | proguardFiles getDefaultProguardFile('proguard-android.txt')
26 | }
27 | }
28 |
29 | dataBinding.enabled = true
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | }
37 |
38 | androidExtensions {
39 | features = ["parcelize"]
40 | }
41 |
42 | dependencies {
43 | implementation project(':lib')
44 |
45 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
46 | implementation "io.reactivex.rxjava3:rxjava:$rxJava_version"
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stepango/example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.stepango.example
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Parcelable
6 | import android.text.SpannableString
7 | import android.text.style.AbsoluteSizeSpan
8 | import android.util.Log
9 | import androidx.databinding.DataBindingUtil
10 | import androidx.databinding.ObservableInt
11 | import com.stepango.example.databinding.ActivityMainBinding
12 | import com.stepango.rxdatabindings.ObservableSpanned
13 | import com.stepango.rxdatabindings.ObservableString
14 | import com.stepango.rxdatabindings.observe
15 | import com.stepango.rxdatabindings.setTo
16 | import kotlinx.android.parcel.Parcelize
17 | import kotlin.properties.Delegates
18 |
19 |
20 | class MainActivity : Activity() {
21 |
22 | private var viewModel by Delegates.notNull()
23 |
24 | override fun onCreate(savedInstanceState: Bundle?) {
25 | super.onCreate(savedInstanceState)
26 | val binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
27 | viewModel = ViewModel(savedInstanceState.extract { ViewModelStateImpl() })
28 | binding.viewModel = viewModel
29 | }
30 |
31 | override fun onSaveInstanceState(outState: Bundle?) {
32 | super.onSaveInstanceState(outState)
33 | outState?.putState(viewModel.state)
34 | }
35 |
36 | }
37 |
38 | interface ViewModelState : Parcelable {
39 | val text: ObservableString
40 | val counter: ObservableInt
41 | val styledText: ObservableSpanned
42 | }
43 |
44 | @Parcelize
45 | data class ViewModelStateImpl(
46 | override val text: ObservableString = ObservableString(),
47 | override val counter: ObservableInt = ObservableInt(),
48 | override val styledText: ObservableSpanned = ObservableSpanned()
49 | ) : ViewModelState
50 |
51 | @Parcelize
52 | class ViewModel(val state: ViewModelState) : ViewModelState by state {
53 |
54 | init {
55 | counter.observe(fireInitialValue = true)
56 | .setTo(text) { "Wow! You counted till $it" }
57 | .setTo(styledText) {
58 | SpannableString("Now that's... awesome!").apply {
59 | setSpan(AbsoluteSizeSpan(it, true), 14, 22, 0)
60 | }
61 | }
62 | .doOnNext { Log.d("THREAD", Thread.currentThread().name) }
63 | .subscribe()
64 | }
65 |
66 | fun incCounter() = counter.set(counter.get().inc())
67 | fun decCounter() = counter.set(counter.get().dec())
68 |
69 | }
70 |
71 | inline fun Bundle?.extract(defaultValueProducer: () -> T): T {
72 | this ?: return defaultValueProducer()
73 | val key = T::class.java.name
74 | return if (containsKey(key)) {
75 | Log.d("State::", "restored $key")
76 | getParcelable(key) ?: throw IllegalStateException("null Parcelable")
77 | } else {
78 | defaultValueProducer()
79 | }
80 | }
81 |
82 | fun Bundle.putState(value: T) {
83 | val name = value::class.java.name
84 | putParcelable(name, value)
85 | Log.d("State::", "saved $name")
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
30 |
31 |
34 |
35 |
40 |
41 |
47 |
48 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stepango/RxDatabindings/538909f9ff936948f6f1a390a52241fd83379939/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stepango/RxDatabindings/538909f9ff936948f6f1a390a52241fd83379939/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stepango/RxDatabindings/538909f9ff936948f6f1a390a52241fd83379939/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stepango/RxDatabindings/538909f9ff936948f6f1a390a52241fd83379939/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stepango/RxDatabindings/538909f9ff936948f6f1a390a52241fd83379939/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | RxDatabindings
3 | Press me
4 | Press me now
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | ext {
6 | release_version = '3.0.0'
7 | release_code = 13
8 |
9 | kotlin_version = '1.3.71'
10 | rxJava_version = '3.0.0'
11 | android_plugin_version = '3.6.1'
12 | }
13 |
14 | repositories {
15 | google()
16 | jcenter()
17 | }
18 |
19 | dependencies {
20 | classpath "com.android.tools.build:gradle:$android_plugin_version"
21 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
22 |
23 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
24 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
25 |
26 | // NOTE: Do not place your application dependencies here; they belong
27 | // in the individual module build.gradle files
28 | }
29 |
30 | }
31 |
32 | allprojects {
33 | repositories {
34 | google()
35 | jcenter()
36 | }
37 | }
38 |
39 | task clean(type: Delete) {
40 | delete rootProject.buildDir
41 | }
42 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # Specifies the JVM arguments used for the daemon process.
4 | # The setting is particularly useful for tweaking memory settings.
5 | org.gradle.jvmargs=-Xmx1536m
6 |
7 | # Android plugin will use the appropriate AndroidX library instead of a Support Library
8 | android.useAndroidX=true
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stepango/RxDatabindings/538909f9ff936948f6f1a390a52241fd83379939/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Mar 30 17:04:20 OMST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS='"-Xmx64m"'
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS="-Xmx64m"
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/lib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lib/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library", "kt_jvm_test")
2 |
3 | kt_android_library(
4 | name = "rxdatabindings",
5 | srcs = glob(["src/main/java/com/stepango/rxdatabindings/*.kt"]),
6 | deps = [
7 | "@maven//:junit_junit",
8 | "@maven//:io_reactivex_rxjava3_rxjava",
9 | "@maven//:androidx_databinding_databinding_common",
10 | "@maven//:androidx_databinding_databinding_runtime",
11 | ]
12 | )
13 |
14 | java_import(
15 | name = "android_sdk",
16 | jars = ["@bazel_tools//tools/android:android_jar"],
17 | neverlink = 1,
18 | visibility = ["//visibility:private"],
19 | )
20 |
21 | kt_jvm_test(
22 | name = "rxdatabindings_test",
23 | srcs = glob([
24 | "src/test/java/com/stepango/test/*.kt",
25 | "src/test/java/com/stepango/test/*.java"
26 | ]),
27 | deps = [
28 | "@maven//:junit_junit",
29 | "@maven//:io_reactivex_rxjava3_rxjava",
30 | "@maven//:androidx_databinding_databinding_common",
31 | "@maven//:androidx_databinding_databinding_runtime",
32 | ":rxdatabindings",
33 | ]
34 | )
35 |
--------------------------------------------------------------------------------
/lib/VERSION:
--------------------------------------------------------------------------------
1 | 2.1.0
--------------------------------------------------------------------------------
/lib/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | id 'kotlin-android'
4 | }
5 |
6 | android {
7 | compileSdkVersion 29
8 |
9 | defaultConfig {
10 | minSdkVersion 15
11 | targetSdkVersion 29
12 | versionCode release_code
13 | versionName "$release_version"
14 | }
15 |
16 | compileOptions {
17 | sourceCompatibility JavaVersion.VERSION_1_8
18 | targetCompatibility JavaVersion.VERSION_1_8
19 | }
20 | }
21 |
22 | dependencies {
23 |
24 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
25 | compileOnly "io.reactivex.rxjava3:rxjava:$rxJava_version"
26 | compileOnly "androidx.databinding:databinding-common:$android_plugin_version"
27 | compileOnly "androidx.databinding:databinding-runtime:$android_plugin_version"
28 |
29 | testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
30 | testImplementation "io.reactivex.rxjava3:rxjava:$rxJava_version"
31 | testImplementation "androidx.databinding:databinding-common:$android_plugin_version"
32 | testImplementation "androidx.databinding:databinding-runtime:$android_plugin_version"
33 | testImplementation "junit:junit:4.12"
34 |
35 | }
36 |
37 | apply plugin: 'maven-publish'
38 | apply plugin: 'com.jfrog.bintray'
39 |
40 | version "$release_version"
41 | group 'com.stepango.rxdatabindings'
42 |
43 | publishing {
44 | publications {
45 | Production(MavenPublication) {
46 | artifact("$buildDir/outputs/aar/lib-release.aar")
47 | groupId this.group
48 | artifactId 'rxdatabindings'
49 | version this.version
50 |
51 | pom.withXml {
52 | def dependenciesNode = asNode().appendNode('dependencies')
53 |
54 | // Iterate over the implementation dependencies (we don't want the test ones),
55 | // adding a node for each
56 | configurations.implementation.allDependencies.each {
57 | // Ensure dependencies such as fileTree are not included in the pom.
58 | if (it.name != 'unspecified') {
59 | def dependencyNode = dependenciesNode.appendNode('dependency')
60 | dependencyNode.appendNode('groupId', it.group)
61 | dependencyNode.appendNode('artifactId', it.name)
62 | dependencyNode.appendNode('version', it.version)
63 | }
64 | }
65 | }
66 | }
67 | }
68 | }
69 |
70 | bintray {
71 | user = project.getProperties()['user'] ?: System.getenv('BINTRAY_USER')
72 | key = project.getProperties()['apiKey'] ?: System.getenv('BINTRAY_API_KEY')
73 | publications = ['Production']
74 | configurations = ['archives']
75 | // Default: false. Whether to override version artifacts already published
76 | override = false
77 | // Default: false. Whether version should be auto published after an upload
78 | publish = true
79 | pkg {
80 | repo = 'stepango' // the name of the repository you created on Bintray
81 | name = 'rxDataBindings' // the name of the package you created inside it
82 | version {
83 | name = this.version
84 | released = new Date()
85 | vcsTag = this.version
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/lib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/stepango/rxdatabindings/DataBindingScheduler.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 Goncharov Stepan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.stepango.rxdatabindings
18 |
19 | import io.reactivex.rxjava3.core.Scheduler
20 | import io.reactivex.rxjava3.schedulers.Schedulers
21 |
22 |
23 | var rxDataBindingsScheduler: Scheduler = Schedulers.io()
24 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/stepango/rxdatabindings/DatabindingsExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 Goncharov Stepan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.stepango.rxdatabindings
17 |
18 | import android.os.Parcelable
19 | import android.text.Spanned
20 | import androidx.databinding.ObservableBoolean
21 | import androidx.databinding.ObservableByte
22 | import androidx.databinding.ObservableChar
23 | import androidx.databinding.ObservableDouble
24 | import androidx.databinding.ObservableField
25 | import androidx.databinding.ObservableFloat
26 | import androidx.databinding.ObservableInt
27 | import androidx.databinding.ObservableLong
28 | import androidx.databinding.ObservableParcelable
29 | import androidx.databinding.ObservableShort
30 | import io.reactivex.rxjava3.core.Observable
31 | import io.reactivex.rxjava3.core.Scheduler
32 | import androidx.databinding.Observable as DataBindingObservable
33 |
34 |
35 | internal inline fun T.observe(
36 | scheduler: Scheduler?,
37 | fireInitialValue: Boolean,
38 | crossinline transformer: (T) -> R?
39 | ): Observable = Observable.create { source ->
40 |
41 | if (fireInitialValue && !source.isDisposed) try {
42 | transformer(this)?.let(source::onNext)
43 | } catch (throwable: Throwable) {
44 | source.onError(throwable)
45 | return@create
46 | }
47 |
48 | object : DataBindingObservable.OnPropertyChangedCallback() {
49 | @Suppress("UNCHECKED_CAST")
50 | override fun onPropertyChanged(observable: DataBindingObservable, id: Int) = if (!source.isDisposed) try {
51 | transformer(observable as T)?.let(source::onNext) ?: Unit
52 | } catch (throwable: Throwable) {
53 | source.onError(throwable)
54 | } else Unit
55 | }.let {
56 | source.setCancellable { removeOnPropertyChangedCallback(it) }
57 | addOnPropertyChangedCallback(it)
58 | }
59 |
60 | }.let { if (scheduler != null) it.subscribeOn(scheduler) else it }
61 |
62 | fun ObservableBoolean.observe(
63 | scheduler: Scheduler? = rxDataBindingsScheduler,
64 | fireInitialValue: Boolean = true
65 | ): Observable =
66 | observe(scheduler, fireInitialValue) { it.get() }
67 |
68 | fun ObservableByte.observe(
69 | scheduler: Scheduler? = rxDataBindingsScheduler,
70 | fireInitialValue: Boolean = true
71 | ): Observable =
72 | observe(scheduler, fireInitialValue) { it.get() }
73 |
74 | fun ObservableShort.observe(
75 | scheduler: Scheduler? = rxDataBindingsScheduler,
76 | fireInitialValue: Boolean = true
77 | ): Observable =
78 | observe(scheduler, fireInitialValue) { it.get() }
79 |
80 | fun ObservableInt.observe(
81 | scheduler: Scheduler? = rxDataBindingsScheduler,
82 | fireInitialValue: Boolean = true
83 | ): Observable =
84 | observe(scheduler, fireInitialValue) { it.get() }
85 |
86 | fun ObservableLong.observe(
87 | scheduler: Scheduler? = rxDataBindingsScheduler,
88 | fireInitialValue: Boolean = true
89 | ): Observable =
90 | observe(scheduler, fireInitialValue) { it.get() }
91 |
92 | fun ObservableFloat.observe(
93 | scheduler: Scheduler? = rxDataBindingsScheduler,
94 | fireInitialValue: Boolean = true
95 | ): Observable =
96 | observe(scheduler, fireInitialValue) { it.get() }
97 |
98 | fun ObservableDouble.observe(
99 | scheduler: Scheduler? = rxDataBindingsScheduler,
100 | fireInitialValue: Boolean = true
101 | ): Observable =
102 | observe(scheduler, fireInitialValue) { it.get() }
103 |
104 | fun ObservableNumber.observe(
105 | scheduler: Scheduler? = rxDataBindingsScheduler,
106 | fireInitialValue: Boolean = true
107 | ): Observable =
108 | observe(scheduler, fireInitialValue) { it.get() }
109 |
110 | fun ObservableChar.observe(
111 | scheduler: Scheduler? = rxDataBindingsScheduler,
112 | fireInitialValue: Boolean = true
113 | ): Observable =
114 | observe(scheduler, fireInitialValue) { it.get() }
115 |
116 | fun ObservableString.observe(
117 | scheduler: Scheduler? = rxDataBindingsScheduler,
118 | fireInitialValue: Boolean = true
119 | ): Observable =
120 | observe(scheduler, fireInitialValue) { it.get() }
121 |
122 | fun ObservableSpanned.observe(
123 | scheduler: Scheduler? = rxDataBindingsScheduler,
124 | fireInitialValue: Boolean = true
125 | ): Observable =
126 | observe(scheduler, fireInitialValue) { it.get() }
127 |
128 | fun ObservableField.observe(
129 | scheduler: Scheduler? = rxDataBindingsScheduler,
130 | fireInitialValue: Boolean = true
131 | ): Observable = observe(scheduler, fireInitialValue) { it.get() }
132 |
133 | fun ObservableParcelable.observe(
134 | scheduler: Scheduler? = rxDataBindingsScheduler,
135 | fireInitialValue: Boolean = true
136 | ): Observable = observe(scheduler, fireInitialValue) { it.get() }
137 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/stepango/rxdatabindings/FlowableExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 Goncharov Stepan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.stepango.rxdatabindings
18 |
19 | import android.os.Parcelable
20 | import android.text.Spanned
21 | import androidx.databinding.ObservableBoolean
22 | import androidx.databinding.ObservableByte
23 | import androidx.databinding.ObservableChar
24 | import androidx.databinding.ObservableDouble
25 | import androidx.databinding.ObservableField
26 | import androidx.databinding.ObservableFloat
27 | import androidx.databinding.ObservableInt
28 | import androidx.databinding.ObservableLong
29 | import androidx.databinding.ObservableParcelable
30 | import androidx.databinding.ObservableShort
31 | import io.reactivex.rxjava3.core.Flowable
32 |
33 |
34 | /**
35 | * Set value to field with corresponding type
36 | * @param field observable value holder
37 | */
38 | fun Flowable.setTo(field: ObservableInt): Flowable = doOnNext(field::set)
39 |
40 | /**
41 | * Set value to field with corresponding type
42 | * @param field observable value holder
43 | */
44 | fun Flowable.setTo(field: ObservableByte): Flowable = doOnNext(field::set)
45 |
46 | /**
47 | * Set value to field with corresponding type
48 | * @param field observable value holder
49 | */
50 | fun Flowable.setTo(field: ObservableChar): Flowable = doOnNext(field::set)
51 |
52 | /**
53 | * Set value to field with corresponding type
54 | * @param field observable value holder
55 | */
56 | fun Flowable.setTo(field: ObservableLong): Flowable = doOnNext(field::set)
57 |
58 | /**
59 | * Set value to field with corresponding type
60 | * @param field observable value holder
61 | */
62 | fun Flowable.setTo(field: ObservableShort): Flowable = doOnNext(field::set)
63 |
64 | /**
65 | * Set value to field with corresponding type
66 | * @param field observable value holder
67 | */
68 | fun Flowable.setTo(field: ObservableFloat): Flowable = doOnNext(field::set)
69 |
70 | /**
71 | * Set value to field with corresponding type
72 | * @param field observable value holder
73 | */
74 | fun Flowable.setTo(field: ObservableDouble): Flowable = doOnNext(field::set)
75 |
76 | /**
77 | * Set value to field with corresponding type
78 | * @param field observable value holder
79 | */
80 | fun Flowable.setTo(field: ObservableBoolean): Flowable = doOnNext(field::set)
81 |
82 | fun Flowable.setTo(field: ObservableString): Flowable = doOnNext(field::set)
83 |
84 | fun Flowable.setTo(field: ObservableSpanned): Flowable = doOnNext(field::set)
85 |
86 | fun Flowable.setTo(field: ObservableNumber): Flowable = doOnNext(field::set)
87 |
88 | /**
89 | * Set value to field with corresponding type
90 | * @param field observable value holder
91 | */
92 | fun Flowable.setTo(field: ObservableField): Flowable = doOnNext(field::set)
93 |
94 | /**
95 | * Set value to field with corresponding type
96 | * @param field observable value holder
97 | */
98 | fun Flowable.setTo(field: ObservableParcelable): Flowable = doOnNext(field::set)
99 |
100 | /**
101 | * Set transformed value to field with corresponding type
102 | * @param field observable value holder
103 | * @param transformer value transformer
104 | */
105 | inline fun Flowable.setTo(
106 | field: ObservableInt,
107 | crossinline transformer: (T) -> Int
108 | ): Flowable = doOnNext { field.set(transformer(it)) }
109 |
110 | /**
111 | * Set transformed value to field with corresponding type
112 | * @param field observable value holder
113 | * @param transformer value transformer
114 | */
115 | inline fun Flowable.setTo(
116 | field: ObservableByte,
117 | crossinline transformer: (T) -> Byte
118 | ): Flowable = doOnNext { field.set(transformer(it)) }
119 |
120 | /**
121 | * Set transformed value to field with corresponding type
122 | * @param field observable value holder
123 | * @param transformer value transformer
124 | */
125 | inline fun Flowable.setTo(
126 | field: ObservableChar,
127 | crossinline transformer: (T) -> Char
128 | ): Flowable = doOnNext { field.set(transformer(it)) }
129 |
130 | /**
131 | * Set transformed value to field with corresponding type
132 | * @param field observable value holder
133 | * @param transformer value transformer
134 | */
135 | inline fun Flowable.setTo(
136 | field: ObservableLong,
137 | crossinline transformer: (T) -> Long
138 | ): Flowable = doOnNext { field.set(transformer(it)) }
139 |
140 | /**
141 | * Set transformed value to field with corresponding type
142 | * @param field observable value holder
143 | * @param transformer value transformer
144 | */
145 | inline fun Flowable.setTo(
146 | field: ObservableShort,
147 | crossinline transformer: (T) -> Short
148 | ): Flowable = doOnNext { field.set(transformer(it)) }
149 |
150 | /**
151 | * Set transformed value to field with corresponding type
152 | * @param field observable value holder
153 | * @param transformer value transformer
154 | */
155 | inline fun Flowable.setTo(
156 | field: ObservableFloat,
157 | crossinline transformer: (T) -> Float
158 | ): Flowable = doOnNext { field.set(transformer(it)) }
159 |
160 | /**
161 | * Set transformed value to field with corresponding type
162 | * @param field observable value holder
163 | * @param transformer value transformer
164 | */
165 | inline fun Flowable.setTo(
166 | field: ObservableDouble,
167 | crossinline transformer: (T) -> Double
168 | ): Flowable = doOnNext { field.set(transformer(it)) }
169 |
170 | /**
171 | * Set transformed value to field with corresponding type
172 | * @param field observable value holder
173 | * @param transformer value transformer
174 | */
175 | inline fun Flowable.setTo(
176 | field: ObservableBoolean,
177 | crossinline transformer: (T) -> Boolean
178 | ): Flowable = doOnNext { field.set(transformer(it)) }
179 |
180 | inline fun Flowable.setTo(
181 | field: ObservableString,
182 | crossinline transformer: (T) -> String
183 | ): Flowable = doOnNext { field.set(transformer(it)) }
184 |
185 | inline fun Flowable.setTo(
186 | field: ObservableSpanned,
187 | crossinline transformer: (T) -> Spanned
188 | ): Flowable = doOnNext { field.set(transformer(it)) }
189 |
190 | inline fun Flowable.setTo(
191 | field: ObservableNumber,
192 | crossinline transformer: (T) -> Number
193 | ): Flowable = doOnNext { field.set(transformer(it)) }
194 |
195 | /**
196 | * Set transformed value to field with corresponding type
197 | * @param field observable value holder
198 | * @param transformer value transformer
199 | */
200 | inline fun Flowable.setTo(
201 | field: ObservableField,
202 | crossinline transformer: (T) -> R
203 | ): Flowable = doOnNext { field.set(transformer(it)) }
204 |
205 | /**
206 | * Set transformed value to field with corresponding type
207 | * @param field observable value holder
208 | * @param transformer value transformer
209 | */
210 | inline fun Flowable.setTo(
211 | field: ObservableParcelable,
212 | crossinline transformer: (T) -> R
213 | ): Flowable = doOnNext { field.set(transformer(it)) }
214 |
215 | /**
216 | * Safe variant of @see [setTo] method that accepts and
217 | * skip null values emitted by transformer
218 | */
219 | inline fun Flowable.safeSetTo(
220 | field: ObservableInt,
221 | crossinline transformer: (T) -> Int?
222 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
223 |
224 | /**
225 | * Safe variant of @see [setTo] method that accepts and
226 | * skip null values emitted by transformer
227 | */
228 | inline fun Flowable.safeSetTo(
229 | field: ObservableByte,
230 | crossinline transformer: (T) -> Byte?
231 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
232 |
233 | /**
234 | * Safe variant of @see [setTo] method that accepts and
235 | * skip null values emitted by transformer
236 | */
237 | inline fun Flowable.safeSetTo(
238 | field: ObservableChar,
239 | crossinline transformer: (T) -> Char?
240 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
241 |
242 | /**
243 | * Safe variant of @see [setTo] method that accepts and
244 | * skip null values emitted by transformer
245 | */
246 | inline fun Flowable.safeSetTo(
247 | field: ObservableLong,
248 | crossinline transformer: (T) -> Long?
249 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
250 |
251 | /**
252 | * Safe variant of @see [setTo] method that accepts and
253 | * skip null values emitted by transformer
254 | */
255 | inline fun Flowable.safeSetTo(
256 | field: ObservableShort,
257 | crossinline transformer: (T) -> Short?
258 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
259 |
260 | /**
261 | * Safe variant of @see [setTo] method that accepts and
262 | * skip null values emitted by transformer
263 | */
264 | inline fun Flowable.safeSetTo(
265 | field: ObservableFloat,
266 | crossinline transformer: (T) -> Float?
267 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
268 |
269 | /**
270 | * Safe variant of @see [setTo] method that accepts and
271 | * skip null values emitted by transformer
272 | */
273 | inline fun Flowable.safeSetTo(
274 | field: ObservableDouble,
275 | crossinline transformer: (T) -> Double?
276 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
277 |
278 | /**
279 | * Safe variant of @see [setTo] method that accepts and
280 | * skip null values emitted by transformer
281 | */
282 | inline fun Flowable.safeSetTo(
283 | field: ObservableBoolean,
284 | crossinline transformer: (T) -> Boolean?
285 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
286 |
287 | inline fun Flowable.safeSetTo(
288 | field: ObservableString,
289 | crossinline transformer: (T) -> String?
290 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
291 |
292 | inline fun Flowable.safeSetTo(
293 | field: ObservableSpanned,
294 | crossinline transformer: (T) -> Spanned?
295 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
296 |
297 | inline fun Flowable.safeSetTo(
298 | field: ObservableNumber,
299 | crossinline transformer: (T) -> Number?
300 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
301 |
302 | /**
303 | * Safe variant of @see [setTo] method that accepts and
304 | * skip null values emitted by transformer
305 | */
306 | inline fun Flowable.safeSetTo(
307 | field: ObservableField,
308 | crossinline transformer: (T) -> R?
309 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
310 |
311 | /**
312 | * Safe variant of @see [setTo] method that accepts and
313 | * skip null values emitted by transformer
314 | */
315 | inline fun Flowable.safeSetTo(
316 | field: ObservableParcelable,
317 | crossinline transformer: (T) -> R?
318 | ): Flowable = doOnNext { tValue -> transformer(tValue)?.let(field::set) }
319 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/stepango/rxdatabindings/MaybeExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 Goncharov Stepan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.stepango.rxdatabindings
18 |
19 | import android.os.Parcelable
20 | import android.text.Spanned
21 | import androidx.databinding.ObservableBoolean
22 | import androidx.databinding.ObservableByte
23 | import androidx.databinding.ObservableChar
24 | import androidx.databinding.ObservableDouble
25 | import androidx.databinding.ObservableField
26 | import androidx.databinding.ObservableFloat
27 | import androidx.databinding.ObservableInt
28 | import androidx.databinding.ObservableLong
29 | import androidx.databinding.ObservableParcelable
30 | import androidx.databinding.ObservableShort
31 | import io.reactivex.rxjava3.core.Maybe
32 |
33 |
34 | /**
35 | * Set value to field with corresponding type
36 | * @param field observable value holder
37 | */
38 | fun Maybe.setTo(field: ObservableInt): Maybe = doOnSuccess(field::set)
39 |
40 | /**
41 | * Set value to field with corresponding type
42 | * @param field observable value holder
43 | */
44 | fun Maybe.setTo(field: ObservableByte): Maybe = doOnSuccess(field::set)
45 |
46 | /**
47 | * Set value to field with corresponding type
48 | * @param field observable value holder
49 | */
50 | fun Maybe.setTo(field: ObservableChar): Maybe = doOnSuccess(field::set)
51 |
52 | /**
53 | * Set value to field with corresponding type
54 | * @param field observable value holder
55 | */
56 | fun Maybe.setTo(field: ObservableLong): Maybe = doOnSuccess(field::set)
57 |
58 | /**
59 | * Set value to field with corresponding type
60 | * @param field observable value holder
61 | */
62 | fun Maybe.setTo(field: ObservableShort): Maybe = doOnSuccess(field::set)
63 |
64 | /**
65 | * Set value to field with corresponding type
66 | * @param field observable value holder
67 | */
68 | fun Maybe.setTo(field: ObservableFloat): Maybe = doOnSuccess(field::set)
69 |
70 | /**
71 | * Set value to field with corresponding type
72 | * @param field observable value holder
73 | */
74 | fun Maybe.setTo(field: ObservableDouble): Maybe = doOnSuccess(field::set)
75 |
76 | /**
77 | * Set value to field with corresponding type
78 | * @param field observable value holder
79 | */
80 | fun Maybe.setTo(field: ObservableBoolean): Maybe = doOnSuccess(field::set)
81 |
82 | fun Maybe.setTo(field: ObservableString): Maybe = doOnSuccess(field::set)
83 |
84 | fun Maybe.setTo(field: ObservableSpanned): Maybe = doOnSuccess(field::set)
85 |
86 | fun Maybe.setTo(field: ObservableNumber): Maybe = doOnSuccess(field::set)
87 |
88 | /**
89 | * Set value to field with corresponding type
90 | * @param field observable value holder
91 | */
92 | fun Maybe.setTo(field: ObservableField): Maybe = doOnSuccess(field::set)
93 |
94 | /**
95 | * Set value to field with corresponding type
96 | * @param field observable value holder
97 | */
98 | fun Maybe.setTo(field: ObservableParcelable): Maybe = doOnSuccess(field::set)
99 |
100 | /**
101 | * Set transformed value to field with corresponding type
102 | * @param field observable value holder
103 | * @param transformer value transformer
104 | */
105 | inline fun Maybe.setTo(
106 | field: ObservableInt,
107 | crossinline transformer: (T) -> Int
108 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
109 |
110 | /**
111 | * Set transformed value to field with corresponding type
112 | * @param field observable value holder
113 | * @param transformer value transformer
114 | */
115 | inline fun Maybe.setTo(
116 | field: ObservableByte,
117 | crossinline transformer: (T) -> Byte
118 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
119 |
120 | /**
121 | * Set transformed value to field with corresponding type
122 | * @param field observable value holder
123 | * @param transformer value transformer
124 | */
125 | inline fun Maybe.setTo(
126 | field: ObservableChar,
127 | crossinline transformer: (T) -> Char
128 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
129 |
130 | /**
131 | * Set transformed value to field with corresponding type
132 | * @param field observable value holder
133 | * @param transformer value transformer
134 | */
135 | inline fun Maybe.setTo(
136 | field: ObservableLong,
137 | crossinline transformer: (T) -> Long
138 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
139 |
140 | /**
141 | * Set transformed value to field with corresponding type
142 | * @param field observable value holder
143 | * @param transformer value transformer
144 | */
145 | inline fun Maybe.setTo(
146 | field: ObservableShort,
147 | crossinline transformer: (T) -> Short
148 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
149 |
150 | /**
151 | * Set transformed value to field with corresponding type
152 | * @param field observable value holder
153 | * @param transformer value transformer
154 | */
155 | inline fun Maybe.setTo(
156 | field: ObservableFloat,
157 | crossinline transformer: (T) -> Float
158 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
159 |
160 | /**
161 | * Set transformed value to field with corresponding type
162 | * @param field observable value holder
163 | * @param transformer value transformer
164 | */
165 | inline fun Maybe.setTo(
166 | field: ObservableDouble,
167 | crossinline transformer: (T) -> Double
168 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
169 |
170 | /**
171 | * Set transformed value to field with corresponding type
172 | * @param field observable value holder
173 | * @param transformer value transformer
174 | */
175 | inline fun Maybe.setTo(
176 | field: ObservableBoolean,
177 | crossinline transformer: (T) -> Boolean
178 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
179 |
180 | inline fun Maybe.setTo(
181 | field: ObservableString,
182 | crossinline transformer: (T) -> String
183 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
184 |
185 | inline fun Maybe.setTo(
186 | field: ObservableSpanned,
187 | crossinline transformer: (T) -> Spanned
188 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
189 |
190 | inline fun Maybe.setTo(
191 | field: ObservableNumber,
192 | crossinline transformer: (T) -> Number
193 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
194 |
195 | /**
196 | * Set transformed value to field with corresponding type
197 | * @param field observable value holder
198 | * @param transformer value transformer
199 | */
200 | inline fun Maybe.setTo(
201 | field: ObservableField,
202 | crossinline transformer: (T) -> R
203 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
204 |
205 | /**
206 | * Set transformed value to field with corresponding type
207 | * @param field observable value holder
208 | * @param transformer value transformer
209 | */
210 | inline fun Maybe.setTo(
211 | field: ObservableParcelable,
212 | crossinline transformer: (T) -> R
213 | ): Maybe = doOnSuccess { field.set(transformer(it)) }
214 |
215 | /**
216 | * Safe variant of @see [setTo] method that accepts and
217 | * skip null values emitted by transformer
218 | */
219 | inline fun Maybe.safeSetTo(
220 | field: ObservableInt,
221 | crossinline transformer: (T) -> Int?
222 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
223 |
224 | /**
225 | * Safe variant of @see [setTo] method that accepts and
226 | * skip null values emitted by transformer
227 | */
228 | inline fun Maybe.safeSetTo(
229 | field: ObservableByte,
230 | crossinline transformer: (T) -> Byte?
231 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
232 |
233 | /**
234 | * Safe variant of @see [setTo] method that accepts and
235 | * skip null values emitted by transformer
236 | */
237 | inline fun Maybe.safeSetTo(
238 | field: ObservableChar,
239 | crossinline transformer: (T) -> Char?
240 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
241 |
242 | /**
243 | * Safe variant of @see [setTo] method that accepts and
244 | * skip null values emitted by transformer
245 | */
246 | inline fun Maybe.safeSetTo(
247 | field: ObservableLong,
248 | crossinline transformer: (T) -> Long?
249 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
250 |
251 | /**
252 | * Safe variant of @see [setTo] method that accepts and
253 | * skip null values emitted by transformer
254 | */
255 | inline fun Maybe.safeSetTo(
256 | field: ObservableShort,
257 | crossinline transformer: (T) -> Short?
258 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
259 |
260 | /**
261 | * Safe variant of @see [setTo] method that accepts and
262 | * skip null values emitted by transformer
263 | */
264 | inline fun Maybe.safeSetTo(
265 | field: ObservableFloat,
266 | crossinline transformer: (T) -> Float?
267 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
268 |
269 | /**
270 | * Safe variant of @see [setTo] method that accepts and
271 | * skip null values emitted by transformer
272 | */
273 | inline fun Maybe.safeSetTo(
274 | field: ObservableDouble,
275 | crossinline transformer: (T) -> Double?
276 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
277 |
278 | /**
279 | * Safe variant of @see [setTo] method that accepts and
280 | * skip null values emitted by transformer
281 | */
282 | inline fun Maybe.safeSetTo(
283 | field: ObservableBoolean,
284 | crossinline transformer: (T) -> Boolean?
285 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
286 |
287 | inline fun Maybe.safeSetTo(
288 | field: ObservableString,
289 | crossinline transformer: (T) -> String?
290 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
291 |
292 | inline fun Maybe.safeSetTo(
293 | field: ObservableSpanned,
294 | crossinline transformer: (T) -> Spanned?
295 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
296 |
297 | inline fun Maybe.safeSetTo(
298 | field: ObservableNumber,
299 | crossinline transformer: (T) -> Number?
300 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
301 |
302 | /**
303 | * Safe variant of @see [setTo] method that accepts and
304 | * skip null values emitted by transformer
305 | */
306 | inline fun Maybe.safeSetTo(
307 | field: ObservableField,
308 | crossinline transformer: (T) -> R?
309 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
310 |
311 | /**
312 | * Safe variant of @see [setTo] method that accepts and
313 | * skip null values emitted by transformer
314 | */
315 | inline fun Maybe.safeSetTo(
316 | field: ObservableParcelable,
317 | crossinline transformer: (T) -> R?
318 | ): Maybe = doOnSuccess { tValue -> transformer(tValue)?.let(field::set) }
319 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/stepango/rxdatabindings/ObservableExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 Goncharov Stepan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.stepango.rxdatabindings
18 |
19 | import android.os.Parcelable
20 | import android.text.Spanned
21 | import androidx.databinding.ObservableBoolean
22 | import androidx.databinding.ObservableByte
23 | import androidx.databinding.ObservableChar
24 | import androidx.databinding.ObservableDouble
25 | import androidx.databinding.ObservableField
26 | import androidx.databinding.ObservableFloat
27 | import androidx.databinding.ObservableInt
28 | import androidx.databinding.ObservableLong
29 | import androidx.databinding.ObservableParcelable
30 | import androidx.databinding.ObservableShort
31 | import io.reactivex.rxjava3.core.Observable
32 |
33 |
34 | /**
35 | * Set value to field with corresponding type
36 | * @param field observable value holder
37 | */
38 | fun Observable.setTo(field: ObservableInt): Observable = doOnNext(field::set)
39 |
40 | /**
41 | * Set value to field with corresponding type
42 | * @param field observable value holder
43 | */
44 | fun Observable.setTo(field: ObservableByte): Observable = doOnNext(field::set)
45 |
46 | /**
47 | * Set value to field with corresponding type
48 | * @param field observable value holder
49 | */
50 | fun Observable.setTo(field: ObservableChar): Observable