public void TestCode() { var codeFile = new CodeDocument {TabCharacter = " "}; codeFile.Namespace("Test") .Class("public", "TestClass", "") ._() ._("private string _value;") ._() .Function("public", "TestClass", "string value") ._("_value = value;") .End() ._() .Function("public void ", "TestMethod", "") ._("_value = 5;") .End() ._() ._() .Interface("public", "TestInterface", "") ._("void TestMethod();") .End() .End() .End(); Debug.WriteLine(codeFile.ToString()); Assert.IsTrue(true); }
public void TestStateCodeGeneration() { ICodeBlock codeBlock = new CodeDocument(0); mButtonInButtonList.CurrentState = "InvalidState"; StateCodeGenerator.WriteSetStateOnNamedObject(mButtonInButtonList, codeBlock); string result = codeBlock.ToString(); if (result.Contains(mButtonInButtonList.CurrentState)) { throw new Exception("Code generation for NamedObjects is generating state setting code when states don't really exist"); } // Make sure generation doesn't mess up on a entity with a "" base (instead of null) StateCodeGenerator scg = new StateCodeGenerator(); EntitySave entitySave = new EntitySave(); entitySave.States.Add(new StateSave()); entitySave.BaseEntity = ""; scg.GenerateFields(codeBlock, entitySave); }
private static ICodeBlock GetGlobalContentFilesMethods() { ICodeBlock codeBlock = new CodeDocument(); var currentBlock = codeBlock; var classLevelBlock = currentBlock; codeBlock._(); // Don't use foreach to make this tolerate changes to the collection while it generates //foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) for (int i = 0; i < ProjectManager.GlueProjectSave.GlobalFiles.Count; i++) { ReferencedFileSave rfs = ProjectManager.GlueProjectSave.GlobalFiles[i]; ReferencedFileSaveCodeGenerator.AppendFieldOrPropertyForReferencedFile(currentBlock, rfs, GlobalContentContainerName, null); } const bool inheritsFromElement = false; ReferencedFileSaveCodeGenerator.GenerateGetStaticMemberMethod(ProjectManager.GlueProjectSave.GlobalFiles, currentBlock, true, inheritsFromElement); ReferencedFileSaveCodeGenerator.GenerateGetFileMethodByName( ProjectManager.GlueProjectSave.GlobalFiles, currentBlock, false, "GetFile", false); if (ProjectManager.GlueProjectSave.GlobalContentSettingsSave.RecordLockContention) { currentBlock.Line("public static List<string> LockRecord = new List<string>();"); } currentBlock .AutoProperty("public static bool", "IsInitialized", "", "private"); currentBlock .AutoProperty("public static bool", "ShouldStopLoading"); currentBlock.Line("const string ContentManagerName = \"Global\";"); var initializeFunction = currentBlock.Function("public static void", "Initialize", ""); currentBlock = initializeFunction ._(); //stringBuilder.AppendLine("\t\t\tstring ContentManagerName = \"Global\";"); // Do the high-proprity loads first // Update May 10, 2011 // If loading asynchronously // the first Screen may load before // we even get to the high-priority RFS's // (which are localization). This could cause // the first Screen to have unlocalized text. That's // why we want to load it before we even start our async loading. foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) { if (IsRfsHighPriority(rfs)) { ReferencedFileSaveCodeGenerator.GetInitializationForReferencedFile(rfs, null, initializeFunction, true, LoadType.CompleteLoad); } } bool loadAsync = GenerateLoadAsyncCode(classLevelBlock, initializeFunction); if (ContentLoadWriter.SuppressGlobalContentDictionaryRefresh == false) { ReferencedFileSaveCodeGenerator.RefreshGlobalContentDictionary(); } if (loadAsync) { currentBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); } foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) { if (!IsRfsHighPriority(rfs) && rfs.LoadedAtRuntime) { var blockToUse = initializeFunction; if (loadAsync) { blockToUse = classLevelBlock .Function("static void", "Load" + rfs.Name.Replace("/", "_").Replace(".", "_"), ""); } ReferencedFileSaveCodeGenerator.GetInitializationForReferencedFile(rfs, null, blockToUse, true, LoadType.CompleteLoad); if (loadAsync) { blockToUse.Line("m" + rfs.GetInstanceName() + "Mre.Set();"); blockToUse.End(); } } } if (loadAsync) { currentBlock.Line("#endif"); } if (!loadAsync) { currentBlock = currentBlock .Line("\t\t\tIsInitialized = true;") .End(); } GenerateReloadFileMethod(classLevelBlock); foreach (var generator in CodeWriter.GlobalContentCodeGenerators) { generator.GenerateInitializeEnd(initializeFunction); generator.GenerateAdditionalMethods(classLevelBlock); } return codeBlock; }
public static ICodeBlock GetMethodCallForBehavior(string behaviorName, IBehaviorContainer container) { ICodeBlock codeBlock = new CodeDocument(); string returnString = GetRawBehaviorMethodHeader(behaviorName); if (returnString.StartsWith("//")) { codeBlock.Line(returnString); return codeBlock; } else { returnString = returnString.Trim(); returnString = returnString.Replace("public ", ""); returnString = returnString.Replace("private ", ""); returnString = returnString.Replace("protected ", ""); returnString = returnString.Replace("internal ", ""); returnString = returnString.Replace("override ", ""); returnString = returnString.Replace("virtual ", ""); returnString = returnString.Replace("static ", ""); // The first word is going to be the return value returnString = returnString.Substring(returnString.IndexOf(' ') + 1); List<BehaviorRequirement> requirements = BehaviorManager.GetBehaviorRequirementsForBehavior(behaviorName); if (requirements.Count != 0) { // Let's clear out the argments and fill them with the objects that fulfill the requirements int start = returnString.IndexOf('(') + 1; int indexOfClose = returnString.IndexOf(')'); string argumentList = returnString.Substring(start, indexOfClose - start) ; returnString = returnString.Replace(argumentList, ""); argumentList = ""; for (int i = 0; i < requirements.Count; i++) { //string requirementFulfiller = string requirementFulfiller = container.GetFulfillerName(requirements[i]); argumentList += requirementFulfiller; if (i != requirements.Count - 1) { argumentList += ", "; } } returnString = returnString.Insert(start, argumentList); } codeBlock.Line(returnString + ";"); return codeBlock; } }
private static ICodeBlock GetGlobalContentFilesMethods() { ICodeBlock codeBlock = new CodeDocument(); var currentBlock = codeBlock; codeBlock._(); // Don't use foreach to make this tolerate changes to the collection while it generates //foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) for (int i = 0; i < ProjectManager.GlueProjectSave.GlobalFiles.Count; i++ ) { ReferencedFileSave rfs = ProjectManager.GlueProjectSave.GlobalFiles[i]; ReferencedFileSaveCodeGenerator.AppendFieldOrPropertyForReferencedFile(currentBlock, rfs, GlobalContentContainerName, null); } const bool inheritsFromElement = false; ReferencedFileSaveCodeGenerator.GenerateGetStaticMemberMethod(ProjectManager.GlueProjectSave.GlobalFiles, currentBlock, true, inheritsFromElement); ReferencedFileSaveCodeGenerator.GenerateGetFileMethodByName( ProjectManager.GlueProjectSave.GlobalFiles, currentBlock, false, "GetFile", false); if (ProjectManager.GlueProjectSave.GlobalContentSettingsSave.RecordLockContention) { currentBlock.Line("public static List<string> LockRecord = new List<string>();"); } currentBlock .AutoProperty("public static bool", "IsInitialized", "", "private"); currentBlock .AutoProperty("public static bool", "ShouldStopLoading"); currentBlock.Line("const string ContentManagerName = \"Global\";"); currentBlock = currentBlock .Function("public static void", "Initialize", "") ._(); //stringBuilder.AppendLine("\t\t\tstring ContentManagerName = \"Global\";"); // Do the high-proprity loads first // Update May 10, 2011 // If loading asynchronously // the first Screen may load before // we even get to the high-priority RFS's // (which are localization). This could cause // the first Screen to have unlocalized text. That's // why we want to load it before we even start our async loading. foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) { if (IsRfsHighPriority(rfs)) { ReferencedFileSaveCodeGenerator.GetInitializationForReferencedFile(rfs, null, currentBlock, true, LoadType.CompleteLoad); } } bool loadAsync = ProjectManager.GlueProjectSave.GlobalContentSettingsSave.LoadAsynchronously; if (loadAsync) { currentBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); currentBlock.Line("NamedDelegate namedDelegate = new NamedDelegate();"); foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) { if (!IsRfsHighPriority(rfs) && !rfs.LoadedOnlyWhenReferenced && rfs.LoadedAtRuntime) { currentBlock.Line("namedDelegate.Name = \"" + rfs.Name + "\";"); currentBlock.Line("namedDelegate.LoadMethod = Load" + rfs.Name.Replace("/", "_").Replace(".", "_") + ";"); currentBlock.Line("LoadMethodList.Add( namedDelegate );"); } } currentBlock._(); currentBlock.Line("#if WINDOWS_8"); currentBlock.Line("System.Threading.Tasks.Task.Run((System.Action)AsyncInitialize);"); currentBlock.Line("#else"); currentBlock.Line("ThreadStart threadStart = new ThreadStart(AsyncInitialize);"); currentBlock.Line("Thread thread = new Thread(threadStart);"); currentBlock.Line("thread.Name = \"GlobalContent Async load\";"); currentBlock.Line("thread.Start();"); currentBlock.Line("#endif"); currentBlock.Line("#endif"); currentBlock = currentBlock.End(); currentBlock._(); currentBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); currentBlock .Function("static void", "RequestContentLoad", "string contentName") .Lock("LoadMethodList") .Line("int index = -1;") .For("int i = 0; i < LoadMethodList.Count; i++") .If("LoadMethodList[i].Name == contentName") .Line("index = i;") .Line("break;") .End() .End() .If("index != -1") .Line("NamedDelegate delegateToShuffle = LoadMethodList[index];") .Line("LoadMethodList.RemoveAt(index);") .Line("LoadMethodList.Insert(0, delegateToShuffle);") .End() .End() .End(); currentBlock.Line("#endif"); currentBlock._(); currentBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); currentBlock .Function("static void", "AsyncInitialize", "") .Line("#if XBOX360") .Line("// We can not use threads 0 or 2") .Line("// Async screen loading uses thread 4, so we'll use 3 here") .Line("Thread.CurrentThread.SetProcessorAffinity(3);") .Line("#endif") .Line("bool shouldLoop = LoadMethodList.Count != 0;") .While("shouldLoop") .Line("System.Action action = null;") .Lock("LoadMethodList") .Line("action = LoadMethodList[0].LoadMethod;") .Line("LoadMethodList.RemoveAt(0);") .Line("shouldLoop = LoadMethodList.Count != 0 && !ShouldStopLoading;") .End() .Line("action();") .End() .Line("IsInitialized = true;") ._() .End(); currentBlock.Line("#endif"); //stringBuilder.AppendLine("\t\t\tstring ContentManagerName = \"Global\";"); } if (ContentLoadWriter.SuppressGlobalContentDictionaryRefresh == false) { ReferencedFileSaveCodeGenerator.RefreshGlobalContentDictionary(); } if (loadAsync) { currentBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); } foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) { if (!IsRfsHighPriority(rfs) && rfs.LoadedAtRuntime) { if (loadAsync) { currentBlock = currentBlock .Function("static void", "Load" + rfs.Name.Replace("/", "_").Replace(".", "_"), ""); } ReferencedFileSaveCodeGenerator.GetInitializationForReferencedFile(rfs, null, currentBlock, true, LoadType.CompleteLoad); if (loadAsync) { currentBlock.Line("m" + rfs.GetInstanceName() + "Mre.Set();"); currentBlock = currentBlock.End(); } } } if (loadAsync) { currentBlock.Line("#endif"); } if (!loadAsync) { currentBlock = currentBlock .Line("\t\t\tIsInitialized = true;") .End(); } GenerateReloadFileMethod(currentBlock); return codeBlock; }
internal static ICodeBlock GenerateInitialize(IElement saveObject) { ICodeBlock codeBlock = new CodeDocument(3); ICodeBlock currentBlock = codeBlock; // Start measuring performance before anything else PerformancePluginCodeGenerator.GenerateStartTimingInitialize(saveObject, codeBlock); PerformancePluginCodeGenerator.SaveObject = saveObject; PerformancePluginCodeGenerator.CodeBlock = codeBlock; PerformancePluginCodeGenerator.GenerateStart("CustomLoadStaticContent from Initialize"); // Load static content before looping through the CodeGenerators // The reason for this is there is a ReferencedFileSaveCodeGenerator // which needs to work with static RFS's which are instantiated here currentBlock.Line("LoadStaticContent(ContentManagerName);"); PerformancePluginCodeGenerator.GenerateEnd(); PerformancePluginCodeGenerator.GenerateStart("General Initialize internals"); foreach (ElementComponentCodeGenerator codeGenerator in CodeGenerators) { codeGenerator.GenerateInitialize(codeBlock, saveObject); } foreach (ElementComponentCodeGenerator codeGenerator in CodeGenerators) { codeGenerator.GenerateInitializeLate(codeBlock, saveObject); } if (saveObject is ScreenSave) { ScreenSave asScreenSave = saveObject as ScreenSave; codeBlock._(); if (asScreenSave.IsRequiredAtStartup) { string startupScreen = ProjectManager.StartUpScreen; string qualifiedName = ProjectManager.ProjectNamespace + "." + startupScreen.Replace("\\", "."); codeBlock.Line(string.Format("this.NextScreen = typeof({0}).FullName;", qualifiedName)); } if (asScreenSave.UseGlobalContent) { // no need to do anything here because Screens are smart enough to know to not load if they // are using global content } if (!string.IsNullOrEmpty(asScreenSave.NextScreen)) { string nameToUse = ProjectManager.ProjectNamespace + "." + asScreenSave.NextScreen.Replace("\\", "."); codeBlock.Line(string.Format("this.NextScreen = typeof({0}).FullName;", nameToUse)); } } codeBlock._(); PerformancePluginCodeGenerator.GenerateEnd(); #region PostInitializeCode PerformancePluginCodeGenerator.GenerateStart("Post Initialize"); if (saveObject.InheritsFromElement() == false) { codeBlock.Line("PostInitialize();"); } PerformancePluginCodeGenerator.GenerateEnd(); #endregion PerformancePluginCodeGenerator.GenerateStart("Base.Initialize"); InheritanceCodeWriter.Self.WriteBaseInitialize(saveObject, codeBlock); PerformancePluginCodeGenerator.GenerateEnd(); // I think we want to set this after calling base.Initialize so that the base // has a chance to set values on derived objects PerformancePluginCodeGenerator.GenerateStart("Reset Variables"); // Now that variables are set, we can record reset variables NamedObjectSaveCodeGenerator.AssignResetVariables(codeBlock, saveObject); PerformancePluginCodeGenerator.GenerateEnd(); PerformancePluginCodeGenerator.GenerateStart("AddToManagers"); #region If shouldCallAddToManagers, call AddToManagers bool shouldCallAddToManagers = !saveObject.InheritsFromElement(); if (shouldCallAddToManagers) { currentBlock = currentBlock .If("addToManagers"); if (saveObject is ScreenSave) { currentBlock.Line("AddToManagers();"); } else { currentBlock.Line("AddToManagers(null);"); } } #endregion PerformancePluginCodeGenerator.GenerateEnd(); PerformancePluginCodeGenerator.GenerateEndTimingInitialize(saveObject, codeBlock); return codeBlock; }
internal static void GenerateUsings(StringBuilder stringBuilder, IElement saveObject) { if (stringBuilder.Contains("// Generated Usings")) { ICodeBlock usings = new CodeDocument(); UsingsCodeGenerator.GenerateUsingStatements(usings, saveObject); int startOfUsingSection = GetIndexAfter("// Generated Usings", stringBuilder); stringBuilder.Insert(startOfUsingSection, usings.ToString()); } }
public static ICodeBlock CreateClass(string namespaceName, string className, bool isPartial, List<TypedMemberBase> members, bool isStatic, List<string> usingStatements, Dictionary<string, string> untypedMembers, ICodeBlock methodContent) { var codeBlock = new CodeDocument(); #region Append Using Statements foreach(var usingStatement in usingStatements.Distinct()) { codeBlock.Line("using " + usingStatement + ";"); } #endregion #region Append Namespace codeBlock._(); ICodeBlock currentBlock = codeBlock; currentBlock = currentBlock.Namespace(namespaceName); #endregion #region Append class header currentBlock = currentBlock.Class(className, Public: true, Static: isStatic, Partial: isPartial); #endregion for (int i = 0; i < members.Count; i++) { TypedMemberBase member = members[i]; bool isPublic = member.Modifier == Modifier.Public; bool isPrivate = member.Modifier == Modifier.Private; bool isInternal = member.Modifier == Modifier.Internal; string memberType = member.MemberType.ToString(); memberType = PrepareTypeToBeWritten(member, memberType); // We used to remove whitespace here, // but the member name may contain an assignment. // In that case we want spaces preserved. Whatever // calls this method is in charge of removing whitespace. string memberName = member.MemberName; currentBlock.Line(StringHelper.Modifiers( Public: isPublic, Private: isPrivate, Internal: isInternal, Static: isStatic, Type: memberType, Name: memberName) + ";"); } foreach (KeyValuePair<string, string> kvp in untypedMembers) { string memberName = kvp.Key; string type = kvp.Value; bool isPublic = !memberName.StartsWith("m"); currentBlock.Line(StringHelper.Modifiers(Public: isPublic, Static: isStatic, Type: type, Name: memberName) + ";"); } if (methodContent == null) { currentBlock.Tag("Methods"); } else { currentBlock.InsertBlock(methodContent); } currentBlock._()._(); currentBlock.Replace(" System.Single ", " float "); currentBlock.Replace(" System.Boolean ", " bool "); currentBlock.Replace(" System.Int32 ", " int "); currentBlock.Replace(" System.String ", " string "); return codeBlock; }
public static ICodeBlock GetPostInitializeForReferencedFile(ReferencedFileSave referencedFile) { AssetTypeInfo ati = referencedFile.GetAssetTypeInfo(); ICodeBlock codeBlock = new CodeDocument(); if (ati != null && !referencedFile.IsSharedStatic) { string variableName = referencedFile.GetInstanceName(); if (!string.IsNullOrEmpty(ati.PostInitializeCode)) { codeBlock.Line(ati.PostInitializeCode.Replace("this", variableName) + ";"); } } return codeBlock; }
static ICodeBlock GetActivityForReferencedFile(ReferencedFileSave referencedFile, IElement element) { ICodeBlock codeBlock = new CodeDocument(); /////////////////////EARLY OUT///////////////////////// if (!referencedFile.LoadedAtRuntime) { return codeBlock; } //////////////////END EARLY OUT////////////////////// AssetTypeInfo ati = referencedFile.GetAssetTypeInfo(); // If it's an emitter, call TimedEmit: ParticleCodeGenerator.GenerateTimedEmit(codeBlock, referencedFile, element); if (ati != null && (!referencedFile.IsSharedStatic || element is ScreenSave )&& !referencedFile.LoadedOnlyWhenReferenced && ati.ActivityMethod != null) { AddIfConditionalSymbolIfNecesssary(codeBlock, referencedFile); string variableName = referencedFile.GetInstanceName(); codeBlock.Line(ati.ActivityMethod.Replace("this", variableName) + ";"); AddEndIfIfNecessary(codeBlock, referencedFile); return codeBlock; } else { return codeBlock; } }
public static void CreateEmptyCodeIfNecessary(IElement currentElement, string fullFileName, bool forceRegenerateContents) { bool doesFileExist = File.Exists(fullFileName); if (!doesFileExist) { PluginManager.ReceiveOutput("Forcing a regneration of " + fullFileName + " because Glue can't find it anywhere."); // There is no shared code file for this event, so we need to make one ProjectManager.CodeProjectHelper.CreateAndAddPartialCodeFile(fullFileName, true); } if (!doesFileExist || forceRegenerateContents) { string namespaceString = GlueCommands.Self.GenerateCodeCommands.GetNamespaceForElement(currentElement); ICodeBlock templateCodeBlock = new CodeDocument(); EventCodeGenerator.AddUsingStatementsToBlock(templateCodeBlock); ICodeBlock namespaceCB = templateCodeBlock.Namespace(namespaceString); ICodeBlock classCB = namespaceCB.Class("public partial", currentElement.ClassName, null); classCB ._() .End() .End(); string templateToSave = templateCodeBlock.ToString(); FlatRedBall.Glue.IO.FileWatchManager.IgnoreNextChangeOnFile(fullFileName); FileManager.SaveText(templateToSave, fullFileName); } // Add if it isn't part of the project const bool saveFile = false; // don't save it - we just want to make sure it's part of the project ProjectManager.CodeProjectHelper.CreateAndAddPartialCodeFile(fullFileName, saveFile); }
/// <summary> /// Injects the insideOfMethod into an event for the argument /// </summary> /// <param name="currentElement">The IElement containing the EventResponseSave.</param> /// <param name="eventResponseSave">The EventResponseSave which should have its contents set or replaced.</param> /// <param name="insideOfMethod">The inside of the methods to assign.</param> /// <returns>The full file name which contains the method contents.</returns> public static string InjectTextForEventAndSaveCustomFile(IElement currentElement, EventResponseSave eventResponseSave, string insideOfMethod) { // In case the user passes null we don't want to have null reference exceptions: if (insideOfMethod == null) { insideOfMethod = ""; } ParsedMethod parsedMethod = eventResponseSave.GetParsedMethodFromAssociatedFile(); string fullFileName = eventResponseSave.GetSharedCodeFullFileName(); bool forceRegenerate = false; string fileContents = null; if (File.Exists(fullFileName)) { fileContents = FileManager.FromFileText(fullFileName); forceRegenerate = fileContents.Contains("public partial class") == false && fileContents.Contains("{") == false; if (forceRegenerate) { GlueGui.ShowMessageBox("Forcing a regneration of " + fullFileName + " because it appears to be empty."); } } CreateEmptyCodeIfNecessary(currentElement, fullFileName, forceRegenerate); fileContents = FileManager.FromFileText(fullFileName); int indexToAddAt = 0; if (parsedMethod != null) { int startIndex; int endIndex; GetStartAndEndIndexForMethod(parsedMethod, fileContents, out startIndex, out endIndex); // We want to include the \r\n at the end, so add 2 endIndex += 2; string whatToRemove = fileContents.Substring(startIndex, endIndex - startIndex); fileContents = fileContents.Replace(whatToRemove, null); indexToAddAt = startIndex; // remove the method to re-add it } else { indexToAddAt = EventManager.GetLastLocationInClass(fileContents, startOfLine:true); } ICodeBlock codeBlock = new CodeDocument(2); codeBlock.TabCharacter = " "; insideOfMethod = "" + insideOfMethod.Replace("\r\n", "\r\n "); codeBlock = EventCodeGenerator.FillWithCustomEventCode(codeBlock, eventResponseSave, insideOfMethod, currentElement); string methodContents = codeBlock.ToString(); fileContents = fileContents.Insert(indexToAddAt, codeBlock.ToString()); eventResponseSave.Contents = null; try { FlatRedBall.Glue.IO.FileWatchManager.IgnoreNextChangeOnFile(fullFileName); FileManager.SaveText(fileContents, fullFileName); } catch (Exception e) { PluginManager.ReceiveError("Could not save file to " + fullFileName); } return fullFileName; }
private static ICodeBlock GenerateEventGeneratedCodeFile(IElement element) { ICodeBlock codeBlock = new CodeDocument(); var currentBlock = codeBlock; string elementNamespace = ProjectManager.ProjectNamespace; elementNamespace += "." + element.Name.Replace("/", ".").Replace("\\", ".").Substring( 0, element.Name.Length - (element.ClassName.Length + 1)); AddUsingStatementsToBlock(currentBlock); currentBlock = currentBlock .Namespace(elementNamespace); currentBlock = currentBlock .Class("public partial", element.ClassName, ""); foreach (EventResponseSave ers in element.Events) { currentBlock = FillWithGeneratedEventCode(currentBlock, ers, element); } return codeBlock; }
private static void GenerateCustomClass(CustomClassSave customClass) { if (customClass.GenerateCode) { string fileName = ""; ICodeBlock codeBlock = new CodeDocument(); List<TypedMemberBase> members; Dictionary<string, string> untypedMembers; ReferencedFileSave rfs = null; if (customClass.CsvFilesUsingThis.Count != 0) { rfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(customClass.CsvFilesUsingThis[0]); } if (rfs != null) { // let's just use the existing code flow, even though it's less efficient: GenerateAndSaveDataClass(rfs, rfs.CsvDelimiter); } else { fileName = GetClassInfo(fileName, null, customClass, out members, out untypedMembers); bool succeeded = GenerateClassFromMembers(rfs, true, customClass.Name, members, untypedMembers); } } //return fileName; }
private static bool GenerateClassFromMembers(ReferencedFileSave rfs, bool succeeded, string className, List<TypedMemberBase> members, Dictionary<string, string> untypedMembers) { ICodeBlock codeBlock = new CodeDocument(); // If the CSV // is going to // be deserialized // to a dictionary, // then we should create // const members for all of // the keys in the dictionary // to make accessing the dictionary // type-safe. if (rfs != null) { succeeded = CreateConstsForCsvEntries(rfs, members, untypedMembers, codeBlock); } if (succeeded) { ICodeBlock codeContent = CodeWriter.CreateClass(ProjectManager.ProjectNamespace + ".DataTypes", className, true, members, false, new List<string>(), untypedMembers, codeBlock); string absoluteFileName = null; if (rfs != null) { absoluteFileName = FileManager.RelativeDirectory + GetFullDataFileNameFor(rfs); } else { absoluteFileName = FileManager.RelativeDirectory + "DataTypes/" + className + ".Generated.cs"; } CodeWriter.SaveFileContents(codeContent.ToString(), absoluteFileName, true); #region Add the code item for the generated .cs file if it's not already part of the project if (ProjectManager.ProjectBase.GetItem(absoluteFileName) == null) { ProjectManager.ProjectBase.AddCodeBuildItem(absoluteFileName); } #endregion } if (succeeded) { string message; if (rfs != null) { message = "Generating class " + className + " from CSV " + rfs.Name; } else { message = "Generating class " + className + " from Custom Class"; } Plugins.PluginManager.ReceiveOutput(message); } return succeeded; }
private static ICodeBlock GetLoadGlobalContentCode() { ICodeBlock codeBlock = new CodeDocument(); if (ProjectManager.GlueProjectSave.GlobalContentSettingsSave.LoadAsynchronously) { codeBlock .Struct("", "NamedDelegate") .Line("public string Name;") .Line("public System.Action LoadMethod;") .End() ._() .Line("static List<NamedDelegate> LoadMethodList = new List<NamedDelegate>();") ._(); } string className = "GlobalContent"; #region Instantiate the ClassProperties ClassProperties classProperties = new ClassProperties(); classProperties.Members = new List<FlatRedBall.Instructions.Reflection.TypedMemberBase>(); classProperties.UntypedMembers = new Dictionary<string, string>(); #endregion classProperties.NamespaceName = ProjectManager.ProjectNamespace; classProperties.ClassName = className; classProperties.IsStatic = true; classProperties.Partial = true; classProperties.UsingStatements = new List<string>(); #region Add using statements // todo: remove these, we don't need them anymore and they could cause ambiguity classProperties.UsingStatements.Add("System.Collections.Generic"); classProperties.UsingStatements.Add("System.Threading"); classProperties.UsingStatements.Add("FlatRedBall"); classProperties.UsingStatements.Add("FlatRedBall.Math.Geometry"); classProperties.UsingStatements.Add("FlatRedBall.ManagedSpriteGroups"); classProperties.UsingStatements.Add("FlatRedBall.Graphics.Animation"); classProperties.UsingStatements.Add("FlatRedBall.Graphics.Particle"); classProperties.UsingStatements.Add("FlatRedBall.AI.Pathfinding"); classProperties.UsingStatements.Add("FlatRedBall.Utilities"); classProperties.UsingStatements.Add("BitmapFont = FlatRedBall.Graphics.BitmapFont"); classProperties.UsingStatements.Add("FlatRedBall.Localization"); bool shouldAddUsingForDataTypes = false; for (int i = 0; i < ProjectManager.GlueProjectSave.GlobalFiles.Count; i++) { if (FileManager.GetExtension(ProjectManager.GlueProjectSave.GlobalFiles[i].Name) == "csv") { shouldAddUsingForDataTypes = true; break; } } if (shouldAddUsingForDataTypes) { classProperties.UsingStatements.Add(ProjectManager.ProjectNamespace + ".DataTypes"); classProperties.UsingStatements.Add("FlatRedBall.IO.Csv"); } #endregion var contents = GetGlobalContentFilesMethods(); codeBlock.InsertBlock(contents); classProperties.MethodContent = codeBlock; var toReturn = CodeWriter.CreateClass(classProperties); var block = new CodeBlockBaseNoIndent(null); block.Line("#if ANDROID || IOS"); block.Line("// Android doesn't allow background loading. iOS doesn't allow background rendering (which is used by converting textures to use premult alpha)"); block.Line("#define REQUIRES_PRIMARY_THREAD_LOADING"); block.Line("#endif"); toReturn.PreCodeLines.Add(block); return toReturn; }
public static ICodeBlock GetPostCustomActivityForReferencedFile(ReferencedFileSave referencedFile) { ICodeBlock codeBlock = new CodeDocument(); if (!referencedFile.LoadedAtRuntime) { return codeBlock; } AssetTypeInfo ati = referencedFile.GetAssetTypeInfo(); // January 8, 2012 // This used to not // check LoadedOnlyWhenReferenced // but I think it should otherwise // this code will always load Scenes // that are LoadedOnlyWhenReferenced by // calling their ManageAll method - so I // added a check for LoadedOnlyWhenReferenced. if (ati != null && !referencedFile.IsSharedStatic && !referencedFile.LoadedOnlyWhenReferenced && ati.AfterCustomActivityMethod != null) { AddIfConditionalSymbolIfNecesssary(codeBlock, referencedFile); string variableName = referencedFile.GetInstanceName(); codeBlock.Line(ati.AfterCustomActivityMethod.Replace("this", variableName) + ";"); AddEndIfIfNecessary(codeBlock, referencedFile); return codeBlock; } else { return codeBlock; } }
protected ICodeBlock GetDestroyForReferencedFile(IElement element, ReferencedFileSave referencedFile) { ICodeBlock codeBlock = new CodeDocument(3); ///////////////////////////////EARLY OUT/////////////////////// if (!referencedFile.LoadedAtRuntime || !referencedFile.DestroyOnUnload) { return codeBlock; } if (referencedFile.GetGeneratesMember() == false) { return codeBlock; } /////////////////////////////END EARLY OUT///////////////////// AddIfConditionalSymbolIfNecesssary(codeBlock, referencedFile); string fileName = referencedFile.Name; AssetTypeInfo ati = referencedFile.GetAssetTypeInfo(); string variableName = referencedFile.GetInstanceName(); bool isScreenSave = element is ScreenSave; if (referencedFile.LoadedOnlyWhenReferenced) { variableName = "m" + variableName; codeBlock = codeBlock.If(variableName + " != null"); } if (ati != null && (!referencedFile.IsSharedStatic || isScreenSave)) { string typeName = ati.RuntimeTypeName; string destroyMethod = ati.DestroyMethod; string recycleMethod = ati.RecycledDestroyMethod; if (string.IsNullOrEmpty(recycleMethod)) { recycleMethod = destroyMethod; } if (!string.IsNullOrEmpty(ati.DestroyMethod)) { if (isScreenSave && recycleMethod != destroyMethod) { codeBlock = codeBlock.If("this.UnloadsContentManagerWhenDestroyed && ContentManagerName != \"Global\""); codeBlock.Line(destroyMethod.Replace("this", variableName) + ";"); if (referencedFile.LoadedOnlyWhenReferenced) { codeBlock = codeBlock.End().ElseIf(variableName + " != null"); } else { codeBlock = codeBlock.End().Else(); } codeBlock.Line(recycleMethod.Replace("this", variableName) + ";"); codeBlock = codeBlock.End(); } else { codeBlock.Line(destroyMethod.Replace("this", variableName) + ";"); } } if (ati.ShouldBeDisposed && element.UseGlobalContent == false) { codeBlock = codeBlock.If("this.UnloadsContentManagerWhenDestroyed && ContentManagerName != \"Global\""); codeBlock.Line(string.Format("{0}.Dispose();", variableName)); codeBlock = codeBlock.End(); } } if (element is ScreenSave && referencedFile.IsSharedStatic) { if (referencedFile.LoadedOnlyWhenReferenced) { variableName = "m" + referencedFile.GetInstanceName(); } // We used to do this here, but we want to do it after all Objects have been destroyed // because we may need to make the file one way before the destruction of the objects. if (ati != null && ati.SupportsMakeOneWay) { codeBlock = codeBlock.If("this.UnloadsContentManagerWhenDestroyed && ContentManagerName != \"Global\""); codeBlock.Line(string.Format("{0} = null;", variableName)); codeBlock = codeBlock.End().Else(); codeBlock.Line(string.Format("{0}.MakeOneWay();", variableName)); codeBlock = codeBlock.End(); } else { codeBlock.Line(string.Format("{0} = null;", variableName)); } } if (referencedFile.LoadedOnlyWhenReferenced) { codeBlock = codeBlock.End(); } AddEndIfIfNecessary(codeBlock, referencedFile); return codeBlock; }
internal static ICodeBlock GenerateDestroy(IElement saveObject) { bool isScreen = saveObject is ScreenSave; ICodeBlock codeBlock = new CodeDocument(3); var currentBlock = codeBlock; #region Call base.Destroy if it has a derived object // The Screen template already includes a call to base.Destroy if ( saveObject.InheritsFromEntity() ) { currentBlock.Line("base.Destroy();"); } #endregion #region If Entity, remove from managers (SpriteManager, GuiManager) if (saveObject is EntitySave) { if (saveObject.InheritsFromFrbType()) { AssetTypeInfo ati = AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(saveObject.BaseObject); if (ati != null) { currentBlock.Line(ati.DestroyMethod + ";"); } } else if (! saveObject.InheritsFromElement()) { currentBlock.Line("FlatRedBall.SpriteManager.RemovePositionedObject(this);"); } if ((saveObject as EntitySave).ImplementsIWindow && !(saveObject as EntitySave).GetInheritsFromIWindow()) { currentBlock.Line("FlatRedBall.Gui.GuiManager.RemoveWindow(this);"); } } #endregion foreach (ElementComponentCodeGenerator codeGenerator in CodeWriter.CodeGenerators) { codeGenerator.GenerateDestroy(currentBlock, saveObject); } return currentBlock; }
public static ICodeBlock GetAddToManagersForReferencedFile(IElement mSaveObject, ReferencedFileSave referencedFile) { bool shouldAddToManagers = GetIfShouldAddToManagers(mSaveObject, referencedFile); ICodeBlock codeBlock = new CodeDocument(3); // We don't want to add shared static stuff to the manager - it's just used to pull and clone objects out of. // Update September 12, 2012 // We actually do want to add // static objects if they are part // of a Screen. if (shouldAddToManagers) { ICodeBlock currentBlock = codeBlock; AssetTypeInfo ati = referencedFile.GetAssetTypeInfo(); string fileName = referencedFile.Name; AddIfConditionalSymbolIfNecesssary(codeBlock, referencedFile); string typeName = ati.RuntimeTypeName; string variableName = referencedFile.GetInstanceName(); if (BaseElementTreeNode.IsOnOwnLayer(mSaveObject) && ati.LayeredAddToManagersMethod.Count != 0 && !string.IsNullOrEmpty(ati.LayeredAddToManagersMethod[0])) { string layerAddToManagersMethod = ati.LayeredAddToManagersMethod[0]; if (mSaveObject is EntitySave) { layerAddToManagersMethod = layerAddToManagersMethod.Replace("mLayer", "layerToAddTo"); } currentBlock.Line(layerAddToManagersMethod.Replace("this", variableName) + ";"); } else if (ati.LayeredAddToManagersMethod.Count != 0 && !string.IsNullOrEmpty(ati.LayeredAddToManagersMethod[0]) && mSaveObject is ScreenSave) { string layerAddToManagersMethod = ati.LayeredAddToManagersMethod[0]; // The Screen has an mLayer //layerAddToManagersMethod = layerAddToManagersMethod.Replace("mLayer", "layerToAddTo"); currentBlock.Line(layerAddToManagersMethod.Replace("this", variableName) + ";"); } else { currentBlock.Line(ati.AddToManagersMethod[0].Replace("this", variableName) + ";"); } if (referencedFile.IsManuallyUpdated && !string.IsNullOrEmpty(ati.MakeManuallyUpdatedMethod)) { currentBlock.Line(ati.MakeManuallyUpdatedMethod.Replace("this", variableName) + ";"); } AddEndIfIfNecessary(codeBlock, referencedFile); } return codeBlock; }
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 }
public void CodeGenerationStart(IElement element) { var stateChainCollection = GlueCommands.TreeNodeCommands.GetProperty<StateChainCollection>(element, PropertyName); if(stateChainCollection == null) return; var elementNameWithoutPath = FileManager.RemovePath(element.Name); var document = new CodeDocument(); ICodeBlock codeBlock = document; if (stateChainCollection.StateChains.Count <= 0) { return; } codeBlock = codeBlock .Line("using FlatRedBall.Instructions;") .Namespace(GlueCommands.GenerateCodeCommands.GetNamespaceForElement(element)) .Class("public partial ", element.ClassName, ""); //Create Enum codeBlock = codeBlock .Enum("public", "StateChains") .Line("None = 0,"); for (int i = 0; i < stateChainCollection.StateChains.Count; i++) { if (i == stateChainCollection.StateChains.Count - 1) codeBlock.Line(stateChainCollection.StateChains[i].Name); else codeBlock.Line(stateChainCollection.StateChains[i].Name + ","); } codeBlock = codeBlock.End(); //Private members codeBlock ._() .Line("private StateChains _currentStateChain = StateChains.None;") .Line("private int _index;") .Line("private Instruction _instruction;") ._(); //CurrentStateChain Property codeBlock = codeBlock .Property("public StateChains", "CurrentStateChain") .Get() .Line("return _currentStateChain;") .End() .Set() .Line("StopStateChain();") ._() .Line("_currentStateChain = value;") .Line("_index = 0;") ._() .Switch("_currentStateChain"); foreach (var stateChain in stateChainCollection.StateChains) { codeBlock .Case("StateChains." + stateChain.Name) .Line("StartNextState" + stateChain.Name + "();"); } codeBlock = codeBlock .End() .End() .End(); codeBlock._(); //ManageStateChains codeBlock = codeBlock .Function("public void", "ManageStateChains", "") .If("CurrentStateChain == StateChains.None") .Line("return;") .End() ._() .Switch("CurrentStateChain"); foreach (var stateChain in stateChainCollection.StateChains) { var index = 0; codeBlock = codeBlock .Case("StateChains." + stateChain.Name); foreach (var stateChainState in stateChain.StateChainStates.Where(stateChainState => !string.IsNullOrEmpty(stateChainState.State))) { if (index == 0) { codeBlock .If("_index == 0 && CurrentState == VariableState." + stateChainState.State) .Line("_index++;") .Line("StartNextState" + stateChain.Name + "();"); } else { codeBlock .ElseIf("_index == " + index + " && CurrentState == VariableState." + stateChainState.State) .Line("_index++;") .Line("StartNextState" + stateChain.Name + "();"); } index++; } codeBlock = codeBlock .End(); } codeBlock = codeBlock .End() .End(); codeBlock._(); //StopStateChain codeBlock = codeBlock .Function("public void", "StopStateChain", "") .If("CurrentStateChain == StateChains.None") .Line("return;") .End() ._() .Switch("CurrentStateChain"); foreach (var stateChain in stateChainCollection.StateChains) { var index = 0; codeBlock = codeBlock .Case("StateChains." + stateChain.Name); foreach (var stateChainState in stateChain.StateChainStates) { if (index == 0) { codeBlock .If("_index == 0") .Line("Instructions.Remove(_instruction);") .Line("StopStateInterpolation(VariableState." + stateChainState.State + ");") .End(); }else { codeBlock .ElseIf("_index == " + index) .Line("Instructions.Remove(_instruction);") .Line("StopStateInterpolation(VariableState." + stateChainState.State + ");") .End(); } index++; } codeBlock = codeBlock .End(); } codeBlock = codeBlock .End() .Line("_instruction = null;") .End(); codeBlock._(); //StartNextState***** foreach (var stateChain in stateChainCollection.StateChains) { codeBlock = codeBlock .Function("private void", "StartNextState" + stateChain.Name, "") .If("_index < 0") .Line("_index = 0;") .End() ._() .If("_index >= " + stateChain.StateChainStates.Count) .Line("_index = 0;") .End() ._() .Switch("_index"); var index = 0; foreach (var stateChainState in stateChain.StateChainStates) { codeBlock .Case(index.ToString()) .Line("_instruction = InterpolateToState(VariableState." + stateChainState.State + ", " + stateChainState.Time / 1000 + ");"); index++; } codeBlock = codeBlock .End() .End() ._(); } GlueCommands.ProjectCommands.CreateAndAddPartialFile(element, "StateChains", document.ToString()); }
internal static ICodeBlock GenerateFields(IElement saveObject) { ICodeBlock codeBlock = new CodeDocument(2); foreach (ElementComponentCodeGenerator codeGenerator in CodeWriter.CodeGenerators) { if (codeGenerator == null) { throw new Exception("The CodeWriter contains a null code generator. A plugin must have added this"); } try { codeGenerator.GenerateFields(codeBlock, saveObject); } catch (Exception e) { throw new Exception("Error generating fields in generator " + codeGenerator.GetType().Name + "\n\n" + e.ToString()); } } PerformancePluginCodeGenerator.GenerateFields(saveObject, codeBlock); EntitySave asEntitySave = saveObject as EntitySave; // No need to create LayerProvidedByContainer if this inherits from another object. if (asEntitySave != null && !saveObject.InheritsFromEntity()) { // Add the layer that is going to get assigned in generated code codeBlock.Line("protected FlatRedBall.Graphics.Layer LayerProvidedByContainer = null;"); } return codeBlock; }
private static string GetBehaviorContents(string behaviorName) { ICodeBlock codeBlock = new CodeDocument(); string fileName = BehaviorFolder + behaviorName + ".cs"; if (File.Exists(fileName)) { string behaviorContents = FileManager.FromFileText(fileName ); codeBlock.Line(behaviorContents); } else { codeBlock.Line("// There is an invalid behavior reference to behavior " + behaviorName); } return codeBlock.ToString(); }
internal static ICodeBlock GenerateAddToManagers(IElement saveObject) { ICodeBlock codeBlock = new CodeDocument(2); ICodeBlock currentBlock = codeBlock; bool isEntity = saveObject is EntitySave; bool isScreen = !isEntity; bool inheritsFromNonFrbType = !string.IsNullOrEmpty(saveObject.BaseElement) && !saveObject.InheritsFromFrbType(); GenerateReAddToManagers(saveObject, currentBlock); #region Generate the method header if (isScreen) { currentBlock = currentBlock .Function("public override void", "AddToManagers", ""); } else if (saveObject.InheritsFromElement()) // it's an EntitySave { currentBlock = currentBlock .Function("public override void", "AddToManagers", "FlatRedBall.Graphics.Layer layerToAddTo"); } else // It's a base EntitySave { currentBlock = currentBlock .Function("public virtual void", "AddToManagers", "FlatRedBall.Graphics.Layer layerToAddTo"); } #endregion PerformancePluginCodeGenerator.SaveObject = saveObject; PerformancePluginCodeGenerator.CodeBlock = currentBlock; PerformancePluginCodeGenerator.GenerateStart("Pooled PostInitialize"); #region Call PostInitialize *again* if this is a pooled, base Entity FactoryCodeGenerator.CallPostInitializeIfNecessary(saveObject, currentBlock); #endregion PerformancePluginCodeGenerator.GenerateEnd(); PerformancePluginCodeGenerator.GenerateStart("Layer for this code"); #region Generate layer if a screen if (IsOnOwnLayer(saveObject)) { // Only Screens need to define a layer. Otherwise, the layer is fed to the Entity if (isScreen) { currentBlock.Line("mLayer = SpriteManager.AddLayer();"); } } #endregion #region Assign the layer so that custom code can get to it if (isEntity) { currentBlock.Line("LayerProvidedByContainer = layerToAddTo;"); } #endregion PerformancePluginCodeGenerator.GenerateEnd(); GenerateAddThisEntityToManagers(saveObject, currentBlock); const string addFilesToManagers = "Add Files to Managers"; PerformancePluginCodeGenerator.GenerateStart(saveObject, currentBlock, addFilesToManagers); #region Add all ReferencedFileSaves // Add referenced files before adding objects because the objects // may be aliases for the files (if using Entire File) and may add them // to layers. for (int i = 0; i < saveObject.ReferencedFiles.Count; i++) { PerformancePluginCodeGenerator.GenerateStart("Adding file " + saveObject.ReferencedFiles[i].GetInstanceName()); currentBlock.InsertBlock(ReferencedFileSaveCodeGenerator.GetAddToManagersForReferencedFile(saveObject, saveObject.ReferencedFiles[i])); PerformancePluginCodeGenerator.GenerateEnd(); } #endregion PerformancePluginCodeGenerator.GenerateEnd(saveObject, currentBlock, addFilesToManagers); PerformancePluginCodeGenerator.GenerateStart("Create layer instances"); #region First generate all code for Layers before other stuff // We want the code for Layers to be generated before other stuff // since Layes may be used when generating the objects for (int i = 0; i < saveObject.NamedObjects.Count; i++) { NamedObjectSave nos = saveObject.NamedObjects[i]; if ( nos.SourceType == SourceType.FlatRedBallType && nos.SourceClassType == "Layer") { NamedObjectSaveCodeGenerator.WriteAddToManagersForNamedObject(saveObject, nos, currentBlock); foreach (CustomVariable customVariable in saveObject.CustomVariables) { if (customVariable.SourceObject == nos.InstanceName) { CustomVariableCodeGenerator.AppendAssignmentForCustomVariableInElement(currentBlock, customVariable, saveObject); } } } } #endregion PerformancePluginCodeGenerator.GenerateEnd(); PerformancePluginCodeGenerator.GenerateStart("General AddToManagers code"); foreach (ElementComponentCodeGenerator codeGenerator in CodeGenerators) { codeGenerator.GenerateAddToManagers(currentBlock, saveObject); } PerformancePluginCodeGenerator.GenerateEnd(); PerformancePluginCodeGenerator.GenerateStart("Add to managers base and bottom up"); if ( saveObject.InheritsFromElement()) { if (saveObject is ScreenSave) { currentBlock.Line("base.AddToManagers();"); } else { currentBlock.Line("base.AddToManagers(layerToAddTo);"); } } else { if (isScreen) { if (! saveObject.InheritsFromElement()) { // Screen will always call base.AddToManagers so that // Screen.cs gets a chance to set up its timing currentBlock.Line("base.AddToManagers();"); } currentBlock.Line("AddToManagersBottomUp();"); } else { currentBlock.Line("AddToManagersBottomUp(layerToAddTo);"); } } PerformancePluginCodeGenerator.GenerateEnd(); // The code for custom variables // used to be up in Initialize, but // it probably belongs in AddToManagers. // See the note in Initialize for more information. // UPDATE: Nevermind, we don't want custom variable // setting to be done here because if so then the variables // won't be available to the user in CustomInitialize PerformancePluginCodeGenerator.GenerateStart("Custom Initialize"); currentBlock.Line("CustomInitialize();"); PerformancePluginCodeGenerator.GenerateEnd(); return codeBlock; }
private static ICodeBlock GetAllFactoryMethods(string factoryClassName, string baseClassName, int numberToPreAllocate, bool poolObjects) { string className = factoryClassName.Substring(0, factoryClassName.Length - "Factory".Length); ICodeBlock codeBlock = new CodeDocument(); GetCreateNewFactoryMethod(codeBlock, factoryClassName, poolObjects, baseClassName); codeBlock._(); GetInitializeFactoryMethod(codeBlock, className, poolObjects, "mScreenListReference"); codeBlock._(); if (!string.IsNullOrEmpty(baseClassName)) { GetInitializeFactoryMethod(codeBlock, FileManager.RemovePath(baseClassName), poolObjects, "mBaseScreenListReference"); codeBlock._(); } GetDestroyFactoryMethod(codeBlock, factoryClassName); codeBlock._(); GetFactoryInitializeMethod(codeBlock, factoryClassName, numberToPreAllocate); codeBlock._(); GetMakeUnusedFactory(codeBlock, factoryClassName, poolObjects); return codeBlock; }