Inheritance: ICodeBlock
        internal string GenerateInterfaceCodeFor(BehaviorSave behavior)
        {
            CodeBlockBase fileLevel = new CodeBlockBase(null);
            ICodeBlock namespaceLevel = fileLevel.Namespace(GueDerivingClassCodeGenerator.GueRuntimeNamespace);

            StateCodeGenerator.Self.GenerateStateEnums(behavior, namespaceLevel, enumNamePrefix:behavior.Name);


            ICodeBlock interfaceLevel = namespaceLevel.Interface("public", $"I{behavior.Name}", "");


            GenerateInterface(interfaceLevel, behavior);

            return fileLevel.ToString();
        }
示例#2
0
        public static void GenerateCode(IElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            string template;

            if (element is ScreenSave)
            {
                template = mScreenTemplateGeneratedCode;
            }
            else
            {
                template = mEntityTemplateGeneratedCode;
            }

            // Since anything can modify an enumeration value we want to make sure that
            // it's proper before generating code for it:

            // If enumeration values don't work property let's just print some output and carry on
            try
            {
                element.FixEnumerationValues();
            }
            catch (Exception e)
            {
                PluginManager.ReceiveError("Error fixing enumerations for " + element + ": " + e.ToString());
            }

            // Do this before doing anything else since 
            // these reusable entire file RFS's are used 
            // in other code.
            RefreshReusableEntireFileRfses(element);

            EventCodeGenerator.GenerateEventGeneratedFile(element);

            if (element.Events.Count != 0)
            {
                var sharedCodeFullFileName = 
                    EventResponseSave.GetSharedCodeFullFileName(element, FileManager.GetDirectory(ProjectManager.GlueProjectFileName));

                EventCodeGenerator.CreateEmptyCodeIfNecessary(element,
                    sharedCodeFullFileName, false);
            }



            EventCodeGenerator.AddStubsForCustomEvents(element);

            CreateGeneratedFileIfNecessary(element);

            StringBuilder stringBuilder = new StringBuilder(template);

            foreach (PluginManager pluginManager in PluginManager.GetInstances())
            {
                CodeGeneratorPluginMethods.CallCodeGenerationStart(pluginManager, element);
            }

            if (ContentLoadWriter.SuppressGlobalContentDictionaryRefresh == false)
            {
                ReferencedFileSaveCodeGenerator.RefreshGlobalContentDictionary();
            }

            if (ReferencedFileSaveCodeGenerator.GlobalContentFilesDictionary == null)
            {
                throw new Exception("Global content files dictionary should not be null");
            }

            string objectName = FileManager.RemovePath(element.Name);

            string projectNamespace = ProjectManager.ProjectNamespace;

            if (element is EntitySave)
            {
                string directory = FileManager.MakeRelative(FileManager.GetDirectory(element.Name));

                if (directory.ToLower() != "Entities/".ToLower())
                {
                    string relativeDirectory = FileManager.MakeRelative(directory);
                    relativeDirectory = relativeDirectory.Substring(0, relativeDirectory.Length - 1);
                    relativeDirectory = relativeDirectory.Replace('/', '.');

                    projectNamespace += "." + relativeDirectory;
                }
            }
            else if (element is ScreenSave)
            {
                projectNamespace += ".Screens";
            }

            string contentManagerName = element.UseGlobalContent ? "\"Global\"" : null;
            ScreenSave asScreenSave = element as ScreenSave;
            if (asScreenSave != null &&
                !string.IsNullOrEmpty(asScreenSave.ContentManagerMethod))
            {
                contentManagerName = asScreenSave.ContentManagerMethod;
            }

            var whatToInheritFrom = GetInheritance(element);
            CodeWriter.SetClassNameAndNamespace(
                projectNamespace,
                objectName,
                stringBuilder,
                !string.IsNullOrEmpty(contentManagerName),
                contentManagerName,
                whatToInheritFrom
                );

            #region Make Activity, Initialize, PostInitalize, and Destroy "override" if necessary

            if ( element.InheritsFromElement())
            {

                if (stringBuilder.Contains("virtual void Initialize"))
                {
                    stringBuilder.Replace("virtual void Initialize", "override void Initialize");
                }

                if (stringBuilder.Contains("virtual void Activity"))
                {
                    stringBuilder.Replace("virtual void Activity", "override void Activity");
                }

                if (stringBuilder.Contains("virtual void Destroy"))
                {
                    stringBuilder.Replace("virtual void Destroy", "override void Destroy");
                }
            }

            #endregion

            try
            {
                CodeWriter.GenerateUsings(stringBuilder, element);
            }
            catch (Exception e)
            {
                string stackTrace = e.StackTrace;

                throw new Exception("Error trying to generate using statements for " + element + "\n\n" + stackTrace, e);
            }

            #region Generate Fields

            ICodeBlock fieldsSection = CodeWriter.GenerateFields(element);
            int startOfFieldsSection = CodeWriter.GetIndexAfter("// Generated Fields", stringBuilder);
            stringBuilder.Insert(startOfFieldsSection, fieldsSection.ToString());

            #endregion


            #region Generate Initialize

            ICodeBlock initializeSection = CodeWriter.GenerateInitialize(element);
            int startOfInitializeSection = CodeWriter.GetIndexAfter("// Generated Initialize", stringBuilder);
            stringBuilder.Insert(startOfInitializeSection, initializeSection.ToString());

            #endregion


            #region Generate AddToManagers

            int startOfAddToManagers = CodeWriter.GetIndexAfter("// Generated AddToManagers", stringBuilder);
            ICodeBlock addToManagersSection = CodeWriter.GenerateAddToManagers(element);
            stringBuilder.Insert(startOfAddToManagers, addToManagersSection.ToString());


            #endregion


            #region GenerateActivity



            ICodeBlock activityBlock = new CodeDocument(3);
            ICodeBlock currentBlock = activityBlock;

            currentBlock = CodeWriter.GenerateActivity(currentBlock, element);
            currentBlock = CodeWriter.GenerateAfterActivity(currentBlock, element);

            int startOfActivity = CodeWriter.GetIndexAfter("// Generated Activity", stringBuilder);
            stringBuilder.Insert(startOfActivity, activityBlock.ToString());


            #endregion

            #region Generate Destroy

            ICodeBlock destroySection = CodeWriter.GenerateDestroy(element);
            int startOfDestroySection = CodeWriter.GetIndexAfter("// Generated Destroy", stringBuilder);
            stringBuilder.Insert(startOfDestroySection, destroySection.ToString());

            #endregion


            #region Generate Methods

            ICodeBlock methodsSection = new CodeDocument(2);

            CodeWriter.GenerateMethods(methodsSection, element);

            int startOfMethodsSection = CodeWriter.GetIndexAfter("// Generated Methods", stringBuilder);
            stringBuilder.Insert(startOfMethodsSection, methodsSection.ToString());

            #endregion


            #region Extra Classes
            CodeBlockBase codeBlock = new CodeBlockBase(null);

            foreach (var codeGenerator in CodeGenerators)
            {
                codeGenerator.GenerateAdditionalClasses(codeBlock, element);
            }


            string extraClasses = codeBlock.ToString();

            if (!string.IsNullOrEmpty(extraClasses))
            {
                const string extraClassesComment = "// Extra classes";
                int indexToReplace = stringBuilder.LastIndexOf(extraClassesComment);

                stringBuilder.Remove(indexToReplace, extraClassesComment.Length);

                stringBuilder.Insert(indexToReplace, extraClasses);

            }
            #endregion

            string generatedCodeFileName = element.Name + ".Generated.cs";



            CodeWriter.SaveFileContents(stringBuilder.ToString(), FileManager.RelativeDirectory + generatedCodeFileName, true);


            #region Extra stuff if it's a ScreenSave

            if (element is ScreenSave)
            {
                bool inherits = !string.IsNullOrEmpty(element.BaseElement) && element.BaseElement != "<NONE>";
                if (inherits)
                {
                    #region Set the inheritance to the proper class

                    string fileContents;
                    string nameWithoutPath = FileManager.RemovePath(element.Name);

                    fileContents = FileManager.FromFileText(FileManager.RelativeDirectory + element.Name + ".Generated.cs");

                    #endregion

                    #region Replace the ContentManagerName

                    contentManagerName =
                        (element as ScreenSave).ContentManagerForCodeGeneration;

                    if (fileContents.Contains("base(" + contentManagerName + ")"))
                    {
                        // use the lower-case contentManagerName since that's the argument that's given to
                        // the base class' constructor.
                        fileContents = fileContents.Replace("base(" + contentManagerName + ")",
                            "base()");
                    }

                    #endregion

                    EliminateCall("\tInitialize();", ref fileContents);
                    EliminateCall(" Initialize();", ref fileContents);

                    CodeWriter.SaveFileContents(fileContents, FileManager.RelativeDirectory + element.Name + ".Generated.cs", true);
                }
            }

            #endregion

            #region Extra stuff if it's an EntitySave

            if (element is EntitySave)
            {
                EntitySave entitySave = element as EntitySave;

                string fileContents = stringBuilder.ToString();
                string fileName = FileManager.RelativeDirectory + element.Name + ".Generated.cs";
                bool shouldSave = false;

                #region Ok, the code is generated, but we may still need to give it a base class


                bool inherits;

                

                EntitySave rootEntitySave;
                List<string> inheritanceList = InheritanceCodeWriter.Self.GetInheritanceList(element, entitySave, out inherits, out rootEntitySave);
                InheritanceCodeWriter.Self.RemoveCallsForInheritance(entitySave, inherits, rootEntitySave, ref fileContents, ref shouldSave);

                #endregion

                #region If this thing is created by other entities, then we should make it IPoolable

                if (entitySave.CreatedByOtherEntities)
                {
                    FactoryCodeGenerator.UpdateFactoryClass(entitySave);
                }

                #endregion

                #region If this uses global content, then make it use global content regardless of what is passed in

                if (entitySave.UseGlobalContent)
                {
                    fileContents = fileContents.Replace("ContentManagerName = contentManagerName;", "ContentManagerName = FlatRedBall.FlatRedBallServices.GlobalContentManager;");
                    shouldSave = true;
                }

                #endregion


                #region If a change was made to the fileContents, let's save it

                if (shouldSave)
                {
                    bool tryAgain = true;

                    CodeWriter.SaveFileContents(fileContents, fileName, tryAgain);
                }

                #endregion
            }
            #endregion


        }
        private static string GetCameraSetupCsContents()
        {
            string newContents = Resources.Resource1.CameraSetupTemplate;

            newContents = CodeWriter.ReplaceNamespace(newContents, ProjectManager.ProjectNamespace);

            ICodeBlock classContents = new CodeBlockBase(null);
            classContents.TabCount = 2;

            GenerateSetupCameraMethod(classContents);
            GenerateResetCameraMethod(classContents);

            StringFunctions.ReplaceLine(ref newContents, "// Generated Code:", classContents.ToString());
            return newContents;
        }
        public override string GetCode()
        {

            string entityClassName = FileManager.RemovePath(FileManager.RemoveExtension(EntitySave.Name));
            if (entityClassName.StartsWith("I"))
            {
                int m = 3;
            }
            string baseEntityName = null;
            if (!string.IsNullOrEmpty(EntitySave.BaseEntity))
            {
                EntitySave rootEntitySave = EntitySave.GetRootBaseEntitySave();

                // There could be an invalid inheritance chain.  We don't want Glue to bomb if so, so
                // we'll check for this.
                if (rootEntitySave != null && rootEntitySave != EntitySave)
                {
                    baseEntityName = rootEntitySave.Name;
                }
            }


            string factoryClassName = ClassName;

            ClassProperties classProperties = new ClassProperties();

            classProperties.NamespaceName = ProjectManager.ProjectNamespace + ".Factories";
            classProperties.ClassName = factoryClassName + " : IEntityFactory";
            
            classProperties.Members = new List<FlatRedBall.Instructions.Reflection.TypedMemberBase>();

            classProperties.UntypedMembers = new Dictionary<string, string>();
            string positionedObjectListType = string.Format("FlatRedBall.Math.PositionedObjectList<{0}>", entityClassName);
            
            // Factories used to be always static but we're going to make them singletons instead
            //classProperties.IsStatic = true;

            classProperties.UsingStatements = new List<string>();
            classProperties.UsingStatements.Add(GlueCommands.Self.GenerateCodeCommands.GetNamespaceForElement(EntitySave));
            classProperties.UsingStatements.Add("System");

            if (!string.IsNullOrEmpty(baseEntityName))
            {
                EntitySave baseEntity = ObjectFinder.Self.GetEntitySave(baseEntityName);
                classProperties.UsingStatements.Add(GlueCommands.Self.GenerateCodeCommands.GetNamespaceForElement(baseEntity));
            }


            classProperties.UsingStatements.Add("FlatRedBall.Math");
            classProperties.UsingStatements.Add("FlatRedBall.Graphics");
            classProperties.UsingStatements.Add(ProjectManager.ProjectNamespace + ".Performance");


            ICodeBlock codeContent = CodeWriter.CreateClass(classProperties);

            const int numberOfInstancesToPool = 20;

            var methodTag = codeContent.GetTag("Methods")[0];

            var methodBlock = GetAllFactoryMethods(factoryClassName, baseEntityName, numberOfInstancesToPool,
                                                ShouldPoolObjects);
            methodTag.InsertBlock(methodBlock);

            var codeBlock = new CodeBlockBase(null);
            codeBlock.Line("static string mContentManagerName;");
            codeBlock.Line("static PositionedObjectList<" + entityClassName + "> mScreenListReference;");
            
            if (!string.IsNullOrEmpty(baseEntityName))
            {
                codeBlock.Line("static PositionedObjectList<" + FileManager.RemovePath(baseEntityName) + "> mBaseScreenListReference;");

            }
            codeBlock.Line(string.Format("static PoolList<{0}> mPool = new PoolList<{0}>();", entityClassName));

            codeBlock.Line(string.Format("public static Action<{0}> EntitySpawned;", entityClassName));

            codeBlock.Function("object", "IEntityFactory.CreateNew", "")
                .Line(string.Format("return {0}.CreateNew();", factoryClassName));

            codeBlock.Function("object", "IEntityFactory.CreateNew", "Layer layer")
                .Line(string.Format("return {0}.CreateNew(layer);", factoryClassName));

            #region ScreenListReference property
            var propertyBlock = new CodeBlockProperty(codeBlock, "public static " + positionedObjectListType, "ScreenListReference");

            //codeContent.Property("ScreenListReference", Public: true, Static: true, Type: positionedObjectListType);
            propertyBlock.Get().Line("return mScreenListReference;").End();
            propertyBlock.Set().Line("mScreenListReference = value;").End();
            #endregion


            #region Self and mSelf
            codeBlock.Line("static " + factoryClassName + " mSelf;");

            var selfProperty = codeBlock.Property("public static " + factoryClassName, "Self");
            var selfGet = selfProperty.Get();
            selfGet.If("mSelf == null")
                .Line("mSelf = new " + entityClassName + "Factory" + "();");
            selfGet.Line("return mSelf;");
            #endregion

            ((codeContent.BodyCodeLines.Last() as CodeBlockBase).BodyCodeLines.Last() as CodeBlockBase).InsertBlock(codeBlock);
            return codeContent.ToString();
        }