Simplify none game state change handling
This commit is contained in:
1 parent
9dd2a1dc44
commit
e95ee4be5e
1 file changed
+103
-103
@@ -261,114 +261,114 @@ class Twitch:
|
|||||||
elif self._state is State.CHANNELS_FETCH:
|
elif self._state is State.CHANNELS_FETCH:
|
||||||
if self.game is None:
|
if self.game is None:
|
||||||
self.change_state(State.GAME_SELECT)
|
self.change_state(State.GAME_SELECT)
|
||||||
else:
|
continue
|
||||||
# pre-display the active drop without substracting a minute
|
# pre-display the active drop without substracting a minute
|
||||||
if (active_drop := self.get_active_drop()) is not None:
|
if (active_drop := self.get_active_drop()) is not None:
|
||||||
active_drop.display(countdown=False)
|
active_drop.display(countdown=False)
|
||||||
# start with all current channels
|
# start with all current channels
|
||||||
new_channels: OrderedSet[Channel] = OrderedSet(self.channels.values())
|
new_channels: OrderedSet[Channel] = OrderedSet(self.channels.values())
|
||||||
# gather and add ACL channels from campaigns
|
# gather and add ACL channels from campaigns
|
||||||
# NOTE: we consider only campaigns that can be progressed
|
# NOTE: we consider only campaigns that can be progressed
|
||||||
# NOTE: we use a separate set so that we can set them online separately
|
# NOTE: we use a separate set so that we can set them online separately
|
||||||
no_acl = False
|
no_acl = False
|
||||||
acl_channels: OrderedSet[Channel] = OrderedSet()
|
acl_channels: OrderedSet[Channel] = OrderedSet()
|
||||||
for campaign in self.inventory[self.game]:
|
for campaign in self.inventory[self.game]:
|
||||||
if any(drop.can_earn() for drop in campaign.drops):
|
if any(drop.can_earn() for drop in campaign.drops):
|
||||||
if campaign.allowed_channels:
|
if campaign.allowed_channels:
|
||||||
acl_channels.update(campaign.allowed_channels)
|
acl_channels.update(campaign.allowed_channels)
|
||||||
else:
|
|
||||||
no_acl = True
|
|
||||||
# remove all ACL channels from the separate set that already exist
|
|
||||||
acl_channels.difference_update(new_channels)
|
|
||||||
# use the separate set to set them online if possible
|
|
||||||
if acl_channels:
|
|
||||||
await asyncio.gather(*(channel.check_online() for channel in acl_channels))
|
|
||||||
if no_acl:
|
|
||||||
# if there's at least one campaign without an ACL,
|
|
||||||
# add a list of live channels with drops enabled
|
|
||||||
new_channels.update(await self.get_live_streams())
|
|
||||||
# sort them descending by viewers,
|
|
||||||
# then by priority so that prioritized ones are first
|
|
||||||
# NOTE: We can drop OrderedSet now because there's no more channels being added
|
|
||||||
ordered_channels: list[Channel] = sorted(
|
|
||||||
new_channels, key=viewers_key, reverse=True
|
|
||||||
)
|
|
||||||
ordered_channels.sort(key=lambda ch: ch.priority, reverse=True)
|
|
||||||
# ensure that we won't end up with more channels than we can handle
|
|
||||||
# NOTE: we substract 2 due to the two base topics always being added:
|
|
||||||
# channel points gain and drop update subscriptions
|
|
||||||
# NOTE: we trim from the end because that's where the non-priority,
|
|
||||||
# offline (or online but low viewers) channels end up
|
|
||||||
max_channels = MAX_WEBSOCKETS * WS_TOPICS_LIMIT - 2
|
|
||||||
to_remove = ordered_channels[max_channels:]
|
|
||||||
ordered_channels = ordered_channels[:max_channels]
|
|
||||||
if to_remove:
|
|
||||||
# tracked channels and gui are cleared below, so no need to do it here
|
|
||||||
# just make sure to unsubscribe from their topics
|
|
||||||
self.websocket.remove_topics(
|
|
||||||
WebsocketTopic.as_str("Channel", "StreamState", channel.id)
|
|
||||||
for channel in to_remove
|
|
||||||
)
|
|
||||||
del to_remove
|
|
||||||
# set our new channel list
|
|
||||||
channels.clear()
|
|
||||||
self.gui.channels.clear()
|
|
||||||
self.gui.channels.shrink()
|
|
||||||
for channel in ordered_channels:
|
|
||||||
channels[channel.id] = channel
|
|
||||||
channel.display(add=True)
|
|
||||||
# subscribe to these channel's state updates
|
|
||||||
self.websocket.add_topics([
|
|
||||||
WebsocketTopic(
|
|
||||||
"Channel", "StreamState", channel_id, self.process_stream_state
|
|
||||||
)
|
|
||||||
for channel_id in channels
|
|
||||||
])
|
|
||||||
# relink watching channel after cleanup,
|
|
||||||
# or stop watching it if it no longer qualifies
|
|
||||||
watching_channel = self.watching_channel.get_with_default(None)
|
|
||||||
if watching_channel is not None:
|
|
||||||
new_watching = channels.get(watching_channel.id)
|
|
||||||
if new_watching is not None and self.can_watch(new_watching):
|
|
||||||
self.watch(new_watching)
|
|
||||||
else:
|
else:
|
||||||
# we're removing a channel we're watching
|
no_acl = True
|
||||||
self.stop_watching()
|
# remove all ACL channels from the separate set that already exist
|
||||||
# pre-display the active drop again with a substracted minute
|
acl_channels.difference_update(new_channels)
|
||||||
for channel in channels.values():
|
# use the separate set to set them online if possible
|
||||||
# check if there's any channels we can watch first
|
if acl_channels:
|
||||||
if self.can_watch(channel):
|
await asyncio.gather(*(channel.check_online() for channel in acl_channels))
|
||||||
if (active_drop := self.get_active_drop(channel)) is not None:
|
if no_acl:
|
||||||
active_drop.display(countdown=False, subone=True)
|
# if there's at least one campaign without an ACL,
|
||||||
break
|
# add a list of live channels with drops enabled
|
||||||
self.change_state(State.CHANNEL_SWITCH)
|
new_channels.update(await self.get_live_streams())
|
||||||
|
# sort them descending by viewers,
|
||||||
|
# then by priority so that prioritized ones are first
|
||||||
|
# NOTE: We can drop OrderedSet now because there's no more channels being added
|
||||||
|
ordered_channels: list[Channel] = sorted(
|
||||||
|
new_channels, key=viewers_key, reverse=True
|
||||||
|
)
|
||||||
|
ordered_channels.sort(key=lambda ch: ch.priority, reverse=True)
|
||||||
|
# ensure that we won't end up with more channels than we can handle
|
||||||
|
# NOTE: we substract 2 due to the two base topics always being added:
|
||||||
|
# channel points gain and drop update subscriptions
|
||||||
|
# NOTE: we trim from the end because that's where the non-priority,
|
||||||
|
# offline (or online but low viewers) channels end up
|
||||||
|
max_channels = MAX_WEBSOCKETS * WS_TOPICS_LIMIT - 2
|
||||||
|
to_remove = ordered_channels[max_channels:]
|
||||||
|
ordered_channels = ordered_channels[:max_channels]
|
||||||
|
if to_remove:
|
||||||
|
# tracked channels and gui are cleared below, so no need to do it here
|
||||||
|
# just make sure to unsubscribe from their topics
|
||||||
|
self.websocket.remove_topics(
|
||||||
|
WebsocketTopic.as_str("Channel", "StreamState", channel.id)
|
||||||
|
for channel in to_remove
|
||||||
|
)
|
||||||
|
del to_remove
|
||||||
|
# set our new channel list
|
||||||
|
channels.clear()
|
||||||
|
self.gui.channels.clear()
|
||||||
|
self.gui.channels.shrink()
|
||||||
|
for channel in ordered_channels:
|
||||||
|
channels[channel.id] = channel
|
||||||
|
channel.display(add=True)
|
||||||
|
# subscribe to these channel's state updates
|
||||||
|
self.websocket.add_topics([
|
||||||
|
WebsocketTopic(
|
||||||
|
"Channel", "StreamState", channel_id, self.process_stream_state
|
||||||
|
)
|
||||||
|
for channel_id in channels
|
||||||
|
])
|
||||||
|
# relink watching channel after cleanup,
|
||||||
|
# or stop watching it if it no longer qualifies
|
||||||
|
watching_channel = self.watching_channel.get_with_default(None)
|
||||||
|
if watching_channel is not None:
|
||||||
|
new_watching = channels.get(watching_channel.id)
|
||||||
|
if new_watching is not None and self.can_watch(new_watching):
|
||||||
|
self.watch(new_watching)
|
||||||
|
else:
|
||||||
|
# we're removing a channel we're watching
|
||||||
|
self.stop_watching()
|
||||||
|
# pre-display the active drop again with a substracted minute
|
||||||
|
for channel in channels.values():
|
||||||
|
# check if there's any channels we can watch first
|
||||||
|
if self.can_watch(channel):
|
||||||
|
if (active_drop := self.get_active_drop(channel)) is not None:
|
||||||
|
active_drop.display(countdown=False, subone=True)
|
||||||
|
break
|
||||||
|
self.change_state(State.CHANNEL_SWITCH)
|
||||||
elif self._state is State.CHANNEL_SWITCH:
|
elif self._state is State.CHANNEL_SWITCH:
|
||||||
if self.game is None:
|
if self.game is None:
|
||||||
self.change_state(State.GAME_SELECT)
|
self.change_state(State.GAME_SELECT)
|
||||||
|
continue
|
||||||
|
# Change into the selected channel, stay in the watching channel,
|
||||||
|
# or select a new channel that meets the required conditions
|
||||||
|
priority_channels: list[Channel] = []
|
||||||
|
selected_channel = self.gui.channels.get_selection()
|
||||||
|
if selected_channel is not None:
|
||||||
|
self.gui.channels.clear_selection()
|
||||||
|
priority_channels.append(selected_channel)
|
||||||
|
watching_channel = self.watching_channel.get_with_default(None)
|
||||||
|
if watching_channel is not None:
|
||||||
|
priority_channels.append(watching_channel)
|
||||||
|
# If there's no selected channel, change into a channel we can watch
|
||||||
|
for channel in chain(priority_channels, channels.values()):
|
||||||
|
if self.can_watch(channel):
|
||||||
|
self.watch(channel)
|
||||||
|
# break the state change chain by clearing the flag
|
||||||
|
self._state_change.clear()
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
# Change into the selected channel, stay in the watching channel,
|
self.gui.print(
|
||||||
# or select a new channel that meets the required conditions
|
f"No suitable channel to watch for game: {self.game}\n"
|
||||||
priority_channels: list[Channel] = []
|
"Waiting for an ONLINE channel..."
|
||||||
selected_channel = self.gui.channels.get_selection()
|
)
|
||||||
if selected_channel is not None:
|
self.change_state(State.IDLE)
|
||||||
self.gui.channels.clear_selection()
|
|
||||||
priority_channels.append(selected_channel)
|
|
||||||
watching_channel = self.watching_channel.get_with_default(None)
|
|
||||||
if watching_channel is not None:
|
|
||||||
priority_channels.append(watching_channel)
|
|
||||||
# If there's no selected channel, change into a channel we can watch
|
|
||||||
for channel in chain(priority_channels, channels.values()):
|
|
||||||
if self.can_watch(channel):
|
|
||||||
self.watch(channel)
|
|
||||||
# break the state change chain by clearing the flag
|
|
||||||
self._state_change.clear()
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.gui.print(
|
|
||||||
f"No suitable channel to watch for game: {self.game}\n"
|
|
||||||
"Waiting for an ONLINE channel..."
|
|
||||||
)
|
|
||||||
self.change_state(State.IDLE)
|
|
||||||
elif self._state is State.EXIT:
|
elif self._state is State.EXIT:
|
||||||
# we've been requested to exit the application
|
# we've been requested to exit the application
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in new issue
Block a user