/// <summary>
        /// Reloads the specified asset.
        /// </summary>
        /// <param name="assetName">Name of the asset to load</param>
        /// <returns>The new reference to the reloaded asset</returns>
        public object Reload(string assetName, AssetLoadedHandler Callback)
        {
            if (mCache.ContainsKey(assetName))
            {
                AssetTracker oldAssetTracker = mCache[assetName];

                // Remove tracker so Load<T>() will create a new one
                mCache.Remove(assetName);
                mCacheNames.Remove(assetName);

                // Load it again
                object asset = Load(assetName, Callback);

                // Invoke AssetChanged event
                oldAssetTracker.OnAssetChanged(new AssetChangedEventArgs(asset));

                // Destroy previous tracker
                DisposeAssetTracker(oldAssetTracker, true);

                return(asset);
            }
            else
            {
                return(Load(assetName, Callback));
            }
        }
			/// <summary>
			/// Constructor for convenience
			/// </summary>
			internal LoadAsyncParams(string name, AssetLoaded loadedMethod) {
				ItemLoadedMethods.Add(loadedMethod);
				Tracker = new AssetTracker();
				Tracker.AssetName = name;
				Tracker.RefCount = 1;
				Tracker.Status = EAssetStatus.Loading;
			}
示例#3
0
 /// <summary>
 /// Constructor for convenience
 /// </summary>
 internal LoadAsyncParams(string name, AssetLoaded loadedMethod)
 {
     ItemLoadedMethods.Add(loadedMethod);
     Tracker           = new AssetTracker();
     Tracker.AssetName = name;
     Tracker.RefCount  = 1;
     Tracker.Status    = EAssetStatus.Loading;
 }
示例#4
0
 /// <summary>
 /// Asyncronously loads the specified asset array
 /// </summary>
 /// <param name="assetNames">Names of assets to laod</param>
 /// <param name="itemLoadedMethod">Method to call once load is completed</param>
 /// <returns>AssetTracker array of assets to be loaded. Allows to poll the asset status if desired</returns>
 public AssetTracker[] LoadAsync(string[] assetNames, AssetLoaded itemLoadedMethod, AssetLoadedHandler Callback)
 {
     AssetTracker[] assets = new AssetTracker[assetNames.Length];
     for (int i = 0; i < assets.Length; i++)
     {
         assets[i] = LoadAsync(assetNames[i], itemLoadedMethod, Callback);
     }
     return(assets);
 }
        /// <summary>
        /// Force an asset to be disposed. Optionally releases child assets
        /// </summary>
        /// <param name="assetName">Name of asset to unload</param>
        /// <param name="releaseChildren">Release child assets</param>
        public void Unload(string assetName, bool releaseChildren)
        {
            if (mCache.ContainsKey(assetName))
            {
                AssetTracker tracker = mCache[assetName];

                // Fire changed event
                tracker.OnAssetChanged(new AssetChangedEventArgs(null));

                // Destroy disposables
                DisposeAssetTracker(tracker, releaseChildren);

                // Remove from dictionary
                mCache.Remove(assetName);
                mCacheNames.Remove(assetName);
            }
        }
        /// <summary>
        /// Release asset. Decrements the reference count and
        /// removes child assets when the count is zero
        /// </summary>
        /// <param name="assetName">Asset to release</param>
        public void Release(string assetName)
        {
            if (mCache.ContainsKey(assetName))
            {
                AssetTracker tracker = mCache[assetName];
                tracker.RefCount--;

                if (tracker.RefCount == 0)
                {
                    tracker.OnAssetChanged(new AssetChangedEventArgs(null));
                    DisposeAssetTracker(tracker, true);

                    // Remove from dictionary
                    mCache.Remove(assetName);
                    mCacheNames.Remove(assetName);
                }
            }
        }
        /// <summary>
        /// Destroy IDisposables that were tracked by this asset but do not
        /// exist as assets in their own right. This will also dispose the
        /// unmanaged internals like vertex and index buffers
        /// </summary>
        /// <param name="tracker">AssetTracker to dispose</param>
        /// <param name="releaseChildren">If true, child assets will be released</param>
        private void DisposeAssetTracker(AssetTracker tracker, bool releaseChildren)
        {
            // Invoke asset changed event.
            tracker.OnAssetChanged(new AssetChangedEventArgs(null));

            // Mark tracker as disposed
            tracker.Status = EAssetStatus.Disposed;

            // Destroy tracked disposables
            foreach (IDisposable disposable in tracker.Disposables)
            {
                disposable.Dispose();
            }

            // Dispose the actual asset, if possible
            if (tracker.Asset is IDisposable)
            {
                ((IDisposable)tracker.Asset).Dispose();
            }

            // Handle child assets
            foreach (string childAsset in tracker.RefersTo)
            {
                if (mCache.ContainsKey(childAsset))
                {
                    // Maintain child reference list
                    mCache[childAsset].ReferredToBy.Remove(tracker.AssetName);

                    // release child assets if requested
                    if (releaseChildren)
                    {
                        Release(childAsset);
                    }
                }
            }
        }
		/// <summary>
		/// Asyncronously loads the specified asset array
		/// </summary>
		/// <param name="assetNames">Names of assets to laod</param>
		/// <param name="itemLoadedMethod">Method to call once load is completed</param>
		/// <returns>AssetTracker array of assets to be loaded. Allows to poll the asset status if desired</returns>
		public AssetTracker[] LoadAsync(string[] assetNames, AssetLoaded itemLoadedMethod, AssetLoadedHandler Callback) {
			AssetTracker[] assets = new AssetTracker[assetNames.Length];
			for (int i = 0; i < assets.Length; i++)
				assets[i] = LoadAsync(assetNames[i], itemLoadedMethod, Callback);
			return assets;
		}
示例#9
0
        /// <summary>
        /// Asyncronously loads the specified asset
        /// </summary>
        /// <param name="assetName">Name of asset to laod</param>
        /// <param name="itemLoadedMethod">Method to call once load is completed</param>
        /// <returns>AssetTracker of asset to be loaded. Allows to poll the asset status if desired</returns>
        public AssetTracker LoadAsync(string assetName, AssetLoaded itemLoadedMethod, AssetLoadedHandler Callback)
        {
            AssetTracker tracker = null;

            // Check if asset is already loaded
            if (mCache.ContainsKey(assetName))
            {
                tracker = mCache[assetName];

                // Increment reference count
                tracker.RefCount++;

                // Call the specified item loaded method
                if (itemLoadedMethod != null)
                {
                    itemLoadedMethod(tracker.Asset);
                }
            }
            else
            {
                if (mLoadThread == null)
                {
                    // First time LoadAsync has been called so
                    // initialise thread, reset event and queue
                    mLoadThread     = new Thread(new ThreadStart(LoadingThreadWorker));
                    mLoadItemsQueue = new Queue <LoadAsyncParams>();
                    mLoadResetEvent = new AutoResetEvent(false);

                    // Start thread. It will wait once queue is empty
                    mLoadThread.Start();
                }

                // Create the async argument structure and enqueue it for async load.
                lock (mLoadItemsQueue) {
                    // first check if this item is already enqueued
                    Queue <LoadAsyncParams> .Enumerator enumer = mLoadItemsQueue.GetEnumerator();
                    while (enumer.MoveNext())
                    {
                        if (enumer.Current.Tracker.AssetName == assetName)
                        {
                            // Register the itemLoaded method
                            enumer.Current.ItemLoadedMethods.Add(itemLoadedMethod);
                            tracker = enumer.Current.Tracker;
                            tracker.RefCount++;
                            break;
                        }
                    }

                    // Item not already queued for loading
                    if (tracker == null)
                    {
                        LoadAsyncParams args = new LoadAsyncParams(assetName, itemLoadedMethod);
                        tracker = args.Tracker;
                        mLoadItemsQueue.Enqueue(args);
                    }
                }

                // Tell loading thread to stop waiting
                mLoadResetEvent.Set();
            }

            tracker.OnAssetLoaded = Callback;

            // Return tracker. Allows async caller to poll loaded status
            return(tracker);
        }
        private object Load(string assetName, AssetTracker tracker, AssetLoadedHandler Callback)
        {
            // Return asset if currently loaded
            if (mCache.ContainsKey(assetName))
            {
                // Get asset tracker
                AssetTracker trackerExisting = mCache[assetName];

                object asset = trackerExisting.Asset;

                // Increment tracker's reference count after the cast as the cast will
                // throw an exception if the incorrect generic type parameter is given
                trackerExisting.RefCount++;

                // Maintain the reference lists to show that this asset was loaded by
                // the asset on the top of the stack
                if (mCacheLoadingStack.Count > 0)
                {
                    mCacheLoadingStack.Peek().RefersTo.Add(assetName);
                    trackerExisting.ReferredToBy.Add(mCacheLoadingStack.Peek().AssetName);
                }

                return(asset);
            }

            // Need to load the asset. Create an AssetTracker to track it
            // unless we have been passed an existing AssetTracker
            if (tracker == null)
            {
                // Initialise tracker
                tracker           = new AssetTracker();
                tracker.RefCount  = 1;
                tracker.AssetName = assetName;
            }

            // Stack count will be zero if called by user.
            // Otherwise, Load<T> was called internally by ReadAsset<T>
            if (mCacheLoadingStack.Count > 0)
            {
                // Maintain the reference lists

                // The asset on the top of the stack refers to this asset
                mCacheLoadingStack.Peek().RefersTo.Add(assetName);

                // This asset was loaded by the asset on the top of the stack
                tracker.ReferredToBy.Add(mCacheLoadingStack.Peek().AssetName);
            }

            // Put current asset tracker on top of the stack
            // for next call to Load<T>
            mCacheLoadingStack.Push(tracker);

            try {
                tracker.Asset = ReadAsset(assetName, tracker.TrackDisposableAsset);
                tracker.Asset = Callback(tracker);

                // Ensure the list of disposables doesn't refer to the
                // actual asset, or to any assets in the loadedAssets Dictionary.
                // Best to do this now to avoid multiple disposing later
                tracker.Disposables.RemoveAll(delegate(IDisposable d) {
                    string tmp = "";
                    return(tracker.Asset == d || SearchForAsset(d, out tmp));
                });
            } catch (Exception ex) {
                System.Diagnostics.Debug.WriteLine("Asset.Load() Exception\n" + ex.ToString());
            } finally {
                // Asset has been loaded so the top tracker is not needed on the stack
                mCacheLoadingStack.Pop();
            }

            // Store the asset and it's disposables list
            mCache.Add(assetName, tracker);
            mCacheNames.Add(assetName);

            // Mark tracker as ready to use
            tracker.Status = EAssetStatus.Active;

            // Return loaded asset
            return(tracker.Asset);
        }
示例#11
0
		/// <summary>
		/// Destroy IDisposables that were tracked by this asset but do not 
		/// exist as assets in their own right. This will also dispose the
		/// unmanaged internals like vertex and index buffers
		/// </summary>
		/// <param name="tracker">AssetTracker to dispose</param>
		/// <param name="releaseChildren">If true, child assets will be released</param>
		private void DisposeAssetTracker( AssetTracker tracker, bool releaseChildren ) {
			// Invoke asset changed event.
			tracker.OnAssetChanged( new AssetChangedEventArgs( null ) );

			// Mark tracker as disposed
			tracker.Status = EAssetStatus.Disposed;

			// Destroy tracked disposables
			foreach( IDisposable disposable in tracker.Disposables ) {
				disposable.Dispose();
			}

			// Dispose the actual asset, if possible
			if( tracker.Asset is IDisposable )
				( (IDisposable)tracker.Asset ).Dispose();

			// Handle child assets
			foreach( string childAsset in tracker.RefersTo ) {
				if( mCache.ContainsKey( childAsset ) ) {
					// Maintain child reference list
					mCache[ childAsset ].ReferredToBy.Remove( tracker.AssetName );

					// release child assets if requested
					if( releaseChildren )
						Release( childAsset );
				}
			}
		}
示例#12
0
		private object Load( string assetName, AssetTracker tracker, AssetLoadedHandler Callback ) {
			// Return asset if currently loaded
			if( mCache.ContainsKey( assetName ) ) {
				// Get asset tracker
				AssetTracker trackerExisting = mCache[ assetName ];

				object asset = trackerExisting.Asset;

				// Increment tracker's reference count after the cast as the cast will  
				// throw an exception if the incorrect generic type parameter is given 
				trackerExisting.RefCount++;

				// Maintain the reference lists to show that this asset was loaded by
				// the asset on the top of the stack
				if( mCacheLoadingStack.Count > 0 ) {
					mCacheLoadingStack.Peek().RefersTo.Add( assetName );
					trackerExisting.ReferredToBy.Add( mCacheLoadingStack.Peek().AssetName );
				}

				return asset;
			}

			// Need to load the asset. Create an AssetTracker to track it
			// unless we have been passed an existing AssetTracker
			if( tracker == null ) {
				// Initialise tracker
				tracker = new AssetTracker();
				tracker.RefCount = 1;
				tracker.AssetName = assetName;
			}

			// Stack count will be zero if called by user. 
			// Otherwise, Load<T> was called internally by ReadAsset<T>
			if( mCacheLoadingStack.Count > 0 ) {
				// Maintain the reference lists

				// The asset on the top of the stack refers to this asset
				mCacheLoadingStack.Peek().RefersTo.Add( assetName );

				// This asset was loaded by the asset on the top of the stack
				tracker.ReferredToBy.Add( mCacheLoadingStack.Peek().AssetName );
			}

			// Put current asset tracker on top of the stack 
			// for next call to Load<T>
			mCacheLoadingStack.Push( tracker );

			try {
				tracker.Asset = ReadAsset( assetName, tracker.TrackDisposableAsset );
				tracker.Asset = Callback( tracker );

				// Ensure the list of disposables doesn't refer to the 
				// actual asset, or to any assets in the loadedAssets Dictionary.
				// Best to do this now to avoid multiple disposing later
				tracker.Disposables.RemoveAll( delegate( IDisposable d ) {
					string tmp = "";
					return tracker.Asset == d || SearchForAsset( d, out tmp );
				} );
			} catch( Exception ex ) {
				System.Diagnostics.Debug.WriteLine( "Asset.Load() Exception\n" + ex.ToString() );

			} finally {
				// Asset has been loaded so the top tracker is not needed on the stack
				mCacheLoadingStack.Pop();
			}

			// Store the asset and it's disposables list
			mCache.Add( assetName, tracker );
			mCacheNames.Add( assetName );

			// Mark tracker as ready to use
			tracker.Status = EAssetStatus.Active;

			// Return loaded asset
			return tracker.Asset;
		}