1 package cz.cuni.amis.pogamut.base.agent.utils.runner; 2 3 import java.util.List; 4 5 import cz.cuni.amis.pogamut.base.agent.IAgent; 6 import cz.cuni.amis.pogamut.base.agent.params.IAgentParameters; 7 import cz.cuni.amis.pogamut.base.factory.guice.GuiceAgentModule; 8 9 /** 10 * Utility interface for classes that can instantiate & start (possibly multiple) agents at once. Agents may be also 11 * of different classes. 12 * <p><p> 13 * Every implementor is instantiated with default values that should be passed into the agent when no 14 * other parameters are provided. 15 * <p><p> 16 * Note that the {@link IMultipleAgentRunner} utilize {@link IAgentParameters#assignDefaults(IAgentParameters)} to fill 17 * missing fields into {@link IAgentParameters} which allows you to instantiate the {@link IAgentParameters} implementor 18 * with custom data leaving the rest to the {@link IMultipleAgentRunner} (eases the pain of starting agents greatly). 19 * <p><p> 20 * The interface also provides a "synchronizing" feature via {@link IMultipleAgentRunner#setPausing(boolean)}. If set true, 21 * the runner will pause all agents after their construction and resume them at once when all agents has been instantiated. 22 * <p> 23 * Pausing behavior is disabled (== set to false) as default. 24 * <p><p> 25 * NOTE: it might seem strange why there exists {@link IAgentRunner} and {@link IMultipleAgentRunner} interfaces when 26 * {@link IAgentRunner} can be implemented using {@link IMultipleAgentRunner}. Even though that is true, it would 27 * be infeasible as {@link IMultipleAgentRunner} always needs to instantiate new factories for every {@link IAgentDescriptor} 28 * passed (unlike the {@link IAgentRunner} that may utilize the same factory instance repeatedly). 29 * <p><p> 30 * <b>USING FROM THE main(String[] args) METHOD</b> 31 * <p> 32 * Starting agents from the main method requires special care: 33 * <ol> 34 * <li>if one of your agents fails, all agents should be closed (simulation has been broken)</li> 35 * <li>when all your agent dies, Pogamut platform should be closed (so the JVM could terminate)</li> 36 * </ol> 37 * Previous two points are not-so-easy to implement (and we won't bother you with them). Instead, you 38 * could just call {@link IAgentRunner#setMain(boolean)} with 'true' and the runner will behave differently. 39 * (Note that all startAgent methods will block!) 40 * 41 * @author Jimmy 42 * 43 * @param <AGENT> common ancestor of all agents that are going to be started 44 * @param <PARAMS> 45 * @param <MODULE> 46 */ 47 public interface IMultipleAgentRunner<AGENT extends IAgent, PARAMS extends IAgentParameters, MODULE extends GuiceAgentModule> { 48 49 /** 50 * Start an agent instances described by 'agentDescriptors'. The method creates a new factory 51 * for every descriptor (as it must use different agent modules). The length of the 'agentDescriptors' array 52 * together with {@link IAgentDescriptor#getCount()} determines how many agents are going to be instantiated and started. 53 * <p><p> 54 * Note that if any instantiation/start of the agent fails, all agents are killed before the method throws 55 * the exception. 56 * 57 * @param agentsParameters 58 * @return array of started agents 59 */ 60 public List<AGENT> startAgents(IAgentDescriptor<PARAMS, MODULE>... agentDescriptors); 61 62 /** 63 * Sets the pausing behavior. 64 * <p><p> 65 * If set true, the runner will pause all agents after their construction and resume them 66 * at once whenever all agents has been successfully started. 67 * 68 * @param state 69 * @return this instance 70 */ 71 public IMultipleAgentRunner<AGENT, PARAMS, MODULE> setPausing(boolean state); 72 73 /** 74 * Tells, whether the pausing behavior is enabled. 75 * <p><p> 76 * If enabled, the runner will pause all agents after their construction and resume them 77 * at once whenever all agents has been instantiated. 78 * 79 * @return state of the pausing behavior 80 */ 81 public boolean isPausing(); 82 83 /** 84 * Sets 'main' functionality. 85 * @param state 86 * @return 87 */ 88 public IMultipleAgentRunner<AGENT, PARAMS, MODULE> setMain(boolean state); 89 90 /** 91 * Whether the runner is set to provide 'main' functionality. 92 * @return 93 */ 94 public boolean isMain(); 95 }