package com.laytonsmith.core.events; import com.laytonsmith.annotations.core; import com.laytonsmith.core.Documentation; import com.laytonsmith.core.ParseTree; import com.laytonsmith.core.constructs.CArray; import com.laytonsmith.core.constructs.Construct; import com.laytonsmith.core.constructs.Target; import com.laytonsmith.core.environments.Environment; import com.laytonsmith.core.events.BoundEvent.ActiveEvent; import com.laytonsmith.core.exceptions.EventException; import com.laytonsmith.core.exceptions.PrefilterNonMatchException; import java.util.Map; /** * This interface should be implemented to allow the bind() function to bind to * a particular event type. To be recognized as an event type, it should also tag * itself with @api, and it will be included in the EventList. */ public interface Event extends Comparable<Event>, Documentation{ /** * This should return the name of the event. * @return */ @Override public String getName(); /** * This should return the docs that are used in the wiki. The format should * be as follows: {prefilter: explanation | ...} Documentation {event_obj: explanation | ...} * The explanation for the prefilter may follow certain formatting, which will expand to a link: * <string match><br /> * <regex><br /> * <math match><br /> * <expr> * @return */ @Override public String docs(); /** * This function should return true if the event code should be run, based * on this prefilter and triggering event's parameters. * @param prefilter The prefilter map, provided by the script * @param e The bindable event itself * @return True, iff the event code should be run * @throws com.laytonsmith.core.exceptions.PrefilterNonMatchException Equivalent * to returning false, though throwing an exception is sometimes easier, given * that lower level code may be handling the prefilter match. */ public boolean matches(Map<String, Construct> prefilter, BindableEvent e) throws PrefilterNonMatchException; /** * If an event is manually triggered, then it may be required for an event * object to be faked, so the rest of the event will work properly. * @param manualObject * @param t * @return */ public BindableEvent convert(CArray manualObject, Target t); /** * This function is called when an event is triggered. It passes the event, and expects * back a Map, which will be converted into a CArray, and passed to the bound event, * as the event object. If an EventException is thrown, it is considered a fatal error, * and will throw an uncatchable CH exception. * @param e The bindable event * @return The map build from the event * @throws com.laytonsmith.core.exceptions.EventException If some exception occurs * during map building */ public Map<String, Construct> evaluate(BindableEvent e) throws EventException; /** * This is called to determine if an event is cancellable in the first place * @param e * @return */ public boolean isCancellable(BindableEvent e); /** * This is called if the script attempts to cancel the event, so the underlying * event can also be cancelled. If the underlying event is not cancellable, this * should throw an EventException, which is caught in the triggering code, and * at this time ignored. * @param e The bindable event * @param state True, if the event should be cancelled, false if it should be uncancelled. * @throws com.laytonsmith.core.exceptions.EventException If the event isn't cancellable */ public void cancel(BindableEvent e, boolean state) throws EventException; /** * This function returns the "driver" class of the event needed to trigger it. * Though not strictly needed, this method helps optimize code. All events may * more strictly filter events based on other conditions, but all events must * have a single Type of event that drives the CH event. This is also the type of * the event that will be sent to the matches function. * @return The underlying driver for this event */ public Driver driver(); /** * This function is called once a script binds to this event, which gives * this event type a chance to "activate" if needed. It may throw an * UnsupportedOperationException if it is not needed. The listener * is automatically registered, based on the driver returned. * The BoundEvent is also sent, in case the event can do some further optimization * based on it. * @param event The event that is triggering bind. Things like the prefilters and * environment are available with the event. */ public void bind(BoundEvent event); /** * This function is called once a script unbinds this event. It may throw an * UnsupportedOperationException if it is not needed. The BoundEvent is sent, * in case the event can do some further optimization based on it. * @param event The event that is triggering bind. Things like the prefilters and * environment are available with the event. */ public void unbind(BoundEvent event); /** * This function is called once when the plugin starts up, to give this * event a chance to make a hook into the server if it needs it. * It may throw an UnsupportedOperationException if it is not needed. */ public void hook(); /** * Because an event type knows best how to actually trigger an event, the prebuild, * preconfigured script, and the BoundEvent generating the action are passed to * the Event itself. AbstractEvent's default implementation is to simply run the * script, but an event can choose to override this functionality if needed. * @param s * @param b * @param env * @param activeEvent * @throws com.laytonsmith.core.exceptions.EventException */ public void execute(ParseTree s, BoundEvent b, Environment env, ActiveEvent activeEvent) throws EventException; /** * If it is required to do something extra for server wide events, this can be * done here. This is called when the EventHandler is instructed to manually trigger * this event server-wide. * @param e */ public void manualTrigger(BindableEvent e); /** * If the event is an external event, and there is no reason to attempt a serverwide manual * triggering, this function should return false, in which case the serverWide variable * is ignored, and it is only piped through CH specific handlers. * @return */ public boolean supportsExternal(); /** * Called when a script wishes to modify an event specific parameter, this function * takes a key, a construct, and the underlying event. It returns true if the underlying * event was successfully updated. * @param key * @param value * @param event * @return */ public boolean modifyEvent(String key, Construct value, BindableEvent event); /** * Returns if this event is cancelled. If the event is not cancellable, false should * be returned, though this case shouldn't normally occur, since isCancellable will * be called prior to calling this function. * @param underlyingEvent * @return */ public boolean isCancelled(BindableEvent underlyingEvent); /** * Some events don't need to show up in documentation. Maybe they are experimental, or magic * functions. If they shouldn't show up in the normal API documentation, return false. * @return */ public boolean appearInDocumentation(); /** * When bound, dictates if this event should be added to the bind counter. In most * cases this should be true, but it should be false if this is a "passive" event. * An event added to the counter won't allow the script to halt until it is unbound. * @return */ public boolean addCounter(); /** * Returns whether or not this event, or the event's containing class is * annotated with the {@link core} annotation. * @return */ public boolean isCore(); }