mirror of
https://github.com/tursom/TursomServer.git
synced 2024-12-27 13:20:35 +08:00
add FlowGraphic
This commit is contained in:
parent
3610737e47
commit
dcbfaeb033
@ -9,6 +9,7 @@ dependencies {
|
||||
compileOnly("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
|
||||
compileOnly(group = "com.google.code.gson", name = "gson", version = "2.8.6")
|
||||
compileOnly(group = "io.netty", name = "netty-all", version = "4.1.43.Final")
|
||||
testImplementation(group = "junit", name = "junit", version = "4.12")
|
||||
}
|
||||
|
||||
@kotlin.Suppress("UNCHECKED_CAST")
|
||||
|
259
ts-core/src/test/kotlin/FlowExample.kt
Normal file
259
ts-core/src/test/kotlin/FlowExample.kt
Normal file
@ -0,0 +1,259 @@
|
||||
import org.junit.Test
|
||||
|
||||
data class Flow(
|
||||
val source: Edge,
|
||||
val sourceFlowChannel: Int,
|
||||
val targetFlowChannel: Int,
|
||||
val fraction: Int = 0,
|
||||
)
|
||||
|
||||
enum class FlowChannel(val index: Int) {
|
||||
A(0), B(1)
|
||||
}
|
||||
|
||||
class Edge {
|
||||
companion object {
|
||||
val invMap = intArrayOf(1, 0)
|
||||
}
|
||||
|
||||
private val sourceList: ArrayList<Flow> = ArrayList()
|
||||
private val flow: IntArray = IntArray(2)
|
||||
private val flowCache: IntArray = IntArray(2)
|
||||
|
||||
operator fun get(channel: FlowChannel) = flow[channel.index]
|
||||
operator fun set(channel: FlowChannel, value: Int) {
|
||||
flow[channel.index] = value
|
||||
}
|
||||
|
||||
fun addFlow(flow: Flow) {
|
||||
sourceList.add(flow)
|
||||
}
|
||||
|
||||
fun addFlow(vararg flows: Flow) {
|
||||
flows.forEach { flow ->
|
||||
sourceList.add(flow)
|
||||
}
|
||||
}
|
||||
|
||||
fun calc() {
|
||||
flowCache.fill(0)
|
||||
sourceList.forEach { (source, sourceFlowId, targetFlowId, fraction) ->
|
||||
flowCache[targetFlowId] += source.flow[sourceFlowId] shr fraction
|
||||
}
|
||||
}
|
||||
|
||||
fun finishCalc() {
|
||||
repeat(2) { index ->
|
||||
flow[index] = flowCache[index]
|
||||
}
|
||||
}
|
||||
|
||||
fun finishCalc(channel: FlowChannel) {
|
||||
flow[channel.index] = flowCache[channel.index]
|
||||
}
|
||||
|
||||
fun changed(): Boolean {
|
||||
repeat(2) { index ->
|
||||
if (flow[index] != flowCache[index]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Edge(flow=${flow.contentToString()}, flowCache=${flowCache.contentToString()})"
|
||||
}
|
||||
}
|
||||
|
||||
class Graphic(
|
||||
var precision: Int = 8,
|
||||
) : Iterable<Edge> {
|
||||
companion object {
|
||||
inline operator fun invoke(
|
||||
builder: GraphicBuilder.() -> Unit,
|
||||
) = GraphicBuilder().also(builder).build()
|
||||
}
|
||||
|
||||
private val edgeList = ArrayList<Edge>()
|
||||
var input: Int = 0
|
||||
var inputFlowChannel: FlowChannel = FlowChannel.A
|
||||
|
||||
fun addEdge(edge: Edge): Int {
|
||||
edgeList.add(edge)
|
||||
return edgeList.size - 1
|
||||
}
|
||||
|
||||
fun getEdge(id: Int): Edge = edgeList[id]
|
||||
|
||||
fun calc() {
|
||||
edgeList[input][inputFlowChannel] = 1 shl precision
|
||||
edgeList.forEach { edge ->
|
||||
edge.calc()
|
||||
}
|
||||
}
|
||||
|
||||
fun changed(): Boolean {
|
||||
edgeList[input].finishCalc(inputFlowChannel)
|
||||
edgeList.forEach { edge ->
|
||||
if (edge.changed()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun finishCalc() {
|
||||
edgeList.forEach { edge ->
|
||||
edge.finishCalc()
|
||||
}
|
||||
}
|
||||
|
||||
fun result(): List<Pair<Int, Int>> {
|
||||
return edgeList.map { it[FlowChannel.A] to it[FlowChannel.B] }
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<Edge> = edgeList.iterator()
|
||||
|
||||
class GraphicBuilder {
|
||||
var precision: Int = 8
|
||||
val edgeMap = ArrayList<EdgeBuilder>()
|
||||
inline fun edge(builder: EdgeBuilder.() -> Unit) {
|
||||
edgeMap.add(EdgeBuilder(edgeMap.size).also(builder))
|
||||
}
|
||||
|
||||
fun build(): Graphic {
|
||||
val graphic = Graphic(precision)
|
||||
repeat(edgeMap.size) {
|
||||
graphic.addEdge(Edge())
|
||||
}
|
||||
edgeMap.forEach { builder ->
|
||||
builder.init(graphic)
|
||||
}
|
||||
return graphic
|
||||
}
|
||||
}
|
||||
|
||||
class EdgeBuilder(private val id: Int) {
|
||||
private val flowList = ArrayList<FlowBuilder>()
|
||||
fun init(graphic: Graphic) {
|
||||
val edge = graphic.getEdge(id)
|
||||
flowList.forEach { (source, sourceFlowChannel, targetFlowChannel, fraction) ->
|
||||
edge.addFlow(Flow(
|
||||
graphic.getEdge(source),
|
||||
sourceFlowChannel, targetFlowChannel, fraction
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fun flow(
|
||||
source: Int,
|
||||
sourceFlowChannel: Int,
|
||||
targetFlowChannel: Int,
|
||||
fraction: Int = 0,
|
||||
) {
|
||||
flowList.add(FlowBuilder(source, sourceFlowChannel, targetFlowChannel, fraction))
|
||||
}
|
||||
}
|
||||
|
||||
data class FlowBuilder(
|
||||
val source: Int,
|
||||
val sourceFlowChannel: Int,
|
||||
val targetFlowChannel: Int,
|
||||
val fraction: Int = 0,
|
||||
)
|
||||
}
|
||||
|
||||
class FlowExample {
|
||||
@Test
|
||||
fun test() {
|
||||
val graphic = getTestGraphic()
|
||||
graphic.precision = 8
|
||||
|
||||
var changed = true
|
||||
var it = 0
|
||||
while (changed) {
|
||||
it++
|
||||
graphic.calc()
|
||||
changed = graphic.changed()
|
||||
println("step $it changed $changed")
|
||||
graphic.finishCalc()
|
||||
println(graphic.result())
|
||||
}
|
||||
}
|
||||
|
||||
fun getTestGraphic() = Graphic {
|
||||
// 0
|
||||
edge {
|
||||
flow(1, 1, 1, 1)
|
||||
flow(6, 1, 1, 1)
|
||||
}
|
||||
// 1
|
||||
edge {
|
||||
flow(0, 0, 0, 1)
|
||||
flow(6, 1, 0, 1)
|
||||
flow(7, 1, 1, 1)
|
||||
flow(2, 1, 1, 1)
|
||||
}
|
||||
// 2
|
||||
edge {
|
||||
flow(1, 0, 0, 1)
|
||||
flow(7, 1, 0, 1)
|
||||
flow(8, 1, 1, 1)
|
||||
flow(3, 1, 1, 1)
|
||||
}
|
||||
// 3
|
||||
edge {
|
||||
flow(1, 0, 0, 1)
|
||||
flow(8, 1, 0, 1)
|
||||
flow(9, 1, 1, 1)
|
||||
flow(4, 0, 1, 1)
|
||||
}
|
||||
// 4
|
||||
edge {
|
||||
flow(5, 0, 0, 1)
|
||||
flow(10, 1, 0, 1)
|
||||
flow(3, 0, 1, 1)
|
||||
flow(9, 1, 1, 1)
|
||||
}
|
||||
// 5
|
||||
edge {
|
||||
flow(6, 0, 0, 1)
|
||||
flow(11, 1, 0, 1)
|
||||
flow(4, 1, 1, 1)
|
||||
flow(0, 1, 1, 1)
|
||||
}
|
||||
// 6
|
||||
edge {
|
||||
flow(0, 0, 0, 1)
|
||||
flow(1, 1, 0, 1)
|
||||
flow(5, 1, 1, 1)
|
||||
flow(11, 1, 1, 1)
|
||||
}
|
||||
// 7
|
||||
edge {
|
||||
flow(1, 0, 0, 1)
|
||||
flow(2, 1, 0, 1)
|
||||
}
|
||||
// 8
|
||||
edge {
|
||||
flow(2, 0, 0, 1)
|
||||
flow(3, 1, 0, 1)
|
||||
}
|
||||
// 9
|
||||
edge {
|
||||
flow(3, 0, 0, 1)
|
||||
flow(4, 0, 0, 1)
|
||||
}
|
||||
// 10
|
||||
edge {
|
||||
flow(5, 0, 0, 1)
|
||||
flow(4, 1, 0, 1)
|
||||
}
|
||||
// 11
|
||||
edge {
|
||||
flow(6, 0, 0, 1)
|
||||
flow(5, 1, 0, 1)
|
||||
}
|
||||
}
|
||||
}
|
@ -218,7 +218,7 @@ open class WebSocketClient<in T : WebSocketClient<T, H>, H : WebSocketHandler<T,
|
||||
|
||||
companion object {
|
||||
private val threadId = AtomicInteger()
|
||||
private val group: EventLoopGroup = NioEventLoopGroup(0, ThreadFactory {
|
||||
val group: EventLoopGroup = NioEventLoopGroup(0, ThreadFactory {
|
||||
val thread = Thread(it, "WebSocketClient-${threadId.incrementAndGet()}")
|
||||
thread.isDaemon = true
|
||||
thread
|
||||
|
Loading…
Reference in New Issue
Block a user