Skip to content

Commit

Permalink
Merge pull request #12 from FoxesWorld/modules
Browse files Browse the repository at this point in the history
Modules
  • Loading branch information
AidenF0X authored Feb 11, 2022
2 parents a161429 + d8e0981 commit a848d64
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 0 deletions.
101 changes: 101 additions & 0 deletions src/main/kotlin/ru/foxesworld/foxxey/logging/Logging.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package ru.foxesworld.foxxey.logging

import kotlinx.coroutines.runBlocking
import mu.KLogger
import mu.KotlinLogging
import kotlin.system.measureTimeMillis

/**
* @author vie10
**/

private val log = KotlinLogging.logger { }

fun main() {
runBlocking {
log.wrappedRunWithoutResult("module", "start") {

}
}
}

fun KLogger.debugExceptionAndInfoMessage(exception: Throwable, msg: () -> Any) {
info(msg)
debug(exception, msg)
}

suspend fun KLogger.wrappedRunWithoutResult(
target: Any,
verb: String,
startEnd: String = "ing",
failureEnd: String = "ing",
successEnd: String = "ed",
block: suspend () -> Unit
) {
wrappedRunWithoutResult(
logging = {
onStart = {
info { "${verb.replaceFirstChar { it.uppercase() }}$startEnd $target.." }
}
onFailure = {
debugExceptionAndInfoMessage(it) { "${verb}$failureEnd $target failed." }
}
onSuccess = { measuredMillis, _ ->
info {
"${
target.toString().replaceFirstChar { it.uppercase() }
} ${verb}$successEnd in $measuredMillis millis."
}
}
},
block
)
}

suspend fun wrappedRunWithoutResult(
logging: (LoggingBlock<Unit>.() -> Unit)? = null,
block: suspend () -> Unit
) {
val loggingBlock = if (logging != null) LoggingBlock<Unit>().apply(logging) else null
loggingBlock?.onStart?.invoke()
val result: Result<Unit>
val measuredMillis = measureTimeMillis {
result = runCatching {
block()
}
}

result.onSuccess {
loggingBlock?.onSuccess?.invoke(measuredMillis, it)
}.onFailure {
loggingBlock?.onFailure?.invoke(it)
}
}

suspend fun <T> wrappedRun(
logging: (LoggingBlock<T>.() -> Unit)? = null,
block: suspend () -> T
): Result<T> {
val loggingBlock = if (logging != null) LoggingBlock<T>().apply(logging) else null
loggingBlock?.onStart?.invoke()
val result: Result<T>
val measuredMillis = measureTimeMillis {
result = runCatching {
block()
}
}

result.onSuccess {
loggingBlock?.onSuccess?.invoke(measuredMillis, it)
}.onFailure {
loggingBlock?.onFailure?.invoke(it)
}

return result
}

class LoggingBlock<T>(
var onStart: (() -> Unit)? = null,
var onSuccess: ((measuredMillis: Long, result: T) -> Unit)? = null,
var onFailure: ((exception: Throwable) -> Unit)? = null
)
61 changes: 61 additions & 0 deletions src/main/kotlin/ru/foxesworld/foxxey/modules/BaseModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package ru.foxesworld.foxxey.modules

import mu.KotlinLogging
import org.koin.dsl.module
import ru.foxesworld.foxxey.commands.Command
import ru.foxesworld.foxxey.logging.wrappedRunWithoutResult
import ru.foxesworld.foxxey.modules.Module.Info
import ru.foxesworld.foxxey.modules.Module.State
import org.koin.core.module.Module as KoinModule

private val log = KotlinLogging.logger { }

/**
* @author vie10
**/
abstract class BaseModule(
override val info: Info,
module: (KoinModule.() -> Unit)? = null,
commands: (ArrayList<Command>.() -> Unit)? = null
) : Module {

private val module: KoinModule = module {
module?.run { this() }
}
override val commands: List<Command> = arrayListOf<Command>().apply {
commands?.run { this() }
}
override val state: State
get() = _state
private var _state: State = State.Unloaded

final override suspend fun start() = log.wrappedRunWithoutResult(
target = "module $info",
verb = "start"
) {
onStart()
_state = State.Started
}

protected abstract fun onStart()

final override suspend fun stop() = log.wrappedRunWithoutResult(
target = "module $module",
verb = "stop"
) {
onStop()
_state = State.Stopped
}

protected abstract fun onStop()

final override suspend fun load() {
getKoin().loadModules(listOf(module))
_state = State.Loaded
}

final override suspend fun unload() {
getKoin().unloadModules(listOf(module))
_state = State.Unloaded
}
}
62 changes: 62 additions & 0 deletions src/main/kotlin/ru/foxesworld/foxxey/modules/Module.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package ru.foxesworld.foxxey.modules

import kotlinx.serialization.SerialName
import org.koin.core.component.KoinComponent
import ru.foxesworld.foxxey.commands.Command
import ru.foxesworld.foxxey.config.ConfigInfo

/**
* @author vie10
**/
interface Module : KoinComponent {

val info: Info
val state: State
val commands: List<Command>

suspend fun start()

suspend fun stop()

suspend fun load()

suspend fun unload()

data class Info(
@SerialName("id")
val id: String,
@SerialName("name")
val name: String,
@SerialName("version-code")
val versionCode: String,
@SerialName("version")
val version: String,
@SerialName("dependencies")
val dependencies: Set<Dependency>,
@SerialName("config")
val config: Set<ConfigInfo>
) {

data class Dependency(
@SerialName("id")
val id: String,
@SerialName("version-code")
val versionCode: VersionCode
) {

data class VersionCode(
@SerialName("from")
val from: Int,
@SerialName("to")
val to: Int
)
}
}

enum class State {
Unloaded,
Loaded,
Stopped,
Started
}
}

0 comments on commit a848d64

Please sign in to comment.