From 1471e82f3a7c37484857487099faee2b2610b92f Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 14 Oct 2010 16:19:17 +0000 Subject: [PATCH] Provide a HistoryList mechanism down here in the basic service. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6194 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../crowd/chat/client/ChatDirector.java | 48 ++++--- .../crowd/chat/client/HistoryList.java | 127 ++++++++++++++++++ 2 files changed, 160 insertions(+), 15 deletions(-) create mode 100644 src/java/com/threerings/crowd/chat/client/HistoryList.java diff --git a/src/java/com/threerings/crowd/chat/client/ChatDirector.java b/src/java/com/threerings/crowd/chat/client/ChatDirector.java index 04b64b713..fc6b24fb0 100644 --- a/src/java/com/threerings/crowd/chat/client/ChatDirector.java +++ b/src/java/com/threerings/crowd/chat/client/ChatDirector.java @@ -154,21 +154,6 @@ public class ChatDirector extends BasicDirector registerCommandHandlers(); } - /** - * Registers all the chat-command handlers. - */ - protected void registerCommandHandlers () - { - MessageBundle msg = _ctx.getMessageManager().getBundle(_bundle); - registerCommandHandler(msg, "help", new HelpHandler()); - registerCommandHandler(msg, "clear", new ClearHandler()); - registerCommandHandler(msg, "speak", new SpeakHandler()); - registerCommandHandler(msg, "emote", new EmoteHandler()); - registerCommandHandler(msg, "think", new ThinkHandler()); - registerCommandHandler(msg, "tell", new TellHandler()); - registerCommandHandler(msg, "broadcast", new BroadcastHandler()); - } - /** * Adds the supplied chat display to the front of the chat display list. It will subsequently * be notified of incoming chat messages as well as tell responses. @@ -599,6 +584,21 @@ public class ChatDirector extends BasicDirector _auxes.remove(source.getOid()); } + /** + * Returns the history list containing a trailing window of messages that have passed through + * this chat director. The history list is created on demand so that systems which don't make + * use of chat history need not incur the overhead of tracking historical chat messages. Thus + * messages will only be added to the history after this method has been called at + * least once. + */ + public HistoryList getHistory () + { + if (_hlist == null) { + addChatDisplay(_hlist = new HistoryList()); + } + return _hlist; + } + /** * Run a message through all the currently registered filters. */ @@ -702,6 +702,21 @@ public class ChatDirector extends BasicDirector _cservice = null; } + /** + * Registers all the chat-command handlers. + */ + protected void registerCommandHandlers () + { + MessageBundle msg = _ctx.getMessageManager().getBundle(_bundle); + registerCommandHandler(msg, "help", new HelpHandler()); + registerCommandHandler(msg, "clear", new ClearHandler()); + registerCommandHandler(msg, "speak", new SpeakHandler()); + registerCommandHandler(msg, "emote", new EmoteHandler()); + registerCommandHandler(msg, "think", new ThinkHandler()); + registerCommandHandler(msg, "tell", new TellHandler()); + registerCommandHandler(msg, "broadcast", new BroadcastHandler()); + } + /** * Processes and dispatches the specified chat message. */ @@ -1443,6 +1458,9 @@ public class ChatDirector extends BasicDirector /** Operation used to display chat messages. */ protected DisplayMessageOp _displayMessageOp = new DisplayMessageOp(); + /** A rolling chat history, or null if {@link #getHistory} is never called. */ + protected HistoryList _hlist; + /** Registered chat command handlers. */ protected static HashMap _handlers = Maps.newHashMap(); diff --git a/src/java/com/threerings/crowd/chat/client/HistoryList.java b/src/java/com/threerings/crowd/chat/client/HistoryList.java new file mode 100644 index 000000000..304fa955e --- /dev/null +++ b/src/java/com/threerings/crowd/chat/client/HistoryList.java @@ -0,0 +1,127 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.crowd.chat.client; + +import java.util.ArrayList; + +import com.samskivert.util.ObserverList; + +import com.threerings.crowd.chat.data.ChatMessage; + +/** + * Stores chat history. + */ +public class HistoryList extends ArrayList + implements ChatDisplay +{ + /** An interface for chat history observers. */ + public interface Observer { + /** Called when messages have been added or removed from the chat history. + * @param adjustment the number of messages that have been added (+) or removed (-). */ + void historyUpdated (int adjustment); + } + + // documentation inherited from interface + public boolean displayMessage (ChatMessage msg, boolean alreadyDisplayed) + { + // see if we're full, and if so, clear out a bunch of old stuff + int adjusted; + if (size() == MAX_HISTORY) { + removeRange(0, PRUNE_HISTORY); + adjusted = PRUNE_HISTORY; + + } else { + adjusted = 0; + } + + // add the message to the history + add(msg); + + // notify observers that something changed + notify(adjusted); + + return true; + } + + @Override + public void clear () + { + // see how many entries we're clearing out.. + int adjusted = size(); + super.clear(); + + // and notify the chat displays of that fact + notify(adjusted); + } + + /** + * Adds an {@link Observer} that wants to know about changes to the history. + */ + public void addObserver (Observer obs) + { + _obs.add(obs); + } + + /** + * Removes a {@link Observer} from hearing about changes to the history. + */ + public void removeObserver (Observer obs) + { + _obs.remove(obs); + } + + /** + * Notifies listening {@link Observer}s that there has been a change to this history. + */ + protected void notify (int adjustment) + { + _historyUpdatedOp.setAdjustment(adjustment); + _obs.apply(_historyUpdatedOp); + } + + protected static class HistoryUpdatedOp + implements ObserverList.ObserverOp + { + public void setAdjustment (int adjustment) { + _adjustment = adjustment; + } + + public boolean apply (Observer obs) { + obs.historyUpdated(_adjustment); + return true; + } + + protected int _adjustment; + } + + /** A list of {@link Observer}s interested in history changes. */ + protected ObserverList _obs = ObserverList.newFastUnsafe(); + + /** An operation used to notify observers of history updates. */ + protected HistoryList.HistoryUpdatedOp _historyUpdatedOp = new HistoryUpdatedOp(); + + /** The maximum number of history entries we'll keep. */ + protected static final int MAX_HISTORY = 2000; + + /** The number of history entries we'll prune when we hit the max. */ + protected static final int PRUNE_HISTORY = 200; +}