Compare commits

..

27 Commits

Author SHA1 Message Date
5a31a5566c Update gradle.properties 2022-02-02 13:44:10 +06:00
fecbfc4130 update publish.gradle 2022-01-04 23:20:02 +06:00
bf3c4bc11f Merge pull request #10 from InsanusMokrassar/0.0.15
0.0.15
2022-01-04 22:58:37 +06:00
2ef2d60213 update publish scripts 2022-01-04 22:55:14 +06:00
a1c2e48622 potential fix for build issues 2022-01-04 19:33:47 +06:00
ffdf808a89 update workflow 2022-01-04 19:26:06 +06:00
ef8bc50bd9 ignore kotlin-js-store 2022-01-04 19:21:53 +06:00
df5dea4915 remove kotlin-js-store 2022-01-04 19:16:01 +06:00
989f3af9db actualization 2022-01-04 19:10:38 +06:00
4c0cdc8d1e Update gradle.properties 2022-01-04 18:58:27 +06:00
ce132cb4e7 0.0.14 2021-11-12 18:15:42 +06:00
c519881800 update publishing scripts 2021-11-12 17:15:36 +06:00
17d7fe6659 Merge pull request #9 from InsanusMokrassar/0.0.13
0.0.13
2021-11-12 17:00:35 +06:00
63af9ba8e0 0.13.0 2021-11-12 14:35:36 +06:00
b5d0eda79d start 0.0.13 2021-11-12 13:36:43 +06:00
5d32bf567c Update mppProjectWithSerialization.gradle 2021-09-23 13:19:27 +06:00
0444d5fe8d Update mppJavaProject.gradle 2021-09-23 13:19:14 +06:00
ea18b23a2c Merge pull request #8 from InsanusMokrassar/0.0.12
0.0.12
2021-09-22 23:51:14 +06:00
271d094f10 Update commit-publish.yml 2021-09-22 22:47:00 +06:00
4335e6e1cd Update gradle.properties 2021-09-22 20:44:10 +06:00
d2d7578be4 start 0.0.12 2021-09-22 20:40:56 +06:00
2105fa5718 Merge pull request #7 from InsanusMokrassar/0.0.11
0.0.11
2021-07-03 14:04:26 +06:00
165a3a9856 Update gradle-wrapper.properties 2021-07-03 13:55:18 +06:00
f811968b05 Update build.gradle 2021-07-03 13:54:59 +06:00
c2e3b49786 Update gradle.properties 2021-07-03 13:54:21 +06:00
6d813ef142 update dependencies 2021-07-02 18:44:54 +06:00
9083b888c6 Update gradle.properties 2021-07-02 18:43:48 +06:00
23 changed files with 68 additions and 333 deletions

View File

@@ -7,7 +7,10 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 1.8
java-version: 11
- name: Fix android 32.0.0 dx
continue-on-error: true
run: cd /usr/local/lib/android/sdk/build-tools/32.0.0/ && mv d8 dx && cd lib && mv d8.jar dx.jar
- name: Update version
run: |
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"

1
.gitignore vendored
View File

@@ -11,5 +11,6 @@ out/
secret.gradle
local.properties
kotlin-js-store/
publishing.sh

View File

@@ -1,6 +1,5 @@
buildscript {
repositories {
jcenter()
google()
mavenCentral()
mavenLocal()
@@ -8,7 +7,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
classpath 'com.android.tools.build:gradle:7.0.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:$dexcount_version"
@@ -19,10 +18,8 @@ buildscript {
allprojects {
repositories {
mavenLocal()
jcenter()
mavenCentral()
google()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
}

View File

@@ -51,12 +51,12 @@ class DefaultAdminsCacheAPIRepo(
}
override suspend fun getChatAdmins(chatId: ChatId): List<AdministratorChatMember>? = suspendCoroutine {
actor.offer(GetChatAdminsRepoAction(chatId, it))
actor.trySend(GetChatAdminsRepoAction(chatId, it))
}
override suspend fun setChatAdmins(chatId: ChatId, chatMembers: List<AdministratorChatMember>) = suspendCoroutine<Unit> {
actor.offer(SetChatAdminsRepoAction(chatId, chatMembers, it))
actor.trySend(SetChatAdminsRepoAction(chatId, chatMembers, it))
}
override suspend fun lastUpdate(chatId: ChatId): DateTime? = suspendCoroutine {
actor.offer(GetUpdateDateTimeRepoAction(chatId, it))
actor.trySend(GetUpdateDateTimeRepoAction(chatId, it))
}
}

View File

@@ -1,17 +0,0 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api "dev.inmo:micro_utils.coroutines:$micro_utils_version"
}
}
}
}

View File

@@ -1,17 +0,0 @@
package dev.inmo.tgbotapi.libraries.fsm.core
sealed interface State {
val context: Any
}
/**
* Use this state as parent of your state in case you want to avoid saving of this state in queue for [context] if this
* queue is not empty
*/
interface ImmediateOrNeverState : State
/**
* Use this state as parent of your state in case you want to keep saving of this state in queue for [context] if this
* queue is not empty
*/
interface QueueableState : State

View File

@@ -1,15 +0,0 @@
package dev.inmo.tgbotapi.libraries.fsm.core
import kotlin.reflect.KClass
class StateHandlerHolder<I : State>(
private val inputKlass: KClass<I>,
private val strict: Boolean = false,
private val delegateTo: StatesHandler<I>
) : StatesHandler<State> {
fun checkHandleable(state: State) = state::class == inputKlass || (!strict && inputKlass.isInstance(state))
override suspend fun StatesMachine.handleState(state: State): State? {
return delegateTo.run { handleState(state as I) }
}
}

View File

@@ -1,5 +0,0 @@
package dev.inmo.tgbotapi.libraries.fsm.core
fun interface StatesHandler<I : State> {
suspend fun StatesMachine.handleState(state: I): State?
}

View File

@@ -1,46 +0,0 @@
package dev.inmo.tgbotapi.libraries.fsm.core
import dev.inmo.micro_utils.coroutines.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.asFlow
private suspend fun <I : State> StatesMachine.launchStateHandling(
state: State,
handlers: List<StateHandlerHolder<out I>>
): State? {
return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
handleState(state)
}
}
class StatesMachine (
private val statesManager: StatesManager,
private val handlers: List<StateHandlerHolder<*>>
) : StatesHandler<State> {
override suspend fun StatesMachine.handleState(state: State): State? = launchStateHandling(state, handlers)
fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
val statePerformer: suspend (State) -> Unit = { state: State ->
val newState = launchStateHandling(state, handlers)
if (newState != null) {
statesManager.update(state, newState)
} else {
statesManager.endChain(state)
}
}
statesManager.onStartChain.subscribeSafelyWithoutExceptions(this) {
launch { statePerformer(it) }
}
statesManager.onChainStateUpdated.subscribeSafelyWithoutExceptions(this) {
launch { statePerformer(it.second) }
}
statesManager.getActiveStates().forEach {
launch { statePerformer(it) }
}
}
suspend fun startChain(state: State) {
statesManager.startChain(state)
}
}

View File

@@ -1,92 +0,0 @@
package dev.inmo.tgbotapi.libraries.fsm.core
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
interface StatesManager {
val onChainStateUpdated: Flow<Pair<State, State>>
val onStartChain: Flow<State>
val onEndChain: Flow<State>
/**
* Must set current set using [State.context]
*/
suspend fun update(old: State, new: State)
/**
* Starts chain with [state] as first [State]. May returns false in case of [State.context] of [state] is already
* busy by the other [State]
*/
suspend fun startChain(state: State)
/**
* Ends chain with context from [state]. In case when [State.context] of [state] is absent, [state] should be just
* ignored
*/
suspend fun endChain(state: State)
suspend fun getActiveStates(): List<State>
}
/**
* @param onContextsConflictResolver Receive old [State], new one and the state currently placed on new [State.context]
* key. In case when this callback will returns true, the state placed on [State.context] of new will be replaced by
* new state by using [endChain] with that state
*/
class InMemoryStatesManager(
private val onContextsConflictResolver: suspend (old: State, new: State, currentNew: State) -> Boolean = { _, _, _ -> true }
) : StatesManager {
private val _onChainStateUpdated = MutableSharedFlow<Pair<State, State>>(0)
override val onChainStateUpdated: Flow<Pair<State, State>> = _onChainStateUpdated.asSharedFlow()
private val _onStartChain = MutableSharedFlow<State>(0)
override val onStartChain: Flow<State> = _onStartChain.asSharedFlow()
private val _onEndChain = MutableSharedFlow<State>(0)
override val onEndChain: Flow<State> = _onEndChain.asSharedFlow()
private val contextsToStates = mutableMapOf<Any, State>()
private val mapMutex = Mutex()
override suspend fun update(old: State, new: State) = mapMutex.withLock {
when {
contextsToStates[old.context] != old -> return@withLock
old.context == new.context || !contextsToStates.containsKey(new.context) -> {
contextsToStates[old.context] = new
_onChainStateUpdated.emit(old to new)
}
else -> {
val stateOnNewOneContext = contextsToStates.getValue(new.context)
if (onContextsConflictResolver(old, new, stateOnNewOneContext)) {
endChainWithoutLock(stateOnNewOneContext)
contextsToStates.remove(old.context)
contextsToStates[new.context] = new
_onChainStateUpdated.emit(old to new)
}
}
}
}
override suspend fun startChain(state: State) = mapMutex.withLock {
if (!contextsToStates.containsKey(state.context)) {
contextsToStates[state.context] = state
_onStartChain.emit(state)
}
}
private suspend fun endChainWithoutLock(state: State) {
if (contextsToStates[state.context] == state) {
contextsToStates.remove(state.context)
_onEndChain.emit(state)
}
}
override suspend fun endChain(state: State) {
mapMutex.withLock {
endChainWithoutLock(state)
}
}
override suspend fun getActiveStates(): List<State> = contextsToStates.values.toList()
}

View File

@@ -1,35 +0,0 @@
package dev.inmo.tgbotapi.libraries.fsm.core.dsl
import dev.inmo.tgbotapi.libraries.fsm.core.*
import kotlin.reflect.KClass
class FSMBuilder(
var statesManager: StatesManager = InMemoryStatesManager()
) {
private var states = mutableListOf<StateHandlerHolder<*>>()
fun <I : State> add(kClass: KClass<I>, handler: StatesHandler<I>) {
states.add(StateHandlerHolder(kClass, false, handler))
}
fun <I : State> addStrict(kClass: KClass<I>, handler: StatesHandler<I>) {
states.add(StateHandlerHolder(kClass, true, handler))
}
fun build() = StatesMachine(
statesManager,
states.toList()
)
}
inline fun <reified I : State> FSMBuilder.onStateOrSubstate(handler: StatesHandler<I>) {
add(I::class, handler)
}
inline fun <reified I : State> FSMBuilder.strictlyOn(handler: StatesHandler<I>) {
addStrict(I::class, handler)
}
fun buildFSM(
block: FSMBuilder.() -> Unit
): StatesMachine = FSMBuilder().apply(block).build()

View File

@@ -1,54 +0,0 @@
import dev.inmo.tgbotapi.libraries.fsm.core.*
import dev.inmo.tgbotapi.libraries.fsm.core.dsl.buildFSM
import dev.inmo.tgbotapi.libraries.fsm.core.dsl.strictlyOn
import kotlinx.coroutines.*
import kotlin.random.Random
import kotlin.test.Test
sealed interface TrafficLightState : ImmediateOrNeverState {
val trafficLightNumber: Int
override val context: Int
get() = trafficLightNumber
}
data class GreenCommon(override val trafficLightNumber: Int) : TrafficLightState
data class YellowCommon(override val trafficLightNumber: Int) : TrafficLightState
data class RedCommon(override val trafficLightNumber: Int) : TrafficLightState
class PlayableMain {
fun test() {
runBlocking {
val countOfTrafficLights = 10
val initialStates = (0 until countOfTrafficLights).map {
when (0/*Random.nextInt(3)*/) {
0 -> GreenCommon(it)
1 -> YellowCommon(it)
else -> RedCommon(it)
}
}
val statesManager = InMemoryStatesManager()
val machine = buildFSM {
strictlyOn<GreenCommon> {
delay(1000L)
YellowCommon(it.context).also(::println)
}
strictlyOn<YellowCommon> {
delay(1000L)
RedCommon(it.context).also(::println)
}
strictlyOn<RedCommon> {
delay(1000L)
GreenCommon(it.context).also(::println)
}
this.statesManager = statesManager
}
initialStates.forEach { machine.startChain(it) }
val scope = CoroutineScope(Dispatchers.Default)
machine.start(scope).join()
}
}
}

View File

@@ -1 +0,0 @@
<manifest package="dev.inmo.tgbotapi.libraries.fsm.core"/>

View File

@@ -1,17 +0,0 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":tgbotapi.libraries.fsm.core")
}
}
}
}

View File

@@ -1 +0,0 @@
<manifest package="dev.inmo.tgbotapi.libraries.fsm.tgbotapi"/>

View File

@@ -6,33 +6,32 @@ kotlin.incremental.js=true
android.useAndroidX=true
android.enableJetifier=true
kotlin_version=1.5.10
kotlin_serialisation_core_version=1.2.1
kotlin_coroutines_version=1.5.0
kotlin_version=1.6.10
kotlin_serialisation_core_version=1.3.2
github_release_plugin_version=2.2.12
tgbotapi_version=0.35.0
micro_utils_version=0.5.12
exposed_version=0.32.1
plagubot_version=0.3.0
tgbotapi_version=0.38.4
micro_utils_version=0.9.5
exposed_version=0.37.2
plagubot_version=0.5.1
# ANDROID
android_minSdkVersion=21
android_compileSdkVersion=30
android_buildToolsVersion=30.0.3
dexcount_version=2.0.0
android_compileSdkVersion=32
android_buildToolsVersion=32.0.0
dexcount_version=3.0.1
junit_version=4.12
test_ext_junit_version=1.1.2
espresso_core=3.3.0
# Dokka
dokka_version=1.4.32
dokka_version=1.6.10
# Project data
group=dev.inmo
version=0.0.10
android_code_version=9
version=0.0.16
android_code_version=16

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -28,3 +28,8 @@ kotlin {
}
}
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

View File

@@ -47,4 +47,9 @@ kotlin {
}
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
apply from: "$defaultAndroidSettingsPresetPath"

View File

@@ -38,14 +38,42 @@ publishing {
}
}
repositories {
maven {
name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotApiLibraries")
credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
maven {
name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/TelegramBotApiLibraries")
credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
}
}
}
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
}
}
}
}
}
}
if (project.hasProperty("signing.gnupg.keyName")) {
apply plugin: 'signing'
signing {
useGpgCmd()
sign publishing.publications
}
task signAll {
tasks.withType(Sign).forEach {
dependsOn(it)
}
}
}

1
publish.kpsb Normal file
View File

@@ -0,0 +1 @@
{"licenses":[{"id":"MIT","title":"MIT License","url":"https://opensource.org/licenses/MIT"}],"mavenConfig":{"name":"${project.name}","description":"${project.name}","url":"https://github.com/InsanusMokrassar/TelegramBotApiLibraries","vcsUrl":"https://github.com/InsanusMokrassar/TelegramBotApiLibraries.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotApiLibraries"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}

View File

@@ -1 +0,0 @@
{"licenses":[{"id":"MIT","title":"MIT License","url":"https://opensource.org/licenses/MIT"}],"mavenConfig":{"name":"${project.name}","description":"${project.name}","url":"https://github.com/InsanusMokrassar/TelegramBotApiLibraries","vcsUrl":"https://github.com/InsanusMokrassar/TelegramBotApiLibraries.git","includeGpgSigning":false,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/TelegramBotApiLibraries"}]}}

View File

@@ -4,10 +4,7 @@ String[] includes = [
":cache:admins:common",
":cache:admins:micro_utils",
":cache:admins:plagubot",
":cache:media",
":fsm:core",
":fsm:tgbotapi"
":cache:media"
]