Fix crash when implementing INetworkSerializable in C#-only

#1664
This commit is contained in:
Wojtek Figat
2023-10-11 18:39:51 +02:00
parent 8f3a5bd74a
commit fa96707c57
2 changed files with 39 additions and 10 deletions

View File

@@ -258,18 +258,32 @@ void NetworkReplicationService::Dispose()
NetworkReplicationService NetworkReplicationServiceInstance;
void INetworkSerializable_Serialize(void* instance, NetworkStream* stream, void* tag)
void INetworkSerializable_Native_Serialize(void* instance, NetworkStream* stream, void* tag)
{
const int16 vtableOffset = (int16)(intptr)tag;
((INetworkSerializable*)((byte*)instance + vtableOffset))->Serialize(stream);
}
void INetworkSerializable_Deserialize(void* instance, NetworkStream* stream, void* tag)
void INetworkSerializable_Native_Deserialize(void* instance, NetworkStream* stream, void* tag)
{
const int16 vtableOffset = (int16)(intptr)tag;
((INetworkSerializable*)((byte*)instance + vtableOffset))->Deserialize(stream);
}
void INetworkSerializable_Script_Serialize(void* instance, NetworkStream* stream, void* tag)
{
auto obj = (ScriptingObject*)instance;
auto interface = ScriptingObject::ToInterface<INetworkSerializable>(obj);
interface->Serialize(stream);
}
void INetworkSerializable_Script_Deserialize(void* instance, NetworkStream* stream, void* tag)
{
auto obj = (ScriptingObject*)instance;
auto interface = ScriptingObject::ToInterface<INetworkSerializable>(obj);
interface->Deserialize(stream);
}
NetworkReplicatedObject* ResolveObject(Guid objectId)
{
auto it = Objects.Find(objectId);
@@ -1064,9 +1078,21 @@ bool NetworkReplicator::InvokeSerializer(const ScriptingTypeHandle& typeHandle,
const ScriptingType::InterfaceImplementation* interface = type.GetInterface(INetworkSerializable::TypeInitializer);
if (interface)
{
serializer.Methods[0] = INetworkSerializable_Serialize;
serializer.Methods[1] = INetworkSerializable_Deserialize;
serializer.Tags[0] = serializer.Tags[1] = (void*)(intptr)interface->VTableOffset; // Pass VTableOffset to the callback
if (interface->IsNative)
{
// Native interface (implemented in C++)
serializer.Methods[0] = INetworkSerializable_Native_Serialize;
serializer.Methods[1] = INetworkSerializable_Native_Deserialize;
serializer.Tags[0] = serializer.Tags[1] = (void*)(intptr)interface->VTableOffset; // Pass VTableOffset to the callback
}
else
{
// Generic interface (implemented in C# or elsewhere)
ASSERT(type.Type == ScriptingTypes::Script);
serializer.Methods[0] = INetworkSerializable_Script_Serialize;
serializer.Methods[1] = INetworkSerializable_Script_Deserialize;
serializer.Tags[0] = serializer.Tags[1] = nullptr;
}
SerializersTable.Add(typeHandle, serializer);
}
else if (const ScriptingTypeHandle baseTypeHandle = typeHandle.GetType().GetBaseType())