command/partition: add command "delpartition"
This commit is contained in:
parent
9cbfa66886
commit
cc7f66822e
1
NEWS
1
NEWS
|
@ -4,6 +4,7 @@ ver 0.22 (not yet released)
|
||||||
"window" parameters
|
"window" parameters
|
||||||
- add command "readpicture" to download embedded pictures
|
- add command "readpicture" to download embedded pictures
|
||||||
- command "moveoutput" moves an output between partitions
|
- command "moveoutput" moves an output between partitions
|
||||||
|
- command "delpartition" deletes a partition
|
||||||
- show partition name in "status" response
|
- show partition name in "status" response
|
||||||
* tags
|
* tags
|
||||||
- new tags "Grouping" (for ID3 "TIT1"), "Work" and "Conductor"
|
- new tags "Grouping" (for ID3 "TIT1"), "Work" and "Conductor"
|
||||||
|
|
|
@ -1262,6 +1262,10 @@ client is assigned to one partition at a time.
|
||||||
:command:`newpartition {NAME}`
|
:command:`newpartition {NAME}`
|
||||||
Create a new partition.
|
Create a new partition.
|
||||||
|
|
||||||
|
:command:`delpartition {NAME}`
|
||||||
|
Delete a partition. The partition must be empty (no connected
|
||||||
|
clients and no outputs).
|
||||||
|
|
||||||
:command:`moveoutput {OUTPUTNAME}`
|
:command:`moveoutput {OUTPUTNAME}`
|
||||||
Move an output to the current partition.
|
Move an output to the current partition.
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,20 @@ Instance::FindPartition(const char *name) noexcept
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Instance::DeletePartition(Partition &partition) noexcept
|
||||||
|
{
|
||||||
|
// TODO: use boost::intrusive::list to avoid this loop
|
||||||
|
for (auto i = partitions.begin();; ++i) {
|
||||||
|
assert(i != partitions.end());
|
||||||
|
|
||||||
|
if (&*i == &partition) {
|
||||||
|
partitions.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
|
|
||||||
const Database &
|
const Database &
|
||||||
|
|
|
@ -171,6 +171,8 @@ struct Instance final
|
||||||
gcc_pure
|
gcc_pure
|
||||||
Partition *FindPartition(const char *name) noexcept;
|
Partition *FindPartition(const char *name) noexcept;
|
||||||
|
|
||||||
|
void DeletePartition(Partition &partition) noexcept;
|
||||||
|
|
||||||
void BeginShutdownPartitions() noexcept;
|
void BeginShutdownPartitions() noexcept;
|
||||||
|
|
||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
|
|
|
@ -103,6 +103,7 @@ static constexpr struct command commands[] = {
|
||||||
{ "decoders", PERMISSION_READ, 0, 0, handle_decoders },
|
{ "decoders", PERMISSION_READ, 0, 0, handle_decoders },
|
||||||
{ "delete", PERMISSION_CONTROL, 1, 1, handle_delete },
|
{ "delete", PERMISSION_CONTROL, 1, 1, handle_delete },
|
||||||
{ "deleteid", PERMISSION_CONTROL, 1, 1, handle_deleteid },
|
{ "deleteid", PERMISSION_CONTROL, 1, 1, handle_deleteid },
|
||||||
|
{ "delpartition", PERMISSION_ADMIN, 1, 1, handle_delpartition },
|
||||||
{ "disableoutput", PERMISSION_ADMIN, 1, 1, handle_disableoutput },
|
{ "disableoutput", PERMISSION_ADMIN, 1, 1, handle_disableoutput },
|
||||||
{ "enableoutput", PERMISSION_ADMIN, 1, 1, handle_enableoutput },
|
{ "enableoutput", PERMISSION_ADMIN, 1, 1, handle_enableoutput },
|
||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
|
|
|
@ -112,6 +112,48 @@ handle_newpartition(Client &client, Request request, Response &response)
|
||||||
return CommandResult::OK;
|
return CommandResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandResult
|
||||||
|
handle_delpartition(Client &client, Request request, Response &response)
|
||||||
|
{
|
||||||
|
const char *name = request.front();
|
||||||
|
if (!IsValidPartitionName(name)) {
|
||||||
|
response.Error(ACK_ERROR_ARG, "bad name");
|
||||||
|
return CommandResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &instance = client.GetInstance();
|
||||||
|
auto *partition = instance.FindPartition(name);
|
||||||
|
if (partition == nullptr) {
|
||||||
|
response.Error(ACK_ERROR_NO_EXIST, "no such partition");
|
||||||
|
return CommandResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (partition == &instance.partitions.front()) {
|
||||||
|
response.Error(ACK_ERROR_UNKNOWN,
|
||||||
|
"cannot delete the default partition");
|
||||||
|
return CommandResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!partition->clients.empty()) {
|
||||||
|
response.Error(ACK_ERROR_UNKNOWN,
|
||||||
|
"partition still has clients");
|
||||||
|
return CommandResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!partition->outputs.IsDummy()) {
|
||||||
|
response.Error(ACK_ERROR_UNKNOWN,
|
||||||
|
"partition still has outputs");
|
||||||
|
return CommandResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
partition->BeginShutdown();
|
||||||
|
instance.DeletePartition(*partition);
|
||||||
|
|
||||||
|
instance.EmitIdle(IDLE_PARTITION);
|
||||||
|
|
||||||
|
return CommandResult::OK;
|
||||||
|
}
|
||||||
|
|
||||||
CommandResult
|
CommandResult
|
||||||
handle_moveoutput(Client &client, Request request, Response &response)
|
handle_moveoutput(Client &client, Request request, Response &response)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,9 @@ handle_listpartitions(Client &client, Request request, Response &response);
|
||||||
CommandResult
|
CommandResult
|
||||||
handle_newpartition(Client &client, Request request, Response &response);
|
handle_newpartition(Client &client, Request request, Response &response);
|
||||||
|
|
||||||
|
CommandResult
|
||||||
|
handle_delpartition(Client &client, Request request, Response &response);
|
||||||
|
|
||||||
CommandResult
|
CommandResult
|
||||||
handle_moveoutput(Client &client, Request request, Response &response);
|
handle_moveoutput(Client &client, Request request, Response &response);
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,18 @@ public:
|
||||||
return *outputs[i];
|
return *outputs[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are all outputs dummy?
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
bool IsDummy() const noexcept {
|
||||||
|
for (const auto &i : outputs)
|
||||||
|
if (!i->IsDummy())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the audio output device with the specified name.
|
* Returns the audio output device with the specified name.
|
||||||
* Returns nullptr if the name does not exist.
|
* Returns nullptr if the name does not exist.
|
||||||
|
|
Loading…
Reference in New Issue