Partition: add a local idle_monitor
Make idle events per-partition, but leave Instance::EmitIdle() and its underlying idle_monitor which broadcasts idle events to all partitions.
This commit is contained in:
parent
879bafb837
commit
49309b419f
@ -180,10 +180,7 @@ Instance::OnRemoteTag(const char *uri, const Tag &tag) noexcept
|
|||||||
void
|
void
|
||||||
Instance::OnIdle(unsigned flags) noexcept
|
Instance::OnIdle(unsigned flags) noexcept
|
||||||
{
|
{
|
||||||
/* send "idle" notifications to all subscribed
|
/* broadcast to all partitions */
|
||||||
clients */
|
for (auto &partition : partitions)
|
||||||
client_list->IdleAdd(flags);
|
partition.EmitIdle(flags);
|
||||||
|
|
||||||
if (flags & (IDLE_PLAYLIST|IDLE_PLAYER|IDLE_MIXER|IDLE_OUTPUT))
|
|
||||||
OnStateModified();
|
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,10 @@ struct Instance final
|
|||||||
|
|
||||||
std::unique_ptr<InputCacheManager> input_cache;
|
std::unique_ptr<InputCacheManager> input_cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor for global idle events to be broadcasted to all
|
||||||
|
* partitions.
|
||||||
|
*/
|
||||||
MaskMonitor idle_monitor;
|
MaskMonitor idle_monitor;
|
||||||
|
|
||||||
#ifdef ENABLE_NEIGHBOR_PLUGINS
|
#ifdef ENABLE_NEIGHBOR_PLUGINS
|
||||||
|
@ -40,6 +40,7 @@ Partition::Partition(Instance &_instance,
|
|||||||
:instance(_instance),
|
:instance(_instance),
|
||||||
name(_name),
|
name(_name),
|
||||||
listener(new ClientListener(instance.event_loop, *this)),
|
listener(new ClientListener(instance.event_loop, *this)),
|
||||||
|
idle_monitor(instance.event_loop, BIND_THIS_METHOD(OnIdleMonitor)),
|
||||||
global_events(instance.event_loop, BIND_THIS_METHOD(OnGlobalEvent)),
|
global_events(instance.event_loop, BIND_THIS_METHOD(OnGlobalEvent)),
|
||||||
playlist(max_length, *this),
|
playlist(max_length, *this),
|
||||||
outputs(*this),
|
outputs(*this),
|
||||||
@ -60,12 +61,6 @@ Partition::BeginShutdown() noexcept
|
|||||||
listener.reset();
|
listener.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Partition::EmitIdle(unsigned mask) noexcept
|
|
||||||
{
|
|
||||||
instance.EmitIdle(mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
PrefetchSong(InputCacheManager &cache, const char *uri) noexcept
|
PrefetchSong(InputCacheManager &cache, const char *uri) noexcept
|
||||||
{
|
{
|
||||||
@ -215,6 +210,18 @@ Partition::OnMixerVolumeChanged(Mixer &, int) noexcept
|
|||||||
EmitIdle(IDLE_MIXER);
|
EmitIdle(IDLE_MIXER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Partition::OnIdleMonitor(unsigned mask) noexcept
|
||||||
|
{
|
||||||
|
/* send "idle" notifications to all subscribed
|
||||||
|
clients */
|
||||||
|
for (auto &client : clients)
|
||||||
|
client.IdleAdd(mask);
|
||||||
|
|
||||||
|
if (mask & (IDLE_PLAYLIST|IDLE_PLAYER|IDLE_MIXER|IDLE_OUTPUT))
|
||||||
|
instance.OnStateModified();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Partition::OnGlobalEvent(unsigned mask) noexcept
|
Partition::OnGlobalEvent(unsigned mask) noexcept
|
||||||
{
|
{
|
||||||
|
@ -63,6 +63,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
|
|||||||
boost::intrusive::link_mode<boost::intrusive::normal_link>>>,
|
boost::intrusive::link_mode<boost::intrusive::normal_link>>>,
|
||||||
boost::intrusive::constant_time_size<false>> clients;
|
boost::intrusive::constant_time_size<false>> clients;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor for idle events local to this partition.
|
||||||
|
*/
|
||||||
|
MaskMonitor idle_monitor;
|
||||||
|
|
||||||
MaskMonitor global_events;
|
MaskMonitor global_events;
|
||||||
|
|
||||||
struct playlist playlist;
|
struct playlist playlist;
|
||||||
@ -91,10 +96,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
|
|||||||
/**
|
/**
|
||||||
* Emit an "idle" event to all clients of this partition.
|
* Emit an "idle" event to all clients of this partition.
|
||||||
*
|
*
|
||||||
* This method is not thread-safe and may only be called from
|
* This method can be called from any thread.
|
||||||
* the main thread.
|
|
||||||
*/
|
*/
|
||||||
void EmitIdle(unsigned mask) noexcept;
|
void EmitIdle(unsigned mask) noexcept {
|
||||||
|
idle_monitor.OrMask(mask);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate the #InputCacheManager with soon-to-be-played song
|
* Populate the #InputCacheManager with soon-to-be-played song
|
||||||
@ -282,6 +288,9 @@ private:
|
|||||||
/* virtual methods from class MixerListener */
|
/* virtual methods from class MixerListener */
|
||||||
void OnMixerVolumeChanged(Mixer &mixer, int volume) noexcept override;
|
void OnMixerVolumeChanged(Mixer &mixer, int volume) noexcept override;
|
||||||
|
|
||||||
|
/* callback for #idle_monitor */
|
||||||
|
void OnIdleMonitor(unsigned mask) noexcept;
|
||||||
|
|
||||||
/* callback for #global_events */
|
/* callback for #global_events */
|
||||||
void OnGlobalEvent(unsigned mask) noexcept;
|
void OnGlobalEvent(unsigned mask) noexcept;
|
||||||
};
|
};
|
||||||
|
@ -34,12 +34,3 @@ ClientList::Remove(Client &client) noexcept
|
|||||||
|
|
||||||
list.erase(list.iterator_to(client));
|
list.erase(list.iterator_to(client));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ClientList::IdleAdd(unsigned flags) noexcept
|
|
||||||
{
|
|
||||||
assert(flags != 0);
|
|
||||||
|
|
||||||
for (auto &client : list)
|
|
||||||
client.IdleAdd(flags);
|
|
||||||
}
|
|
||||||
|
@ -56,8 +56,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Remove(Client &client) noexcept;
|
void Remove(Client &client) noexcept;
|
||||||
|
|
||||||
void IdleAdd(unsigned flags) noexcept;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user