/* This file is part of leafdigital leafChat. leafChat is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. leafChat is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with leafChat. If not, see <http://www.gnu.org/licenses/>. Copyright 2011 Samuel Marshall. */ package leafchat.core.api; /** * Generic object representing communication between plugins. All messages * must extend this class. * <p> * In addition to the visible API below, user-defined message types may include * a public static {@link MessageInfo} member called 'info'. This provides * information for the scripting system. For example, if a message type isn't * appropriate for use as a scripting event, override the MessageInfo to return * false to {@link MessageInfo#allowScripting()}. Here's a code example. * <pre>public static MessageInfo info=new MessageInfo(ErrorIRCMsg.class,"Error", "The server sends this event when you quit or are otherwise disconnected.") { protected void listScriptingVariables(Variables v) { super.listScriptingVariables(v); v.add("message"); } };</pre> */ public abstract class Msg { /** Indicates message should not be further processed */ private boolean stopped; /** * Informative indicator that message has already been 'handled' (displayed * to user etc.) although it is still being passed through */ private boolean handled; /** @return True if message processing has been stopped */ public boolean isStopped() { return stopped; } /** Call to stop further processing */ public void markStopped() { stopped=true; } /** @return True if message has already been 'handled' (usually 'displayed to user') */ public boolean isHandled() { return handled; } /** Call to mark handled; still processed, but marked as already shown to user */ public void markHandled() { handled=true; } /** * Priority constant: * Use where message should be handled last */ public final static int PRIORITY_LAST = 6000; /** * Priority constant: * Use where message should be handled after most handlers, but not * necessarily last */ public final static int PRIORITY_LATE = 8000; /** * Priority constant: * Where message should be handled after normal handlers */ public final static int PRIORITY_AFTERNORMAL = 9000; /** * Priority constant: * Use for default message handling or where order does not matter */ public final static int PRIORITY_NORMAL = 10000; /** * Priority constant: * Where message should be handled before normal handlers */ public final static int PRIORITY_BEFORENORMAL = 11000; /** * Priority constant: * Use where message should be handled before most other handlers */ public final static int PRIORITY_EARLY = 12000; /** * Priority constant: * Use where message should be handled first */ public final static int PRIORITY_FIRST = 14000; private String sequenceName=null; private int sequenceNumber; /** * Associate this message with a particular sequence. There can be any number * of sequences, each with an arbitrary name. A message with number N in * a sequence S will only be dispatched once there are no messages with number * M<N and sequence S in the pending-message queue. (Note that this does not * completely guarantee sequencing in all cases, since the queue could become * empty and then an earlier-sequenced message could be sent.) * @param sequenceName Arbitrary sequence name * @param sequenceNumber Position in sequence */ public void setSequence(String sequenceName,int sequenceNumber) { this.sequenceName=sequenceName; this.sequenceNumber=sequenceNumber; } /** * Indicates that this message should belong to the same sequence as some * other message (i.e. this one is presumably being dispatched in response * to that one). * @param relative Message whose sequence details will be copied. */ public void setSequence(Msg relative) { this.sequenceName=relative.sequenceName; this.sequenceNumber=relative.sequenceNumber; } /** * Checks whether this message ought to run before the message under * consideration. * @param consider Message being considered * @return True if this message should run earlier than the considered one */ public boolean sequenceBefore(Msg consider) { if(sequenceName==null || consider.sequenceName==null) return false; if(!sequenceName.equals(consider.sequenceName)) return false; return sequenceNumber < consider.sequenceNumber; } }