1 package cz.cuni.amis.pogamut.base.agent; 2 3 import javax.management.MXBean; 4 5 import cz.cuni.amis.introspection.Folder; 6 import cz.cuni.amis.pogamut.base.agent.state.level0.IAgentState; 7 import cz.cuni.amis.pogamut.base.component.IComponent; 8 import cz.cuni.amis.pogamut.base.component.IComponentAware; 9 import cz.cuni.amis.pogamut.base.component.IControllable; 10 import cz.cuni.amis.pogamut.base.component.bus.ComponentBus; 11 import cz.cuni.amis.pogamut.base.component.bus.event.IFatalErrorEvent; 12 import cz.cuni.amis.pogamut.base.component.exception.ComponentCantPauseException; 13 import cz.cuni.amis.pogamut.base.component.exception.ComponentCantResumeException; 14 import cz.cuni.amis.pogamut.base.component.exception.ComponentCantStartException; 15 import cz.cuni.amis.pogamut.base.component.exception.ComponentCantStopException; 16 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger; 17 import cz.cuni.amis.utils.flag.ImmutableFlag; 18 19 /** 20 * MXBean interface - serves the purpose only to JMX, you should always derive your agent from 21 * at least AbstractAgent, even though it's not enforced right now it may be in the future! 22 * <p><p> 23 * The key component of the agent is EventBus. The agent is propagating system events like 24 * "state of the agent has changed", "agent is starting", "agent is running", "agent name has changed", 25 * etc. See {@link ComponentBus} for information how the system is working - notice that the best 26 * way how to see what events are propagated - attach a listener to "ISystemClass.class" into the event bus 27 * and log all events that are being broadcasted. 28 * 29 * @author Jimmy 30 */ 31 @MXBean 32 33 public interface IAgent extends IControllable, IComponent, IComponentAware { 34 /** 35 * Returns human-readable agent's name. 36 * <p><p> 37 * Do not use as unique id of the agent:<p> 38 * 1) the name might change during the life of agent<p> 39 * 2) we do not ensure it's unique 40 * <p> 41 * Use getComponentId().getToken() instead! 42 * <p><p> 43 * Use getComponentId().getName().setFlag() to change the name of the agent. 44 * 45 * @return 46 */ 47 public String getName(); 48 49 /** 50 * Returns agent id - contains also a human-readable name that can be changed 51 * @return 52 */ 53 public IAgentId getComponentId(); 54 55 /** 56 * Returns AgentLogger for the instance allowing creating new log categories 57 * or adding new handlers to them. 58 * 59 * @return 60 */ 61 public IAgentLogger getLogger(); 62 63 /** 64 * Returns the state of the agent (whether it's running / dead / etc.). 65 * <p><p> 66 * Note that the type AgentState wraps two things: 67 * <ul> 68 * <li>AgentStateType that describes the type of the state (init, running, paused, etc.)</li> 69 * <li>String description of the state</li> 70 * </ul> 71 * 72 * @return 73 */ 74 public ImmutableFlag<IAgentState> getState(); 75 76 /** 77 * Returns folder with introspection information. Useful for showing agent model 78 * variables and parameters. 79 * @return Folder with introspection info 80 */ 81 public Folder getIntrospection(); 82 83 /** 84 * Attempt to launch the agent. If it does not throw an exception, agent has been successfully started, also 85 * the state of the agent state is changed into Running state. 86 * <p><p> 87 * This method is not suitable for simultaneous start of multiple agents that should start working together in the environment. 88 * (I.e., during tournaments of agents when you need to synchronize their start in the environment.) In such cases 89 * use {@link IAgent#startPaused()} and then multiple threads+barrier to execute {@link IAgent#resume()} of all agents at once. 90 * 91 * @throws ComponentCantStartException 92 */ 93 @Override 94 public void start() throws ComponentCantStartException; 95 96 97 /** 98 * Attempt to launch the agent. If it does not throw an exception, agent has been successfully started (paused). 99 * <p><p> 100 * In contrast with {@link IAgent#start()} this method will initialize the agent inside the environment but pauses 101 * it after the start (i.e., its reasoning should not run, the action should not do any decisions). 102 * <p><p> 103 * To fully start the agent, you need to {@link IAgent#resume()} it. 104 * <p><p> 105 * It is designed to provide safe synchronization of multiple agent simulations when you need to start the reasoning 106 * of agents synchronously. 107 * 108 * @throws ComponentCantStartException 109 */ 110 public void startPaused() throws ComponentCantStartException; 111 112 /** 113 * This should pause the the agent. If it does not throw an exception, agent has been successfully started, 114 * also the state of the agent state is changed into Paused state. 115 * <BR><BR> 116 * If your agent can't be paused, throw OperationNotSupportedException. 117 * 118 * @throws ComponentCantPauseException 119 */ 120 public void pause() throws ComponentCantPauseException; 121 122 /** 123 * This should resume the logic of the agent. If it does not throw an exception, agent has been successfully resumed, 124 * also the state of the agent state is changed into Running state. 125 * <BR><BR> 126 * If your agent can't be paused therefore can't be resumed, 127 * throw OperationNotSupportedException. 128 * 129 * @throws ComponentCantResumeException 130 */ 131 public void resume() throws ComponentCantResumeException; 132 133 /** 134 * Attempt to stop the agent, usually meaning dropping all running flags and see whether 135 * it will stop automatically. This method may be blocking. If it does not throw the exception, 136 * the agent has been successfully stopped, also the state of the agent is changed into End state. 137 * <p><p> 138 * If the stop can not complete - it must automatically call kill() method. 139 * 140 * @throws ComponentCantStopException 141 */ 142 @Override 143 public void stop() throws ComponentCantStopException; 144 145 /** 146 * Stops the agent (unconditionally), closing whatever connection it may have, this 147 * method must be non-blocking + interrupting all the communication, logic or whatever 148 * threads the agent may have. 149 * <p><p> 150 * After calling kill() method, the only method that may be called is getState() to examine state of the agent. 151 * <p><p> 152 * This also equals to "exception happened outside the agent" and "{@link IFatalErrorEvent} should be propagated inside 153 * the agent" 154 */ 155 @Override 156 public void kill(); 157 158 }