?? agent.java
字號:
waitOn(suspendLock, 0);
}
}
//#MIDP_EXCLUDE_END
/**
This method adds a new behaviour to the agent. This behaviour
will be executed concurrently with all the others, using a
cooperative round robin scheduling. This method is typically
called from an agent <code>setup()</code> to fire off some
initial behaviour, but can also be used to spawn new behaviours
dynamically.
@param b The new behaviour to add to the agent.
@see jade.core.Agent#setup()
@see jade.core.behaviours.Behaviour
*/
public void addBehaviour(Behaviour b) {
b.setAgent(this);
myScheduler.add(b);
}
/**
This method removes a given behaviour from the agent. This method
is called automatically when a top level behaviour terminates,
but can also be called from a behaviour to terminate itself or
some other behaviour.
@param b The behaviour to remove.
@see jade.core.behaviours.Behaviour
*/
public void removeBehaviour(Behaviour b) {
myScheduler.remove(b);
b.setAgent(null);
}
/**
Send an <b>ACL</b> message to another agent. This methods sends
a message to the agent specified in <code>:receiver</code>
message field (more than one agent can be specified as message
receiver).
@param msg An ACL message object containing the actual message to
send.
@see jade.lang.acl.ACLMessage
*/
public final void send(ACLMessage msg) {
// Set the sender of the message if not yet set
// FIXME. Probably we should always set the sender of the message!
try {
msg.getSender().getName().charAt(0);
}
catch (Exception e) {
msg.setSender(myAID);
}
myToolkit.handleSend(msg, myAID, true);
}
/**
Receives an <b>ACL</b> message from the agent message
queue. This method is non-blocking and returns the first message
in the queue, if any. Therefore, polling and busy waiting is
required to wait for the next message sent using this method.
@return A new ACL message, or <code>null</code> if no message is
present.
@see jade.lang.acl.ACLMessage
*/
public final ACLMessage receive() {
return receive(null);
}
/**
Receives an <b>ACL</b> message matching a given template. This
method is non-blocking and returns the first matching message in
the queue, if any. Therefore, polling and busy waiting is
required to wait for a specific kind of message using this method.
@param pattern A message template to match received messages
against.
@return A new ACL message matching the given template, or
<code>null</code> if no such message is present.
@see jade.lang.acl.ACLMessage
@see jade.lang.acl.MessageTemplate
*/
public final ACLMessage receive(MessageTemplate pattern) {
ACLMessage msg = null;
synchronized (msgQueue) {
for (Iterator messages = msgQueue.iterator(); messages.hasNext(); ) {
ACLMessage cursor = (ACLMessage)messages.next();
if (pattern == null || pattern.match(cursor)) {
msgQueue.remove(cursor);
//#MIDP_EXCLUDE_BEGIN
myToolkit.handleReceived(myAID, cursor);
//#MIDP_EXCLUDE_END
msg = cursor;
break; // Exit while loop
}
}
}
return msg;
}
/**
Receives an <b>ACL</b> message from the agent message
queue. This method is blocking and suspends the whole agent until
a message is available in the queue.
@return A new ACL message, blocking the agent until one is
available.
@see jade.core.Agent#receive()
@see jade.lang.acl.ACLMessage
*/
public final ACLMessage blockingReceive() {
return blockingReceive(null, 0);
}
/**
Receives an <b>ACL</b> message from the agent message queue,
waiting at most a specified amount of time.
@param millis The maximum amount of time to wait for the message.
@return A new ACL message, or <code>null</code> if the specified
amount of time passes without any message reception.
*/
public final ACLMessage blockingReceive(long millis) {
return blockingReceive(null, millis);
}
/**
Receives an <b>ACL</b> message matching a given message
template. This method is blocking and suspends the whole agent
until a message is available in the queue.
@param pattern A message template to match received messages
against.
@return A new ACL message matching the given template, blocking
until such a message is available.
@see jade.core.Agent#receive(MessageTemplate)
@see jade.lang.acl.ACLMessage
@see jade.lang.acl.MessageTemplate
*/
public final ACLMessage blockingReceive(MessageTemplate pattern) {
return blockingReceive(pattern, 0);
}
/**
Receives an <b>ACL</b> message matching a given message template,
waiting at most a specified time.
@param pattern A message template to match received messages
against.
@param millis The amount of time to wait for the message, in
milliseconds.
@return A new ACL message matching the given template, or
<code>null</code> if no suitable message was received within
<code>millis</code> milliseconds.
@see jade.core.Agent#blockingReceive()
*/
public final ACLMessage blockingReceive(MessageTemplate pattern, long millis) {
ACLMessage msg = null;
synchronized(msgQueue) {
msg = receive(pattern);
long timeToWait = millis;
while(msg == null) {
long startTime = System.currentTimeMillis();
if (Thread.currentThread().equals(myThread)) {
doWait(timeToWait);
}
else {
// blockingReceive() called from an external thread --> Do not change the agent state
waitUntilWake(timeToWait);
}
long elapsedTime = System.currentTimeMillis() - startTime;
msg = receive(pattern);
if(millis != 0) {
timeToWait -= elapsedTime;
if(timeToWait <= 0)
break;
}
}
}
return msg;
}
/**
Puts a received <b>ACL</b> message back into the message
realizes it read a message of interest for some other
behaviour. The message is put in front of the message queue, so
it will be the first returned by a <code>receive()</code> call.
@see jade.core.Agent#receive()
*/
public final void putBack(ACLMessage msg) {
synchronized(msgQueue) {
msgQueue.addFirst(msg);
}
}
final void setToolkit(AgentToolkit at) {
myToolkit = at;
}
final void resetToolkit() {
//#MIDP_EXCLUDE_BEGIN
myToolkit = DummyToolkit.instance();
//#MIDP_EXCLUDE_END
/*#MIDP_INCLUDE_BEGIN
myToolkit = null;
#MIDP_INCLUDE_END*/
}
//#MIDP_EXCLUDE_BEGIN
//#APIDOC_EXCLUDE_BEGIN
/**
This method blocks until the agent has finished its start-up phase
(i.e. until just before its setup() method is called.
When this method returns, the target agent is registered with the
AMS and the JADE platform is aware of it.
*/
public synchronized void waitUntilStarted() {
while(myLifeCycle.getState() == AP_INITIATED) {
try {
wait();
}
catch(InterruptedException ie) {
// Do nothing...
}
}
}
//#APIDOC_EXCLUDE_END
// Notify creator that the start-up phase has completed
private synchronized void notifyStarted() {
notifyAll();
}
// Notify toolkit of the added behaviour
// Package scooped as it is called by the Scheduler
void notifyAddBehaviour(Behaviour b) {
if (generateBehaviourEvents) {
myToolkit.handleBehaviourAdded(myAID, b);
}
}
// Notify the toolkit of the removed behaviour
// Package scooped as it is called by the Scheduler
void notifyRemoveBehaviour(Behaviour b) {
if (generateBehaviourEvents) {
myToolkit.handleBehaviourRemoved(myAID, b);
}
}
//#APIDOC_EXCLUDE_BEGIN
// Notify the toolkit of the change in behaviour state
// Public as it is called by the Scheduler and by the Behaviour class
public void notifyChangeBehaviourState(Behaviour b, String from, String to) {
b.setExecutionState(to);
if (generateBehaviourEvents) {
myToolkit.handleChangeBehaviourState(myAID, b, from, to);
}
}
public void setGenerateBehaviourEvents(boolean b) {
generateBehaviourEvents = b;
}
//#APIDOC_EXCLUDE_END
// For persistence service
private boolean getGenerateBehaviourEvents() {
return generateBehaviourEvents;
}
// Notify toolkit that the current agent has changed its state
private void notifyChangedAgentState(int oldState, int newState) {
myToolkit.handleChangedAgentState(myAID, oldState, newState);
}
//#MIDP_EXCLUDE_END
private void activateAllBehaviours() {
myScheduler.restartAll();
}
/**
Put a received message into the agent message queue. The message
is put at the back end of the queue. This method is called by
JADE runtime system when a message arrives, but can also be used
by an agent, and is just the same as sending a message to oneself
(though slightly faster).
@param msg The ACL message to put in the queue.
@see jade.core.Agent#send(ACLMessage msg)
*/
public final void postMessage(final ACLMessage msg) {
synchronized (msgQueue) {
if (msg != null) {
//#MIDP_EXCLUDE_BEGIN
myToolkit.handlePosted(myAID, msg);
//#MIDP_EXCLUDE_END
msgQueue.addLast(msg);
doWake();
messageCounter++;
}
}
}
//#CUSTOM_EXCLUDE_BEGIN
private jade.content.ContentManager theContentManager = null;
/**
* Retrieves the agent's content manager
* @return The content manager.
*/
public jade.content.ContentManager getContentManager() {
if (theContentManager == null) {
theContentManager = new jade.content.ContentManager();
}
return theContentManager;
}
private transient Hashtable helpersTable;
/**
* Retrieves the agent's service helper
* @return The service helper.
*/
public ServiceHelper getHelper( String serviceName ) throws ServiceException {
ServiceHelper se = null;
if (helpersTable == null) {
helpersTable = new Hashtable();
}
se = (ServiceHelper) helpersTable.get(serviceName);
// is the helper already into the agent's helpersTable ?
if (se == null) {
// there isn't, request its creation
se = myToolkit.getHelper(this, serviceName);
if (se != null) {
se.init(this);
helpersTable.put(serviceName, se);
}
else {
throw new ServiceException("Null helper");
}
}
return se;
}
//#CUSTOM_EXCLUDE_END
/**
Retrieve a configuration property set in the <code>Profile</code>
of the local container (first) or as a System property.
@param key the key that maps to the property that has to be
retrieved.
@param aDefault a default value to be returned if there is no mapping
for <code>key</code>
*/
public String getProperty(String key, String aDefault) {
String val = myToolkit.getProperty(key, aDefault);
if (val == null || val.equals(aDefault)) {
// Try among the System properties
String sval = System.getProperty(key);
if (sval != null) {
val = sval;
}
}
return val;
}
/**
This method is used to interrupt the agent's thread.
In J2SE/PJAVA it just calls myThread.interrupt(). In MIDP,
where interrupt() is not supported the thread interruption is
simulated as described below.
The agent thread can be in one of the following three states:
1) Running a behaviour.
2) Sleeping on msgQueue due to a doWait()
3) Sleeping on myScheduler due to a schedule() with no active behaviours
Note that in MIDP the suspended state is not supported
The idea is: set the 'isInterrupted' flag, then wake up the
thread wherever it may be
*/
private void interruptThread() {
//#MIDP_EXCLUDE_BEGIN
myThread.interrupt();
//#MIDP_EXCLUDE_END
/*#MIDP_INCLUDE_BEGIN
synchronized (this) {
isInterrupted = true;
// case 1: Nothing to do.
// case 2: Signal on msgQueue.
synchronized (msgQueue) {msgQueue.notifyAll();}
// case 3: Signal on the Scheduler
synchronized (myScheduler) {myScheduler.notifyAll();}
}
#MIDP_INCLUDE_END*/
}
/**
Since in MIDP Thread.interrupt() does not exist and a simulated
interruption is used to "interrupt" the agent's thread, we must
check whether the simulated interruption happened just before and
after going to sleep.
*/
void waitOn(Object lock, long millis) throws InterruptedException {
/*#MIDP_INCLUDE_BEGIN
synchronized (this) {
if (isInterrupted) {
isInterrupted = false;
throw new InterruptedException();
}
}
#MIDP_INCLUDE_END*/
lock.wait(millis);
/*#MIDP_INCLUDE_BEGIN
synchronized (this) {
if (isInterrupted) {
isInterrupted = false;
throw new InterruptedException();
}
}
#MIDP_INCLUDE_END*/
}
//#J2ME_EXCLUDE_BEGIN
// For persistence service -- Hibernate needs java.util collections
private java.util.Set getBehaviours() {
Behaviour[] behaviours = myScheduler.getBehaviours();
java.util.Set result = new java.util.HashSet();
result.addAll(java.util.Arrays.asList(behaviour
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -