This commit is contained in:
tursom 2021-04-11 22:48:14 +08:00
parent c3f421c2f8
commit 781c5fb294
40 changed files with 677 additions and 51 deletions

View File

@ -7,6 +7,9 @@ include("ts-core:ts-pool")
include("ts-core:ts-hash")
include("ts-core:ts-log")
include("ts-core:ts-delegation")
include("ts-core:ts-clone")
include("ts-core:ts-mail")
include("ts-core:ts-coroutine")
include("ts-socket")
//include("web", "aop", "database", "utils", "utils:xml", "utils:async-http", "web:netty-web")
//include("socket", "socket:socket-async")

View File

@ -2,7 +2,6 @@
package cn.tursom.core
import cn.tursom.core.buffer.impl.HeapByteBuffer
import java.io.*
import java.nio.ByteOrder
@ -546,8 +545,6 @@ private val ByteArrayOutputStream_count =
val ByteArrayOutputStream.buf get() = ByteArrayOutputStream_buf.get(this) as ByteArray
val ByteArrayOutputStream.count get() = ByteArrayOutputStream_count.get(this) as Int
fun ByteArray.toByteBuffer() = HeapByteBuffer(this, 0, size)
inline fun <T> Array<T>.forEachIndex(fromIndex: Int, toIndex: Int, action: (T) -> Unit) {
for (i in fromIndex..toIndex) {
action(this[i])

View File

@ -0,0 +1,20 @@
dependencies {
implementation(project(":"))
implementation(project(":utils"))
api project (":utils:xml")
// kotlin 协程
compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
// kotlin 反射
//implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
// OkHttp
//implementation("com.squareup.okhttp3:okhttp:3.14.1")
//implementation group: 'cglib', name: 'cglib', version: '3.3.0'
// https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson
api group : 'com.squareup.retrofit2', name: 'converter-gson', version: '2.9.0'
// https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit
compile group : 'com.squareup.retrofit2', name: 'retrofit', version: '2.9.0'
// https://mvnrepository.com/artifact/org.jsoup/jsoup
api group : 'org.jsoup', name: 'jsoup', version: '1.13.1'
}

View File

@ -4,7 +4,7 @@ plugins {
}
dependencies {
api(project(":"))
api(project(":ts-core"))
}
@kotlin.Suppress("UNCHECKED_CAST")

View File

@ -79,4 +79,8 @@ class HeapByteBuffer(
readPosition = 0
array.fill(byte, arrayOffset, arrayOffset + capacity)
}
companion object {
fun ByteArray.toByteBuffer() = HeapByteBuffer(this, 0, size)
}
}

View File

@ -0,0 +1,32 @@
plugins {
kotlin("jvm")
`maven-publish`
}
dependencies {
api(project(":ts-core"))
api(project(":ts-core:ts-datastruct"))
}
@kotlin.Suppress("UNCHECKED_CAST")
(rootProject.ext["excludeTest"] as (Project, TaskContainer) -> Unit)(project, tasks)
tasks.register("install") {
finalizedBy(tasks["publishToMavenLocal"])
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = project.group.toString()
artifactId = project.name
version = project.version.toString()
from(components["java"])
try {
artifact(tasks["sourcesJar"])
} catch (e: Exception) {
}
}
}
}

View File

@ -1,4 +1,4 @@
package com.ddbes.kotlin.clone
package cn.tursom.core.clone
import kotlin.reflect.KClass

View File

@ -1,4 +1,4 @@
package com.ddbes.kotlin.clone
package cn.tursom.core.clone
import kotlin.reflect.KClass

View File

@ -1,4 +1,4 @@
package com.ddbes.kotlin.clone
package cn.tursom.core.clone
import kotlin.reflect.KClass

View File

@ -1,4 +1,4 @@
package com.ddbes.kotlin.clone
package cn.tursom.core.clone
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)

View File

@ -1,18 +1,14 @@
@file:Suppress("unused")
package cn.tursom.utils.clone
package cn.tursom.core.clone
import cn.tursom.core.Unsafe
import cn.tursom.core.cast
import cn.tursom.core.datastruct.ArrayMap
import cn.tursom.core.datastruct.KPropertyValueMap
import cn.tursom.core.datastruct.ReadWriteMap
import cn.tursom.core.datastruct.SoftArrayMap
import cn.tursom.core.final
import cn.tursom.utils.datastruct.KPropertyValueMap
import com.ddbes.kotlin.clone.Key
import com.ddbes.kotlin.clone.NoPropertyClone
import com.ddbes.kotlin.clone.Relation
import com.ddbes.kotlin.clone.Relations
import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty1
@ -161,7 +157,6 @@ fun <T : Any> List<Any?>.clone(
/**
* 新建并拷贝
* @author 王景阔
* 创建类型 T 的实例
* 并将对象两个的所有同名字段拷贝进新建的实例中
* @return 新建的实例
@ -392,7 +387,8 @@ fun cast(source: Any, target: Class<*>): Any? = if (target.isInstance(source)) {
Boolean::class.java -> if (source is Number) source != 0 else source.toString().toBoolean()
java.lang.Byte::class.java -> if (source is Number) source.toByte() else source.toString().toByteOrNull()
java.lang.Character::class.java -> if (source is Number) source.toChar() else source.toString().toIntOrNull()?.toChar()
java.lang.Character::class.java -> if (source is Number) source.toChar() else source.toString().toIntOrNull()
?.toChar()
java.lang.Short::class.java -> if (source is Number) source.toShort() else source.toString().toShortOrNull()
java.lang.Integer::class.java -> if (source is Number) source.toInt() else source.toString().toIntOrNull()
java.lang.Long::class.java -> if (source is Number) source.toLong() else source.toString().toLongOrNull()

View File

@ -0,0 +1,32 @@
plugins {
kotlin("jvm")
`maven-publish`
}
dependencies {
api(project(":ts-core"))
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
}
@kotlin.Suppress("UNCHECKED_CAST")
(rootProject.ext["excludeTest"] as (Project, TaskContainer) -> Unit)(project, tasks)
tasks.register("install") {
finalizedBy(tasks["publishToMavenLocal"])
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = project.group.toString()
artifactId = project.name
version = project.version.toString()
from(components["java"])
try {
artifact(tasks["sourcesJar"])
} catch (e: Exception) {
}
}
}
}

View File

@ -0,0 +1,11 @@
package cn.tursom.core.coroutine
import kotlinx.coroutines.CoroutineScope
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
class CoroutineContextScope(override val coroutineContext: CoroutineContext) : CoroutineScope {
companion object {
suspend fun get() = CoroutineContextScope(coroutineContext)
}
}

View File

@ -0,0 +1,53 @@
package cn.tursom.core.coroutine
import cn.tursom.core.cast
import cn.tursom.core.toHexString
import kotlinx.coroutines.Job
import java.util.concurrent.ConcurrentHashMap
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
open class CoroutineLocal<T> {
open suspend fun get(): T? {
var attach: MutableMap<CoroutineLocal<*>, Any?>? = coroutineContext[CoroutineLocalContext]
if (attach == null) {
if (injectCoroutineLocalContext()) {
attach = coroutineContext[CoroutineLocalContext]
}
if (attach == null) {
val job = coroutineContext[Job] ?: return null
attach = attachMap[job]
}
}
return attach?.get(this)?.cast()
}
open suspend infix fun set(value: T): Boolean {
var attach: MutableMap<CoroutineLocal<*>, Any?>? = coroutineContext[CoroutineLocalContext]
if (attach == null) {
if (injectCoroutineLocalContext()) {
attach = coroutineContext[CoroutineLocalContext]
}
if (attach == null) {
val job = coroutineContext[Job] ?: return false
attach = attachMap[job]
if (attach == null) {
attach = HashMap()
attachMap[job] = attach
job.invokeOnCompletion {
attachMap.remove(job)
}
}
}
}
attach[this] = value
return true
}
override fun toString(): String = "CoroutineLocal@${hashCode().toHexString(false)}"
companion object {
private val attachMap = ConcurrentHashMap<CoroutineContext, MutableMap<CoroutineLocal<*>, Any?>>()
override fun toString(): String = attachMap.toString()
}
}

View File

@ -0,0 +1,46 @@
package cn.tursom.core.coroutine
import cn.tursom.core.cast
import kotlinx.coroutines.ThreadContextElement
import kotlin.coroutines.CoroutineContext
open class CoroutineLocalContext(
private val mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) }
) : CoroutineContext.Element, ThreadContextElement<MutableMap<CoroutineLocal<*>, Any?>>,
MutableMap<CoroutineLocal<*>, Any?> {
override val key: CoroutineContext.Key<*> get() = Key
private var map: MutableMap<CoroutineLocal<*>, Any?> = mapBuilder()
override fun toString(): String {
return "CoroutineLocalContext$map"
}
companion object Key : CoroutineContext.Key<CoroutineLocalContext>
override fun restoreThreadContext(context: CoroutineContext, oldState: MutableMap<CoroutineLocal<*>, Any?>) {
map = oldState
}
override fun updateThreadContext(context: CoroutineContext): MutableMap<CoroutineLocal<*>, Any?> {
val oldState = map
map = mapBuilder()
return oldState
}
@JvmName("getTyped")
operator fun <T> get(key: CoroutineLocal<T>): T? = map[key].cast()
operator fun <T> set(key: CoroutineLocal<T>, value: T?): T? = map.put(key, value).cast()
override val size: Int get() = map.size
override fun containsKey(key: CoroutineLocal<*>): Boolean = map.containsKey(key)
override fun containsValue(value: Any?): Boolean = map.containsValue(value)
override fun get(key: CoroutineLocal<*>): Any? = map[key]
override fun isEmpty(): Boolean = map.isEmpty()
override val entries: MutableSet<MutableMap.MutableEntry<CoroutineLocal<*>, Any?>> get() = map.entries
override val keys: MutableSet<CoroutineLocal<*>> get() = map.keys
override val values: MutableCollection<Any?> get() = map.values
override fun clear() = map.clear()
override fun put(key: CoroutineLocal<*>, value: Any?): Any? = map.put(key, value)
override fun putAll(from: Map<out CoroutineLocal<*>, Any?>) = map.putAll(from)
override fun remove(key: CoroutineLocal<*>): Any? = map.remove(key)
}

View File

@ -0,0 +1,16 @@
package cn.tursom.core.coroutine
import cn.tursom.core.cast
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
class CoroutineLocalContinuation(
private val completion: Continuation<*>
) : Continuation<Any?> by completion.cast() {
override val context: CoroutineContext = completion.context + if (completion.context[CoroutineLocalContext] == null) {
CoroutineLocalContext()
} else {
EmptyCoroutineContext
}
}

View File

@ -0,0 +1,37 @@
package cn.tursom.core.coroutine
import cn.tursom.core.cast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
class CoroutineScopeContext(
var coroutineScope: CoroutineScope = GlobalScope
) : CoroutineContext.Element {
override val key: CoroutineContext.Key<*> get() = Companion
override fun toString(): String = "CoroutineScopeContext(coroutineScope=$coroutineScope)"
companion object : CoroutineContext.Key<CoroutineScopeContext>, CoroutineLocal<CoroutineScope>() {
override suspend fun get(): CoroutineScope = coroutineContext[this]?.coroutineScope ?: super.get()
?: coroutineContext[Job]?.let {
if (it is CoroutineScope) {
it.cast<CoroutineScope>()
} else {
null
}
} ?: CoroutineContextScope(coroutineContext)
override suspend infix fun set(value: CoroutineScope): Boolean {
val coroutineScopeContext = coroutineContext[this]
return if (coroutineScopeContext != null) {
coroutineScopeContext.coroutineScope = value
true
} else {
super.set(value)
}
}
}
}

View File

@ -0,0 +1,77 @@
package cn.tursom.core.coroutine
import cn.tursom.core.SimpThreadLocal
import cn.tursom.core.cast
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
object CurrentThreadCoroutineScope {
private val eventLoopThreadLocal: SimpThreadLocal<CoroutineDispatcher> = SimpThreadLocal {
newBlockingEventLoop()
}
private suspend fun getCoroutineScope(): CoroutineScope {
val eventLoop = eventLoopThreadLocal.get()
val coroutineScopeContext = CoroutineScopeContext()
val newBlockingCoroutine = newBlockingCoroutine(
coroutineContext + coroutineScopeContext + Dispatchers.Unconfined,
Thread.currentThread(),
eventLoop
)
coroutineScopeContext.coroutineScope = newBlockingCoroutine
return newBlockingCoroutine
}
suspend fun launch(
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
val coroutineScope = getCoroutineScope()
//coroutineScope.launch(start = start, block = block)
coroutineScope.start(start, block = block)
return coroutineScope as Job
}
private val EventLoop = Class.forName("kotlinx.coroutines.EventLoop")
private val EventLoopShouldBeProcessedFromContext = EventLoop.methods
.first { it.name == "shouldBeProcessedFromContext" }
.apply { isAccessible = true }
private val BlockingEventLoop = Class.forName("kotlinx.coroutines.BlockingEventLoop")
private val BlockingEventLoopConstructor = BlockingEventLoop
.getConstructor(Thread::class.java)
.apply { isAccessible = true }
private fun newBlockingEventLoop(thread: Thread = Thread.currentThread()): CoroutineDispatcher {
return BlockingEventLoopConstructor.newInstance(thread) as CoroutineDispatcher
}
private val BlockingCoroutine = Class.forName("kotlinx.coroutines.BlockingCoroutine")
private val BlockingCoroutineConstructor = BlockingCoroutine.constructors[0].apply { isAccessible = true }
private val BlockingCoroutineStart =
BlockingCoroutine.methods.first { it.name == "start" && it.parameters.size == 3 }.apply { isAccessible = true }
private val BlockingCoroutineJoinBlocking =
BlockingCoroutine.methods.first { it.name == "joinBlocking" }.apply { isAccessible = true }
//private val BlockingCoroutineOnCompleted = BlockingCoroutine.methods.first { it.name == "onCompleted" }.apply { isAccessible = true }
private fun newBlockingCoroutine(
coroutineContext: CoroutineContext,
thread: Thread = Thread.currentThread(),
eventLoop: CoroutineDispatcher
): CoroutineScope {
return BlockingCoroutineConstructor.newInstance(coroutineContext, thread, eventLoop).cast()
}
private fun <T> CoroutineScope.start(
start: CoroutineStart = CoroutineStart.DEFAULT,
receiver: CoroutineScope = this,
block: suspend CoroutineScope.() -> T
) {
BlockingCoroutineStart.invoke(this, start, receiver, block)
}
private fun <T> CoroutineScope.joinBlocking(): T {
return BlockingCoroutineJoinBlocking.invoke(this).cast()
}
}

View File

@ -0,0 +1,13 @@
package cn.tursom.core.coroutine
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlinx.coroutines.internal.MainDispatcherFactory
@Suppress("unused")
@InternalCoroutinesApi
class MainCoroutineDispatcherFactory : MainDispatcherFactory {
override val loadPriority: Int = 1
override fun createDispatcher(allFactories: List<MainDispatcherFactory>): MainCoroutineDispatcher = MainDispatcher
}

View File

@ -0,0 +1,51 @@
package cn.tursom.core.coroutine
import cn.tursom.core.cast
import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher
import java.io.Closeable
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.concurrent.thread
import kotlin.coroutines.CoroutineContext
object MainDispatcher : MainCoroutineDispatcher(), Closeable {
private val loaded = AtomicBoolean(false)
private val dispatcher: ExecutorCoroutineDispatcher = Executors.newSingleThreadExecutor {
thread(start = false, block = it::run, name = "MainDispatcher", isDaemon = false)
}.asCoroutineDispatcher()
private var oldDispatcher: MainCoroutineDispatcher? = null
private val mainDispatcherLoader: Class<*> = Class.forName("kotlinx.coroutines.internal.MainDispatcherLoader")
private val dispatcherField: Field = mainDispatcherLoader.getDeclaredField("dispatcher").also { dispatcher ->
dispatcher.isAccessible = true
val mf: Field = Field::class.java.getDeclaredField("modifiers")
mf.isAccessible = true
mf.setInt(dispatcher, dispatcher.modifiers and Modifier.FINAL.inv())
}
fun init() {
if (loaded.compareAndSet(false, true)) {
oldDispatcher = dispatcherField.get(null).cast()
dispatcherField.set(null, this)
}
}
fun resume() {
if (loaded.compareAndSet(true, false) && oldDispatcher != null) {
dispatcherField.set(null, oldDispatcher)
}
}
override val immediate: MainCoroutineDispatcher get() = this
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatcher.dispatch(context, block)
}
override fun close() {
dispatcher.close()
}
}

View File

@ -0,0 +1,234 @@
@file:Suppress("unused")
package cn.tursom.core.coroutine
import cn.tursom.core.cast
import cn.tursom.core.forAllFields
import cn.tursom.core.isInheritanceFrom
import kotlinx.coroutines.*
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.coroutineContext
fun CoroutineScope.launchWithCoroutineLocalContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> Unit
): Job {
return launch(context + CoroutineLocalContext(mapBuilder), start, block)
}
@Suppress("DeferredIsResult")
fun <T> CoroutineScope.asyncWithCoroutineLocalContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> T
): Deferred<T> {
return async(context + CoroutineLocalContext(mapBuilder), start, block)
}
suspend fun <T> withCoroutineLocalContext(
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> T
): T {
return withContext(CoroutineLocalContext(mapBuilder), block)
}
@Throws(InterruptedException::class)
fun <T> runBlockingWithCoroutineLocalContext(
context: CoroutineContext = EmptyCoroutineContext,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> T
): T {
return runBlocking(context + CoroutineLocalContext(mapBuilder), block)
}
fun CoroutineScope.launchWithCoroutineScopeContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
return launch(context + CoroutineScopeContext(this), start, block)
}
@Suppress("DeferredIsResult")
fun <T> CoroutineScope.asyncWithCoroutineScopeContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T> {
return async(context + CoroutineScopeContext(this), start, block)
}
fun CoroutineScope.launchWithCoroutineLocalAndCoroutineScopeContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> Unit
): Job {
return launch(context + CoroutineLocalContext(mapBuilder) + CoroutineScopeContext(this), start, block)
}
@Suppress("DeferredIsResult")
fun <T> CoroutineScope.asyncWithCoroutineLocalAndCoroutineScopeContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> T
): Deferred<T> {
return async(context + CoroutineLocalContext(mapBuilder) + CoroutineScopeContext(this), start, block)
}
@Throws(InterruptedException::class)
fun <T> runBlockingWithCoroutineLocalAndCoroutineScopeContext(
context: CoroutineContext = EmptyCoroutineContext,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> T
): T {
return runBlocking(context + CoroutineLocalContext(mapBuilder) + CoroutineScopeContext()) {
CoroutineScopeContext set this
block()
}
}
fun CoroutineScope.launchWithEnhanceContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> Unit
): Job {
return launch(context + CoroutineLocalContext(mapBuilder), start, block)
}
@Suppress("DeferredIsResult")
fun <T> CoroutineScope.asyncWithEnhanceContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> T
): Deferred<T> {
return async(context + CoroutineLocalContext(mapBuilder), start, block)
}
@Throws(InterruptedException::class)
fun <T> runBlockingWithEnhanceContext(
context: CoroutineContext = EmptyCoroutineContext,
mapBuilder: () -> MutableMap<CoroutineLocal<*>, Any?> = { HashMap(4) },
block: suspend CoroutineScope.() -> T
): T {
return runBlocking(context + CoroutineLocalContext(mapBuilder)) {
block()
}
}
suspend fun <T> runWithCoroutineLocalContext(
block: suspend () -> T
): T {
val continuation: Any? = getContinuation()
val coroutineLocalContinuation = if (continuation is Continuation<*>) {
CoroutineLocalContinuation(continuation.cast())
} else {
return continuation.cast()
}
return (block.cast<(Any?) -> T>()).invoke(coroutineLocalContinuation)
}
suspend fun <T> runWithCoroutineLocal(
block: suspend () -> T
): T {
if (coroutineContext[CoroutineLocalContext] == null) {
return runWithCoroutineLocalContext(block)
}
return block()
}
@Suppress("NOTHING_TO_INLINE")
inline fun getContinuation(continuation: Continuation<*>): Continuation<*> {
return continuation
}
suspend inline fun getContinuation(): Continuation<*> {
val getContinuation: (continuation: Continuation<*>) -> Continuation<*> = ::getContinuation
return (getContinuation.cast<suspend () -> Continuation<*>>()).invoke()
}
suspend fun injectCoroutineContext(
coroutineContext: CoroutineContext,
key: CoroutineContext.Key<out CoroutineContext.Element>? = null
): Boolean {
return if (key == null || coroutineContext[key] == null) {
getContinuation().injectCoroutineContext(coroutineContext, key)
} else {
true
}
}
suspend fun injectCoroutineLocalContext(coroutineLocalContext: CoroutineLocalContext? = null): Boolean {
return if (coroutineContext[CoroutineLocalContext] == null) {
getContinuation().injectCoroutineLocalContext(coroutineLocalContext)
} else {
true
}
}
fun Continuation<*>.injectCoroutineLocalContext(
coroutineLocalContext: CoroutineLocalContext? = null
): Boolean {
return if (context[CoroutineLocalContext] == null) {
injectCoroutineContext(coroutineLocalContext ?: CoroutineLocalContext(), CoroutineLocalContext)
} else {
true
}
}
private val BaseContinuationImpl = Class.forName("kotlin.coroutines.jvm.internal.BaseContinuationImpl")
private val BaseContinuationImplCompletion =
BaseContinuationImpl.getDeclaredField("completion").apply { isAccessible = true }
fun Continuation<*>.injectCoroutineContext(
coroutineContext: CoroutineContext,
key: CoroutineContext.Key<out CoroutineContext.Element>? = null
): Boolean {
if (key != null && context[key] != null) return true
if (BaseContinuationImpl.isInstance(this)) {
BaseContinuationImplCompletion.get(this).cast<Continuation<*>>().injectCoroutineContext(coroutineContext, key)
}
combinedContext(context)
if (context[CoroutineLocalContext] != null) return true
javaClass.forAllFields {
if (!it.type.isInheritanceFrom(CoroutineContext::class.java)) {
return@forAllFields
}
it.isAccessible = true
it.set(this, it.get(this).cast<CoroutineContext>() + coroutineContext)
}
return context[CoroutineLocalContext] != null
}
private val combinedContextClass = Class.forName("kotlin.coroutines.CombinedContext")
private val left = combinedContextClass.getDeclaredField("left").apply { isAccessible = true }
fun combinedContext(coroutineContext: CoroutineContext): Boolean {
if (!combinedContextClass.isInstance(coroutineContext)) return false
if (coroutineContext[CoroutineLocalContext] == null) {
val leftObj = left.get(coroutineContext).cast<CoroutineContext>()
left.set(coroutineContext, leftObj + CoroutineLocalContext())
}
return true
}
//fun CoroutineScope.runOnUiThread(action: suspend CoroutineScope.() -> Unit): Job {
// return launch(Dispatchers.Main, block = action)
//}
suspend fun <T> runOnUiThread(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
action: suspend CoroutineScope.() -> T
): T {
return withContext(coroutineContext + Dispatchers.Main, action)
}

View File

@ -1,6 +1,5 @@
package cn.tursom.utils.datastruct
package cn.tursom.core.datastruct
import cn.tursom.core.datastruct.KPropertyEntriesIterator
import kotlin.reflect.KProperty1
class KPropertyEntries(val target: Any, private val propertyMap: Map<String, KProperty1<Any, *>> = KPropertyValueMap[target]) : Set<Map.Entry<String, Any?>> {

View File

@ -1,6 +1,5 @@
package cn.tursom.utils.datastruct
package cn.tursom.core.datastruct
import cn.tursom.core.datastruct.KPropertyValueCollectionIterator
import kotlin.reflect.KProperty1
class KPropertyValueCollection(val target: Any, private val propertyMap: Map<String, KProperty1<Any, *>> = KPropertyValueMap[target]) : Collection<Any?> {

View File

@ -1,8 +1,6 @@
package cn.tursom.utils.datastruct
package cn.tursom.core.datastruct
import cn.tursom.core.cast
import cn.tursom.core.datastruct.ReadWriteMap
import cn.tursom.core.datastruct.SoftArrayMap
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.memberProperties

View File

@ -1,4 +1,4 @@
package cn.tursom.utils.datastruct
package cn.tursom.core.datastruct
import kotlin.reflect.KClass
import kotlin.reflect.full.memberProperties

View File

@ -0,0 +1,35 @@
plugins {
kotlin("jvm")
`maven-publish`
}
dependencies {
compile(project(":"))
// https://mvnrepository.com/artifact/javax.mail/mail
//compile group: "javax.mail", name: "mail", version: "1.4"
// https://mvnrepository.com/artifact/com.sun.mail/javax.mail
compile(group = "com.sun.mail", name = "javax.mail", version = "1.5.1")
}
@kotlin.Suppress("UNCHECKED_CAST")
(rootProject.ext["excludeTest"] as (Project, TaskContainer) -> Unit)(project, tasks)
tasks.register("install") {
finalizedBy(tasks["publishToMavenLocal"])
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = project.group.toString()
artifactId = project.name
version = project.version.toString()
from(components["java"])
try {
artifact(tasks["sourcesJar"])
} catch (e: Exception) {
}
}
}
}

View File

@ -1,20 +0,0 @@
dependencies {
implementation project(":")
implementation project(":utils")
api project(":utils:xml")
// kotlin
compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
// kotlin
//implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
// OkHttp
//implementation("com.squareup.okhttp3:okhttp:3.14.1")
//implementation group: 'cglib', name: 'cglib', version: '3.3.0'
// https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson
api group: 'com.squareup.retrofit2', name: 'converter-gson', version: '2.9.0'
// https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit
compile group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.9.0'
// https://mvnrepository.com/artifact/org.jsoup/jsoup
api group: 'org.jsoup', name: 'jsoup', version: '1.13.1'
}

View File

@ -1,7 +0,0 @@
dependencies {
compile project(":")
// https://mvnrepository.com/artifact/javax.mail/mail
//compile group: 'javax.mail', name: 'mail', version: '1.4'
// https://mvnrepository.com/artifact/com.sun.mail/javax.mail
compile group: 'com.sun.mail', name: 'javax.mail', version: '1.5.1'
}