mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:47:44 +00:00
Userland: Split IPC endpoints into proxies and stubs
This enables support for automatically generating client methods. With this added the user gets code completion support for all IPC methods which are available on a connection object.
This commit is contained in:
parent
065040872f
commit
78803ce384
20 changed files with 175 additions and 53 deletions
|
@ -20,8 +20,7 @@ namespace LanguageServers {
|
||||||
|
|
||||||
class ClientConnection
|
class ClientConnection
|
||||||
: public IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint>
|
: public IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint>
|
||||||
, public LanguageServerEndpoint {
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
||||||
~ClientConnection() override;
|
~ClientConnection() override;
|
||||||
|
|
|
@ -60,6 +60,25 @@ static String snake_case(String const& identifier)
|
||||||
return builder.to_string();
|
return builder.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_primitive_type(String const& type)
|
||||||
|
{
|
||||||
|
return (type == "u8" || type == "i8" || type == "u16" || type == "i16"
|
||||||
|
|| type == "u32" || type == "i32" || type == "bool" || type == "double"
|
||||||
|
|| type == "float" || type == "int" || type == "unsigned" || type == "unsigned int");
|
||||||
|
}
|
||||||
|
|
||||||
|
String message_name(String const& endpoint, String& message, bool is_response)
|
||||||
|
{
|
||||||
|
StringBuilder builder;
|
||||||
|
builder.append("Messages::");
|
||||||
|
builder.append(endpoint);
|
||||||
|
builder.append("::");
|
||||||
|
builder.append(message);
|
||||||
|
if (is_response)
|
||||||
|
builder.append("Response");
|
||||||
|
return builder.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
|
@ -231,10 +250,11 @@ int main(int argc, char** argv)
|
||||||
#include <LibGfx/Color.h>
|
#include <LibGfx/Color.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
#include <LibGfx/ShareableBitmap.h>
|
#include <LibGfx/ShareableBitmap.h>
|
||||||
|
#include <LibIPC/Connection.h>
|
||||||
#include <LibIPC/Decoder.h>
|
#include <LibIPC/Decoder.h>
|
||||||
#include <LibIPC/Dictionary.h>
|
#include <LibIPC/Dictionary.h>
|
||||||
#include <LibIPC/Encoder.h>
|
#include <LibIPC/Encoder.h>
|
||||||
#include <LibIPC/Endpoint.h>
|
#include <LibIPC/Stub.h>
|
||||||
#include <LibIPC/File.h>
|
#include <LibIPC/File.h>
|
||||||
#include <LibIPC/Message.h>
|
#include <LibIPC/Message.h>
|
||||||
)~~~");
|
)~~~");
|
||||||
|
@ -329,6 +349,9 @@ public:
|
||||||
|
|
||||||
message_generator.append(R"~~~(
|
message_generator.append(R"~~~(
|
||||||
@message.name@(decltype(nullptr)) : m_ipc_message_valid(false) { }
|
@message.name@(decltype(nullptr)) : m_ipc_message_valid(false) { }
|
||||||
|
@message.name@(@message.name@ const&) = default;
|
||||||
|
@message.name@(@message.name@&&) = default;
|
||||||
|
@message.name@& operator=(@message.name@ const&) = default;
|
||||||
@message.constructor@
|
@message.constructor@
|
||||||
virtual ~@message.name@() override {}
|
virtual ~@message.name@() override {}
|
||||||
|
|
||||||
|
@ -452,15 +475,109 @@ private:
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
endpoint_generator.append(R"~~~(
|
endpoint_generator.append(R"~~~(
|
||||||
class @endpoint.name@Endpoint : public IPC::Endpoint {
|
template<typename LocalEndpoint, typename PeerEndpoint>
|
||||||
|
class @endpoint.name@Proxy {
|
||||||
public:
|
public:
|
||||||
@endpoint.name@Endpoint() { }
|
// Used to disambiguate the constructor call.
|
||||||
virtual ~@endpoint.name@Endpoint() override { }
|
struct Tag { };
|
||||||
|
|
||||||
|
@endpoint.name@Proxy(IPC::Connection<LocalEndpoint, PeerEndpoint>& connection, Tag)
|
||||||
|
: m_connection(connection)
|
||||||
|
{ }
|
||||||
|
)~~~");
|
||||||
|
|
||||||
|
for (auto& message : endpoint.messages) {
|
||||||
|
auto message_generator = endpoint_generator.fork();
|
||||||
|
|
||||||
|
auto do_implement_proxy = [&](String const& name, Vector<Parameter> const& parameters, bool is_synchronous) {
|
||||||
|
String return_type = "void";
|
||||||
|
if (is_synchronous && !message.outputs.is_empty())
|
||||||
|
return_type = message_name(endpoint.name, message.name, true);
|
||||||
|
message_generator.set("message.name", message.name);
|
||||||
|
message_generator.set("message.complex_return_type", return_type);
|
||||||
|
message_generator.set("async_prefix_maybe", is_synchronous ? "" : "async_");
|
||||||
|
|
||||||
|
message_generator.set("handler_name", snake_case(name));
|
||||||
|
message_generator.append(R"~~~(
|
||||||
|
@message.complex_return_type@ @async_prefix_maybe@@handler_name@()~~~");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < parameters.size(); ++i) {
|
||||||
|
auto& parameter = parameters[i];
|
||||||
|
auto argument_generator = message_generator.fork();
|
||||||
|
argument_generator.set("argument.type", parameter.type);
|
||||||
|
argument_generator.set("argument.name", parameter.name);
|
||||||
|
argument_generator.append("@argument.type@ @argument.name@");
|
||||||
|
if (i != parameters.size() - 1)
|
||||||
|
argument_generator.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
message_generator.append(") {");
|
||||||
|
|
||||||
|
if (is_synchronous) {
|
||||||
|
if (return_type != "void") {
|
||||||
|
message_generator.append(R"~~~(
|
||||||
|
return move(*)~~~");
|
||||||
|
} else{
|
||||||
|
message_generator.append(R"~~~(
|
||||||
|
)~~~");
|
||||||
|
}
|
||||||
|
|
||||||
|
message_generator.append("m_connection.template send_sync<Messages::@endpoint.name@::@message.name@>(");
|
||||||
|
} else {
|
||||||
|
message_generator.append(R"~~~(
|
||||||
|
m_connection.post_message(Messages::@endpoint.name@::@message.name@ { )~~~");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < parameters.size(); ++i) {
|
||||||
|
auto& parameter = parameters[i];
|
||||||
|
auto argument_generator = message_generator.fork();
|
||||||
|
argument_generator.set("argument.name", parameter.name);
|
||||||
|
if (is_primitive_type(parameters[i].type))
|
||||||
|
argument_generator.append("@argument.name@");
|
||||||
|
else
|
||||||
|
argument_generator.append("move(@argument.name@)");
|
||||||
|
if (i != parameters.size() - 1)
|
||||||
|
argument_generator.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_synchronous) {
|
||||||
|
if (return_type != "void") {
|
||||||
|
message_generator.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
message_generator.append(R"~~~();
|
||||||
|
}
|
||||||
|
)~~~");
|
||||||
|
} else {
|
||||||
|
message_generator.append(R"~~~( });
|
||||||
|
}
|
||||||
|
)~~~");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
do_implement_proxy(message.name, message.inputs, message.is_synchronous);
|
||||||
|
if (message.is_synchronous)
|
||||||
|
do_implement_proxy(message.name, message.inputs, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint_generator.append(R"~~~(
|
||||||
|
private:
|
||||||
|
IPC::Connection<LocalEndpoint, PeerEndpoint>& m_connection;
|
||||||
|
};
|
||||||
|
)~~~");
|
||||||
|
|
||||||
|
endpoint_generator.append(R"~~~(
|
||||||
|
template<typename LocalEndpoint, typename PeerEndpoint>
|
||||||
|
class @endpoint.name@Proxy;
|
||||||
|
class @endpoint.name@Stub;
|
||||||
|
|
||||||
|
class @endpoint.name@Endpoint {
|
||||||
|
public:
|
||||||
|
template<typename LocalEndpoint>
|
||||||
|
using Proxy = @endpoint.name@Proxy<LocalEndpoint, @endpoint.name@Endpoint>;
|
||||||
|
using Stub = @endpoint.name@Stub;
|
||||||
|
|
||||||
static u32 static_magic() { return @endpoint.magic@; }
|
static u32 static_magic() { return @endpoint.magic@; }
|
||||||
virtual u32 magic() const override { return @endpoint.magic@; }
|
|
||||||
static String static_name() { return "@endpoint.name@"; }
|
|
||||||
virtual String name() const override { return "@endpoint.name@"; }
|
|
||||||
|
|
||||||
static OwnPtr<IPC::Message> decode_message(ReadonlyBytes buffer, int sockfd)
|
static OwnPtr<IPC::Message> decode_message(ReadonlyBytes buffer, int sockfd)
|
||||||
{
|
{
|
||||||
|
@ -550,6 +667,16 @@ public:
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class @endpoint.name@Stub : public IPC::Stub {
|
||||||
|
public:
|
||||||
|
@endpoint.name@Stub() { }
|
||||||
|
virtual ~@endpoint.name@Stub() override { }
|
||||||
|
|
||||||
|
virtual u32 magic() const override { return @endpoint.magic@; }
|
||||||
|
virtual String name() const override { return "@endpoint.name@"; }
|
||||||
|
|
||||||
virtual OwnPtr<IPC::MessageBuffer> handle(const IPC::Message& message) override
|
virtual OwnPtr<IPC::MessageBuffer> handle(const IPC::Message& message) override
|
||||||
{
|
{
|
||||||
switch (message.message_id()) {
|
switch (message.message_id()) {
|
||||||
|
@ -619,15 +746,8 @@ public:
|
||||||
|
|
||||||
auto do_handle_message_decl = [&](String const& name, Vector<Parameter> const& parameters, bool is_response) {
|
auto do_handle_message_decl = [&](String const& name, Vector<Parameter> const& parameters, bool is_response) {
|
||||||
String return_type = "void";
|
String return_type = "void";
|
||||||
if (message.is_synchronous && !message.outputs.is_empty() && !is_response) {
|
if (message.is_synchronous && !message.outputs.is_empty() && !is_response)
|
||||||
StringBuilder builder;
|
return_type = message_name(endpoint.name, message.name, true);
|
||||||
builder.append("Messages::");
|
|
||||||
builder.append(endpoint.name);
|
|
||||||
builder.append("::");
|
|
||||||
builder.append(message.name);
|
|
||||||
builder.append("Response");
|
|
||||||
return_type = builder.to_string();
|
|
||||||
}
|
|
||||||
message_generator.set("message.complex_return_type", return_type);
|
message_generator.set("message.complex_return_type", return_type);
|
||||||
|
|
||||||
message_generator.set("handler_name", snake_case(name));
|
message_generator.set("handler_name", snake_case(name));
|
||||||
|
@ -637,11 +757,7 @@ public:
|
||||||
auto make_argument_type = [](String const& type) {
|
auto make_argument_type = [](String const& type) {
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
|
||||||
bool const_ref = true;
|
bool const_ref = !is_primitive_type(type);
|
||||||
if (type == "u8" || type == "i8" || type == "u16" || type == "i16"
|
|
||||||
|| type == "u32" || type == "i32" || type == "bool" || type == "double"
|
|
||||||
|| type == "float" || type == "int" || type == "unsigned" || type == "unsigned int")
|
|
||||||
const_ref = false;
|
|
||||||
|
|
||||||
builder.append(type);
|
builder.append(type);
|
||||||
if (const_ref)
|
if (const_ref)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
Decoder.cpp
|
Decoder.cpp
|
||||||
Encoder.cpp
|
Encoder.cpp
|
||||||
Endpoint.cpp
|
|
||||||
Message.cpp
|
Message.cpp
|
||||||
|
Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
serenity_lib(LibIPC ipc)
|
serenity_lib(LibIPC ipc)
|
||||||
|
|
|
@ -17,10 +17,13 @@ NonnullRefPtr<T> new_client_connection(Args&&... args)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ClientEndpoint, typename ServerEndpoint>
|
template<typename ClientEndpoint, typename ServerEndpoint>
|
||||||
class ClientConnection : public Connection<ServerEndpoint, ClientEndpoint> {
|
class ClientConnection : public Connection<ServerEndpoint, ClientEndpoint>, public ServerEndpoint::Stub {
|
||||||
public:
|
public:
|
||||||
ClientConnection(ServerEndpoint& endpoint, NonnullRefPtr<Core::LocalSocket> socket, int client_id)
|
using ClientProxy = typename ClientEndpoint::Proxy;
|
||||||
: IPC::Connection<ServerEndpoint, ClientEndpoint>(endpoint, move(socket))
|
using ServerStub = typename ServerEndpoint::Stub;
|
||||||
|
|
||||||
|
ClientConnection(ServerStub& stub, NonnullRefPtr<Core::LocalSocket> socket, int client_id)
|
||||||
|
: IPC::Connection<ServerEndpoint, ClientEndpoint>(stub, move(socket))
|
||||||
, m_client_id(client_id)
|
, m_client_id(client_id)
|
||||||
{
|
{
|
||||||
VERIFY(this->socket().is_connected());
|
VERIFY(this->socket().is_connected());
|
||||||
|
|
|
@ -28,8 +28,11 @@ namespace IPC {
|
||||||
template<typename LocalEndpoint, typename PeerEndpoint>
|
template<typename LocalEndpoint, typename PeerEndpoint>
|
||||||
class Connection : public Core::Object {
|
class Connection : public Core::Object {
|
||||||
public:
|
public:
|
||||||
Connection(LocalEndpoint& local_endpoint, NonnullRefPtr<Core::LocalSocket> socket)
|
using LocalStub = typename LocalEndpoint::Stub;
|
||||||
: m_local_endpoint(local_endpoint)
|
using PeerProxy = typename PeerEndpoint::Proxy;
|
||||||
|
|
||||||
|
Connection(LocalStub& local_stub, NonnullRefPtr<Core::LocalSocket> socket)
|
||||||
|
: m_local_stub(local_stub)
|
||||||
, m_socket(move(socket))
|
, m_socket(move(socket))
|
||||||
, m_notifier(Core::Notifier::construct(m_socket->fd(), Core::Notifier::Read, this))
|
, m_notifier(Core::Notifier::construct(m_socket->fd(), Core::Notifier::Read, this))
|
||||||
{
|
{
|
||||||
|
@ -248,13 +251,13 @@ protected:
|
||||||
auto messages = move(m_unprocessed_messages);
|
auto messages = move(m_unprocessed_messages);
|
||||||
for (auto& message : messages) {
|
for (auto& message : messages) {
|
||||||
if (message.endpoint_magic() == LocalEndpoint::static_magic())
|
if (message.endpoint_magic() == LocalEndpoint::static_magic())
|
||||||
if (auto response = m_local_endpoint.handle(message))
|
if (auto response = m_local_stub.handle(message))
|
||||||
post_message(*response);
|
post_message(*response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LocalEndpoint& m_local_endpoint;
|
LocalStub& m_local_stub;
|
||||||
NonnullRefPtr<Core::LocalSocket> m_socket;
|
NonnullRefPtr<Core::LocalSocket> m_socket;
|
||||||
RefPtr<Core::Timer> m_responsiveness_timer;
|
RefPtr<Core::Timer> m_responsiveness_timer;
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,12 @@
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
template<typename ClientEndpoint, typename ServerEndpoint>
|
template<typename ClientEndpoint, typename ServerEndpoint>
|
||||||
class ServerConnection : public IPC::Connection<ClientEndpoint, ServerEndpoint> {
|
class ServerConnection : public IPC::Connection<ClientEndpoint, ServerEndpoint>, public ClientEndpoint::Stub {
|
||||||
public:
|
public:
|
||||||
ServerConnection(ClientEndpoint& local_endpoint, const StringView& address)
|
using ClientStub = typename ClientEndpoint::Stub;
|
||||||
|
using ServerProxy = typename ServerEndpoint::Proxy;
|
||||||
|
|
||||||
|
ServerConnection(ClientStub& local_endpoint, const StringView& address)
|
||||||
: Connection<ClientEndpoint, ServerEndpoint>(local_endpoint, Core::LocalSocket::construct())
|
: Connection<ClientEndpoint, ServerEndpoint>(local_endpoint, Core::LocalSocket::construct())
|
||||||
{
|
{
|
||||||
// We want to rate-limit our clients
|
// We want to rate-limit our clients
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibIPC/Endpoint.h>
|
#include <LibIPC/Stub.h>
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
Endpoint::Endpoint()
|
Stub::Stub()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Endpoint::~Endpoint()
|
Stub::~Stub()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,16 @@ namespace IPC {
|
||||||
class Message;
|
class Message;
|
||||||
class MessageBuffer;
|
class MessageBuffer;
|
||||||
|
|
||||||
class Endpoint {
|
class Stub {
|
||||||
public:
|
public:
|
||||||
virtual ~Endpoint();
|
virtual ~Stub();
|
||||||
|
|
||||||
virtual u32 magic() const = 0;
|
virtual u32 magic() const = 0;
|
||||||
virtual String name() const = 0;
|
virtual String name() const = 0;
|
||||||
virtual OwnPtr<MessageBuffer> handle(const Message&) = 0;
|
virtual OwnPtr<MessageBuffer> handle(const Message&) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Endpoint();
|
Stub();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_name;
|
String m_name;
|
|
@ -21,7 +21,7 @@ class BufferQueue;
|
||||||
class Mixer;
|
class Mixer;
|
||||||
|
|
||||||
class ClientConnection final : public IPC::ClientConnection<AudioClientEndpoint, AudioServerEndpoint>
|
class ClientConnection final : public IPC::ClientConnection<AudioClientEndpoint, AudioServerEndpoint>
|
||||||
, public AudioServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection)
|
C_OBJECT(ClientConnection)
|
||||||
public:
|
public:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id, Mixer& mixer);
|
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id, Mixer& mixer);
|
||||||
|
|
|
@ -15,8 +15,7 @@ namespace Clipboard {
|
||||||
|
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ClientConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>
|
: public IPC::ClientConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>
|
||||||
, public ClipboardServerEndpoint {
|
{
|
||||||
|
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace ImageDecoder {
|
||||||
|
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ClientConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
|
: public IPC::ClientConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
|
||||||
, public ImageDecoderServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
namespace LaunchServer {
|
namespace LaunchServer {
|
||||||
|
|
||||||
class ClientConnection final : public IPC::ClientConnection<LaunchClientEndpoint, LaunchServerEndpoint>
|
class ClientConnection final : public IPC::ClientConnection<LaunchClientEndpoint, LaunchServerEndpoint>
|
||||||
, public LaunchServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection)
|
C_OBJECT(ClientConnection)
|
||||||
public:
|
public:
|
||||||
~ClientConnection() override;
|
~ClientConnection() override;
|
||||||
|
|
|
@ -15,8 +15,7 @@ namespace LookupServer {
|
||||||
|
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ClientConnection<LookupClientEndpoint, LookupServerEndpoint>
|
: public IPC::ClientConnection<LookupClientEndpoint, LookupServerEndpoint>
|
||||||
, public LookupServerEndpoint {
|
{
|
||||||
|
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
namespace NotificationServer {
|
namespace NotificationServer {
|
||||||
|
|
||||||
class ClientConnection final : public IPC::ClientConnection<NotificationClientEndpoint, NotificationServerEndpoint>
|
class ClientConnection final : public IPC::ClientConnection<NotificationClientEndpoint, NotificationServerEndpoint>
|
||||||
, public NotificationServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection)
|
C_OBJECT(ClientConnection)
|
||||||
public:
|
public:
|
||||||
~ClientConnection() override;
|
~ClientConnection() override;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace RequestServer {
|
||||||
|
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>
|
: public IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>
|
||||||
, public RequestServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace SymbolServer {
|
||||||
|
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ClientConnection<SymbolClientEndpoint, SymbolServerEndpoint>
|
: public IPC::ClientConnection<SymbolClientEndpoint, SymbolServerEndpoint>
|
||||||
, public SymbolServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace WebContent {
|
||||||
|
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ClientConnection<WebContentClientEndpoint, WebContentServerEndpoint>
|
: public IPC::ClientConnection<WebContentClientEndpoint, WebContentServerEndpoint>
|
||||||
, public WebContentServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace WebSocket {
|
||||||
|
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ClientConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>
|
: public IPC::ClientConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>
|
||||||
, public WebSocketServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -29,7 +29,7 @@ class WMClientConnection;
|
||||||
|
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ClientConnection<WindowClientEndpoint, WindowServerEndpoint>
|
: public IPC::ClientConnection<WindowClientEndpoint, WindowServerEndpoint>
|
||||||
, public WindowServerEndpoint {
|
{
|
||||||
C_OBJECT(ClientConnection)
|
C_OBJECT(ClientConnection)
|
||||||
public:
|
public:
|
||||||
~ClientConnection() override;
|
~ClientConnection() override;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace WindowServer {
|
||||||
|
|
||||||
class WMClientConnection final
|
class WMClientConnection final
|
||||||
: public IPC::ClientConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>
|
: public IPC::ClientConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>
|
||||||
, public WindowManagerServerEndpoint {
|
{
|
||||||
C_OBJECT(WMClientConnection)
|
C_OBJECT(WMClientConnection)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue