/// <summary> /// Calls the private Load<T>(string, AssetTracker) method. /// Reflection is needed to use an arbitrary generic type parameter /// </summary> /// <param name="loadArgs"></param> void CallGenericLoad(LoadAsyncParams loadArgs) { // The AssetType must not be null if (loadArgs.AssetType == null) { return; } MethodInfo closedMethod = null; // Unfortunate workaround to get it working on the XBox 360. // Just using GetMethod fails on the generic methods. MethodInfo[] mis = typeof(ContentTracker).GetMethods(); for (int i = 0; i < mis.Length; i++) { if (mis[i].Name == "LoadToTracker") { closedMethod = mis[i].MakeGenericMethod(loadArgs.AssetType); break; } } //////////////////////////// // Works on PC but not XBox 360. //// Get the method info //MethodInfo genericMethod = // typeof(ContentTracker).GetMethod( // "LoadToTracker", // BindingFlags.Public | BindingFlags.Instance, // null, // new Type[] { typeof(string), typeof(AssetTracker) }, // null); //// Supply the generic method with the type parameter //closedMethod = genericMethod.MakeGenericMethod(loadArgs.AssetType); //////////////////////// // Invoke the load method if (closedMethod != null) { closedMethod.Invoke( this, new object[] { loadArgs.Tracker.AssetName, loadArgs.Tracker, false }); } }
/// <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; }
/// <summary> /// Asyncronously loads the specified asset /// </summary> /// <typeparam name="T">Generic type parameter</typeparam> /// <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 /// users to poll the asset status if desired</returns> public AssetTracker LoadAsync <T>(string assetName, AssetLoaded itemLoadedMethod) { AssetTracker tracker = null; // Check if asset is already loaded if (loadedAssets.ContainsKey(assetName)) { tracker = loadedAssets[assetName]; // Increment reference count tracker.RefCount++; // Call the specified item loaded method if (itemLoadedMethod != null) { itemLoadedMethod(tracker.Asset); } } else { if (loadThread == null) { // First time LoadAsync has been called so // initialise thread, reset event and queue loadThread = new Thread(new ThreadStart(LoadingThreadWorker)); loadItemsQueue = new Queue <LoadAsyncParams>(); loadResetEvent = new AutoResetEvent(false); // Start thread. It will wait once queue is empty loadThread.Start(); } // Create the async argument structure and enqueue it for async load. lock (loadItemsQueue) { // first check if this item is already enqueued Queue <LoadAsyncParams> .Enumerator enumer = loadItemsQueue.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(typeof(T), assetName, itemLoadedMethod); tracker = args.Tracker; loadItemsQueue.Enqueue(args); } } // Tell loading thread to stop waiting loadResetEvent.Set(); } // Return tracker. Allows async caller to poll loaded status return(tracker); }