-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Show spectating users during gameplay #31527
Conversation
defc3fa
to
99c7e16
Compare
((IBindableList<SpectatorUser>)Spectators).BindTo(client.WatchingUsers); | ||
((IBindable<LocalUserPlayingState>)UserPlayingState).BindTo(gameplayState.PlayingState); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find it super odd that these bindings are done here. I get that this is to allow the base class to be tested, but it doesn't sit well. Two proposals:
- Rename this class to
OnlineSpectatorList
(dunno) - Change how the testing is done to not require that and move the
ISerialisableDrawable
to the base implementation
Leaning towards the second.
abf4b7b
to
3c4bfc0
Compare
((IBindableList<SpectatorUser>)Spectators).BindTo(client.WatchingUsers); | ||
((IBindable<LocalUserPlayingState>)UserPlayingState).BindTo(gameplayState.PlayingState); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this is a threaded component, these should not be bound on the BDL thread. Especially and in particular the BindableList<>
.
There is a potential race condition where:
- This thread is in the middle of copying elements from the remote list on the BDL thread.
- The remote list changes on the Update thread.
I believe these days we use LoadComplete()
to bind bindables in general.
Here's an example:
[Test]
public void RunTest()
{
var list1 = new BindableList<int>([0]);
new Thread(() =>
{
int nextAdd = 1;
int nextRemove = 0;
while (true)
{
if (RNG.Next() % 3 == 0)
list1.Remove(nextRemove++);
else
list1.Add(nextAdd++);
}
})
{
IsBackground = true
}.Start();
new Thread(() =>
{
while (true)
{
var list2 = new BindableList<int>();
list2.BindTo(list1);
}
})
{
IsBackground = true
}.Start();
while (true)
{
Thread.Sleep(2000);
}
}
Please forgive the playfield on the above looking a bit broken, it's what happens when the skin doesn't fully correctly reload during pause. That was the quickest way to capture these screenshots. (By the way this sort of thing is what needs to happen now that every ruleset can have elements in arbitrary places...)