All Downloads are FREE. Search and download functionalities are using the official Maven repository.

co.paralleluniverse.actors.behaviors.GenEventActor Maven / Gradle / Ivy

There is a newer version: 0.8.0
Show newest version
/*
 * Quasar: lightweight threads and actors for the JVM.
 * Copyright (C) 2013, Parallel Universe Software Co. All rights reserved.
 * 
 * This program and the accompanying materials are dual-licensed under
 * either the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation
 *  
 *   or (per the licensee's choosing)
 *  
 * under the terms of the GNU Lesser General Public License version 3.0
 * as published by the Free Software Foundation.
 */
package co.paralleluniverse.actors.behaviors;

import co.paralleluniverse.actors.Actor;
import co.paralleluniverse.actors.ActorRef;
import co.paralleluniverse.actors.MailboxConfig;
import static co.paralleluniverse.actors.behaviors.RequestReplyHelper.reply;
import static co.paralleluniverse.actors.behaviors.RequestReplyHelper.replyError;
import co.paralleluniverse.fibers.FiberScheduler;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.strands.Strand;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author pron
 */
public class GenEventActor extends GenBehaviorActor {
    private static final Logger LOG = LoggerFactory.getLogger(GenEventActor.class);
    private final List> handlers = new ArrayList<>();

    public GenEventActor(String name, Initializer initializer, Strand strand, MailboxConfig mailboxConfig) {
        super(name, initializer, strand, mailboxConfig);
    }

    //
    /////////// Behavior boilerplate ///////////////////////////////////
    @Override
    protected GenEvent makeRef(ActorRef ref) {
        return new GenEvent.Local(ref);
    }

    @Override
    public GenEvent ref() {
        return (GenEvent) super.ref();
    }

    @Override
    protected GenEvent self() {
        return ref();
    }

    @Override
    public GenEvent spawn(FiberScheduler scheduler) {
        return (GenEvent) super.spawn(scheduler);
    }

    @Override
    public GenEvent spawn() {
        return (GenEvent) super.spawn();
    }
    //

    //
    /////////// Constructors ///////////////////////////////////
    public GenEventActor(String name, Initializer initializer, MailboxConfig mailboxConfig) {
        this(name, initializer, null, mailboxConfig);
    }

    public GenEventActor(String name, Initializer initializer) {
        this(name, initializer, null, null);
    }

    public GenEventActor(Initializer initializer, MailboxConfig mailboxConfig) {
        this(null, initializer, null, mailboxConfig);
    }

    public GenEventActor(Initializer initializer) {
        this(null, initializer, null, null);
    }

    public GenEventActor(String name, MailboxConfig mailboxConfig) {
        this(name, null, null, mailboxConfig);
    }

    public GenEventActor(String name) {
        this(name, null, null, null);
    }

    public GenEventActor(MailboxConfig mailboxConfig) {
        this(null, null, null, mailboxConfig);
    }

    public GenEventActor() {
        this(null, null, null, null);
    }
    //

    @Override
    public Logger log() {
        return LOG;
    }

    protected boolean addHandler(EventHandler handler) throws SuspendExecution, InterruptedException {
        verifyInActor();
        LOG.info("{} adding handler {}", this, handler);
        return handlers.add(handler);
    }

    protected boolean removeHandler(EventHandler handler) throws SuspendExecution, InterruptedException {
        verifyInActor();
        LOG.info("{} removing handler {}", this, handler);
        return handlers.remove(handler);
    }

    protected void notify(Event event) throws SuspendExecution {
        ref().send(event);
    }

    @Override
    protected final void handleMessage(Object m1) throws InterruptedException, SuspendExecution {
        if (m1 instanceof GenRequestMessage) {
            final GenRequestMessage req = (GenRequestMessage) m1;
            try {
                if (m1 instanceof HandlerMessage) {
                    final HandlerMessage m = (HandlerMessage) m1;
                    if (m.add)
                        reply(req, addHandler(m.handler));
                    else
                        reply(req, removeHandler(m.handler));
                }
            } catch (Exception e) {
                replyError(req, e);
            }
        } else
            notifyHandlers((Event) m1);
    }

    @Override
    protected void onTerminate(Throwable cause) throws SuspendExecution, InterruptedException {
        super.onTerminate(cause);
        handlers.clear();
    }

    public static  GenEventActor currentGenEvent() {
        return (GenEventActor) Actor.currentActor();
    }

    private void notifyHandlers(Event event) {
        LOG.debug("{} Got event {}", this, event);
        for (EventHandler handler : handlers)
            handler.handleEvent(event);
    }

    static class HandlerMessage extends GenRequestMessage {
        final EventHandler handler;
        final boolean add;

        public HandlerMessage(ActorRef from, Object id, EventHandler handler, boolean add) {
            super(from, id);
            this.handler = handler;
            this.add = add;
        }

        @Override
        protected String contentString() {
            return super.contentString() + " handler: " + handler + " add: " + add;
        }
    }
}