public static GhostComponentAttribute GetGhostComponentAttribute(Mono.Cecil.TypeDefinition managedType) { var attribute = managedType.GetAttribute <GhostComponentAttribute>(); if (attribute != null) { var ghostAttribute = new GhostComponentAttribute(); if (attribute.HasProperties) { foreach (var a in attribute.Properties) { typeof(GhostComponentAttribute).GetProperty(a.Name)?.SetValue(ghostAttribute, a.Argument.Value); } } return(ghostAttribute); } return(null); }
public static GhostComponentAttribute GetGhostComponentAttribute(Mono.Cecil.TypeDefinition managedType) { if (GhostAuthoringComponentEditor.GhostDefaultOverrides.TryGetValue(managedType.FullName.Replace('/', '+'), out var newComponent)) { return(newComponent.attribute); } var attribute = managedType.GetAttribute <GhostComponentAttribute>(); if (attribute != null) { var ghostAttribute = new GhostComponentAttribute(); if (attribute.HasProperties) { foreach (var a in attribute.Properties) { typeof(GhostComponentAttribute).GetProperty(a.Name)?.SetValue(ghostAttribute, a.Argument.Value); } } return(ghostAttribute); } return(null); }
public GhostComponentGenType(TypeDefinition typeDefinition, CodeGenService.GhostComponent config = null) : base( typeDefinition, config) { templateFilePath = CodeGenServiceEditor.GhostComponentSerializerPath; GhostComponentAttribute ghostComponentAttribute = null; if (config != null) { ghostComponentAttribute = config.Attribute; } else { ghostComponentAttribute = CecilExtensions.GetGhostComponentAttribute(typeDefinition); } if (ghostComponentAttribute == null) { Debug.LogError(typeDefinition.FullName); } templateArgs.IsUpdateValue = ghostComponentAttribute.IsUpdateValue ? "true" : "false"; templateArgs.SendType = ghostComponentAttribute.SendType.ToString(); templateArgs.Fields = new List <FieldT4Info>(); foreach (var fieldDefinition in typeDefinition.Fields) { if (!fieldDefinition.FieldType.IsValueType || fieldDefinition.Name.StartsWith("<")) { continue; } bool isGhostField = fieldDefinition.IsGhostField(); CodeGenService.GhostComponentField field = null; if (config != null) { field = config.Fields.FirstOrDefault(f => f.Name == fieldDefinition.Name); isGhostField = field != null; } if (!isGhostField) { continue; } GhostFieldAttribute attr = null; if (field != null) { attr = field.Attribute; } else { attr = CecilExtensions.GetGhostFieldAttribute(typeDefinition, fieldDefinition); } TypeReference fieldType = fieldDefinition.FieldType; string type = ConvertBaseValueType(fieldType.Name); templateArgs.Fields.Add(new FieldT4Info { Name = fieldDefinition.Name, TypeName = type, TypeName1 = ToUpper(type), Interpolate = attr.Interpolate, SendData = attr.SendData, InterpolateMethodStr = GetInterpolateMethodStr(type) }); } }
public void GenerateSerializer(CodeGenerator.Context context, Mono.Cecil.TypeDefinition generatorType, Mono.Cecil.TypeDefinition componentType, GhostComponentAttribute ghostAttributes) { var replacements = new Dictionary <string, string>(); if (context.FieldState.curChangeMask > 0) { replacements.Add("GHOST_CHANGE_MASK_BITS", context.FieldState.curChangeMask.ToString()); m_TargetGenerator.GenerateFragment("GHOST_FLUSH_FINAL_COMPONENT_CHANGE_MASK", replacements); } if (componentType.Namespace != null && componentType.Namespace != "") { context.imports.Add(componentType.Namespace); } foreach (var ns in context.imports) { replacements["GHOST_USING"] = CodeGenNamespaceUtils.GetValidNamespaceForType(context.generatedNs, ns); m_TargetGenerator.GenerateFragment("GHOST_USING_STATEMENT", replacements); } context.collectionAssemblies.Add(componentType.Module.Assembly.Name.Name); if (generatorType != componentType) { context.collectionAssemblies.Add(generatorType.Module.Assembly.Name.Name); } replacements.Clear(); replacements.Add("GHOST_NAME", generatorType.FullName.Replace(".", "").Replace("/", "_")); replacements.Add("GHOST_NAMESPACE", context.generatedNs); replacements.Add("GHOST_COMPONENT_TYPE", componentType.FullName.Replace("/", ".")); replacements.Add("GHOST_CHANGE_MASK_BITS", context.FieldState.numFields.ToString()); replacements.Add("GHOST_FIELD_HASH", context.FieldState.ghostfieldHash.ToString()); replacements.Add("GHOST_COMPONENT_EXCLUDE_FROM_COLLECTION_HASH", context.IsRuntimeAssembly ? "0" : "1"); replacements.Add("GHOST_VARIANT_HASH", context.VariantHash.ToString()); if (ghostAttributes != null) { if (ghostAttributes.OwnerPredictedSendType == GhostSendType.Interpolated || (ghostAttributes.PrefabType & GhostPrefabType.Client) == GhostPrefabType.InterpolatedClient) { replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Interpolated"); } else if (ghostAttributes.OwnerPredictedSendType == GhostSendType.Predicted || (ghostAttributes.PrefabType & GhostPrefabType.Client) == GhostPrefabType.PredictedClient) { replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Predicted"); } else if (ghostAttributes.PrefabType == GhostPrefabType.Server) { replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.None"); } else { replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Interpolated | GhostComponentSerializer.SendMask.Predicted"); } replacements.Add("GHOST_SEND_CHILD_ENTITY", ghostAttributes.SendDataForChildEntity?"1":"0"); var ownerType = ghostAttributes.OwnerSendType; if (componentType.IsICommandData() && (ghostAttributes.OwnerSendType & SendToOwnerType.SendToOwner) != 0) { UnityEngine.Debug.LogError($"ICommandData {componentType.FullName} is configured to be sent to ghost owner. It will be ignored"); ownerType &= ~SendToOwnerType.SendToOwner; } replacements.Add("GHOST_SEND_OWNER", "SendToOwnerType." + ownerType); } else if (!componentType.IsICommandData()) { replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Interpolated | GhostComponentSerializer.SendMask.Predicted"); replacements.Add("GHOST_SEND_OWNER", "SendToOwnerType.All"); replacements.Add("GHOST_SEND_CHILD_ENTITY", "1"); } else { replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Predicted"); replacements.Add("GHOST_SEND_OWNER", "SendToOwnerType.SendToNonOwner"); replacements.Add("GHOST_SEND_CHILD_ENTITY", "0"); } if (componentType.IsBufferElementData()) { m_TargetGenerator.GenerateFragment("GHOST_COPY_FROM_BUFFER", replacements, m_TargetGenerator, "COPY_FROM_SNAPSHOT_SETUP"); } else { m_TargetGenerator.GenerateFragment("GHOST_COPY_FROM_COMPONENT", replacements, m_TargetGenerator, "COPY_FROM_SNAPSHOT_SETUP"); } if (m_TargetGenerator.Fragments["__GHOST_REPORT_PREDICTION_ERROR__"].Content.Length > 0) { m_TargetGenerator.GenerateFragment("GHOST_PREDICTION_ERROR_HEADER", replacements, m_TargetGenerator); } var serializerName = generatorType.FullName.Replace("/", "+") + "Serializer.cs"; m_TargetGenerator.GenerateFile("", context.outputFolder, serializerName, replacements, context.batch); context.generatedTypes.Add(replacements["GHOST_NAME"]); }