mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-08-17 09:21:41 +08:00
Update release package imports
This commit is contained in:
+32
-14
@@ -39010,10 +39010,9 @@ GuiRemoteProtocolJsonChannelRenderer_Async
|
||||
#undef ERROR_MESSAGE_PREFIX
|
||||
}
|
||||
|
||||
void GuiRemoteProtocolJsonChannelRenderer_Async::SendToClient(vint senderClientId, vint receiverClientId, const JsonPackage& package)
|
||||
void GuiRemoteProtocolJsonChannelRenderer_Async::SendToClient(vint receiverClientId, const JsonPackage& package)
|
||||
{
|
||||
QueuedPackage queuedPackage;
|
||||
queuedPackage.senderClientId = senderClientId;
|
||||
queuedPackage.receiverClientId = receiverClientId;
|
||||
queuedPackage.package = package;
|
||||
|
||||
@@ -39023,11 +39022,18 @@ GuiRemoteProtocolJsonChannelRenderer_Async
|
||||
}
|
||||
}
|
||||
|
||||
void GuiRemoteProtocolJsonChannelRenderer_Async::BroadcastFromClient(vint senderClientId, const JsonPackage& package)
|
||||
void GuiRemoteProtocolJsonChannelRenderer_Async::BroadcastFromClient(const JsonPackage& package)
|
||||
{
|
||||
List<vint> blockedReceivers;
|
||||
BroadcastFromClient(package, blockedReceivers);
|
||||
}
|
||||
|
||||
void GuiRemoteProtocolJsonChannelRenderer_Async::BroadcastFromClient(const JsonPackage& package, const List<vint>& blockedReceivers)
|
||||
{
|
||||
QueuedPackage queuedPackage;
|
||||
queuedPackage.senderClientId = senderClientId;
|
||||
queuedPackage.package = package;
|
||||
queuedPackage.blockedReceivers = Ptr(new List<vint>);
|
||||
CopyFrom(*queuedPackage.blockedReceivers.Obj(), blockedReceivers);
|
||||
|
||||
SPIN_LOCK(lockPendingPackages)
|
||||
{
|
||||
@@ -39086,11 +39092,18 @@ GuiRemoteProtocolJsonChannelRenderer_Async
|
||||
{
|
||||
if (queuedPackage.receiverClientId)
|
||||
{
|
||||
channel->SendToClient(queuedPackage.senderClientId, queuedPackage.receiverClientId.Value(), queuedPackage.package);
|
||||
channel->SendToClient(queuedPackage.receiverClientId.Value(), queuedPackage.package);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->BroadcastFromClient(queuedPackage.senderClientId, queuedPackage.package);
|
||||
if (queuedPackage.blockedReceivers)
|
||||
{
|
||||
channel->BroadcastFromClient(queuedPackage.package, *queuedPackage.blockedReceivers.Obj());
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->BroadcastFromClient(queuedPackage.package);
|
||||
}
|
||||
}
|
||||
}
|
||||
channel->BatchWrite(disconnected);
|
||||
@@ -39279,14 +39292,19 @@ GuiRemoteProtocolAsyncJsonChannelRenderer
|
||||
}
|
||||
}
|
||||
|
||||
void GuiRemoteProtocolAsyncJsonChannelRenderer::SendToClient(vint senderClientId, vint receiverClientId, const JsonPackage& package)
|
||||
void GuiRemoteProtocolAsyncJsonChannelRenderer::SendToClient(vint receiverClientId, const JsonPackage& package)
|
||||
{
|
||||
channel->SendToClient(senderClientId, receiverClientId, package);
|
||||
channel->SendToClient(receiverClientId, package);
|
||||
}
|
||||
|
||||
void GuiRemoteProtocolAsyncJsonChannelRenderer::BroadcastFromClient(vint senderClientId, const JsonPackage& package)
|
||||
void GuiRemoteProtocolAsyncJsonChannelRenderer::BroadcastFromClient(const JsonPackage& package)
|
||||
{
|
||||
channel->BroadcastFromClient(senderClientId, package);
|
||||
channel->BroadcastFromClient(package);
|
||||
}
|
||||
|
||||
void GuiRemoteProtocolAsyncJsonChannelRenderer::BroadcastFromClient(const JsonPackage& package, const List<vint>& blockedReceivers)
|
||||
{
|
||||
channel->BroadcastFromClient(package, blockedReceivers);
|
||||
}
|
||||
|
||||
void GuiRemoteProtocolAsyncJsonChannelRenderer::BatchWrite(bool& disconnected)
|
||||
@@ -39553,9 +39571,9 @@ GuiRemoteProtocolCoreChannel
|
||||
|
||||
for (auto&& pendingPackage : packages)
|
||||
{
|
||||
channel->SendToClient(client->GetClientId(), receiverClientId, pendingPackage);
|
||||
channel->SendToClient(receiverClientId, pendingPackage);
|
||||
}
|
||||
channel->SendToClient(client->GetClientId(), receiverClientId, package);
|
||||
channel->SendToClient(receiverClientId, package);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39733,7 +39751,7 @@ GuiRemoteProtocolCoreChannel
|
||||
|
||||
for (auto&& package : packages)
|
||||
{
|
||||
channel->SendToClient(client->GetClientId(), receiverClientId, package);
|
||||
channel->SendToClient(receiverClientId, package);
|
||||
}
|
||||
channel->BatchWrite(disconnected);
|
||||
}
|
||||
@@ -39836,7 +39854,7 @@ GuiRemoteProtocolRendererChannel
|
||||
|
||||
void GuiRemoteProtocolRendererChannel::Write(Ptr<glr::json::JsonObject> package)
|
||||
{
|
||||
channel->SendToClient(client->GetClientId(), GacUIRemoteProtocolCoreClientId, package);
|
||||
channel->SendToClient(GacUIRemoteProtocolCoreClientId, package);
|
||||
|
||||
if (!receiving)
|
||||
{
|
||||
|
||||
+41
-6
@@ -22822,6 +22822,7 @@ namespace vl::presentation::remoteprotocol::channeling
|
||||
using IJsonChannel = inter_process::IChannel<JsonPackage>;
|
||||
using IJsonChannelClient = inter_process::IChannelClient<JsonPackage>;
|
||||
using IJsonChannelServer = inter_process::IChannelServer<JsonPackage>;
|
||||
using IJsonLocalChannelServer = inter_process::INetworkProtocolLocalChannelServer<JsonPackage, glr::json::JsonNodeListSerializer>;
|
||||
|
||||
/***********************************************************************
|
||||
ChannelPackageSemantic
|
||||
@@ -22847,7 +22848,39 @@ ChannelPackageSemantic
|
||||
extern void JsonChannelUnpack(Ptr<glr::json::JsonObject> package, ChannelPackageInfo& info, Ptr<glr::json::JsonNode>& arguments);
|
||||
extern void JsonChannelUnpack(Ptr<glr::json::JsonNode> package, ChannelPackageInfo& info, Ptr<glr::json::JsonNode>& arguments);
|
||||
|
||||
using GuiRemoteProtocolChannelServer = inter_process::NetworkProtocolChannelServer<JsonPackage, glr::json::JsonNodeListSerializer>;
|
||||
class GuiRemoteProtocolLocalChannelServerBase
|
||||
: public Object
|
||||
, public virtual inter_process::INetworkProtocolServer
|
||||
{
|
||||
private:
|
||||
bool stopped = true;
|
||||
|
||||
public:
|
||||
inter_process::WaitForClientResult OnClientConnected(inter_process::INetworkProtocolConnection* connection) override
|
||||
{
|
||||
return inter_process::WaitForClientResult::Reject;
|
||||
}
|
||||
|
||||
void Start() override
|
||||
{
|
||||
stopped = false;
|
||||
}
|
||||
|
||||
void Stop() override
|
||||
{
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
bool IsStopped() override
|
||||
{
|
||||
return stopped;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TServerBase>
|
||||
using GuiRemoteProtocolNetworkChannelServer = inter_process::NetworkProtocolChannelServer<JsonPackage, glr::json::JsonNodeListSerializer, TServerBase>;
|
||||
|
||||
using GuiRemoteProtocolChannelServer = GuiRemoteProtocolNetworkChannelServer<GuiRemoteProtocolLocalChannelServerBase>;
|
||||
|
||||
class GuiRemoteProtocolChannelClient
|
||||
: public inter_process::NetworkProtocolChannelClient<JsonPackage, glr::json::JsonNodeListSerializer>
|
||||
@@ -23052,8 +23085,8 @@ GuiRemoteProtocolJsonChannelRenderer_Async
|
||||
protected:
|
||||
struct QueuedPackage
|
||||
{
|
||||
vint senderClientId = -1;
|
||||
Nullable<vint> receiverClientId;
|
||||
Ptr<collections::List<vint>> blockedReceivers;
|
||||
JsonPackage package;
|
||||
};
|
||||
|
||||
@@ -23104,8 +23137,9 @@ GuiRemoteProtocolJsonChannelRenderer_Async
|
||||
const WString& GetChannelName() override;
|
||||
IJsonChannelReader* GetReader() override;
|
||||
void Initialize(IJsonChannelReader* _reader) override;
|
||||
void SendToClient(vint senderClientId, vint receiverClientId, const JsonPackage& package) override;
|
||||
void BroadcastFromClient(vint senderClientId, const JsonPackage& package) override;
|
||||
void SendToClient(vint receiverClientId, const JsonPackage& package) override;
|
||||
void BroadcastFromClient(const JsonPackage& package) override;
|
||||
void BroadcastFromClient(const JsonPackage& package, const collections::List<vint>& blockedReceivers) override;
|
||||
void BatchWrite(bool& disconnected) override;
|
||||
|
||||
IGuiRemoteEventProcessor* GetRemoteEventProcessor();
|
||||
@@ -23185,8 +23219,9 @@ GuiRemoteProtocolAsyncJsonChannelRenderer
|
||||
const WString& GetChannelName() override;
|
||||
IJsonChannelReader* GetReader() override;
|
||||
void Initialize(IJsonChannelReader* _reader) override;
|
||||
void SendToClient(vint senderClientId, vint receiverClientId, const JsonPackage& package) override;
|
||||
void BroadcastFromClient(vint senderClientId, const JsonPackage& package) override;
|
||||
void SendToClient(vint receiverClientId, const JsonPackage& package) override;
|
||||
void BroadcastFromClient(const JsonPackage& package) override;
|
||||
void BroadcastFromClient(const JsonPackage& package, const collections::List<vint>& blockedReceivers) override;
|
||||
void BatchWrite(bool& disconnected) override;
|
||||
|
||||
void SetInvokeInMainThread(IGuiRemoteProtocolAsyncRendererInvoker* _invokeInMainThread);
|
||||
|
||||
+19
-3
@@ -34,11 +34,27 @@ Console
|
||||
std::wcout << s << std::flush;
|
||||
}
|
||||
|
||||
WString Console::Read()
|
||||
Nullable<WString> Console::TryRead()
|
||||
{
|
||||
std::wstring s;
|
||||
std::getline(std::wcin, s, L'\n');
|
||||
return s.c_str();
|
||||
if (!std::getline(std::wcin, s, L'\n'))
|
||||
{
|
||||
if (s.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (!s.empty() && s[s.size() - 1] == L'\r')
|
||||
{
|
||||
s.pop_back();
|
||||
}
|
||||
return WString::CopyFrom(s.c_str(), (vint)s.size());
|
||||
}
|
||||
|
||||
WString Console::Read()
|
||||
{
|
||||
auto result = TryRead();
|
||||
return result ? result.Value() : WString::Empty;
|
||||
}
|
||||
|
||||
void Console::SetColor(bool red, bool green, bool blue, bool light)
|
||||
|
||||
+85
-21
@@ -48,29 +48,93 @@ Console
|
||||
}
|
||||
}
|
||||
|
||||
Nullable<WString> Console::TryRead()
|
||||
{
|
||||
auto inHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (inHandle == INVALID_HANDLE_VALUE || inHandle == NULL)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
WString result;
|
||||
DWORD fileMode = 0;
|
||||
if ((GetFileType(inHandle) & FILE_TYPE_CHAR) && GetConsoleMode(inHandle, &fileMode))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
wchar_t buffer = 0;
|
||||
DWORD count = 0;
|
||||
if (!ReadConsole(inHandle, &buffer, 1, &count, 0) || count == 0)
|
||||
{
|
||||
return result.Length() == 0 ? Nullable<WString>() : Nullable<WString>(result);
|
||||
}
|
||||
|
||||
if (buffer == L'\r')
|
||||
{
|
||||
if (!ReadConsole(inHandle, &buffer, 1, &count, 0) || count == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (buffer == L'\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result + WString::FromChar(buffer);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
AString buffer;
|
||||
for (;;)
|
||||
{
|
||||
char c = 0;
|
||||
DWORD count = 0;
|
||||
if (!ReadFile(inHandle, &c, 1, &count, 0) || count == 0)
|
||||
{
|
||||
if (buffer.Length() == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = buffer + AString::FromChar(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Length() > 0 && buffer[buffer.Length() - 1] == '\r')
|
||||
{
|
||||
buffer = buffer.Left(buffer.Length() - 1);
|
||||
}
|
||||
int codePage = GetConsoleCP();
|
||||
if (codePage == 0)
|
||||
{
|
||||
codePage = CP_THREAD_ACP;
|
||||
}
|
||||
auto charCount = MultiByteToWideChar(codePage, 0, buffer.Buffer(), (int)buffer.Length(), nullptr, 0);
|
||||
auto wbuffer = new wchar_t[charCount + 1];
|
||||
MultiByteToWideChar(codePage, 0, buffer.Buffer(), (int)buffer.Length(), wbuffer, charCount);
|
||||
wbuffer[charCount] = 0;
|
||||
return WString::TakeOver(wbuffer, charCount);
|
||||
}
|
||||
}
|
||||
|
||||
WString Console::Read()
|
||||
{
|
||||
WString result;
|
||||
DWORD count;
|
||||
for (;;)
|
||||
{
|
||||
wchar_t buffer;
|
||||
ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &buffer, 1, &count, 0);
|
||||
if (buffer == L'\r')
|
||||
{
|
||||
ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &buffer, 1, &count, 0);
|
||||
break;
|
||||
}
|
||||
else if (buffer == L'\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result + WString::FromChar(buffer);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
auto result = TryRead();
|
||||
return result ? result.Value() : WString::Empty;
|
||||
}
|
||||
|
||||
void Console::SetColor(bool red, bool green, bool blue, bool light)
|
||||
|
||||
+7
-2
@@ -8733,8 +8733,12 @@ namespace vl
|
||||
/// <param name="string">Content to write.</param>
|
||||
static void WriteLine(const WString& string);
|
||||
|
||||
/// <summary>Read a string from the command-line window.</summary>
|
||||
/// <returns>The whole line read from the command-line window.</returns>
|
||||
/// <summary>Try to read a string from the command-line window or redirected input.</summary>
|
||||
/// <returns>The whole line read from the command-line window or redirected input. Returns null if no line is available.</returns>
|
||||
static Nullable<WString> TryRead();
|
||||
|
||||
/// <summary>Read a string from the command-line window or redirected input.</summary>
|
||||
/// <returns>The whole line read from the command-line window or redirected input. Returns an empty string if no line is available.</returns>
|
||||
static WString Read();
|
||||
|
||||
static void SetColor(bool red, bool green, bool blue, bool light);
|
||||
@@ -8745,6 +8749,7 @@ namespace vl
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\EXCEPTION.H
|
||||
***********************************************************************/
|
||||
|
||||
@@ -3807,7 +3807,15 @@ RESTART_LOOP:
|
||||
}
|
||||
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_BROKEN_PIPE || error == ERROR_INVALID_HANDLE)
|
||||
if (error == ERROR_BROKEN_PIPE || error == ERROR_NO_DATA)
|
||||
{
|
||||
if (!stopped)
|
||||
{
|
||||
OnDisconnected();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (error == ERROR_INVALID_HANDLE)
|
||||
{
|
||||
if (!stopped)
|
||||
{
|
||||
@@ -3866,7 +3874,16 @@ RESTART_LOOP:
|
||||
else
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_OPERATION_ABORTED || error == ERROR_INVALID_HANDLE || error == ERROR_BROKEN_PIPE || error == ERROR_NO_DATA)
|
||||
if (error == ERROR_BROKEN_PIPE || error == ERROR_NO_DATA)
|
||||
{
|
||||
if (!self->stopped)
|
||||
{
|
||||
self->OnDisconnected();
|
||||
}
|
||||
finalize();
|
||||
return;
|
||||
}
|
||||
if (error == ERROR_OPERATION_ABORTED || error == ERROR_INVALID_HANDLE)
|
||||
{
|
||||
if (!self->stopped)
|
||||
{
|
||||
@@ -4061,6 +4078,14 @@ void NamedPipeConnection::InstallCallback(INetworkProtocolCallback* _callback)
|
||||
void NamedPipeConnection::Stop()
|
||||
{
|
||||
stopped = 1;
|
||||
SPIN_LOCK(lockWrite)
|
||||
{
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CancelIoEx(hPipe, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ReadWaitContext* context = readWaitContext.exchange(nullptr);
|
||||
if (context)
|
||||
{
|
||||
@@ -4081,7 +4106,6 @@ void NamedPipeConnection::Stop()
|
||||
{
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CancelIoEx(hPipe, NULL);
|
||||
CloseHandle(hPipe);
|
||||
hPipe = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace vl::inter_process
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\HTTPCLIENTAPI.WINDOWS.H
|
||||
***********************************************************************/
|
||||
|
||||
+157
-1
@@ -1297,6 +1297,71 @@ ThreadLocalStorage
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
TaskQueue
|
||||
***********************************************************************/
|
||||
|
||||
TaskQueue::TaskQueue()
|
||||
{
|
||||
CHECK_ERROR(semaphoreTasks.Create(0, 65536), L"vl::TaskQueue::TaskQueue()#Failed to create the task semaphore.");
|
||||
}
|
||||
|
||||
TaskQueue::~TaskQueue()
|
||||
{
|
||||
}
|
||||
|
||||
void TaskQueue::QueueTask(Func<void()> task)
|
||||
{
|
||||
SPIN_LOCK(lockTasks)
|
||||
{
|
||||
tasks.Add(task);
|
||||
}
|
||||
semaphoreTasks.Release();
|
||||
}
|
||||
|
||||
void TaskQueue::QueueExitTask()
|
||||
{
|
||||
SPIN_LOCK(lockTasks)
|
||||
{
|
||||
exitTaskQueued = true;
|
||||
}
|
||||
semaphoreTasks.Release();
|
||||
}
|
||||
|
||||
void TaskQueue::RunTaskQueue()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Func<void()> task;
|
||||
bool hasTask = false;
|
||||
bool shouldExit = false;
|
||||
SPIN_LOCK(lockTasks)
|
||||
{
|
||||
if (tasks.Count() > 0)
|
||||
{
|
||||
task = tasks[0];
|
||||
tasks.RemoveAt(0);
|
||||
hasTask = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldExit = exitTaskQueued;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldExit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!hasTask)
|
||||
{
|
||||
semaphoreTasks.Wait();
|
||||
continue;
|
||||
}
|
||||
task();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2833,13 +2898,104 @@ Unicode General (extern templates)
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\INTERPROCESS\TEXTNETWORKPROTOCOL.CPP
|
||||
.\INTERPROCESS\CHANNELIMPLS\CHANNELPACKAGE.CPP
|
||||
***********************************************************************/
|
||||
|
||||
namespace vl::inter_process
|
||||
{
|
||||
NetworkPackage NetworkPackage::Create(Nullable<vint> _clientId, const WString& _channelName, const WString& _messageBody)
|
||||
{
|
||||
NetworkPackage package;
|
||||
package.clientId = std::move(_clientId);
|
||||
package.channelName = _channelName;
|
||||
package.messageBody = _messageBody;
|
||||
return package;
|
||||
}
|
||||
|
||||
NetworkPackage NetworkPackage::Create(Nullable<vint> _clientId, const ClientIdList& _extraClientIds, const WString& _channelName, const WString& _messageBody)
|
||||
{
|
||||
auto package = Create(std::move(_clientId), _channelName, _messageBody);
|
||||
if (_extraClientIds.Count() > 0)
|
||||
{
|
||||
ClientIdList extraClientIds;
|
||||
for (auto clientId : _extraClientIds)
|
||||
{
|
||||
extraClientIds.Add(clientId);
|
||||
}
|
||||
package.extraClientIds = std::move(extraClientIds);
|
||||
}
|
||||
return package;
|
||||
}
|
||||
|
||||
WString NetworkPackage::ToString(const NetworkPackage& package)
|
||||
{
|
||||
auto clientIds = package.clientId ? itow(package.clientId.Value()) : WString::Empty;
|
||||
if (package.extraClientIds)
|
||||
{
|
||||
for (auto clientId : package.extraClientIds.Value())
|
||||
{
|
||||
clientIds += L",";
|
||||
clientIds += itow(clientId);
|
||||
}
|
||||
}
|
||||
|
||||
return clientIds
|
||||
+ L";" + package.channelName
|
||||
+ L";" + package.messageBody
|
||||
;
|
||||
}
|
||||
|
||||
void NetworkPackage::Parse(const WString& str, NetworkPackage& package)
|
||||
{
|
||||
#define ERROR_MESSAGE_PREFIX L"vl::inter_process::NetworkPackage::Parse(const WString&, NetworkPackage&)#"
|
||||
const wchar_t* reading = str.Buffer();
|
||||
|
||||
const wchar_t* afterClientId = wcschr(reading, L';');
|
||||
CHECK_ERROR(afterClientId != nullptr, ERROR_MESSAGE_PREFIX L"Invalid package format.");
|
||||
package.clientId.Reset();
|
||||
package.extraClientIds.Reset();
|
||||
const wchar_t* firstExtraClientId = wcschr(reading, L',');
|
||||
if (firstExtraClientId && firstExtraClientId > afterClientId)
|
||||
{
|
||||
firstExtraClientId = nullptr;
|
||||
}
|
||||
auto clientIdLength = firstExtraClientId ? (vint)(firstExtraClientId - reading) : (vint)(afterClientId - reading);
|
||||
if (clientIdLength > 0)
|
||||
{
|
||||
package.clientId = wtoi(str.Left(clientIdLength));
|
||||
}
|
||||
|
||||
if (firstExtraClientId)
|
||||
{
|
||||
ClientIdList extraClientIds;
|
||||
auto readingExtraClientId = firstExtraClientId + 1;
|
||||
while (readingExtraClientId < afterClientId)
|
||||
{
|
||||
auto delimiter = wcschr(readingExtraClientId, L',');
|
||||
if (delimiter && delimiter > afterClientId)
|
||||
{
|
||||
delimiter = nullptr;
|
||||
}
|
||||
auto endingExtraClientId = delimiter ? delimiter : afterClientId;
|
||||
CHECK_ERROR(endingExtraClientId > readingExtraClientId, ERROR_MESSAGE_PREFIX L"Invalid extra client id format.");
|
||||
extraClientIds.Add(wtoi(WString::CopyFrom(readingExtraClientId, (vint)(endingExtraClientId - readingExtraClientId))));
|
||||
readingExtraClientId = endingExtraClientId + (delimiter ? 1 : 0);
|
||||
}
|
||||
if (extraClientIds.Count() > 0)
|
||||
{
|
||||
package.extraClientIds = std::move(extraClientIds);
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t* afterChannelName = wcschr(afterClientId + 1, L';');
|
||||
CHECK_ERROR(afterChannelName != nullptr, ERROR_MESSAGE_PREFIX L"Invalid package format.");
|
||||
package.channelName = str.Sub((vint)(afterClientId - reading + 1), (vint)(afterChannelName - afterClientId - 1));
|
||||
package.messageBody = str.Right(str.Length() - (vint)(afterChannelName - reading + 1));
|
||||
#undef ERROR_MESSAGE_PREFIX
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\STREAM\ACCESSOR.CPP
|
||||
***********************************************************************/
|
||||
|
||||
+375
-142
File diff suppressed because it is too large
Load Diff
@@ -10127,6 +10127,15 @@ namespace vl
|
||||
return testing;
|
||||
}
|
||||
|
||||
Ptr<WfExpression> CreateIsType(Ptr<WfExpression> expression, Ptr<WfType> type)
|
||||
{
|
||||
auto testing = Ptr(new WfTypeTestingExpression);
|
||||
testing->test = WfTypeTesting::IsType;
|
||||
testing->expression = expression;
|
||||
testing->type = type;
|
||||
return testing;
|
||||
}
|
||||
|
||||
Ptr<WfExpression> CreateBool(bool value)
|
||||
{
|
||||
auto expression = Ptr(new WfLiteralExpression);
|
||||
@@ -11077,44 +11086,6 @@ namespace vl
|
||||
return functionDecl;
|
||||
}
|
||||
|
||||
Ptr<WfStatement> BuildRegisterService()
|
||||
{
|
||||
auto block = CreateBlock();
|
||||
auto registerBranch = CreateBlock();
|
||||
AddStatement(
|
||||
registerBranch,
|
||||
CreateExpressionStatement(
|
||||
CreateCall(
|
||||
CreateMember(CreateMember(CreateReference(L"_lc"), L"Dispatcher"), L"RegisterService"),
|
||||
CreateReference(L"typeId"),
|
||||
CreateCall(CreateMember(CreateReference(L"_lc"), L"PtrToRef"), CreateReference(L"service"))
|
||||
)
|
||||
)
|
||||
);
|
||||
auto nonCtorBranch = CreateBlock();
|
||||
AddStatement(nonCtorBranch, CreateRaise(L"RPC service type id is not an @rpc:Ctor interface."));
|
||||
auto invalidTypeIdBranch = CreateBlock();
|
||||
AddStatement(invalidTypeIdBranch, CreateRaise(L"RPC service type id does not exist."));
|
||||
auto invalidRegisterBranch = CreateBlock();
|
||||
AddStatement(
|
||||
invalidRegisterBranch,
|
||||
CreateIf(
|
||||
CreateCall(CreateReference(L"rpcwrapper_IsInterfaceTypeId"), CreateReference(L"typeId")),
|
||||
nonCtorBranch,
|
||||
invalidTypeIdBranch
|
||||
)
|
||||
);
|
||||
AddStatement(
|
||||
block,
|
||||
CreateIf(
|
||||
CreateCall(CreateReference(L"rpcwrapper_IsCtorInterfaceTypeId"), CreateReference(L"typeId")),
|
||||
registerBranch,
|
||||
invalidRegisterBranch
|
||||
)
|
||||
);
|
||||
return block;
|
||||
}
|
||||
|
||||
Ptr<WfDeclaration> GenerateObjectOpsFactory(const List<RpcInterfaceModel>& interfaces)
|
||||
{
|
||||
auto functionDecl = CreateFunctionDeclaration(L"rpcops_IRpcObjectOps", CreateTypeFromCpp<Ptr<rpc_controller::IRpcObjectOps>>(), WfFunctionKind::Normal);
|
||||
@@ -11161,15 +11132,6 @@ namespace vl
|
||||
newOps->declarations.Add(objectHold);
|
||||
}
|
||||
|
||||
{
|
||||
auto registerService = CreateFunctionDeclaration(L"RegisterService", CreatePredefinedType(WfPredefinedTypeName::Void), WfFunctionKind::Override);
|
||||
registerService->arguments.Add(CreateFunctionArgument(L"typeId", CreatePredefinedType(WfPredefinedTypeName::Int)));
|
||||
registerService->arguments.Add(CreateFunctionArgument(L"service", CreateTypeFromCpp<Ptr<reflection::IDescriptable>>()));
|
||||
auto block = registerService->statement.Cast<WfBlockStatement>();
|
||||
AddStatement(block, BuildRegisterService());
|
||||
newOps->declarations.Add(registerService);
|
||||
}
|
||||
|
||||
AddStatement(functionDecl->statement.Cast<WfBlockStatement>(), CreateReturn(newOps));
|
||||
return functionDecl;
|
||||
}
|
||||
@@ -11246,6 +11208,42 @@ namespace vl
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SortInterfaceModelsLeafFirst(const List<RpcInterfaceModel>& interfaces, List<const RpcInterfaceModel*>& sortedInterfaces)
|
||||
{
|
||||
sortedInterfaces.Clear();
|
||||
|
||||
List<WString> typeFullNames;
|
||||
Group<WString, WString> dependencyGroup;
|
||||
for (auto&& interfaceModel : interfaces)
|
||||
{
|
||||
typeFullNames.Add(interfaceModel.fullName);
|
||||
}
|
||||
for (auto&& interfaceModel : interfaces)
|
||||
{
|
||||
for (auto&& baseFullName : interfaceModel.baseFullNames)
|
||||
{
|
||||
if (typeFullNames.Contains(baseFullName))
|
||||
{
|
||||
dependencyGroup.Add(baseFullName, interfaceModel.fullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PartialOrderingProcessor pop;
|
||||
pop.InitWithGroup(typeFullNames, dependencyGroup);
|
||||
pop.Sort();
|
||||
|
||||
for (auto&& component : pop.components)
|
||||
{
|
||||
for (vint i = 0; i < component.nodeCount; i++)
|
||||
{
|
||||
auto interfaceModel = FindInterfaceModel(interfaces, typeFullNames[component.firstNode[i]]);
|
||||
CHECK_ERROR(interfaceModel, L"SortInterfaceModelsLeafFirst: Invalid RPC interface name.");
|
||||
sortedInterfaces.Add(interfaceModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ContainsEventModel(const List<const RpcEventModel*>& events, const WString& fullName)
|
||||
{
|
||||
for (auto eventModel : events)
|
||||
@@ -11928,6 +11926,28 @@ namespace vl
|
||||
AddStatement(block, switchStat);
|
||||
return functionDecl;
|
||||
}
|
||||
|
||||
Ptr<WfDeclaration> GenerateWrapperGetTypeId(const List<RpcInterfaceModel>& interfaces)
|
||||
{
|
||||
auto functionDecl = CreateFunctionDeclaration(L"rpcwrapper_GetTypeId", CreatePredefinedType(WfPredefinedTypeName::Int), WfFunctionKind::Normal);
|
||||
functionDecl->arguments.Add(CreateFunctionArgument(L"obj", CreatePredefinedType(WfPredefinedTypeName::Object)));
|
||||
auto block = functionDecl->statement.Cast<WfBlockStatement>();
|
||||
|
||||
List<const RpcInterfaceModel*> sortedInterfaces;
|
||||
SortInterfaceModelsLeafFirst(interfaces, sortedInterfaces);
|
||||
for (auto interfaceModel : sortedInterfaces)
|
||||
{
|
||||
AddStatement(
|
||||
block,
|
||||
CreateIf(
|
||||
CreateIsType(CreateReference(L"obj"), CreateRawType(interfaceModel->fullName)),
|
||||
CreateReturn(CreateRpcConstantReference(L"rpctype_", interfaceModel->fullName))
|
||||
));
|
||||
}
|
||||
|
||||
AddStatement(block, CreateReturn(CreateInt(rpc_controller::RpcTypeId_NotFound)));
|
||||
return functionDecl;
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<WfModule> GenerateModuleRpc(WfLexicalScopeManager* manager, WString assemblyName)
|
||||
@@ -12016,6 +12036,7 @@ namespace vl
|
||||
}
|
||||
|
||||
module->declarations.Add(GenerateWrapperDispatcher(interfaces, opsInterfaceName));
|
||||
module->declarations.Add(GenerateWrapperGetTypeId(interfaces));
|
||||
|
||||
return module;
|
||||
}
|
||||
@@ -12727,7 +12748,6 @@ namespace vl
|
||||
void CollectMangledNames(WfLexicalScopeManager* manager);
|
||||
List<RpcInterfaceModel> BuildInterfaceModels(WfLexicalScopeManager* manager);
|
||||
bool HasRpcEvents(const List<RpcInterfaceModel>& interfaces);
|
||||
Ptr<WfStatement> BuildRegisterService();
|
||||
WString GetRpcOpsInterfaceName(const WString& assemblyName);
|
||||
WString GetRpcOpsInvokeMethodName(const RpcMethodModel& methodModel);
|
||||
WString GetRpcOpsInvokeEventName(const RpcEventModel& eventModel);
|
||||
@@ -13940,15 +13960,6 @@ namespace vl
|
||||
newOps->declarations.Add(objectHold);
|
||||
}
|
||||
|
||||
{
|
||||
auto registerService = CreateFunctionDeclaration(L"RegisterService", CreatePredefinedType(WfPredefinedTypeName::Void), WfFunctionKind::Override);
|
||||
registerService->arguments.Add(CreateFunctionArgument(L"typeId", CreatePredefinedType(WfPredefinedTypeName::Int)));
|
||||
registerService->arguments.Add(CreateFunctionArgument(L"service", CreateTypeFromCpp<Ptr<reflection::IDescriptable>>()));
|
||||
auto block = registerService->statement.Cast<WfBlockStatement>();
|
||||
AddStatement(block, BuildRegisterService());
|
||||
newOps->declarations.Add(registerService);
|
||||
}
|
||||
|
||||
AddStatement(functionDecl->statement.Cast<WfBlockStatement>(), CreateReturn(newOps));
|
||||
return functionDecl;
|
||||
}
|
||||
|
||||
+295
-100
File diff suppressed because it is too large
Load Diff
+230
-103
@@ -961,6 +961,7 @@ namespace vl
|
||||
};
|
||||
|
||||
using RpcEventExceptionMap = Ptr<reflection::description::IValueDictionary>;
|
||||
using RpcLocalServiceMap = collections::Dictionary<vint, Ptr<reflection::IDescriptable>>;
|
||||
|
||||
extern void MergeRpcEventExceptionMap(RpcEventExceptionMap target, RpcEventExceptionMap source);
|
||||
|
||||
@@ -1060,7 +1061,6 @@ namespace vl
|
||||
virtual reflection::description::Value InvokeMethod(RpcObjectReference ref, vint methodId, Ptr<reflection::description::IValueArray> arguments) = 0;
|
||||
virtual void EndInvokeMethod(vint slot) = 0;
|
||||
virtual void ObjectHold(RpcObjectReference ref, vint remoteClientId, bool hold) = 0;
|
||||
virtual void RegisterService(vint typeId, Ptr<reflection::IDescriptable> service) = 0;
|
||||
};
|
||||
|
||||
class IRpcListEventOps
|
||||
@@ -1088,9 +1088,7 @@ namespace vl
|
||||
, public reflection::Description<IRpcOperations>
|
||||
{
|
||||
public:
|
||||
virtual IRpcListOps* GetListOps() = 0;
|
||||
virtual IRpcObjectOps* GetObjectOps() = 0;
|
||||
virtual IRpcListEventOps* GetListEventOps() = 0;
|
||||
virtual IRpcObjectEventOps* GetObjectEventOps() = 0;
|
||||
};
|
||||
|
||||
@@ -1100,9 +1098,8 @@ namespace vl
|
||||
{
|
||||
public:
|
||||
virtual void Finalize() = 0;
|
||||
virtual bool IsRegisteredService(RpcObjectReference ref) = 0;
|
||||
virtual void RegisterService(vint typeId, RpcObjectReference ref) = 0;
|
||||
virtual RpcObjectReference RequestService(vint typeId) = 0;
|
||||
virtual void Initialize() = 0;
|
||||
virtual void DeclareLocalService(RpcObjectReference ref) = 0;
|
||||
|
||||
virtual IRpcObjectEventOps* BroadcastFromClient_ObjectEventOps(vint selfClientId) = 0;
|
||||
virtual IRpcObjectOps* SendToClient_ObjectOps(vint targetClientId) = 0;
|
||||
@@ -1120,22 +1117,86 @@ namespace vl
|
||||
virtual bool GetItemChangedSuppressedFlag(RpcObjectReference ref) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* [Configuration]
|
||||
*
|
||||
* RunRpcTestCase_JsonRequest configures one RpcJsonDispatcher and one RpcJsonLifecycle for each client.
|
||||
* messageDispatcher = shared IRpcJsonMessageDispatcher
|
||||
* dispatcher = RpcJsonDispatcher(clientId, messageDispatcher)
|
||||
* lifecycle = RpcJsonLifecycle(clientId, dispatcher)
|
||||
* serializer = rpcops_IRpcSerializer()
|
||||
* getTypeId = [rpcwrapper_GetTypeId(BoxValue<IDescriptable*>(obj))]
|
||||
* lifecycle->Register(serializer, rpcops_IRpcObjectOpsJson(lifecycle), rpcops_IRpcObjectEventOpsJson(lifecycle), getTypeId, eventAttacher)
|
||||
*
|
||||
* Triggering RpcLifecycleBase::AttachLocalObjectEvents
|
||||
* call rpclistener_Attach(ref.typeId, this, ref, obj, (cached)rpcops_IOps_CreateJson(this))
|
||||
*
|
||||
* [Call graph for JSON based RPC]
|
||||
*
|
||||
* Calling Method of Remote Object:
|
||||
* -> IMyInterface::Method (generated Workflow code)
|
||||
* -> rpcops_IOps_<Application>::InvokeMethod_IMyInterface_Method (generated Workflow code)
|
||||
* {
|
||||
* -> IRpcLifecycle->GetDispatcher()->SendToClient_ObjectOps()->InvokeMethod
|
||||
* -> RpcJsonObjectOps::InvokeMethod
|
||||
* -> IRpcJsonMessageDispatcher::OnJsonRequest
|
||||
* ---- NETWORK PROTOCOL (request) ----
|
||||
* -> RpcJsonObjectOps::Translate
|
||||
* -> IRpcLifecycle->GetController()->GetObjectOps()->InvokeMethod
|
||||
* -> RpcCalleeObjectOpsForList::InvokeMethod
|
||||
* -> rpcops_IRpcObjectOpsJson()->InvokeMethod (generated Workflow code)
|
||||
* -> IMyInterface::Method (actual)
|
||||
* ---- NETWORK PROTOCOL (response) ----
|
||||
* }
|
||||
* { optional EndInvokeMethod when @rpc:Byval on return value }
|
||||
*
|
||||
* Triggering Event of Remote Object (events are automatically hooked when creating a wrapper for a remote object):
|
||||
* -> IMyInterface::SomethingHappened
|
||||
* -> rpcops_IOps_<Application>::InvokeMethod_IMyInterface_SomethingHappened (generated Workflow code)
|
||||
* {
|
||||
* -> IRpcLifecycle->GetDispatcher()->BroadcastFromClient_ObjectEventOps()->InvokeEvent
|
||||
* -> RpcJsonEventObjectOps::InvokeEvent
|
||||
* -> IRpcJsonMessageDispatcher::OnJsonRequest
|
||||
* ---- NETWORK PROTOCOL (broadcast) ----
|
||||
* -> RpcJsonEventObjectOps::Translate
|
||||
* -> IRpcLifecycle->GetController()->GetObjectOps()->InvokeEvent
|
||||
* -> RpcCalleeObjectEventOpsForList::InvokeEvent
|
||||
* -> rpcops_IRpcObjectEventOpsJson()->InvokeEvent (generated Workflow code)
|
||||
* -> IMyInterface::SomethingHappened
|
||||
* ---- NETWORK PROTOCOL (response) ----
|
||||
* }
|
||||
*
|
||||
* Triggering Event of Local Object (when a local object is tracked, RpcLifecycleBase::AttachLocalObjectEvents will be called)
|
||||
* The same to remote object.
|
||||
*
|
||||
* Registering Service:
|
||||
* -> IRpcLifecycle->RegisterLocalService
|
||||
* {
|
||||
* -> IRpcLifecycle->GetDispatcher()->DeclareLocalService(ref)
|
||||
* ---- NETWORK PROTOCOL (broadcast) ----
|
||||
* -> IRpcLifecycle::DeclareRemoteService(ref)
|
||||
* }
|
||||
*/
|
||||
class IRpcLifecycle
|
||||
: public virtual reflection::IDescriptable
|
||||
, public reflection::Description<IRpcLifecycle>
|
||||
{
|
||||
public:
|
||||
virtual void Finalize() = 0;
|
||||
virtual void Initialize() = 0;
|
||||
virtual vint GetClientId() = 0;
|
||||
virtual IRpcDispatcher* GetDispatcher() = 0;
|
||||
virtual IRpcController* GetController() = 0;
|
||||
virtual IRpcSerializer* GetSerializer() = 0;
|
||||
virtual const RpcLocalServiceMap& GetRegisteredLocalServices() = 0;
|
||||
virtual Ptr<reflection::IDescriptable> RefToPtr(RpcObjectReference ref) = 0;
|
||||
virtual RpcObjectReference PtrToRef(Ptr<reflection::IDescriptable> obj) = 0;
|
||||
virtual void LocalObjectHold(RpcObjectReference ref, vint remoteClientId) = 0;
|
||||
virtual void LocalObjectUnhold(RpcObjectReference ref, vint remoteClientId) = 0;
|
||||
virtual void RegisterService(const WString& fullName, Ptr<reflection::IDescriptable> service) = 0;
|
||||
virtual Ptr<reflection::IDescriptable> RequestService(const WString& fullName) = 0;
|
||||
virtual void RegisterLocalService(vint typeId, Ptr<reflection::IDescriptable> service) = 0;
|
||||
virtual void DeclareRemoteService(RpcObjectReference ref) = 0;
|
||||
virtual vint GetTypeIdFromName(WString typeName) = 0;
|
||||
virtual Ptr<reflection::IDescriptable> RequestService(WString typeName) = 0;
|
||||
};
|
||||
|
||||
class IRpcWrapperBase
|
||||
@@ -1196,8 +1257,6 @@ namespace vl
|
||||
protected:
|
||||
Ptr<IRpcObjectOps> objectCallback;
|
||||
Ptr<IRpcObjectEventOps> eventCallback;
|
||||
Ptr<IRpcListOps> listCallback;
|
||||
Ptr<IRpcListEventOps> listEventCallback;
|
||||
collections::Dictionary<RpcEventSuppressionKey, vint> eventSuppressedFlags;
|
||||
collections::Dictionary<RpcObjectReference, vint> itemChangedSuppressedFlags;
|
||||
|
||||
@@ -1212,13 +1271,11 @@ namespace vl
|
||||
RpcControllerDefault();
|
||||
~RpcControllerDefault();
|
||||
|
||||
void Register(Ptr<IRpcObjectOps> objectCallback, Ptr<IRpcObjectEventOps> eventCallback, Ptr<IRpcListOps> listCallback, Ptr<IRpcListEventOps> listEventCallback);
|
||||
void Register(Ptr<IRpcObjectOps> objectCallback, Ptr<IRpcObjectEventOps> eventCallback);
|
||||
|
||||
// IRpcController
|
||||
|
||||
IRpcListOps* GetListOps()override;
|
||||
IRpcObjectOps* GetObjectOps()override;
|
||||
IRpcListEventOps* GetListEventOps()override;
|
||||
IRpcObjectEventOps* GetObjectEventOps()override;
|
||||
|
||||
void Finalize()override;
|
||||
@@ -1233,85 +1290,6 @@ namespace vl
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\RPC\WFLIBRARYRPCJSON.H
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Vczh Library++ 3.0
|
||||
Developer: Zihan Chen(vczh)
|
||||
Framework::RPC
|
||||
|
||||
JSON Helpers:
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_JSON
|
||||
#define VCZH_WORKFLOW_LIBRARY_RPC_JSON
|
||||
|
||||
|
||||
namespace vl
|
||||
{
|
||||
namespace rpc_controller
|
||||
{
|
||||
using RpcJsonSerializeCallback = Func<Ptr<glr::json::JsonNode>(const reflection::description::Value&)>;
|
||||
using RpcJsonDeserializeCallback = Func<reflection::description::Value(Ptr<glr::json::JsonNode>)>;
|
||||
|
||||
extern Ptr<glr::json::JsonNode> JsonSerializePredefinedTypes(const reflection::description::Value& value, const RpcJsonSerializeCallback& rpcjson_Serialize);
|
||||
extern reflection::description::Value JsonDeserializePredefinedTypes(const reflection::description::Value& value, const RpcJsonDeserializeCallback& rpcjson_Deserialize);
|
||||
|
||||
class IRpcJsonMessageDispatcher
|
||||
: public virtual reflection::IDescriptable
|
||||
, public reflection::Description<IRpcJsonMessageDispatcher>
|
||||
{
|
||||
public:
|
||||
virtual vint AllocateRequestId() = 0;
|
||||
virtual Ptr<glr::json::JsonNode> OnJsonRequest(Ptr<glr::json::JsonNode> message) = 0;
|
||||
};
|
||||
|
||||
class RpcJsonObjectOps : public Object, public IRpcObjectOps
|
||||
{
|
||||
private:
|
||||
vint sourceClientId = RpcClientId_Invalid;
|
||||
vint targetClientId = RpcClientId_Invalid;
|
||||
IRpcJsonMessageDispatcher* dispatcher = nullptr;
|
||||
IRpcLifecycle* lifecycle = nullptr;
|
||||
|
||||
public:
|
||||
RpcJsonObjectOps(IRpcJsonMessageDispatcher* _dispatcher);
|
||||
RpcJsonObjectOps(vint _sourceClientId, vint _targetClientId, IRpcJsonMessageDispatcher* _dispatcher, IRpcLifecycle* _lifecycle = nullptr);
|
||||
~RpcJsonObjectOps();
|
||||
|
||||
reflection::description::Value InvokeMethod(RpcObjectReference ref, vint methodId, Ptr<reflection::description::IValueArray> arguments)override;
|
||||
void EndInvokeMethod(vint slot)override;
|
||||
void ObjectHold(RpcObjectReference ref, vint remoteClientId, bool hold)override;
|
||||
void RegisterService(vint typeId, Ptr<reflection::IDescriptable> service)override;
|
||||
|
||||
static Ptr<glr::json::JsonNode> Translate(Ptr<glr::json::JsonNode> message, IRpcObjectOps* ops, IRpcLifecycle* lifecycle = nullptr);
|
||||
};
|
||||
|
||||
class RpcJsonObjectEventOps : public Object, public IRpcObjectEventOps
|
||||
{
|
||||
private:
|
||||
vint sourceClientId = RpcClientId_Invalid;
|
||||
IRpcJsonMessageDispatcher* dispatcher = nullptr;
|
||||
|
||||
public:
|
||||
RpcJsonObjectEventOps(IRpcJsonMessageDispatcher* _dispatcher);
|
||||
RpcJsonObjectEventOps(vint _sourceClientId, IRpcJsonMessageDispatcher* _dispatcher);
|
||||
~RpcJsonObjectEventOps();
|
||||
|
||||
reflection::description::Value InvokeEvent(RpcObjectReference ref, vint eventId, Ptr<reflection::description::IValueArray> arguments)override;
|
||||
|
||||
static Ptr<glr::json::JsonNode> Translate(Ptr<glr::json::JsonNode> message, IRpcObjectEventOps* ops);
|
||||
};
|
||||
|
||||
extern vint ReadRequestId(Ptr<glr::json::JsonNode> message);
|
||||
extern void WriteRequestId(Ptr<glr::json::JsonNode> message, vint requestId);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\RPC\WFLIBRARYRPCLIFECYCLE.H
|
||||
***********************************************************************/
|
||||
@@ -1392,7 +1370,10 @@ namespace vl
|
||||
RpcControllerDefault controller;
|
||||
vint clientId = RpcClientId_Invalid;
|
||||
vint nextObjectId = RpcObjectId_Invalid;
|
||||
bool initialized = false;
|
||||
LocalProperties localObjectProperties;
|
||||
RpcLocalServiceMap registeredLocalServices;
|
||||
collections::Dictionary<vint, RpcObjectReference> registeredRemoteServices;
|
||||
static WString InternalProperty_LocalObjectTracker;
|
||||
static WString InternalProperty_WrapperTracker;
|
||||
UniversalWrapperFactory universalWrapperFactory;
|
||||
@@ -1403,13 +1384,13 @@ namespace vl
|
||||
bool TryGetTrackedWrapperRef(reflection::DescriptableObject* obj, RpcObjectReference& ref)const;
|
||||
IRpcWrapperBase* GetTrackedWrapper(RpcObjectReference ref)const;
|
||||
void TrackLocalObject(RpcObjectReference ref, reflection::IDescriptable* obj);
|
||||
RpcObjectReference CreateLocalObject(Ptr<reflection::IDescriptable> obj, RpcObjectReference ref);
|
||||
void UntrackLocalObject(RpcObjectReference ref, bool clearInternalProperty);
|
||||
void RemoveLocalObject(RpcObjectReference ref, bool clearInternalProperty);
|
||||
bool IsTracked(vint objectId)const;
|
||||
Ptr<reflection::IDescriptable> CreateCallerProxy(RpcObjectReference ref, IRpcSerializer* serializer);
|
||||
void DisconnectWrappersForFinalize();
|
||||
protected:
|
||||
IRpcDispatcher* dispatcher = nullptr;
|
||||
collections::Dictionary<WString, vint> idMap;
|
||||
Ptr<IRpcSerializer> serializer;
|
||||
|
||||
@@ -1427,13 +1408,16 @@ namespace vl
|
||||
// IRpcLifecycle
|
||||
|
||||
void Finalize()override;
|
||||
void Initialize()override;
|
||||
vint GetClientId()override;
|
||||
IRpcDispatcher* GetDispatcher()override;
|
||||
RpcControllerDefault* GetController()override;
|
||||
const RpcLocalServiceMap& GetRegisteredLocalServices()override;
|
||||
void LocalObjectHold(RpcObjectReference ref, vint remoteClientId)override;
|
||||
void LocalObjectUnhold(RpcObjectReference ref, vint remoteClientId)override;
|
||||
void RegisterService(const WString& fullName, Ptr<reflection::IDescriptable> service)override;
|
||||
Ptr<reflection::IDescriptable> RequestService(const WString& fullName)override;
|
||||
void RegisterLocalService(vint typeId, Ptr<reflection::IDescriptable> service)override;
|
||||
void DeclareRemoteService(RpcObjectReference ref)override;
|
||||
vint GetTypeIdFromName(WString typeName)override;
|
||||
Ptr<reflection::IDescriptable> RequestService(WString typeName)override;
|
||||
Ptr<reflection::IDescriptable> RefToPtr(RpcObjectReference ref)override;
|
||||
Ptr<reflection::IDescriptable> RefToPtr(RpcObjectReference ref, IRpcSerializer* serializer);
|
||||
RpcObjectReference PtrToRef(Ptr<reflection::IDescriptable> obj)override;
|
||||
@@ -1444,6 +1428,153 @@ namespace vl
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\RPC\WFLIBRARYRPCJSON.H
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Vczh Library++ 3.0
|
||||
Developer: Zihan Chen(vczh)
|
||||
Framework::RPC
|
||||
|
||||
JSON Helpers:
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_JSON
|
||||
#define VCZH_WORKFLOW_LIBRARY_RPC_JSON
|
||||
|
||||
|
||||
namespace vl
|
||||
{
|
||||
namespace rpc_controller
|
||||
{
|
||||
class RpcCalleeListOps;
|
||||
class RpcCalleeListEventOps;
|
||||
class RpcCalleeObjectOpsForList;
|
||||
class RpcCalleeObjectEventOpsForList;
|
||||
|
||||
using RpcJsonSerializeCallback = Func<Ptr<glr::json::JsonNode>(const reflection::description::Value&)>;
|
||||
using RpcJsonDeserializeCallback = Func<reflection::description::Value(Ptr<glr::json::JsonNode>)>;
|
||||
|
||||
extern Ptr<glr::json::JsonNode> JsonSerializePredefinedTypes(const reflection::description::Value& value, const RpcJsonSerializeCallback& rpcjson_Serialize);
|
||||
extern reflection::description::Value JsonDeserializePredefinedTypes(const reflection::description::Value& value, const RpcJsonDeserializeCallback& rpcjson_Deserialize);
|
||||
|
||||
class IRpcJsonMessageDispatcher
|
||||
: public virtual reflection::IDescriptable
|
||||
, public reflection::Description<IRpcJsonMessageDispatcher>
|
||||
{
|
||||
public:
|
||||
enum class RequestType
|
||||
{
|
||||
Direct,
|
||||
Broadcast,
|
||||
BroadcastAndDrop,
|
||||
};
|
||||
|
||||
virtual vint AllocateRequestId() = 0;
|
||||
virtual Ptr<glr::json::JsonNode> OnJsonRequest(Ptr<glr::json::JsonNode> message, RequestType requestType) = 0;
|
||||
|
||||
static Ptr<glr::json::JsonNode> DefaultTranslate(
|
||||
Ptr<glr::json::JsonNode> message,
|
||||
RequestType requestType,
|
||||
IRpcObjectOps* objectOps,
|
||||
IRpcObjectEventOps* objectEventOps,
|
||||
IRpcDispatcher* dispatcher,
|
||||
IRpcLifecycle* lifecycle
|
||||
);
|
||||
};
|
||||
|
||||
class RpcJsonObjectOps : public Object, public IRpcObjectOps
|
||||
{
|
||||
private:
|
||||
vint sourceClientId = RpcClientId_Invalid;
|
||||
vint targetClientId = RpcClientId_Invalid;
|
||||
IRpcJsonMessageDispatcher* dispatcher = nullptr;
|
||||
|
||||
public:
|
||||
RpcJsonObjectOps(IRpcJsonMessageDispatcher* _dispatcher);
|
||||
RpcJsonObjectOps(vint _sourceClientId, vint _targetClientId, IRpcJsonMessageDispatcher* _dispatcher);
|
||||
~RpcJsonObjectOps();
|
||||
|
||||
reflection::description::Value InvokeMethod(RpcObjectReference ref, vint methodId, Ptr<reflection::description::IValueArray> arguments)override;
|
||||
void EndInvokeMethod(vint slot)override;
|
||||
void ObjectHold(RpcObjectReference ref, vint remoteClientId, bool hold)override;
|
||||
|
||||
static Ptr<glr::json::JsonNode> Translate(Ptr<glr::json::JsonNode> message, IRpcObjectOps* ops, IRpcLifecycle* lifecycle = nullptr);
|
||||
};
|
||||
|
||||
class RpcJsonObjectEventOps : public Object, public IRpcObjectEventOps
|
||||
{
|
||||
private:
|
||||
vint sourceClientId = RpcClientId_Invalid;
|
||||
IRpcJsonMessageDispatcher* dispatcher = nullptr;
|
||||
|
||||
public:
|
||||
RpcJsonObjectEventOps(IRpcJsonMessageDispatcher* _dispatcher);
|
||||
RpcJsonObjectEventOps(vint _sourceClientId, IRpcJsonMessageDispatcher* _dispatcher);
|
||||
~RpcJsonObjectEventOps();
|
||||
|
||||
reflection::description::Value InvokeEvent(RpcObjectReference ref, vint eventId, Ptr<reflection::description::IValueArray> arguments)override;
|
||||
|
||||
static Ptr<glr::json::JsonNode> Translate(Ptr<glr::json::JsonNode> message, IRpcObjectEventOps* ops, IRpcLifecycle* lifecycle = nullptr);
|
||||
};
|
||||
|
||||
class RpcJsonDispatcher : public Object, public IRpcDispatcher
|
||||
{
|
||||
private:
|
||||
vint sourceClientId = RpcClientId_Invalid;
|
||||
IRpcJsonMessageDispatcher* dispatcher = nullptr;
|
||||
Ptr<RpcJsonObjectEventOps> objectEventOps;
|
||||
collections::Dictionary<vint, Ptr<RpcJsonObjectOps>> objectOps;
|
||||
|
||||
public:
|
||||
RpcJsonDispatcher(vint _sourceClientId, IRpcJsonMessageDispatcher* _dispatcher);
|
||||
|
||||
void Finalize()override;
|
||||
void Initialize()override;
|
||||
void DeclareLocalService(RpcObjectReference ref)override;
|
||||
IRpcObjectEventOps* BroadcastFromClient_ObjectEventOps(vint selfClientId)override;
|
||||
IRpcObjectOps* SendToClient_ObjectOps(vint targetClientId)override;
|
||||
|
||||
static Ptr<glr::json::JsonNode> Translate(Ptr<glr::json::JsonNode> message, IRpcDispatcher* dispatcher, IRpcLifecycle* lifecycle);
|
||||
};
|
||||
|
||||
class RpcJsonLifecycle : public RpcLifecycleBase
|
||||
{
|
||||
private:
|
||||
RpcJsonDispatcher* dispatcher = nullptr;
|
||||
Func<vint(reflection::IDescriptable*)> getTypeId;
|
||||
Func<void(RpcObjectReference, reflection::IDescriptable*)> eventAttacher;
|
||||
Ptr<RpcCalleeListOps> listOps;
|
||||
Ptr<RpcCalleeListEventOps> listEventOps;
|
||||
Ptr<RpcCalleeObjectOpsForList> objectOpsForList;
|
||||
Ptr<RpcCalleeObjectEventOpsForList> objectEventOpsForList;
|
||||
|
||||
protected:
|
||||
vint DecideTypeId(reflection::IDescriptable* obj)const override;
|
||||
void AttachLocalObjectEvents(RpcObjectReference ref, reflection::IDescriptable* obj)override;
|
||||
|
||||
public:
|
||||
RpcJsonLifecycle(vint _clientId, RpcJsonDispatcher* _dispatcher);
|
||||
|
||||
void Register(
|
||||
Ptr<IRpcSerializer> _serializer,
|
||||
Ptr<IRpcObjectOps> _objectOps,
|
||||
Ptr<IRpcObjectEventOps> _objectEventOps,
|
||||
Func<vint(reflection::IDescriptable*)> _getTypeId,
|
||||
Func<void(RpcObjectReference, reflection::IDescriptable*)> _eventAttacher
|
||||
);
|
||||
IRpcSerializer* GetSerializer()override;
|
||||
IRpcDispatcher* GetDispatcher()override;
|
||||
};
|
||||
|
||||
extern vint ReadRequestId(Ptr<glr::json::JsonNode> message);
|
||||
extern void WriteRequestId(Ptr<glr::json::JsonNode> message, vint requestId);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\RPC\WFLIBRARYRPCWRAPPERS.H
|
||||
***********************************************************************/
|
||||
@@ -1663,7 +1794,6 @@ namespace vl
|
||||
reflection::description::Value InvokeMethod(RpcObjectReference ref, vint methodId, Ptr<reflection::description::IValueArray> arguments)override;
|
||||
void EndInvokeMethod(vint slot)override;
|
||||
void ObjectHold(RpcObjectReference ref, vint remoteClientId, bool hold)override;
|
||||
void RegisterService(vint typeId, Ptr<reflection::IDescriptable> service)override;
|
||||
};
|
||||
|
||||
class RpcCalleeObjectEventOpsForList : public Object, public IRpcObjectEventOps
|
||||
@@ -1796,6 +1926,7 @@ Predefined Types
|
||||
F(vl::rpc_controller::RpcException)\
|
||||
F(vl::rpc_controller::RpcByvalReturnValue)\
|
||||
F(vl::rpc_controller::IRpcSerializer)\
|
||||
F(vl::rpc_controller::IRpcJsonMessageDispatcher::RequestType)\
|
||||
F(vl::rpc_controller::IRpcJsonMessageDispatcher)\
|
||||
F(vl::rpc_controller::IRpcListOps)\
|
||||
F(vl::rpc_controller::IRpcListEventOps)\
|
||||
@@ -1846,9 +1977,9 @@ Interface Implementation Proxy (Implement)
|
||||
INVOKEGET_INTERFACE_PROXY_NOPARAMS(AllocateRequestId);
|
||||
}
|
||||
|
||||
vl::Ptr<vl::glr::json::JsonNode> OnJsonRequest(vl::Ptr<vl::glr::json::JsonNode> message)override
|
||||
vl::Ptr<vl::glr::json::JsonNode> OnJsonRequest(vl::Ptr<vl::glr::json::JsonNode> message, vl::rpc_controller::IRpcJsonMessageDispatcher::RequestType requestType)override
|
||||
{
|
||||
INVOKEGET_INTERFACE_PROXY(OnJsonRequest, message);
|
||||
INVOKEGET_INTERFACE_PROXY(OnJsonRequest, message, requestType);
|
||||
}
|
||||
END_INTERFACE_PROXY(vl::rpc_controller::IRpcJsonMessageDispatcher)
|
||||
|
||||
@@ -1975,10 +2106,6 @@ Interface Implementation Proxy (Implement)
|
||||
INVOKE_INTERFACE_PROXY(ObjectHold, ref, remoteClientId, hold);
|
||||
}
|
||||
|
||||
void RegisterService(vl::vint typeId, vl::Ptr<vl::reflection::IDescriptable> service)override
|
||||
{
|
||||
INVOKE_INTERFACE_PROXY(RegisterService, typeId, service);
|
||||
}
|
||||
END_INTERFACE_PROXY(vl::rpc_controller::IRpcObjectOps)
|
||||
|
||||
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::rpc_controller::IRpcListEventOps)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user