Skip to content

Commit d807c9d

Browse files
feat(jni): client helpers for execute methods
Executing a methods requires preparig a promise and storying it while waiting for the messege reaches the service and a response is delivered back to the client. This commit provides a method helper which allow storing promisses for certain result types. This object is stored globally (the client is anyway a subsystem).
1 parent 785ceb5 commit d807c9d

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

templates/module/Source/modulejni/Private/Generated/jni/jniclient.cpp.tpl

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,23 +108,44 @@ limitations under the License.
108108
#endif
109109
#endif
110110

111+
#include <atomic>
112+
#include "HAL/CriticalSection.h"
111113
#include "GenericPlatform/GenericPlatformMisc.h"
112114

113115
/**
114116
\brief data structure to hold the last sent property values
115117
*/
116118

117119

120+
class {{$Class}}MethodHelper
121+
{
122+
public:
123+
template <typename ResultType>
124+
FGuid StorePromise(TPromise<ResultType>& Promise);
125+
126+
template <typename ResultType>
127+
bool FulfillPromise(const FGuid& Id, const ResultType& Value);
128+
private:
129+
TMap<FGuid, void*> ReplyPromisesMap;
130+
FCriticalSection ReplyPromisesMapCS;
131+
132+
};
133+
118134
namespace {
119135

120136
{{$Class}}* g{{$Class}}Handle = nullptr;
137+
121138
TFunction<void(bool)> notifyIsReady = [](bool value) { (void)value; UE_LOG(Log{{$Iface}}Client_JNI, Warning, TEXT("notifyIsReady used but not set ")); };
122139
{{- range .Interface.Properties }}
123140
TFunction<void({{ueReturn "" .}})> on{{Camel .Name}}ChangedEmpty = []({{ueReturn "" .}} value) { (void)value; UE_LOG(Log{{$Iface}}Client_JNI, Warning, TEXT("on{{Camel .Name}}Changed used but not set ")); };
124141
TFunction<void({{ueReturn "" .}})> on{{Camel .Name}}Changed = on{{Camel .Name}}ChangedEmpty;
125142
{{- end}}
126143

144+
{{$Class}}MethodHelper g{{$Class}}methodHelper;
145+
127146
}
147+
148+
128149
DEFINE_LOG_CATEGORY(Log{{$Iface}}Client_JNI);
129150

130151
{{$Class}}::{{$Class}}()
@@ -402,4 +423,51 @@ JNI_METHOD void {{$jniFullFuncPrefix}}_nativeIsReady(JNIEnv* Env, jclass Clazz,
402423
#endif
403424

404425

426+
template <typename ResultType>
427+
FGuid {{$Class}}MethodHelper::StorePromise(TPromise<ResultType>& Promise)
428+
{
429+
FGuid Id = FGuid::NewGuid();
430+
FScopeLock Lock(&ReplyPromisesMapCS);
431+
ReplyPromisesMap.Add(Id, &Promise);
432+
//TODO invalid id if sth goes wrong + log + checking
433+
UE_LOG(Log{{$Iface}}Client_JNI, Warning, TEXT(" method store id %s"), *(Id.ToString(EGuidFormats::Digits)));
434+
return Id;
435+
}
436+
437+
template <typename ResultType>
438+
bool {{$Class}}MethodHelper::FulfillPromise(const FGuid& Id, const ResultType& Value)
439+
{
440+
UE_LOG(Log{{$Iface}}Client_JNI, Warning, TEXT(" method resolving id %s"), *(Id.ToString(EGuidFormats::Digits)));
441+
TPromise<ResultType>* PromisePtr = nullptr;
442+
443+
{
444+
FScopeLock Lock(&ReplyPromisesMapCS);
445+
if (auto** Found = ReplyPromisesMap.Find(Id))
446+
{
447+
PromisePtr = static_cast<TPromise<ResultType>*>(*Found);
448+
ReplyPromisesMap.Remove(Id);
449+
}
450+
}
451+
452+
if (PromisePtr)
453+
{
454+
AsyncTask(ENamedThreads::GameThread, [Value, PromisePtr]()
455+
{
456+
PromisePtr->SetValue(Value);
457+
});
458+
return true;
459+
460+
}
461+
return false;
462+
}
463+
{{- $returnTypes := getEmptyStringList}}
464+
{{- range .Interface.Operations }}
465+
{{- $type := ueReturn "" .Return }}
466+
{{- $returnTypes = (appendList $returnTypes $type) }}
467+
{{- end }}
468+
{{- $returnTypes = unique $returnTypes }}
469+
{{- range $returnTypes}}
470+
template FGuid {{$Class}}MethodHelper::StorePromise<{{.}}>(TPromise<{{.}}>& Promise);
471+
template bool {{$Class}}MethodHelper::FulfillPromise<{{.}}>(const FGuid& Id, const {{.}}& Value);
472+
{{- end}}
405473

0 commit comments

Comments
 (0)