Created client-side message objects which are the only thing passed

to the newly simplified ChatDisplay interface, which now has but one method.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1620 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2002-07-26 20:35:02 +00:00
parent ea5e5adbad
commit ef52f31ad4
9 changed files with 231 additions and 259 deletions
@@ -1,9 +1,10 @@
//
// $Id: ChatDirector.java,v 1.27 2002/07/22 22:54:03 ray Exp $
// $Id: ChatDirector.java,v 1.28 2002/07/26 20:35:01 ray Exp $
package com.threerings.crowd.chat;
import java.util.ArrayList;
import java.util.Iterator;
import com.samskivert.util.HashIntMap;
import com.samskivert.util.Tuple;
@@ -11,6 +12,9 @@ import com.samskivert.util.Tuple;
import com.threerings.presents.client.*;
import com.threerings.presents.dobj.*;
import com.threerings.util.MessageBundle;
import com.threerings.util.MessageManager;
import com.threerings.crowd.Log;
import com.threerings.crowd.client.LocationObserver;
import com.threerings.crowd.data.PlaceObject;
@@ -31,10 +35,12 @@ public class ChatDirector
* observer so that it can automatically process place constrained
* chat.
*/
public ChatDirector (CrowdContext ctx)
public ChatDirector (CrowdContext ctx, MessageManager msgmgr, String bundle)
{
// keep the context around
_ctx = ctx;
_msgmgr = msgmgr;
_bundle = bundle;
// register for chat notifications
_ctx.getClient().getInvocationDirector().registerReceiver(
@@ -102,28 +108,41 @@ public class ChatDirector
*/
public void displaySystemMessage (String bundle, String message)
{
displaySystemMessage(PLACE_CHAT_TYPE, bundle, message);
displaySystemMessage(bundle, message, PLACE_CHAT_TYPE);
}
/**
* Requests that the specified system message be dispatched to all
* registered chat displays.
*
* @param type {@link ChatCodes#PLACE_CHAT_TYPE} if the message was
* received on the place object or the type associated with the
* auxiliary chat object on which the message was received.
* @param bundle the message bundle identifier that should be used to
* localize this message.
* @param message the localizable message string.
* @param localtype {@link ChatCodes#PLACE_CHAT_TYPE} if the message was
* received on the place object or the type associated with the
* auxiliary chat object on which the message was received.
*/
public void displaySystemMessage (
String type, String bundle, String message)
String bundle, String message, String localtype)
{
// pass this on to our chat displays
for (int i = 0; i < _displays.size(); i++) {
ChatDisplay display = (ChatDisplay)_displays.get(i);
display.displaySystemMessage(type, bundle, message);
}
dispatchMessage(new SystemMessage(xlate(bundle, message), localtype));
}
/**
* Display a feedback message.
*/
public void displayFeedbackMessage (String bundle, String message)
{
displayFeedbackMessage(bundle, message, PLACE_CHAT_TYPE);
}
/**
* Display a feedback message.
*/
public void displayFeedbackMessage (String bundle, String message,
String localtype)
{
dispatchMessage(new FeedbackMessage(xlate(bundle, message), localtype));
}
/**
@@ -145,8 +164,8 @@ public class ChatDirector
}
// make sure they can say what they want to say
for (int ii = 0; ii < _validators.size(); ii++) {
if (!((ChatValidator)_validators.get(ii)).validateSpeak(message)) {
for (Iterator iter = _validators.iterator(); iter.hasNext(); ) {
if (!((ChatValidator) iter.next()).validateSpeak(message)) {
return -1;
}
}
@@ -179,8 +198,8 @@ public class ChatDirector
public int requestTell (String target, String message)
{
// make sure they can say what they want to say
for (int ii = 0; ii < _validators.size(); ii++) {
if (!((ChatValidator)_validators.get(ii)).validateTell(
for (Iterator iter = _validators.iterator(); iter.hasNext(); ) {
if (!((ChatValidator) iter.next()).validateTell(
target, message)) {
return -1;
}
@@ -198,11 +217,14 @@ public class ChatDirector
* chat director assumes the caller will be managing the subscription
* to this object and will remain subscribed to it for as long as it
* remains in effect as an auxiliary chat source.
*
* @param localtype a type to be associated with all chat messages
* that arrive on the specified DObject.
*/
public void addAuxiliarySource (String type, DObject source)
public void addAuxiliarySource (DObject source, String localtype)
{
source.addListener(this);
_auxes.put(source.getOid(), type);
_auxes.put(source.getOid(), localtype);
}
/**
@@ -247,9 +269,11 @@ public class ChatDirector
{
String name = event.getName();
if (name.equals(ChatService.SPEAK_NOTIFICATION)) {
handleSpeakMessage(getType(event.getTargetOid()), event.getArgs());
handleSpeakMessage(getLocalType(event.getTargetOid()),
event.getArgs());
} else if (name.equals(ChatService.SYSTEM_NOTIFICATION)) {
handleSystemMessage(getType(event.getTargetOid()), event.getArgs());
handleSystemMessage(getLocalType(event.getTargetOid()),
event.getArgs());
}
}
@@ -263,11 +287,8 @@ public class ChatDirector
return;
}
// pass this on to our chat displays
for (int i = 0; i < _displays.size(); i++) {
ChatDisplay display = (ChatDisplay)_displays.get(i);
display.displayTellMessage(source, null, message);
}
dispatchMessage(new UserMessage(message, ChatCodes.TELL_CHAT_TYPE,
source, ChatCodes.DEFAULT_MODE));
}
/**
@@ -280,11 +301,7 @@ public class ChatDirector
public void handleTellNotification (
String source, String bundle, String message)
{
// pass this on to our chat displays
for (int i = 0; i < _displays.size(); i++) {
ChatDisplay display = (ChatDisplay)_displays.get(i);
display.displayTellMessage(source, bundle, message);
}
handleTellNotification(source, xlate(bundle, message));
}
/**
@@ -304,10 +321,8 @@ public class ChatDirector
// pass this on to our chat displays
String target = (String)tup.left, message = (String)tup.right;
for (int i = 0; i < _displays.size(); i++) {
ChatDisplay display = (ChatDisplay)_displays.get(i);
display.handleTellSucceeded(invid, target, message);
}
displayFeedbackMessage(_bundle,
MessageBundle.tcompose("m.told_format", target, message));
}
/**
@@ -328,10 +343,9 @@ public class ChatDirector
// pass this on to our chat displays
String target = (String)tup.left;
for (int i = 0; i < _displays.size(); i++) {
ChatDisplay display = (ChatDisplay)_displays.get(i);
display.handleTellFailed(invid, target, reason);
}
displayFeedbackMessage(_bundle,
MessageBundle.compose("m.tell_failed", target, reason));
}
/**
@@ -343,14 +357,13 @@ public class ChatDirector
* auxiliary chat object on which the message was received.
* @param args the arguments provided with the speak notification.
*/
protected void handleSpeakMessage (String type, Object[] args)
protected void handleSpeakMessage (String localtype, Object[] args)
{
String speaker = (String)args[0];
if (isBlocked(speaker)) {
return;
}
String bundle = null;
String message;
byte mode;
@@ -361,16 +374,11 @@ public class ChatDirector
mode = ((Byte) args[2]).byteValue();
} else {
bundle = (String)args[1];
message = (String)args[2];
message = xlate((String) args[1], (String) args[2]);
mode = ((Byte) args[3]).byteValue();
}
// pass this on to our chat displays
for (int i = 0; i < _displays.size(); i++) {
ChatDisplay display = (ChatDisplay)_displays.get(i);
display.displaySpeakMessage(type, speaker, bundle, message, mode);
}
dispatchMessage(new UserMessage(message, localtype, speaker, mode));
}
/**
@@ -383,18 +391,44 @@ public class ChatDirector
* @param args the arguments provided with the system message
* notification.
*/
protected void handleSystemMessage (String type, Object[] args)
protected void handleSystemMessage (String localtype, Object[] args)
{
String bundle = (String)args[0];
String message = (String)args[1];
displaySystemMessage(type, bundle, message);
displaySystemMessage((String) args[0], (String) args[1], localtype);
}
/**
* Translate the specified message using the specified bundle.
*/
protected String xlate (String bundle, String message)
{
if (bundle != null && _msgmgr != null) {
MessageBundle msgb = _msgmgr.getBundle(bundle);
if (msgb == null) {
Log.warning("No message bundle available to translate " +
"message [bundle=" + bundle + ", message=" +
message + "].");
} else {
message = msgb.xlate(message);
}
}
return message;
}
/**
* Dispatch the provided message to our ChatDisplays.
*/
protected void dispatchMessage (ChatMessage msg)
{
for (Iterator iter = _displays.iterator(); iter.hasNext(); ) {
((ChatDisplay) iter.next()).displayMessage(msg);
}
}
/**
* Looks up and returns the message type associated with the specified
* oid.
*/
protected String getType (int oid)
protected String getLocalType (int oid)
{
String type = (String)_auxes.get(oid);
return (type == null) ? PLACE_CHAT_TYPE : type;
@@ -412,6 +446,12 @@ public class ChatDirector
/** Our active chat context. */
protected CrowdContext _ctx;
/** The message manager. */
protected MessageManager _msgmgr;
/** The bundle to use for our own internal messages. */
protected String _bundle;
/** The place object that we currently occupy. */
protected PlaceObject _place;
@@ -1,5 +1,5 @@
//
// $Id: ChatDisplay.java,v 1.12 2002/07/22 22:54:03 ray Exp $
// $Id: ChatDisplay.java,v 1.13 2002/07/26 20:35:01 ray Exp $
package com.threerings.crowd.chat;
@@ -11,93 +11,8 @@ package com.threerings.crowd.chat;
public interface ChatDisplay
{
/**
* Called to display a speak message. A speak message is one that is
* broadcast to all occupants of a particular place. A speak message
* originated by this client will result in a subsequent call to this
* method after the speak message is accepted by the server and
* broadcast to everyone in the place.
*
* @param type {@link ChatCodes#PLACE_CHAT_TYPE} for a speak message
* delivered via the place object, or for messages delivered via an
* auxiliary chat object, the type code provided when that auxiliary
* object was registered.
* @param speaker the username of the speaker.
* @param bundle for speak messages that originated with a server
* entity rather than another client, this will be non-null and will
* contain a bundle identifier that should be used to translate the
* message text.
* @param message the text of the message.
* @param mode the mode of the speak (@see ChatCodes.DEFAULT_MODE
* @see ChatCodes.THINK_MODE,
* @see ChatCodes.EMOTE_MODE ).
*/
public void displaySpeakMessage (
String type, String speaker, String bundle, String message,
byte mode);
/**
* Called to display a tell message. A tell message is one that is
* delivered directly from one user to another regardless of their
* location in the system.
*
* @param speaker the username of the speaker.
* @param bundle for tell messages that originated with a server
* entity rather than another client, this will be non-null and will
* contain a bundle identifier that should be used to translate the
* message text.
* @param message the text of the message.
*/
public void displayTellMessage (
String speaker, String bundle, String message);
/**
* Called to display a system message. A system message is one that is
* broadcast to all occupants of a particular place and rather than
* originating from some other user in the place, originates from the
* server and should be displayed visually differently from speak
* messages.
*
* @param type {@link ChatCodes#PLACE_CHAT_TYPE} for a speak message
* delivered via the place object, or for messages delivered via an
* auxiliary chat object, the type code provided when that auxiliary
* object was registered.
* @param bundle the bundle identifier to be used when localizing this
* message for display to the client.
* @param message the text of the message.
*/
public void displaySystemMessage (
String type, String bundle, String message);
/**
* Called in response to a successful tell request that originated on
* this client. The request id supplied will match the one returned
* when the request was generated, with the target and message
* detailing the target user name and tell message text associated
* with the request.
*
* @param reqid the request id of the request that resulted in this
* response.
* @param target the name of the user to whom the tell request was
* dispatched.
* @param message the text of the message.
*
* @see ChatDirector#requestTell
*/
public void handleTellSucceeded (int reqid, String target, String message);
/**
* Called in response to a failed tell request that originated on this
* client. The request id supplied will match the one returned when
* the request was generated, with the target and message detailing
* the target user name and tell message text associated with the
* request.
*
* @param reqid the request id of the request that resulted in this
* response.
* @param reason a translatable string explaining the reason for the
* tell request failure.
*
* @see ChatDirector#requestTell
*/
public void handleTellFailed (int reqid, String target, String reason);
* Called to display a message.
* @see ChatMessage
*/
public void displayMessage (ChatMessage msg);
}
@@ -1,5 +1,5 @@
//
// $Id: ChatCodes.java,v 1.9 2002/07/22 22:54:03 ray Exp $
// $Id: ChatCodes.java,v 1.10 2002/07/26 20:35:01 ray Exp $
package com.threerings.crowd.chat;
@@ -13,7 +13,7 @@ public interface ChatCodes extends InvocationCodes
/** The module name for the chat services. */
public static final String MODULE_NAME = "chat";
/** The chat type code for chat messages delivered on the place object
/** The chat localtype code for chat messages delivered on the place object
* currently occupied by the client. This is the only type of chat
* message that will be delivered unless the chat director is
* explicitly provided with other chat message sources via {@link
@@ -29,6 +29,9 @@ public interface ChatCodes extends InvocationCodes
/** The message identifier for a system notification message. */
public static final String SYSTEM_NOTIFICATION = "sysnot";
/** The chat localtype for tells. */
public static final String TELL_CHAT_TYPE = "tellChat";
/** The message identifier for a tell request. */
public static final String TELL_REQUEST = "Tell";
@@ -0,0 +1,30 @@
//
// $Id: ChatMessage.java,v 1.1 2002/07/26 20:35:01 ray Exp $
package com.threerings.crowd.chat;
/**
* The abstract base class of all the client-side ChatMessage objects.
*/
public abstract class ChatMessage
{
/** The actual text of the message. */
public String message;
/** The localtype of this chat, set to the type registered with an
* auxiliary source in the ChatDirector. */
public String localtype;
/** The time that this message was created on the client. */
public long timestamp;
/**
* Construct a ChatMessage.
*/
public ChatMessage (String message, String localtype)
{
this.message = message;
this.localtype = localtype;
timestamp = System.currentTimeMillis();
}
}
@@ -0,0 +1,19 @@
//
// $Id: FeedbackMessage.java,v 1.1 2002/07/26 20:35:01 ray Exp $
package com.threerings.crowd.chat;
/**
* A ChatMessage to indicate to the user that an action they took
* has been processed.
*/
public class FeedbackMessage extends ChatMessage
{
/**
* Construct a FeedbackMessage.
*/
public FeedbackMessage (String message, String localtype)
{
super(message, localtype);
}
}
@@ -0,0 +1,19 @@
//
// $Id: SystemMessage.java,v 1.1 2002/07/26 20:35:01 ray Exp $
package com.threerings.crowd.chat;
/**
* A ChatMessage that represents a message that came from the server
* and did not result from direct user action.
*/
public class SystemMessage extends ChatMessage
{
/**
* Construct a SystemMessage.
*/
public SystemMessage (String message, String localtype)
{
super(message, localtype);
}
}
@@ -0,0 +1,27 @@
//
// $Id: UserMessage.java,v 1.1 2002/07/26 20:35:01 ray Exp $
package com.threerings.crowd.chat;
/**
* A ChatMessage representing a message that came from another user.
*/
public class UserMessage extends ChatMessage
{
/** The user that the message came from. */
public String speaker;
/** The mode of the message. @see ChatCodes.DEFAULT_MODE */
public byte mode;
/**
* Construct a user message.
*/
public UserMessage (String message, String localtype,
String speaker, byte mode)
{
super(message, localtype);
this.speaker = speaker;
this.mode = mode;
}
}
@@ -1,5 +1,5 @@
//
// $Id: ChatPanel.java,v 1.17 2002/07/22 22:54:04 ray Exp $
// $Id: ChatPanel.java,v 1.18 2002/07/26 20:35:01 ray Exp $
package com.threerings.micasa.client;
@@ -37,6 +37,10 @@ import com.threerings.util.MessageBundle;
import com.threerings.crowd.chat.ChatCodes;
import com.threerings.crowd.chat.ChatDirector;
import com.threerings.crowd.chat.ChatDisplay;
import com.threerings.crowd.chat.ChatMessage;
import com.threerings.crowd.chat.FeedbackMessage;
import com.threerings.crowd.chat.SystemMessage;
import com.threerings.crowd.chat.UserMessage;
import com.threerings.crowd.client.OccupantObserver;
import com.threerings.crowd.client.PlaceView;
import com.threerings.crowd.data.OccupantInfo;
@@ -55,7 +59,7 @@ public class ChatPanel
_ctx = ctx;
// create our chat director and register ourselves with it
_chatdtr = new ChatDirector(_ctx);
_chatdtr = new ChatDirector(_ctx, null, null);
_chatdtr.addChatDisplay(this);
// register as an occupant observer
@@ -174,15 +178,7 @@ public class ChatPanel
protected void displayOccupantMessage (String message)
{
// stick a newline on the message
message = message + "\n";
Document doc = _text.getDocument();
try {
doc.insertString(doc.getLength(), message, _noticeStyle);
} catch (BadLocationException ble) {
Log.warning("Unable to insert text!? [error=" + ble + "].");
}
append(message + "\n", _noticeStyle);
}
protected void sendText ()
@@ -224,124 +220,47 @@ public class ChatPanel
_entry.setText("");
}
// documentation inherited
public void displaySpeakMessage (
String type, String speaker, String bundle, String message, byte mode)
// documentation inherited from interface ChatDisplay
public void displayMessage (ChatMessage message)
{
// wrap the speaker in brackets
speaker = "<" + speaker + "> ";
// translate the message if necessary
message = xlate(bundle, message);
// stick a newline on the message
message = message + "\n";
Document doc = _text.getDocument();
try {
doc.insertString(doc.getLength(), speaker, _nameStyle);
doc.insertString(doc.getLength(), message, _msgStyle);
} catch (BadLocationException ble) {
Log.warning("Unable to insert text!? [error=" + ble + "].");
}
}
// documentation inherited
public void displaySystemMessage (
String type, String bundle, String message)
{
// translate the message
message = xlate(bundle, message);
// stick a newline on the message
message = message + "\n";
Document doc = _text.getDocument();
try {
doc.insertString(doc.getLength(), message, _errStyle);
} catch (BadLocationException ble) {
Log.warning("Unable to insert text!? [error=" + ble + "].");
}
}
/**
* Translates the supplied message using the supplied bundle
* identifier iff the bundle identifier is not null. Otherwise it
* returns the original message.
*/
protected String xlate (String bundle, String message)
{
if (bundle != null) {
MessageBundle msgb = _ctx.getMessageManager().getBundle(bundle);
if (msgb == null) {
Log.warning("No message bundle available to translate " +
"[bundle=" + bundle + ", msg=" + message + "].");
if (message instanceof UserMessage) {
UserMessage msg = (UserMessage) message;
if (msg.localtype == ChatCodes.TELL_CHAT_TYPE) {
append("[" + msg.speaker + " whispers] ", _nameStyle);
append(msg.message + "\n", _msgStyle);
} else {
message = msgb.xlate(message);
append("<" + msg.speaker + "> ", _nameStyle);
append(msg.message + "\n", _msgStyle);
}
} else if ((message instanceof SystemMessage) ||
(message instanceof FeedbackMessage)) {
append(message.message + "\n", _noticeStyle);
} else {
Log.warning("Received unknown message type [message=" +
message + "].");
}
return message;
}
protected void displayError (String message)
{
// stick a newline on the message
message = message + "\n";
append(message + "\n", _errStyle);
}
/**
* Append the specified text in the specified style.
*/
protected void append (String text, Style style)
{
Document doc = _text.getDocument();
try {
doc.insertString(doc.getLength(), message, _errStyle);
doc.insertString(doc.getLength(), text, style);
} catch (BadLocationException ble) {
Log.warning("Unable to insert text!? [error=" + ble + "].");
}
}
// documentation inherited
public void displayTellMessage (
String speaker, String bundle, String message)
{
// wrap the speaker in brackets
speaker = "[" + speaker + " whispers] ";
// translate the message if necessary
message = xlate(bundle, message);
// stick a newline on the message
message = message + "\n";
Document doc = _text.getDocument();
try {
doc.insertString(doc.getLength(), speaker, _nameStyle);
doc.insertString(doc.getLength(), message, _msgStyle);
} catch (BadLocationException ble) {
Log.warning("Unable to insert text!? [error=" + ble + "].");
}
}
// documentation inherited from interface
public void handleTellSucceeded (int reqid, String target, String message)
{
// wrap the speaker in brackets
target = "[You whispered to " + target + "] ";
// stick a newline on the message
message = message + "\n";
Document doc = _text.getDocument();
try {
doc.insertString(doc.getLength(), target, _nameStyle);
doc.insertString(doc.getLength(), message, _msgStyle);
} catch (BadLocationException ble) {
Log.warning("Unable to insert text!? [error=" + ble + "].");
}
}
// documentation inherited from interface
public void handleTellFailed (int reqid, String target, String reason)
{
displayError(reason);
}
public void willEnterPlace (PlaceObject place)
{
Log.info("We be here: " + place);
@@ -1,5 +1,5 @@
//
// $Id: SpotSceneDirector.java,v 1.16 2002/07/22 22:54:04 ray Exp $
// $Id: SpotSceneDirector.java,v 1.17 2002/07/26 20:35:02 ray Exp $
package com.threerings.whirled.spot.client;
@@ -309,7 +309,7 @@ public class SpotSceneDirector
// we've got our cluster chat object, configure the chat director
// with it and keep a reference ourselves
if (_chatdir != null) {
_chatdir.addAuxiliarySource(CLUSTER_CHAT_TYPE, object);
_chatdir.addAuxiliarySource(object, CLUSTER_CHAT_TYPE);
_clobj = object;
}
}