package actor;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public abstract class ActorThread<M> extends Thread {

    private final LinkedBlockingQueue<M> q = new LinkedBlockingQueue<>();

    /** Called by another thread, to send a message to this thread. */
    public void send(M message) {
        String handlerName = this.getClass().getSimpleName();
        q.offer(message);
        System.out.println(" # Message to " + handlerName + " : " + message);
    }

    /** Returns the first message in the queue, or blocks if none available. */
    protected M receive() throws InterruptedException {
        M mess = q.take();
        return mess;
    }

    /**
     * Returns the first message in the queue, or blocks up to 'timeout'
     * milliseconds if none available. Returns null if no message is obtained
     * within 'timeout' milliseconds.
     */
    protected M receiveWithTimeout(long timeout) throws InterruptedException {
        return q.poll(timeout, TimeUnit.MILLISECONDS);
    }

    /** Wait for a message continuously */
    @Deprecated
    protected M take() throws InterruptedException {
        return q.take();
    }
}