/*** 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(message->Read()); this->cookie = message->Read(); } inline void PrepareMessage() { message->Write(0); message->Write(this->cookie); } inline void WriteError() { message->Write(AuStaticCast(this->error)); message->Write(this->cookie); } }; struct AuRPCResponseOwned : AuRPCResponse { AuSPtr buffer; inline void PrepareResponse(AuUInt8 type) { buffer = AuMakeShared(); SysAssert(buffer); this->message = buffer.get(); buffer->Write(0); buffer->Write(type); } inline void FinalizeWrite() { auto length = buffer->writePtr - buffer->base; buffer->writePtr = buffer->base; buffer->Write(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, pClient, AuByteBuffer &, refReadOnly)), AUI_METHOD(void, OnConnect, (AuSPtr, pClient)), AUI_METHOD(void, OnDisconnect, (AuSPtr, 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 &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 response) = 0; virtual bool IsConnected() = 0; virtual void SetCallbacks(const AuSPtr &callbacks) = 0; }; struct AuIRPCService { virtual AuUInt32 GetId() = 0; virtual void Dispatch(const AuSPtr &pResponse, AuUInt32 id, AuByteBuffer &buffer, AuSharedFuture &refFuture) = 0; }; struct AuIRPCServer : AuIPC::IExportableIPC { virtual bool RegisterService(const AuSPtr &service) = 0; virtual void BroadcastMessage(const AuMemoryViewRead &view) = 0; virtual AuList> GetClients() = 0; virtual void SetCallbacks(const AuSPtr &pCallbacks) = 0; }; struct AuIRPC { virtual bool StartClient(AuAsync::WorkerPId_t worker) = 0; virtual bool StartServer(AuAsync::WorkerPId_t worker) = 0; virtual AuSPtr ToServer() = 0; virtual AuSPtr Connect(const AuString& str) = 0; virtual void SetRecommendedPipeLength(AuUInt32 uLength) = 0; }; AuSPtr AuRPCNewRequest(AuUInt32 serviceId, AuUInt32 methodId); AuSPtr AuRPCNewInstance();