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)
|
if (!typeHandle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const NetworkRpcName rpcName(typeHandle, GetCSharpCachedName(name));
|
|
||||||
|
|
||||||
NetworkRpcInfo rpcInfo;
|
NetworkRpcInfo rpcInfo;
|
||||||
rpcInfo.Server = isServer;
|
rpcInfo.Server = isServer;
|
||||||
rpcInfo.Client = isClient;
|
rpcInfo.Client = isClient;
|
||||||
@@ -698,6 +696,7 @@ void NetworkReplicator::AddRPC(const ScriptingTypeHandle& typeHandle, const Stri
|
|||||||
rpcInfo.Tag = (void*)*(SerializeFunc*)&execute;
|
rpcInfo.Tag = (void*)*(SerializeFunc*)&execute;
|
||||||
|
|
||||||
// Add to the global RPCs table
|
// Add to the global RPCs table
|
||||||
|
const NetworkRpcName rpcName(typeHandle, GetCSharpCachedName(name));
|
||||||
NetworkRpcInfo::RPCsTable[rpcName] = rpcInfo;
|
NetworkRpcInfo::RPCsTable[rpcName] = rpcInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,11 +1109,13 @@ NetworkStream* NetworkReplicator::BeginInvokeRPC()
|
|||||||
CachedWriteStream = New<NetworkStream>();
|
CachedWriteStream = New<NetworkStream>();
|
||||||
CachedWriteStream->Initialize();
|
CachedWriteStream->Initialize();
|
||||||
CachedWriteStream->SenderId = NetworkManager::LocalClientId;
|
CachedWriteStream->SenderId = NetworkManager::LocalClientId;
|
||||||
|
Scripting::ObjectsLookupIdMapping.Set(&IdsRemappingTable);
|
||||||
return CachedWriteStream;
|
return CachedWriteStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkReplicator::EndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, Span<uint32> targetIds)
|
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));
|
const NetworkRpcInfo* info = NetworkRpcInfo::RPCsTable.TryGet(NetworkRpcName(type, name));
|
||||||
if (!info || !obj || NetworkManager::IsOffline())
|
if (!info || !obj || NetworkManager::IsOffline())
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -279,6 +279,20 @@ namespace FlaxEngine
|
|||||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||||
public static partial Object FromUnmanagedPtr(IntPtr ptr);
|
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 />
|
/// <inheritdoc />
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "Engine/Content/Asset.h"
|
#include "Engine/Content/Asset.h"
|
||||||
#include "Engine/Content/Content.h"
|
#include "Engine/Content/Content.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
|
#include "Engine/Threading/ThreadLocal.h"
|
||||||
#include "ManagedCLR/MAssembly.h"
|
#include "ManagedCLR/MAssembly.h"
|
||||||
#include "ManagedCLR/MClass.h"
|
#include "ManagedCLR/MClass.h"
|
||||||
#include "ManagedCLR/MUtils.h"
|
#include "ManagedCLR/MUtils.h"
|
||||||
@@ -750,6 +751,20 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FromUnmanagedPtr(ScriptingObject*
|
|||||||
result = obj->GetOrCreateManagedInstance();
|
result = obj->GetOrCreateManagedInstance();
|
||||||
return result;
|
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
|
#endif
|
||||||
|
|
||||||
class ScriptingObjectInternal
|
class ScriptingObjectInternal
|
||||||
@@ -768,6 +783,8 @@ public:
|
|||||||
ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ChangeID", &ObjectInternal_ChangeID);
|
ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ChangeID", &ObjectInternal_ChangeID);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetUnmanagedInterface", &ObjectInternal_GetUnmanagedInterface);
|
ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetUnmanagedInterface", &ObjectInternal_GetUnmanagedInterface);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Object::FromUnmanagedPtr", &ObjectInternal_FromUnmanagedPtr);
|
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)
|
static ScriptingObject* Spawn(const ScriptingObjectSpawnParams& params)
|
||||||
|
|||||||
@@ -1460,12 +1460,13 @@ namespace Flax.Build.Plugins
|
|||||||
// Replicate ScriptingObject as Guid ID
|
// Replicate ScriptingObject as Guid ID
|
||||||
module.GetType("System.Guid", out var guidType);
|
module.GetType("System.Guid", out var guidType);
|
||||||
module.GetType("FlaxEngine.Object", out var scriptingObjectType);
|
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 (serialize)
|
||||||
{
|
{
|
||||||
if (il.IsRPC)
|
|
||||||
il.Emit(OpCodes.Ldloc, il.StreamLocalIndex);
|
|
||||||
else
|
|
||||||
il.Emit(OpCodes.Ldarg_1);
|
|
||||||
valueContext.Load(ref il);
|
valueContext.Load(ref il);
|
||||||
il.Emit(OpCodes.Dup);
|
il.Emit(OpCodes.Dup);
|
||||||
Instruction jmp1 = il.Create(OpCodes.Nop);
|
Instruction jmp1 = il.Create(OpCodes.Nop);
|
||||||
@@ -1477,15 +1478,18 @@ namespace Flax.Build.Plugins
|
|||||||
il.Emit(jmp1);
|
il.Emit(jmp1);
|
||||||
il.Emit(OpCodes.Call, module.ImportReference(scriptingObjectType.Resolve().GetMethod("get_ID")));
|
il.Emit(OpCodes.Call, module.ImportReference(scriptingObjectType.Resolve().GetMethod("get_ID")));
|
||||||
il.Emit(jmp2);
|
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")));
|
il.Emit(OpCodes.Callvirt, module.ImportReference(networkStreamType.GetMethod("WriteGuid")));
|
||||||
}
|
}
|
||||||
else
|
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);
|
module.GetType("System.Type", out var typeType);
|
||||||
if (il.IsRPC)
|
if (il.IsRPC)
|
||||||
il.Emit(OpCodes.Ldloc_1);
|
il.Emit(OpCodes.Ldloc_1);
|
||||||
@@ -1493,6 +1497,8 @@ namespace Flax.Build.Plugins
|
|||||||
il.Emit(OpCodes.Ldarg_1);
|
il.Emit(OpCodes.Ldarg_1);
|
||||||
il.Emit(OpCodes.Callvirt, module.ImportReference(networkStreamType.GetMethod("ReadGuid")));
|
il.Emit(OpCodes.Callvirt, module.ImportReference(networkStreamType.GetMethod("ReadGuid")));
|
||||||
il.Emit(OpCodes.Stloc_S, (byte)varStart);
|
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.Ldloca_S, (byte)varStart);
|
||||||
il.Emit(OpCodes.Ldtoken, valueContext.ValueType);
|
il.Emit(OpCodes.Ldtoken, valueContext.ValueType);
|
||||||
il.Emit(OpCodes.Call, module.ImportReference(typeType.Resolve().GetMethod("GetTypeFromHandle")));
|
il.Emit(OpCodes.Call, module.ImportReference(typeType.Resolve().GetMethod("GetTypeFromHandle")));
|
||||||
|
|||||||
Reference in New Issue
Block a user