Add objects ID inverse mapping from client to server for proper C# networking codegen
This commit is contained in:
@@ -687,8 +687,6 @@ void NetworkReplicator::AddRPC(const ScriptingTypeHandle& typeHandle, const Stri
|
||||
if (!typeHandle)
|
||||
return;
|
||||
|
||||
const NetworkRpcName rpcName(typeHandle, GetCSharpCachedName(name));
|
||||
|
||||
NetworkRpcInfo rpcInfo;
|
||||
rpcInfo.Server = isServer;
|
||||
rpcInfo.Client = isClient;
|
||||
@@ -698,6 +696,7 @@ void NetworkReplicator::AddRPC(const ScriptingTypeHandle& typeHandle, const Stri
|
||||
rpcInfo.Tag = (void*)*(SerializeFunc*)&execute;
|
||||
|
||||
// Add to the global RPCs table
|
||||
const NetworkRpcName rpcName(typeHandle, GetCSharpCachedName(name));
|
||||
NetworkRpcInfo::RPCsTable[rpcName] = rpcInfo;
|
||||
}
|
||||
|
||||
@@ -1110,11 +1109,13 @@ NetworkStream* NetworkReplicator::BeginInvokeRPC()
|
||||
CachedWriteStream = New<NetworkStream>();
|
||||
CachedWriteStream->Initialize();
|
||||
CachedWriteStream->SenderId = NetworkManager::LocalClientId;
|
||||
Scripting::ObjectsLookupIdMapping.Set(&IdsRemappingTable);
|
||||
return CachedWriteStream;
|
||||
}
|
||||
|
||||
void NetworkReplicator::EndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, Span<uint32> targetIds)
|
||||
{
|
||||
Scripting::ObjectsLookupIdMapping.Set(nullptr);
|
||||
const NetworkRpcInfo* info = NetworkRpcInfo::RPCsTable.TryGet(NetworkRpcName(type, name));
|
||||
if (!info || !obj || NetworkManager::IsOffline())
|
||||
return;
|
||||
|
||||
@@ -279,6 +279,20 @@ namespace FlaxEngine
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
public static partial Object FromUnmanagedPtr(IntPtr ptr);
|
||||
|
||||
/// <summary>
|
||||
/// Maps the object ID using the current Scripting::ObjectsLookupIdMapping (key to value). Used to map prefab object IDs into prefab instance object IDs, or when using network replication IDs table.
|
||||
/// </summary>
|
||||
/// <param name="id">Inout object identifier mapped as a result or unchanged if not mapped.</param>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_MapObjectID")]
|
||||
public static partial void MapObjectID(ref Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Remaps the object ID using the current Scripting::ObjectsLookupIdMapping (value to key). Used to remap prefab instance IDs into prefab object IDs, or when using network replication IDs table.
|
||||
/// </summary>
|
||||
/// <param name="id">Inout object identifier mapped as a result or unchanged if not mapped.</param>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_RemapObjectID")]
|
||||
public static partial void RemapObjectID(ref Guid id);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Engine/Content/Asset.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Threading/ThreadLocal.h"
|
||||
#include "ManagedCLR/MAssembly.h"
|
||||
#include "ManagedCLR/MClass.h"
|
||||
#include "ManagedCLR/MUtils.h"
|
||||
@@ -750,6 +751,20 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FromUnmanagedPtr(ScriptingObject*
|
||||
result = obj->GetOrCreateManagedInstance();
|
||||
return result;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) ObjectInternal_MapObjectID(Guid* id)
|
||||
{
|
||||
const auto idsMapping = Scripting::ObjectsLookupIdMapping.Get();
|
||||
if (idsMapping && id->IsValid())
|
||||
idsMapping->TryGet(*id, *id);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) ObjectInternal_RemapObjectID(Guid* id)
|
||||
{
|
||||
const auto idsMapping = Scripting::ObjectsLookupIdMapping.Get();
|
||||
if (idsMapping && id->IsValid())
|
||||
idsMapping->KeyOf(*id, id);
|
||||
}
|
||||
#endif
|
||||
|
||||
class ScriptingObjectInternal
|
||||
@@ -768,6 +783,8 @@ public:
|
||||
ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ChangeID", &ObjectInternal_ChangeID);
|
||||
ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetUnmanagedInterface", &ObjectInternal_GetUnmanagedInterface);
|
||||
ADD_INTERNAL_CALL("FlaxEngine.Object::FromUnmanagedPtr", &ObjectInternal_FromUnmanagedPtr);
|
||||
ADD_INTERNAL_CALL("FlaxEngine.Object::MapObjectID", &ObjectInternal_MapObjectID);
|
||||
ADD_INTERNAL_CALL("FlaxEngine.Object::RemapObjectID", &ObjectInternal_RemapObjectID);
|
||||
}
|
||||
|
||||
static ScriptingObject* Spawn(const ScriptingObjectSpawnParams& params)
|
||||
|
||||
@@ -1460,12 +1460,13 @@ namespace Flax.Build.Plugins
|
||||
// Replicate ScriptingObject as Guid ID
|
||||
module.GetType("System.Guid", out var guidType);
|
||||
module.GetType("FlaxEngine.Object", out var scriptingObjectType);
|
||||
var varStart = il.Variables.Count;
|
||||
var reference = module.ImportReference(guidType);
|
||||
reference.IsValueType = true; // Fix locals init to have valuetype for Guid instead of class
|
||||
il.Variables.Add(new VariableDefinition(reference));
|
||||
il.InitLocals = true;
|
||||
if (serialize)
|
||||
{
|
||||
if (il.IsRPC)
|
||||
il.Emit(OpCodes.Ldloc, il.StreamLocalIndex);
|
||||
else
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
valueContext.Load(ref il);
|
||||
il.Emit(OpCodes.Dup);
|
||||
Instruction jmp1 = il.Create(OpCodes.Nop);
|
||||
@@ -1477,15 +1478,18 @@ namespace Flax.Build.Plugins
|
||||
il.Emit(jmp1);
|
||||
il.Emit(OpCodes.Call, module.ImportReference(scriptingObjectType.Resolve().GetMethod("get_ID")));
|
||||
il.Emit(jmp2);
|
||||
il.Emit(OpCodes.Stloc, varStart);
|
||||
il.Emit(OpCodes.Ldloca_S, (byte)varStart);
|
||||
il.Emit(OpCodes.Call, module.ImportReference(scriptingObjectType.Resolve().GetMethod("RemapObjectID", 1)));
|
||||
if (il.IsRPC)
|
||||
il.Emit(OpCodes.Ldloc, il.StreamLocalIndex);
|
||||
else
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldloc, varStart);
|
||||
il.Emit(OpCodes.Callvirt, module.ImportReference(networkStreamType.GetMethod("WriteGuid")));
|
||||
}
|
||||
else
|
||||
{
|
||||
var varStart = il.Variables.Count;
|
||||
var reference = module.ImportReference(guidType);
|
||||
reference.IsValueType = true; // Fix locals init to have valuetype for Guid instead of class
|
||||
il.Variables.Add(new VariableDefinition(reference));
|
||||
il.InitLocals = true;
|
||||
module.GetType("System.Type", out var typeType);
|
||||
if (il.IsRPC)
|
||||
il.Emit(OpCodes.Ldloc_1);
|
||||
@@ -1493,6 +1497,8 @@ namespace Flax.Build.Plugins
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Callvirt, module.ImportReference(networkStreamType.GetMethod("ReadGuid")));
|
||||
il.Emit(OpCodes.Stloc_S, (byte)varStart);
|
||||
if (valueContext.Field != null)
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldloca_S, (byte)varStart);
|
||||
il.Emit(OpCodes.Ldtoken, valueContext.ValueType);
|
||||
il.Emit(OpCodes.Call, module.ImportReference(typeType.Resolve().GetMethod("GetTypeFromHandle")));
|
||||
|
||||
Reference in New Issue
Block a user