Use observer lists, and remove code to disallow adding observers more than

once since the observer list now takes care of that.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2062 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Walter Korman
2002-12-12 23:54:27 +00:00
parent 3d2e98f7da
commit ce8fe382a3
2 changed files with 118 additions and 50 deletions
@@ -1,16 +1,19 @@
// //
// $Id: ChatDirector.java,v 1.40 2002/11/13 01:29:41 ray Exp $ // $Id: ChatDirector.java,v 1.41 2002/12/12 23:54:27 shaper Exp $
package com.threerings.crowd.chat; package com.threerings.crowd.chat;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import com.samskivert.util.HashIntMap; import com.samskivert.util.HashIntMap;
import com.samskivert.util.ObserverList;
import com.threerings.presents.client.*; import com.threerings.presents.client.BasicDirector;
import com.threerings.presents.dobj.*; import com.threerings.presents.client.Client;
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.MessageEvent;
import com.threerings.presents.dobj.MessageListener;
import com.threerings.util.MessageBundle; import com.threerings.util.MessageBundle;
import com.threerings.util.MessageManager; import com.threerings.util.MessageManager;
@@ -30,8 +33,8 @@ public class ChatDirector extends BasicDirector
implements ChatCodes, LocationObserver, MessageListener, ChatReceiver implements ChatCodes, LocationObserver, MessageListener, ChatReceiver
{ {
/** /**
* An interface that can receive information about the {@link * An interface to receive information about the {@link #MAX_CHATTERS}
* #MAX_CHATTERS} most recent users that we've been chatting with. * most recent users that we've been chatting with.
*/ */
public static interface ChatterObserver public static interface ChatterObserver
{ {
@@ -42,12 +45,13 @@ public class ChatDirector extends BasicDirector
} }
/** /**
* A validator for adding usernames to the chatter list. * An interface for those who would like to validate whether usernames
* may be added to the chatter list.
*/ */
public static interface ChatterValidator public static interface ChatterValidator
{ {
/** /**
* Returns true if the username can be added to the chatters list. * Returns whether the username may be added to the chatters list.
*/ */
public boolean isChatterValid (String username); public boolean isChatterValid (String username);
} }
@@ -71,9 +75,6 @@ public class ChatDirector extends BasicDirector
_ctx.getClient().getInvocationDirector().registerReceiver( _ctx.getClient().getInvocationDirector().registerReceiver(
new ChatDecoder(this)); new ChatDecoder(this));
// watch the session, clear displays when the user logs off.
_ctx.getClient().addClientObserver(this);
// register ourselves as a location observer // register ourselves as a location observer
_ctx.getLocationDirector().addLocationObserver(this); _ctx.getLocationDirector().addLocationObserver(this);
} }
@@ -96,11 +97,6 @@ public class ChatDirector extends BasicDirector
*/ */
public void addChatDisplay (ChatDisplay display) public void addChatDisplay (ChatDisplay display)
{ {
if (_displays.contains(display)) {
Log.warning("Tried to add ChatDisplay more than once!");
Log.logStackTrace(new Exception());
return;
}
_displays.add(display); _displays.add(display);
} }
@@ -182,14 +178,18 @@ public class ChatDirector extends BasicDirector
} }
/** /**
* Notify ChatterObservers that the list of chatters has changed. * Notifies all registered {@link ChatterObserver}s that the list of
* chatters has changed.
*/ */
protected void notifyChatterObservers () protected void notifyChatterObservers ()
{ {
for (int ii=0, nn=_chatterObservers.size(); ii < nn; ii++) { _chatterObservers.apply(new ObserverList.ObserverOp() {
ChatterObserver co = (ChatterObserver) _chatterObservers.get(ii); public boolean apply (Object observer) {
co.chattersUpdated(_chatters.listIterator()); ((ChatterObserver)observer).chattersUpdated(
} _chatters.listIterator());
return true;
}
});
} }
/** /**
@@ -197,9 +197,12 @@ public class ChatDirector extends BasicDirector
*/ */
public void clearDisplays () public void clearDisplays ()
{ {
for (int ii=0, nn=_displays.size(); ii < nn; ii++) { _displays.apply(new ObserverList.ObserverOp() {
((ChatDisplay) _displays.get(ii)).clear(); public boolean apply (Object observer) {
} ((ChatDisplay)observer).clear();
return true;
}
});
} }
/** /**
@@ -301,10 +304,10 @@ public class ChatDirector extends BasicDirector
SpeakService speakService, String message, byte mode) SpeakService speakService, String message, byte mode)
{ {
// make sure they can say what they want to say // make sure they can say what they want to say
for (Iterator iter = _validators.iterator(); iter.hasNext(); ) { _validateMessageOp.setMessage(message);
if (!((ChatValidator) iter.next()).validateSpeak(message)) { _validators.apply(_validateMessageOp);
return; if (!_validateMessageOp.isValid()) {
} return;
} }
// dispatch a speak request using the supplied speak service // dispatch a speak request using the supplied speak service
@@ -339,11 +342,10 @@ public class ChatDirector extends BasicDirector
public void requestTell (final String target, final String message) public void requestTell (final String target, final String message)
{ {
// make sure they can say what they want to say // make sure they can say what they want to say
for (Iterator iter = _validators.iterator(); iter.hasNext(); ) { _validateMessageOp.setMessage(target, message);
if (!((ChatValidator) iter.next()).validateTell( _validators.apply(_validateMessageOp);
target, message)) { if (!_validateMessageOp.isValid()) {
return; return;
}
} }
// create a listener that will report success or failure // create a listener that will report success or failure
@@ -537,11 +539,10 @@ public class ChatDirector extends BasicDirector
/** /**
* Dispatches the provided message to our chat displays. * Dispatches the provided message to our chat displays.
*/ */
protected void dispatchMessage (ChatMessage msg) protected void dispatchMessage (ChatMessage message)
{ {
for (Iterator iter = _displays.iterator(); iter.hasNext(); ) { _displayMessageOp.setMessage(message);
((ChatDisplay) iter.next()).displayMessage(msg); _displays.apply(_displayMessageOp);
}
} }
/** /**
@@ -596,6 +597,61 @@ public class ChatDirector extends BasicDirector
_cservice = null; _cservice = null;
} }
/**
* An operation that checks with all chat validators to determine
* whether chat messages are valid for display.
*/
protected static class ValidateMessageOp implements ObserverList.ObserverOp
{
public boolean isValid ()
{
return _valid;
}
public void setMessage (String message)
{
setMessage(null, message);
}
public void setMessage (String target, String message)
{
_target = target;
_message = message;
_valid = true;
}
public boolean apply (Object observer)
{
if (_target == null) {
_valid = ((ChatValidator)observer).validateSpeak(_message);
} else {
_valid = ((ChatValidator)observer).validateTell(
_target, _message);
}
return _valid;
}
protected String _target;
protected String _message;
protected boolean _valid;
}
protected static class DisplayMessageOp implements ObserverList.ObserverOp
{
public void setMessage (ChatMessage message)
{
_message = message;
}
public boolean apply (Object observer)
{
((ChatDisplay)observer).displayMessage(_message);
return true;
}
protected ChatMessage _message;
}
/** Our active chat context. */ /** Our active chat context. */
protected CrowdContext _ctx; protected CrowdContext _ctx;
@@ -612,10 +668,12 @@ public class ChatDirector extends BasicDirector
protected PlaceObject _place; protected PlaceObject _place;
/** A list of registered chat displays. */ /** A list of registered chat displays. */
protected ArrayList _displays = new ArrayList(); protected ObserverList _displays =
new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
/** A list of registered chat validators. */ /** A list of registered chat validators. */
protected ArrayList _validators = new ArrayList(); protected ObserverList _validators =
new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
/** A mapping from auxiliary chat objects to the types under which /** A mapping from auxiliary chat objects to the types under which
* they are registered. */ * they are registered. */
@@ -631,11 +689,18 @@ public class ChatDirector extends BasicDirector
protected LinkedList _chatters = new LinkedList(); protected LinkedList _chatters = new LinkedList();
/** Observers that are watching our chatters list. */ /** Observers that are watching our chatters list. */
protected ArrayList _chatterObservers = new ArrayList(); protected ObserverList _chatterObservers =
new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
/** Used by {@link #nextRequestId}. */ /** Used by {@link #nextRequestId}. */
protected int _requestId; protected int _requestId;
/** Operation used to validate chat messages for display. */
protected ValidateMessageOp _validateMessageOp = new ValidateMessageOp();
/** Operation used to display chat messages. */
protected DisplayMessageOp _displayMessageOp = new DisplayMessageOp();
/** The maximum number of chatter usernames to track. */ /** The maximum number of chatter usernames to track. */
protected static final int MAX_CHATTERS = 6; protected static final int MAX_CHATTERS = 6;
} }
@@ -1,11 +1,12 @@
// //
// $Id: MuteDirector.java,v 1.4 2002/10/28 00:22:38 ray Exp $ // $Id: MuteDirector.java,v 1.5 2002/12/12 23:54:27 shaper Exp $
package com.threerings.crowd.chat; package com.threerings.crowd.chat;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import com.samskivert.util.ObserverList;
import com.threerings.crowd.util.CrowdContext; import com.threerings.crowd.util.CrowdContext;
import com.threerings.presents.client.BasicDirector; import com.threerings.presents.client.BasicDirector;
@@ -56,9 +57,7 @@ public class MuteDirector extends BasicDirector
*/ */
public void addMuteObserver (MuteObserver obs) public void addMuteObserver (MuteObserver obs)
{ {
if (!_observers.contains(obs)) { _observers.add(obs);
_observers.add(obs);
}
} }
/** /**
@@ -107,11 +106,14 @@ public class MuteDirector extends BasicDirector
/** /**
* Notify our observers of a change in the mutelist. * Notify our observers of a change in the mutelist.
*/ */
protected void notifyObservers (String username, boolean muted) protected void notifyObservers (final String username, final boolean muted)
{ {
for (int ii=0, nn=_observers.size(); ii < nn; ii++) { _observers.apply(new ObserverList.ObserverOp() {
((MuteObserver) _observers.get(ii)).muteChanged(username, muted); public boolean apply (Object observer) {
} ((MuteObserver)observer).muteChanged(username, muted);
return true;
}
});
} }
// documentation inherited // documentation inherited
@@ -130,5 +132,6 @@ public class MuteDirector extends BasicDirector
protected HashSet _mutelist = new HashSet(); protected HashSet _mutelist = new HashSet();
/** List of mutelist observers. */ /** List of mutelist observers. */
protected ArrayList _observers = new ArrayList(); protected ObserverList _observers =
new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
} }