예제 #1
0
        /// <summary>
        /// Unload the specified bundle.
        /// </summary>
        /// <param name="bundleName">Name of the bundle.</param>
        /// <param name="objectDatabaseContentIndexMap">The object database asset index map, where newly loaded assets will be merged (ignored if null).</param>
        /// <returns></returns>
        public void UnloadBundle(string bundleName, ObjectDatabaseContentIndexMap objectDatabaseContentIndexMap)
        {
            lock (loadedBundles)
                lock (objects)
                {
                    // Unload package
                    UnloadBundleRecursive(bundleName, objectDatabaseContentIndexMap);

                    // Remerge previously loaded packages
                    foreach (var otherLoadedBundle in loadedBundles)
                    {
                        var bundle = otherLoadedBundle.Description;

                        // Read objects
                        foreach (var objectEntry in bundle.Objects)
                        {
                            objects[objectEntry.Key] = new ObjectLocation {
                                Info = objectEntry.Value, BundleUrl = otherLoadedBundle.BundleUrl
                            };
                        }

                        contentIndexMap.Merge(bundle.Assets);
                        objectDatabaseContentIndexMap.Merge(bundle.Assets);
                    }
                }
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObjectDatabase" /> class.
        /// </summary>
        /// <param name="vfsMainUrl">The VFS main URL.</param>
        /// <param name="indexName">Name of the index file.</param>
        /// <param name="vfsAdditionalUrl">The VFS additional URL. It will be used only if vfsMainUrl is read-only.</param>
        public ObjectDatabase(string vfsMainUrl, string indexName, string vfsAdditionalUrl = null, bool loadDefaultBundle = true)
        {
            if (vfsMainUrl == null)
            {
                throw new ArgumentNullException(nameof(vfsMainUrl));
            }

            // Create the merged asset index map
            ContentIndexMap = new ObjectDatabaseContentIndexMap();

            // Try to open file backends
            bool isReadOnly = Platform.Type != PlatformType.Windows;
            var  backend    = new FileOdbBackend(vfsMainUrl, indexName, isReadOnly);

            ContentIndexMap.Merge(backend.ContentIndexMap);
            if (backend.IsReadOnly)
            {
                backendRead1 = backend;
                if (vfsAdditionalUrl != null)
                {
                    backendWrite = backendRead2 = new FileOdbBackend(vfsAdditionalUrl, indexName, false);
                    ContentIndexMap.Merge(backendWrite.ContentIndexMap);
                }
            }
            else
            {
                backendWrite = backendRead1 = backend;
            }

            ContentIndexMap.WriteableContentIndexMap = backendWrite.ContentIndexMap;

            BundleBackend = new BundleOdbBackend(vfsMainUrl);

            // Try to open "default" pack file synchronously
            if (loadDefaultBundle)
            {
                try
                {
                    BundleBackend.LoadBundle("default", ContentIndexMap).GetAwaiter().GetResult();
                }
                catch (FileNotFoundException)
                {
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObjectDatabase" /> class.
        /// </summary>
        /// <param name="vfsMainUrl">The VFS main URL.</param>
        /// <param name="indexName">Name of the index file.</param>
        /// <param name="vfsAdditionalUrl">The VFS additional URL. It will be used only if vfsMainUrl is read-only.</param>
        public ObjectDatabase(string vfsMainUrl, string indexName, string vfsAdditionalUrl = null, bool loadDefaultBundle = true)
        {
            if (vfsMainUrl == null) throw new ArgumentNullException(nameof(vfsMainUrl));

            // Create the merged asset index map
            ContentIndexMap = new ObjectDatabaseContentIndexMap();

            // Try to open file backends
            bool isReadOnly = Platform.Type != PlatformType.Windows;
            var backend = new FileOdbBackend(vfsMainUrl, indexName, isReadOnly);

            ContentIndexMap.Merge(backend.ContentIndexMap);
            if (backend.IsReadOnly)
            {
                backendRead1 = backend;
                if (vfsAdditionalUrl != null)
                {
                    backendWrite = backendRead2 = new FileOdbBackend(vfsAdditionalUrl, indexName, false);
                    ContentIndexMap.Merge(backendWrite.ContentIndexMap);
                }
            }
            else
            {
                backendWrite = backendRead1 = backend;
            }

            ContentIndexMap.WriteableContentIndexMap = backendWrite.ContentIndexMap;

            BundleBackend = new BundleOdbBackend(vfsMainUrl);

            // Try to open "default" pack file synchronously
            if (loadDefaultBundle)
            {
                try
                {
                    BundleBackend.LoadBundle("default", ContentIndexMap).GetAwaiter().GetResult();
                }
                catch (FileNotFoundException)
                {
                }
            }
        }
예제 #4
0
        public async Task LoadBundleFromUrl(string bundleName, ObjectDatabaseContentIndexMap objectDatabaseContentIndexMap, string bundleUrl, bool ignoreDependencies = false)
        {
            BundleDescription bundle;

            using (var packStream = VirtualFileSystem.OpenStream(bundleUrl, VirtualFileMode.Open, VirtualFileAccess.Read))
            {
                bundle = ReadBundleDescription(packStream);
            }

            // Read and resolve dependencies
            if (!ignoreDependencies)
            {
                foreach (var dependency in bundle.Dependencies)
                {
                    await LoadBundle(dependency, objectDatabaseContentIndexMap);
                }
            }

            lock (loadedBundles)
            {
                LoadedBundle loadedBundle = null;

                foreach (var currentBundle in loadedBundles)
                {
                    if (currentBundle.BundleName == bundleName)
                    {
                        loadedBundle = currentBundle;
                        break;
                    }
                }

                if (loadedBundle == null)
                {
                    loadedBundle = new LoadedBundle
                    {
                        BundleName     = bundleName,
                        BundleUrl      = bundleUrl,
                        Description    = bundle,
                        ReferenceCount = 1
                    };

                    loadedBundles.Add(loadedBundle);
                }
                else
                {
                    loadedBundle.ReferenceCount++;
                }
            }

            // Read objects
            lock (objects)
            {
                foreach (var objectEntry in bundle.Objects)
                {
                    objects[objectEntry.Key] = new ObjectLocation {
                        Info = objectEntry.Value, BundleUrl = bundleUrl
                    };
                }
            }

            // Merge with local (asset bundles) index map
            contentIndexMap.Merge(bundle.Assets);

            // Merge with global object database map
            objectDatabaseContentIndexMap.Merge(bundle.Assets);
        }
예제 #5
0
        public async Task LoadBundleFromUrl(string bundleName, ObjectDatabaseContentIndexMap objectDatabaseContentIndexMap, string bundleUrl, bool ignoreDependencies = false)
        {
            BundleDescription bundle = null;

            // If there is a .bundle, add incremental id before it
            var currentBundleExtensionUrl = bundleUrl.Length - (bundleUrl.EndsWith(BundleExtension) ? BundleExtension.Length : 0);

            // Process incremental bundles one by one
            using (var packStream = VirtualFileSystem.OpenStream(bundleUrl, VirtualFileMode.Open, VirtualFileAccess.Read))
            {
                bundle = ReadBundleDescription(packStream);
            }

            var files = new List <string> {
                bundleUrl
            };

            files.AddRange(bundle.IncrementalBundles.Select(x => bundleUrl.Insert(currentBundleExtensionUrl, "." + x)));

            if (bundle == null)
            {
                throw new FileNotFoundException("Could not find bundle", bundleUrl);
            }

            // Read and resolve dependencies
            if (!ignoreDependencies)
            {
                foreach (var dependency in bundle.Dependencies)
                {
                    await LoadBundle(dependency, objectDatabaseContentIndexMap);
                }
            }

            LoadedBundle loadedBundle = null;

            lock (loadedBundles)
            {
                foreach (var currentBundle in loadedBundles)
                {
                    if (currentBundle.BundleName == bundleName)
                    {
                        loadedBundle = currentBundle;
                        break;
                    }
                }

                if (loadedBundle == null)
                {
                    loadedBundle = new LoadedBundle
                    {
                        BundleName     = bundleName,
                        BundleUrl      = bundleUrl,
                        Description    = bundle,
                        ReferenceCount = 1,
                        Files          = files,
                        Streams        = new List <Stream>(files.Select(x => (Stream)null)),
                    };

                    loadedBundles.Add(loadedBundle);
                }
                else
                {
                    loadedBundle.ReferenceCount++;
                }
            }

            // Read objects
            lock (objects)
            {
                foreach (var objectEntry in bundle.Objects)
                {
                    objects[objectEntry.Key] = new ObjectLocation {
                        Info = objectEntry.Value, LoadedBundle = loadedBundle
                    };
                }
            }

            // Merge with local (asset bundles) index map
            contentIndexMap.Merge(bundle.Assets);

            // Merge with global object database map
            objectDatabaseContentIndexMap.Merge(bundle.Assets);
        }