output/Interface: convert to abstract class

Yet another C-style vtable replaced with C++.
This commit is contained in:
Max Kellermann
2017-08-09 16:58:44 +02:00
parent 1cf7f3d87c
commit 31bad5f7af
30 changed files with 531 additions and 1130 deletions

View File

@@ -26,8 +26,7 @@
#define MPD_OUTPUT_HTTPD_INTERNAL_H
#include "HttpdClient.hxx"
#include "output/Wrapper.hxx"
#include "output/Filtered.hxx"
#include "output/Interface.hxx"
#include "output/Timer.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
@@ -49,11 +48,7 @@ class PreparedEncoder;
class Encoder;
struct Tag;
class HttpdOutput final : ServerSocket, DeferredMonitor {
friend struct AudioOutputWrapper<HttpdOutput>;
AudioOutput base;
class HttpdOutput final : AudioOutput, ServerSocket, DeferredMonitor {
/**
* True if the audio output is open and accepts client
* connections.
@@ -157,11 +152,9 @@ public:
HttpdOutput(EventLoop &_loop, const ConfigBlock &block);
~HttpdOutput();
static HttpdOutput *Create(EventLoop &event_loop,
const ConfigBlock &block);
static constexpr HttpdOutput *Cast(AudioOutput *ao) {
return &ContainerCast(*ao, &HttpdOutput::base);
static AudioOutput *Create(EventLoop &event_loop,
const ConfigBlock &block) {
return new HttpdOutput(event_loop, block);
}
using DeferredMonitor::GetEventLoop;
@@ -169,11 +162,11 @@ public:
void Bind();
void Unbind();
void Enable() {
void Enable() override {
Bind();
}
void Disable() {
void Disable() noexcept override {
Unbind();
}
@@ -187,12 +180,12 @@ public:
/**
* Caller must lock the mutex.
*/
void Open(AudioFormat &audio_format);
void Open(AudioFormat &audio_format) override;
/**
* Caller must lock the mutex.
*/
void Close();
void Close() noexcept override;
/**
* Check whether there is at least one client.
@@ -227,7 +220,7 @@ public:
void SendHeader(HttpdClient &client) const;
gcc_pure
std::chrono::steady_clock::duration Delay() const noexcept;
std::chrono::steady_clock::duration Delay() const noexcept override;
/**
* Reads data from the encoder (as much as available) and
@@ -252,14 +245,14 @@ public:
*/
void EncodeAndPlay(const void *chunk, size_t size);
void SendTag(const Tag &tag);
void SendTag(const Tag &tag) override;
size_t Play(const void *chunk, size_t size);
size_t Play(const void *chunk, size_t size) override;
void CancelAllClients();
void Cancel();
bool Pause();
void Cancel() noexcept override;
bool Pause() noexcept override;
private:
virtual void RunDeferred() override;

View File

@@ -50,8 +50,8 @@ const Domain httpd_output_domain("httpd_output");
inline
HttpdOutput::HttpdOutput(EventLoop &_loop, const ConfigBlock &block)
:ServerSocket(_loop), DeferredMonitor(_loop),
base(httpd_output_plugin),
:AudioOutput(FLAG_ENABLE_DISABLE|FLAG_PAUSE),
ServerSocket(_loop), DeferredMonitor(_loop),
encoder(nullptr), unflushed_input(0),
metadata(nullptr)
{
@@ -113,12 +113,6 @@ HttpdOutput::Unbind()
});
}
HttpdOutput *
HttpdOutput::Create(EventLoop &event_loop, const ConfigBlock &block)
{
return new HttpdOutput(event_loop, block);
}
/**
* Creates a new #HttpdClient object and adds it into the
* HttpdOutput.clients linked list.
@@ -246,7 +240,7 @@ HttpdOutput::OpenEncoder(AudioFormat &audio_format)
unflushed_input = 0;
}
inline void
void
HttpdOutput::Open(AudioFormat &audio_format)
{
assert(!open);
@@ -264,8 +258,8 @@ HttpdOutput::Open(AudioFormat &audio_format)
pause = false;
}
inline void
HttpdOutput::Close()
void
HttpdOutput::Close() noexcept
{
assert(open);
@@ -300,7 +294,7 @@ HttpdOutput::SendHeader(HttpdClient &client) const
client.PushPage(header);
}
inline std::chrono::steady_clock::duration
std::chrono::steady_clock::duration
HttpdOutput::Delay() const noexcept
{
if (!LockHasClients() && pause) {
@@ -367,7 +361,7 @@ HttpdOutput::EncodeAndPlay(const void *chunk, size_t size)
BroadcastFromEncoder();
}
inline size_t
size_t
HttpdOutput::Play(const void *chunk, size_t size)
{
pause = false;
@@ -383,7 +377,7 @@ HttpdOutput::Play(const void *chunk, size_t size)
}
bool
HttpdOutput::Pause()
HttpdOutput::Pause() noexcept
{
pause = true;
@@ -395,7 +389,7 @@ HttpdOutput::Pause()
return true;
}
inline void
void
HttpdOutput::SendTag(const Tag &tag)
{
if (encoder->ImplementsTag()) {
@@ -463,29 +457,16 @@ HttpdOutput::CancelAllClients()
}
void
HttpdOutput::Cancel()
HttpdOutput::Cancel() noexcept
{
BlockingCall(GetEventLoop(), [this](){
CancelAllClients();
});
}
typedef AudioOutputWrapper<HttpdOutput> Wrapper;
const struct AudioOutputPlugin httpd_output_plugin = {
"httpd",
nullptr,
&Wrapper::Init,
&Wrapper::Finish,
&Wrapper::Enable,
&Wrapper::Disable,
&Wrapper::Open,
&Wrapper::Close,
&Wrapper::Delay,
&Wrapper::SendTag,
&Wrapper::Play,
nullptr,
&Wrapper::Cancel,
&Wrapper::Pause,
&HttpdOutput::Create,
nullptr,
};