/
UE4CVServer.cpp
121 lines (105 loc) · 3.42 KB
/
UE4CVServer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Fill out your copyright notice in the Description page of Project Settings.
// #include "RealisticRendering.h"
#include "UnrealCVPrivate.h"
#include "UE4CVServer.h"
FUE4CVServer::FUE4CVServer(FCommandDispatcher* CommandDispatcher)
{
this->CommandDispatcher = CommandDispatcher;
// Command Dispatcher defines the behavior of the server, TODO: Write with javadoc style
this->NetworkManager = NewObject<UNetworkManager>();
this->NetworkManager->AddToRoot(); // Avoid GC
this->NetworkManager->OnReceived().AddRaw(this, &FUE4CVServer::HandleRequest);
}
FUE4CVServer::~FUE4CVServer()
{
this->NetworkManager->FinishDestroy(); // TODO: Check is this usage correct?
}
void FUE4CVServer::ProcessPendingRequest()
{
/*
if (PendingTask.Active) // Do query or wait for callback
{
FExecStatus ExecStatus = PendingTask.CheckStatus();
if (ExecStatus == FExecStatusType::Pending)
{
return; // The task is still pending
}
else
{
PendingTask.Active = false;
FString ReplyRawMessage = FString::Printf(TEXT("%d:%s"), PendingTask.RequestId, *ExecStatus.GetMessage());
SendClientMessage(ReplyRawMessage);
}
}
while (!PendingRequest.IsEmpty())
{
FRequest Request;
bool DequeueStatus = PendingRequest.Dequeue(Request);
check(DequeueStatus);
FExecStatus ExecStatus = CommandDispatcher->Exec(Request.Message);
if (ExecStatus == FExecStatusType::Pending)
{
PendingTask = FPendingTask(ExecStatus.Promise, Request.RequestId);
break;
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Response: %s"), *ExecStatus.GetMessage());
FString ReplyRawMessage = FString::Printf(TEXT("%d:%s"), Request.RequestId, *ExecStatus.GetMessage());
SendClientMessage(ReplyRawMessage);
}
}
*/
while (!PendingRequest.IsEmpty())
{
FRequest Request;
bool DequeueStatus = PendingRequest.Dequeue(Request);
check(DequeueStatus);
int32 RequestId = Request.RequestId;
FCallbackDelegate CallbackDelegate;
CallbackDelegate.BindLambda([this, RequestId](FExecStatus ExecStatus)
{
UE_LOG(LogTemp, Warning, TEXT("Response: %s"), *ExecStatus.GetMessage());
FString ReplyRawMessage = FString::Printf(TEXT("%d:%s"), RequestId, *ExecStatus.GetMessage());
SendClientMessage(ReplyRawMessage);
});
CommandDispatcher->ExecAsync(Request.Message, CallbackDelegate);
}
}
bool FUE4CVServer::Start()
{
NetworkManager->Start();
return true;
}
void FUE4CVServer::HandleRequest(const FString& InRawMessage)
{
UE_LOG(LogTemp, Warning, TEXT("Request: %s"), *InRawMessage);
// Parse Raw Message
FString MessageFormat = "(\\d{1,8}):(.*)";
FRegexPattern RegexPattern(MessageFormat);
FRegexMatcher Matcher(RegexPattern, InRawMessage);
if (Matcher.FindNext())
{
// TODO: Handle malform request message
FString StrRequestId = Matcher.GetCaptureGroup(1);
FString Message = Matcher.GetCaptureGroup(2);
uint32 RequestId = FCString::Atoi(*StrRequestId);
FRequest Request(Message, RequestId);
this->PendingRequest.Enqueue(Request);
/*
FExecStatus ExecStatus = CommandDispatcher->Exec(Message);
UE_LOG(LogTemp, Warning, TEXT("Response: %s"), *ExecStatus.Message);
FString ReplyRawMessage = FString::Printf(TEXT("%d:%s"), RequestId, *ExecStatus.Message);
SendClientMessage(ReplyRawMessage);
*/
}
else
{
SendClientMessage(FString::Printf(TEXT("error: Malformat raw message '%s'"), *InRawMessage));
}
}
void FUE4CVServer::SendClientMessage(FString Message)
{
// TODO: Do not use game thread to send message.
NetworkManager->SendMessage(Message);
}