Skip to content

Commit 35935e8

Browse files
0xFA11wackoisgodandrews-unity
authored
Implement RFC #1: Standard RPC to replace Convenience and Performance RPCs (#408)
* initial chunk * implement rpc params and reliability, refactor ILPP * rename rpc attributes and update xmldoc * implement unity diagnostics error messages * fix yamato build (using var syntax is not supported by the compiler) * fix: Fixing an issue with latest trunk and ILPP - Fixed an issue where on latest 21.1 you could not build ILPP without some PrivateCorelib issues - Removed UTP package as it causes issues with burst and ILPP that needs to be resolved at some future point - Updated Burst to latest 1.43 and Mono to 1.10.1-preview.1 (this is the legit package not the shim package) All this is compat back to 2018.4 * fix: Make codegen great again. Fixed some resolver issues on linux and moved some core around to be more clean and consistent. * minor refactor * remove convenience and performance RPC implementations alonside with other related types and implementations * bump yamato editor version from 2020.1 to 2020.2 * minor update Co-authored-by: Andrew Spiering <aspiering@gmail.com> Co-authored-by: Andrew Spiering <andrews@unity3d.com>
1 parent 03e6018 commit 35935e8

File tree

72 files changed

+2675
-4970
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2675
-4970
lines changed

.yamato/project.metafile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Editors where tests will happen. The first entry of this array is also used
22
# for validation
33
test_editors:
4-
- 2020.1
4+
- 2020.2
55
- trunk
66

77
# Platforms that will be tested. The first entry in this array will also

com.unity.multiplayer.mlapi/Runtime/Core/RPCMethods.meta renamed to com.unity.multiplayer.mlapi/Editor/CodeGen.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using MLAPI.Messaging;
7+
using MLAPI.Serialization;
8+
using Mono.Cecil;
9+
using Mono.Cecil.Cil;
10+
using Mono.Cecil.Rocks;
11+
using Unity.CompilationPipeline.Common.Diagnostics;
12+
using Unity.CompilationPipeline.Common.ILPostProcessing;
13+
using UnityEngine;
14+
15+
namespace MLAPI.Editor.CodeGen
16+
{
17+
internal static class CodeGenHelpers
18+
{
19+
public const string RuntimeAssemblyName = "Unity.Multiplayer.MLAPI.Runtime";
20+
21+
public static readonly string NetworkBehaviour_FullName = typeof(NetworkedBehaviour).FullName;
22+
public static readonly string ServerRpcAttribute_FullName = typeof(ServerRpcAttribute).FullName;
23+
public static readonly string ClientRpcAttribute_FullName = typeof(ClientRpcAttribute).FullName;
24+
public static readonly string ServerRpcParams_FullName = typeof(ServerRpcParams).FullName;
25+
public static readonly string ClientRpcParams_FullName = typeof(ClientRpcParams).FullName;
26+
public static readonly string INetworkSerializable_FullName = typeof(INetworkSerializable).FullName;
27+
public static readonly string INetworkSerializable_NetworkRead_Name = nameof(INetworkSerializable.NetworkRead);
28+
public static readonly string INetworkSerializable_NetworkWrite_Name = nameof(INetworkSerializable.NetworkWrite);
29+
public static readonly string UnityColor_FullName = typeof(Color).FullName;
30+
public static readonly string UnityVector2_FullName = typeof(Vector2).FullName;
31+
public static readonly string UnityVector3_FullName = typeof(Vector3).FullName;
32+
public static readonly string UnityVector4_FullName = typeof(Vector4).FullName;
33+
public static readonly string UnityQuaternion_FullName = typeof(Quaternion).FullName;
34+
public static readonly string UnityRay_FullName = typeof(Ray).FullName;
35+
public static readonly string UnityRay2D_FullName = typeof(Ray2D).FullName;
36+
37+
public static uint Hash(this MethodDefinition methodDefinition)
38+
{
39+
var sigArr = Encoding.UTF8.GetBytes($"{methodDefinition.Module.Name} / {methodDefinition.FullName}");
40+
var sigLen = sigArr.Length;
41+
unsafe
42+
{
43+
fixed (byte* sigPtr = sigArr)
44+
{
45+
return XXHash.Hash32(sigPtr, sigLen);
46+
}
47+
}
48+
}
49+
50+
public static bool IsSubclassOf(this TypeDefinition typeDefinition, string ClassTypeFullName)
51+
{
52+
if (!typeDefinition.IsClass) return false;
53+
54+
var baseTypeRef = typeDefinition.BaseType;
55+
while (baseTypeRef != null)
56+
{
57+
if (baseTypeRef.FullName == ClassTypeFullName)
58+
{
59+
return true;
60+
}
61+
62+
try
63+
{
64+
baseTypeRef = baseTypeRef.Resolve().BaseType;
65+
}
66+
catch
67+
{
68+
return false;
69+
}
70+
}
71+
72+
return false;
73+
}
74+
75+
public static bool HasInterface(this TypeReference typeReference, string InterfaceTypeFullName)
76+
{
77+
try
78+
{
79+
var typeDef = typeReference.Resolve();
80+
var typeFaces = typeDef.Interfaces;
81+
return typeFaces.Any(iface => iface.InterfaceType.FullName == InterfaceTypeFullName);
82+
}
83+
catch
84+
{
85+
}
86+
87+
return false;
88+
}
89+
90+
public static bool IsSupportedType(this TypeReference typeReference)
91+
{
92+
var typeSystem = typeReference.Module.TypeSystem;
93+
94+
// common primitives
95+
if (typeReference == typeSystem.Boolean) return true;
96+
if (typeReference == typeSystem.Char) return true;
97+
if (typeReference == typeSystem.SByte) return true;
98+
if (typeReference == typeSystem.Byte) return true;
99+
if (typeReference == typeSystem.Int16) return true;
100+
if (typeReference == typeSystem.UInt16) return true;
101+
if (typeReference == typeSystem.Int32) return true;
102+
if (typeReference == typeSystem.UInt32) return true;
103+
if (typeReference == typeSystem.Int64) return true;
104+
if (typeReference == typeSystem.UInt64) return true;
105+
if (typeReference == typeSystem.Single) return true;
106+
if (typeReference == typeSystem.Double) return true;
107+
if (typeReference == typeSystem.String) return true;
108+
109+
// Unity primitives
110+
if (typeReference.FullName == UnityColor_FullName) return true;
111+
if (typeReference.FullName == UnityVector2_FullName) return true;
112+
if (typeReference.FullName == UnityVector3_FullName) return true;
113+
if (typeReference.FullName == UnityVector4_FullName) return true;
114+
if (typeReference.FullName == UnityQuaternion_FullName) return true;
115+
if (typeReference.FullName == UnityRay_FullName) return true;
116+
if (typeReference.FullName == UnityRay2D_FullName) return true;
117+
118+
// INetworkSerializable
119+
if (typeReference.HasInterface(INetworkSerializable_FullName)) return true;
120+
121+
// Enum
122+
if (typeReference.GetEnumAsInt() != null) return true;
123+
124+
// todo: [RFC] Serializable Types
125+
// StaticArray[]
126+
// IEnumerable<T>
127+
// IEnumerable<KeyValuePair<K, V>>
128+
// IEnumerable<Tuple<T1, T2, T3...T7>>
129+
// IEnumerable<Tuple<T1, T2...TRest>>
130+
131+
return false;
132+
}
133+
134+
public static TypeReference GetEnumAsInt(this TypeReference typeReference)
135+
{
136+
try
137+
{
138+
var typeDef = typeReference.Resolve();
139+
if (typeDef.IsEnum)
140+
{
141+
return typeDef.GetEnumUnderlyingType();
142+
}
143+
}
144+
catch
145+
{
146+
}
147+
148+
return null;
149+
}
150+
151+
public static void AddError(this List<DiagnosticMessage> diagnostics, string message)
152+
{
153+
diagnostics.AddError((SequencePoint)null, message);
154+
}
155+
156+
public static void AddError(this List<DiagnosticMessage> diagnostics, MethodDefinition methodDefinition, string message)
157+
{
158+
diagnostics.AddError(methodDefinition.DebugInformation.SequencePoints.FirstOrDefault(), message);
159+
}
160+
161+
public static void AddError(this List<DiagnosticMessage> diagnostics, SequencePoint sequencePoint, string message)
162+
{
163+
diagnostics.Add(new DiagnosticMessage
164+
{
165+
DiagnosticType = DiagnosticType.Error,
166+
File = sequencePoint?.Document.Url.Replace($"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}", ""),
167+
Line = sequencePoint?.StartLine ?? 0,
168+
Column = sequencePoint?.StartColumn ?? 0,
169+
MessageData = $" - {message}"
170+
});
171+
}
172+
173+
public static AssemblyDefinition AssemblyDefinitionFor(ICompiledAssembly compiledAssembly)
174+
{
175+
var assemblyResolver = new PostProcessorAssemblyResolver(compiledAssembly);
176+
var readerParameters = new ReaderParameters
177+
{
178+
SymbolStream = new MemoryStream(compiledAssembly.InMemoryAssembly.PdbData),
179+
SymbolReaderProvider = new PortablePdbReaderProvider(),
180+
AssemblyResolver = assemblyResolver,
181+
ReflectionImporterProvider = new PostProcessorReflectionImporterProvider(),
182+
ReadingMode = ReadingMode.Immediate
183+
};
184+
185+
var assemblyDefinition = AssemblyDefinition.ReadAssembly(new MemoryStream(compiledAssembly.InMemoryAssembly.PeData), readerParameters);
186+
187+
//apparently, it will happen that when we ask to resolve a type that lives inside MLAPI.Runtime, and we
188+
//are also postprocessing MLAPI.Runtime, type resolving will fail, because we do not actually try to resolve
189+
//inside the assembly we are processing. Let's make sure we do that, so that we can use postprocessor features inside
190+
//MLAPI.Runtime itself as well.
191+
assemblyResolver.AddAssemblyDefinitionBeingOperatedOn(assemblyDefinition);
192+
193+
return assemblyDefinition;
194+
}
195+
}
196+
}
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)