View Javadoc

1   package cz.cuni.amis.pogamut.udk.agent.module.utils;
2   
3   import java.util.Collection;
4   import java.util.HashMap;
5   import java.util.HashSet;
6   import java.util.Map;
7   import java.util.Set;
8   
9   import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
10  import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
11  import cz.cuni.amis.pogamut.udk.bot.impl.UDKBot;
12  import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.BeginMessage;
13  
14  /**
15   * This class is a simple implementation of TabooSet (similar to TabooList). It allows you to insert
16   * items that are taboo either for infinite time (via {@link TabooSet#add(Object)}) or for a specified
17   * amount of UT2004 time (via {@link TabooSet#add(Object, double)}).
18   * <p><p>
19   * Items inside taboo set are either removed automatically due to a timeout (a specified amount of time has passed)
20   * or manually via {@link TabooSet#remove(Object)}.
21   */
22  public class TabooSet<T> {
23  	
24  	/**
25  	 * Map of tabu items together with their time until which they are valid (negative time == valid for infinity).
26  	 */
27  	private Map<T, Double> taboo = new HashMap<T, Double>();	
28  	
29  	/**
30  	 * Adds a tabu item that is valid for an infinite amount of time.
31  	 * @param item
32  	 */
33  	public void add(T item) {
34  		taboo.put(item, (double)-1);
35  	}
36  	
37  	/**
38  	 * Adds a tabu item that is valid for a period of 'timeout' time (in seconds).
39  	 * @param item
40  	 * @param timeout in seconds
41  	 */
42  	public void add(T item, double timeout) {
43  		taboo.put(item, time+timeout);
44  	}
45  	
46  	/**
47  	 * Removes a tabu item from the set.
48  	 * @param item
49  	 */
50  	public void remove(T item) {
51  		taboo.remove(item);
52  	}
53  	
54  	/**
55  	 * Determines whether an 'item' is inside tabu set or not based on the current
56  	 * UT2004 time.
57  	 * @param item
58  	 * @return
59  	 */
60  	public boolean isTaboo(T item) {
61  		if (taboo.containsKey(item)) {
62  			double tabuTime = taboo.get(item);
63  			if (tabuTime < 0) {
64  				return true;
65  			}
66  			if (tabuTime < time) {
67  				taboo.remove(item);
68  				return false;
69  			} else {
70  				return true;
71  			}
72  		} else {
73  			return false;
74  		}
75  	}
76  	
77  	/**
78  	 * Filters collection according to the current state of the tabu set. It returns a new hash set
79  	 * containing items from 'collection' that are not inside tabu set.
80  	 * 
81  	 * @param collection
82  	 * @return
83  	 */
84  	public Set<T> filter(Collection<T> collection) {
85  		Set<T> set = new HashSet<T>();
86  		for (T t : collection) {
87  			if (isTaboo(t)) continue;
88  			set.add(t);
89  		}
90  		return set;
91  	}
92  	
93  	/**
94  	 * Clears the taboo set.
95  	 */
96  	public void clear() {
97  		taboo.clear();
98  	}
99  	
100 	/**
101 	 * Returns current UT2004 time that is used by the TabuSet.
102 	 */
103 	public double getTime() {
104 		return time;
105 	}
106 	
107 	/**
108 	 * Current UT2004 time updated by {@link TabooSet#beginMessageListener}.
109 	 */
110 	private double time;
111 	
112 	/**
113 	 * {@link BeginMessage} listener that updates {@link TabooSet#time}.
114 	 * @author Jimmy
115 	 */
116 	private class BeginMessageListener implements IWorldEventListener<BeginMessage> {
117 
118 		
119 		public BeginMessageListener(IWorldView worldView) {
120 			worldView.addEventListener(BeginMessage.class, this);
121 		}
122 
123 		@Override
124 		public void notify(BeginMessage event) {
125 			time = event.getTime();
126 		}
127 		
128 	};
129 	
130 	/**
131 	 * {@link BeginMessage} listener that updates {@link TabooSet#time}.
132 	 */
133 	BeginMessageListener beginMessageListener;
134 	
135 	/**
136 	 * Constructor of the TabuSet.
137 	 * @param bot
138 	 */
139 	public TabooSet(UDKBot bot) {
140 		beginMessageListener = new BeginMessageListener(bot.getWorldView());
141 	}
142 
143 }