Ayfri
02/14/2022, 10:21 PMeventemitter3
library with a pretty ugly (I think) but simple solution
sealed interface DisplayObjectEvents<T : Any> {
object added : DisplayObjectEvents<Container>
object click : DisplayObjectEvents<FederatedPointerEvent>
object clickcapture : DisplayObjectEvents<FederatedPointerEvent>
object destroyed : DisplayObjectEvents<Nothing>
object mousedown : DisplayObjectEvents<FederatedPointerEvent>
...
(there are almost 100 elements in total)
}
But I want to be able to use it like that myObject.on<DisplayObjectEvents.added> { // it is Container here }
, so I created this
inline fun <reified T : DisplayObjectEvents<T>> DisplayObject.on(noinline callback: (T) -> Unit) = on(T::class.simpleName!!, callback as ListenerFn, null)
// ListenerFn is just a function type that take Any arguments Any number of time
// Which is the default type for my library for events in TypeScript
But
myObject.on<DisplayObject.added> {
// it is of type DisplayObject.added
}
What I've done wrong ?Ayfri
02/14/2022, 10:24 PMinline fun <T : Any> DisplayObject.on(event: DisplayObjectEvents<T>, noinline callback: (T) -> Unit) = on(event::class.simpleName!!, callback as ListenerFn, null)
myObject.on(DisplayObjectEvents.added) {
// it is correctly of type Container
}
Ruckus
02/14/2022, 10:33 PMreified T : DisplayObjectEvents<T>
means that T
needs to be both a DisplayObjectEvents
as well as its generic parameter. You could either pass in a parameter (as you've done) or have two generic types.Ruckus
02/14/2022, 10:41 PMon<DisplayObjectEvents.added>
, since added
has a generic of Container
which does not fit the restriction T : DisplayObjectEvents<T>
.Ruckus
02/14/2022, 10:45 PMinline fun <reified D : DisplayObjectEvents<T>, T : Any> DisplayObject.on(noinline callback: (T) -> Unit) = on(D::class.simpleName!!, callback as ListenerFn, null)
And used like
obj.on<DisplayObjectEvents.added, Container> { ... }
But I personally think the extra parameter version you have is cleaner.Ayfri
02/14/2022, 10:45 PM