View Javadoc

1   package cz.cuni.amis.pogamut.sposh;
2   
3   import java.lang.reflect.Method;
4   import java.util.ArrayList;
5   import java.util.List;
6   
7   import cz.cuni.amis.pogamut.sposh.executor.ActionResult;
8   
9   
10  /**
11   * Base class for definitions of senses and acts of SPOSH bot.
12   * <p/>
13   * User will implement actions and senses used in the plan by deriving this
14   * class and by creating senses and actions for SPOSH plan in following fashion:
15   * <p>
16   * actions are methods annotated with @SPOSHAction annotation. Name of method is
17   * arbitrary and return type should one of the standard ones (String + numbers).
18   * SPOSH engine will use toString() method for the return values of user defined 
19   * classes (probably), but because there are some issues with jython-java
20   * interaction, it may produce some weird bugs.
21   * <ul>
22   *   <li>in plan file: shoot</li>
23   *   <li>in behaviour: @SPOSHAction public void shoot()</li>
24   * </ul>
25   * Sense is a method returning value annotated with @SPOSHSense. Name and return
26   * restrictions are similar to action.
27   * <ul>
28   *   <li>in plan file: hear</li>
29   *   <li>in behaviour: @SPOSHSense public boolean hearNoise()</li>
30   * </ul>
31   *
32   * For simplest action see {@link JavaBehaviour#doNothing()} or sense {@link JavaBehaviour#fail()}.
33   *
34   * The actions can utilize log, that is available through {@code log} member of class
35   * (it is a {@link AgentLogger} of the SPOSH bot.
36   *
37   * This basic class (as well all derived ones) implements following actions
38   * <ul>
39   *   <li>doNothing</li>
40   * </ul>
41   * and senses
42   * <ul>
43   *   <li>fail</li>
44   *   <li>succeed</li>
45   * </ul>
46   *
47   * @author Honza
48   * @author Jimmy
49   */
50  public class JavaBehaviour<AGENT> {
51  
52      private String name = "behaviour";
53      private String[] actions = null;
54      private String[] senses = null;   
55      protected AGENT bot = null;
56  
57   //
58   // 2nd CHANGE (ubrani parametru IAgentLogger)
59   //
60      
61      /**
62       * Create new behaviour.
63       * @param name Name of behaviour so it is easy to distinguish between 
64       *             different behaviours classes in the log and error messages
65       * @param bot Class of the bot that this behaviour is serving. 
66       *            Used by sense and actions for gathering info and manipulation of the bot.
67       */
68      public JavaBehaviour(String name, AGENT bot) {
69          this.name = name;
70          this.bot = bot;
71          this.getActions();
72          this.getSenses();
73      }
74      
75      /**
76       * Get name of the behaviour specified in the constructor.
77       * @return Name of the behaviour
78       */
79      public String getName() {
80          return this.name;
81      }
82  
83      /**
84       * Returns list of actions that are declared in the behaviour class. Search
85       * for the actions is performed only on first execution of method.
86       * <p>
87       * Use Java Reflection API to search through the methods for methods
88       * with&nbsp;annotations @SPOSHActions and return list of strings
89       * that contains the methods.
90       * @return list with names of actions methods
91       */
92      public String[] getActions() {
93          if (this.actions != null) {
94              return this.actions;
95          }
96  
97          Method methods[] = this.getClass().getMethods();
98          List<String> result = new ArrayList<String>();
99  
100         for (Method method : methods) {
101             if (method.isAnnotationPresent(SPOSHAction.class)) {
102                 result.add(method.getName());
103             }
104         }
105         this.actions = result.toArray(new String[0]);
106         return this.actions;
107     }
108 
109     /**
110      * Returns list of senses that are declared in the behaviour class. Search
111      * for the senses is performed only on first execution of method.
112      * <p>
113      * Use Java Reflection API to search through the methods for methods 
114      * with&nbsp;annotations @SPOSHSense and return list of strings
115      * that contains the methods.
116      * @return list with names of sense methods
117      */
118     public String[] getSenses() {
119         if (this.senses != null) {
120             return this.senses;
121         }
122         Method methods[] = this.getClass().getMethods();
123         List<String> result = new ArrayList<String>();
124         for (Method method : methods) {
125             if (method.isAnnotationPresent(SPOSHSense.class)) {
126                 result.add(method.getName());
127             }
128         }
129         this.senses = result.toArray(new String[0]);
130         return this.senses;
131     }
132 
133     /**
134      * Standard action that has to be implemented everywhere. Sleep for 250ms.
135      * @return true
136      */
137     @SPOSHAction
138     public ActionResult doNothing() {
139         try {
140             Thread.sleep(50);
141         } catch (InterruptedException e) {
142         }
143         return ActionResult.FINISHED;
144     }
145 
146     /**
147      * Standard sense that has to be implemented everywhere.
148      * @return false
149      */
150     @SPOSHSense
151     public boolean fail() {
152         return false;
153     }
154 
155     /**
156      * Standard sense that has to be implemented everywhere.
157      * @return true
158      */
159     @SPOSHSense
160     public boolean succeed() {
161         return true;
162     }
163     
164     /**
165 	 * Method that is triggered every time the plan for executor is evaluated. It is triggered right before the plan evaluation. 
166 	 */
167 	public void logicBeforePlan() {		
168 	}
169 	
170 	/**
171 	 * Method that is triggered every time the plan for executor is evaluated. It is triggered right after the plan evaluation. 
172 	 */
173 	public void logicAfterPlan() {		
174 	}
175 	
176 	/**
177 	 * Returns underlying AGENT instance.
178 	 * @return
179 	 */
180 	public AGENT getBot() {
181 		return bot;
182 	}
183 	
184 }