|
Akka/Scala example source code file (FSMStateFunctionBuilder.java)
The FSMStateFunctionBuilder.java Akka example source code/** * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com> */ package akka.japi.pf; import akka.actor.FSM; import scala.PartialFunction; import java.util.List; /** * Builder used to create a partial function for {@link akka.actor.FSM#whenUnhandled}. * * @param <S> the state type * @param <D> the data type * * This is an EXPERIMENTAL feature and is subject to change until it has received more real world testing. */ @SuppressWarnings("rawtypes") public class FSMStateFunctionBuilder<S, D> { private PFBuilder<FSM.Event<D>, FSM.State<S, D>> builder = new PFBuilder<FSM.Event<D>, FSM.State<S, D>>(); /** * An erased processing of the event matcher. The compile time checks are enforced * by the public typed versions. * * It works like this. * * If eventOrType or dataOrType is a Class, then we do a isInstance check, * otherwise we do an equals check. The null value compares true for anything. * If the predicate is null, it is skipped otherwise the predicate has to match * as well. * * @param eventOrType an event or a type to match against * @param dataOrType a data instance or a type to match against * @param predicate a predicate to match against * @param apply an action to apply to the event and state data if there is a match * @return the builder with the case statement added */ private FSMStateFunctionBuilder<S, D> erasedEvent(final Object eventOrType, final Object dataOrType, final FI.TypedPredicate2 predicate, final FI.Apply2 apply) { builder.match(FSM.Event.class, new FI.TypedPredicate<FSM.Event>() { @Override public boolean defined(FSM.Event e) { boolean res = true; if (eventOrType != null) { if (eventOrType instanceof Class) { Class eventType = (Class) eventOrType; res = eventType.isInstance(e.event()); } else { res = eventOrType.equals(e.event()); } } if (res && dataOrType != null) { if (dataOrType instanceof Class) { Class dataType = (Class) dataOrType; res = dataType.isInstance(e.stateData()); } else { res = dataOrType.equals(e.stateData()); } } if (res && predicate != null) { @SuppressWarnings("unchecked") boolean ures = predicate.defined(e.event(), e.stateData()); res = ures; } return res; } }, new FI.Apply<FSM.Event, FSM.State<S, D>>() { public FSM.State<S, D> apply(FSM.Event e) throws Exception { @SuppressWarnings("unchecked") FSM.State<S, D> res = (FSM.State<S, D>) apply.apply(e.event(), e.stateData()); return res; } } ); return this; } /** * Add a case statement that matches on an event and data type and a predicate. * * @param eventType the event type to match on * @param dataType the data type to match on * @param predicate a predicate to evaluate on the matched types * @param apply an action to apply to the event and state data if there is a match * @param <P> the event type to match on * @param <Q> the data type to match on * @return the builder with the case statement added */ public final <P, Q> FSMStateFunctionBuilder<S, D> event(final Class<P> eventType, final Class<Q> dataType, final FI.TypedPredicate2<P, Q> predicate, final FI.Apply2<P, Q, FSM.State<S, D>> apply) { erasedEvent(eventType, dataType, predicate, apply); return this; } /** * Add a case statement that matches on an event and data type. * * @param eventType the event type to match on * @param dataType the data type to match on * @param apply an action to apply to the event and state data if there is a match * @param <P> the event type to match on * @param <Q> the data type to match on * @return the builder with the case statement added */ public <P, Q> FSMStateFunctionBuilder<S, D> event(final Class<P> eventType, final Class<Q> dataType, final FI.Apply2<P, Q, FSM.State<S, D>> apply) { return erasedEvent(eventType, dataType, null, apply); } /** * Add a case statement that matches if the event type and predicate matches. * * @param eventType the event type to match on * @param predicate a predicate that will be evaluated on the data and the event * @param apply an action to apply to the event and state data if there is a match * @return the builder with the case statement added */ public <P> FSMStateFunctionBuilder<S, D> event(final Class<P> eventType, final FI.TypedPredicate2<P, D> predicate, final FI.Apply2<P, D, FSM.State<S, D>> apply) { return erasedEvent(eventType, null, predicate, apply); } /** * Add a case statement that matches if the event type and predicate matches. * * @param eventType the event type to match on * @param apply an action to apply to the event and state data if there is a match * @return the builder with the case statement added */ public <P> FSMStateFunctionBuilder<S, D> event(final Class<P> eventType, final FI.Apply2<P, D, FSM.State<S, D>> apply) { return erasedEvent(eventType, null, null, apply); } /** * Add a case statement that matches if the predicate matches. * * @param predicate a predicate that will be evaluated on the data and the event * @param apply an action to apply to the event and state data if there is a match * @return the builder with the case statement added */ public FSMStateFunctionBuilder<S, D> event(final FI.TypedPredicate2<Object, D> predicate, final FI.Apply2<Object, D, FSM.State<S, D>> apply) { return erasedEvent(null, null, predicate, apply); } /** * Add a case statement that matches on the data type and if any of the event types * in the list match or any of the event instances in the list compares equal. * * @param eventMatches a list of types or instances to match against * @param dataType the data type to match on * @param apply an action to apply to the event and state data if there is a match * @param <Q> the data type to match on * @return the builder with the case statement added */ public <Q> FSMStateFunctionBuilder<S, D> event(final List<Object> eventMatches, final Class<Q> dataType, final FI.Apply2<Object, Q, FSM.State<S, D>> apply) { builder.match(FSM.Event.class, new FI.TypedPredicate<FSM.Event>() { @Override public boolean defined(FSM.Event e) { if (dataType != null && !dataType.isInstance(e.stateData())) return false; boolean emMatch = false; Object event = e.event(); for (Object em : eventMatches) { if (em instanceof Class) { Class emc = (Class) em; emMatch = emc.isInstance(event); } else { emMatch = event.equals(em); } if (emMatch) break; } return emMatch; } }, new FI.Apply<FSM.Event, FSM.State<S, D>>() { public FSM.State<S, D> apply(FSM.Event e) throws Exception { @SuppressWarnings("unchecked") Q q = (Q) e.stateData(); return apply.apply(e.event(), q); } } ); return this; } /** * Add a case statement that matches if any of the event types in the list match or * any of the event instances in the list compares equal. * * @param eventMatches a list of types or instances to match against * @param apply an action to apply to the event and state data if there is a match * @return the builder with the case statement added */ public FSMStateFunctionBuilder<S, D> event(final List<Object> eventMatches, final FI.Apply2<Object, D, FSM.State<S, D>> apply) { return event(eventMatches, null, apply); } /** * Add a case statement that matches on the data type and if the event compares equal. * * @param event an event to compare equal against * @param dataType the data type to match on * @param apply an action to apply to the event and state data if there is a match * @param <Q> the data type to match on * @return the builder with the case statement added */ public <P, Q> FSMStateFunctionBuilder<S, D> eventEquals(final P event, final Class<Q> dataType, final FI.Apply2<P, Q, FSM.State<S, D>> apply) { return erasedEvent(event, dataType, null, apply); } /** * Add a case statement that matches if event compares equal. * * @param event an event to compare equal against * @param apply an action to apply to the event and state data if there is a match * @return the builder with the case statement added */ public <P> FSMStateFunctionBuilder<S, D> eventEquals(final P event, final FI.Apply2<P, D, FSM.State<S, D>> apply) { return erasedEvent(event, null, null, apply); } /** * Add a case statement that matches on any type of event. * * @param apply an action to apply to the event and state data * @return the builder with the case statement added */ public FSMStateFunctionBuilder<S, D> anyEvent(final FI.Apply2<Object, D, FSM.State<S, D>> apply) { return erasedEvent(null, null, null, apply); } /** * Build a {@link scala.PartialFunction} from this builder. * After this call the builder will be reset. * * @return a PartialFunction for this builder. */ public PartialFunction<FSM.Event<D>, FSM.State<S, D>> build() { return builder.build(); } } Other Akka source code examplesHere is a short list of links related to this Akka FSMStateFunctionBuilder.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.