package com.github.czyzby.context.event;
import com.github.czyzby.autumn.annotation.Component;
import com.github.czyzby.autumn.annotation.Initiate;
import com.github.czyzby.autumn.annotation.Inject;
import com.github.czyzby.autumn.annotation.OnEvent;
import com.github.czyzby.autumn.annotation.OnMessage;
import com.github.czyzby.autumn.processor.event.EventDispatcher;
import com.github.czyzby.autumn.processor.event.MessageDispatcher;
import com.github.czyzby.kiwi.log.Logger;
import com.github.czyzby.kiwi.log.LoggerService;
/** Event-driven architecture is relatively easy way of achieving communication between different application components
* without dependencies hell. After all, a simple listener that reacts to a selected string message is much easier to
* transfer to another project than a complex class that requires 5 others.
*
* <p>
* Autumn makes it easier to communicate with events thanks to its unified event API. By using simple (yet powerful)
* {@link OnEvent} and {@link OnMessage} annotations you can turn any methods into an event listener. You can post
* events using {@link EventDispatcher} and {@link MessageDispatcher} components. This class demonstrates the standard
* use of Autumn events API.
*
* <p>
* The main difference between messages and events is that the latter can carry additional parameters. Messages should
* be used when some basic events occur and no additional data is needed to handle them other than the simple fact that,
* well, they happened. For example, "assetsLoaded" or "connectedWithServer" could be good messages. On contrary, any
* Java object can become an event, so event API is much more powerful than messages - it should be used when simple
* messages are simply not enough. A good example of an event could be ServerPacket.
*
* <p>
* Note that method-based event listeners are using reflection. If you notice that they are causing any delays, try
* using POJO event listeners by annotating classes rather than methods. Don't be scared though, they are not much
* harder to use than method-based listeners. See {@link MyEventHandler} and {@link MyMessageHandler} for some examples.
*
* @author MJ */
@Component
public class MyHandler {
/** Kiwi logger for this class. */
private static final Logger LOGGER = LoggerService.forClass(MyHandler.class);
/** Will be invoked any time "myMessage" is posted using {@link MessageDispatcher}. Note that annotated listener
* methods can contain any injectable parameters, using the same mechanism as {@link Inject} or {@link Initiate}
* annotations.
*
* @param eventDispatcher will be automatically injected. */
@OnMessage("myMessage")
public void onMessage(final EventDispatcher eventDispatcher) {
LOGGER.info("I detected 'myMessage'. Posting MyEvent.");
final MyEvent event = new MyEvent("MyHandler#onMessage");
eventDispatcher.postEvent(event);
}
/** Will be invoked any time {@link MyEvent} instance is posted using {@link EventDispatcher}. Note that annotated
* listener methods can contain any injectable parameters, using the same mechanism as {@link Inject} or
* {@link Initiate} annotations, as well as {@link MyEvent} parameter.
* <p>
* By returning a boolean result, you can decide whether the event listener should be kept or removed. This allows
* you to easily removed no longer needed listeners. (Note that same applies to OnMessage methods.)
*
* @param event will be injected.
* @return see {@link OnEvent#KEEP} and {@link OnEvent#REMOVE}. */
@OnEvent(MyEvent.class)
public boolean onEvent(final MyEvent event) {
LOGGER.info("I detected a MyEvent: {0}. Removing this listener.", event.getMessage());
return OnEvent.REMOVE;
}
}