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

                    // 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
                            };
                        }

                        assetIndexMap.Merge(bundle.Assets);
                        objectDatabaseAssetIndexMap.Merge(bundle.Assets);
                    }
                }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Loads the specified bundle.
        /// </summary>
        /// <param name="bundleName">Name of the bundle.</param>
        /// <param name="objectDatabaseAssetIndexMap">The object database asset index map, where newly loaded assets will be merged (ignored if null).</param>
        /// <returns></returns>
        public async Task LoadBundle(string bundleName, ObjectDatabaseAssetIndexMap objectDatabaseAssetIndexMap)
        {
            if (bundleName == null)
            {
                throw new ArgumentNullException("bundleName");
            }

            // Check loaded bundles
            lock (loadedBundles)
            {
                foreach (var currentBundle in loadedBundles)
                {
                    if (currentBundle.BundleName == bundleName)
                    {
                        currentBundle.ReferenceCount++;
                        return;
                    }
                }
            }

            // Resolve package
            var vfsUrl = await ResolveBundle(bundleName, true);

            await LoadBundleFromUrl(bundleName, objectDatabaseAssetIndexMap, vfsUrl);
        }
Ejemplo n.º 3
0
        public bool TestSingleUrl(PathSelector pathSelector, string asset)
        {
            var assetIndexMap = new ObjectDatabaseAssetIndexMap();
            assetIndexMap[asset] = ObjectId.New();

            return pathSelector.Select(null, assetIndexMap).Count() == 1;
        }
Ejemplo n.º 4
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 = "index", string vfsAdditionalUrl = null, bool loadDefaultBundle = true)
        {
            if (vfsMainUrl == null)
            {
                throw new ArgumentNullException("vfsMainUrl");
            }

            // Create the merged asset index map
            AssetIndexMap = new ObjectDatabaseAssetIndexMap();

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

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

            AssetIndexMap.WriteableAssetIndexMap = backendWrite.AssetIndexMap;

            bundleBackend = new BundleOdbBackend(vfsMainUrl);

            // Try to open "default" pack file synchronously
            if (loadDefaultBundle)
            {
                try
                {
                    bundleBackend.LoadBundle("default", AssetIndexMap).GetAwaiter().GetResult();
                }
                catch (FileNotFoundException)
                {
                }
            }
        }
Ejemplo n.º 5
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 = "index", string vfsAdditionalUrl = null, bool loadDefaultBundle = true)
        {
            if (vfsMainUrl == null) throw new ArgumentNullException("vfsMainUrl");

            // Create the merged asset index map
            AssetIndexMap = new ObjectDatabaseAssetIndexMap();

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

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

            AssetIndexMap.WriteableAssetIndexMap = backendWrite.AssetIndexMap;

            bundleBackend = new BundleOdbBackend(vfsMainUrl);

            // Try to open "default" pack file synchronously
            if (loadDefaultBundle)
            {
                try
                {
                    bundleBackend.LoadBundle("default", AssetIndexMap).GetAwaiter().GetResult();
                }
                catch (FileNotFoundException)
                {
                }
            }
        }
Ejemplo n.º 6
0
        private void UnloadBundleRecursive(string bundleName, ObjectDatabaseAssetIndexMap objectDatabaseAssetIndexMap)
        {
            if (bundleName == null)
            {
                throw new ArgumentNullException("bundleName");
            }

            lock (loadedBundles)
            {
                int loadedBundleIndex = -1;

                for (int index = 0; index < loadedBundles.Count; index++)
                {
                    var currentBundle = loadedBundles[index];
                    if (currentBundle.BundleName == bundleName)
                    {
                        loadedBundleIndex = index;
                        break;
                    }
                }

                if (loadedBundleIndex == -1)
                {
                    throw new InvalidOperationException("Bundle has not been loaded.");
                }

                var loadedBundle = loadedBundles[loadedBundleIndex];
                var bundle       = loadedBundle.Description;
                if (--loadedBundle.ReferenceCount == 0)
                {
                    // Remove and dispose stream from pool
                    lock (bundleStreams)
                    {
                        Stream stream;
                        if (bundleStreams.TryGetValue(loadedBundle.BundleUrl, out stream))
                        {
                            bundleStreams.Remove(loadedBundle.BundleUrl);
                            stream.Dispose();
                        }
                    }

                    // Actually unload bundle
                    loadedBundles.RemoveAt(loadedBundleIndex);

                    // Unload objects from index map (if possible, replace with objects of other bundles
                    var removedObjects = new HashSet <ObjectId>();
                    foreach (var objectEntry in bundle.Objects)
                    {
                        objects.Remove(objectEntry.Key);
                        removedObjects.Add(objectEntry.Key);
                    }

                    // Unmerge with local (asset bundles) index map
                    assetIndexMap.Unmerge(bundle.Assets);

                    // Unmerge with global object database map
                    objectDatabaseAssetIndexMap.Unmerge(bundle.Assets);

                    // Remove dependencies too
                    foreach (var dependency in bundle.Dependencies)
                    {
                        UnloadBundleRecursive(dependency, objectDatabaseAssetIndexMap);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        public async Task LoadBundleFromUrl(string bundleName, ObjectDatabaseAssetIndexMap objectDatabaseAssetIndexMap, 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, objectDatabaseAssetIndexMap);
                }
            }

            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
            assetIndexMap.Merge(bundle.Assets);

            // Merge with global object database map
            objectDatabaseAssetIndexMap.Merge(bundle.Assets);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Loads the specified bundle.
        /// </summary>
        /// <param name="bundleName">Name of the bundle.</param>
        /// <param name="objectDatabaseAssetIndexMap">The object database asset index map, where newly loaded assets will be merged (ignored if null).</param>
        /// <returns></returns>
        public async Task LoadBundle(string bundleName, ObjectDatabaseAssetIndexMap objectDatabaseAssetIndexMap)
        {
            if (bundleName == null)
            {
                throw new ArgumentNullException("bundleName");
            }

            // Check loaded bundles
            lock (loadedBundles)
            {
                foreach (var currentBundle in loadedBundles)
                {
                    if (currentBundle.BundleName == bundleName)
                    {
                        currentBundle.ReferenceCount++;
                        return;
                    }
                }
            }

            // Resolve package
            var vfsUrl = await ResolveBundle(bundleName, true);

            BundleDescription bundle;

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

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

            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      = vfsUrl,
                        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 = vfsUrl
                    };
                }
            }

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

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