Inheritance: CodeBlockBaseNoIndent
        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;
        }
Example #4
0
		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;
        }
Example #6
0
        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;
        }
Example #7
0
        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());
            }
        }
Example #8
0
        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;
        }
Example #14
0
        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;
        }
Example #15
0
        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;
        }
Example #16
0
        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;
        }
Example #19
0
        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;
        }
Example #21
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


        }
        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());
        }
Example #23
0
        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;


        }
Example #24
0
		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();
		}
Example #25
0
        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;
        }