Skip to content

Commit

Permalink
Merge pull request #94 from ggrell/reactorwitheffects-remove-mutation…
Browse files Browse the repository at this point in the history
…witheffect

Removing ReactorWithEffects.MutationWithEffect
  • Loading branch information
ggrell authored Nov 11, 2020
2 parents cd65521 + 248baf1 commit ecf1ee1
Show file tree
Hide file tree
Showing 20 changed files with 804 additions and 159 deletions.
8 changes: 5 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.siteUrl = "https://github.com/ggrell/RxReactor"
ext.gitUrl = "https://github.com/ggrell/RxReactor.git"

ext.buildConfig = [
minSdk : 15,
compileSdk: 29,
Expand Down Expand Up @@ -74,10 +77,9 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:4.1.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:$versions.dokka"
}
}
Expand All @@ -96,7 +98,7 @@ task clean(type: Delete) {
subprojects {
group = "com.gyurigrell"
def isRelease = Boolean.valueOf(project.hasProperty("release") ? project.property("release") as String : "false")
version = "0.4.6" + (isRelease ? "" : "-SNAPSHOT")
version = "0.9.0" + (isRelease ? "" : "-SNAPSHOT")

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
kotlinOptions {
Expand Down
46 changes: 0 additions & 46 deletions gradle/library-artifacts.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,6 @@ if (project.plugins.hasPlugin('com.android.library')) {
}
}

def siteUrl = "https://github.com/ggrell/RxReactor"
def gitUrl = "https://github.com/ggrell/RxReactor.git"

install {
repositories {
mavenInstaller {
pom {
project {
packaging 'aar'

groupId project.group
artifactId archivesBaseName

url siteUrl

licenses {
license {
name 'BSD 3-Clause License'
url 'https://github.com/ggrell/RxReactor/blob/master/LICENSE'
}
}

developers {
developer {
id 'ggrell'
name 'Gyuri Grell'
email 'ggrell@pobox.com'
}
}

scm {
connection gitUrl
developerConnection gitUrl
url siteUrl
}
}
}
}
}
}

afterEvaluate {
task sourcesJar(type: Jar) {
classifier 'sources'
Expand All @@ -56,10 +15,5 @@ if (project.plugins.hasPlugin('com.android.library')) {
classifier 'javadoc'
from dokkaJavadoc.outputDirectory
}

artifacts {
archives sourcesJar
archives javadocJar
}
}
}
44 changes: 43 additions & 1 deletion rxreactor1-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'jacoco'
apply plugin: 'org.jetbrains.dokka'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'maven-publish'
apply from: "$rootDir/gradle/library-artifacts.gradle"
apply from: "$rootDir/gradle/jacoco-android.gradle"

Expand Down Expand Up @@ -59,3 +59,45 @@ tasks.withType(Test) {
jacoco {
toolVersion = versions.jacoco
}

afterEvaluate {
publishing {
publications {
rxreactor1Android(MavenPublication) {
groupId = project.group
artifactId = archivesBaseName

from components.release
artifact sourcesJar
artifact javadocJar

pom {
name = "RxReactor (RxJava 1) for Android"
description = "A Kotlin framework for a reactive and unidirectional RxJava 1 application architecture"
url = siteUrl

licenses {
license {
name = 'BSD 3-Clause License'
url = 'https://github.com/ggrell/RxReactor/blob/master/LICENSE'
}
}

developers {
developer {
id = 'ggrell'
name = 'Gyuri Grell'
email = 'ggrell@pobox.com'
}
}

scm {
connection = gitUrl
developerConnection = gitUrl
url = siteUrl
}
}
}
}
}
}
45 changes: 40 additions & 5 deletions rxreactor1/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apply plugin: 'kotlin'
apply plugin: 'jacoco'
apply plugin: 'org.jetbrains.dokka'
apply plugin: 'com.github.kt3k.coveralls'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'maven-publish'

dependencies {
implementation deps.kotlin.stdlib.jdk
Expand Down Expand Up @@ -33,7 +33,42 @@ task javadocJar(type: Jar, dependsOn: dokkaJavadoc) {
from dokkaJavadoc.outputDirectory
}

artifacts {
archives sourcesJar
archives javadocJar
}
publishing {
publications {
rxreactor2(MavenPublication) {
groupId = project.group
artifactId = archivesBaseName

from components.java
artifact sourcesJar
artifact javadocJar

pom {
name = "RxReactor (RxJava 1)"
description = "A Kotlin framework for a reactive and unidirectional RxJava 1 application architecture"
url = siteUrl

licenses {
license {
name = 'BSD 3-Clause License'
url = 'https://github.com/ggrell/RxReactor/blob/master/LICENSE'
}
}

developers {
developer {
id = 'ggrell'
name = 'Gyuri Grell'
email = 'ggrell@pobox.com'
}
}

scm {
connection = gitUrl
developerConnection = gitUrl
url = siteUrl
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@ package com.gyurigrell.rxreactor1
* An optional interface to apply to your view which provides some formality around how to set up the reactor and the
* bindings between controls and state.
*/
interface ReactorView<Action, Mutation, State> {
var reactor: Reactor<Action, Mutation, State>
@Deprecated("This will be removed in 1.0")
interface ReactorView {
var reactor: Reactor<*, *, *>

fun bindControls(reactor: Reactor<Action, Mutation, State>)
fun bindState(reactor: Reactor<Action, Mutation, State>)
fun bindEffects(reactor: Reactor<Action, Mutation, State>)
fun <Action, Mutation, State> bindViews(reactor: Reactor<Action, Mutation, State>)
fun <Action, Mutation, State> bindState(reactor: Reactor<Action, Mutation, State>)
}

fun <Action, Mutation, State> ReactorView<Action, Mutation, State>.bind(reactor: Reactor<Action, Mutation, State>) {
fun <Action, Mutation, State> ReactorView.bind(reactor: Reactor<Action, Mutation, State>) {
this.reactor = reactor
bindControls(reactor)
bindViews(reactor)
bindState(reactor)
bindEffects(reactor)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import rx.Observable
* @param Effect the type of the effect that is emitted for side-effects that don't modify state
* @property initialState the initial state of the reactor, from which the {@see currentState} will be initialized.
*/
abstract class ReactorWithEffects<Action, Mutation : MutationWithEffect<Effect>, State, Effect>(
abstract class ReactorWithEffects<Action, Mutation : ReactorWithEffects.MutationWithEffect<Effect>, State, Effect>(
initialState: State
) : Reactor<Action, Mutation, State>(initialState) {
/**
Expand Down Expand Up @@ -54,19 +54,29 @@ abstract class ReactorWithEffects<Action, Mutation : MutationWithEffect<Effect>,
*/
open fun transformEffect(effect: Observable<Effect>): Observable<Effect> = effect

/**
* Emits all effects provided by the Observable
* @param effect tan Observable that emits effects
*/
protected fun emitEffect(effect: Observable<Effect>) {
effect.subscribe(effectRelay).also { subscriptions.add(it) }
}

/**
* Simplified way to emits effects
* @param effect one or more Effects to be emitted
*/
protected fun emitEffect(vararg effect: Effect) {
Observable.from(effect).subscribe(effectRelay).also { subscriptions.add(it) }
}

/**
* The interface that needs to be applied to the [Mutation] sealed class defined in this [ReactorWithEffects]. It
* applies a field named [effect] which defaults to `null`, meaning that mutation doesn't emit effects. Generally
* there should only be a single mutation that has an override where it provides an effect.
* @param Effect this is just the [Effect] type defined in the reactor.
* ```
* sealed class Mutation: MutationWithEffect<Effect> {
* object Mutation1 : Mutation()
* data class Mutation2(val someValue): Mutation()
* data class EmitEffect(override val effect: Effect): Mutation()
* }
* ```
*/
@Deprecated("Prefer calling `emitEffect()` function instead")
interface MutationWithEffect<Effect> {
val effect: Effect?
get() = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.gyurigrell.rxreactor1

import com.gyurigrell.rxreactor1.ReactorWithEffectsTests.TestReactor.*

import org.junit.Test
import rx.Observable
import rx.observers.TestSubscriber
Expand Down Expand Up @@ -86,7 +87,7 @@ class ReactorWithEffectsTests {
effects.assertValue(Effect.EffectWithValue(theValue))
}

class TestReactor(
private class TestReactor(
initialState: State = State()
) : ReactorWithEffects<Action, Mutation, State, Effect>(initialState) {
sealed class Action {
Expand All @@ -99,7 +100,6 @@ class ReactorWithEffectsTests {
sealed class Mutation : MutationWithEffect<Effect> {
object SimpleActionMutation : Mutation()
data class ActionWithValueMutation(val theValue: String) : Mutation()
data class FireEffect(override val effect: Effect) : Mutation()
}

data class State(
Expand All @@ -113,22 +113,27 @@ class ReactorWithEffectsTests {
}

override fun mutate(action: Action): Observable<Mutation> = when (action) {
is Action.SimpleAction -> Observable.just(Mutation.SimpleActionMutation)
is Action.SimpleAction ->
Observable.just(Mutation.SimpleActionMutation)

is Action.ActionWithValue -> Observable.just(Mutation.ActionWithValueMutation(action.theValue))
is Action.ActionWithValue ->
Observable.just(Mutation.ActionWithValueMutation(action.theValue))

is Action.ActionFiresEffectOne -> Observable.just(Mutation.FireEffect(Effect.EffectOne))
is Action.ActionFiresEffectOne -> {
emitEffect(Effect.EffectOne)
Observable.empty() // No mutations
}

is Action.ActionFiresEffectWithValue ->
Observable.just(Mutation.FireEffect(Effect.EffectWithValue(action.theValue)))
is Action.ActionFiresEffectWithValue -> {
emitEffect(Effect.EffectWithValue(action.theValue))
Observable.empty() // No mutations
}
}

override fun reduce(state: State, mutation: Mutation): State = when (mutation) {
is Mutation.SimpleActionMutation -> state.copy(simpleAction = true)

is Mutation.ActionWithValueMutation -> state.copy(actionWithValue = mutation.theValue)

is Mutation.FireEffect -> state // This will never happen, but need to be exhaustive
}
}
}
Loading

0 comments on commit ecf1ee1

Please sign in to comment.