Skip to content

Commit

Permalink
reduks bus api overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
beyondeye authored and daely committed Jan 11, 2017
1 parent 8a1eab6 commit 68cb949
Show file tree
Hide file tree
Showing 12 changed files with 287 additions and 140 deletions.
60 changes: 23 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,26 @@ repositories {
}
// main reduks package
compile 'com.github.beyondeye.reduks:reduks-core:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-core:2.0.0b12'
//rx-java based state store+ additional required dep for android support
compile 'com.github.beyondeye.reduks:reduks-rx:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-android:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-rx:2.0.0b12'
compile 'com.github.beyondeye.reduks:reduks-android:2.0.0b12'
//kovenant based state store and Async Action Middleware
compile 'com.github.beyondeye.reduks:reduks-kovenant:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-android:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-kovenant:2.0.0b12'
compile 'com.github.beyondeye.reduks:reduks-android:2.0.0b12'
//dev tools
compile 'com.github.beyondeye.reduks:reduks-devtools:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-devtools:2.0.0b12'
//immutable collections
compile 'com.github.beyondeye.reduks:reduks-pcollections:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-pcollections:2.0.0b12'
//reduks bus
compile 'com.github.beyondeye.reduks:reduks-pcollections:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-bus:2.0.0b11'
compile 'com.github.beyondeye.reduks:reduks-pcollections:2.0.0b12'
compile 'com.github.beyondeye.reduks:reduks-bus:2.0.0b12'
```

Expand Down Expand Up @@ -489,55 +489,41 @@ interface ReduksActivity<S> {
val reduks: Reduks<S>
}
```
For posting data on the bus the fragment need to obtain a reference to the [`Reduks`](./reduks/src/main/kotlin/com/beyondeye/reduks/Reduks.kt) object of the parent activity. It can be easily done overriding the `onAttach()` method:
For posting data on the bus the fragment need to obtain a reference to the [`Reduks`](./reduks/src/main/kotlin/com/beyondeye/reduks/Reduks.kt) object of the parent activity.
You can get it easily from the parent activity for example by defining the following extension property in the fragment
```kotlin
fun Context.bindReduksFromParentActivity(): Reduks<out StateWithBusData>? =
if (this is ReduksActivity<*>) {
this.reduks as? Reduks<out StateWithBusData>
} else {
throw RuntimeException(this.toString() + " must implement ReduksActivity<out StateWithBusData>")
}

fun Fragment.reduks() =
if (activity is ReduksActivity<*>)
(activity as ReduksActivity<out StateWithBusData>).reduks
else null
```
and then we can use it
```
class LoginFragment : Fragment() {
private var reduks: Reduks<out StateWithBusData>?=null
override fun onAttach(context: Context?) {
super.onAttach(context)
reduks=context?.bindReduksFromParentActivity()
}

override fun onDetach() {
super.onDetach()
reduks=null
}
fun onSubmitLogin() {
reduks?.postBusData(LoginFragmentResult("Kotlin","IsAwsome"))
reduks()?.postBusData(LoginFragmentResult("Kotlin","IsAwsome"))
}
}
```
And in another fragment (or in the parent activity) we can listen for data posted on the bus in this way
```kotlin
class LoginDataDisplayFragment : Fragment() {
private var reduks: Reduks<out StateWithBusData>?=null
val busHandlers:MutableList<StoreSubscription> = mutableListOf()

override fun onAttach(context: Context?) {
super.onAttach(context)
reduks=context?.bindReduksFromParentActivity()
reduks?.addBusDataHandler { lfr:LoginFragmentResult? ->
reduks()?.addBusDataHandlerWithTag(tag) { lfr:LoginFragmentResult? ->
if(lfr!=null) {
print("login with username=${lfr.username} and password=${lfr.password} and ")
}
}?.addToList(busHandlers)
}
}

override fun onDetach() {
super.onDetach()
reduks?.removeBusDataHandlers(busHandlers)
reduks=null
reduks()?.removeBusDataHandlersWithTag(tag) //remove all bus data handler attached to this fragment tag
}
}
```

Notices that we are using the Fragment tag (assuming it is defined) for automatically keeping track of all registered bus data handlers and removing them when the Fragment is detached from the activity
for the full source code of the example discussed see [here](./code_fragments/src/main/java/beyondeye/com/examples/busExample.kt)
####Persisting Reduks state and activity lifecycle
TODO
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ buildscript {
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:2.2.0'
classpath 'com.android.tools.build:gradle:2.2.3'
classpath "com.netflix.nebula:gradle-extra-configurations-plugin:2.2.+"
classpath "com.github.dcendents:android-maven-gradle-plugin:$dcendents_maven_plugin_version"

Expand All @@ -22,7 +22,7 @@ allprojects {
}
//COMMON BUILD TOOL AND SDK VERSION FOR ALL MODULES
ext {
VERSION_NAME='2.0.0b11-SNAPSHOT' //GLOBAL VERSION FOR REDUKS libs
VERSION_NAME='2.0.0b12-SNAPSHOT' //GLOBAL VERSION FOR REDUKS libs
POM_NAME='Reduks: Reduxjs for Kotlin+Android'
GROUP_MAVEN_PUSH= 'com.github.beyondeye.reduks' //used by maven-push: MAKE SURE THAT THIS MATCHES group DEFINED BELOW IN THIS FILE AND USED BY JITPACK
sourceCompatibility_ = 1.6 //I want this library to be linkable from android projects
Expand Down
34 changes: 8 additions & 26 deletions code_fragments/src/main/java/beyondeye/com/examples/busExample.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,47 +42,29 @@ fun test() {
store.postBusData(LoginFragmentResult(username = "Kotlin", password = "IsAwsome"))

}

fun Context.bindReduksFromParentActivity(): Reduks<out StateWithBusData>? =
if (this is ReduksActivity<*>) {
this.reduks as? Reduks<out StateWithBusData>
} else {
throw RuntimeException(this.toString() + " must implement ReduksActivity<out StateWithBusData>")
}
fun Fragment.reduks() =
if (activity is ReduksActivity<*>)
(activity as ReduksActivity<out StateWithBusData>).reduks
else null

class LoginFragment : Fragment() {
private var reduks: Reduks<out StateWithBusData>?=null
override fun onAttach(context: Context?) {
super.onAttach(context)
reduks=context?.bindReduksFromParentActivity()
}

override fun onDetach() {
super.onDetach()
reduks=null
}
fun onSubmitLogin() {
reduks?.postBusData(LoginFragmentResult("Kotlin","IsAwsome"))
reduks()?.postBusData(LoginFragmentResult("Kotlin","IsAwsome"))
}
}

class LoginDataDisplayFragment : Fragment() {
private var reduks: Reduks<out StateWithBusData>?=null
val busHandlers:MutableList<StoreSubscription> = mutableListOf()

override fun onAttach(context: Context?) {
super.onAttach(context)
reduks=context?.bindReduksFromParentActivity()
reduks?.addBusDataHandler { lfr:LoginFragmentResult? ->
reduks()?.addBusDataHandlerWithTag(tag) { lfr:LoginFragmentResult? ->
if(lfr!=null) {
print("login with username=${lfr.username} and password=${lfr.password} and ")
}
}?.addToList(busHandlers)
}
}

override fun onDetach() {
super.onDetach()
reduks?.removeBusDataHandlers(busHandlers)
reduks=null
reduks()?.removeBusDataHandlersWithTag(tag) //remove all bus data handler attached to this fragment tag
}
}
6 changes: 3 additions & 3 deletions example/counter-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
buildscript {
ext {
kotlin_version = '1.0.6'
android_support_version = '25.0.0'
reduks_version = '2.0.0b11'
android_support_version = '25.1.0'
reduks_version = '2.0.0b12'
}

repositories {
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
classpath 'com.android.tools.build:gradle:2.2.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

// NOTE: Do not place your application dependencies here; they belong
Expand Down
4 changes: 2 additions & 2 deletions example/counter/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ version '1.0-SNAPSHOT'

buildscript {
ext {
kotlin_version = '1.0.5'
reduks_version = '2.0.0b11'
kotlin_version = '1.0.6'
reduks_version = '2.0.0b12'
}

repositories {
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ org.gradle.jvmargs=-Xmx2048M
dcendents_maven_plugin_version=1.4.1

#general libs
kotlin_version=1.0.5
kotlin_version=1.0.6
junit_version=4.12
gson_version=2.8.0
kovenant_version=3.3.0
Expand All @@ -38,7 +38,7 @@ kovenant_version=3.3.0
androidBuildToolsVersion=24.0.2

#android libs
support_version=25.0.0
support_version=25.1.0
robolectric_version=3.1.1

#rx libs
Expand Down
12 changes: 8 additions & 4 deletions reduks-bus/src/main/kotlin/com/beyondeye/reduks/bus/BusStore.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ class BusStore<S: StateWithBusData>(val wrappedStore: Store<S>, reducer: Reducer
override var dispatch: (Any) -> Any
get() = wrappedStore.dispatch
set(value) { wrappedStore.dispatch=value }
fun unsubscribeAllBusDataHandlers() {
fun removeAllBusDataHandlers() {
busDataHandlerSubscriptions.forEach { it.unsubscribe() }
busDataHandlerSubscriptions.clear()
}
private val busDataHandlerSubscriptions:MutableList<StoreSubscription> = mutableListOf()
fun <BusDataType> addBusDataHandler(key:String, fn: (bd: BusDataType) -> Unit): StoreSubscription {
internal val busDataHandlerSubscriptions:MutableList<StoreSubscription> = mutableListOf()
/**
* this function name has _busstore suffix for avoid clash with Store.addBusDataHandler in function inlining
*/
fun <BusDataType> addBusDataHandler_busstore(key:String, fn: (bd: BusDataType) -> Unit): StoreSubscription {
val sub=wrappedStore.subscribe(getStoreSubscriberBuilderForBusDataHandler<S,BusDataType>(key,fn))
busDataHandlerSubscriptions.add(sub!!)
return sub
Expand All @@ -36,4 +39,5 @@ class BusStore<S: StateWithBusData>(val wrappedStore: Store<S>, reducer: Reducer
override fun replaceReducer(reducer: Reducer<S>) {
wrappedStore.replaceReducer(combineReducers(reducer, getBusReducer()))
}
}
}
val <S:StateWithBusData> BusStore<S>.nSubscriptions:Int get()=busDataHandlerSubscriptions.size
Loading

0 comments on commit 68cb949

Please sign in to comment.