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

Moving away from ktlint #29

Merged
merged 6 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ jobs:
echo sonatypeUrl=${SONATYPE_URL} >> ~/.gradle/gradle.properties
echo sonatypeUsername=${SONATYPE_USERNAME} >> ~/.gradle/gradle.properties
cat ~/.gradle/gradle.properties
- name: Run lint checks on library module
run: ./gradlew :lighthouse:ktlintCheck
- name: Run lint checks on entire project
run: ./gradlew ktfmtCheck
- name: Unit test the library module
run: ./gradlew :lighthouse:test
- name: Build release version of library
Expand Down
26 changes: 5 additions & 21 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
plugins {
alias(libs.plugins.ktlint)
alias(libs.plugins.ktfmt)
}

subprojects {
apply(plugin = "org.jlleitschuh.gradle.ktlint")

configure<org.jlleitschuh.gradle.ktlint.KtlintExtension> {
version.set("0.50.0")
debug.set(false)
verbose.set(true)
android.set(true)
outputToConsole.set(true)
outputColorName.set("GREEN")
ignoreFailures.set(false)
enableExperimentalRules.set(false)
disabledRules.set(setOf("max-line-length"))
kotlinScriptAdditionalPaths {
include(fileTree("scripts/"))
}
filter {
exclude("**/generated/**")
include("**/kotlin/**")
}
apply(plugin = "com.ncorti.ktfmt.gradle")
ktfmt {
kotlinLangStyle()
}
}
}
65 changes: 35 additions & 30 deletions demo/src/main/java/com/ivanempire/lighthouse/demo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,28 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)

// Example implementation of a custom logging system
val customLogger = object : LighthouseLogger() {
override fun logStateMessage(tag: String, message: String) {
Log.d(tag, message)
}
val customLogger =
object : LighthouseLogger() {
override fun logStateMessage(tag: String, message: String) {
Log.d(tag, message)
}

override fun logStatusMessage(tag: String, message: String) {
Log.d(tag, message)
}
override fun logStatusMessage(tag: String, message: String) {
Log.d(tag, message)
}

override fun logPacketMessage(tag: String, message: String) {
Log.d(tag, message)
}
override fun logPacketMessage(tag: String, message: String) {
Log.d(tag, message)
}

override fun logErrorMessage(tag: String, message: String, ex: Throwable?) {
Log.e(tag, message, ex)
override fun logErrorMessage(tag: String, message: String, ex: Throwable?) {
Log.e(tag, message, ex)
}
}
}

// Setup the client
lighthouseClient = LighthouseClient
.Builder(this)
.setLogger(customLogger)
.setRetryCount(2)
.build()
lighthouseClient =
LighthouseClient.Builder(this).setLogger(customLogger).setRetryCount(2).build()

// Skips the need for Dagger in a simple demo app
val viewModelFactory = MainActivityViewModelFactory(lighthouseClient)
Expand All @@ -71,9 +69,7 @@ class MainActivity : ComponentActivity() {

Column(modifier = Modifier.padding(16.dp)) {
LazyColumn(
modifier = Modifier
.weight(1f)
.fillMaxWidth(),
modifier = Modifier.weight(1f).fillMaxWidth(),
) {
items(
items = discoveredDeviceList.value,
Expand All @@ -85,17 +81,26 @@ class MainActivity : ComponentActivity() {

val isDiscoveryRunning = remember { mutableStateOf(false) }

Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
Button(onClick = {
viewModel.stopDiscovery()
isDiscoveryRunning.value = false
}, enabled = !isDiscoveryRunning.value) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
Button(
onClick = {
viewModel.stopDiscovery()
isDiscoveryRunning.value = false
},
enabled = !isDiscoveryRunning.value
) {
Text(text = "Stop discovery")
}
Button(onClick = {
viewModel.startDiscovery()
isDiscoveryRunning.value = true
}, enabled = !isDiscoveryRunning.value) {
Button(
onClick = {
viewModel.startDiscovery()
isDiscoveryRunning.value = true
},
enabled = !isDiscoveryRunning.value
) {
Text(text = "Start discovery")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,11 @@ class MainActivityViewModel(
val discoveredDevices = backingDiscoveredDevices.asStateFlow()

fun startDiscovery() {
discoveryJob = viewModelScope.launch {
lighthouseClient.discoverDevices().collect {
backingDiscoveredDevices.value = it
discoveryJob =
viewModelScope.launch {
lighthouseClient.discoverDevices().collect { backingDiscoveredDevices.value = it }
}
}
}

fun stopDiscovery() = runBlocking {
discoveryJob?.cancelAndJoin()
}
fun stopDiscovery() = runBlocking { discoveryJob?.cancelAndJoin() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.ivanempire.lighthouse.LighthouseClient

class MainActivityViewModelFactory(private val lighthouseClient: LighthouseClient) : ViewModelProvider.Factory {
class MainActivityViewModelFactory(private val lighthouseClient: LighthouseClient) :
ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
): T {
return MainActivityViewModel(
lighthouseClient,
) as T
)
as T
}
}
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[versions]
ktfmt = "0.17.0"
gradle = "8.3.0"
maven = "0.26.0"
junit = "4.13.2"
Expand Down Expand Up @@ -32,4 +33,4 @@ mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito-cor
testing-junit = { module = "junit:junit", version.ref = "junit" }

[plugins]
ktlint = "org.jlleitschuh.gradle.ktlint:12.1.0"
ktfmt = { id = "com.ncorti.ktfmt.gradle", version.ref = "ktfmt" }
2 changes: 1 addition & 1 deletion lighthouse/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ dependencies {
testImplementation(libs.mockito.core)
testImplementation(libs.testing.junit)
testImplementation(libs.kotlinx.coroutines.test)
}
}
31 changes: 21 additions & 10 deletions lighthouse/src/main/java/com/ivanempire/lighthouse/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@ import com.ivanempire.lighthouse.models.packets.UniqueServiceName
*
* @param latestComponent The latest ALIVE or BYEBYE packet's parsed [UniqueServiceName] field
*/
internal fun AbridgedMediaDevice.updateEmbeddedComponent(latestComponent: UniqueServiceName): AbridgedMediaDevice {
internal fun AbridgedMediaDevice.updateEmbeddedComponent(
latestComponent: UniqueServiceName
): AbridgedMediaDevice {
return when (latestComponent) {
is EmbeddedDevice -> {
val updatedDeviceList = this.deviceList.filterNot { it.deviceType == latestComponent.deviceType } + latestComponent
val updatedDeviceList =
this.deviceList.filterNot { it.deviceType == latestComponent.deviceType } +
latestComponent
this.copy(deviceList = updatedDeviceList)
}
is EmbeddedService -> {
val updatedServiceList = this.serviceList.filterNot { it.serviceType == latestComponent.serviceType } + latestComponent
val updatedServiceList =
this.serviceList.filterNot { it.serviceType == latestComponent.serviceType } +
latestComponent
this.copy(serviceList = updatedServiceList)
}
else -> this
Expand All @@ -32,14 +38,19 @@ internal fun AbridgedMediaDevice.updateEmbeddedComponent(latestComponent: Unique
*
* @param latestComponent The latest BYEBYE packet's parsed [UniqueServiceName] field
*/
internal fun AbridgedMediaDevice.removeEmbeddedComponent(latestComponent: UniqueServiceName): AbridgedMediaDevice {
internal fun AbridgedMediaDevice.removeEmbeddedComponent(
latestComponent: UniqueServiceName
): AbridgedMediaDevice {
return when (latestComponent) {
is EmbeddedDevice -> this.copy(
deviceList = deviceList.filterNot { it.deviceType == latestComponent.deviceType },
)
is EmbeddedService -> this.copy(
serviceList = serviceList.filterNot { it.serviceType == latestComponent.serviceType },
)
is EmbeddedDevice ->
this.copy(
deviceList = deviceList.filterNot { it.deviceType == latestComponent.deviceType },
)
is EmbeddedService ->
this.copy(
serviceList =
serviceList.filterNot { it.serviceType == latestComponent.serviceType },
)
else -> this
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ import com.ivanempire.lighthouse.models.Constants.DEFAULT_SEARCH_REQUEST
import com.ivanempire.lighthouse.models.devices.AbridgedMediaDevice
import com.ivanempire.lighthouse.models.search.SearchRequest
import com.ivanempire.lighthouse.socket.RealSocketListener
import kotlinx.coroutines.flow.Flow
import java.lang.IllegalStateException
import kotlinx.coroutines.flow.Flow

/**
* The main entrypoint for the Lighthouse library
*/
/** The main entrypoint for the Lighthouse library */
interface LighthouseClient {

/** Builder class for the Lighthouse configuration */
Expand All @@ -24,7 +22,8 @@ interface LighthouseClient {

private var logger: LighthouseLogger? = null

private val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
private val wifiManager =
context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager

/**
* Specify a retry count in the off-chance the network packet is not received by the
Expand All @@ -33,9 +32,7 @@ interface LighthouseClient {
* @param retryCount Number of times to retry sending an SSDP search packet, must be > 0
*/
fun setRetryCount(retryCount: Int) = apply {
assert(retryCount > 0) {
IllegalStateException("Retry count must be greater than 0")
}
assert(retryCount > 0) { IllegalStateException("Retry count must be greater than 0") }
this.retryCount += retryCount
}

Expand All @@ -44,18 +41,17 @@ interface LighthouseClient {
*
* @param logger Custom implementation of [LighthouseLogger]
*/
fun setLogger(logger: LighthouseLogger) = apply {
this.logger = logger
}
fun setLogger(logger: LighthouseLogger) = apply { this.logger = logger }

fun build(): LighthouseClient {
val socketListener = RealSocketListener(wifiManager, retryCount, logger)

val discoveryManager = RealDiscoveryManager(
LighthouseState(logger),
socketListener,
logger,
)
val discoveryManager =
RealDiscoveryManager(
LighthouseState(logger),
socketListener,
logger,
)
return RealLighthouseClient(discoveryManager, logger = logger)
}
}
Expand All @@ -67,5 +63,7 @@ interface LighthouseClient {
* @param searchRequest The [SearchRequest] to send to the multicast group to discover devices
* @return Flow of lists of [AbridgedMediaDevice] that have been discovered on the network
*/
suspend fun discoverDevices(searchRequest: SearchRequest = DEFAULT_SEARCH_REQUEST): Flow<List<AbridgedMediaDevice>>
suspend fun discoverDevices(
searchRequest: SearchRequest = DEFAULT_SEARCH_REQUEST
): Flow<List<AbridgedMediaDevice>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import com.ivanempire.lighthouse.core.LighthouseState
import com.ivanempire.lighthouse.models.packets.MediaPacket
import java.net.DatagramPacket

/**
* Starting point for consumers to implement their own logging systems.
*/
/** Starting point for consumers to implement their own logging systems. */
abstract class LighthouseLogger {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ internal interface DiscoveryManager {
fun createNewDeviceFlow(searchRequest: SearchRequest): Flow<List<AbridgedMediaDevice>>

/**
* Creates a [Flow] of a list of [AbridgedMediaDevice] instances that have not received any
* SSDP packets in the last [AbridgedMediaDevice.cache] seconds. These will be removed from the
* Creates a [Flow] of a list of [AbridgedMediaDevice] instances that have not received any SSDP
* packets in the last [AbridgedMediaDevice.cache] seconds. These will be removed from the
* library's device list when this flow is combined with [createNewDeviceFlow].
*
* @return [Flow] of a list of stale [AbridgedMediaDevice] instances
Expand Down
Loading
Loading