diff --git a/Libraries/LibAudio/AClientConnection.cpp b/Libraries/LibAudio/AClientConnection.cpp index bc0eecaa7f..00f36d6387 100644 --- a/Libraries/LibAudio/AClientConnection.cpp +++ b/Libraries/LibAudio/AClientConnection.cpp @@ -9,23 +9,17 @@ AClientConnection::AClientConnection() void AClientConnection::handshake() { - ASAPI_ClientMessage request; - request.type = ASAPI_ClientMessage::Type::Greeting; - request.greeting.client_pid = getpid(); - auto response = sync_request(request, ASAPI_ServerMessage::Type::Greeting); - set_server_pid(response.greeting.server_pid); - set_my_client_id(response.greeting.your_client_id); + auto response = send_sync(getpid()); + set_server_pid(response.server_pid()); + set_my_client_id(response.your_client_id()); } void AClientConnection::enqueue(const ABuffer& buffer) { for (;;) { const_cast(buffer).shared_buffer().share_with(server_pid()); - ASAPI_ClientMessage request; - request.type = ASAPI_ClientMessage::Type::EnqueueBuffer; - request.play_buffer.buffer_id = buffer.shared_buffer_id(); - auto response = sync_request(request, ASAPI_ServerMessage::Type::EnqueueBufferResponse); - if (response.success) + auto response = send_sync(buffer.shared_buffer_id()); + if (response.success()) break; sleep(1); } @@ -33,16 +27,10 @@ void AClientConnection::enqueue(const ABuffer& buffer) int AClientConnection::get_main_mix_volume() { - ASAPI_ClientMessage request; - request.type = ASAPI_ClientMessage::Type::GetMainMixVolume; - auto response = sync_request(request, ASAPI_ServerMessage::Type::DidGetMainMixVolume); - return response.value; + return send_sync().volume(); } void AClientConnection::set_main_mix_volume(int volume) { - ASAPI_ClientMessage request; - request.type = ASAPI_ClientMessage::Type::SetMainMixVolume; - request.value = volume; - sync_request(request, ASAPI_ServerMessage::Type::DidSetMainMixVolume); + send_sync(volume); } diff --git a/Libraries/LibAudio/ASAPI.h b/Libraries/LibAudio/ASAPI.h index 2915360ff3..6d91f6bcef 100644 --- a/Libraries/LibAudio/ASAPI.h +++ b/Libraries/LibAudio/ASAPI.h @@ -1,10 +1,11 @@ #pragma once +#include + struct ASAPI_ServerMessage { enum class Type { Invalid, Greeting, - PlayingBuffer, FinishedPlayingBuffer, EnqueueBufferResponse, DidGetMainMixVolume, @@ -49,3 +50,201 @@ struct ASAPI_ClientMessage { } play_buffer; }; }; + +// FIXME: Everything below this line should be generated from some kind of IPC protocol description. + +namespace ASAPI_Server { +class Greeting; +class FinishedPlayingBuffer; +class EnqueueBufferResponse; +class DidGetMainMixVolume; +class DidSetMainMixVolume; +} + +namespace ASAPI_Client { + +template +class Message { +public: + static ASAPI_ClientMessage::Type message_type() { return type; } + operator const ASAPI_ClientMessage&() const { return m_message; } + +protected: + Message() + { + m_message.type = type; + } + + Message(const ASAPI_ClientMessage& message) + : m_message(message) + { + ASSERT(message.type == type); + } + + ASAPI_ClientMessage m_message; +}; + +class Greeting : public Message { +public: + typedef ASAPI_Server::Greeting ResponseType; + Greeting(const ASAPI_ClientMessage& message) + : Message(message) + { + } + + Greeting(int client_pid) + { + m_message.greeting.client_pid = client_pid; + } + + int client_pid() const { return m_message.greeting.client_pid; } +}; + +class EnqueueBuffer : public Message { +public: + typedef ASAPI_Server::EnqueueBufferResponse ResponseType; + + EnqueueBuffer(const ASAPI_ClientMessage& message) + : Message(message) + { + } + + EnqueueBuffer(int buffer_id) + { + m_message.play_buffer.buffer_id = buffer_id; + } + + int buffer_id() const { return m_message.play_buffer.buffer_id; } +}; + +class GetMainMixVolume : public Message { +public: + typedef ASAPI_Server::DidGetMainMixVolume ResponseType; + + GetMainMixVolume(const ASAPI_ClientMessage& message) + : Message(message) + { + } + + GetMainMixVolume() + { + } +}; + +class SetMainMixVolume : public Message { +public: + typedef ASAPI_Server::DidSetMainMixVolume ResponseType; + + SetMainMixVolume(const ASAPI_ClientMessage& message) + : Message(message) + { + } + + SetMainMixVolume(int volume) + { + m_message.value = volume; + } +}; + +} + +namespace ASAPI_Server { + +template +class Message { +public: + static ASAPI_ServerMessage::Type message_type() { return type; } + operator const ASAPI_ServerMessage&() const { return m_message; } + +protected: + Message() + { + m_message.type = type; + } + + Message(const ASAPI_ServerMessage& message) + : m_message(message) + { + ASSERT(message.type == type); + } + + ASAPI_ServerMessage m_message; +}; + +class Greeting : public Message { +public: + Greeting(const ASAPI_ServerMessage& message) + : Message(message) + { + } + + Greeting(int server_pid, int your_client_id) + { + m_message.greeting.server_pid = server_pid; + m_message.greeting.your_client_id = your_client_id; + } + + int server_pid() const { return m_message.greeting.server_pid; } + int your_client_id() const { return m_message.greeting.your_client_id; } +}; + +class FinishedPlayingBuffer : public Message { +public: + FinishedPlayingBuffer(const ASAPI_ServerMessage& message) + : Message(message) + { + } + + FinishedPlayingBuffer(int buffer_id) + { + m_message.playing_buffer.buffer_id = buffer_id; + } + + int buffer_id() const { return m_message.playing_buffer.buffer_id; } +}; + +class EnqueueBufferResponse : public Message { +public: + EnqueueBufferResponse(const ASAPI_ServerMessage& message) + : Message(message) + { + } + + EnqueueBufferResponse(bool success, int buffer_id) + { + m_message.success = success; + m_message.playing_buffer.buffer_id = buffer_id; + } + + bool success() const { return m_message.success; } + int buffer_id() const { return m_message.playing_buffer.buffer_id; } +}; + +class DidGetMainMixVolume : public Message { +public: + DidGetMainMixVolume(const ASAPI_ServerMessage& message) + : Message(message) + { + } + + DidGetMainMixVolume(int volume) + { + m_message.value = volume; + } + + int volume() const { return m_message.value; } +}; + +class DidSetMainMixVolume : public Message { +public: + DidSetMainMixVolume(const ASAPI_ServerMessage& message) + : Message(message) + { + } + + DidSetMainMixVolume() + { + } +}; + +} diff --git a/Libraries/LibCore/CoreIPCClient.h b/Libraries/LibCore/CoreIPCClient.h index cf23731bc8..7c4010f4bd 100644 --- a/Libraries/LibCore/CoreIPCClient.h +++ b/Libraries/LibCore/CoreIPCClient.h @@ -167,6 +167,18 @@ namespace Client { return response; } + template + typename RequestType::ResponseType send_sync(Args&&... args) + { + bool success = post_message_to_server(RequestType(forward(args)...)); + ASSERT(success); + + ServerMessage response; + success = wait_for_specific_event(RequestType::ResponseType::message_type(), response); + ASSERT(success); + return response; + } + protected: struct IncomingMessageBundle { ServerMessage message; diff --git a/Servers/AudioServer/ASClientConnection.cpp b/Servers/AudioServer/ASClientConnection.cpp index 94d30e00d2..bebf2c3927 100644 --- a/Servers/AudioServer/ASClientConnection.cpp +++ b/Servers/AudioServer/ASClientConnection.cpp @@ -25,11 +25,7 @@ ASClientConnection::~ASClientConnection() void ASClientConnection::send_greeting() { - ASAPI_ServerMessage message; - message.type = ASAPI_ServerMessage::Type::Greeting; - message.greeting.server_pid = getpid(); - message.greeting.your_client_id = client_id(); - post_message(message); + post_message(ASAPI_Server::Greeting(getpid(), client_id())); } bool ASClientConnection::handle_message(const ASAPI_ClientMessage& message, const ByteBuffer&&) @@ -53,25 +49,20 @@ bool ASClientConnection::handle_message(const ASAPI_ClientMessage& message, cons m_queue = m_mixer.create_queue(*this); if (m_queue->is_full()) { - reply.success = false; - } else { - m_queue->enqueue(ABuffer::create_with_shared_buffer(*shared_buffer)); + post_message(ASAPI_Server::EnqueueBufferResponse(false, message.play_buffer.buffer_id)); + break; } - post_message(reply); + m_queue->enqueue(ABuffer::create_with_shared_buffer(*shared_buffer)); + post_message(ASAPI_Server::EnqueueBufferResponse(true, message.play_buffer.buffer_id)); break; } case ASAPI_ClientMessage::Type::GetMainMixVolume: { - ASAPI_ServerMessage reply; - reply.type = ASAPI_ServerMessage::Type::DidGetMainMixVolume; - reply.value = m_mixer.main_volume(); - post_message(reply); + post_message(ASAPI_Server::DidGetMainMixVolume(m_mixer.main_volume())); break; } case ASAPI_ClientMessage::Type::SetMainMixVolume: { - ASAPI_ServerMessage reply; - reply.type = ASAPI_ServerMessage::Type::DidSetMainMixVolume; m_mixer.set_main_volume(message.value); - post_message(reply); + post_message(ASAPI_Server::DidSetMainMixVolume()); break; } case ASAPI_ClientMessage::Type::Invalid: @@ -85,8 +76,5 @@ bool ASClientConnection::handle_message(const ASAPI_ClientMessage& message, cons void ASClientConnection::did_finish_playing_buffer(Badge, int buffer_id) { - ASAPI_ServerMessage reply; - reply.type = ASAPI_ServerMessage::Type::FinishedPlayingBuffer; - reply.playing_buffer.buffer_id = buffer_id; - post_message(reply); + post_message(ASAPI_Server::FinishedPlayingBuffer(buffer_id)); }