package eis.eis2java.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Collection;
import eis.eis2java.environment.AbstractEnvironment;
import eis.eis2java.handlers.DefaultPerceptHandler;
import eis.eis2java.translation.Filter;
import eis.eis2java.translation.Java2Parameter;
import eis.eis2java.util.AllPerceptsModule;
import eis.iilang.Percept;
/**
* Annotation for methods that generate a percept. The method must not take any
* parameters but is allowed to return any value for which a
* {@link Java2Parameter} translator has been registered.
* <p>
* {@link @AsPercept} tags have four parameters:
* <ol>
* <li>name: the name of the percept to be returned
* <li>multiplePercepts: true when the percept function returns a List of
* (translatable) Objects, and each of the elements in the list should give
* another percept. E.g. "on" returning [1,2] gives the percepts {on(1), on(2)}.
* <li>multipleArguments: true when the percept function returns a List of
* (translatable) objects, and each of the elements of the list should be put as
* another argument in the percept. E.g., "on" returning [1,2] gives the percept
* on(1,2).
* <li>filter. One of Filter.Type.ALWAYS, ONCE, ONCHANGE or ONCHANGENEG.
* <li>event. True when the percepts are event based and the results from all
* calls to this method should be passed to the agent.
* </ol>
*
* <p>
* It is possible to combine multiplePercepts and multipleArguments, in which
* case the function should return a list of lists. The outside list is used for
* the multiplePercepts, the inner for the multipleArguments. E.g., "on"
* returning [[1,2],[3,4,5]] then results in the percepts {on(1,2),on(3,4,5)}.
* </p>
*
* The filter type determines the way percepts are filtered before sending out
* through EIS:
* <p>
* <TABLE border='1'>
* <thead>
* <tr>
* <th>filter name</th>
* <th>full name</th>
* <th>behaviour</th>
* </tr>
* </thead> <tbody>
* <tr>
* <td>ALWAYS</td>
* <td>send always</td>
* <td>send percepts every round</td>
* </tr>
* <tr>
* <td>ONCE</td>
* <td>send one time</td>
* *
* <td>send percepts only the first round</td>
* </tr>
* <tr>
* <td>ON_CHANGE</td>
* <td>send when changed</td>
* <td>send percept(s), but only if any of the percepts changes</td>
* </tr>
* <tr>
* <td>ON_CHANGE_NEG</td>
* <td>send on change using 'not'</td>
* <td>if percept p is new then send p; if percept p was removed and
* (multiplePercepts=true or (multiple=false and p became null)) then send
* not(p)</td>
* </tr>
* </tbody>
* </table>
* <p>
* <em>
* Important: </em>the {@link AbstractEnvironment} compares old and new percepts
* based on the {@link Object} that is returned, not based on the translator
* result. This is to avoid extra overhead of translation. This means that you
* <em>must return</em> a static (non-changing) object as percept, and that that
* percept object must have a functioning equals.
* </p>
*
* @author Lennard de Rijk
* @author W.Pasman 27sep2011 added filter annotation
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AsPercept {
/** The name of the {@link Percept} when generated */
String name();
/**
* If defined as true the return value of the annotated function must be of
* type {@link Collection}. The return value will be used to generate
* multiple percepts with the same name.
*/
boolean multiplePercepts() default false;
/**
* if defined as true the return value of the annotated function must be of
* type {@link Collection}. The return value will be used to generate
* multiple arguments for the percept. If {@link #multiplePercepts()} is
* also true, {@link #multiplePercepts()} takes the outer {@link Collection}
* , and each element inside that collection is a {@link Collection} for
* multipleActions.
*
* @return
*/
boolean multipleArguments() default false;
Filter.Type filter() default Filter.Type.ALWAYS;
/**
* If defined as true the method returns a list of events that have occurred
* since its last invocation. This flag is used by {@link AllPerceptsModule}
* to ensure that all events on each update are stored passed on to the
* environment as a batch. This setting has no effect on the
* {@link DefaultPerceptHandler}.
*
*/
boolean event() default false;
}