/* * ExperienceMod - Bukkit server plugin for modifying the experience system in Minecraft. * Copyright (C) 2012 Kristian S. Stangeland * * This program 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 2 of * the License, or (at your option) any later version. * * This program 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 this program; * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA */ package com.comphenix.xp.messages; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.commons.lang.NullArgumentException; import org.bukkit.entity.Player; import com.comphenix.xp.Action; import com.comphenix.xp.Debugger; public class MessageQueue { // Map of every message to send in the future private Map<Action, MessageFormatter> lookup = new ConcurrentHashMap<Action, MessageFormatter>(); private Queue<Action> ordered = new ConcurrentLinkedQueue<Action>(); private long messageDelay; private long lastMessageTime; private Debugger debugger; private Player player; private ChannelProvider channelProvider; public MessageQueue(long messageDelay, Player player, ChannelProvider channelProvider, Debugger debugger) { this.player = player; this.channelProvider = channelProvider; this.debugger = debugger; this.messageDelay = messageDelay; this.lastMessageTime = 0; } public Player getPlayer() { return player; } public void setPlayer(Player player) { this.player = player; } public boolean hasPlayer() { return player != null; } public void enqueue(Action action, MessageFormatter formatter) { if (formatter == null) throw new NullArgumentException("formatter"); // Special case if (messageDelay == 0) { transmitt(action, formatter); return; } // Enqueue the message if (lookup.containsKey(action)) { lookup.put(action, MessageFormatter.add(lookup.get(action), formatter)); } else { lookup.put(action, formatter); ordered.add(action); } } public void transmitt(Action action, MessageFormatter formatter) { // Set debugger action.setDebugger(debugger); // Send as player or as a general message if (hasPlayer()) action.emoteMessages(channelProvider, formatter, player); else action.announceMessages(channelProvider, formatter); } /** * Gets the current message delay in milliseconds. * @return Message delay in milliseconds. */ public long getMessageDelay() { return messageDelay; } /** * Sets the message delay in milliseconds. * @param messageDelay The new message delay in milliseconds. */ public void setMessageDelay(long messageDelay) { this.messageDelay = messageDelay; } /** * Whether or not a message can be sent by this player. * @return TRUE if it can, FALSE if not. */ public boolean isReady() { return (System.currentTimeMillis() - lastMessageTime) >= messageDelay; } public ChannelProvider getChannelProvider() { return channelProvider; } public void setChannelProvider(ChannelProvider channelProvider) { this.channelProvider = channelProvider; } public Debugger getDebugger() { return debugger; } /** * Performs message transmissions, if it's ready. */ public void onTick() { // See if we have any messages to transmit if (ordered.size() > 0 && isReady()) { // Always choose the oldest message/composite message Action oldest = ordered.poll(); // Transmit and clean up transmitt(oldest, lookup.get(oldest)); lookup.remove(oldest); lastMessageTime = System.currentTimeMillis(); } } }