import com.google.common.collect.Multimap
import com.google.common.eventbus.EventBus as GuavaEventBus
import java.util.concurrent.ConcurrentHashMap
static { // Version 0.3
def stickyMaps = new WeakHashMap<Object, Map<Class, Object>>()
def getStickyEvents = { GuavaEventBus bus ->
def events = stickyMaps.get(bus)
if (!events) {
synchronized (stickyMaps) {
events = stickyMaps.get(bus)
if (!events) {
events = new ConcurrentHashMap<Class, Object>()
stickyMaps.put(bus, events)
}
}
}
return events
}
GuavaEventBus.metaClass.registerSticky = { object ->
def thisBus = delegate
Multimap<Class, ?> methodsInListener = thisBus.finder.findAllSubscribers(object)
thisBus.subscribersByTypeLock.writeLock().lock()
try {
thisBus.subscribersByType.putAll(methodsInListener)
// dispatch sticky events
methodsInListener.entries().each { e1 ->
Class eventType = e1.key
def wrapper = e1.value
def stickyEvents = getStickyEvents(thisBus as GuavaEventBus)
stickyEvents.entrySet().each { entry ->
Class candidateEventType = entry.key
if (eventType.isAssignableFrom(candidateEventType)) {
def stickyEvent = entry.getValue()
// println("sticky Dispatch $candidateEventType Want: $eventType $wrapper $stickyEvent")
thisBus.enqueueEvent(stickyEvent, wrapper)
}
}
}
thisBus.dispatchQueuedEvents()
} finally {
thisBus.subscribersByTypeLock.writeLock().unlock()
}
}
GuavaEventBus.metaClass.postSticky = { event ->
def stickyEvents = getStickyEvents(delegate as GuavaEventBus)
synchronized (stickyEvents) {
stickyEvents.put(event.class, event)
}
delegate.post(event)
}
GuavaEventBus.metaClass.getStickyEvent = { Class eventType ->
def stickyEvents = getStickyEvents(delegate as GuavaEventBus)
synchronized (stickyEvents) {
return eventType.cast(stickyEvents.get(eventType))
}
}
GuavaEventBus.metaClass.removeStickyEvent = { Class eventType ->
def stickyEvents = getStickyEvents(delegate as GuavaEventBus)
synchronized (stickyEvents) {
return eventType.cast(stickyEvents.remove(eventType))
}
}
GuavaEventBus.metaClass.removeStickyEvent = { Object event ->
def stickyEvents = getStickyEvents(delegate as GuavaEventBus)
synchronized (stickyEvents) {
def eventType = event.getClass()
def existingEvent = stickyEvents.get(eventType)
if (event == existingEvent) {
stickyEvents.remove(eventType)
return true
} else {
return false
}
}
}
GuavaEventBus.metaClass.removeAllStickyEvents = {
def stickyEvents = getStickyEvents(delegate as GuavaEventBus)
synchronized (stickyEvents) {
stickyEvents.clear()
}
}
}