AuroraRPC/Include/AuRPCAPI.hpp

185 lines
4.5 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuRPCAPI.hpp
Date: 2022-6-29
Author: Reece
***/
#pragma once
struct AuRPCRequest;
struct AuIRPCSession;
AUE_DEFINE(ERPCRequestState, (
ePending,
eSubmitting,
eSent,
eResponse,
eFailed
));
AUE_DEFINE(ERPCError, (
eNone,
eMissingService,
eMissingMethod,
eProtocolError,
eIOError,
eChannelTerminated,
eChannelFailure,
eAborted
));
struct AuRPCResponse
{
inline virtual ~AuRPCResponse()
{
}
inline AuRPCResponse() : error(ERPCError::eNone)
{
}
inline AuRPCResponse(ERPCError error) : error(error)
{
}
inline AuByteBuffer *GetBuffer()
{
return this->message;
}
inline ERPCError GetError()
{
return this->error;
}
inline void SetError(ERPCError error)
{
this->error = error;
}
private:
friend struct AuRPCResponseOwned;
friend struct AuRPCServerChannel;
friend struct AuRPCClientChannel;
friend struct AuRPCPipe;
friend struct AuRPCServer;
ERPCError error;
AuUInt64 cookie {};
AuByteBuffer *message {};
inline void Deserialize()
{
this->error = AuStaticCast<ERPCError>(message->Read<AuUInt8>());
this->cookie = message->Read<AuUInt64>();
}
inline void PrepareMessage()
{
message->Write<AuUInt8>(0);
message->Write<AuUInt64>(this->cookie);
}
inline void WriteError()
{
message->Write<AuUInt8>(AuStaticCast<AuUInt8>(this->error));
message->Write<AuUInt64>(this->cookie);
}
};
struct AuRPCResponseOwned : AuRPCResponse
{
AuSPtr<AuByteBuffer> buffer;
inline void PrepareResponse(AuUInt8 type)
{
buffer = AuMakeShared<AuByteBuffer>();
SysAssert(buffer);
this->message = buffer.get();
buffer->Write<AuUInt32>(0);
buffer->Write(type);
}
inline void FinalizeWrite()
{
auto length = buffer->writePtr - buffer->base;
buffer->writePtr = buffer->base;
buffer->Write<AuUInt32>(length);
buffer->writePtr += (length - 4);
}
};
AUI_INTERFACE(AuRPCRequestCallback,
AUI_METHOD(void, OnResponse, (const AuRPCResponse &, response))
);
AUI_INTERFACE(AuIRPCChannelCallbacks,
AUI_METHOD(void, OnConnect, ()),
AUI_METHOD(void, OnDisconnect, ()),
AUI_METHOD(void, OnBroadcast, (AuByteBuffer &, refReadOnly)),
AUI_METHOD(void, OnMessage, (AuByteBuffer &, refReadOnly))
);
AUI_INTERFACE(AuIRPCServerCallbacks,
AUI_METHOD(void, OnMessage, (AuSPtr<AuIRPCSession>, pClient,
AuByteBuffer &, refReadOnly)),
AUI_METHOD(void, OnConnect, (AuSPtr<AuIRPCSession>, pClient)),
AUI_METHOD(void, OnDisconnect, (AuSPtr<AuIRPCSession>, pClient))
);
struct AuIRPCRequest
{
virtual bool SetData(const AuByteBuffer &toRead) = 0;
virtual bool SetData(const AuMemoryViewRead &view) = 0;
virtual bool EmptyRequest() = 0;
virtual void SetCallback(const AuSPtr<AuRPCRequestCallback> &callback) = 0;
};
struct AuIRPCSession
{
virtual AuUInt64 GetConnectTimeNS() = 0;
virtual void SendMessage(const AuMemoryViewRead &view) = 0;
};
struct AuIRPCClientChannel :
AuIRPCSession
{
virtual void Disconnect() = 0;
virtual void SendRequest(AuSPtr<AuIRPCRequest> response) = 0;
virtual bool IsConnected() = 0;
virtual void SetCallbacks(const AuSPtr<AuIRPCChannelCallbacks> &callbacks) = 0;
};
struct AuIRPCService
{
virtual AuUInt32 GetId() = 0;
virtual void Dispatch(const AuSPtr<AuRPCResponse> &pResponse,
AuUInt32 id,
AuByteBuffer &buffer,
AuSharedFuture<void> &refFuture) = 0;
};
struct AuIRPCServer :
AuIPC::IExportableIPC
{
virtual bool RegisterService(const AuSPtr<AuIRPCService> &service) = 0;
virtual void BroadcastMessage(const AuMemoryViewRead &view) = 0;
virtual AuList<AuSPtr<AuIRPCSession>> GetClients() = 0;
virtual void SetCallbacks(const AuSPtr<AuIRPCServerCallbacks> &pCallbacks) = 0;
};
struct AuIRPC
{
virtual bool StartClient(AuAsync::WorkerPId_t worker) = 0;
virtual bool StartServer(AuAsync::WorkerPId_t worker) = 0;
virtual AuSPtr<AuIRPCServer> ToServer() = 0;
virtual AuSPtr<AuIRPCClientChannel> Connect(const AuString& str) = 0;
virtual void SetRecommendedPipeLength(AuUInt32 uLength) = 0;
};
AuSPtr<AuIRPCRequest> AuRPCNewRequest(AuUInt32 serviceId, AuUInt32 methodId);
AuSPtr<AuIRPC> AuRPCNewInstance();