mirror of
https://github.com/ppy/osu.git
synced 2025-01-14 17:52:56 +08:00
Always add player instances at first, populate later
This commit is contained in:
parent
b391a8f94e
commit
5ac0eb02cd
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
public class TestSceneMultiplayerSpectator : MultiplayerTestScene
|
||||
{
|
||||
[Cached(typeof(SpectatorStreamingClient))]
|
||||
private TestSpectatorStreamingClient testSpectatorStreamingClient = new TestSpectatorStreamingClient();
|
||||
private TestSpectatorStreamingClient streamingClient = new TestSpectatorStreamingClient();
|
||||
|
||||
[Cached(typeof(UserLookupCache))]
|
||||
private UserLookupCache lookupCache = new TestUserLookupCache();
|
||||
@ -62,18 +62,42 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
AddStep("add streaming client", () =>
|
||||
{
|
||||
Remove(testSpectatorStreamingClient);
|
||||
Add(testSpectatorStreamingClient);
|
||||
Remove(streamingClient);
|
||||
Add(streamingClient);
|
||||
});
|
||||
|
||||
AddStep("finish previous gameplay", () =>
|
||||
{
|
||||
foreach (var id in playingUserIds)
|
||||
testSpectatorStreamingClient.EndPlay(id, importedBeatmapId);
|
||||
streamingClient.EndPlay(id, importedBeatmapId);
|
||||
playingUserIds.Clear();
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDelayedStart()
|
||||
{
|
||||
AddStep("start players silently", () =>
|
||||
{
|
||||
Client.CurrentMatchPlayingUserIds.Add(55);
|
||||
Client.CurrentMatchPlayingUserIds.Add(56);
|
||||
playingUserIds.Add(55);
|
||||
playingUserIds.Add(56);
|
||||
nextFrame[55] = 0;
|
||||
nextFrame[56] = 0;
|
||||
});
|
||||
|
||||
loadSpectateScreen(false);
|
||||
|
||||
AddWaitStep("wait a bit", 10);
|
||||
AddStep("load player 55", () => streamingClient.StartPlay(55, importedBeatmapId));
|
||||
AddUntilStep("one player added", () => spectator.ChildrenOfType<Player>().Count() == 1);
|
||||
|
||||
AddWaitStep("wait a bit", 10);
|
||||
AddStep("load player 56", () => streamingClient.StartPlay(56, importedBeatmapId));
|
||||
AddUntilStep("two players added", () => spectator.ChildrenOfType<Player>().Count() == 2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGeneral()
|
||||
{
|
||||
@ -178,7 +202,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddWaitStep("wait a bit", 10);
|
||||
}
|
||||
|
||||
private void loadSpectateScreen()
|
||||
private void loadSpectateScreen(bool waitForPlayerLoad = true)
|
||||
{
|
||||
AddStep("load screen", () =>
|
||||
{
|
||||
@ -188,7 +212,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
LoadScreen(spectator = new MultiplayerSpectator(playingUserIds.ToArray()));
|
||||
});
|
||||
|
||||
AddUntilStep("wait for screen load", () => spectator.LoadState == LoadState.Loaded && spectator.AllPlayersLoaded);
|
||||
AddUntilStep("wait for screen load", () => spectator.LoadState == LoadState.Loaded && (!waitForPlayerLoad || spectator.AllPlayersLoaded));
|
||||
}
|
||||
|
||||
private void start(int userId, int? beatmapId = null) => start(new[] { userId }, beatmapId);
|
||||
@ -200,7 +224,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
foreach (int id in userIds)
|
||||
{
|
||||
Client.CurrentMatchPlayingUserIds.Add(id);
|
||||
testSpectatorStreamingClient.StartPlay(id, beatmapId ?? importedBeatmapId);
|
||||
streamingClient.StartPlay(id, beatmapId ?? importedBeatmapId);
|
||||
playingUserIds.Add(id);
|
||||
nextFrame[id] = 0;
|
||||
}
|
||||
@ -211,7 +235,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
AddStep("end play", () =>
|
||||
{
|
||||
testSpectatorStreamingClient.EndPlay(userId, beatmapId ?? importedBeatmapId);
|
||||
streamingClient.EndPlay(userId, beatmapId ?? importedBeatmapId);
|
||||
playingUserIds.Remove(userId);
|
||||
nextFrame.Remove(userId);
|
||||
});
|
||||
@ -225,7 +249,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
foreach (int id in userIds)
|
||||
{
|
||||
testSpectatorStreamingClient.SendFrames(id, nextFrame[id], count);
|
||||
streamingClient.SendFrames(id, nextFrame[id], count);
|
||||
nextFrame[id] += count;
|
||||
}
|
||||
});
|
||||
@ -246,7 +270,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
private Player getPlayer(int userId) => getInstance(userId).ChildrenOfType<Player>().Single();
|
||||
|
||||
private PlayerInstance getInstance(int userId) => spectator.ChildrenOfType<PlayerInstance>().Single(p => p.User.Id == userId);
|
||||
private PlayerInstance getInstance(int userId) => spectator.ChildrenOfType<PlayerInstance>().Single(p => p.UserId == userId);
|
||||
|
||||
public class TestSpectatorStreamingClient : SpectatorStreamingClient
|
||||
{
|
||||
@ -297,7 +321,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
public override void WatchUser(int userId)
|
||||
{
|
||||
if (userSentStateDictionary[userId])
|
||||
if (userSentStateDictionary.TryGetValue(userId, out var sent) && sent)
|
||||
{
|
||||
// usually the server would do this.
|
||||
sendState(userId, userBeatmapDictionary[userId]);
|
||||
|
@ -32,7 +32,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
|
||||
public MultiplayerSpectator(int[] userIds)
|
||||
: base(userIds.AsSpan().Slice(0, Math.Min(16, userIds.Length)).ToArray())
|
||||
{
|
||||
instances = new PlayerInstance[userIds.Length];
|
||||
instances = new PlayerInstance[UserIds.Length];
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -70,6 +70,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
|
||||
masterClockContainer
|
||||
};
|
||||
|
||||
for (int i = 0; i < UserIds.Length; i++)
|
||||
grid.Add(instances[i] = new PlayerInstance(UserIds[i], new SpectatorCatchUpSlaveClock(masterClockContainer.GameplayClock)));
|
||||
|
||||
// Todo: This is not quite correct - it should be per-user to adjust for other mod combinations.
|
||||
var playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Ruleset.Value);
|
||||
var scoreProcessor = Ruleset.Value.CreateInstance().CreateScoreProcessor();
|
||||
@ -93,24 +96,14 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
|
||||
protected override void StartGameplay(int userId, GameplayState gameplayState)
|
||||
{
|
||||
int userIndex = getIndexForUser(userId);
|
||||
var existingInstance = instances[userIndex];
|
||||
|
||||
if (existingInstance != null)
|
||||
{
|
||||
grid.Remove(existingInstance);
|
||||
syncManager.RemoveSlave(existingInstance.GameplayClock);
|
||||
leaderboard.RemoveClock(existingInstance.User.Id);
|
||||
}
|
||||
var instance = instances[userIndex];
|
||||
syncManager.RemoveSlave(instance.GameplayClock);
|
||||
leaderboard.RemoveClock(instance.UserId);
|
||||
|
||||
LoadComponentAsync(instances[userIndex] = new PlayerInstance(gameplayState.Score, new SpectatorCatchUpSlaveClock(masterClockContainer.GameplayClock)), d =>
|
||||
{
|
||||
if (instances[userIndex] == d)
|
||||
{
|
||||
grid.Add(d);
|
||||
syncManager.AddSlave(d.GameplayClock);
|
||||
leaderboard.AddClock(d.User.Id, d.GameplayClock);
|
||||
}
|
||||
});
|
||||
instance.LoadPlayer(gameplayState.Score);
|
||||
syncManager.AddSlave(instance.GameplayClock);
|
||||
leaderboard.AddClock(instance.UserId, instance.GameplayClock);
|
||||
}
|
||||
|
||||
protected override void EndGameplay(int userId)
|
||||
|
@ -8,7 +8,6 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate.Sync;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
|
||||
{
|
||||
@ -16,30 +15,30 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
|
||||
{
|
||||
public bool PlayerLoaded => stack?.CurrentScreen is Player;
|
||||
|
||||
public User User => Score.ScoreInfo.User;
|
||||
|
||||
public WorkingBeatmap Beatmap { get; private set; }
|
||||
|
||||
public readonly Score Score;
|
||||
public readonly int UserId;
|
||||
public readonly SpectatorCatchUpSlaveClock GameplayClock;
|
||||
|
||||
public Score Score { get; private set; }
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmapManager { get; set; }
|
||||
|
||||
private OsuScreenStack stack;
|
||||
|
||||
public PlayerInstance(Score score, SpectatorCatchUpSlaveClock gameplayClock)
|
||||
public PlayerInstance(int userId, SpectatorCatchUpSlaveClock gameplayClock)
|
||||
{
|
||||
Score = score;
|
||||
UserId = userId;
|
||||
GameplayClock = gameplayClock;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Masking = true;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(BeatmapManager beatmapManager)
|
||||
public void LoadPlayer(Score score)
|
||||
{
|
||||
Beatmap = beatmapManager.GetWorkingBeatmap(Score.ScoreInfo.Beatmap, bypassCache: true);
|
||||
Score = score;
|
||||
|
||||
InternalChild = new GameplayIsolationContainer(Beatmap, Score.ScoreInfo.Ruleset, Score.ScoreInfo.Mods)
|
||||
InternalChild = new GameplayIsolationContainer(beatmapManager.GetWorkingBeatmap(Score.ScoreInfo.Beatmap, bypassCache: true), Score.ScoreInfo.Ruleset, Score.ScoreInfo.Mods)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new DrawSizePreservingFillContainer
|
||||
|
Loading…
Reference in New Issue
Block a user