Beispiel #1
0
        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);
        }
Beispiel #2
0
        private static string GetContentManagerString(ReferencedFileSave referencedFile)
        {
            string contentManagerString = "ContentManagerName";

            // If the referencedFile is shared static, then this is needed in LoadStaticContent
            if (referencedFile.GetContainerType() == ContainerType.Screen && referencedFile.IsSharedStatic)
            {
                // If the referenced file is part of a screen, then we need to use the "contentManagerName" (which is an argument to the
                // LoadStaticContent method) instead of the "ContentManagerName" which is a member of the Screen.  The reason is that the
                // content manager for a screen is not static.
                contentManagerString = "contentManagerName";
            }
            return(contentManagerString);
        }
        internal void ReactToChangedReferencedFile(string changedMember, object oldValue, ref bool updateTreeView)
        {
            ReferencedFileSave rfs = GlueState.Self.CurrentReferencedFileSave;



            #region Opens With

            if (changedMember == "OpensWith")
            {
                if (rfs.OpensWith == "New Application...")
                {
                    string newApplication = EditorData.FileAssociationSettings.SetApplicationForExtension(null, "New Application...");

                    if (!string.IsNullOrEmpty(newApplication))
                    {
                        rfs.OpensWith = newApplication;
                    }
                    else
                    {
                        rfs.OpensWith = "<DEFAULT>";
                    }
                }
            }

            #endregion

            #region Name

            else if (changedMember == "Name")
            {
                if ((string)oldValue != rfs.Name && ProjectManager.GlueProjectSave != null)
                {
                    if ((string)oldValue != null)
                    {
                        RenameReferencedFile((string)oldValue, rfs.Name, rfs, GlueState.Self.CurrentElement);
                    }
                }
            }

            #endregion

            #region LoadedAtRuntime

            if (changedMember == "LoadedAtRuntime")
            {
                updateTreeView = false;
            }

            #endregion

            #region Loaded only when referenced

            else if (changedMember == "LoadedOnlyWhenReferenced")
            {
                updateTreeView = false;
                if (rfs.LoadedOnlyWhenReferenced)
                {
                    // We need to make this public, or else it won't work on WP7 and Silverlight.
                    // Update - The preferred method to get access to this stuff by string is either
                    // GetMember or GetStaticMember, so there's no reason to force this stuff as public
                    // when LoadedWhenReferenced is set to true.
                    //rfs.HasPublicProperty = true;
                }
            }

            #endregion

            #region Has public property

            else if (changedMember == "HasPublicProperty")
            {
                updateTreeView = false;
                // GetMember and GetStaticMember
                // make it so we no longer require
                // the member to be public.
                //if (rfs.LoadedOnlyWhenReferenced && !rfs.HasPublicProperty)
                //{
                //    System.Windows.Forms.MessageBox.Show("This file must have a public property if it " +
                //        "is \"Loaded Only When Referenced\" so that it can be accessed through reflection " +
                //        "on non-PC platforms.");

                //    rfs.HasPublicProperty = true;
                //}

                //if (rfs.ContainerType == ContainerType.None && rfs.HasPublicProperty == false)
                //{
                //    System.Windows.Forms.MessageBox.Show("Global content must be public so custom code can access it.");
                //    rfs.HasPublicProperty = true;
                //}
            }

            #endregion

            #region IsSharedStatic

            else if (changedMember == "IsSharedStatic")
            {
                updateTreeView = false;
                // If this is made IsSharedStatic, that means that the file will not be added to managers
                // We should see if any named objects reference this and notify the user
                List <NamedObjectSave> namedObjects = EditorLogic.CurrentElement.NamedObjects;

                foreach (NamedObjectSave namedObject in namedObjects)
                {
                    if (namedObject.SourceType == SourceType.File && namedObject.SourceFile == rfs.Name && namedObject.AddToManagers == false)
                    {
                        DialogResult result = MessageBox.Show("The object " + namedObject.InstanceName + " references this file.  " +
                                                              "Shared files are not added to the engine, but since the object has its AddToManagers also set to false " +
                                                              "the content in this file will not be added to managers.  Would you like to set the object's AddToManagers to " +
                                                              "true?", "Add to managers?", MessageBoxButtons.YesNo);

                        if (result == DialogResult.Yes)
                        {
                            namedObject.AddToManagers = true;
                        }
                    }
                }
            }

            #endregion

            #region IsDatabaseForLocalizing

            else if (changedMember == "IsDatabaseForLocalizing")
            {
                updateTreeView = false;
                bool oldValueAsBool = (bool)oldValue;
                bool newValue       = rfs.IsDatabaseForLocalizing;

                if (newValue)
                {
                    TaskManager.Self.AddSync(() => RemoveCodeForCsv(rfs), "Removing old CSV");
                }
                else
                {
                    CsvCodeGenerator.GenerateAndSaveDataClass(rfs, rfs.CsvDelimiter);
                }

                // Let's revert the change just to see if
                // things have changed project-wide, and if
                // have to tell the user to re-generate all code.
                rfs.IsDatabaseForLocalizing = oldValueAsBool;
                ObjectFinder.Self.GlueProject.UpdateIfTranslationIsUsed();
                bool oldProjectLocalization = ObjectFinder.Self.GlueProject.UsesTranslation;

                rfs.IsDatabaseForLocalizing = newValue;
                ObjectFinder.Self.GlueProject.UpdateIfTranslationIsUsed();
                bool newProjectLocalization = ObjectFinder.Self.GlueProject.UsesTranslation;



                if (oldProjectLocalization != newProjectLocalization)
                {
                    MessageBox.Show("Because of the change to the \"Is Database For Localizing\" the generated code for the entire project is likely out of date." +
                                    "We recommend closing and re-opening the project in Glue to cause a full regeneration.", "Generated code is out of date");
                }
            }

            #endregion

            #region UseContentPipeline

            else if (changedMember == "UseContentPipeline")
            {
                ContentPipelineHelper.ReactToUseContentPipelineChange(rfs);

                // Make sure that
                // all other RFS's
                // that use this file
                // get changed too.
                List <ReferencedFileSave> matchingRfses = ObjectFinder.Self.GetMatchingReferencedFiles(rfs);

                foreach (ReferencedFileSave rfsToUpdate in matchingRfses)
                {
                    rfsToUpdate.UseContentPipeline = rfs.UseContentPipeline;
                    // No need to
                    // call this method
                    // because there's only
                    // one file in the project
                    // even though there's multiple
                    // ReferencedFileSaves, and this
                    // method just modifies the content
                    // project.
                    //ContentPipelineHelper.ReactToUseContentPipelineChange(rfsToUpdate);

                    IElement container = rfsToUpdate.GetContainer();

                    if (container != null)
                    {
                        CodeWriter.GenerateCode(container);
                    }
                    else
                    {
                        GlueCommands.Self.GenerateCodeCommands.GenerateGlobalContentCode();
                    }
                }


                updateTreeView = false;
            }

            #endregion

            #region TextureFormat

            else if (changedMember == "TextureFormat")
            {
                ContentPipelineHelper.UpdateTextureFormatFor(rfs);

                // See the UseContentPipeline section for comments on what this
                // code does.
                List <ReferencedFileSave> matchingRfses = ObjectFinder.Self.GetMatchingReferencedFiles(rfs);
                foreach (ReferencedFileSave rfsToUpdate in matchingRfses)
                {
                    rfsToUpdate.TextureFormat = rfs.TextureFormat;
                    IElement container = rfsToUpdate.GetContainer();

                    if (container != null)
                    {
                        CodeWriter.GenerateCode(container);
                    }
                    else
                    {
                        GlueCommands.Self.GenerateCodeCommands.GenerateGlobalContentCode();
                    }
                }


                updateTreeView = false;
            }

            #endregion

            #region IncludeDirectoryRelativeToContainer

            else if (changedMember == "IncludeDirectoryRelativeToContainer")
            {
                if (rfs.GetContainerType() == ContainerType.None)
                {
                    // This RFS
                    // is in GlobalContent
                    // so we need to find all
                    // RFS's that use this RFS
                    // and regenerate them
                    List <IElement> elements = ObjectFinder.Self.GetAllElementsReferencingFile(rfs.Name);

                    foreach (IElement element in elements)
                    {
                        CodeWriter.GenerateCode(element);
                    }
                }
                else
                {
                }
            }

            #endregion

            #region AdditionalArguments

            else if (changedMember == "AdditionalArguments")
            {
                rfs.PerformExternalBuild(runAsync: true);
            }

            #endregion

            #region CreatesDictionary

            else if (changedMember == "CreatesDictionary")
            {
                // This could change things like the constants added to the code file, so let's generate the code now.
                GlueCommands.Self.GenerateCodeCommands.GenerateCurrentCsvCode();
            }

            #endregion
        }
Beispiel #4
0
        private static void DragAddFileToGlobalContent(TreeNode treeNodeMoving, ReferencedFileSave referencedFileSave)
        {
            if (referencedFileSave.GetContainerType() == ContainerType.None)
            {
                // This means the user dragged a file from global content onto the global content tree node -
                // we shouldn't do anything here.  It's not a valid operation, but at the same time, it may have
                // happened accidentally and we don't want to burden the user with popups.
            }
            else
            {
                bool isAlreadyPartOfReferencedFiles = false;
                // If the file is already part of GlobalContent, then warn the user and do nothing
                foreach (ReferencedFileSave fileInGlobalContent in ObjectFinder.Self.GlueProject.GlobalFiles)
                {
                    if (fileInGlobalContent.Name == referencedFileSave.Name)
                    {
                        isAlreadyPartOfReferencedFiles = true;
                        break;
                    }
                }


                if (isAlreadyPartOfReferencedFiles)
                {
                    MessageBox.Show("The file\n\n" + referencedFileSave.Name + "\n\nis already a Global Content File");
                }
                else
                {
                    // If we got here, that means that the file that
                    // the user is dragging in to Global Content Files
                    // can be added to Global Content Files; however, the
                    // owner of the file may not be using global content.  We
                    // should ask the user if the containing IElement should use
                    // global content
                    IElement container = referencedFileSave.GetContainer();



                    if (!container.UseGlobalContent)
                    {
                        string screenOrEntity = "Screen";

                        if (container is EntitySave)
                        {
                            screenOrEntity = "Entity";
                        }

                        DialogResult result = MessageBox.Show("The " + screenOrEntity + " " + container.ToString() +
                                                              "does not UseGlobalContent.  Would you like " +
                                                              " to set UseGlobalContent to true?", "Set UseGlobalContent to true?", MessageBoxButtons.YesNo);

                        if (result == DialogResult.Yes)
                        {
                            container.UseGlobalContent = true;
                        }
                    }

                    bool useFullPathAsName = true;
                    ElementCommands.Self.AddReferencedFileToGlobalContent(referencedFileSave.Name, useFullPathAsName);

                    GlobalContentCodeGenerator.UpdateLoadGlobalContentCode();

                    ProjectManager.SaveProjects();
                    GluxCommands.Self.SaveGlux();
                }
            }
        }
Beispiel #5
0
        public static bool UpdateFile(string changedFile)
        {
            bool shouldSave = false;
            bool handled    = false;

            lock (mUpdateFileLock)
            {
                if (ProjectManager.ProjectBase != null)
                {
                    handled = TryHandleProjectFileChanges(changedFile);

                    string projectFileName = ProjectManager.ProjectBase.FullFileName;

                    var standardizedGlux = FileManager.RemoveExtension(FileManager.Standardize(projectFileName).ToLower()) + ".glux";
                    var partialGlux      = FileManager.RemoveExtension(FileManager.Standardize(projectFileName).ToLower()) + @"\..*\.generated\.glux";
                    var partialGluxRegex = new Regex(partialGlux);
                    if (!handled && ((changedFile.ToLower() == standardizedGlux) || partialGluxRegex.IsMatch(changedFile.ToLower())))
                    {
                        TaskManager.Self.OnUiThread(ReloadGlux);
                        handled = true;
                    }

                    if (ProjectManager.IsContent(changedFile))
                    {
                        PluginManager.ReactToChangedFile(changedFile);
                    }

                    #region If it's a CSV, then re-generate the code for the objects

                    string extension = FileManager.GetExtension(changedFile);

                    if (extension == "csv" ||
                        extension == "txt")
                    {
                        ReferencedFileSave rfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(changedFile);

                        bool shouldGenerate = rfs != null &&
                                              (extension == "csv" || rfs.TreatAsCsv) &&
                                              rfs.IsDatabaseForLocalizing == false;

                        if (shouldGenerate)
                        {
                            try
                            {
                                CsvCodeGenerator.GenerateAndSaveDataClass(rfs, rfs.CsvDelimiter);

                                shouldSave = true;
                            }
                            catch (Exception e)
                            {
                                GlueCommands.Self.PrintError("Error saving Class from CSV " + rfs.Name +
                                                             "\n" + e.ToString());
                            }
                        }
                    }


                    #endregion

                    #region If it's a file that references other content we may need to update the project

                    if (FileHelper.DoesFileReferenceContent(changedFile))
                    {
                        ReferencedFileSave rfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(changedFile);


                        if (rfs != null)
                        {
                            string error;
                            rfs.RefreshSourceFileCache(false, out error);

                            if (!string.IsNullOrEmpty(error))
                            {
                                ErrorReporter.ReportError(rfs.Name, error, false);
                            }
                            else
                            {
                                handled = true;
                            }

                            handled   |= GlueCommands.Self.ProjectCommands.UpdateFileMembershipInProject(rfs);
                            shouldSave = true;

                            MainGlueWindow.Self.Invoke((MethodInvoker) delegate
                            {
                                if (rfs.GetContainerType() == ContainerType.Entity)
                                {
                                    if (EditorLogic.CurrentEntityTreeNode != null)
                                    {
                                        if (EditorLogic.CurrentEntitySave == rfs.GetContainer())
                                        {
                                            PluginManager.RefreshCurrentElement();
                                        }
                                    }
                                }
                                else if (rfs.GetContainerType() == ContainerType.Screen)
                                {
                                    if (EditorLogic.CurrentScreenTreeNode != null)
                                    {
                                        if (EditorLogic.CurrentScreenSave == rfs.GetContainer())
                                        {
                                            PluginManager.RefreshCurrentElement();
                                        }
                                    }
                                }
                            });
                        }
                        else
                        {
                            // There may not be a RFS for this in Glue, but even if there's not,
                            // this file may be referenced by other RFS's.  I don't want to do a full
                            // project scan, so we'll just see if this file is part of Visual Studio.  If so
                            // then let's add its children

                            if (ProjectManager.ContentProject.IsFilePartOfProject(changedFile))
                            {
                                string relativePath = ProjectManager.MakeRelativeContent(changedFile);

                                shouldSave |= GlueCommands.Self.ProjectCommands.UpdateFileMembershipInProject(
                                    ProjectManager.ProjectBase, relativePath, false, false);
                                handled |= shouldSave;
                            }
                        }
                    }

                    #endregion

                    #region If it's a .cs file, we should see if we've added a new .cs file, and if so refresh the Element for it
                    if (extension == "cs")
                    {
                        TaskManager.Self.OnUiThread(() => ReactToChangedCodeFile(changedFile));
                    }


                    #endregion

                    #region Maybe it's a directory that was added or removed

                    if (FileManager.GetExtension(changedFile) == "")
                    {
                        ElementViewWindow.Invoke((MethodInvoker) delegate
                        {
                            try
                            {
                                // It's a directory, so let's just rebuild our directory TreeNodes
                                ElementViewWindow.AddDirectoryNodes();
                            }
                            catch (System.IO.IOException)
                            {
                                // this could be because something else is accessing the directory, so sleep, try again
                                System.Threading.Thread.Sleep(100);
                                ElementViewWindow.AddDirectoryNodes();
                            }
                        });
                    }

                    #endregion


                    #region Check for broken references to objects in file - like an Entity may reference an object in a file but it may have been removed

                    if (ObjectFinder.Self.GetReferencedFileSaveFromFile(changedFile) != null)
                    {
                        // This is a file that is part of the project, so let's see if any named objects are missing references
                        CheckForBrokenReferencesToObjectsInFile(changedFile);
                    }

                    #endregion

                    // This could be an externally built file:

                    ProjectManager.UpdateExternallyBuiltFile(changedFile);

                    if (handled)
                    {
                        PluginManager.ReceiveOutput("Handled changed file: " + changedFile);
                    }

                    if (shouldSave)
                    {
                        ProjectManager.SaveProjects();
                    }
                }
            }

            return(handled);
        }
        private void UpdateIncludedAndExcluded(ReferencedFileSave instance)
        {
            ResetToDefault();

            AssetTypeInfo ati = instance.GetAssetTypeInfo();


            ExcludeMember(nameof(ReferencedFileSave.InvalidFileNameCharacters));
            ExcludeMember(nameof(ReferencedFileSave.ToStringDelegate));
            ExcludeMember(nameof(ReferencedFileSave.Properties));

            ContainerType containerType = instance.GetContainerType();

            if (containerType == ContainerType.Entity)
            {
                // We do this because this is set automatically if the Entity is unique
                ExcludeMember(nameof(ReferencedFileSave.IsSharedStatic));

                // We do this because whether the objects from a file are manually updated or not
                // should be up to the entity, not the source file.
                ExcludeMember(nameof(ReferencedFileSave.IsManuallyUpdated));
            }

            if (containerType == ContainerType.Entity || ati == null || ati.QualifiedRuntimeTypeName.QualifiedType != "Microsoft.Xna.Framework.Media.Song")
            {
                ExcludeMember(nameof(ReferencedFileSave.DestroyOnUnload));
            }

            #region Extension-based additions/removals
            string extension = FileManager.GetExtension(instance.Name);

            if (extension != "csv" && !instance.TreatAsCsv)
            {
                ExcludeMember(nameof(ReferencedFileSave.CreatesDictionary));
                ExcludeMember(nameof(ReferencedFileSave.IsDatabaseForLocalizing));
                ExcludeMember(nameof(ReferencedFileSave.UniformRowType));
            }
            else
            {
                IncludeMember(nameof(ReferencedFileSave.UniformRowType), typeof(ReferencedFileSave), new AvailablePrimitiveTypeArraysStringConverter());
            }

            if ((extension != "txt" && extension != "csv") ||
                (extension == "txt" && instance.TreatAsCsv == false)
                )
            {
                ExcludeMember(nameof(ReferencedFileSave.CsvDelimiter));
            }

            if (extension != "txt")
            {
                ExcludeMember(nameof(ReferencedFileSave.TreatAsCsv));
            }

            if (extension == "png")
            {
                Attribute[] fileDetailsCategoryAttribute = new Attribute[] {
                    new CategoryAttribute("File Details")
                };
                IncludeMember("ImageWidth", typeof(int), null, GetImageWidth, null, fileDetailsCategoryAttribute);
                IncludeMember("ImageHeight", typeof(int), null, GetImageHeight, null, fileDetailsCategoryAttribute);
            }

            if (extension == "emix")
            {
                Attribute[] fileDetailsCategoryAttribute = new Attribute[] {
                    new CategoryAttribute("File Details")
                };

                IncludeMember("EquilibriumParticleCount", typeof(float), null, GetEquilibriumParticleCount, null, fileDetailsCategoryAttribute);
                IncludeMember("BurstParticleCount", typeof(float), null, GetBurstParticleCount, null, fileDetailsCategoryAttribute);
            }

            #endregion

            AddProjectSpecificFileMember();


            if (!instance.LoadedAtRuntime)
            {
                ExcludeMember(nameof(ReferencedFileSave.IsSharedStatic));
                ExcludeMember(nameof(ReferencedFileSave.IsManuallyUpdated));
                ExcludeMember(nameof(ReferencedFileSave.LoadedOnlyWhenReferenced));
                ExcludeMember(nameof(ReferencedFileSave.HasPublicProperty));
                ExcludeMember("InstanceName");
                ExcludeMember(nameof(ReferencedFileSave.IncludeDirectoryRelativeToContainer));
            }

            if (ati == null || string.IsNullOrEmpty(ati.MakeManuallyUpdatedMethod))
            {
                ExcludeMember(nameof(ReferencedFileSave.IsManuallyUpdated));
            }

            if (!instance.GetCanUseContentPipeline())
            {
                ExcludeMember(nameof(ReferencedFileSave.UseContentPipeline));
            }
            if (!instance.UseContentPipeline || ati.QualifiedRuntimeTypeName.QualifiedType != "Microsoft.Xna.Framework.Graphics.Texture2D")
            {
                ExcludeMember("TextureFormat");
            }

            IncludeMember("OpensWith", typeof(ReferencedFileSave), new AvailableApplicationsStringConverters());

            bool shouldShowRuntimeType = instance.LoadedAtRuntime;
            if (shouldShowRuntimeType)
            {
                IncludeMember("RuntimeType", typeof(ReferencedFileSave), new AvailableRuntimeTypeConverter()
                {
                    ReferencedFileSave = instance
                });
            }
            else
            {
                ExcludeMember(nameof(ReferencedFileSave.RuntimeType));
            }

            if (string.IsNullOrEmpty(instance.SourceFile))
            {
                ExcludeMember(nameof(ReferencedFileSave.SourceFile));
                ExcludeMember(nameof(ReferencedFileSave.BuildTool));
                ExcludeMember(nameof(ReferencedFileSave.AdditionalArguments));
                ExcludeMember(nameof(ReferencedFileSave.ConditionalCompilationSymbols));
            }
            else
            {
            }
        }