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 }