Backtrack a bit for recording channel speaks to the history. Instead of weighing down UserMessage with extra stuff (there is a lot of infrastructure that seems intent on avoiding this), record the value only in the server's history by wrapping messages in a new value class.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5991 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Jamie Doornbos
2009-11-10 00:05:56 +00:00
parent 09c7229fa6
commit 5e6cf46926
4 changed files with 56 additions and 39 deletions
@@ -609,7 +609,7 @@ public class ChatDirector extends BasicDirector
getChannelLocalType(event.getArgs()[0] as ChatChannel)); getChannelLocalType(event.getArgs()[0] as ChatChannel));
} }
} }
// documentation inherited // documentation inherited
override public function clientDidLogon (event :ClientEvent) :void override public function clientDidLogon (event :ClientEvent) :void
{ {
@@ -34,9 +34,6 @@ public class UserMessage extends ChatMessage
/** The mode of the message. @see ChatCodes.DEFAULT_MODE */ /** The mode of the message. @see ChatCodes.DEFAULT_MODE */
public byte mode; public byte mode;
/** The channel of the message, or null if not set. */
public ChatChannel channel;
/** /**
* For unserialization. * For unserialization.
*/ */
@@ -44,33 +41,25 @@ public class UserMessage extends ChatMessage
{ {
} }
/**
* Construct a user message.
*/
public UserMessage (Name speaker, String bundle, String message, byte mode)
{
super(message, bundle);
this.speaker = speaker;
this.mode = mode;
}
/** /**
* Constructs a user message for a player originated tell (which has no bundle and is in the * Constructs a user message for a player originated tell (which has no bundle and is in the
* default mode). * default mode).
*/ */
public UserMessage (Name speaker, String message) public UserMessage (Name speaker, String message)
{ {
this(speaker, null, message, ChatCodes.DEFAULT_MODE); super(message, null);
}
/**
* Construct a user message.
*/
public UserMessage (Name speaker, String bundle, String message, byte mode)
{
this(null, speaker, bundle, message, mode);
}
/**
* Construct a user message that was spoken using the channel system.
*/
public UserMessage (
ChatChannel channel, Name speaker, String bundle, String message, byte mode)
{
super(message, bundle);
this.channel = channel;
this.speaker = speaker; this.speaker = speaker;
this.mode = mode; this.mode = ChatCodes.DEFAULT_MODE;
} }
/** /**
@@ -85,7 +85,7 @@ public abstract class ChatChannelManager
public void speak (ClientObject caller, final ChatChannel channel, String message, byte mode) public void speak (ClientObject caller, final ChatChannel channel, String message, byte mode)
{ {
final UserMessage umsg = new UserMessage( final UserMessage umsg = new UserMessage(
intern(channel), ((BodyObject)caller).getVisibleName(), null, message, mode); ((BodyObject)caller).getVisibleName(), null, message, mode);
// if we're hosting this channel, dispatch it directly // if we're hosting this channel, dispatch it directly
if (_channels.containsKey(channel)) { if (_channels.containsKey(channel)) {
@@ -241,10 +241,11 @@ public abstract class ChatChannelManager
*/ */
protected void deliverSpeak (ChatChannel channel, UserMessage message, int[] bodyIds) protected void deliverSpeak (ChatChannel channel, UserMessage message, int[] bodyIds)
{ {
channel = intern(channel);
for (int bodyId : bodyIds) { for (int bodyId : bodyIds) {
BodyObject bobj = getBodyObject(bodyId); BodyObject bobj = getBodyObject(bodyId);
if (bobj != null && shouldDeliverSpeak(channel, message, bobj)) { if (bobj != null && shouldDeliverSpeak(channel, message, bobj)) {
SpeakUtil.recordToChatHistory(message, bobj.username); SpeakUtil.recordToChatHistory(channel, message, bobj.getVisibleName());
bobj.postMessage(ChatCodes.CHAT_CHANNEL_NOTIFICATION, channel, message); bobj.postMessage(ChatCodes.CHAT_CHANNEL_NOTIFICATION, channel, message);
} }
} }
@@ -34,6 +34,7 @@ import com.threerings.util.Name;
import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.RootDObjectManager; import com.threerings.presents.dobj.RootDObjectManager;
import com.threerings.crowd.chat.data.ChatChannel;
import com.threerings.crowd.chat.data.ChatCodes; import com.threerings.crowd.chat.data.ChatCodes;
import com.threerings.crowd.chat.data.ChatMessage; import com.threerings.crowd.chat.data.ChatMessage;
import com.threerings.crowd.chat.data.KeepNoHistory; import com.threerings.crowd.chat.data.KeepNoHistory;
@@ -61,6 +62,31 @@ public class SpeakUtil
void messageDelivered (Name hearer, UserMessage message); void messageDelivered (Name hearer, UserMessage message);
} }
/**
* Recorded parcel of chat for historical purposes, maintained by
* {@link #recordToChatHistory(UserMessage, Name...)},
* {@link #recordToChatHistory(ChatChannel, UserMessage, Name...)},
* {@link #getChatHistory(Name)}, and {@link #clearHistory(Name)}.
*/
public static class ChatHistoryEntry
{
/** The channel on which the message was sent, of null if the channel manager was not
* used. */
public ChatChannel channel;
/** The message sent. */
public ChatMessage message;
/**
* Creates a new history entry.
*/
public ChatHistoryEntry (ChatChannel channel, ChatMessage message)
{
this.channel = channel;
this.message = message;
}
}
/** /**
* Registers a {@link MessageObserver} to be notified whenever a user-originated chat message * Registers a {@link MessageObserver} to be notified whenever a user-originated chat message
* is heard by another user. * is heard by another user.
@@ -203,9 +229,9 @@ public class SpeakUtil
* Returns a list of {@link ChatMessage} objects to which this user has been privy in the * Returns a list of {@link ChatMessage} objects to which this user has been privy in the
* recent past. If the given name implements {@link KeepNoHistory}, null is returned. * recent past. If the given name implements {@link KeepNoHistory}, null is returned.
*/ */
public static List<ChatMessage> getChatHistory (Name username) public static List<ChatHistoryEntry> getChatHistory (Name username)
{ {
List<ChatMessage> history = getHistoryList(username); List<ChatHistoryEntry> history = getHistoryList(username);
if (history != null) { if (history != null) {
pruneHistory(System.currentTimeMillis(), history); pruneHistory(System.currentTimeMillis(), history);
} }
@@ -222,10 +248,11 @@ public class SpeakUtil
} }
/** /**
* Records the specified message to the specified users' chat histories. If {@link * Records the specified channel and message to the specified users' chat histories. If {@link
* ChatMessage#timestamp} is not already filled in, it will be. * ChatMessage#timestamp} is not already filled in, it will be.
*/ */
public static void recordToChatHistory (UserMessage msg, Name... usernames) public static void recordToChatHistory (
ChatChannel channel, UserMessage msg, Name... usernames)
{ {
// fill in the message's time stamp if necessary // fill in the message's time stamp if necessary
if (msg.timestamp == 0L) { if (msg.timestamp == 0L) {
@@ -234,11 +261,11 @@ public class SpeakUtil
for (Name username : usernames) { for (Name username : usernames) {
// add the message to this user's chat history // add the message to this user's chat history
List<ChatMessage> history = getHistoryList(username); List<ChatHistoryEntry> history = getHistoryList(username);
if (history == null) { if (history == null) {
continue; continue;
} }
history.add(msg); history.add(new ChatHistoryEntry(channel, msg));
// if the history is big enough, potentially prune it (we always prune when asked for // if the history is big enough, potentially prune it (we always prune when asked for
// the history, so this is just to balance memory usage with CPU expense) // the history, so this is just to balance memory usage with CPU expense)
@@ -259,7 +286,7 @@ public class SpeakUtil
msg.timestamp = System.currentTimeMillis(); msg.timestamp = System.currentTimeMillis();
} }
recordToChatHistory(msg, username); recordToChatHistory(null, msg, username);
// Log.info("Noted that " + username + " heard " + msg + "."); // Log.info("Noted that " + username + " heard " + msg + ".");
// notify any message observers // notify any message observers
@@ -279,12 +306,12 @@ public class SpeakUtil
* Returns this user's chat history, creating one if necessary. If the given name implements * Returns this user's chat history, creating one if necessary. If the given name implements
* {@link KeepNoHistory}, null is returned. * {@link KeepNoHistory}, null is returned.
*/ */
protected static List<ChatMessage> getHistoryList (Name username) protected static List<ChatHistoryEntry> getHistoryList (Name username)
{ {
if (username instanceof KeepNoHistory) { if (username instanceof KeepNoHistory) {
return null; return null;
} }
List<ChatMessage> history = _histories.get(username); List<ChatHistoryEntry> history = _histories.get(username);
if (history == null) { if (history == null) {
_histories.put(username, history = Lists.newArrayList()); _histories.put(username, history = Lists.newArrayList());
} }
@@ -294,12 +321,12 @@ public class SpeakUtil
/** /**
* Prunes all messages from this history which are expired. * Prunes all messages from this history which are expired.
*/ */
protected static void pruneHistory (long now, List<ChatMessage> history) protected static void pruneHistory (long now, List<ChatHistoryEntry> history)
{ {
int prunepos = 0; int prunepos = 0;
for (int ll = history.size(); prunepos < ll; prunepos++) { for (int ll = history.size(); prunepos < ll; prunepos++) {
ChatMessage msg = history.get(prunepos); ChatHistoryEntry entry = history.get(prunepos);
if (now - msg.timestamp < HISTORY_EXPIRATION) { if (now - entry.message.timestamp < HISTORY_EXPIRATION) {
break; // stop when we get to the first valid message break; // stop when we get to the first valid message
} }
} }
@@ -343,7 +370,7 @@ public class SpeakUtil
} }
/** Recent chat history for the server. */ /** Recent chat history for the server. */
protected static Map<Name, List<ChatMessage>> _histories = Maps.newHashMap(); protected static Map<Name, List<ChatHistoryEntry>> _histories = Maps.newHashMap();
/** Used to note the recipients of a chat message. */ /** Used to note the recipients of a chat message. */
protected static MessageMapper _messageMapper = new MessageMapper(); protected static MessageMapper _messageMapper = new MessageMapper();