/// <summary> /// Function to load a single dependency for a file. /// </summary> /// <param name="dependency">Dependency to load.</param> /// <param name="childDependencies">The dependencies for this dependency.</param> /// <returns>The loaded dependency object.</returns> private object LoadDependency(GorgonEditorDependency dependency, IReadOnlyDictionary <GorgonEditorDependency, object> childDependencies) { GorgonFileSystemFileEntry dependencyFile = FileSystem.GetFile(dependency.Path); if (dependencyFile == null) { throw new IOException(string.Format(Resources.GORFS_ERR_DEPENDENCY_NOT_FOUND, dependency.Path)); } // Find a handler for this file. KeyValuePair <Type, Func <Stream, IReadOnlyDictionary <GorgonEditorDependency, object>, object> > handler = _fileHandlers.FirstOrDefault(item => string.Equals(item.Key.FullName, dependency.Type, StringComparison.OrdinalIgnoreCase)); if (handler.Key == null) { throw new IOException(string.Format(Resources.GORFS_ERR_FILE_NO_HANDLER, dependency.Path)); } using (Stream dependencyStream = dependencyFile.OpenStream(false)) { return(handler.Value(dependencyStream, childDependencies)); } }
/// <summary> /// Function to load a file from the editor file. /// </summary> /// <typeparam name="T">The type of object to load. Must be a reference type.</typeparam> /// <param name="path">Path to the file to load.</param> /// <remarks> /// Use this method to load a file from the file system generated by the editor. The type parameter T is used to determine how to load an object through a registered type loader. /// <para>The type loader is registered by supplying a type and a function to read in the file. This allows the developer to load in their own file formats if required. New loader types /// can be added through the <see cref="RegisteredEditorTypes"/> parameter.</para> /// <para>Without adding any new loader types Gorgon will support loading of its supported image codecs, sprites (for the 2D renderer), animations and fonts. The loader will attempt to load /// any dependencies required by the requested file as well.</para> /// </remarks> public T ReadFile <T>(string path) where T : class { if (path == null) { throw new ArgumentNullException("path"); } if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentException(Resources.GORFS_ERR_PARAMETER_MUST_NOT_BE_EMPTY, "path"); } Type type = typeof(T); Func <Stream, IReadOnlyDictionary <GorgonEditorDependency, object>, object> loader; if (!_fileHandlers.TryGetValue(type, out loader)) { throw new IOException(string.Format(Resources.GORFS_ERR_FILE_NO_HANDLER, path)); } GorgonFileSystemFileEntry file = FileSystem.GetFile(path); if (file == null) { throw new IOException(string.Format(Resources.GORFS_ERR_FILE_NOT_FOUND, path)); } // Load the meta data if it's not been loaded yet. if (_hasMetaData == null) { GetDependencies(); } GorgonEditorDependencyCollection dependencies; IReadOnlyDictionary <GorgonEditorDependency, object> dependencyObjects = new Dictionary <GorgonEditorDependency, object>(); // Check to see if the file has dependencies. if (Dependencies.TryGetValue(file.FullPath, out dependencies)) { dependencyObjects = LoadDependencies(dependencies); } using (Stream fileStream = file.OpenStream(false)) { return((T)loader(fileStream, dependencyObjects)); } }
/// <summary> /// Function to retrieve the dependencies file and process it. /// </summary> private void GetDependencies() { if ((_hasMetaData != null) && (!_hasMetaData.Value)) { return; } // If we've already loaded the file system meta data for this file system, then leave. if (_metaDataFile != null) { return; } GorgonFileSystemFileEntry file = FileSystem.GetFile(MetaDataFile); if (file == null) { _hasMetaData = false; return; } // Create and load the object. using (Stream metaFile = file.OpenStream(false)) { _metaDataFile = XDocument.Load(metaFile); } XElement rootNode = _metaDataFile.Element(MetaDataRootName); if (rootNode == null) { _hasMetaData = false; return; } XElement dependencyNode = rootNode.Element(ContentDependencyFiles); if (dependencyNode == null) { _hasMetaData = false; return; } IEnumerable <XElement> fileNodes = dependencyNode.Elements(FileNode); var dependencies = new Dictionary <string, GorgonEditorDependencyCollection>(); // Lock here because we're updating a collection that's not thread safe. foreach (XElement fileNode in fileNodes) { XAttribute path = fileNode.Attribute(NameAttr); if ((path == null) || (string.IsNullOrWhiteSpace(path.Value))) { continue; } dependencies.Add(path.Value, GorgonEditorDependencyCollection .Deserialize(fileNode.Elements(GorgonEditorDependency.DependencyNode))); } Dependencies = dependencies; _hasMetaData = Dependencies.Count > 0; }