123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- // Engine/Source/Runtime/WebBrowser/Private/WebJSScripting.h
- #pragma once
- #include "CoreMinimal.h"
- #include "Misc/Guid.h"
- #include "WebInterfaceJSFunction.h"
- #include "UObject/GCObject.h"
- class Error;
- /**
- * Implements handling of bridging UObjects client side with JavaScript renderer side.
- */
- class FWebInterfaceJSScripting
- : public FGCObject
- {
- public:
- FWebInterfaceJSScripting(bool bInJSBindingToLoweringEnabled)
- : BaseGuid(FGuid::NewGuid())
- , bJSBindingToLoweringEnabled(bInJSBindingToLoweringEnabled)
- {}
- virtual void BindUObject(const FString& Name, UObject* Object, bool bIsPermanent = true) =0;
- virtual void UnbindUObject(const FString& Name, UObject* Object = nullptr, bool bIsPermanent = true) =0;
- virtual void InvokeJSFunction(FGuid FunctionId, int32 ArgCount, FWebInterfaceJSParam Arguments[], bool bIsError=false) =0;
- virtual void InvokeJSErrorResult(FGuid FunctionId, const FString& Error) =0;
- FString GetBindingName(const FString& Name, UObject* Object) const
- {
- return bJSBindingToLoweringEnabled ? Name.ToLower() : Name;
- }
- FString GetBindingName(const FFieldVariant& Property) const
- {
- return bJSBindingToLoweringEnabled ? Property.GetName().ToLower() : Property.GetName();
- }
- public:
- // FGCObject API
- virtual void AddReferencedObjects( FReferenceCollector& Collector ) override
- {
- // Ensure bound UObjects are not garbage collected as long as this object is valid.
- for (auto& Binding : BoundObjects)
- {
- Collector.AddReferencedObject(Binding.Key);
- }
- }
- virtual FString GetReferencerName() const override
- {
- return TEXT("FWebInterfaceJSScripting");
- }
- protected:
- // Creates a reversible memory addres -> psuedo-guid mapping.
- // This is done by xoring the address with the first 64 bits of a base guid owned by the instance.
- // Used to identify UObjects from the render process withough exposing internal pointers.
- FGuid PtrToGuid(UObject* Ptr)
- {
- FGuid Guid = BaseGuid;
- if (Ptr == nullptr)
- {
- Guid.Invalidate();
- }
- else
- {
- UPTRINT IntPtr = reinterpret_cast<UPTRINT>(Ptr);
- if (sizeof(UPTRINT) > 4)
- {
- Guid[0] ^= (static_cast<uint64>(IntPtr) >> 32);
- }
- Guid[1] ^= IntPtr & 0xFFFFFFFF;
- }
- return Guid;
- }
- // In addition to reversing the mapping, it verifies that we are currently holding on to an instance of that UObject
- UObject* GuidToPtr(const FGuid& Guid)
- {
- UPTRINT IntPtr = 0;
- if (sizeof(UPTRINT) > 4)
- {
- IntPtr = static_cast<UPTRINT>(static_cast<uint64>(Guid[0] ^ BaseGuid[0]) << 32);
- }
- IntPtr |= (Guid[1] ^ BaseGuid[1]) & 0xFFFFFFFF;
- UObject* Result = reinterpret_cast<UObject*>(IntPtr);
- if (BoundObjects.Contains(Result))
- {
- return Result;
- }
- else
- {
- return nullptr;
- }
- }
- void RetainBinding(UObject* Object)
- {
- if (BoundObjects.Contains(Object))
- {
- if(!BoundObjects[Object].bIsPermanent)
- {
- BoundObjects[Object].Refcount++;
- }
- }
- else
- {
- BoundObjects.Add(Object, {false, 1});
- }
- }
- void ReleaseBinding(UObject* Object)
- {
- if (BoundObjects.Contains(Object))
- {
- auto& Binding = BoundObjects[Object];
- if(!Binding.bIsPermanent)
- {
- Binding.Refcount--;
- if (Binding.Refcount <= 0)
- {
- BoundObjects.Remove(Object);
- }
- }
- }
- }
- struct ObjectBinding
- {
- bool bIsPermanent;
- int32 Refcount;
- };
- /** Private data */
- FGuid BaseGuid;
- /** UObjects currently visible on the renderer side. */
- TMap<UObject*, ObjectBinding> BoundObjects;
- /** Reverse lookup for permanent bindings */
- TMap<FString, UObject*> PermanentUObjectsByName;
- /** The to-lowering option enable for the binding names. */
- const bool bJSBindingToLoweringEnabled;
- };
|