Skip to content

Instantly share code, notes, and snippets.

@Greenddoovie
Last active August 3, 2021 18:18
Show Gist options
  • Save Greenddoovie/83e7c5c7a0cca59da45b07796ae9f426 to your computer and use it in GitHub Desktop.
Save Greenddoovie/83e7c5c7a0cca59da45b07796ae9f426 to your computer and use it in GitHub Desktop.
d12_K057
import kotlinx.coroutines.*
suspend fun main() {
val pub1 = Publisher("albumModel")
val pub2 = Publisher("albumView")
val pub3 = Publisher("albumController")
val sub1 = Subscriber("subscriberA", "ModelDataChanged", pub1)
val sub2 = Subscriber("subscriberB", "", pub2)
val sub3 = Subscriber("subscriberC", "DidShakeMotion", pub3)
val sub4 = Subscriber("subscriberC", "AllDataChanged", null)
val sub5 = Subscriber("subscriberD", "", null)
println(sub1.toString())
println(sub2.toString())
println(sub3.toString())
println(sub4.toString())
println(sub5.toString())
println()
sub1.subScribe()
sub2.subScribe()
sub3.subScribe()
sub4.subScribe()
sub5.subScribe()
sub1.setMainTrue()
pub1.notify("ModelDataChanged", hashMapOf(Pair("data", "abc")), "sync")
pub2.notify("viewUpdated", hashMapOf(Pair("view", "xxx")),"sync")
pub3.notify("DidShakeMotion", hashMapOf(Pair("from", "blue")), "async")
val testHM = HashMap<String?, String?>()
testHM[null] = null
Publisher(null).notify("AllDataChanged", testHM, "delay")
}
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import java.time.LocalDateTime
import kotlin.collections.HashMap
class Publisher (private val name: String?) {
private val center = PublisherCenter
suspend fun notify(eventName : String, data: HashMap<String?, String?>, type : String) {
when (type) {
"sync" -> {
println("notify $eventName event from $name /// startTime : ${LocalDateTime.now()}")
center.syncQ.add(Event(eventName, this, data))
CoroutineScope(Dispatchers.Unconfined).launch {
center.postEvent(type)
}
}
"async" -> {
println("notify $eventName event from $name /// startTime : ${LocalDateTime.now()}")
center.asyncQ.add(Event(eventName, this, data))
CoroutineScope(Dispatchers.Unconfined).async {
center.postEvent(type)
}.await()
}
"delay" -> {
println("notify $eventName event from $name /// startTime : ${LocalDateTime.now()}")
center.delayQ.add(Event(eventName, this, data))
CoroutineScope(Dispatchers.Unconfined).async {
center.postEvent(type)
}.await()
}else -> {
}
}
}
fun getName() : String {
return name?: "dummy"
}
override fun toString(): String {
return name?: "dummy"
}
}
data class Event(val eventName: String, val publisher: Publisher?, val data: HashMap<String?, String?>)
import java.util.*
import kotlin.collections.HashMap
import kotlinx.coroutines.*
object PublisherCenter {
// 키값으로 이벤트 네임과 이벤트 발행객체를 넣고 값으로 서브스크라이버를 갖는 자료구조
val hashMap = HashMap<Pair<Publisher?, String>, MutableList<Subscriber>>()
val syncQ = LinkedList<Event>()
val asyncQ = LinkedList<Event>()
val delayQ = LinkedList<Event>() //
suspend fun postEvent(type : String) {
when (type) {
"sync" -> {
val event = syncQ.poll()
val key =hashMap.keys.filter{
pair -> (pair.first ==event.publisher && pair.second == event.eventName) //eventName, publisher 가 일치하는 경우
|| (pair.first ==null && pair.second == event.eventName) //eventName 이 일치하는 경우
|| (pair.first ==event.publisher && pair.second == "") //sender 가 일치하는 경우
|| (pair.first ==null && pair.second == "") } // 모두 받는 경우
runBlocking {
launch {
for (k in key) {
for (l in hashMap[k]!!) {
l.handler(event.publisher, event.eventName, event.data)
}
}
}.join()
}
}
"async" -> {
val event = asyncQ.poll()
val key =hashMap.keys.filter{
pair -> (pair.first ==event.publisher && pair.second == event.eventName) //eventName, publisher 가 일치하는 경우
|| (pair.first ==null && pair.second == event.eventName) //eventName 이 일치하는 경우
|| (pair.first ==event.publisher && pair.second == "") //sender 가 일치하는 경우
|| (pair.first ==null && pair.second == "") } // 모두 받는 경우
CoroutineScope(Dispatchers.Default).async {
for (k in key) {
for (l in hashMap[k]!!) {
l.handler(event.publisher, event.eventName, event.data)
}
}
}
}
"delay" -> {
val event = delayQ.poll()
val key =hashMap.keys.filter{
pair -> (pair.first ==event.publisher && pair.second == event.eventName) //eventName, publisher 가 일치하는 경우
|| (pair.first ==null && pair.second == event.eventName) //eventName 이 일치하는 경우
|| (pair.first ==event.publisher && pair.second == "") //sender 가 일치하는 경우
|| (pair.first ==null && pair.second == "") } // 모두 받는 경우
CoroutineScope(Dispatchers.Default).async(Dispatchers.Default) {
delay(10000)
for (k in key) {
for (l in hashMap[k]!!) {
l.handler(event.publisher, event.eventName, event.data)
}
}
}.await()
}else -> {Event("", null, hashMapOf(Pair("dummy", "dummy")))}
}
}
fun addSubscribe(subscriber: Subscriber, sender: Publisher?, eventName: String) {
runBlocking {
launch {
if (hashMap[Pair(sender, eventName)] == null) {
hashMap[Pair(sender, eventName)] = mutableListOf(subscriber)
}else {
hashMap[Pair(sender, eventName)]!!.add(subscriber)
}
}
}
}
fun unSubscribe(subscriber: Subscriber, sender: Publisher?, eventName: String) {
hashMap[Pair(sender, eventName)]!!.remove(subscriber)
}
}
import kotlinx.coroutines.*
import java.time.LocalDateTime
import kotlin.collections.HashMap
class Subscriber(private val name : String, private val eventName: String, private val sender: Publisher?){
val center = PublisherCenter
var mainOrNot = false
fun setMainTrue() {
mainOrNot = true
}
fun subScribe() {
center.addSubscribe(this, sender, eventName)
}
fun unSubscribe() {
//publisherCenter 이정보가 저장이 되도록 한다
center.unSubscribe(this, sender, eventName)
}
fun handler(sender : Publisher?, eventName : String, data : HashMap<String?, String?>) {
if (mainOrNot) {
var senderName = sender?.getName() ?: "dummy"
var hmData = ""
for ((k,v) in data) {
val key = k?: ""
val value = v?: ""
hmData += "\"$key\":\"$value\", "
}
println("$name: $eventName event from $senderName userInfo = [${hmData.substring(0, hmData.lastIndex-1)}] ${Thread.currentThread().name} " )
println("$name after handling time : ${LocalDateTime.now()}")
println()
}else {
CoroutineScope(Dispatchers.Default).async {
var senderName = sender?.getName() ?: "dummy"
var hmData = ""
for ((k,v) in data) {
val key = k?: ""
val value = v?: ""
hmData += "\"$key\":\"$value\", "
}
println("$name: $eventName event from $senderName userInfo = [${hmData.substring(0, hmData.lastIndex-1)}] ")
println("$name after handling time : ${LocalDateTime.now()}")
println()
}
}
}
override fun toString(): String {
var senderName = sender?.getName() ?: "nil"
return "$name : event name = \"$eventName\", sender = $senderName"
}
}
@Greenddoovie
Copy link
Author

image

@Greenddoovie
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment