Ejemplo n.º 1
0
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            try
            {
                GorgonExample.PlugInLocationDirectory = new DirectoryInfo(Settings.Default.PlugInLocation);
                GorgonExample.ResourceBaseDirectory   = new DirectoryInfo(Settings.Default.ResourceLocation);

                // Create our virtual file system.
                _fileSystem = new GorgonFileSystem(Program.Log);
                _writer     = new GorgonFileSystemWriter(_fileSystem, Program.WriteDirectory.FullName);

                LoadText();

                labelFileSystem.Text    = $"{GorgonExample.GetResourcePath(@"FolderSystem\").FullName.Ellipses(100, true)} mounted as '/'.";
                labelWriteLocation.Text = $"{Program.WriteDirectory.FullName.Ellipses(100, true)} mounted as '/'";
            }
            catch (Exception ex)
            {
                GorgonExample.HandleException(ex);
                GorgonApplication.Quit();
            }
            finally
            {
                CommandEnable(!string.Equals(_originalText, _changedText, StringComparison.CurrentCulture));
                UpdateInfo();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            try
            {
                _writePath = Path.GetDirectoryName(Gorgon.Log.LogPath) + @"\Examples\FileSystem.Writing\";

                // Create our virtual file system.
                _fileSystem = new GorgonFileSystem();

                LoadText();

                labelFileSystem.Text    = string.Format("{0} mounted as '/'.", Program.GetResourcePath(@"FolderSystem\").Ellipses(100, true));
                labelWriteLocation.Text = string.Format("{0} mounted as '/'", _writePath.Ellipses(100, true));
            }
            catch (Exception ex)
            {
                GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(this, ex));
                Application.Exit();
            }
            finally
            {
                itemLoadChanged.Enabled = !string.Equals(textDisplay.Text, _originalText, StringComparison.CurrentCulture);
                UpdateInfo();
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GorgonFileSystemDirectory"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system that owns this directory.</param>
 /// <param name="name">The name of the directory.</param>
 /// <param name="parent">Parent directory.</param>
 internal GorgonFileSystemDirectory(GorgonFileSystem fileSystem, string name, GorgonFileSystemDirectory parent)
     : base(name.RemoveIllegalPathChars())
 {
     Directories = new GorgonFileSystemDirectoryCollection();
     FileSystem  = fileSystem;
     Files       = new GorgonFileSystemFileEntryCollection(this);
     Parent      = parent;
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VirtualDirectory" /> class.
 /// </summary>
 /// <param name="mountPoint">The mount point that supplied this directory.</param>
 /// <param name="fileSystem">The file system that contains the directory.</param>
 /// <param name="parentDirectory">The parent of this directory.</param>
 /// <param name="name">The name of the directory.</param>
 public VirtualDirectory(GorgonFileSystemMountPoint mountPoint, GorgonFileSystem fileSystem, VirtualDirectory parentDirectory, string name)
 {
     MountPoint  = mountPoint;
     FileSystem  = fileSystem;
     Name        = name != "/" ? name.FormatPathPart() : name;
     Parent      = parentDirectory;
     Directories = new VirtualDirectoryCollection(this);
     Files       = new VirtualFileCollection(this);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Initializes the <see cref="GorgonEditorFile"/> class.
        /// </summary>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="fileSystem"/> parameter is NULL (Nothing in VB.Net).</exception>
        public GorgonEditorFile(GorgonFileSystem fileSystem)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException("fileSystem");
            }

            FileSystem    = fileSystem;
            Dependencies  = new Dictionary <string, GorgonEditorDependencyCollection>();
            _fileHandlers = new Dictionary <Type, Func <Stream, IReadOnlyDictionary <GorgonEditorDependency, object>, object> >();
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            try
            {
                // Picture box.
                _picture = new PictureBox {
                    Name = "pictureImage"
                };

                // Text display.
                _textDisplay = new TextBox {
                    Name = "textDisplay"
                };
                _textFont         = new Font("Consolas", 10.0f, FontStyle.Regular, GraphicsUnit.Point);
                _textDisplay.Font = _textFont;

                _instructions = new Label
                {
                    Name      = "labelInstructions",
                    Text      = "Double click on a file node in the tree to display it.",
                    AutoSize  = false,
                    TextAlign = ContentAlignment.MiddleCenter,
                    Dock      = DockStyle.Fill,
                    Font      = Font
                };

                // Add the instructions.
                splitFileSystem.Panel2.Controls.Add(_instructions);

                // Create the file system.
                _fileSystem = new GorgonFileSystem();

                // Get the zip file provider.
                LoadZipFileSystemProvider();

                // Mount the physical file system directory.
                _fileSystem.Mount(Program.GetResourcePath(@"VFSRoot\"));

                // Mount the zip file into a sub directory.
                _fileSystem.Mount(Program.GetResourcePath("VFSRoot.zip"), "/ZipFile");

                // Fill the root of the tree.
                FillTree(null);
            }
            catch (Exception ex)
            {
                GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(this, ex));
                Application.Exit();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Function to return the file system used for writing out temporary data.
        /// </summary>
        /// <param name="tempDirectory">The physical directory to store the temporary data into.</param>
        /// <returns>A new writable file system for writing temporary data into.</returns>
        private IGorgonFileSystemWriter <Stream> GetScratchArea(DirectoryInfo tempDirectory)
        {
            string scratchPath = Path.Combine(tempDirectory.FullName, "Tools", GetType().FullName).FormatDirectory(Path.DirectorySeparatorChar);

            if (!Directory.Exists(scratchPath))
            {
                Directory.CreateDirectory(scratchPath);
            }

            var scratchArea = new GorgonFileSystem(CommonServices.Log);

            scratchArea.Mount(scratchPath);
            return(new GorgonFileSystemWriter(scratchArea, scratchPath));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="GorgonFileSystemRamDiskWriter"/> class.
        /// </summary>
        /// <param name="fileSystem">A file system used to track the updates when writing.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="fileSystem" /> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="fileSystem"/> does not contain a <see cref="GorgonFileSystemRamDiskProvider"/>.</exception>
        public GorgonFileSystemRamDiskWriter(GorgonFileSystem fileSystem)
            : base(Resources.GORFS_RAMDISK_WRITER_FS_DESC)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }

            _provider = (from providers in fileSystem.Providers
                         let ramProvider = providers as GorgonFileSystemRamDiskProvider
                                           select ramProvider)
                        .FirstOrDefault();

            _ramFiles   = _provider?.FileData ?? throw new ArgumentException(Resources.GORFS_ERR_NO_RAMDISK_PROVIDER, nameof(fileSystem));
            _fileSystem = fileSystem;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Function to load the zip file provider plugin.
        /// </summary>
        /// <returns><b>true</b> if successfully loaded, <b>false</b> if not.</returns>
        private static bool LoadZipProviderPlugIn()
        {
            var zipProviderFile = new FileInfo(Path.Combine(PlugInPath.FormatDirectory(Path.DirectorySeparatorChar), "Gorgon.FileSystem.Zip.dll"));

            // Check to see if the file exists.
            if (!zipProviderFile.Exists)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Could not find the plugin assembly file:\n'{0}'.", zipProviderFile.FullName);
                Console.ResetColor();
#if DEBUG
                Console.ReadKey();
#endif
                return(false);
            }

            // Load the plugin assembly.
            _pluginAssemblies.LoadPlugInAssemblies(zipProviderFile.Directory?.FullName, zipProviderFile.Name);

            // Create our file system provider factory so we can retrieve the zip file provider.
            var providerFactory = new GorgonFileSystemProviderFactory(_pluginService, _log);

            // Get our zip file provider.
            GorgonFileSystemProvider provider;

            try
            {
                provider = providerFactory.CreateProvider(PlugInName);
            }
            catch (GorgonException gEx)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(gEx.Message);
                Console.ResetColor();
#if DEBUG
                Console.ReadKey();
#endif
                return(false);
            }

            _fileSystem = new GorgonFileSystem(provider, _log);

            Console.WriteLine("\nThe zip file file system provider was loaded successfully.");
            return(true);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GorgonFileSystemWriter"/> class.
        /// </summary>
        /// <param name="fileSystem">A file system used to track the updates when writing.</param>
        /// <param name="writeLocation">The directory on the physical file system to actually write data into.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="fileSystem"/>, or the <paramref name="writeLocation"/> parameters are <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="writeLocation"/> is empty.</exception>
        public GorgonFileSystemWriter(GorgonFileSystem fileSystem, string writeLocation)
            : base(Resources.GORFS_FOLDER_WRITER_FS_DESC)
        {
            if (writeLocation == null)
            {
                throw new ArgumentNullException(nameof(writeLocation));
            }

            if (string.IsNullOrWhiteSpace(writeLocation))
            {
                throw new ArgumentEmptyException(nameof(writeLocation));
            }

            // We need the concrete type in here because we need access to its internals.
            _fileSystem   = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
            WriteLocation = writeLocation.FormatDirectory(Path.DirectorySeparatorChar);
            _mountPoint   = new GorgonFileSystemMountPoint(fileSystem.DefaultProvider, WriteLocation, "/");
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Function to load the zip file system provider.
        /// </summary>
        private void LoadZipFileSystemProvider()
        {
            // Name of our zip provider plugin.
            const string zipProviderPlugInName = "Gorgon.IO.Zip.ZipProvider";

            // We can load the objects we need and discard the plugin system after.
            // This works because we keep the references to the objects that our
            // plugin creates, even after the plugin is gone.
            using (var pluginAssemblies = new GorgonMefPlugInCache(Program.Log))
            {
                pluginAssemblies.LoadPlugInAssemblies(Program.PlugInPath, "Gorgon.FileSystem.Zip.DLL");

                var providerFactory = new GorgonFileSystemProviderFactory(
                    new GorgonMefPlugInService(pluginAssemblies),
                    Program.Log);

                _fileSystem = new GorgonFileSystem(providerFactory.CreateProvider(zipProviderPlugInName), Program.Log);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Function to determine if this directory, or optionally, any of the sub directories contains a <see cref="IGorgonVirtualFile"/> with the specified file name.
        /// </summary>
        /// <param name="fileName">The name of the file to search for.</param>
        /// <returns><b>true</b> if found, <b>false</b> if not.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="fileName"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="fileName"/> parameter is empty.</exception>
        /// <remarks>
        /// Use this to determine if a <see cref="IGorgonVirtualFile"/> exists under this directory or any of its sub directories. This search includes all sub directories for this and child directories.
        /// To determine if a file exists in the immediate directory, use the <see cref="IGorgonNamedObjectReadOnlyDictionary{T}.Contains"/> method.
        /// </remarks>
        public bool ContainsFile(string fileName)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentEmptyException(nameof(fileName));
            }

            if (Files.Contains(fileName))
            {
                return(true);
            }

            IEnumerable <VirtualDirectory> directories = GorgonFileSystem.FlattenDirectoryHierarchy(this, "*");

            return(directories.Any(item => item.Files.Contains(fileName)));
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Function to retrieve the total number of directories in this directory including any directories under this one.
 /// </summary>
 /// <returns>The total number of directories.</returns>
 /// <remarks>
 /// Use this to retrieve the total number of <see cref="IGorgonVirtualDirectory"/> entries under this directory. This search includes all sub directories for this and child directories. To get
 /// the count of the immediate subdirectories, use the <see cref="IReadOnlyCollection{T}.Count"/> property on the <see cref="IGorgonVirtualDirectory.Directories"/> property.
 /// </remarks>
 public int GetDirectoryCount() => Directories.Count == 0 ? 0 : GorgonFileSystem.FlattenDirectoryHierarchy(this, "*").Count();
Ejemplo n.º 14
0
        /// <summary>
        /// Function to open the editor file.
        /// </summary>
        /// <param name="path">Path to the editor file.</param>
        public static void Open(string path)
        {
            var packFileSystem = new GorgonFileSystem();

            FileChanged = false;

            // Add the new file system as a mount point.
            var plugIns = from plugIn in Gorgon.PlugIns
                          where plugIn is GorgonFileSystemProviderPlugIn &&
                          !PlugIns.IsDisabled(plugIn)
                          select plugIn;

            foreach (var plugIn in plugIns)
            {
                packFileSystem.Providers.LoadProvider(plugIn.Name);
            }

            if (!packFileSystem.Providers.Any(item => item.CanReadFile(path)))
            {
                throw new FileLoadException(string.Format(APIResources.GOREDIT_ERR_NO_READ_PROVIDERS,
                                                          Path.GetFileName(path)));
            }

            packFileSystem.Mount(path);

            try
            {
                // Remove our previous scratch data.
                ResetFile();

                // At this point we should have a clean scratch area, so all files will exist in the packed file.
                // Unpack the file structure so we can work with it.
                var directories = packFileSystem.FindDirectories("*", true);
                var files       = packFileSystem.FindFiles("*", true);

                // Create our directories.
                foreach (var directory in directories)
                {
                    ScratchArea.ScratchFiles.CreateDirectory(directory.FullPath);
                }

                // Copy our files.
                foreach (var file in files)
                {
                    using (var inputStream = packFileSystem.OpenStream(file, false))
                    {
                        using (var outputStream = ScratchArea.ScratchFiles.OpenStream(file.FullPath, true))
                        {
                            inputStream.CopyTo(outputStream);
                        }
                    }
                }

                FilePath = string.Empty;
                Filename = Path.GetFileName(path);

                // Load the meta data if it exists.
                EditorMetaDataFile.Load();

                // If we can't write the file, then leave the editor file path as blank.
                // If the file path is blank, then the Save As function will be triggered if we attempt to save so we
                // can save it in a format that we DO understand.  This is of course assuming we have any plug-ins loaded
                // that will allow us to save.
                if (GetWriterPlugIn(path) != null)
                {
                    FilePath = path;
                }
            }
            catch
            {
                // We have a problem, reset whatever changes we've made.
                ResetFile();
                throw;
            }
            finally
            {
                // At this point we don't need this file system any more.  We'll
                // be using our scratch system instead.
                packFileSystem.Clear();
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
            try
            {
                // Create a new file system.
                // The file system must be created first and given access to the various
                // data sources via the provider plug-ins.
                // For example, this will allow us to create a file system that can read
                // a RAR file, while another file system would only cater to Zip files.
                // By default, every file system comes with a folder file system provider
                // that can mount a directory from the hard drive as a VFS root.
                _fileSystem = new GorgonFileSystem();

                Console.WriteLine("Gorgon is capable of mounting virtual file systems for file access.  A virtual");
                Console.WriteLine("filesystem root can be a folder on a harddrive, a zip file, or any data store");
                Console.WriteLine("(assuming there's a provider for it).\n");
                Console.WriteLine("In Gorgon, the types of data that can be mounted as a virtual file system is");
                Console.WriteLine("managed by plug-ins called providers. By default, the file system has a folder");
                Console.WriteLine("provider.  This allows a folder to be mounted as the root of a virtual file\nsystem.\n");
                Console.WriteLine("This example will show how to load extra providers into a file system.\n");

                Console.ForegroundColor = ConsoleColor.White;

                // Get our file system providers.
                Console.WriteLine("Found {0} external file system plug-ins.\n", LoadFileSystemProviders());

                // Loop through each provider and print some info.
                for (int i = 0; i < _fileSystem.Providers.Count; i++)
                {
                    var provider = _fileSystem.Providers[i];

                    // Print some info about the file system provider.
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("{0}. {1}", (i + 1), provider.Name);

                    Console.ForegroundColor = ConsoleColor.Gray;
                    Console.WriteLine("    Description: {0}", provider.Description);

                    // Gather the preferred extensions.
                    // File system providers that use a file (like a Zip file) as its root
                    // have a list of file extensions that are preferred.  For example, the
                    // Zip provider, expects to find *.zip files.  These are merely here
                    // for the convenience of the developer and are formatted like a common
                    // dialog file mask so they can be easily dropped into that control.
                    // In this case, we're going to just strip out the relevant part and
                    // concatenate each preferred extension description into a single string.
                    //
                    // Note that a provider may have multiple preferred extensions.
                    var extensionList = (from preferred in provider.PreferredExtensions
                                         select string.Format("*.{0}", preferred.Extension)).ToArray();

                    if (extensionList.Length > 0)
                    {
                        Console.WriteLine("    Preferred Extensions: {0}", string.Join(", ", extensionList));
                    }
                }

                Console.ResetColor();
                Console.WriteLine("\nPress any key to close.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                // Catch all exceptions here.  If we had logging for the application enabled, then this
                // would record the exception in the log.
                GorgonException.Catch(ex, () =>
                {
                    Console.Clear();
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Exception:\n{0}\n\nStack Trace:{1}", ex.Message, ex.StackTrace);
                });
                Console.ResetColor();
#if DEBUG
                Console.ReadKey();
#endif
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static void Main()
        {
            _log = new GorgonLog("FolderFileSystem", "Tape_Worm");
            _log.LogStart();

            try
            {
                Console.WindowHeight = 26.Max(Console.WindowHeight);
                Console.BufferHeight = Console.WindowHeight;

                // Create a new file system.
                _fileSystem = new GorgonFileSystem(_log);

                // Set the following directory as root on the virtual file system.
                // To mount a directory we need to put in the trailing slash.
                //
                // If we wanted to, we could mount a directory as a sub directory of
                // the root of the virtual file system.  For example, mounting the
                // directory D:\Dir with Mount(@"D:\Dir", "/VFSDir"); would mount the
                // contents of the D:\Dir directory under /VFSDir.
                //
                // It's also important to point out that the old Gorgon "file system"
                // would load files from the system into memory when mounting a
                // directory.  While this version only loads directory and file
                // information when mounting.  This is considerably more efficient.
                string physicalPath = GetResourcePath(@"FolderSystem\");
                _fileSystem.Mount(physicalPath);

                Console.ForegroundColor = ConsoleColor.White;

                Console.WriteLine("This example will mount a physical file system directory as the root of a");
                Console.WriteLine("virtual file system.  The virtual file system is capable of mounting various");
                Console.WriteLine("types of data such as a zip file, a file system folder, etc... as the root or a");
                Console.WriteLine("sub directory.  You can even mount a zip file as the root, and a physical file");
                Console.WriteLine("system directory as a virtual sub directory in the same virtual file system and");
                Console.WriteLine("access them as a single unified file system.");

                Console.Write("\nMounted: ");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("'{0}'", physicalPath.Ellipses(Console.WindowWidth - 20, true));
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write(" as ");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("'/'\n");
                Console.ForegroundColor = ConsoleColor.White;

                // Get a count of all sub directories and files under the root directory.
                IGorgonVirtualDirectory[] directoryList = _fileSystem.FindDirectories("*").ToArray();

                // Display directories.
                Console.WriteLine("Virtual file system contents:");

                for (int i = -1; i < directoryList.Length; i++)
                {
                    IGorgonVirtualDirectory directory = _fileSystem.RootDirectory;

                    // Go into the sub directories under root.
                    if (i > -1)
                    {
                        directory = directoryList[i];
                    }

                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("{0}", directory.FullPath);

                    Console.ForegroundColor = ConsoleColor.Yellow;

                    foreach (IGorgonVirtualFile file in directory.Files)
                    {
                        Console.Write("   {0}", file.Name);
                        // Align the size to the same place.
                        Console.CursorLeft = 65;
                        Console.WriteLine("{0}", file.Size.FormatMemory());
                    }
                }

                Console.ResetColor();
                Console.WriteLine("\nPress any key to close.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                ex.Catch(_ =>
                {
                    Console.Clear();
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Exception:\n{0}\n\nStack Trace:{1}", _.Message, _.StackTrace);

                    Console.ResetColor();
#if DEBUG
                    Console.ReadKey();
#endif
                },
                         _log);
            }
            finally
            {
                _log.LogEnd();
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
            try
            {
                Console.WindowHeight = 28;
                Console.BufferHeight = Console.WindowHeight;

                // Create a new file system.
                _fileSystem = new GorgonFileSystem();

                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("This example will mount a zip file as the root of a virtual file system.  The");
                Console.WriteLine("virtual file system is capable of mounting various types of data such as a zip,");
                Console.WriteLine("a file system folder, etc... as the root or a sub directory.  You can even");
                Console.WriteLine("mount a zip file as the root, and a physical file system directory as a virtual");
                Console.WriteLine("sub directory in the same virtual file system and access them as a single");
                Console.WriteLine("unified file system.");

                // Unlike the folder file system example, we need to load
                // a provider to handle zip files before trying to mount
                // one.
                if (!LoadZipProviderPlugIn())
                {
                    return;
                }

                // Set the following zip file as root on the virtual file system.
                //
                // If we wanted to, we could mount a zip file as a sub directory of
                // the root of the virtual file system.  For example, mounting the
                // directory D:\Dir\zipFile.zip with Mount(@"D:\Dir", "/VFSDir"); would mount
                // the contents of the D:\Dir\zipFile.zip directory under /VFSDir.
                //
                // It's also important to point out that the old Gorgon "file system"
                // would load files from the system into memory when mounting a
                // directory.  While this version only loads directory and file
                // information when mounting.  This is considerably more efficient.
                var physicalPath = GetResourcePath(@"FileSystem.zip");
                _fileSystem.Mount(physicalPath);

                Console.Write("\nMounted: ");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("'{0}'", physicalPath.Ellipses(Console.WindowWidth - 20, true));
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write(" as ");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("'/'\n");
                Console.ForegroundColor = ConsoleColor.White;

                // Get a count of all sub directories and files under the root directory.
                var directoryList = _fileSystem.FindDirectories("*", true).ToArray();

                // Display directories.
                Console.WriteLine("Virtual file system contents:");

                for (int i = -1; i < directoryList.Length; i++)
                {
                    GorgonFileSystemDirectory directory = _fileSystem.RootDirectory;

                    // Go into the sub directories under root.
                    if (i > -1)
                    {
                        directory = directoryList[i];
                    }

                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("{0}", directory.FullPath);

                    Console.ForegroundColor = ConsoleColor.Yellow;

                    foreach (var file in directory.Files)
                    {
                        Console.Write("   {0}", file.Name);
                        // Align the size to the same place.
                        Console.CursorLeft = 65;
                        Console.WriteLine("{0}", file.Size.FormatMemory());
                    }
                }

                Console.ResetColor();
                Console.WriteLine("\nPress any key to close.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                // Catch all exceptions here.  If we had logging for the application enabled, then this
                // would record the exception in the log.
                GorgonException.Catch(ex, () =>
                {
                    Console.Clear();
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Exception:\n{0}\n\nStack Trace:{1}", ex.Message, ex.StackTrace);

                    Console.ResetColor();
#if DEBUG
                    Console.ReadKey();
#endif
                });
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Function to load a <see cref="IGorgonAnimation"/> from a <see cref="GorgonFileSystem"/>.
        /// </summary>
        /// <param name="fileSystem">The file system to load the animation from.</param>
        /// <param name="renderer">The renderer for the animation.</param>
        /// <param name="path">The path to the animation file in the file system.</param>
        /// <param name="textureOptions">[Optional] Options for the texture loaded associated the sprite.</param>
        /// <param name="animationCodecs">The list of animation codecs to try and load the animation with.</param>
        /// <param name="imageCodecs">The list of image codecs to try and load the animation texture(s) with.</param>
        /// <returns>The animation data in the file as a <see cref="IGorgonAnimation"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="fileSystem"/>, <paramref name="renderer"/>, or <paramref name="path"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="path"/> parameter is empty.</exception>
        /// <exception cref="FileNotFoundException">Thrown if the file in the <paramref name="path"/> was not found.</exception>
        /// <exception cref="GorgonException">Thrown if the animation data in the file system could not be loaded because a suitable codec was not found.</exception>
        /// <remarks>
        /// <para>
        /// This method extends a <see cref="GorgonFileSystem"/> so that animations can be loaded by calling a method on the file system object itself. This negates the need for users to create complex code
        /// for loading an animation.
        /// </para>
        /// <para>
        /// When loading an animation, the method will attempt to locate any <see cref="GorgonTexture2DView"/> objects associated with the animation (if they exist). When loading, it will check:
        /// <list type="number">
        ///     <item>
        ///         <description>For a texture resource with the same name that is already loaded into memory.</description>
        ///     </item>
        ///     <item>
        ///         <description>Use the local <see cref="IGorgonVirtualDirectory"/> for the sprite file and search for the texture in that directory.</description>
        ///     </item>
        ///     <item>
        ///         <description>Check the entire <paramref name="fileSystem"/> for a file if the texture name contains path information (this is done by the GorgonEditor from v2).</description>
        ///     </item>
        /// </list>
        /// If the file is found, and can be loaded by one of the <paramref name="imageCodecs"/>, then it is loaded and assigned to the sprite.
        /// </para>
        /// <para>
        /// The <paramref name="animationCodecs"/> is a list of codecs for loading sprite data. If the user specifies this parameter, the only the codecs provided will be used for determining if an
        /// animation can be read. If it is not supplied, then all built-in (i.e. not plug in based) sprite codecs will be used.
        /// </para>
        /// <para>
        /// The <paramref name="imageCodecs"/> is a list of codecs for loading image data. If the user specifies this parameter, the only the codecs provided will be used for determining if an image can be
        /// read. If it is not supplied, then all built-in (i.e. not plug in based) image codecs will be used.
        /// </para>
        /// </remarks>
        /// <seealso cref="GorgonFileSystem"/>
        /// <seealso cref="GorgonTexture2DView"/>
        /// <seealso cref="IGorgonAnimation"/>
        public static IGorgonAnimation LoadAnimationFromFileSystem(this GorgonFileSystem fileSystem,
                                                                   Gorgon2D renderer,
                                                                   string path,
                                                                   GorgonTexture2DLoadOptions textureOptions           = null,
                                                                   IEnumerable <IGorgonAnimationCodec> animationCodecs = null,
                                                                   IEnumerable <IGorgonImageCodec> imageCodecs         = null)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }

            IGorgonVirtualFile file = fileSystem.GetFile(path);

            if (file == null)
            {
                throw new FileNotFoundException(string.Format(Resources.GOR2DIO_ERR_FILE_NOT_FOUND, path));
            }

            if ((imageCodecs == null) || (!imageCodecs.Any()))
            {
                // If we don't specify any codecs, then use the built in ones.
                imageCodecs = new IGorgonImageCodec[]
                {
                    new GorgonCodecPng(),
                    new GorgonCodecBmp(),
                    new GorgonCodecDds(),
                    new GorgonCodecGif(),
                    new GorgonCodecJpeg(),
                    new GorgonCodecTga(),
                };
            }
            else
            {
                // Only use codecs that can decode image data.
                imageCodecs = imageCodecs.Where(item => item.CanDecode);
            }

            if ((animationCodecs == null) || (!animationCodecs.Any()))
            {
                // Use all built-in codecs if we haven't asked for any.
                animationCodecs = new IGorgonAnimationCodec[]
                {
                    new GorgonV3AnimationBinaryCodec(renderer),
                    new GorgonV3AnimationJsonCodec(renderer),
                    new GorgonV1AnimationCodec(renderer)
                };
            }
            else
            {
                // Only use codecs that can decode sprite data.
                animationCodecs = animationCodecs.Where(item => item.CanDecode);
            }

            Stream animStream = file.OpenStream();

            try
            {
                if (!animStream.CanSeek)
                {
                    Stream newStream = new DataStream((int)animStream.Length, true, true);
                    animStream.CopyTo(newStream);
                    newStream.Position = 0;

                    animStream.Dispose();
                    animStream = newStream;
                }

                IGorgonAnimationCodec animationCodec = GetAnimationCodec(animStream, animationCodecs);

                if (animationCodec == null)
                {
                    throw new GorgonException(GorgonResult.CannotRead, string.Format(Resources.GOR2DIO_ERR_NO_SUITABLE_ANIM_CODEC_FOUND, path));
                }

                // Load the animation.
                IGorgonAnimation animation = animationCodec.FromStream(animStream, (int)file.Size);

                // We have no textures to update, leave.
                if (animation.Texture2DTrack.KeyFrames.Count == 0)
                {
                    return(animation);
                }

                // Try to locate the textures.

                // V1 sprite animations need texture coordinate correction.
                bool needsCoordinateFix = animationCodec is GorgonV1AnimationCodec;

                foreach (GorgonKeyTexture2D textureKey in animation.Texture2DTrack.KeyFrames)
                {
                    // Let's try and load the texture into memory.
                    // This does this by:
                    // 1. Checking to see if a texture resource with the name specified is already available in memory.
                    // 2. Checking the local directory of the file to see if the texture is there.
                    // 3. A file system wide search.

                    // ReSharper disable once InvertIf
                    (IGorgonImageCodec codec, IGorgonVirtualFile textureFile, bool loaded) =
                        LocateTextureCodecAndFile(fileSystem, file.Directory, renderer, textureKey.TextureName, imageCodecs);

                    // We have not loaded the texture yet.  Do so now.
                    // ReSharper disable once InvertIf
                    if ((!loaded) && (textureFile != null) && (codec != null))
                    {
                        using (Stream textureStream = textureFile.OpenStream())
                        {
                            textureKey.Value = GorgonTexture2DView.FromStream(renderer.Graphics,
                                                                              textureStream,
                                                                              codec,
                                                                              textureFile.Size, GetTextureOptions(textureFile.FullPath, textureOptions));
                        }
                    }

                    if ((needsCoordinateFix) && (textureKey.Value != null))
                    {
                        textureKey.TextureCoordinates = new RectangleF(textureKey.TextureCoordinates.X / textureKey.Value.Width,
                                                                       textureKey.TextureCoordinates.Y / textureKey.Value.Height,
                                                                       textureKey.TextureCoordinates.Width / textureKey.Value.Width,
                                                                       textureKey.TextureCoordinates.Height / textureKey.Value.Height);
                    }
                }

                return(animation);
            }
            finally
            {
                animStream?.Dispose();
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Function called to initialize the application.
        /// </summary>
        private void Initialize()
        {
            // Resize and center the screen.
            var screen = Screen.FromHandle(Handle);

            ClientSize = Settings.Default.Resolution;
            Location   = new Point(screen.Bounds.Left + screen.WorkingArea.Width / 2 - ClientSize.Width / 2, screen.Bounds.Top + screen.WorkingArea.Height / 2 - ClientSize.Height / 2);

            // Initialize our graphics.
            _graphics = new GorgonGraphics();
            _2D       = _graphics.Output.Create2DRenderer(this, ClientSize.Width, ClientSize.Height, BufferFormat.R8G8B8A8_UIntNormal, Settings.Default.IsWindowed);

            // Show the logo because I'm insecure.
            _2D.IsLogoVisible = true;

            // Create fonts.
            _textFont = _graphics.Fonts.CreateFont("GiGi_24pt", new GorgonFontSettings
            {
                FontFamilyName   = "GiGi",
                AntiAliasingMode = FontAntiAliasMode.AntiAlias,
                Size             = 24.0f,
                FontHeightMode   = FontHeightMode.Points,
                TextureSize      = new Size(512, 256)
            });

            // Use the form font for this one.
            _helpFont = _graphics.Fonts.CreateFont("FormFont", new GorgonFontSettings
            {
                FontFamilyName   = Font.FontFamily.Name,
                FontStyle        = FontStyle.Bold,
                AntiAliasingMode = FontAntiAliasMode.AntiAlias,
                Size             = Font.Size,
                FontHeightMode   = FontHeightMode.Points
            });

            // Create our file system and mount the resources.
            _fileSystem = new GorgonFileSystem();
            _fileSystem.Mount(Program.GetResourcePath(@"FolderSystem\"));

            // Get the sprite image.
            _spriteImage = _graphics.Textures.FromMemory <GorgonTexture2D>("0_HardVacuum", _fileSystem.ReadFile("/Images/0_HardVacuum.png"), new GorgonCodecPNG());

            // Get the sprites.
            // The sprites in the file system are from version 1.0 of Gorgon.
            // This version is backwards compatible and can load any version
            // of the sprites produced by older versions of Gorgon.
            _sprites    = new GorgonSprite[3];
            _sprites[0] = _2D.Renderables.FromMemory <GorgonSprite>("Base", _fileSystem.ReadFile("/Sprites/base.gorSprite"));
            _sprites[1] = _2D.Renderables.FromMemory <GorgonSprite>("Mother", _fileSystem.ReadFile("/Sprites/Mother.gorSprite"));
            _sprites[2] = _2D.Renderables.FromMemory <GorgonSprite>("Mother2c", _fileSystem.ReadFile("/Sprites/Mother2c.gorSprite"));

            // Get poetry.
            _textPosition    = new Vector2(0, ClientSize.Height + _textFont.LineHeight);
            _poetry          = _2D.Renderables.CreateText("Poetry", _textFont, Encoding.UTF8.GetString(_fileSystem.ReadFile("/SomeText.txt")), Color.Black);
            _poetry.Position = _textPosition;

            // Set up help text.
            _helpText          = _2D.Renderables.CreateText("Help", _helpFont, "F1 - Show/hide this help text.\nS - Show frame statistics.\nESC - Exit.", Color.Blue);
            _helpText.Position = new Vector2(3, 3);

            // Set the initial blur value.
            // We set a small render target for the blur, this will help
            // speed up the effect.
            _2D.Effects.GaussianBlur.BlurAmount            = 13.0f;
            _2D.Effects.GaussianBlur.BlurRenderTargetsSize = new Size(128, 128);
            _2D.Effects.GaussianBlur.RenderScene           = pass =>
            {
                // Draw the sprite at the upper left corner instead of
                // centered.  Otherwise it'll be centered in the blur
                // render target and will be clipped.
                _sprites[2].Anchor   = Vector2.Zero;
                _sprites[2].Position = Vector2.Zero;
                // Scale to the size of the blur target.
                _sprites[2].Scale = new Vector2(1.0f, _2D.Effects.GaussianBlur.BlurRenderTargetsSize.Height / _sprites[2].Size.Y);
                // Adjust the texture size to avoid bleed when blurring.
                // Bleed means that other portions of the texture get pulled
                // in to the texture because of bi-linear filtering (and the
                // blur operates in a similar manner, and therefore unwanted
                // pixels get pulled in as well).
                // See http://tape-worm.net/?page_id=277 for more info.
                _sprites[2].TextureSize = new Vector2(125.0f / _spriteImage.Settings.Width, _sprites[2].TextureSize.Y);

                _sprites[2].Draw();

                // Reset.
                _sprites[2].TextureSize = new Vector2(128.0f / _spriteImage.Settings.Width, _sprites[2].TextureSize.Y);
            };

            Gorgon.ApplicationIdleLoopMethod = Idle;
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Function to copy the file system data from a file system file.
        /// </summary>
        /// <param name="fileSystemFile">The file system file to copy.</param>
        /// <param name="provider">The provider to use.</param>
        /// <param name="fileSystemDir">The workspace directory to copy the files into.</param>
        /// <returns>The path to the metadata file.</returns>
        private async Task <FileInfo> CopyFileSystemAsync(FileInfo fileSystemFile, IGorgonFileSystemProvider provider, DirectoryInfo fileSystemDir)
        {
            IGorgonFileSystem fileSystem = new GorgonFileSystem(provider, Program.Log);

            fileSystem.Mount(fileSystemFile.FullName);

            IGorgonVirtualFile metaData = fileSystem.GetFile(Path.Combine("/", CommonEditorConstants.EditorMetadataFileName));

            // Get all directories and replicate them.
            IEnumerable <IGorgonVirtualDirectory> directories = fileSystem.FindDirectories("/", "*")
                                                                .OrderBy(item => item.FullPath.Length);

            foreach (IGorgonVirtualDirectory directory in directories)
            {
                var dirInfo = new DirectoryInfo(Path.Combine(fileSystemDir.FullName, directory.FullPath.FormatDirectory(Path.DirectorySeparatorChar).Substring(1)));

                if (dirInfo.Exists)
                {
                    continue;
                }

                dirInfo.Create();
            }

            // Copy all files into the directories we just created.
            var files = fileSystem.FindFiles("/", "*")
                        .Where(item => item != metaData)
                        .OrderByDescending(item => item.Size)
                        .ToList();

            int maxJobCount = (Environment.ProcessorCount * 2).Min(32).Max(1);
            int filesPerJob = (int)((float)files.Count / maxJobCount).FastCeiling();
            var jobs        = new List <Task>();

            if ((files.Count <= 100) || (maxJobCount < 2))
            {
                filesPerJob = files.Count;
            }

            Program.Log.Print($"Copying file system. {filesPerJob} files will be copied in a single job.", LoggingLevel.Verbose);

            void CopyFile(FileCopyJob job)
            {
                foreach (IGorgonVirtualFile file in job.Files)
                {
                    var fileInfo = new FileInfo(Path.Combine(fileSystemDir.FullName, file.Directory.FullPath.FormatDirectory(Path.DirectorySeparatorChar).Substring(1), file.Name));

                    using (Stream readStream = file.OpenStream())
                        using (Stream writeStream = fileInfo.OpenWrite())
                        {
                            readStream.CopyToStream(writeStream, (int)readStream.Length, job.ReadBuffer);
                        }
                }
            }

            // Build up the tasks for our jobs.
            while (files.Count > 0)
            {
                var jobData = new FileCopyJob();

                // Copy the file information to the file copy job data.
                int length = filesPerJob.Min(files.Count);
                for (int i = 0; i < length; ++i)
                {
                    jobData.Files.Add(files[i]);
                }
                files.RemoveRange(0, length);

                jobs.Add(Task.Run(() => CopyFile(jobData)));
            }

            Program.Log.Print($"{jobs.Count} jobs running for file copy from '{fileSystemFile.FullName}'.", LoggingLevel.Verbose);

            // Wait for the file copy to finish.
            await Task.WhenAll(jobs);

            var metaDataOutput = new FileInfo(Path.Combine(fileSystemDir.FullName, CommonEditorConstants.EditorMetadataFileName));

            if (metaData == null)
            {
                Program.Log.Print($"'{fileSystemFile.FullName}' has no metadata. A new metadata index will be generated.", LoggingLevel.Verbose);
                return(metaDataOutput);
            }

            Program.Log.Print($"'{fileSystemFile.FullName}' has metadata. Copying to the .", LoggingLevel.Verbose);
            byte[] writeBuffer = new byte[81920];
            using (Stream readStream = metaData.OpenStream())
                using (Stream writeStream = metaDataOutput.OpenWrite())
                {
                    readStream.CopyToStream(writeStream, (int)readStream.Length, writeBuffer);
                }

            metaDataOutput.Attributes = FileAttributes.Archive | FileAttributes.Normal;
            metaDataOutput.Refresh();

            return(metaDataOutput);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Function to initialize the application.
        /// </summary>
        /// <returns>The main window for the application.</returns>
        private static FormMain Initialize()
        {
            GorgonExample.ResourceBaseDirectory   = new DirectoryInfo(Settings.Default.ResourceLocation);
            GorgonExample.PlugInLocationDirectory = new DirectoryInfo(Settings.Default.PlugInLocation);

            FormMain window = GorgonExample.Initialize(new DX.Size2(Settings.Default.Resolution.Width, Settings.Default.Resolution.Height), "Depth");

            try
            {
                IReadOnlyList <IGorgonVideoAdapterInfo> videoDevices = GorgonGraphics.EnumerateAdapters(log: GorgonApplication.Log);

                if (videoDevices.Count == 0)
                {
                    throw new GorgonException(GorgonResult.CannotCreate,
                                              "Gorgon requires at least a Direct3D 11.4 capable video device.\nThere is no suitable device installed on the system.");
                }

                // Find the best video device.
                _graphics = new GorgonGraphics(videoDevices.OrderByDescending(item => item.FeatureSet).First());

                _screen = new GorgonSwapChain(_graphics,
                                              window,
                                              new GorgonSwapChainInfo("Gorgon2D Depth Buffer Example")
                {
                    Width  = Settings.Default.Resolution.Width,
                    Height = Settings.Default.Resolution.Height,
                    Format = BufferFormat.R8G8B8A8_UNorm
                });

                _depthBuffer = GorgonDepthStencil2DView.CreateDepthStencil(_graphics, new GorgonTexture2DInfo(_screen.RenderTargetView)
                {
                    Binding = TextureBinding.DepthStencil,
                    Format  = BufferFormat.D24_UNorm_S8_UInt
                });

                // Tell the graphics API that we want to render to the "screen" swap chain.
                _graphics.SetRenderTarget(_screen.RenderTargetView, _depthBuffer);

                // Initialize the renderer so that we are able to draw stuff.
                _renderer = new Gorgon2D(_graphics);

                GorgonExample.LoadResources(_graphics);

                // Load our packed file system plug in.
                _assemblyCache = new GorgonMefPlugInCache(GorgonApplication.Log);
                _assemblyCache.LoadPlugInAssemblies(GorgonExample.GetPlugInPath().FullName, "Gorgon.FileSystem.GorPack.dll");
                IGorgonPlugInService plugIns = new GorgonMefPlugInService(_assemblyCache);

                // Load the file system containing our application data (sprites, images, etc...)
                IGorgonFileSystemProviderFactory providerFactory = new GorgonFileSystemProviderFactory(plugIns, GorgonApplication.Log);
                IGorgonFileSystemProvider        provider        = providerFactory.CreateProvider("Gorgon.IO.GorPack.GorPackProvider");
                IGorgonFileSystem fileSystem = new GorgonFileSystem(provider, GorgonApplication.Log);

                // We can load the editor file system directly.
                // This is handy for switching a production environment where your data may be stored
                // as a compressed file, and a development environment where your data consists of loose
                // files.
                // fileSystem.Mount(@"D:\unpak\scratch\DeepAsAPuddle.gorPack\fs\");

                // For now though, we'll load the packed file.
                fileSystem.Mount(Path.Combine(GorgonExample.GetResourcePath(@"FileSystems").FullName, "Depth.gorPack"));

                // Get our sprites.  These make up the frames of animation for our Guy.
                // If and when there's an animation editor, we'll only need to create a single sprite and load the animation.
                IGorgonVirtualFile[] spriteFiles = fileSystem.FindFiles("/Sprites/", "*", true).ToArray();

                // Load our sprite data (any associated textures will be loaded as well).
                Dictionary <string, GorgonSprite> sprites = new Dictionary <string, GorgonSprite>(StringComparer.OrdinalIgnoreCase);

                for (int i = 0; i < spriteFiles.Length; i++)
                {
                    IGorgonVirtualFile file = spriteFiles[i];
                    (GorgonSprite sprite, GorgonTexture2D texture) = fileSystem.LoadSprite(_renderer, file.FullPath);

                    // The LoadSprite extension method will automatically find and load your associated texture if you're using
                    // a Gorgon editor file system. So it's important that you leep track of your textures, disposing of just
                    // the associated GorgonTexture2DView won't cut it here, so you'll need to dispose the actual texture resource
                    // when you're done with it.
                    if (!_textures.Contains(texture))
                    {
                        _textures.Add(texture);
                    }

                    // At super duper resolution, the example graphics would be really hard to see, so we'll scale them up.
                    sprite.Scale       = new DX.Vector2((_screen.Width / (_screen.Height / 2)) * 2.0f);
                    sprites[file.Name] = sprite;
                }

                _snowTile       = sprites["Snow"];
                _snowTile.Depth = 0.5f;

                _icicle       = sprites["Icicle"];
                _icicle.Depth = 0.2f;

                _guySprite       = sprites["Guy_Up_0"];
                _guySprite.Depth = 0.1f;
                _guyPosition     = new DX.Vector2(_screen.Width / 2 + _guySprite.ScaledSize.Width * 1.25f, _screen.Height / 2 + _guySprite.ScaledSize.Height);

                BuildAnimations(sprites);
            }
            finally
            {
                GorgonExample.EndInit();
            }

            return(window);
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Function to load a <see cref="GorgonPolySprite"/> from a <see cref="GorgonFileSystem"/>.
        /// </summary>
        /// <param name="fileSystem">The file system to load the sprite from.</param>
        /// <param name="renderer">The renderer for the sprite.</param>
        /// <param name="path">The path to the sprite file in the file system.</param>
        /// <param name="textureOptions">[Optional] Options for the texture loaded associated the sprite.</param>
        /// <param name="spriteCodecs">The list of polygonal sprite codecs to try and load the sprite with.</param>
        /// <param name="imageCodecs">The list of image codecs to try and load the sprite texture with.</param>
        /// <returns>The sprite data in the file as a <see cref="GorgonSprite"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="fileSystem"/>, <paramref name="renderer"/>, or <paramref name="path"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="path"/> parameter is empty.</exception>
        /// <exception cref="FileNotFoundException">Thrown if the file in the <paramref name="path"/> was not found.</exception>
        /// <exception cref="GorgonException">Thrown if the sprite data in the file system could not be loaded because a suitable codec was not found.</exception>
        /// <remarks>
        /// <para>
        /// This method extends a <see cref="GorgonFileSystem"/> so that sprites can be loaded by calling a method on the file system object itself. This negates the need for users to create complex code
        /// for loading a sprite.
        /// </para>
        /// <para>
        /// When loading a sprite, the method will attempt to locate the <see cref="GorgonTexture2DView"/> associated with the sprite (if it exists). When loading, it will check:
        /// <list type="number">
        ///     <item>
        ///         <description>For a texture resource with the same name that is already loaded into memory.</description>
        ///     </item>
        ///     <item>
        ///         <description>Use the local <see cref="IGorgonVirtualDirectory"/> for the sprite file and search for the texture in that directory.</description>
        ///     </item>
        ///     <item>
        ///         <description>Check the entire <paramref name="fileSystem"/> for a file if the texture name contains path information (this is done by the GorgonEditor from v2).</description>
        ///     </item>
        /// </list>
        /// If the file is found, and can be loaded by one of the <paramref name="imageCodecs"/>, then it is loaded and assigned to the sprite.
        /// </para>
        /// <para>
        /// The <paramref name="spriteCodecs"/> is a list of codecs for loading polygonal sprite data. If the user specifies this parameter, the only the codecs provided will be used for determining if a
        /// sprite can be read. If it is not supplied, then all built-in (i.e. not plug in based) sprite codecs will be used.
        /// </para>
        /// <para>
        /// The <paramref name="imageCodecs"/> is a list of codecs for loading image data. If the user specifies this parameter, the only the codecs provided will be used for determining if an image can be
        /// read. If it is not supplied, then all built-in (i.e. not plug in based) image codecs will be used.
        /// </para>
        /// </remarks>
        /// <seealso cref="GorgonFileSystem"/>
        /// <seealso cref="GorgonTexture2DView"/>
        /// <seealso cref="GorgonPolySprite"/>
        public static GorgonPolySprite LoadPolySpriteFromFileSystem(this GorgonFileSystem fileSystem,
                                                                    Gorgon2D renderer,
                                                                    string path,
                                                                    GorgonTexture2DLoadOptions textureOptions         = null,
                                                                    IEnumerable <IGorgonPolySpriteCodec> spriteCodecs = null,
                                                                    IEnumerable <IGorgonImageCodec> imageCodecs       = null)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }

            IGorgonVirtualFile file = fileSystem.GetFile(path);

            if (file == null)
            {
                throw new FileNotFoundException(string.Format(Resources.GOR2DIO_ERR_FILE_NOT_FOUND, path));
            }

            if ((imageCodecs == null) || (!imageCodecs.Any()))
            {
                // If we don't specify any codecs, then use the built in ones.
                imageCodecs = new IGorgonImageCodec[]
                {
                    new GorgonCodecPng(),
                    new GorgonCodecBmp(),
                    new GorgonCodecDds(),
                    new GorgonCodecGif(),
                    new GorgonCodecJpeg(),
                    new GorgonCodecTga(),
                };
            }
            else
            {
                // Only use codecs that can decode image data.
                imageCodecs = imageCodecs.Where(item => item.CanDecode);
            }

            if ((spriteCodecs == null) || (!spriteCodecs.Any()))
            {
                // Use all built-in codecs if we haven't asked for any.
                spriteCodecs = new IGorgonPolySpriteCodec[]
                {
                    new GorgonV3PolySpriteBinaryCodec(renderer),
                    new GorgonV3PolySpriteJsonCodec(renderer)
                };
            }
            else
            {
                // Only use codecs that can decode sprite data.
                spriteCodecs = spriteCodecs.Where(item => item.CanDecode);
            }

            Stream spriteStream = file.OpenStream();

            try
            {
                if (!spriteStream.CanSeek)
                {
                    Stream newStream = new DataStream((int)spriteStream.Length, true, true);
                    spriteStream.CopyTo(newStream);
                    newStream.Position = 0;
                    spriteStream.Dispose();
                    spriteStream = newStream;
                }

                IGorgonPolySpriteCodec spriteCodec = GetPolySpriteCodec(spriteStream, spriteCodecs);

                if (spriteCodec == null)
                {
                    throw new GorgonException(GorgonResult.CannotRead, string.Format(Resources.GOR2DIO_ERR_NO_SUITABLE_SPRITE_CODEC_FOUND, path));
                }

                // Try to locate the texture.
                string textureName = spriteCodec.GetAssociatedTextureName(spriteStream);

                GorgonTexture2DView textureForSprite = null;

                // Let's try and load the texture into memory.
                // This does this by:
                // 1. Checking to see if a texture resource with the name specified is already available in memory.
                // 2. Checking the local directory of the file to see if the texture is there.
                // 3. A file system wide search.

                // ReSharper disable once InvertIf
                if (!string.IsNullOrWhiteSpace(textureName))
                {
                    (IGorgonImageCodec codec, IGorgonVirtualFile textureFile, bool loaded) =
                        LocateTextureCodecAndFile(fileSystem, file.Directory, renderer, textureName, imageCodecs);

                    // We have not loaded the texture yet.  Do so now.
                    // ReSharper disable once InvertIf
                    if ((!loaded) && (textureFile != null) && (codec != null))
                    {
                        using (Stream textureStream = textureFile.OpenStream())
                        {
                            textureForSprite = GorgonTexture2DView.FromStream(renderer.Graphics,
                                                                              textureStream,
                                                                              codec,
                                                                              textureFile.Size,
                                                                              GetTextureOptions(textureFile.FullPath, textureOptions));
                        }
                    }
                }

                return(spriteCodec.FromStream(spriteStream, textureForSprite, (int)file.Size));
            }
            finally
            {
                spriteStream?.Dispose();
            }
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Function to retrieve the total number of files in this directory and any directories under this one.
 /// </summary>
 /// <returns>The total number of files.</returns>
 /// <remarks>
 /// Use this to retrieve the total number of <see cref="IGorgonVirtualFile"/> entries under this directory. This search includes all sub directories for this and child directories. To get
 /// the count of the immediate files, use the <see cref="IReadOnlyCollection{T}.Count"/> property on the <see cref="IGorgonVirtualDirectory.Files"/> property.
 /// </remarks>
 public int GetFileCount() => GorgonFileSystem.FlattenDirectoryHierarchy(this, "*").Sum(item => item.Files.Count) + Files.Count;
Ejemplo n.º 24
0
        /// <summary>
        /// Function called to initialize the application.
        /// </summary>
        private void Initialize()
        {
            GorgonExample.ResourceBaseDirectory = new DirectoryInfo(Settings.Default.ResourceLocation);

            // Resize and center the screen.
            var screen = Screen.FromHandle(Handle);

            ClientSize = Settings.Default.Resolution;
            Location   = new Point(screen.Bounds.Left + (screen.WorkingArea.Width / 2) - (ClientSize.Width / 2),
                                   screen.Bounds.Top + (screen.WorkingArea.Height / 2) - (ClientSize.Height / 2));

            // Initialize our graphics.
            IReadOnlyList <IGorgonVideoAdapterInfo> videoAdapters = GorgonGraphics.EnumerateAdapters(log: GorgonApplication.Log);

            if (videoAdapters.Count == 0)
            {
                throw new GorgonException(GorgonResult.CannotCreate,
                                          "Gorgon requires at least a Direct3D 11.4 capable video device.\nThere is no suitable device installed on the system.");
            }

            // Find the best video device.
            _graphics = new GorgonGraphics(videoAdapters.OrderByDescending(item => item.FeatureSet).First());

            // Build our "screen".
            _screen = new GorgonSwapChain(_graphics,
                                          this,
                                          new GorgonSwapChainInfo
            {
                Width  = ClientSize.Width,
                Height = ClientSize.Height,
                Format = BufferFormat.R8G8B8A8_UNorm
            });

            if (!Settings.Default.IsWindowed)
            {
                // Go full screen by using borderless windowed mode.
                _screen.EnterFullScreen();
            }

            // Build up our 2D renderer.
            _renderer = new Gorgon2D(_graphics);

            // Load in the logo texture from our resources.
            GorgonExample.LoadResources(_graphics);

            // Create fonts.
            _textFont = GorgonExample.Fonts.GetFont(new GorgonFontInfo("GiGi", 24.0f, FontHeightMode.Points, "GiGi_24pt")
            {
                AntiAliasingMode = FontAntiAliasMode.AntiAlias,
                TextureWidth     = 512,
                TextureHeight    = 256
            });

            // Use the form font for this one.
            _helpFont = GorgonExample.Fonts.GetFont(new GorgonFontInfo(Font.FontFamily.Name,
                                                                       Font.Size,
                                                                       Font.Unit == GraphicsUnit.Pixel ? FontHeightMode.Pixels : FontHeightMode.Points,
                                                                       "Form Font")
            {
                AntiAliasingMode = FontAntiAliasMode.AntiAlias,
                FontStyle        = FontStyle.Bold
            });

            // Create our file system and mount the resources.
            _fileSystem = new GorgonFileSystem(GorgonApplication.Log);
            _fileSystem.Mount(GorgonExample.GetResourcePath(@"FileSystems\FolderSystem").FullName);

            // In the previous versions of Gorgon, we used to load the image first, and then the sprites.
            // But in this version, we have an extension that will load the sprite textures for us.
            _sprites = new GorgonSprite[3];

            // The sprites are in the v2 format.
            IEnumerable <IGorgonSpriteCodec> v2Codec  = new[] { new GorgonV2SpriteCodec(_renderer) };
            IEnumerable <IGorgonImageCodec>  pngCodec = new[] { new GorgonCodecPng() };

            _sprites[0] = _fileSystem.LoadSpriteFromFileSystem(_renderer, "/Sprites/base.gorSprite", spriteCodecs: v2Codec, imageCodecs: pngCodec);
            _sprites[1] = _fileSystem.LoadSpriteFromFileSystem(_renderer, "/Sprites/Mother.gorSprite", spriteCodecs: v2Codec, imageCodecs: pngCodec);
            _sprites[2] = _fileSystem.LoadSpriteFromFileSystem(_renderer, "/Sprites/Mother2c.gorSprite", spriteCodecs: v2Codec, imageCodecs: pngCodec);

            // This is how you would get the sprites in v2 of Gorgon:

            /*_spriteImage = _graphics.Textures.FromMemory<GorgonTexture2D>("0_HardVacuum", LoadFile("/Images/0_HardVacuum.png"), new GorgonCodecPNG());
             *
             *      // Get the sprites.
             *      // The sprites in the file system are from version 1.0 of Gorgon.
             *      // This version is backwards compatible and can load any version
             *      // of the sprites produced by older versions of Gorgon.
             *      _sprites = new GorgonSprite[3];
             *      _sprites[0] = _renderer.Renderables.FromMemory<GorgonSprite>("Base", LoadFile("/Sprites/base.gorSprite"));
             *      _sprites[1] = _renderer.Renderables.FromMemory<GorgonSprite>("Mother", LoadFile("/Sprites/Mother.gorSprite"));
             *      _sprites[2] = _renderer.Renderables.FromMemory<GorgonSprite>("Mother2c", LoadFile("/Sprites/Mother2c.gorSprite"));
             */

            // Get poetry.
            _textPosition = new DX.Vector2(0, ClientSize.Height + _textFont.LineHeight);

            _poetry = new GorgonTextSprite(_textFont, Encoding.UTF8.GetString(LoadFile("/SomeText.txt")))
            {
                Position = _textPosition,
                Color    = Color.Black
            };

            // Set up help text.
            _helpText = new GorgonTextSprite(_helpFont, "F1 - Show/hide this help text.\nS - Show frame statistics.\nESC - Exit.")
            {
                Color    = Color.Blue,
                Position = new DX.Vector2(3, 3)
            };

            // Unlike the old example, we'll blend to render targets, ping-ponging back and forth, for a much better quality image and smoother transition.
            _blurEffect = new Gorgon2DGaussBlurEffect(_renderer, 3)
            {
                BlurRenderTargetsSize = new DX.Size2((int)_sprites[2].Size.Width * 2, (int)_sprites[2].Size.Height * 2),
                PreserveAlpha         = false
            };
            _blurEffect.Precache();

            _blurredTarget[0] = GorgonRenderTarget2DView.CreateRenderTarget(_graphics, new GorgonTexture2DInfo("Blurred RTV")
            {
                Width   = _blurEffect.BlurRenderTargetsSize.Width,
                Height  = _blurEffect.BlurRenderTargetsSize.Height,
                Binding = TextureBinding.ShaderResource,
                Format  = BufferFormat.R8G8B8A8_UNorm,
                Usage   = ResourceUsage.Default
            });
            _blurredTarget[1] = GorgonRenderTarget2DView.CreateRenderTarget(_graphics, _blurredTarget[0]);
            _blurredImage[0]  = _blurredTarget[0].GetShaderResourceView();
            _blurredImage[1]  = _blurredTarget[1].GetShaderResourceView();

            GorgonApplication.IdleMethod = Idle;
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GorgonFileSystemProviderCollection"/> class.
 /// </summary>
 /// <param name="fileSystem">File system that owns this collection.</param>
 internal GorgonFileSystemProviderCollection(GorgonFileSystem fileSystem)
     : base(false)
 {
     _fileSystem = fileSystem;
 }