Instance: make "partition" a std::list

With this commit, multi-player support becomes possible... it's just
not wired to the frontend yet.

This is based on massive amounts of refactoring work I did over the
past 9 years.
This commit is contained in:
Max Kellermann 2017-02-17 23:21:20 +01:00
parent 9a909d9f27
commit 77178e0590
4 changed files with 42 additions and 24 deletions

View File

@ -59,7 +59,9 @@ Instance::OnDatabaseModified()
/* propagate the change to all subsystems */ /* propagate the change to all subsystems */
stats_invalidate(); stats_invalidate();
partition->DatabaseModified(*database);
for (auto &partition : partitions)
partition.DatabaseModified(*database);
} }
void void
@ -77,7 +79,8 @@ Instance::OnDatabaseSongRemoved(const char *uri)
} }
#endif #endif
partition->StaleSong(uri); for (auto &partition : partitions)
partition.StaleSong(uri);
} }
#endif #endif
@ -87,13 +90,15 @@ Instance::OnDatabaseSongRemoved(const char *uri)
void void
Instance::FoundNeighbor(gcc_unused const NeighborInfo &info) Instance::FoundNeighbor(gcc_unused const NeighborInfo &info)
{ {
partition->EmitIdle(IDLE_NEIGHBOR); for (auto &partition : partitions)
partition.EmitIdle(IDLE_NEIGHBOR);
} }
void void
Instance::LostNeighbor(gcc_unused const NeighborInfo &info) Instance::LostNeighbor(gcc_unused const NeighborInfo &info)
{ {
partition->EmitIdle(IDLE_NEIGHBOR); for (auto &partition : partitions)
partition.EmitIdle(IDLE_NEIGHBOR);
} }
#endif #endif

View File

@ -38,6 +38,8 @@ class Storage;
class UpdateService; class UpdateService;
#endif #endif
#include <list>
class ClientList; class ClientList;
struct Partition; struct Partition;
class StateFile; class StateFile;
@ -87,7 +89,7 @@ struct Instance final
ClientList *client_list; ClientList *client_list;
Partition *partition; std::list<Partition> partitions;
StateFile *state_file = nullptr; StateFile *state_file = nullptr;

View File

@ -265,7 +265,7 @@ glue_state_file_init()
StateFile::DEFAULT_INTERVAL); StateFile::DEFAULT_INTERVAL);
instance->state_file = new StateFile(std::move(path_fs), interval, instance->state_file = new StateFile(std::move(path_fs), interval,
*instance->partition, instance->partitions.front(),
instance->event_loop); instance->event_loop);
instance->state_file->Read(); instance->state_file->Read();
} }
@ -352,18 +352,19 @@ initialize_decoder_and_player(const ReplayGainConfig &replay_gain_config)
} }
} }
instance->partition = new Partition(*instance, instance->partitions.emplace_back(*instance,
"default", "default",
max_length, max_length,
buffered_chunks, buffered_chunks,
buffered_before_play, buffered_before_play,
configured_audio_format, configured_audio_format,
replay_gain_config); replay_gain_config);
auto &partition = instance->partitions.back();
try { try {
param = config_get_param(ConfigOption::REPLAYGAIN); param = config_get_param(ConfigOption::REPLAYGAIN);
if (param != nullptr) if (param != nullptr)
instance->partition->replay_gain_mode = partition.replay_gain_mode =
FromString(param->value.c_str()); FromString(param->value.c_str());
} catch (...) { } catch (...) {
std::throw_with_nested(FormatRuntimeError("Failed to parse line %i", std::throw_with_nested(FormatRuntimeError("Failed to parse line %i",
@ -467,7 +468,7 @@ try {
initialize_decoder_and_player(config.replay_gain); initialize_decoder_and_player(config.replay_gain);
listen_global_init(instance->event_loop, *instance->partition); listen_global_init(instance->event_loop, instance->partitions.front());
#ifdef ENABLE_DAEMON #ifdef ENABLE_DAEMON
daemonize_set_user(); daemonize_set_user();
@ -519,10 +520,12 @@ try {
command_init(); command_init();
instance->partition->outputs.Configure(instance->io_thread.GetEventLoop(), for (auto &partition : instance->partitions) {
partition.outputs.Configure(instance->io_thread.GetEventLoop(),
config.replay_gain, config.replay_gain,
instance->partition->pc); partition.pc);
instance->partition->UpdateEffectiveReplayGainMode(); partition.UpdateEffectiveReplayGainMode();
}
client_manager_init(); client_manager_init();
input_stream_global_init(instance->io_thread.GetEventLoop()); input_stream_global_init(instance->io_thread.GetEventLoop());
@ -547,7 +550,8 @@ try {
ZeroconfInit(instance->event_loop); ZeroconfInit(instance->event_loop);
StartPlayerThread(instance->partition->pc); for (auto &partition : instance->partitions)
StartPlayerThread(partition.pc);
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
if (create_db) { if (create_db) {
@ -582,7 +586,8 @@ try {
/* enable all audio outputs (if not already done by /* enable all audio outputs (if not already done by
playlist_state_restore() */ playlist_state_restore() */
instance->partition->pc.LockUpdateAudio(); for (auto &partition : instance->partitions)
partition.pc.LockUpdateAudio();
#ifdef WIN32 #ifdef WIN32
win32_app_started(); win32_app_started();
@ -617,7 +622,9 @@ try {
delete instance->state_file; delete instance->state_file;
} }
instance->partition->pc.Kill(); for (auto &partition : instance->partitions)
partition.pc.Kill();
ZeroconfDeinit(); ZeroconfDeinit();
listen_global_finish(); listen_global_finish();
delete instance->client_list; delete instance->client_list;
@ -653,7 +660,7 @@ try {
DeinitFS(); DeinitFS();
delete instance->partition; instance->partitions.clear();
command_finish(); command_finish();
decoder_plugin_deinit_all(); decoder_plugin_deinit_all();
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE

View File

@ -20,6 +20,7 @@
#include "config.h" #include "config.h"
#include "PartitionCommands.hxx" #include "PartitionCommands.hxx"
#include "Request.hxx" #include "Request.hxx"
#include "Instance.hxx"
#include "Partition.hxx" #include "Partition.hxx"
#include "client/Client.hxx" #include "client/Client.hxx"
#include "client/Response.hxx" #include "client/Response.hxx"
@ -27,6 +28,9 @@
CommandResult CommandResult
handle_listpartitions(Client &client, Request, Response &r) handle_listpartitions(Client &client, Request, Response &r)
{ {
r.Format("partition: %s\n", client.partition.name.c_str()); for (const auto &partition : client.partition.instance.partitions) {
r.Format("partition: %s\n", partition.name.c_str());
}
return CommandResult::OK; return CommandResult::OK;
} }