/* * Copyright (C) 2009-2019 Lightbend Inc. */ package jdocs.actor.fsm; // #simple-imports import akka.actor.AbstractFSM; import akka.actor.ActorRef; import akka.japi.pf.UnitMatch; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.time.Duration; // #simple-imports import static jdocs.actor.fsm.Buncher.Data; import static jdocs.actor.fsm.Buncher.State.*; import static jdocs.actor.fsm.Buncher.State; import static jdocs.actor.fsm.Buncher.Uninitialized.*; import static jdocs.actor.fsm.Events.*; // #simple-fsm public class Buncher extends AbstractFSM { { // #fsm-body startWith(Idle, Uninitialized); // #when-syntax when( Idle, matchEvent( SetTarget.class, Uninitialized.class, (setTarget, uninitialized) -> stay().using(new Todo(setTarget.getRef(), new LinkedList<>())))); // #when-syntax // #transition-elided onTransition( matchState( Active, Idle, () -> { // reuse this matcher final UnitMatch m = UnitMatch.create( matchData( Todo.class, todo -> todo.getTarget().tell(new Batch(todo.getQueue()), getSelf()))); m.match(stateData()); }) .state( Idle, Active, () -> { /* Do something here */ })); // #transition-elided when( Active, Duration.ofSeconds(1L), matchEvent( Arrays.asList(Flush.class, StateTimeout()), Todo.class, (event, todo) -> goTo(Idle).using(todo.copy(new LinkedList<>())))); // #unhandled-elided whenUnhandled( matchEvent( Queue.class, Todo.class, (queue, todo) -> goTo(Active).using(todo.addElement(queue.getObj()))) .anyEvent( (event, state) -> { log() .warning( "received unhandled request {} in state {}/{}", event, stateName(), state); return stay(); })); // #unhandled-elided initialize(); // #fsm-body } // #simple-fsm static // #simple-state // states enum State { Idle, Active } // #simple-state static // #simple-state // state data interface Data {} // #simple-state static // #simple-state enum Uninitialized implements Data { Uninitialized } // #simple-state static // #simple-state final class Todo implements Data { private final ActorRef target; private final List queue; public Todo(ActorRef target, List queue) { this.target = target; this.queue = queue; } public ActorRef getTarget() { return target; } public List getQueue() { return queue; } // #boilerplate @Override public String toString() { return "Todo{" + "target=" + target + ", queue=" + queue + '}'; } public Todo addElement(Object element) { List nQueue = new LinkedList<>(queue); nQueue.add(element); return new Todo(this.target, nQueue); } public Todo copy(List queue) { return new Todo(this.target, queue); } public Todo copy(ActorRef target) { return new Todo(target, this.queue); } // #boilerplate } // #simple-state // #simple-fsm } // #simple-fsm