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 }