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

jalse.actions.DefaultActionScheduler Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
package jalse.actions;

import static jalse.actions.Actions.emptyActionContext;
import static jalse.actions.Actions.unmodifiableActionContext;
import static jalse.actions.Actions.unmodifiableActorActionContext;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * A {@link ActionScheduler} implementation that schedules all actions against the supplied actor.
 * Weak references are kept against all scheduled tasks so they can be bulk cancelled (these are
 * also cleared on {@link ActionEngine} change).
*
* By default if no {@link ActionEngine} is supplied {@link ForkJoinActionEngine#commonPoolEngine()} * will be used. * * @author Elliot Ford * * @param * Actor type. */ public class DefaultActionScheduler implements ActionScheduler { private final T actor; private ActionEngine engine; private final Set> contexts; /** * Creates a DefaultScheduler for the supplied actor. * * @param actor * Actor to schedule actions against. */ public DefaultActionScheduler(final T actor) { this.actor = Objects.requireNonNull(actor); engine = ForkJoinActionEngine.commonPoolEngine(); // Defaults use common engine contexts = new HashSet<>(); } /** * Cancel all tasks scheduled to the current engine for the actor by this scheduler. */ @Override public void cancelAllScheduledForActor() { synchronized (contexts) { final Iterator> it = contexts.iterator(); while (it.hasNext()) { final ActionContext cxt = it.next(); if (!cxt.isDone()) { cxt.cancel(); } it.remove(); } } } /** * Gets the action Actor. * * @return Actor to schedule events against. */ public T getActor() { return actor; } /** * Gets the associated engine. * * @return Associated engine or null if it has not been set. */ public ActionEngine getEngine() { return engine; } @Override public MutableActionContext newContextForActor(final Action action) { // Check engine running if (engine.isStopped()) { return emptyActionContext(); } else { // New context for actor return unmodifiableActorActionContext(newContextForActor0(action)); } } private MutableActionContext newContextForActor0(final Action action) { // Create new context final MutableActionContext context = engine.newContext(action); context.setActor(actor); // Add then purge synchronized (contexts) { contexts.add(context); contexts.removeIf(ActionContext::isDone); } return context; } @Override public ActionContext scheduleForActor(final Action action, final long initialDelay, final long period, final TimeUnit unit) { // Check engine running if (engine.isStopped()) { return emptyActionContext(); } // Create new actor context final MutableActionContext context = newContextForActor0(action); context.setInitialDelay(initialDelay, unit); context.setPeriod(period, unit); context.schedule(); // Don't allow for mutation (it's running) return unmodifiableActionContext(context); } /** * Associates a engine to this scheduler (if the engine changes all task references are lost). * * @param engine * Engine to schedule actions against. */ public void setEngine(final ActionEngine engine) { if (!Objects.equals(this.engine, engine)) { // Only if changed synchronized (contexts) { contexts.clear(); } } this.engine = engine; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy