WebInterfaceJSFunction.h
7.1 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Engine/Source/Runtime/WebBrowser/Public/WebJSFunction.h
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Misc/Guid.h"
#include "UObject/Class.h"
#include "WebInterfaceJSFunction.generated.h"
class FWebInterfaceJSScripting;
struct WEBBROWSERUI_API FWebInterfaceJSParam
{
struct IStructWrapper
{
virtual ~IStructWrapper() {};
virtual UStruct* GetTypeInfo() = 0;
virtual const void* GetData() = 0;
virtual IStructWrapper* Clone() = 0;
};
template <typename T> struct FStructWrapper
: public IStructWrapper
{
T StructValue;
FStructWrapper(const T& InValue)
: StructValue(InValue)
{}
virtual ~FStructWrapper()
{}
virtual UStruct* GetTypeInfo() override
{
return T::StaticStruct();
}
virtual const void* GetData() override
{
return &StructValue;
}
virtual IStructWrapper* Clone() override
{
return new FStructWrapper<T>(StructValue);
}
};
FWebInterfaceJSParam() : Tag(PTYPE_NULL) {}
FWebInterfaceJSParam(bool Value) : Tag(PTYPE_BOOL), BoolValue(Value) {}
FWebInterfaceJSParam(int8 Value) : Tag(PTYPE_INT), IntValue(Value) {}
FWebInterfaceJSParam(int16 Value) : Tag(PTYPE_INT), IntValue(Value) {}
FWebInterfaceJSParam(int32 Value) : Tag(PTYPE_INT), IntValue(Value) {}
FWebInterfaceJSParam(uint8 Value) : Tag(PTYPE_INT), IntValue(Value) {}
FWebInterfaceJSParam(uint16 Value) : Tag(PTYPE_INT), IntValue(Value) {}
FWebInterfaceJSParam(uint32 Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
FWebInterfaceJSParam(int64 Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
FWebInterfaceJSParam(uint64 Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
FWebInterfaceJSParam(double Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
FWebInterfaceJSParam(float Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
FWebInterfaceJSParam(const FString& Value) : Tag(PTYPE_STRING), StringValue(new FString(Value)) {}
FWebInterfaceJSParam(const FText& Value) : Tag(PTYPE_STRING), StringValue(new FString(Value.ToString())) {}
FWebInterfaceJSParam(const FName& Value) : Tag(PTYPE_STRING), StringValue(new FString(Value.ToString())) {}
FWebInterfaceJSParam(const TCHAR* Value) : Tag(PTYPE_STRING), StringValue(new FString(Value)) {}
FWebInterfaceJSParam(UObject* Value) : Tag(PTYPE_OBJECT), ObjectValue(Value) {}
template <typename T> FWebInterfaceJSParam(const T& Value,
typename TEnableIf<!TIsPointer<T>::Value, UStruct>::Type* InTypeInfo=T::StaticStruct())
: Tag(PTYPE_STRUCT)
, StructValue(new FStructWrapper<T>(Value))
{}
template <typename T> FWebInterfaceJSParam(const TArray<T>& Value)
: Tag(PTYPE_ARRAY)
{
ArrayValue = new TArray<FWebInterfaceJSParam>();
ArrayValue->Reserve(Value.Num());
for(T Item : Value)
{
ArrayValue->Add(FWebInterfaceJSParam(Item));
}
}
template <typename T> FWebInterfaceJSParam(const TMap<FString, T>& Value)
: Tag(PTYPE_MAP)
{
MapValue = new TMap<FString, FWebInterfaceJSParam>();
MapValue->Reserve(Value.Num());
for(const auto& Pair : Value)
{
MapValue->Add(Pair.Key, FWebInterfaceJSParam(Pair.Value));
}
}
template <typename K, typename T> FWebInterfaceJSParam(const TMap<K, T>& Value)
: Tag(PTYPE_MAP)
{
MapValue = new TMap<FString, FWebInterfaceJSParam>();
MapValue->Reserve(Value.Num());
for(const auto& Pair : Value)
{
MapValue->Add(Pair.Key.ToString(), FWebInterfaceJSParam(Pair.Value));
}
}
FWebInterfaceJSParam(const FWebInterfaceJSParam& Other);
FWebInterfaceJSParam(FWebInterfaceJSParam&& Other);
~FWebInterfaceJSParam();
enum { PTYPE_NULL, PTYPE_BOOL, PTYPE_INT, PTYPE_DOUBLE, PTYPE_STRING, PTYPE_OBJECT, PTYPE_STRUCT, PTYPE_ARRAY, PTYPE_MAP } Tag;
union
{
bool BoolValue;
double DoubleValue;
int32 IntValue;
UObject* ObjectValue;
const FString* StringValue;
IStructWrapper* StructValue;
TArray<FWebInterfaceJSParam>* ArrayValue;
TMap<FString, FWebInterfaceJSParam>* MapValue;
};
};
class FWebInterfaceJSScripting;
/** Base class for JS callback objects. */
USTRUCT()
struct WEBBROWSERUI_API FWebInterfaceJSCallbackBase
{
GENERATED_USTRUCT_BODY()
FWebInterfaceJSCallbackBase()
{}
bool IsValid() const
{
return ScriptingPtr.IsValid();
}
protected:
FWebInterfaceJSCallbackBase(TSharedPtr<FWebInterfaceJSScripting> InScripting, const FGuid& InCallbackId)
: ScriptingPtr(InScripting)
, CallbackId(InCallbackId)
{}
void Invoke(int32 ArgCount, FWebInterfaceJSParam Arguments[], bool bIsError = false) const;
private:
TWeakPtr<FWebInterfaceJSScripting> ScriptingPtr;
FGuid CallbackId;
};
/**
* Representation of a remote JS function.
* FWebJSFunction objects represent a JS function and allow calling them from native code.
* FWebJSFunction objects can also be added to delegates and events using the Bind/AddLambda method.
*/
USTRUCT()
struct WEBBROWSERUI_API FWebInterfaceJSFunction
: public FWebInterfaceJSCallbackBase
{
GENERATED_USTRUCT_BODY()
FWebInterfaceJSFunction()
: FWebInterfaceJSCallbackBase()
{}
FWebInterfaceJSFunction(TSharedPtr<FWebInterfaceJSScripting> InScripting, const FGuid& InFunctionId)
: FWebInterfaceJSCallbackBase(InScripting, InFunctionId)
{}
template<typename ...ArgTypes> void operator()(ArgTypes... Args) const
{
FWebInterfaceJSParam ArgArray[sizeof...(Args)] = {FWebInterfaceJSParam(Args)...};
Invoke(sizeof...(Args), ArgArray);
}
};
/**
* Representation of a remote JS async response object.
* UFUNCTIONs taking a FWebJSResponse will get it passed in automatically when called from a web browser.
* Pass a result or error back by invoking Success or Failure on the object.
* UFunctions accepting a FWebJSResponse should have a void return type, as any value returned from the function will be ignored.
* Calling the response methods does not have to happen before returning from the function, which means you can use this to implement asynchronous functionality.
*
* Note that the remote object will become invalid as soon as a result has been delivered, so you can only call either Success or Failure once.
*/
USTRUCT()
struct WEBBROWSERUI_API FWebInterfaceJSResponse
: public FWebInterfaceJSCallbackBase
{
GENERATED_USTRUCT_BODY()
FWebInterfaceJSResponse()
: FWebInterfaceJSCallbackBase()
{}
FWebInterfaceJSResponse(TSharedPtr<FWebInterfaceJSScripting> InScripting, const FGuid& InCallbackId)
: FWebInterfaceJSCallbackBase(InScripting, InCallbackId)
{}
/**
* Indicate successful completion without a return value.
* The remote Promise's then() handler will be executed without arguments.
*/
void Success() const
{
Invoke(0, nullptr, false);
}
/**
* Indicate successful completion passing a return value back.
* The remote Promise's then() handler will be executed with the value passed as its single argument.
*/
template<typename T>
void Success(T Arg) const
{
FWebInterfaceJSParam ArgArray[1] = {FWebInterfaceJSParam(Arg)};
Invoke(1, ArgArray, false);
}
/**
* Indicate failed completion, passing an error message back to JS.
* The remote Promise's catch() handler will be executed with the value passed as the error reason.
*/
template<typename T>
void Failure(T Arg) const
{
FWebInterfaceJSParam ArgArray[1] = {FWebInterfaceJSParam(Arg)};
Invoke(1, ArgArray, true);
}
};