/** * Create percepts contained in a ClientItemMap array and add them to the {@link * #collectedPercepts}. * * @param itemMap list of ClientItemMap elements. * @param type the type of elements in the map. */ private <T extends Item> void createPercepts( ItemMap<T> itemMap, EventTypeEnum type, String perceptname) { ArrayList<T> items = new ArrayList<T>(itemMap.values()); List<Percept> percepts = new ArrayList<Percept>(); Parameter[] parameters = null; try { parameters = translator.translate2Parameter(items); } catch (TranslationException e) { e.printStackTrace(); } if (parameters != null) { percepts.add(new Percept(perceptname, parameters)); } addPercepts(type, percepts); }
/** * Listen to entity events and store them till they are needed. Thread safe because callbacks and * calls from GOAL will be asynchronous. The events that are reported are set up in the constructor. * * @author W.Pasman */ public class EntityEventHandler implements EventListenerInterface { private Translator translator = Translator.getInstance(); private static final String ENTITY = "entity"; /** * The collected percepts. Access this always through {@link #addPercepts(EventTypeEnum, List)} * and {@link #getPercepts()}. * * <p>FIXME collect Events and evaluate the percept lazy. */ private Map<EventTypeEnum, List<Percept>> collectedPercepts = new HashMap<>(); private TygronEntity entity; public EntityEventHandler(TygronEntity entity) { this.entity = entity; EventManager.addListener( this, MapLink.STAKEHOLDERS, MapLink.ACTION_MENUS, MapLink.ACTION_LOGS, MapLink.FUNCTIONS, MapLink.BUILDINGS, MapLink.SETTINGS, MapLink.ZONES, MapLink.LANDS, MapLink.POPUPS); EventManager.addListener(this, Network.ConnectionEvent.FIRST_UPDATE_FINISHED); } /** * Add new percept to the collection. * * @param type * @param percepts */ private synchronized void addPercepts(EventTypeEnum type, List<Percept> percepts) { collectedPercepts.put(type, percepts); } /** * Get the percepts and clean our {@link #collectedPercepts}. * * @return percepts collected since last call to this */ public synchronized Map<EventTypeEnum, List<Percept>> getPercepts() { Map<EventTypeEnum, List<Percept>> copy = collectedPercepts; collectedPercepts = new HashMap<>(); return copy; } @Override public void notifyListener(Event event) { try { notifyListener1(event); } catch (EntityException e) { e.printStackTrace(); // can we do more? } } private void notifyListener1(Event event) throws EntityException { EventTypeEnum type = event.getType(); if (type instanceof MapLink) { switch ((MapLink) type) { case ACTION_LOGS: createPercepts(event.<ItemMap<ActionLog>>getContent(MapLink.COMPLETE_COLLECTION), type); break; case ACTION_MENUS: createPercepts( event.<ItemMap<ActionMenu>>getContent(MapLink.COMPLETE_COLLECTION), type, "actions"); break; case BUILDINGS: createPercepts(event.<ItemMap<Building>>getContent(MapLink.COMPLETE_COLLECTION), type); break; case FUNCTIONS: createPercepts(event.<ItemMap<Function>>getContent(MapLink.COMPLETE_COLLECTION), type); break; case SETTINGS: createPercepts(event.<ItemMap<Setting>>getContent(MapLink.COMPLETE_COLLECTION), type); break; case STAKEHOLDERS: createPercepts(event.<ItemMap<Stakeholder>>getContent(MapLink.COMPLETE_COLLECTION), type); break; case ZONES: createPercepts(event.<ItemMap<Zone>>getContent(MapLink.COMPLETE_COLLECTION), type); break; case LANDS: createPercepts(event.<ItemMap<Land>>getContent(MapLink.COMPLETE_COLLECTION), type); break; case POPUPS: // TODO filter out only popups for the entity. createPercepts( event.<ItemMap<PopupData>>getContent(MapLink.COMPLETE_COLLECTION), type, "requests"); break; default: TLogger.warning("EntityEventHandler received unknown event:" + event); return; } } else if (type == Network.ConnectionEvent.FIRST_UPDATE_FINISHED) { // entity is ready to run! Report to EIS entity.notifyReady(ENTITY); } } /** * see {@link #createPercepts(ItemMap, EventTypeEnum, String)}. The perceptname is {@link * EventTypeEnum#name()}. * * @param itemMap * @param type */ private <T extends Item> void createPercepts(ItemMap<T> itemMap, EventTypeEnum type) { createPercepts(itemMap, type, type.name().toLowerCase()); } /** * Create percepts contained in a ClientItemMap array and add them to the {@link * #collectedPercepts}. * * @param itemMap list of ClientItemMap elements. * @param type the type of elements in the map. */ private <T extends Item> void createPercepts( ItemMap<T> itemMap, EventTypeEnum type, String perceptname) { ArrayList<T> items = new ArrayList<T>(itemMap.values()); List<Percept> percepts = new ArrayList<Percept>(); Parameter[] parameters = null; try { parameters = translator.translate2Parameter(items); } catch (TranslationException e) { e.printStackTrace(); } if (parameters != null) { percepts.add(new Percept(perceptname, parameters)); } addPercepts(type, percepts); } public void stop() { EventManager.removeAllListeners(this); } /** @return true if cache is ready for use (currently it must have STAKEHOLDERS). */ private boolean isReady() { ItemMap<Item> map = EventManager.getItemMap(MapLink.STAKEHOLDERS); return map != null && map.size() > 0; } /** * Wait till critical elements are available: see {@link #isReady()}. But wait at most 10 seconds. */ public void waitForReady() { int WAITTIME = 100; int totaltime = 10000; // milliseconds. while (!isReady()) { totaltime -= WAITTIME; if (totaltime < 0) { throw new IllegalStateException("EventManager initialization timed out."); } try { Thread.sleep(WAITTIME); } catch (InterruptedException e) { e.printStackTrace(); } } } }