Beispiel #1
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="obj">The object to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void TryGetImageAsync(object obj, GrhImageListAsyncCallback callback, object userState)
 {
     if (obj is Grh)
     {
         // Grh
         GetImageAsync((Grh)obj, callback, userState);
     }
     else if (obj is GrhData)
     {
         // GrhData
         GetImageAsync((GrhData)obj, callback, userState);
     }
     else if (obj is GrhIndex)
     {
         // Grhindex
         GetImageAsync((GrhIndex)obj, callback, userState);
     }
     else
     {
         // Invalid type
         if (callback != null)
         {
             callback(this, null, ErrorImage, userState);
         }
     }
 }
Beispiel #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ThreadPoolAsyncCallbackState"/> class.
 /// </summary>
 /// <param name="grhData">The <see cref="StationaryGrhData"/>.</param>
 /// <param name="callback">The callback to invoke when complete.</param>
 /// <param name="userState">The user state object.</param>
 /// <param name="wait">If true, performs a spin-wait. If false, generates the <see cref="Image"/> on the thread.</param>
 /// <param name="bitmap">The unscaled <see cref="Bitmap"/>. Only needed when <paramref name="wait"/> is false.</param>
 public ThreadPoolAsyncCallbackState(StationaryGrhData grhData, GrhImageListAsyncCallback callback, object userState,
                                     bool wait, Bitmap bitmap)
 {
     _grhData   = grhData;
     _callback  = callback;
     _userState = userState;
     _wait      = wait;
     _bitmap    = bitmap;
 }
Beispiel #3
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="grh">The <see cref="Grh"/> to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void GetImageAsync(Grh grh, GrhImageListAsyncCallback callback, object userState)
 {
     if (grh == null)
     {
         if (callback != null)
         {
             callback(this, null, ErrorImage, userState);
         }
     }
     else
     {
         GetImage(grh.CurrentGrhData, true, callback, userState);
     }
 }
Beispiel #4
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="gd">The <see cref="GrhData"/> to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void GetImageAsync(GrhData gd, GrhImageListAsyncCallback callback, object userState)
 {
     if (gd == null)
     {
         if (callback != null)
         {
             callback(this, null, ErrorImage, userState);
         }
     }
     else
     {
         GetImage(gd.GetFrame(0), true, callback, userState);
     }
 }
Beispiel #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ThreadPoolAsyncCallbackState"/> class.
 /// </summary>
 /// <param name="grhData">The <see cref="StationaryGrhData"/>.</param>
 /// <param name="callback">The callback to invoke when complete.</param>
 /// <param name="userState">The user state object.</param>
 /// <param name="wait">If true, performs a spin-wait. If false, generates the <see cref="Image"/> on the thread.</param>
 /// <param name="bitmap">The unscaled <see cref="Bitmap"/>. Only needed when <paramref name="wait"/> is false.</param>
 public ThreadPoolAsyncCallbackState(StationaryGrhData grhData, GrhImageListAsyncCallback callback, object userState,
                                     bool wait, Bitmap bitmap)
 {
     _grhData = grhData;
     _callback = callback;
     _userState = userState;
     _wait = wait;
     _bitmap = bitmap;
 }
Beispiel #6
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="obj">The object to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void TryGetImageAsync(object obj, GrhImageListAsyncCallback callback, object userState)
 {
     if (obj is Grh)
     {
         // Grh
         GetImageAsync((Grh)obj, callback, userState);
     }
     else if (obj is GrhData)
     {
         // GrhData
         GetImageAsync((GrhData)obj, callback, userState);
     }
     else if (obj is GrhIndex)
     {
         // Grhindex
         GetImageAsync((GrhIndex)obj, callback, userState);
     }
     else
     {
         // Invalid type
         if (callback != null)
             callback(this, null, ErrorImage, userState);
     }
 }
Beispiel #7
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="gd">The <see cref="StationaryGrhData"/> to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void GetImageAsync(StationaryGrhData gd, GrhImageListAsyncCallback callback, object userState)
 {
     GetImage(gd, true, callback, userState);
 }
Beispiel #8
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="grh">The <see cref="Grh"/> to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void GetImageAsync(Grh grh, GrhImageListAsyncCallback callback, object userState)
 {
     if (grh == null)
     {
         if (callback != null)
             callback(this, null, ErrorImage, userState);
     }
     else
         GetImage(grh.CurrentGrhData, true, callback, userState);
 }
Beispiel #9
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="grhIndex">The <see cref="GrhIndex"/> to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void GetImageAsync(GrhIndex grhIndex, GrhImageListAsyncCallback callback, object userState)
 {
     var gd = GrhInfo.GetData(grhIndex);
     GetImageAsync(gd, callback, userState);
 }
Beispiel #10
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="gd">The <see cref="GrhData"/> to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void GetImageAsync(GrhData gd, GrhImageListAsyncCallback callback, object userState)
 {
     if (gd == null)
     {
         if (callback != null)
             callback(this, null, ErrorImage, userState);
     }
     else
         GetImage(gd.GetFrame(0), true, callback, userState);
 }
Beispiel #11
0
        /// <summary>
        /// Gets the <see cref="Image"/> for the given argument.
        /// </summary>
        /// <param name="gd">The <see cref="StationaryGrhData"/> to get the <see cref="Image"/> for.</param>
        /// <param name="async">If true, asynchronous mode will be used. This will return null immediately if the desired
        /// <see cref="Image"/> has not yet been created.</param>
        /// <param name="callback">When <see cref="async"/> is false, contains the callback method to invoke when the <see cref="Image"/>
        /// has been created.</param>
        /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
        /// <returns>
        /// The <see cref="Image"/> for the <paramref name="gd"/>, or null if <paramref name="async"/> is set.
        /// </returns>
        Image GetImage(StationaryGrhData gd, bool async, GrhImageListAsyncCallback callback, object userState)
        {
            if (gd == null)
            {
                if (!async)
                {
                    // Return the ErrorImage directly
                    return ErrorImage;
                }
                else
                {
                    // Raise the callback and pass the ErrorImage
                    if (callback != null)
                        callback(this, gd, ErrorImage, userState);
                    return null;
                }
            }

            // Get the key
            var key = GetImageKey(gd);

            // Get the image from the cache
            Image img;
            lock (_imagesSync)
            {
                // Check if the image already exists
                if (!_images.TryGetValue(key, out img))
                {
                    // Image does not exist, so add the placeholder since we are about to create it. Placing the placeholder
                    // in there will make sure that no other threads try to create it at the same time.
                    img = null;
                    _images.Add(key, _placeholder);
                }
            }

            if (!async)
            {
                if (img != null)
                {
                    if (img == _placeholder)
                    {
                        // If we got the placeholder image, do a spin-wait until we get the actual image, then return the image. This will
                        // happen when another thread is creating the image.
                        return SpinWaitForImage(key);
                    }
                    else
                    {
                        // Any other non-null image means that the image was already created, so we can just return it immediately
                        return img;
                    }
                }
                else
                {
                    // Create it on this thread and return it when its done
                    return CreateAndInsertImage(key, gd);
                }
            }
            else
            {
                if (img != null)
                {
                    // When we get the placeholder image while in async mode, this is slightly more annoying since we have
                    // to create another thread to spin-wait on
                    if (img == _placeholder)
                    {
                        // Create the thread to spin-wait on... though only if we were given a callback method. Obviously does no
                        // good to wait for the image when there is no callback method.
                        if (callback != null)
                        {
                            var tpacs = new ThreadPoolAsyncCallbackState(gd, callback, userState, true, null);
                            ExecuteOnThreadPool(tpacs);
                        }
                    }
                    else
                    {
                        // But when we get the actual image, we can just invoke the callback directly from this thread. This is the
                        // once scenario where no threads are created in async mode.
                        if (callback != null)
                            callback(this, gd, img, userState);
                    }
                }
                else
                {
                    // NOTE: The asynchronous aspect is less than optimal due to this.
                    // When originally designing this, I was working under the assumption that SFML would be able to deal with the threading
                    // better. Turns out I was wrong. There are probably some other threading issues that would have to be taken into
                    // account, too, like that content can be disposed on the main thread. I could offload more onto the worker thread
                    // than just the rescaling, such as the generation of the original unscaled bitmap, but the biggest gains come from
                    // the ability to offload the actual image loading. I guess its helpful to have at least a little work offloaded
                    // than to be completely synchronous since that does mean multi-core CPUs can load a bit faster.
                    var bmp = CreateUnscaledBitmap(gd);
                    if (bmp == null)
                    {
                        // If the bitmap failed to be created for whatever reason, use the ErrorImage
                        if (callback != null)
                            callback(this, gd, ErrorImage, userState);

                        lock (_imagesSync)
                        {
                            Debug.Assert(_images[key] == _placeholder);
                            _images[key] = ErrorImage;
                        }
                    }
                    else
                    {
                        // Add the Image creation job to the thread pool
                        var tpacs = new ThreadPoolAsyncCallbackState(gd, callback, userState, false, bmp);
                        ExecuteOnThreadPool(tpacs);
                    }
                }

                // Async always returns null
                return null;
            }
        }
Beispiel #12
0
 /// <summary>
 /// Initializes the <see cref="GrhTreeViewNode"/> class.
 /// </summary>
 static GrhTreeViewNode()
 {
     _grhImageList = GrhImageList.Instance;
     _asyncCallback = GrhImageListAsyncCallback;
     _setNodeImage = SetNodeImage;
 }
Beispiel #13
0
 /// <summary>
 /// Initializes the <see cref="GrhTreeViewNode"/> class.
 /// </summary>
 static GrhTreeViewNode()
 {
     _grhImageList  = GrhImageList.Instance;
     _asyncCallback = GrhImageListAsyncCallback;
     _setNodeImage  = SetNodeImage;
 }
Beispiel #14
0
 /// <summary>
 /// Asynchronously gets the <see cref="Image"/> for the given argument.
 /// </summary>
 /// <param name="gd">The <see cref="StationaryGrhData"/> to get the <see cref="Image"/> for.</param>
 /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
 /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
 public void GetImageAsync(StationaryGrhData gd, GrhImageListAsyncCallback callback, object userState)
 {
     GetImage(gd, true, callback, userState);
 }
Beispiel #15
0
        /// <summary>
        /// Asynchronously gets the <see cref="Image"/> for the given argument.
        /// </summary>
        /// <param name="grhIndex">The <see cref="GrhIndex"/> to get the <see cref="Image"/> for.</param>
        /// <param name="callback">The <see cref="GrhImageListAsyncCallback"/> to invoke when the operation has finished.</param>
        /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
        public void GetImageAsync(GrhIndex grhIndex, GrhImageListAsyncCallback callback, object userState)
        {
            var gd = GrhInfo.GetData(grhIndex);

            GetImageAsync(gd, callback, userState);
        }
Beispiel #16
0
        /// <summary>
        /// Gets the <see cref="Image"/> for the given argument.
        /// </summary>
        /// <param name="gd">The <see cref="StationaryGrhData"/> to get the <see cref="Image"/> for.</param>
        /// <param name="async">If true, asynchronous mode will be used. This will return null immediately if the desired
        /// <see cref="Image"/> has not yet been created.</param>
        /// <param name="callback">When <see cref="async"/> is false, contains the callback method to invoke when the <see cref="Image"/>
        /// has been created.</param>
        /// <param name="userState">The optional user state object to pass to the <paramref name="callback"/>.</param>
        /// <returns>
        /// The <see cref="Image"/> for the <paramref name="gd"/>, or null if <paramref name="async"/> is set.
        /// </returns>
        Image GetImage(StationaryGrhData gd, bool async, GrhImageListAsyncCallback callback, object userState)
        {
            if (gd == null)
            {
                if (!async)
                {
                    // Return the ErrorImage directly
                    return(ErrorImage);
                }
                else
                {
                    // Raise the callback and pass the ErrorImage
                    if (callback != null)
                    {
                        callback(this, gd, ErrorImage, userState);
                    }
                    return(null);
                }
            }

            // Get the key
            var key = GetImageKey(gd);

            // Get the image from the cache
            Image img;

            lock (_imagesSync)
            {
                // Check if the image already exists
                if (!_images.TryGetValue(key, out img))
                {
                    // Image does not exist, so add the placeholder since we are about to create it. Placing the placeholder
                    // in there will make sure that no other threads try to create it at the same time.
                    img = null;
                    _images.Add(key, _placeholder);
                }
            }

            if (!async)
            {
                if (img != null)
                {
                    if (img == _placeholder)
                    {
                        // If we got the placeholder image, do a spin-wait until we get the actual image, then return the image. This will
                        // happen when another thread is creating the image.
                        return(SpinWaitForImage(key));
                    }
                    else
                    {
                        // Any other non-null image means that the image was already created, so we can just return it immediately
                        return(img);
                    }
                }
                else
                {
                    // Create it on this thread and return it when its done
                    return(CreateAndInsertImage(key, gd));
                }
            }
            else
            {
                if (img != null)
                {
                    // When we get the placeholder image while in async mode, this is slightly more annoying since we have
                    // to create another thread to spin-wait on
                    if (img == _placeholder)
                    {
                        // Create the thread to spin-wait on... though only if we were given a callback method. Obviously does no
                        // good to wait for the image when there is no callback method.
                        if (callback != null)
                        {
                            var tpacs = new ThreadPoolAsyncCallbackState(gd, callback, userState, true, null);
                            ExecuteOnThreadPool(tpacs);
                        }
                    }
                    else
                    {
                        // But when we get the actual image, we can just invoke the callback directly from this thread. This is the
                        // once scenario where no threads are created in async mode.
                        if (callback != null)
                        {
                            callback(this, gd, img, userState);
                        }
                    }
                }
                else
                {
                    // NOTE: The asynchronous aspect is less than optimal due to this.
                    // When originally designing this, I was working under the assumption that SFML would be able to deal with the threading
                    // better. Turns out I was wrong. There are probably some other threading issues that would have to be taken into
                    // account, too, like that content can be disposed on the main thread. I could offload more onto the worker thread
                    // than just the rescaling, such as the generation of the original unscaled bitmap, but the biggest gains come from
                    // the ability to offload the actual image loading. I guess its helpful to have at least a little work offloaded
                    // than to be completely synchronous since that does mean multi-core CPUs can load a bit faster.
                    var bmp = CreateUnscaledBitmap(gd);
                    if (bmp == null)
                    {
                        // If the bitmap failed to be created for whatever reason, use the ErrorImage
                        if (callback != null)
                        {
                            callback(this, gd, ErrorImage, userState);
                        }

                        lock (_imagesSync)
                        {
                            Debug.Assert(_images[key] == _placeholder);
                            _images[key] = ErrorImage;
                        }
                    }
                    else
                    {
                        // Add the Image creation job to the thread pool
                        var tpacs = new ThreadPoolAsyncCallbackState(gd, callback, userState, false, bmp);
                        ExecuteOnThreadPool(tpacs);
                    }
                }

                // Async always returns null
                return(null);
            }
        }