public GhostCodeGen.Batch Generate(string outputFolder, string assemblyGeneratedName, string assemblyName,
                                           bool isRuntimeAssembly, IEnumerable <Mono.Cecil.TypeDefinition> validTypes, IEnumerable <Mono.Cecil.TypeDefinition> commandTypes,
                                           Dictionary <string, GhostCodeGen> codeGenCache)
        {
            var context = new Context(assemblyName,
                                      CodeGenNamespaceUtils.GenerateNamespaceFromAssemblyName(assemblyGeneratedName),
                                      isRuntimeAssembly,
                                      outputFolder,
                                      codeGenCache);

            // generate ghost types
            foreach (var type in validTypes)
            {
                context.ResetState();
                GenerateType(context, type);
            }
            // generate registration system
            GenerateRegistrationSystem(context);

            //Generate Rpcs
            foreach (var type in commandTypes)
            {
                context.ResetState();
                GenerateCommand(context, type);
            }


            // generate asmdef
            GenerateAsmDefs(context, assemblyGeneratedName);
            return(context.batch);
        }
Ejemplo n.º 2
0
        public void GenerateSerializer(CodeGenerator.Context context, Mono.Cecil.TypeDefinition type)
        {
            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 (type.Namespace != null && type.Namespace != "")
            {
                context.imports.Add(type.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(type.Module.Assembly.Name.Name);

            replacements.Clear();
            replacements.Add("GHOST_NAME", type.FullName.Replace(".", "").Replace("/", "_"));
            replacements.Add("GHOST_NAMESPACE", context.generatedNs);
            replacements.Add("GHOST_COMPONENT_TYPE", type.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");

            var ghostAttributes = CecilExtensions.GetGhostComponentAttribute(type);

            if (ghostAttributes != null && (ghostAttributes.OwnerPredictedSendType == GhostSendType.Interpolated || (ghostAttributes.PrefabType & GhostPrefabType.Client) == GhostPrefabType.InterpolatedClient))
            {
                replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Interpolated");
            }
            else if (ghostAttributes != null && (ghostAttributes.OwnerPredictedSendType == GhostSendType.Predicted || (ghostAttributes.PrefabType & GhostPrefabType.Client) == GhostPrefabType.PredictedClient))
            {
                replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Predicted");
            }
            else
            {
                replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Interpolated | GhostComponentSerializer.SendMask.Predicted");
            }
            replacements.Add("GHOST_SEND_CHILD_ENTITY", (ghostAttributes != null && !ghostAttributes.SendDataForChildEntity)?"0":"1");

            if (m_TargetGenerator.Fragments["__GHOST_REPORT_PREDICTION_ERROR__"].Content.Length > 0)
            {
                m_TargetGenerator.GenerateFragment("GHOST_PREDICTION_ERROR_HEADER", replacements, m_TargetGenerator);
            }

            var serializerName = type.FullName.Replace("/", "+") + "Serializer.cs";

            m_TargetGenerator.GenerateFile("", context.outputFolder, serializerName, replacements, context.batch);

            context.generatedTypes.Add(replacements["GHOST_NAME"]);
        }
        public void GenerateSerializer(CodeGenerator.Context context, Mono.Cecil.TypeDefinition typeDefinition)
        {
            var replacements = new Dictionary <string, string>();

            replacements.Add("COMMAND_NAME", typeDefinition.FullName.Replace(".", "").Replace("/", "_"));
            replacements.Add("COMMAND_NAMESPACE", context.generatedNs);
            replacements.Add("COMMAND_COMPONENT_TYPE", typeDefinition.FullName.Replace("/", "."));

            context.collectionAssemblies.Add(typeDefinition.Module.Assembly.Name.Name);
            if (typeDefinition.Namespace != null && typeDefinition.Namespace != "")
            {
                context.imports.Add(typeDefinition.Namespace);
            }

            foreach (var ns in context.imports)
            {
                replacements["COMMAND_USING"] = CodeGenNamespaceUtils.GetValidNamespaceForType(context.generatedNs, ns);
                m_CommandGenerator.GenerateFragment("COMMAND_USING_STATEMENT", replacements);
            }

            var serializerName = typeDefinition.FullName.Replace("/", "+") + "CommandSerializer.cs";

            m_CommandGenerator.GenerateFile("", context.outputFolder, serializerName, replacements, context.batch);
        }
        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"]);
        }