diff --git a/src/as/com/threerings/crowd/chat/client/ChatDirector.as b/src/as/com/threerings/crowd/chat/client/ChatDirector.as index 099bccaed..7c342b263 100644 --- a/src/as/com/threerings/crowd/chat/client/ChatDirector.as +++ b/src/as/com/threerings/crowd/chat/client/ChatDirector.as @@ -26,6 +26,7 @@ import mx.collections.ArrayCollection; import com.threerings.util.ArrayUtil; import com.threerings.util.HashMap; import com.threerings.util.Map; +import com.threerings.util.ObserverList; import com.threerings.util.ResultListener; import com.threerings.util.StringUtil; @@ -102,6 +103,16 @@ public class ChatDirector extends BasicDirector registerCommandHandler(msg, "tell", new TellHandler()); } + /** + * 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. + */ + public function pushChatDisplay (display :ChatDisplay) :void + { + _displays.add(display, 0); + } + /** * Adds the supplied chat display to the chat display list. It will * subsequently be notified of incoming chat messages as well as tell @@ -109,9 +120,7 @@ public class ChatDirector extends BasicDirector */ public function addChatDisplay (display :ChatDisplay) :void { - if (-1 == _displays.getItemIndex(display)) { - _displays.addItem(display); - } + _displays.add(display); } /** @@ -120,10 +129,7 @@ public class ChatDirector extends BasicDirector */ public function removeChatDisplay (display :ChatDisplay) :void { - var idx :int = _displays.getItemIndex(display); - if (idx != -1) { - _displays.removeItemAt(idx); - } + _displays.remove(display); } /** @@ -227,9 +233,9 @@ public class ChatDirector extends BasicDirector */ public function clearDisplays () :void { - for (var ii :int = 0; ii < _displays.length; ii++) { - (_displays.getItemAt(ii) as ChatDisplay).clear(); - } + _displays.apply(function (disp :ChatDisplay) :void { + disp.clear(); + }); } /** @@ -278,9 +284,12 @@ public class ChatDirector extends BasicDirector */ public function dispatchMessage (message :ChatMessage) :void { - for each (var display :ChatDisplay in _displays) { - display.displayMessage(message); - } + var displayed :Boolean = false; + _displays.apply(function (disp :ChatDisplay) :void { + if (disp.displayMessage(message, displayed)) { + displayed = true; + } + }); } /** @@ -986,7 +995,7 @@ public class ChatDirector extends BasicDirector protected var _clobj :ClientObject; /** A list of registered chat displays. */ - protected var _displays :ArrayCollection = new ArrayCollection(); + protected var _displays :ObserverList = new ObserverList(); /** A list of registered chat filters. */ // protected ObserverList _filters = diff --git a/src/as/com/threerings/crowd/chat/client/ChatDisplay.as b/src/as/com/threerings/crowd/chat/client/ChatDisplay.as index 08f3d06c8..56b432f80 100644 --- a/src/as/com/threerings/crowd/chat/client/ChatDisplay.as +++ b/src/as/com/threerings/crowd/chat/client/ChatDisplay.as @@ -39,7 +39,9 @@ public interface ChatDisplay * Called to display a chat message. * * @see ChatMessage + * @return true if the message was displayed here. */ - function displayMessage (msg :ChatMessage) :void; + function displayMessage ( + msg :ChatMessage, alreadyDisplayed :Boolean) :Boolean; } } diff --git a/src/as/com/threerings/mx/controls/ChatDisplayBox.as b/src/as/com/threerings/mx/controls/ChatDisplayBox.as index a810f541d..1a0eb51dd 100644 --- a/src/as/com/threerings/mx/controls/ChatDisplayBox.as +++ b/src/as/com/threerings/mx/controls/ChatDisplayBox.as @@ -37,7 +37,8 @@ public class ChatDisplayBox extends TextArea } // documentation inherited from interface ChatDisplay - public function displayMessage (msg :ChatMessage) :void + public function displayMessage ( + msg :ChatMessage, alreadyDisplayed :Boolean) :Boolean { if (!_scrollBot) { _scrollBot = (verticalScrollPosition == maxVerticalScrollPosition); @@ -49,6 +50,7 @@ public class ChatDisplayBox extends TextArea (msg as UserMessage).speaker + "> "; } this.htmlText += msg.message; + return true; } override public function parentChanged (p :DisplayObjectContainer) :void diff --git a/src/as/com/threerings/util/ObserverList.as b/src/as/com/threerings/util/ObserverList.as index f89f44313..424ee89a4 100644 --- a/src/as/com/threerings/util/ObserverList.as +++ b/src/as/com/threerings/util/ObserverList.as @@ -25,14 +25,24 @@ public class ObserverList /** * Add an observer to this list. + * + * @param index the index at which to add the observer, or -1 for the end. */ - public function add (observer :Object) :void + public function add (observer :Object, index :int = -1) :void { if (!ArrayUtil.contains(_list, observer)) { - _list.push(observer); + _list.splice(index, 0, observer); // -1 to splice means "end" } } + /** + * Return the size of the list. + */ + public function size () :int + { + return _list.length; + } + /** * Remove an observer from this list. */