/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.events;

import net.ranides.assira.trace.LoggerUtils;
import net.ranides.assira.trace.ThreadDump;
import org.slf4j.Logger;

/**
 * Basic EventRouter implementation without multi-threading support.
 *
 * It does not schedule events, it executes all event listeners instantly in calling thread.
 *
 * It is usefull everywhere, where we are sure that senders and recipients work in single thread
 * or when registered observers handle messages can be executed anywhere because they are thread-safe.
 *
 * Strictly speaking: can be used if you handle synchronization on your own.
 *
 * Please note, that other EventRouters should extend this class,
 * even if they provide stronger guarantess about multi-threading or execution strategy.
 *
 * @author ranides
 */
public class EventDispatcher extends EventRouter {

    private static final Logger LOGGER = LoggerUtils.getLogger();

    private EventDispatcher() {
        super();
    }

    private EventDispatcher(String name) {
        super(name);
    }

    /**
     * Creates anonymous instant dispatcher.
     * Anonymous dispatchers can't be find by using {@link EventDispatcher#find(String)}.
     *
     * @return dispatcher
     */
    public static EventDispatcher newInstance() {
        return new EventDispatcher();
    }

    /**
     * Creates named instant dispatcher.
     * Named dispatchers can be find by using {@link EventDispatcher#find(String)}.
     *
     * Please note, that named dispatcher CAN BE garbage collected if nobody stores reference to them.
     *
     * @param name name
     * @return dispatcher
     */
    public static EventDispatcher newInstance(String name) {
        return EventRouter.newInstance(name, () -> new EventDispatcher(name));
    }

    @Override
    public boolean signalEvent(Event event) {
		ThreadDump.printIf(LOGGER.isTraceEnabled(), LOGGER::trace);
        executeListenersNow(event);
        return true;
    }

    @Override
    public void dispose() {
        executeDisposeNow();
    }

    @Override
    public String toString() {
        return "EventDispatcher<" + name() + ">";
    }

}
