Last active
January 12, 2020 20:38
-
-
Save jbruchanov/0c31298ca85ea156eb7c0b7beaad3cfd to your computer and use it in GitHub Desktop.
Analytics uFramework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.kotlin | |
interface IEventName { | |
val eventName: String | |
} | |
interface IAnalyticsArgsEvent<T> : IEventName | |
interface IAnalyticsMapArgsEvent : IAnalyticsArgsEvent<Map<String, Any>> | |
class AnalyticsArgsEvent<T>(override val eventName: String) : IAnalyticsArgsEvent<T> | |
class AnalyticsMapArgsEvent(override val eventName: String) : IAnalyticsMapArgsEvent | |
interface IAnalyticsAPI { | |
fun track(event: String) | |
} | |
@Suppress("MemberVisibilityCanBePrivate", "CanBeParameter") | |
class EventContext<T>(val event: IAnalyticsArgsEvent<T>, val args: T) { | |
val eventName = event.eventName | |
} | |
interface IAnalyticsRegistry { | |
fun <T> add(event: IAnalyticsArgsEvent<T>, block: (EventContext<T>) -> Unit) { | |
event.invoke(block) | |
} | |
@JvmSynthetic | |
operator fun <T> IAnalyticsArgsEvent<T>.invoke(block: (EventContext<T>) -> Unit) | |
fun track(event: IAnalyticsMapArgsEvent, args: Map<String, Any> = emptyMap()) = | |
//explicit casting to call other track | |
track(event as IAnalyticsArgsEvent<Map<String, Any>>, args) | |
fun <T> track(event: IAnalyticsArgsEvent<T>, args: T) | |
} | |
interface AppDynamicsRegistry : IAnalyticsRegistry { | |
val api: IAnalyticsAPI | |
} | |
sealed class Feature1Events : IEventName { | |
override val eventName: String = this::class.java.name | |
object Event1 : Feature1Events(), IAnalyticsArgsEvent<Int> | |
object Event1A : Feature1Events(), IAnalyticsArgsEvent<Int?> | |
object Event2 : Feature1Events(), IAnalyticsMapArgsEvent | |
} | |
enum class Feature2Events : IAnalyticsMapArgsEvent { | |
E1, E2; | |
override val eventName: String = name | |
} | |
object Feature3Events { | |
val Event1 = AnalyticsArgsEvent<String>("Event1") | |
val Event2 = AnalyticsMapArgsEvent("Event2") | |
val Event3 = AnalyticsArgsEvent<List<String>>("Event3") | |
} | |
interface IAnalyticsImplRegistry : IAnalyticsRegistry { | |
val api: IAnalyticsAPI | |
} | |
fun main() { | |
fun register(registry: IAnalyticsImplRegistry) { | |
registry.apply { | |
val defHandler: ((EventContext<*>) -> Unit) = | |
{ context: EventContext<*> -> println("DH:${context.eventName} args:${context.args}") } | |
Feature2Events.E1 { | |
api.track(it.eventName) | |
} | |
Feature1Events.Event1(defHandler) | |
Feature1Events.Event1A { | |
api.track("${it.eventName} args:${it.args}") | |
} | |
Feature1Events.Event2(defHandler) | |
Feature1Events.Event2 { | |
api.track("${it.eventName} args:${it.args}") | |
} | |
Feature3Events.Event1 { | |
api.track("${it.eventName} args:${it.args}") | |
} | |
Feature3Events.Event1(defHandler) | |
} | |
val tracker = registry | |
tracker.track(Feature2Events.E1) | |
tracker.track(Feature1Events.Event1, 1) | |
tracker.track(Feature1Events.Event1A, null) | |
tracker.track(Feature1Events.Event2) | |
tracker.track(Feature3Events.Event2) | |
} | |
analytics { | |
register(this) | |
} | |
} | |
fun analytics(function: IAnalyticsImplRegistry.() -> Unit): IAnalyticsImplRegistry { | |
val api = object : IAnalyticsAPI { | |
override fun track(event: String) { | |
println(event) | |
} | |
} | |
return AnalyticsRegistry(api).apply(function) | |
} | |
private typealias EventAction = ((EventContext<*>) -> Unit) | |
class AnalyticsRegistry(override val api: IAnalyticsAPI) : IAnalyticsImplRegistry { | |
private val map = mutableMapOf<IAnalyticsArgsEvent<*>, MutableList<EventAction>>() | |
override fun <T> IAnalyticsArgsEvent<T>.invoke(block: (EventContext<T>) -> Unit) { | |
@Suppress("UNCHECKED_CAST") | |
map.getOrPut(this) { mutableListOf() }.add(block as EventAction) | |
} | |
override fun <T> track(event: IAnalyticsArgsEvent<T>, args: T) { | |
map[event]?.forEach { | |
it.invoke(EventContext(event, args)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment