?? agent.java
字號:
if (!Thread.currentThread().equals(myThread)) {
// If the state-change is forced from the outside, interrupt
// the agent thread to allow the state change to take place
interruptThread();
}
}
}
public void restoreBufferedState() {
changeStateTo(myBufferedLifeCycle);
}
/**
The ActiveLifeCycle handles different internal states (INITIATED,
ACTIVE, WAITING, IDLE). This method switches between them.
*/
private void setActiveState(int newState) {
synchronized (stateLock) {
if (myLifeCycle == myActiveLifeCycle) {
int oldState = myLifeCycle.getState();
if (newState != oldState) {
((ActiveLifeCycle) myLifeCycle).setState(newState);
//#MIDP_EXCLUDE_BEGIN
notifyChangedAgentState(oldState, newState);
//#MIDP_EXCLUDE_END
}
}
else {
// A change state request arrived in the meanwhile.
// Let it take place.
throw new Interrupted();
}
}
}
//#APIDOC_EXCLUDE_BEGIN
/**
Read current agent state. This method can be used to query an
agent for its state from the outside.
@return the Agent Platform Life Cycle state this agent is currently in.
*/
public int getState() {
return myLifeCycle.getState();
}
//#APIDOC_EXCLUDE_END
//#MIDP_EXCLUDE_BEGIN
public AgentState getAgentState() {
return AgentState.getInstance(getState());
}
/**
This is only called by the NotificationService to provide the Introspector
agent with a snapshot of the behaviours currently loaded in the agent
*/
Scheduler getScheduler() {
return myScheduler;
}
/**
This is only called by AgentContainerImpl
*/
MessageQueue getMessageQueue() {
return msgQueue;
}
// For persistence service
private void setMessageQueue(MessageQueue mq) {
msgQueue = mq;
}
/////////////////////////////
// Mobility related code
/////////////////////////////
private transient AgentMobilityHelper mobHelper;
private void initMobHelper() throws ServiceException {
if (mobHelper == null) {
mobHelper = (AgentMobilityHelper) getHelper(AgentMobilityHelper.NAME);
mobHelper.registerMovable(new Movable() {
public void beforeMove() {
Agent.this.beforeMove();
}
public void afterMove() {
Agent.this.afterMove();
}
public void beforeClone() {
Agent.this.beforeClone();
}
public void afterClone() {
Agent.this.afterClone();
}
} );
}
}
/**
Make this agent move to a remote location. This method
is intended to support agent mobility and is called either by the
Agent Platform or by the agent itself to start a migration process.
It should be noted that this method just changes the agent
state to <code>AP_TRANSIT</code>. The actual migration takes
place asynchronously.
<br>
<b>NOT available in MIDP</b>
<br>
@param destination The <code>Location</code> to migrate to.
*/
public void doMove(Location destination) {
// Do nothing if the mobility service is not installed
try {
initMobHelper();
mobHelper.move(destination);
}
catch(ServiceException se) {
// FIXME: Log a proper warning
return;
}
}
/**
Make this agent be cloned on another location. This method
is intended to support agent mobility and is called either by the
Agent Platform or by the agent itself to start a clonation process.
It should be noted that this method just changes the agent
state to <code>AP_COPY</code>. The actual clonation takes
place asynchronously.
<br>
<b>NOT available in MIDP</b>
<br>
@param destination The <code>Location</code> where the copy agent will start.
@param newName The name that will be given to the copy agent.
*/
public void doClone(Location destination, String newName) {
// Do nothing if the mobility service is not installed
try {
initMobHelper();
mobHelper.clone(destination, newName);
}
catch(ServiceException se) {
// FIXME: Log a proper warning
return;
}
}
//#MIDP_EXCLUDE_END
/**
Make a state transition from <em>active</em> or <em>waiting</em>
to <em>suspended</em> within Agent Platform Life Cycle; the
original agent state is saved and will be restored by a
<code>doActivate()</code> call. This method can be called from
the Agent Platform or from the agent iself and stops all agent
activities. Incoming messages for a suspended agent are buffered
by the Agent Platform and are delivered as soon as the agent
resumes. Calling <code>doSuspend()</code> on a suspended agent
has no effect.
<br>
<b>NOT available in MIDP</b>
<br>
@see jade.core.Agent#doActivate()
*/
public void doSuspend() {
//#MIDP_EXCLUDE_BEGIN
if (mySuspendedLifeCycle == null) {
mySuspendedLifeCycle = new SuspendedLifeCycle();
}
changeStateTo(mySuspendedLifeCycle);
//#MIDP_EXCLUDE_END
}
/**
Make a state transition from <em>suspended</em> to
<em>active</em> or <em>waiting</em> (whichever state the agent
was in when <code>doSuspend()</code> was called) within Agent
Platform Life Cycle. This method is called from the Agent
Platform and resumes agent execution. Calling
<code>doActivate()</code> when the agent is not suspended has no
effect.
<br>
<b>NOT available in MIDP</b>
<br>
@see jade.core.Agent#doSuspend()
*/
public void doActivate() {
//#MIDP_EXCLUDE_BEGIN
//doExecute();
restoreBufferedState();
//#MIDP_EXCLUDE_END
}
/**
Make a state transition from <em>active</em> to <em>waiting</em>
within Agent Platform Life Cycle. This method has only effect
when called by the agent thread and causes the agent to
block, stopping all its activities until
a message arrives or the
<code>doWake()</code> method is called.
@see jade.core.Agent#doWake()
*/
public void doWait() {
doWait(0);
}
/**
Make a state transition from <em>active</em> to <em>waiting</em>
within Agent Platform Life Cycle. This method adds a timeout to
the other <code>doWait()</code> version.
@param millis The timeout value, in milliseconds.
@see jade.core.Agent#doWait()
*/
public void doWait(long millis) {
if (Thread.currentThread().equals(myThread)) {
setActiveState(AP_WAITING);
synchronized(msgQueue) {
try {
// Blocks on msgQueue monitor for a while
waitOn(msgQueue, millis);
}
catch (InterruptedException ie) {
if (myLifeCycle != myActiveLifeCycle && !terminating) {
// Change state request from the outside
throw new Interrupted();
}
else {
// Spurious wake up. Just print a warning
System.out.println("Agent "+getName()+" interrupted while waiting");
}
}
setActiveState(AP_ACTIVE);
}
}
}
/**
Make a state transition from <em>waiting</em> to <em>active</em>
within Agent Platform Life Cycle. This method is called from
Agent Platform and resumes agent execution. Calling
<code>doWake()</code> when an agent is not waiting has no effect.
@see jade.core.Agent#doWait()
*/
public void doWake() {
synchronized(stateLock) {
int previous = myLifeCycle.getState();
if((previous == AP_WAITING) || (previous == AP_IDLE)) {
setActiveState(AP_ACTIVE);
}
}
if(myLifeCycle.isMessageAware()) {
activateAllBehaviours();
synchronized(msgQueue) {
msgQueue.notifyAll(); // Wakes up the embedded thread
}
}
}
/**
Make a state transition from <em>active</em>, <em>suspended</em>
or <em>waiting</em> to <em>deleted</em> state within Agent
Platform Life Cycle, thereby destroying the agent. This method
can be called either from the Agent Platform or from the agent
itself. Calling <code>doDelete()</code> on an already deleted
agent has no effect.
*/
public void doDelete() {
if (myDeletedLifeCycle == null) {
myDeletedLifeCycle = new DeletedLifeCycle();
}
changeStateTo(myDeletedLifeCycle);
}
// This is called only by the scheduler
void idle() throws InterruptedException {
setActiveState(AP_IDLE);
// No need for synchronized block since this is only called by the
// scheduler in the synchronized schedule() method
waitOn(myScheduler, 0);
setActiveState(AP_ACTIVE);
}
//#MIDP_EXCLUDE_BEGIN
/**
Write this agent to an output stream; this method can be used to
record a snapshot of the agent state on a file or to send it
through a network connection. Of course, the whole agent must
be serializable in order to be written successfully.
<br>
<b>NOT available in MIDP</b>
<br>
@param s The stream this agent will be sent to. The stream is
<em>not</em> closed on exit.
@exception IOException Thrown if some I/O error occurs during
writing.
@see jade.core.Agent#read(InputStream s)
*/
public void write(OutputStream s) throws IOException {
ObjectOutput out = new ObjectOutputStream(s);
out.writeUTF(myName);
out.writeObject(this);
}
/**
Read a previously saved agent from an input stream and restarts
it under its former name. This method can realize some sort of
mobility through time, where an agent is saved, then destroyed
and then restarted from the saved copy.
<br>
<b>NOT available in MIDP</b>
<br>
@param s The stream the agent will be read from. The stream is
<em>not</em> closed on exit.
@exception IOException Thrown if some I/O error occurs during
stream reading.
@see jade.core.Agent#write(OutputStream s)
*
public static void read(InputStream s) throws IOException {
try {
ObjectInput in = new ObjectInputStream(s);
String name = in.readUTF();
Agent a = (Agent)in.readObject();
a.doStart(name);
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}*/
/**
Read a previously saved agent from an input stream and restarts
it under a different name. This method can realize agent cloning
through streams, where an agent is saved, then an exact copy of
it is restarted as a completely separated agent, with the same
state but with different identity and address.
<br>
<b>NOT available in MIDP</b>
<br>
@param s The stream the agent will be read from. The stream is
<em>not</em> closed on exit.
@param agentName The name of the new agent, copy of the saved
original one.
@exception IOException Thrown if some I/O error occurs during
stream reading.
@see jade.core.Agent#write(OutputStream s)
*
public static void read(InputStream s, String agentName) throws IOException {
try {
ObjectInput in = new ObjectInputStream(s);
String oldName = in.readUTF();
Agent a = (Agent)in.readObject();
a.doStart(agentName);
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}*/
/**
This method reads a previously saved agent, replacing the current
state of this agent with the one previously saved. The stream
must contain the saved state of <b>the same agent</b> that it is
trying to restore itself; that is, <em>both</em> the Java object
<em>and</em> the agent name must be the same.
<br>
<b>NOT available in MIDP</b>
<br>
@param s The input stream the agent state will be read from.
@exception IOException Thrown if some I/O error occurs during
stream reading.
<em>Note: This method is currently not implemented</em>
*/
public void restore(InputStream s) throws IOException {
// FIXME: Not implemented
}
/**
This method should not be used by application code. Use the
same-named method of <code>jade.wrapper.Agent</code> instead.
<br>
<b>NOT available in MIDP</b>
<br>
@see jade.wrapper.Agent#putO2AObject(Object o, boolean blocking)
*/
public void putO2AObject(Object o, boolean blocking) throws InterruptedException {
// Drop object on the floor if object-to-agent communication is
// disabled.
if(o2aQueue == null)
return;
CondVar cond = null;
// the following block is synchronized because o2aQueue.add and o2aLocks.put must be
// an atomic operation
synchronized (o2aQueue) {
// If the queue has a limited capacity and it is full, discard the
// first element
if((o2aQueueSize != 0) && (o2aQueue.size() == o2aQueueSize))
o2aQueue.remove(0);
o2aQueue.add(o);
// If we are going to block, then activate behaviours after storing the CondVar object
if(blocking) {
cond = new CondVar();
// Store lock for later, when getO2AObject will be called
o2aLocks.put(o, cond);
}
} // end synchronization
// Reactivate the agent. This method is synchronized on the scheduler
activateAllBehaviours();
if (blocking)
// Sleep on the condition. This method is synchronized on the condvar
cond.waitOn();
}
/**
This method picks an object (if present) from the internal
object-to-agent communication queue. In order for this method to
work, the agent must have declared its will to accept objects
from other software components running within its JVM. This can
be achieved by calling the
<code>jade.core.Agent.setEnabledO2ACommunication()</code> method.
If the retrieved object was originally inserted by an external
component using a blocking call, that call will return during the
execution of this method.
<br>
<b>NOT available in MIDP</b>
<br>
@return the first object in the queue, or <code>null</code> if
the queue is empty.
@see jade.wrapper.Agent#putO2AObject(Object o, boolean blocking)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -