mirror of https://github.com/ppy/osu
Merge pull request #21463 from peppy/fix-chat-system-message-ordering
Fix system messages appearing out of order in chat display
This commit is contained in:
commit
eea9bd3898
|
@ -73,6 +73,11 @@ public void SetUp() => Schedule(() =>
|
|||
messageIdSequence = 0;
|
||||
channelManager.CurrentChannel.Value = testChannel = new Channel();
|
||||
|
||||
reinitialiseDrawableDisplay();
|
||||
});
|
||||
|
||||
private void reinitialiseDrawableDisplay()
|
||||
{
|
||||
Children = new[]
|
||||
{
|
||||
chatDisplay = new TestStandAloneChatDisplay
|
||||
|
@ -92,13 +97,14 @@ public void SetUp() => Schedule(() =>
|
|||
Channel = { Value = testChannel },
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSystemMessageOrdering()
|
||||
{
|
||||
var standardMessage = new Message(messageIdSequence++)
|
||||
{
|
||||
Timestamp = DateTimeOffset.Now,
|
||||
Sender = admin,
|
||||
Content = "I am a wang!"
|
||||
};
|
||||
|
@ -106,14 +112,45 @@ public void TestSystemMessageOrdering()
|
|||
var infoMessage1 = new InfoMessage($"the system is calling {messageIdSequence++}");
|
||||
var infoMessage2 = new InfoMessage($"the system is calling {messageIdSequence++}");
|
||||
|
||||
var standardMessage2 = new Message(messageIdSequence++)
|
||||
{
|
||||
Timestamp = DateTimeOffset.Now,
|
||||
Sender = admin,
|
||||
Content = "I am a wang!"
|
||||
};
|
||||
|
||||
AddStep("message from admin", () => testChannel.AddNewMessages(standardMessage));
|
||||
AddStep("message from system", () => testChannel.AddNewMessages(infoMessage1));
|
||||
AddStep("message from system", () => testChannel.AddNewMessages(infoMessage2));
|
||||
AddStep("message from admin", () => testChannel.AddNewMessages(standardMessage2));
|
||||
|
||||
AddAssert("message order is correct", () => testChannel.Messages.Count == 3
|
||||
&& testChannel.Messages[0] == standardMessage
|
||||
&& testChannel.Messages[1] == infoMessage1
|
||||
&& testChannel.Messages[2] == infoMessage2);
|
||||
AddAssert("count is correct", () => testChannel.Messages.Count, () => Is.EqualTo(4));
|
||||
|
||||
AddAssert("message order is correct", () => testChannel.Messages, () => Is.EqualTo(new[]
|
||||
{
|
||||
standardMessage,
|
||||
infoMessage1,
|
||||
infoMessage2,
|
||||
standardMessage2
|
||||
}));
|
||||
|
||||
AddAssert("displayed order is correct", () => chatDisplay.DrawableChannel.ChildrenOfType<ChatLine>().Select(c => c.Message), () => Is.EqualTo(new[]
|
||||
{
|
||||
standardMessage,
|
||||
infoMessage1,
|
||||
infoMessage2,
|
||||
standardMessage2
|
||||
}));
|
||||
|
||||
AddStep("reinit drawable channel", reinitialiseDrawableDisplay);
|
||||
|
||||
AddAssert("displayed order is still correct", () => chatDisplay.DrawableChannel.ChildrenOfType<ChatLine>().Select(c => c.Message), () => Is.EqualTo(new[]
|
||||
{
|
||||
standardMessage,
|
||||
infoMessage1,
|
||||
infoMessage2,
|
||||
standardMessage2
|
||||
}));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
|
@ -13,7 +10,6 @@ public class InfoMessage : LocalMessage
|
|||
public InfoMessage(string message)
|
||||
: base(null)
|
||||
{
|
||||
Timestamp = DateTimeOffset.Now;
|
||||
Content = message;
|
||||
|
||||
Sender = APIUser.SYSTEM_USER;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
{
|
||||
public class LocalEchoMessage : LocalMessage
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
#nullable disable
|
||||
using System;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
{
|
||||
|
@ -13,6 +13,7 @@ public class LocalMessage : Message
|
|||
protected LocalMessage(long? id)
|
||||
: base(id)
|
||||
{
|
||||
Timestamp = DateTimeOffset.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
|
@ -59,19 +60,28 @@ public Message()
|
|||
/// <remarks>The <see cref="Link"/>s' <see cref="Link.Index"/> and <see cref="Link.Length"/>s are according to <see cref="DisplayContent"/></remarks>
|
||||
public List<Link> Links;
|
||||
|
||||
private static long constructionOrderStatic;
|
||||
private readonly long constructionOrder;
|
||||
|
||||
public Message(long? id)
|
||||
{
|
||||
Id = id;
|
||||
|
||||
constructionOrder = Interlocked.Increment(ref constructionOrderStatic);
|
||||
}
|
||||
|
||||
public int CompareTo(Message other)
|
||||
{
|
||||
if (!Id.HasValue)
|
||||
return other.Id.HasValue ? 1 : Timestamp.CompareTo(other.Timestamp);
|
||||
if (!other.Id.HasValue)
|
||||
return -1;
|
||||
if (Id.HasValue && other.Id.HasValue)
|
||||
return Id.Value.CompareTo(other.Id.Value);
|
||||
|
||||
return Id.Value.CompareTo(other.Id.Value);
|
||||
int timestampComparison = Timestamp.CompareTo(other.Timestamp);
|
||||
|
||||
if (timestampComparison != 0)
|
||||
return timestampComparison;
|
||||
|
||||
// Timestamp might not be accurate enough to make a stable sorting decision.
|
||||
return constructionOrder.CompareTo(other.constructionOrder);
|
||||
}
|
||||
|
||||
public virtual bool Equals(Message other)
|
||||
|
@ -85,6 +95,6 @@ public virtual bool Equals(Message other)
|
|||
// ReSharper disable once ImpureMethodCallOnReadonlyValueField
|
||||
public override int GetHashCode() => Id.GetHashCode();
|
||||
|
||||
public override string ToString() => $"[{ChannelId}] ({Id}) {Sender}: {Content}";
|
||||
public override string ToString() => $"({(Id?.ToString() ?? "null")}) {Timestamp} {Sender}: {Content}";
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue