1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package zeus.agents;
29
30 import java.util.*;
31 import zeus.util.*;
32 import zeus.concepts.*;
33 import zeus.actors.*;
34 import zeus.actors.event.*;
35
36
37 /***
38 * This class implements the shared agent functionality common to every agent
39 * created with the Zeus toolkit.
40 */
41
42 public class BasicAgent
43 {
44 private HSet[] eventMonitor = new HSet[4];
45
46 public static final int CREATE = 0;
47 public static final int DEATH = 1;
48 public static final int SUSPEND = 2;
49 public static final int RESUME = 3;
50
51 protected AgentContext context = null;
52
53 public BasicAgent(){ ;}
54
55 public BasicAgent(String type, String name, Vector nameservers) {
56 this(type, name, nameservers, null);
57 }
58
59 public BasicAgent(String type, String name,
60 Vector nameservers, Clock clock) {
61
62 context = new ZeusAgentContext(name,type);
63 context.set(this);
64 context.setNameservers(nameservers);
65
66 new MsgHandler(context);
67 new MailBox(context);
68
69 if ( clock != null )
70 context.set(clock);
71
72 for(int i = 0; i < eventMonitor.length; i++ )
73 eventMonitor[i] = new HSet();
74
75 long now, start = System.currentTimeMillis();
76
77 while( context.Clock() == null ) {
78 now = System.currentTimeMillis();
79 if ( now - start > (long)(context.getRegistrationTimeout()*60000) ) {
80 System.err.println("Cannot initialize " + name + " -- exiting");
81 notifyMonitors(DEATH);
82 System.exit(0);
83 }
84 try {
85 Thread.currentThread().sleep(1000);
86 }
87 catch(InterruptedException e) {
88 }
89 }
90 notifyMonitors(CREATE);
91 }
92
93 public AgentContext getAgentContext() { return context; }
94
95
96 /*** Shortcut to add a MessageMonitor, used if your code needs to react to
97 changes in the state of the mailbox */
98 public void addMessageMonitor(MessageMonitor monitor, long event_type) {
99 context.MailBox().addMessageMonitor(monitor,event_type);
100 }
101
102 public void removeMessageMonitor(MessageMonitor monitor, long event_type) {
103 context.MailBox().removeMessageMonitor(monitor,event_type);
104 }
105
106 /*** Add an AgentMonitor if your code needs to react to Agent-level changes in state */
107 public void addAgentMonitor(AgentMonitor monitor, long event_type) {
108 Assert.notNull(monitor);
109 if ( (event_type & AgentEvent.CREATE_MASK) != 0 )
110 eventMonitor[CREATE].add(monitor);
111 if ( (event_type & AgentEvent.DEATH_MASK) != 0 )
112 eventMonitor[DEATH].add(monitor);
113 if ( (event_type & AgentEvent.SUSPEND_MASK) != 0 )
114 eventMonitor[SUSPEND].add(monitor);
115 if ( (event_type & AgentEvent.RESUME_MASK) != 0 )
116 eventMonitor[RESUME].add(monitor);
117 }
118 public void removeAgentMonitor(AgentMonitor monitor, long event_type) {
119 Assert.notNull(monitor);
120 if ( (event_type & AgentEvent.CREATE_MASK) != 0 )
121 eventMonitor[CREATE].remove(monitor);
122 if ( (event_type & AgentEvent.DEATH_MASK) != 0 )
123 eventMonitor[DEATH].remove(monitor);
124 if ( (event_type & AgentEvent.SUSPEND_MASK) != 0 )
125 eventMonitor[SUSPEND].remove(monitor);
126 if ( (event_type & AgentEvent.RESUME_MASK) != 0 )
127 eventMonitor[RESUME].remove(monitor);
128 }
129 public void notifyMonitors(int type) {
130 if ( eventMonitor[type].isEmpty() ) return;
131
132 AgentMonitor monitor;
133 AgentEvent event;
134 Enumeration enum = eventMonitor[type].elements();
135
136 switch(type) {
137 case CREATE:
138 event = new AgentEvent(this,this,AgentEvent.CREATE_MASK);
139 while( enum.hasMoreElements() ) {
140 monitor = (AgentMonitor)enum.nextElement();
141 monitor.agentCreatedEvent(event);
142 }
143 break;
144 case DEATH:
145 event = new AgentEvent(this,this,AgentEvent.DEATH_MASK);
146 while( enum.hasMoreElements() ) {
147 monitor = (AgentMonitor)enum.nextElement();
148 monitor.agentDeathEvent(event);
149 }
150 break;
151 case SUSPEND:
152 event = new AgentEvent(this,this,AgentEvent.SUSPEND_MASK);
153 while( enum.hasMoreElements() ) {
154 monitor = (AgentMonitor)enum.nextElement();
155 monitor.agentSuspendedEvent(event);
156 }
157 break;
158 case RESUME:
159 event = new AgentEvent(this,this,AgentEvent.RESUME_MASK);
160 while( enum.hasMoreElements() ) {
161 monitor = (AgentMonitor)enum.nextElement();
162 monitor.agentResumedEvent(event);
163 }
164 break;
165 }
166 }
167 }