Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Light streamer service and connection to separate module #57

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
5 changes: 2 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'

implementation "com.lightstreamer:ls-android-client:4.2.6"
implementation "com.lightstreamer:ls-log-adapter-java:1.0.2"

implementation "androidx.navigation:navigation-compose:2.5.3"


Expand All @@ -90,6 +87,8 @@ dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'


implementation project(":core:network:light-streamer")
implementation project(":core:common")
// testImplementation "io.mockk:mockk:1.12.4"
// androidTestImplementation "io.mockk:mockk-android:1.12.4"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ data class StockListDto(
val min: Double? = null,
val max: Double? = null,
val ref: Double? = null,
val open: Double? = null,
val open: Double? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import android.util.Log
import com.lightstreamer.client.ItemUpdate
import com.lightstreamer.client.Subscription
import com.lightstreamer.client.SubscriptionListener
import garousi.dev.lightstreamer.connection.LightStreamerConnection
import garousi.dev.lightstreamer.models.SubscriptionMode
import garousi.dev.lightstreamer.service.LightStreamerService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand All @@ -16,15 +18,18 @@ import javax.inject.Inject

class StockListLightStreamerService @Inject constructor(
private val connection: LightStreamerConnection,
private val externalScope: CoroutineScope
) : LightStreamerService<StockListDto> {

private val scope = CoroutineScope(SupervisorJob())
private var dto = StockListDto()
private val _flow: MutableStateFlow<StockListDto> = MutableStateFlow(StockListDto())
override val flow = _flow.asStateFlow()
private val _stockListStream: MutableStateFlow<StockListDto> = MutableStateFlow(StockListDto())
override val stream = _stockListStream.asStateFlow()

init {
connection.connect(serverAddress = serverAddress, adapterSet = adapterSet)
connection.connect(
serverAddress = serverAddress,
adapterSet = adapterSet
)
}

companion object {
Expand Down Expand Up @@ -152,13 +157,13 @@ class StockListLightStreamerService @Inject constructor(
ref = ref,
open = open,
)
scope.launch(Dispatchers.IO) {
_flow.emit(dto)
externalScope.launch(Dispatchers.IO) {
_stockListStream.emit(dto)
}
}

override fun unsubscribe() {
connection.unsubscribe()
scope.cancel()
externalScope.cancel()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerConnection
import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerConnectionImpl
import garousi.dev.lightstreamer.connection.DefaultLightStreamerConnection
import garousi.dev.lightstreamer.connection.LightStreamerConnection
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
abstract class LightStreamerModule {
@Binds
@Singleton
abstract fun bindsLightStreamerService(impl: LightStreamerConnectionImpl): LightStreamerConnection
abstract fun bindsLightStreamerService(impl: DefaultLightStreamerConnection): LightStreamerConnection
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,20 @@
package dev.garousi.stockwatcher.feature.watchlist.di

import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerConnection
import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerService
import dev.garousi.stockwatcher.feature.watchlist.data.StockListDto
import dev.garousi.stockwatcher.feature.watchlist.data.StockListLightStreamerService
import garousi.dev.lightstreamer.service.LightStreamerService
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object WatchlistListModule {
// @Provides
// fun provideGetStockListUseCase(
// repository: StockRepository
// ): GetStockListUseCase {
// return GetStockListUseCase(repository)
// }
//
// @Provides
// fun provideStockListUseCases(
// getStockListUseCase: GetStockListUseCase
// ): StockListUseCases {
// return StockListUseCases(getStockList = getStockListUseCase)
// }

@Provides
interface WatchlistListModule {
@Binds
@Singleton
fun provideStockListLightStreamerService(
connection: LightStreamerConnection,
): LightStreamerService<StockListDto> {
return StockListLightStreamerService(connection = connection)
}
fun bindsStockListLightStreamerService(
impl: StockListLightStreamerService
): LightStreamerService<StockListDto>
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
@file:Suppress("CyclomaticComplexMethod")

package dev.garousi.stockwatcher.feature.watchlist.presentation

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.garousi.stockwatcher.feature.watchlist.data.LightStreamerService
import dev.garousi.stockwatcher.feature.watchlist.data.StockListDto
import garousi.dev.lightstreamer.service.LightStreamerService
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
Expand All @@ -30,41 +28,34 @@ class WatchlistViewModel @Inject constructor(
}

private fun subscribeToDemoAdapterSet() {
stockListLightStreamerService
.subscribe()
.flow
.map { stock ->
_uiState.update { it.copy(isLoading = false) }
stock.itemPos?.let { updatedItemIndex ->
_uiState.update {
it.copy(
stocks = it.stocks.toMutableList().apply {
this[updatedItemIndex - 1] = this[updatedItemIndex - 1].copy(
name = stock.name ?: it.stocks[updatedItemIndex].name,
last = stock.last ?: it.stocks[updatedItemIndex].last,
time = stock.time ?: it.stocks[updatedItemIndex].time,
change = stock.change ?: it.stocks[updatedItemIndex].change,
bidSize = stock.bidSize ?: it.stocks[updatedItemIndex].bidSize,
bid = stock.bid ?: it.stocks[updatedItemIndex].bid,
ask = stock.ask ?: it.stocks[updatedItemIndex].ask,
askSize = stock.askSize ?: it.stocks[updatedItemIndex].askSize,
min = stock.min ?: it.stocks[updatedItemIndex].min,
max = stock.max ?: it.stocks[updatedItemIndex].max,
ref = stock.ref ?: it.stocks[updatedItemIndex].ref,
open = stock.open ?: it.stocks[updatedItemIndex].open,
)
},
)
viewModelScope.launch {
stockListLightStreamerService
.subscribe()
.stream
.collectLatest { stock ->
stock.itemPos?.let { updatedItemIndex ->
_uiState.update {
it.copy(
stocks = it.stocks.toMutableList().apply {
this[updatedItemIndex - 1] = this[updatedItemIndex - 1].copy(
name = stock.name ?: it.stocks[updatedItemIndex].name,
last = stock.last ?: it.stocks[updatedItemIndex].last,
time = stock.time ?: it.stocks[updatedItemIndex].time,
change = stock.change ?: it.stocks[updatedItemIndex].change,
bidSize = stock.bidSize ?: it.stocks[updatedItemIndex].bidSize,
bid = stock.bid ?: it.stocks[updatedItemIndex].bid,
ask = stock.ask ?: it.stocks[updatedItemIndex].ask,
askSize = stock.askSize ?: it.stocks[updatedItemIndex].askSize,
min = stock.min ?: it.stocks[updatedItemIndex].min,
max = stock.max ?: it.stocks[updatedItemIndex].max,
ref = stock.ref ?: it.stocks[updatedItemIndex].ref,
open = stock.open ?: it.stocks[updatedItemIndex].open,
)
}
)
}
}
}
}
.catch { cause: Throwable ->
Log.i("LOGGER", "" + cause.localizedMessage.orEmpty())
}
.stateIn(
scope = viewModelScope,
initialValue = StockListDto(),
started = SharingStarted.Eagerly,
)
}
}
}
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ plugins {
}

subprojects {
apply from: "../buildscripts/ktlint.gradle"
apply from: "../buildscripts/detekt.gradle"
apply from: "../buildscripts/git-hooks.gradle"
apply from: "../buildscripts/versionsplugin.gradle"
apply from: "$rootDir/buildscripts/ktlint.gradle"
apply from: "$rootDir/buildscripts/detekt.gradle"
apply from: "$rootDir/buildscripts/git-hooks.gradle"
apply from: "$rootDir/buildscripts/versionsplugin.gradle"
}
2 changes: 1 addition & 1 deletion config/detekt/detekt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ style:
active: false
includeLineWrapping: false
ForbiddenComment:
active: true
active: false
values:
- 'FIXME:'
- 'STOPSHIP:'
Expand Down
1 change: 1 addition & 0 deletions core/common/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
46 changes: 46 additions & 0 deletions core/common/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'com.google.dagger.hilt.android'
}

android {
namespace 'garousi.dev.common'
compileSdk 33

defaultConfig {
minSdk 23
targetSdk 33

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}

dependencies {

implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

implementation "com.google.dagger:hilt-android:2.44.2"
kapt "com.google.dagger:hilt-compiler:2.44.2"
}
4 changes: 4 additions & 0 deletions core/common/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package garousi.dev.common.di

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@Module
@InstallIn(SingletonComponent::class)
object CoroutinesDispatchersModule {

@DefaultDispatcher
@Provides
fun providesDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default

@IoDispatcher
@Provides
fun providesIoDispatcher(): CoroutineDispatcher = Dispatchers.IO

@MainDispatcher
@Provides
fun providesMainDispatcher(): CoroutineDispatcher = Dispatchers.Main

@MainImmediateDispatcher
@Provides
fun providesMainImmediateDispatcher(): CoroutineDispatcher = Dispatchers.Main.immediate
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package garousi.dev.common.di

import javax.inject.Qualifier

@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class DefaultDispatcher

@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class IoDispatcher

@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class MainDispatcher

@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class MainImmediateDispatcher

@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class ApplicationScope
Loading