WebInterfaceJSFunction.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Engine/Source/Runtime/WebBrowser/Public/WebJSFunction.h
  2. #pragma once
  3. #include "Containers/Array.h"
  4. #include "Containers/Map.h"
  5. #include "Containers/UnrealString.h"
  6. #include "CoreMinimal.h"
  7. #include "HAL/Platform.h"
  8. #include "Internationalization/Text.h"
  9. #include "Misc/Guid.h"
  10. #include "Templates/EnableIf.h"
  11. #include "Templates/IsPointer.h"
  12. #include "Templates/SharedPointer.h"
  13. #include "UObject/Class.h"
  14. #include "UObject/NameTypes.h"
  15. #include "UObject/ObjectMacros.h"
  16. #include "WebInterfaceJSFunction.generated.h"
  17. class FWebInterfaceJSScripting;
  18. class UObject;
  19. class UStruct;
  20. struct WEBBROWSERUI_API FWebInterfaceJSParam
  21. {
  22. struct IStructWrapper
  23. {
  24. virtual ~IStructWrapper() {};
  25. virtual UStruct* GetTypeInfo() = 0;
  26. virtual const void* GetData() = 0;
  27. virtual IStructWrapper* Clone() = 0;
  28. };
  29. template <typename T> struct FStructWrapper
  30. : public IStructWrapper
  31. {
  32. T StructValue;
  33. FStructWrapper(const T& InValue)
  34. : StructValue(InValue)
  35. {}
  36. virtual ~FStructWrapper()
  37. {}
  38. virtual UStruct* GetTypeInfo() override
  39. {
  40. return T::StaticStruct();
  41. }
  42. virtual const void* GetData() override
  43. {
  44. return &StructValue;
  45. }
  46. virtual IStructWrapper* Clone() override
  47. {
  48. return new FStructWrapper<T>(StructValue);
  49. }
  50. };
  51. FWebInterfaceJSParam() : Tag(PTYPE_NULL) {}
  52. FWebInterfaceJSParam(bool Value) : Tag(PTYPE_BOOL), BoolValue(Value) {}
  53. FWebInterfaceJSParam(int8 Value) : Tag(PTYPE_INT), IntValue(Value) {}
  54. FWebInterfaceJSParam(int16 Value) : Tag(PTYPE_INT), IntValue(Value) {}
  55. FWebInterfaceJSParam(int32 Value) : Tag(PTYPE_INT), IntValue(Value) {}
  56. FWebInterfaceJSParam(uint8 Value) : Tag(PTYPE_INT), IntValue(Value) {}
  57. FWebInterfaceJSParam(uint16 Value) : Tag(PTYPE_INT), IntValue(Value) {}
  58. FWebInterfaceJSParam(uint32 Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
  59. FWebInterfaceJSParam(int64 Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
  60. FWebInterfaceJSParam(uint64 Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
  61. FWebInterfaceJSParam(double Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
  62. FWebInterfaceJSParam(float Value) : Tag(PTYPE_DOUBLE), DoubleValue(Value) {}
  63. FWebInterfaceJSParam(const FString& Value) : Tag(PTYPE_STRING), StringValue(new FString(Value)) {}
  64. FWebInterfaceJSParam(const FText& Value) : Tag(PTYPE_STRING), StringValue(new FString(Value.ToString())) {}
  65. FWebInterfaceJSParam(const FName& Value) : Tag(PTYPE_STRING), StringValue(new FString(Value.ToString())) {}
  66. FWebInterfaceJSParam(const TCHAR* Value) : Tag(PTYPE_STRING), StringValue(new FString(Value)) {}
  67. FWebInterfaceJSParam(UObject* Value) : Tag(PTYPE_OBJECT), ObjectValue(Value) {}
  68. template <typename T> FWebInterfaceJSParam(const T& Value,
  69. typename TEnableIf<!TIsPointer<T>::Value, UStruct>::Type* InTypeInfo=T::StaticStruct())
  70. : Tag(PTYPE_STRUCT)
  71. , StructValue(new FStructWrapper<T>(Value))
  72. {}
  73. template <typename T> FWebInterfaceJSParam(const TArray<T>& Value)
  74. : Tag(PTYPE_ARRAY)
  75. {
  76. ArrayValue = new TArray<FWebInterfaceJSParam>();
  77. ArrayValue->Reserve(Value.Num());
  78. for(T Item : Value)
  79. {
  80. ArrayValue->Add(FWebInterfaceJSParam(Item));
  81. }
  82. }
  83. template <typename T> FWebInterfaceJSParam(const TMap<FString, T>& Value)
  84. : Tag(PTYPE_MAP)
  85. {
  86. MapValue = new TMap<FString, FWebInterfaceJSParam>();
  87. MapValue->Reserve(Value.Num());
  88. for(const auto& Pair : Value)
  89. {
  90. MapValue->Add(Pair.Key, FWebInterfaceJSParam(Pair.Value));
  91. }
  92. }
  93. template <typename K, typename T> FWebInterfaceJSParam(const TMap<K, T>& Value)
  94. : Tag(PTYPE_MAP)
  95. {
  96. MapValue = new TMap<FString, FWebInterfaceJSParam>();
  97. MapValue->Reserve(Value.Num());
  98. for(const auto& Pair : Value)
  99. {
  100. MapValue->Add(Pair.Key.ToString(), FWebInterfaceJSParam(Pair.Value));
  101. }
  102. }
  103. FWebInterfaceJSParam(const FWebInterfaceJSParam& Other);
  104. FWebInterfaceJSParam(FWebInterfaceJSParam&& Other);
  105. ~FWebInterfaceJSParam();
  106. enum { PTYPE_NULL, PTYPE_BOOL, PTYPE_INT, PTYPE_DOUBLE, PTYPE_STRING, PTYPE_OBJECT, PTYPE_STRUCT, PTYPE_ARRAY, PTYPE_MAP } Tag;
  107. union
  108. {
  109. bool BoolValue;
  110. double DoubleValue;
  111. int32 IntValue;
  112. UObject* ObjectValue;
  113. const FString* StringValue;
  114. IStructWrapper* StructValue;
  115. TArray<FWebInterfaceJSParam>* ArrayValue;
  116. TMap<FString, FWebInterfaceJSParam>* MapValue;
  117. };
  118. };
  119. class FWebInterfaceJSScripting;
  120. /** Base class for JS callback objects. */
  121. USTRUCT()
  122. struct WEBBROWSERUI_API FWebInterfaceJSCallbackBase
  123. {
  124. GENERATED_USTRUCT_BODY()
  125. FWebInterfaceJSCallbackBase()
  126. {}
  127. bool IsValid() const
  128. {
  129. return ScriptingPtr.IsValid();
  130. }
  131. protected:
  132. FWebInterfaceJSCallbackBase(TSharedPtr<FWebInterfaceJSScripting> InScripting, const FGuid& InCallbackId)
  133. : ScriptingPtr(InScripting)
  134. , CallbackId(InCallbackId)
  135. {}
  136. void Invoke(int32 ArgCount, FWebInterfaceJSParam Arguments[], bool bIsError = false) const;
  137. private:
  138. TWeakPtr<FWebInterfaceJSScripting> ScriptingPtr;
  139. FGuid CallbackId;
  140. };
  141. /**
  142. * Representation of a remote JS function.
  143. * FWebJSFunction objects represent a JS function and allow calling them from native code.
  144. * FWebJSFunction objects can also be added to delegates and events using the Bind/AddLambda method.
  145. */
  146. USTRUCT()
  147. struct WEBBROWSERUI_API FWebInterfaceJSFunction
  148. : public FWebInterfaceJSCallbackBase
  149. {
  150. GENERATED_USTRUCT_BODY()
  151. FWebInterfaceJSFunction()
  152. : FWebInterfaceJSCallbackBase()
  153. {}
  154. FWebInterfaceJSFunction(TSharedPtr<FWebInterfaceJSScripting> InScripting, const FGuid& InFunctionId)
  155. : FWebInterfaceJSCallbackBase(InScripting, InFunctionId)
  156. {}
  157. template<typename ...ArgTypes> void operator()(ArgTypes... Args) const
  158. {
  159. FWebInterfaceJSParam ArgArray[sizeof...(Args)] = {FWebInterfaceJSParam(Args)...};
  160. Invoke(sizeof...(Args), ArgArray);
  161. }
  162. };
  163. /**
  164. * Representation of a remote JS async response object.
  165. * UFUNCTIONs taking a FWebJSResponse will get it passed in automatically when called from a web browser.
  166. * Pass a result or error back by invoking Success or Failure on the object.
  167. * UFunctions accepting a FWebJSResponse should have a void return type, as any value returned from the function will be ignored.
  168. * Calling the response methods does not have to happen before returning from the function, which means you can use this to implement asynchronous functionality.
  169. *
  170. * 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.
  171. */
  172. USTRUCT()
  173. struct WEBBROWSERUI_API FWebInterfaceJSResponse
  174. : public FWebInterfaceJSCallbackBase
  175. {
  176. GENERATED_USTRUCT_BODY()
  177. FWebInterfaceJSResponse()
  178. : FWebInterfaceJSCallbackBase()
  179. {}
  180. FWebInterfaceJSResponse(TSharedPtr<FWebInterfaceJSScripting> InScripting, const FGuid& InCallbackId)
  181. : FWebInterfaceJSCallbackBase(InScripting, InCallbackId)
  182. {}
  183. /**
  184. * Indicate successful completion without a return value.
  185. * The remote Promise's then() handler will be executed without arguments.
  186. */
  187. void Success() const
  188. {
  189. Invoke(0, nullptr, false);
  190. }
  191. /**
  192. * Indicate successful completion passing a return value back.
  193. * The remote Promise's then() handler will be executed with the value passed as its single argument.
  194. */
  195. template<typename T>
  196. void Success(T Arg) const
  197. {
  198. FWebInterfaceJSParam ArgArray[1] = {FWebInterfaceJSParam(Arg)};
  199. Invoke(1, ArgArray, false);
  200. }
  201. /**
  202. * Indicate failed completion, passing an error message back to JS.
  203. * The remote Promise's catch() handler will be executed with the value passed as the error reason.
  204. */
  205. template<typename T>
  206. void Failure(T Arg) const
  207. {
  208. FWebInterfaceJSParam ArgArray[1] = {FWebInterfaceJSParam(Arg)};
  209. Invoke(1, ArgArray, true);
  210. }
  211. };