private static void GenerateInitializeAsync(ICodeBlock currentBlock) { currentBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); currentBlock.Line("NamedDelegate namedDelegate = new NamedDelegate();"); foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) { if (!ReferencedFileSaveCodeGenerator.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"); }
private void AdjustAssetTypeInfo() { var atis = AvailableAssetTypes.Self.AllAssetTypes .Where(item => item.QualifiedRuntimeTypeName.QualifiedType == "Microsoft.Xna.Framework.Media.Song"); foreach (var ati in atis) { ati.CustomLoadFunc = (element, nos, rfs, contentManager) => { bool shouldAssignField = ReferencedFileSaveCodeGenerator.NeedsFullProperty(rfs, element); string variableName; if (shouldAssignField) { variableName = "m" + rfs.GetInstanceName(); } else { variableName = rfs.GetInstanceName(); } var fileName = ReferencedFileSaveCodeGenerator.GetFileToLoadForRfs(rfs, ati); // FlatRedBall.IO.FileManager.RemoveExtension(rfs.Name).ToLowerInvariant().Replace("\\", "/"); if (rfs.DestroyOnUnload == false) { contentManager = "FlatRedBall.FlatRedBallServices.GlobalContentManager"; } //return $"{propertyName} = FlatRedBall.FlatRedBallServices.Load<Microsoft.Xna.Framework.Media.Song>(@"content/screens/gamescreen/baronsong", contentManagerName);"; return($"{variableName} = FlatRedBall.FlatRedBallServices.Load<Microsoft.Xna.Framework.Media.Song>(@\"{fileName}\", {contentManager});"); }; } }
public static ICodeBlock GetLoadCallsForRfs(ReferencedFileSave referencedFile, string fileName, AssetTypeInfo ati, string variableName, ICodeBlock codeBlock, bool useGlobalContent, bool isContentPipeline) { var currentBlock = codeBlock; if (referencedFile.IsCsvOrTreatedAsCsv == false) { string modifiedFileName = fileName.ToLower(); string contentManagerString = GetContentManagerString(referencedFile); string fileNameToLoad = ProjectBase.AccessContentDirectory + modifiedFileName; // If the file isn't part of the content pipeline we have // to manually unload it if (!useGlobalContent && !isContentPipeline) { currentBlock = currentBlock .If(string.Format("!FlatRedBall.FlatRedBallServices.IsLoaded<{2}>(@\"{0}\", {1})", ProjectBase.AccessContentDirectory + modifiedFileName, contentManagerString, ati.QualifiedRuntimeTypeName.QualifiedType)); if (referencedFile.GetContainerType() == ContainerType.Entity) { currentBlock.Line("registerUnload = true;"); } currentBlock = currentBlock.End(); } ReferencedFileSaveCodeGenerator.GetLoadCallForAtiFile(referencedFile, ati, variableName, contentManagerString, fileNameToLoad, codeBlock); } return(currentBlock); }
private static void GenerateReloadFileMethod(ICodeBlock currentBlock) { var reloadFunction = currentBlock .Function("public static void", "Reload", "object whatToReload"); var toLoopThrough = ProjectManager.GlueProjectSave.GlobalFiles.Where(item => item.IsDatabaseForLocalizing == false && item.LoadedAtRuntime && item.IsCsvOrTreatedAsCsv).ToList(); foreach (var rfs in toLoopThrough) { var ifInReload = reloadFunction.If("whatToReload == " + rfs.GetInstanceName()); { ReferencedFileSaveCodeGenerator.GetReload(rfs, null, ifInReload, true, LoadType.MaintainInstance); } } }
string GetGumxLoadCode(IElement element, NamedObjectSave nos, ReferencedFileSave rfs, string contentManagerName) { string fileNameToLoad = ReferencedFileSaveCodeGenerator.GetFileToLoadForRfs(rfs, mGumxAti); string toReturn = $"FlatRedBall.Gum.GumIdb.StaticInitialize(\"{fileNameToLoad}\"); " + "FlatRedBall.Gum.GumIdbExtensions.RegisterTypes(); " + "FlatRedBall.Gui.GuiManager.BringsClickedWindowsToFront = false;"; var displaySettings = GlueState.Self.CurrentGlueProject?.DisplaySettings; if (displaySettings != null) { if (displaySettings.FixedAspectRatio == false || displaySettings.AspectRatioHeight == 0) { toReturn += "FlatRedBall.Gum.GumIdb.FixedCanvasAspectRatio = null;"; } else { var aspectRatio = displaySettings.AspectRatioWidth / displaySettings.AspectRatioHeight; toReturn += $"FlatRedBall.Gum.GumIdb.FixedCanvasAspectRatio = {displaySettings.AspectRatioWidth}/{displaySettings.AspectRatioHeight}m;"; } } // As of August 19, 2019 Glue handles this in the camera code, so this isn't needed anymore //toReturn += // "FlatRedBall.FlatRedBallServices.GraphicsOptions.SizeOrOrientationChanged += (not, used) => { FlatRedBall.Gum.GumIdb.UpdateDisplayToMainFrbCamera(); };" // ; var gumxRfs = GumProjectManager.Self.GetRfsForGumProject(); bool shouldShowOutlines = false; if (gumxRfs != null) { shouldShowOutlines = gumxRfs.Properties.GetValue <bool>("ShowDottedOutlines"); } string valueAsString = shouldShowOutlines.ToString().ToLowerInvariant(); toReturn += $"Gum.Wireframe.GraphicalUiElement.ShowLineRectangles = {valueAsString};"; return(toReturn); }
private static void GenerateReloadFileMethod(ICodeBlock currentBlock) { var reloadFunction = currentBlock .Function("public static void", "Reload", "object whatToReload"); var toLoopThrough = ProjectManager.GlueProjectSave.GlobalFiles.Where(item => // The reason localization databases can't be reloaded is because // this function is called by passing an object (whatToReload). Localization // databases don't create an object in GlobalContent, so there's nothing to reload. // Therefore, the user will have to manually reload item.IsDatabaseForLocalizing == false && item.LoadedAtRuntime && GetIfFileCanBeReloaded(item)).ToList(); foreach (var rfs in toLoopThrough) { var ifInReload = reloadFunction.If("whatToReload == " + rfs.GetInstanceName()); { ReferencedFileSaveCodeGenerator.GetReload(rfs, null, ifInReload, LoadType.MaintainInstance); } } }
private void PerformGluxLoad(string projectFileName, string glueProjectFile) { SetInitWindowText("Loading .glux"); bool succeeded = true; succeeded = DeserializeGluxXmlInternal(projectFileName, glueProjectFile); if (succeeded) { // This seems to take some time (like 1 second). Can we possibly // make it faster by having it chek Game1.cs first? Why is this so slow? ProjectManager.FindGameClass(); AvailableAssetTypes.Self.AdditionalExtensionsToTreatAsAssets.Clear(); IdentifyAdditionalAssetTypes(); SetInitWindowText("Finding and fixing .glux errors"); ProjectManager.GlueProjectSave.FixErrors(true); ProjectManager.GlueProjectSave.RemoveInvalidStatesFromNamedObjects(true); FixProjectErrors(); SetUnsetValues(); ProjectManager.LoadOrCreateProjectSpecificSettings(FileManager.GetDirectory(projectFileName)); SetInitWindowText("Notifying plugins of project..."); // The project specific settings are needed before the plugins do their thing... PluginManager.ReactToLoadedGluxEarly(ProjectManager.GlueProjectSave); // and after that's done we can validate that the build tools are there BuildToolAssociationManager.Self.ProjectSpecificBuildTools.ValidateBuildTools(FileManager.GetDirectory(projectFileName)); ProjectManager.GlueProjectSave.UpdateIfTranslationIsUsed(); Section.GetAndStartContextAndTime("Add items"); SetInitWindowText("Creating project view..."); AddEmptyTreeItems(); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("RefreshSourceFileCache"); // This has to be done before the tree nodes are created. The reason is because a user // may create a ReferencedFileSave using a source type, but not check in the built file. // Glue depends on the built file being there, so we gotta build to make sure that file gets // generated. // Update on May 4, 2011: This should be done AFTER BuildAllOutOfDateFiles because Refreshing // source file cache requires looking at all referenced files, and this requires the files existing // so that dependencies can be tracked. // Update May 4, 2011 Part 2: The SourceFileCache is used when building files. So instead, the refreshing // of the source file cache will also build a file if it encounters a missing file. This should greatly reduce // popup count. SetInitWindowText("Refreshing Source File Cache..."); RefreshSourceFileCache(); SetInitWindowText("Checking for additional missing files..."); SetInitWindowText("Building out of date external files..."); BuildAllOutOfDateFiles(); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("RefreshGlobalContentDirectory"); SetInitWindowText("Refreshing global content dictionary..."); ReferencedFileSaveCodeGenerator.RefreshGlobalContentDictionary(); GlobalContentCodeGenerator.SuppressGlobalContentDictionaryRefresh = true; Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Screens"); SetInitWindowText("Creating tree nodes..."); CreateScreenTreeNodes(); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Entities"); CreateEntityTreeNodes(); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("SortEntities"); ElementViewWindow.SortEntities(); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("PrepareSyncedProjects"); PrepareSyncedProjects(projectFileName); mLastLoadedFilename = projectFileName; Section.EndContextAndTime(); Section.GetAndStartContextAndTime("MakeGeneratedItemsNested"); // This should happen after loading synced projects SetInitWindowText("Nesting generated items"); GlueCommands.Self.ProjectCommands.MakeGeneratedCodeItemsNested(); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("GlobalContent"); #region Update GlobalContent UI and code SetInitWindowText("Updating global content"); ElementViewWindow.UpdateGlobalContentTreeNodes(false); // Screens and Entities have the membership of their files // automatically updated when the tree nodes are created. This // is bad. GlobalContent does this better by requiring the call // to be explicitly made: UpdateGlobalContentFileProjectMembership(); // I think this is handled automatically when regenerating all code... // Yes, down in GenerateAllCodeTask //GlobalContentCodeGenerator.UpdateLoadGlobalContentCode(); #endregion Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Startup"); SetInitWindowText("Setting StartUp Screen"); #region Set the Startup Screen if (!string.IsNullOrEmpty(ProjectManager.GlueProjectSave.StartUpScreen)) { TreeNode startUpTreeNode = GlueState.Self.Find.ScreenTreeNode(ProjectManager.GlueProjectSave.StartUpScreen); ElementViewWindow.StartUpScreen = startUpTreeNode; if (startUpTreeNode == null) { ProjectManager.GlueProjectSave.StartUpScreen = ""; } } #endregion Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Performance code"); FactoryCodeGenerator.AddGeneratedPerformanceTypes(); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("CSV generation"); CsvCodeGenerator.RegenerateAllCsvs(); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("PluginManager Init"); PluginManager.Initialize(false); SetInitWindowText("Notifying Plugins of startup"); PluginManager.ReactToLoadedGlux(ProjectManager.GlueProjectSave, glueProjectFile, SetInitWindowText); Section.EndContextAndTime(); Section.GetAndStartContextAndTime("GenerateAllCode"); SetInitWindowText("Generating all code"); GlueCommands.Self.GenerateCodeCommands.GenerateAllCodeTask(); Section.EndContextAndTime(); GlobalContentCodeGenerator.SuppressGlobalContentDictionaryRefresh = false; } }
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, 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 ._(); foreach (var generator in CodeWriter.GlobalContentCodeGenerators) { generator.GenerateInitializeStart(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 (ReferencedFileSaveCodeGenerator.IsRfsHighPriority(rfs)) { ReferencedFileSaveCodeGenerator.GetInitializationForReferencedFile(rfs, null, initializeFunction, LoadType.CompleteLoad); } } bool loadAsync = GenerateLoadAsyncCode(classLevelBlock, initializeFunction); if (GlobalContentCodeGenerator.SuppressGlobalContentDictionaryRefresh == false) { ReferencedFileSaveCodeGenerator.RefreshGlobalContentDictionary(); } if (loadAsync) { currentBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); } foreach (ReferencedFileSave rfs in ProjectManager.GlueProjectSave.GlobalFiles) { if (!ReferencedFileSaveCodeGenerator.IsRfsHighPriority(rfs) && rfs.LoadedAtRuntime) { var blockToUse = initializeFunction; if (loadAsync) { blockToUse = classLevelBlock .Function("static void", "Load" + rfs.Name.Replace("/", "_").Replace(".", "_"), ""); } ReferencedFileSaveCodeGenerator.GetInitializationForReferencedFile(rfs, null, blockToUse, LoadType.CompleteLoad); if (loadAsync) { blockToUse.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); blockToUse.Line("m" + rfs.GetInstanceName() + "Mre.Set();"); blockToUse.Line("#endif"); 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); }
private string GetRawDialogTreeLoadCode(IElement element, NamedObjectSave namedObject, ReferencedFileSave referencedFile, string contentManager) { var fileName = ReferencedFileSaveCodeGenerator.GetFileToLoadForRfs(referencedFile, referencedFile.GetAssetTypeInfo()); return($"{referencedFile.GetInstanceName()} = DialogTreePlugin.SaveClasses.DialogTreeRaw.RootObject.FromJson(\"{fileName}\");"); }