Example #1
0
        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);
        }
Example #3
0
        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"]);
        }