View Javadoc

1   package nl.tudelft.goal.ut2004.agent.module;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.lang.reflect.Method;
5   import java.util.ArrayList;
6   import java.util.Collection;
7   import java.util.HashMap;
8   import java.util.HashSet;
9   import java.util.List;
10  import java.util.Map;
11  import java.util.Map.Entry;
12  import java.util.Set;
13  
14  import nl.tudelft.goal.EIS2Java.annotation.AsPercept;
15  import nl.tudelft.goal.EIS2Java.util.EIS2JavaUtil;
16  import cz.cuni.amis.pogamut.base.agent.module.SensorModule;
17  import cz.cuni.amis.pogamut.ut2004.bot.IUT2004BotController;
18  import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
19  import cz.cuni.amis.utils.exception.PogamutException;
20  import eis.exceptions.EntityException;
21  
22  /**
23   * Module that prepares a batch of percepts after each update of the world view.
24   * Percepts are gathered based on {@link AsPercept} annotations in the
25   * controller.
26   * 
27   * A batch can be collected using {@link PerceptModule#getAllPercepts()}.
28   * 
29   * @author mpkorstanje
30   * 
31   */
32  @SuppressWarnings("rawtypes")
33  public class PerceptModule extends SensorModule<UT2004Bot> {
34  
35  	// /**
36  	// * {@link BeginMessage} listener.
37  	// */
38  	// private class EndMessageListener implements
39  	// IWorldEventListener<EndMessage> {
40  	// @Override
41  	// public void notify(EndMessage event) {
42  	// updatePercepts();
43  	// }
44  	//
45  	// /**
46  	// * Constructor. Registers itself on the given WorldView object.
47  	// *
48  	// * @param worldView
49  	// * WorldView object to listen to.
50  	// */
51  	// public EndMessageListener(IWorldView worldView) {
52  	// worldView.addEventListener(EndMessage.class, this);
53  	// }
54  	// }
55  
56  	// /** {@link BeginMessage} listener */
57  	// @SuppressWarnings("unused")
58  	// private EndMessageListener endMessageListener;
59  
60  	/**
61  	 * Methods that provide the percepts.
62  	 */
63  	private Set<Method> perceptProviders = new HashSet<Method>();
64  
65  	/**
66  	 * Percepts pulled from bot.
67  	 */
68  	private Map<Method, Object> perceptBatch = new HashMap<Method, Object>();
69  
70  	/**
71  	 * Event percepts pulled from bot.
72  	 */
73  	private Map<Method, List<Object>> eventPerceptBatch = new HashMap<Method, List<Object>>();
74  
75  	public PerceptModule(UT2004Bot agent) {
76  		super(agent);
77  
78  		// Setup end message listener
79  		// endMessageListener = new EndMessageListener(worldView);
80  
81  		// Setup percept providers.
82  		try {
83  			Class<? extends IUT2004BotController> controllerClass = agent.getController().getClass();
84  			perceptProviders = EIS2JavaUtil.processPerceptAnnotations(controllerClass);
85  		} catch (EntityException e) {
86  			throw new PogamutException("Could not proccess all annotations", e);
87  		}
88  	}
89  
90  	/**
91  	 * Calls all percept providers and puts the result in a new batch.
92  	 */
93  	public synchronized void updatePercepts() {
94  
95  		perceptBatch = new HashMap<Method, Object>();
96  
97  		for (Method method : perceptProviders) {
98  			AsPercept annotation = method.getAnnotation(AsPercept.class);
99  			String perceptName = annotation.name();
100 
101 			Object percept;
102 			try {
103 				percept = method.invoke(agent.getController());
104 			} catch (IllegalArgumentException e) {
105 				throw new PogamutException("Unable to update " + perceptName, e);
106 			} catch (IllegalAccessException e) {
107 				throw new PogamutException("Unable to update " + perceptName, e);
108 			} catch (InvocationTargetException e) {
109 				throw new PogamutException("Unable to update " + perceptName, e);
110 			}
111 			
112 			if(percept == null){
113 				System.out.println("?");
114 			}
115 
116 			// Percept is event based, needs special handling.
117 			if (annotation.event()) {
118 				if (!eventPerceptBatch.containsKey(method)) {
119 					eventPerceptBatch.put(method, new ArrayList<Object>());
120 				}
121 
122 				List<Object> events = eventPerceptBatch.get(method);
123 
124 				// Percept provides multiple items, add them independently.
125 				if (!annotation.multiplePercepts()) {
126 					throw new PogamutException("Unable to update " + perceptName
127 							+ " event percept must have multiplePercepts.", this);
128 				}
129 
130 				if (!(percept instanceof Collection<?>)) {
131 					throw new PogamutException("Unable to update " + perceptName
132 							+ " return value must be a collection.", this);
133 				}
134 
135 				events.addAll((Collection<?>) percept);
136 
137 			}
138 			// Regular percept
139 			else {
140 				perceptBatch.put(method, percept);
141 			}
142 		}
143 
144 		perceptBatch.putAll(eventPerceptBatch);
145 	}
146 
147 	public synchronized Map<Method, Object> getAllPercepts() {
148 		// We can clear outstanding events. They'll be exported now.
149 		eventPerceptBatch.clear();
150 		return perceptBatch;
151 	}
152 }