View Javadoc

1   package cz.cuni.amis.pogamut.emohawk.agent.module.sensomotoric;
2   
3   import java.util.HashMap;
4   
5   import cz.cuni.amis.pogamut.base.agent.module.SensomotoricModule;
6   import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
7   import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEventListener;
8   import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectListener;
9   import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectUpdatedEvent;
10  import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
11  import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
12  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.SetEmoticon;
13  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
14  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
15  
16  /**
17   * Wraps emoticon control.
18   * @author Knight
19   */
20  public class Emoticons extends SensomotoricModule<UT2004Bot> {
21  	
22  	
23      
24      /** Here we store pointer to our self object */
25      private Self self = null;
26  
27      /** default duration of emoticons in seconds */
28      private static double DEFAULT_DURATION = 5;
29  
30      /** default bubble for emoticons */
31      private static EmoticonBubbleType DEFAULT_BUBBLE = EmoticonBubbleType.BUBBLE_THOUGHT_CENTER;
32      /** We use this to track the times players changed any of their emoticons and the emoticons themselves */
33      HashMap<UnrealId, EmoticonInfo> playersEmoticons = new HashMap();
34  
35      /**
36       * Returns all 3 emoticons as currently displayed by you (displayed from LEFT-to-RIGHT).
37       * 
38       * 0 emoticons displayed: returns []
39       * 
40       * 1 emoticon displayed: returns [CENTER]
41       * 
42       * 2 emoticons displayed: returns [LEFT, RIGHT]
43       * 
44       * 3 emoticons displayed: returns [LEFT, CENTER, RIGHT]
45       * 
46       * @return array of [left, center, right] emoticon being displayed, NONE emoticons are omitted!
47       */
48      public EmoticonType[] getCurrentEmoticonTypes() {
49      	return getCurrentEmoticon().getEmoticonTypes();
50      }
51      
52      /**
53       * Returns current bot emoticon.
54       * @return
55       */
56      public Emoticon getCurrentEmoticon() {
57          if (self == null) return new Emoticon(EmoticonType.NONE, EmoticonBubbleType.NONE);
58          return new Emoticon(EmoticonType.get(self.getEmotLeft()), EmoticonType.get(self.getEmotCenter()), EmoticonType.get(self.getEmotRight()), EmoticonBubbleType.get(self.getBubble()));
59      }
60  
61      /**
62       * Gets the current emoticon of input player from input Player object.
63       * @param player
64       * @return
65       */
66      public Emoticon getPlayerEmoticon(Player player) {
67          return new Emoticon(EmoticonType.get(player.getEmotLeft()), EmoticonType.get(player.getEmotCenter()), EmoticonType.get(player.getEmotRight()), EmoticonBubbleType.get(player.getBubble()));
68      }
69  
70      /**
71       * Returns emoticon info for player of input id. Not only you get emoticon, but
72       * also the SimTime long when the emoticon was set! If no value, blank emoticon
73       * and 0 time will be returned.
74       * @param playerId
75       * @return
76       */
77      public EmoticonInfo getPlayerEmoticonInfo(UnrealId playerId) {
78          if (playersEmoticons.containsKey(playerId))
79              return playersEmoticons.get(playerId);
80          else 
81              return new EmoticonInfo(new Emoticon(EmoticonType.NONE, EmoticonType.NONE, EmoticonType.NONE, EmoticonBubbleType.NONE), 0);
82      }
83  
84      /**
85       * Sets emoticon for the bot for input duration (seconds).
86       * @param emoticon
87       */
88      public void setEmoticon(Emoticon emoticon) {
89          if (emoticon.getEmoticonCount() == 3)
90              setTripleEmoticon(emoticon.getLeftEmoticon(), emoticon.getCenterEmoticon(), emoticon.getRightEmoticon(), DEFAULT_DURATION, emoticon.getBubble());
91          else if (emoticon.getEmoticonCount() == 2)
92              setDoubleEmoticon(emoticon.getLeftEmoticon(), emoticon.getRightEmoticon(), DEFAULT_DURATION, emoticon.getBubble());
93          else
94              setCenterEmoticonType(emoticon.getCenterEmoticon(), DEFAULT_DURATION, emoticon.getBubble());
95      }
96  
97      /**
98       * Sets emoticon for the bot for input duration (seconds).
99       * @param emoticon
100      * @param duration
101      */
102     public void setEmoticon(Emoticon emoticon, double duration) {
103         if (emoticon.getEmoticonCount() == 3)
104             setTripleEmoticon(emoticon.getLeftEmoticon(), emoticon.getCenterEmoticon(), emoticon.getRightEmoticon(), duration, emoticon.getBubble());
105         else if (emoticon.getEmoticonCount() == 2)
106             setDoubleEmoticon(emoticon.getLeftEmoticon(), emoticon.getRightEmoticon(), duration, emoticon.getBubble());
107         else
108             setCenterEmoticonType(emoticon.getCenterEmoticon(), duration, emoticon.getBubble());
109     }
110 
111     /**
112      * Returns current bot left emoticon.
113      * @return
114      */
115     public EmoticonType getCurrentLeftEmoticonType() {
116         if (self == null) return EmoticonType.NONE;
117         /* TODO - uncomment when new messages genereted
118         if (EmoticonType.has(self.getEmotLeft()))
119             return EmoticonType.get(self.getEmotLeft());
120         */
121         return EmoticonType.NONE;
122     }
123 
124     /**
125      * Returns current bot center emoticon.
126      * @return
127      */
128     public EmoticonType getCurrentCenterEmoticonType() {
129         if (self == null) return EmoticonType.NONE;
130        
131         if (EmoticonType.has(self.getEmotCenter()))
132             return EmoticonType.get(self.getEmotCenter());
133         return EmoticonType.NONE;
134     }
135 
136     /**
137      * Returns current bot right emoticon.
138      * @return
139      */
140     public EmoticonType getCurrentRightEmoticonType() {
141         if (self == null) return EmoticonType.NONE;
142         if (EmoticonType.has(self.getEmotRight()))
143             return EmoticonType.get(self.getEmotRight());
144 
145         return EmoticonType.NONE;
146     }
147 
148     /**
149      * Returns current bot bubble.
150      * @return
151      */
152     public EmoticonBubbleType getCurrentBubbleType() {
153         if (self == null) return EmoticonBubbleType.NONE;
154         if (EmoticonBubbleType.has(self.getBubble())) {
155             return EmoticonBubbleType.get(self.getBubble());
156         }
157         return EmoticonBubbleType.NONE;
158     }
159     
160     /**
161      * May set multiple emoticons at once.
162      * 
163      * Can be invoked with 0 / 1 / 2 / 3 emoticon types.
164      * 
165      * 0 emoticons - stops displaying all emoticons
166      * 
167      * 1 emoticon - display emoticon as "center" one.
168      * 
169      * 2 emoticons - display emoticons as "left" and "center" ones respectively.
170      * 
171      * 3 emoticons - display emoticons as "left" and "center" and "right" ones respectively.
172      * 
173      * @param duration in seconds
174      * @param bubble
175      * @param emoticons
176      */
177     public void setEmoticons(double duration, EmoticonBubbleType bubble, EmoticonType... emoticons) {
178     	clearEmoticons();
179     	if (emoticons == null || emoticons.length == 0) return;
180     	switch(emoticons.length) {
181     	case 1:
182     		setCenterEmoticonType(emoticons[0], duration, bubble);
183     		return;
184     	case 2:
185     		setDoubleEmoticon(emoticons[0], emoticons[1], duration, bubble);
186     		return;
187     	case 3:
188     		setTripleEmoticon(emoticons[0], emoticons[1], emoticons[3], duration, bubble);
189     		return;
190     	default:
191     		log.warning("Unsupported number of emoticons to show (" + emoticons.length + "), cannot show more than 3, discarding the rest.");
192     		setTripleEmoticon(emoticons[0], emoticons[1], emoticons[3], duration, bubble);
193     		return;
194     	}    	
195     }
196 
197     /**
198      * Stops displaying all emoticons.
199      */
200     public void clearEmoticons() {
201     	setTripleEmoticon(EmoticonType.NONE, EmoticonType.NONE, EmoticonType.NONE, 0, EmoticonBubbleType.NONE);
202     }
203     
204     /**
205      * Sets emoticon in the center with default bubble and default duration.
206      * 
207      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
208      * 
209      * @param type
210      */
211     @Deprecated
212     public void setCenterEmoticonType(EmoticonType type) {
213         setCenterEmoticonType(type, DEFAULT_DURATION, DEFAULT_BUBBLE);
214     }
215 
216     /**
217      * Sets emoticon in the center for input duration (seconds).
218      * 
219      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
220      * 
221      * @param type
222      * @param duration
223      */
224     @Deprecated
225     public void setCenterEmoticonType(EmoticonType type, double duration) {
226         setCenterEmoticonType(type, duration, DEFAULT_BUBBLE);
227     }
228 
229     /**
230      * Sets emoticon in the center for input duration (seconds) with input bubble.
231      * 
232      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
233      * 
234      * @param centerEmoticon
235      * @param duration
236      * @param bubble
237      */
238     @Deprecated
239     public void setCenterEmoticonType(EmoticonType centerEmoticon, double duration, EmoticonBubbleType bubble) {
240         this.act.act(new SetEmoticon(centerEmoticon.id, 1, null, 0, null, 0, bubble.id, 1, duration));
241     }
242 
243     /**
244      * Sets double emoticon - left and right for the default duration with default bubble.
245      * 
246      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
247      * 
248      * @param left
249      * @param right
250      */
251     @Deprecated
252     public void setDoubleEmoticon(EmoticonType left, EmoticonType right) {
253         setDoubleEmoticon(left, right, DEFAULT_DURATION);
254     }
255 
256     /**
257      * Sets double emoticon - left and right for input duration with default bubble.
258      * 
259      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
260      * 
261      * @param left
262      * @param right
263      * @param duration
264      */
265     @Deprecated
266     public void setDoubleEmoticon(EmoticonType left, EmoticonType right, double duration) {
267         setDoubleEmoticon(left, right, duration, DEFAULT_BUBBLE);
268     }
269 
270     /**
271      * Sets double emoticon - left and right for input duration with input bubble.
272      * 
273      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
274      * 
275      * @param left
276      * @param right
277      * @param duration
278      * @param bubble
279      */
280     @Deprecated
281     public void setDoubleEmoticon(EmoticonType left, EmoticonType right, double duration, EmoticonBubbleType bubble) {
282         this.act.act(new SetEmoticon(null, 0, left.id, 1, right.id, 1, bubble.id, 1, duration));
283     }
284 
285     /**
286      * Sets triple emoticon - left, center and right for default duration with default bubble.
287      * 
288      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
289      * 
290      * @param left
291      * @param center
292      * @param right
293      */
294     @Deprecated
295     public void setTripleEmoticon(EmoticonType left, EmoticonType center, EmoticonType right) {
296         setTripleEmoticon(left, center, right, DEFAULT_DURATION);
297     }
298 
299     /**
300      * Sets triple emoticon - left, center and right for input duration with default bubble.4
301      * 
302      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
303      * 
304      * @param left
305      * @param center
306      * @param right
307      * @param duration
308      */
309     @Deprecated
310     public void setTripleEmoticon(EmoticonType left, EmoticonType center, EmoticonType right, double duration) {
311         setTripleEmoticon(left, center, right, duration, DEFAULT_BUBBLE);
312     }
313 
314     /**
315      * Sets triple emoticon - left, center and right for input duration with input bubble.
316      * 
317      * Use: {@link Emoticons#setEmoticons(double, EmoticonBubbleType, EmoticonType...)} instead.
318      * 
319      * @param left
320      * @param center
321      * @param right
322      * @param duration
323      * @param bubble
324      */
325     @Deprecated
326     public void setTripleEmoticon(EmoticonType left, EmoticonType center, EmoticonType right, double duration, EmoticonBubbleType bubble) {
327         this.act.act(new SetEmoticon(center.id, 1, left.id, 1, right.id, 1, bubble.id, 1, duration));
328     }
329 
330     /**
331      * Listener for Self object - stores Self object into our link.
332      */
333     IWorldObjectListener<Self> storeSelfListener = new IWorldObjectListener<Self>() {
334         @Override
335         public void notify(IWorldObjectEvent<Self> event) {
336             if (self == null) {
337                 self = event.getObject();
338                 worldView.removeObjectListener(Self.class, this);
339                 storeSelfListener = null;
340             }
341         }
342     };
343 
344     /**
345      * Player object updated listener. Here we update playersEmoticons map and generate
346      * new emoticon worldView events.
347      */
348     IWorldObjectEventListener<Player, WorldObjectUpdatedEvent<Player>> playersListener = new IWorldObjectEventListener<Player, WorldObjectUpdatedEvent<Player>>() {
349         @Override
350         public void notify(WorldObjectUpdatedEvent<Player> event) {
351             Player upPl = event.getObject();
352             Emoticon actualEmot = getPlayerEmoticon(upPl);
353             if (playersEmoticons.containsKey(upPl.getId())) {
354                 Emoticon previousEmot = playersEmoticons.get(upPl.getId()).getEmoticon();
355                 if (!previousEmot.equals(actualEmot) ) {
356                     playersEmoticons.put(upPl.getId(), new EmoticonInfo(actualEmot, event.getSimTime()));
357                     //raise new event in the worldView - new emoticon arrived!
358                     worldView.notify(new NewEmoticonEvent(upPl.getId(), actualEmot, event.getSimTime()));
359                 }            
360             } else {
361                 playersEmoticons.put(upPl.getId(), new EmoticonInfo(actualEmot, event.getSimTime()));
362                 //raise new event in the worldView - new emoticon arrived!
363                 worldView.notify(new NewEmoticonEvent(upPl.getId(), actualEmot, event.getSimTime()));                
364             }
365         }
366     };
367 
368     /**
369      * Default constructor.
370      * @param agent
371      */
372     public Emoticons(UT2004Bot agent) {
373         super(agent);
374         agent.getWorldView().addObjectListener(Self.class, storeSelfListener);
375         agent.getWorldView().addObjectListener(Player.class, WorldObjectUpdatedEvent.class, playersListener);
376     }
377 
378 }