The class below provides a progress model for reporting the progress of an action.

/// <summary>
/// Provides a progress class for reporting progress data.
/// </summary>
/// <typeparam name="T">The type used for the result data.</typeparam>
public class ProgressModel<T>
{
    /// <summary>
    /// Gets the results queue.
    /// </summary>
    public Queue<T> Results { get; private set; }

    /// <summary>
    /// Gets the message queue.
    /// </summary>
    public Queue<string> Messages { get; private set; }

    /// <summary>
    /// Gets or sets a value indicating whether this instance is completed.
    /// </summary>
    public bool IsComplete { get; set; }

    /// <summary>
    /// Flags the response model as canceled.
    /// </summary>
    public void Cancel()
    {
        this.IsCanceled = true;
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="ProgressModel{T}"/> class.
    /// </summary>
    public ProgressModel()
    {
        this.Results = new Queue<T>();
        this.Messages = new Queue<string>();
    }

    /// <summary>
    /// Gets a value indicating whether this instance is canceled.
    /// </summary>
    public bool IsCanceled { get; private set; }

    /// <summary>
    /// Gets or sets the progress.
    /// </summary>
    public float Progress { get; set; }

    /// <summary>
    /// Gets or sets the information that may have been thrown.
    /// </summary>
    public Exception Exception { get; set; }

    /// <summary>
    /// Gets a value indicating whether this instance is faulted.
    /// </summary>
    public bool IsFaulted
    {
        get
        {
            return this.Exception != null;
        }
    }

    /// <summary>
    /// Gets or sets the title.
    /// </summary>
    public string Title { get; set; }   
}

The code below provides a handy helper method for drawing GUI textures via GUI.DrawTextureWithTexCoords.

/// <summary>
/// Draws a image.
/// </summary>
/// <param name="image">The destination image.</param>
/// <param name="x">The x position in the destination image.</param>
/// <param name="y">The y position in the destination image.</param>
/// <param name="width">The destination width of the drawn image.</param>
/// <param name="height">The destination height of the drawn image.</param>
/// <param name="sourceX">The x position in the source image.</param>
/// <param name="sourceY">The y position in the source image.</param>
/// <param name="sourceWidth">The source width.</param>
/// <param name="sourceHeight">The source height.</param>
/// <param name="flipHorizontally">If set to <c>true</c> the image will be drawn fliped horizontally.</param>
/// <param name="flipVertically">If set to <c>true</c> the image will be drawen flipped vertically.</param>
/// <param name="tile">If set to <c>true</c> the image will be tiled across the destination area.</param>
/// <exception cref="System.ArgumentNullException">image</exception>    
/// <exception cref="ArgumentOutOfRangeException">If width, height, sourceWidth or sourceHeight are less then 1.</exception>
public static void Draw(Texture2D image, float x, float y, float width, float height, int sourceX, int sourceY, int sourceWidth, int sourceHeight,
    bool flipHorizontally, bool flipVertically, bool tile)
{
    // perform input validation
    if (image == null)
    {
        throw new ArgumentNullException("image");
    }

    if (sourceWidth < 1)
    {
        throw new ArgumentOutOfRangeException("sourceWidth");
    }

    if (sourceHeight < 1)
    {
        throw new ArgumentOutOfRangeException("sourceHeight");
    }

    if (width < 1)
    {
        throw new ArgumentOutOfRangeException("width");
    }

    if (height < 1)
    {
        throw new ArgumentOutOfRangeException("height");
    }

    var imgHeight = (float)image.height;
    var imgWidth = (float)image.width;
    var srcWidth = sourceWidth / imgWidth;
    var srcHeight = sourceHeight / imgHeight;
    var position = new Rect(x, y + height, width, -height);
    if (tile)
    {
        srcWidth = width / imgWidth;
        srcWidth = flipHorizontally ? -srcWidth : srcWidth;
        srcHeight = -(height / imgHeight);
        srcHeight = !flipVertically ? srcHeight : -srcHeight;
    }
    else
    {
        srcWidth = flipHorizontally ? -srcWidth : srcWidth;
        srcHeight = !flipVertically ? -srcHeight : srcHeight;
    }

    var texCoords = new Rect(sourceX / imgWidth, sourceY / imgHeight, srcWidth, srcHeight);

    GUI.DrawTextureWithTexCoords(position, image, texCoords, true);
}

Provides a helper method for instantiating all types within the app domain that implement an interface

/// <summary>
/// Initializes a collection of types that implement an interface.
/// </summary>
/// <typeparam name="T">The interface type to check for.</typeparam>
/// <param name="loadingErrors">The loading errors that may have occurred.</param>
/// <returns>A list of type <see cref="T"/>.</returns>
public IEnumerable<T> GetPlugins<T>(out IEnumerable<Exception> loadingErrors)
{
    // search for types in each assembly that implement the type
    var fullName = typeof(T).FullName;
    var list = new List<T>();
    var errors = new List<Exception>();

    // search through all assemblies
    foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
    {
        // search through all types
        foreach (var type in asm.GetTypes())
        {
            // ignore abstract classes
            if (type.IsAbstract)
            {
                continue;
            }

            // get interfaces that the type implements
            foreach (var inter in type.GetInterfaces())
            {
                try
                {
                    // check if type implements interface
                    if (string.CompareOrdinal(inter.FullName, fullName) == 0)
                    {
                        // create/add type to list
                        var obj = asm.CreateInstance(type.FullName);
                        var instance = (T)obj;
                        list.Add(instance);
                    }
                }
                catch (Exception ex)
                {
                    // record error
                    errors.Add(ex);
                }
            }
        }
    }

    loadingErrors = errors;
    return list;
}

/// <summary>
/// Determines whether the renderer is visible from the specified camera.
/// </summary>
/// <param name="renderer">The renderer to check for visibility.</param>
/// <param name="camera">The camera to check against.</param>
/// <returns>true if the renderer is visible to the camera; otherwise false.</returns>
public static bool IsVisibleFrom(this Renderer renderer, Camera camera)
{
    var planes = GeometryUtility.CalculateFrustumPlanes(camera);
    return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
}

Will try to fetch then remove an item at index, returning true if succeeded.

/// <summary>Retrieves and removes an item from the list.</summary>
/// <typeparam name="T">The type that the generic list contains.</typeparam>
/// <param name="list">The list.</param>
/// <param name="index">The index of the item to be pulled out of the list.</param>
/// <param name="value">The value that was retrieved from the list.</param>
/// <returns>true if successful; otherwise false.</returns>
public static bool TryPullItemAt<T>(this IList<T> list, int index, out T value)
{
    try
    {
        value = list[index];
        list.RemoveAt(index);
        return true;
    }
    catch
    {
        value = default(T);
        return false;
    }
}

The code below allows you to set and automatically restore the GUI.enabled state when used with a using block similar to GUILayout.HorizontialScope.

/// <summary>
/// Provides  a class for setting and restoring GUI.enabled.
/// </summary>
public class GuiEnabled : IDisposable
{
    /// <summary>
    /// Gets or sets a value indicating the state that is to be restored.
    /// </summary>  
    public bool StateToBeRestored { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="GuiEnabled"/> class.
    /// </summary>
    /// <param name="stateToBeRestored">Value indicating the state that is to be restored.</param>
    public GuiEnabled(bool stateToBeRestored)                                            
    {
        this.StateToBeRestored = stateToBeRestored;
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="GuiEnabled"/> class.
    /// </summary>
    /// <param name="stateToBeRestored">If set to <c>true</c> the GUI.enabled state will be restored to this value.</param>
    /// <param name="setState">Immediatley sets the value of GUI.enabled to this state.</param>
    public GuiEnabled(bool stateToBeRestored, bool setState) : this(stateToBeRestored)
    {
        GUI.enabled = setState;
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
        GUI.enabled = this.StateToBeRestored;
    }
}

Here is an simple use case

GUILayout.Button("Enabled button");
using (var enabled = new GuiEnabled(GUI.enabled, false))
{
    GUILayout.Button("Disabled button");
    //if (someCondition)
    //{   
        // setting to false means after we exit the using block GUI.enabled will be set to false. 
    //    enabled.StateToBeRestored = false; 
    //}
}
GUILayout.Button("Enabled button");

Provides a helper method for determining weather two value ranges intersect.

LINQPad v4 C# sample RangeIntersection.linq (5.18 kb)

/// <summary>
/// Check for the intersection between two sets of ranges.
/// </summary>
/// <param name="range1Start">The start of the first range.</param>
/// <param name="range1End">The end of the first reage.</param>
/// <param name="range2Start">The start of the second range.</param>
/// <param name="range2End">The end of the second range.</param>
/// <returns>true if the two ranges intersect with each other; otherwise false.</returns>
public static bool RangeIntersection(int range1Start, int range1End, int range2Start, int range2End)
{
    var r1Start = range1Start;
    var r1End = range1End;
    var r2Start = range2Start;
    var r2End = range2End;

    if (range1Start > range1End)
    {
        r1Start = range1End;
        r1End = range1Start;
    }

    if (range2Start > range2End)
    {
        r2Start = range2End;
        r2End = range2Start;
    }

    var greatestStart = r1Start > r2Start ? r1Start : r2Start;
    var smallestEnd = r1End < r2End ? r1End : r2End;
    return !(greatestStart > smallestEnd);
}

RangeChecking


        /// <summary>Retrieves and removes an item from the list.</summary>
        /// <typeparam name="T">The type that the generic list contains.</typeparam>
        /// <param name="list">The list.</param>
        /// <param name="index">The index of the item to be pulled out of the list.</param>
        public static T PullItemAt<T>(this IList<T> list, int index)
        {
            var item = list[index];
            list.RemoveAt(index);
            return item;
        }

/// <summary>
/// Adds items to a <see cref="ObservableCollection{T}"/>.
/// </summary>
/// <typeparam name="T">The generic type that the generic observable collection stores.</typeparam>
/// <param name="list">The list where items will be added to.</param>
/// <param name="items">The items to be added.</param>
public static void AddRange<T>(this ObservableCollection<T> list, IEnumerable<T> items)
{
    foreach (var item in items)
    {
        list.Add(item);
    }
}

/// <summary>
/// Tries to get a value from the generic list.
/// </summary>
/// <typeparam name="T">The type that the generic list contains.</typeparam>
/// <param name="list">The generic list reference.</param>
/// <param name="predicate">The predicate used to find the desired element.</param>
/// <param name="item">The item to be returned if the <see cref="predicate"/> argument finds a match.</param>
/// <returns>true if a item was found; otherwise false.</returns>
public static bool TryGet<T>(this IList<T> list, Func<T, bool> predicate, out T item)
{
    var result = list.Where(predicate).ToArray();
    item = result.FirstOrDefault();
    return result.Length != 0;
}

/// <summary>
/// Tries to get a value from the generic list.
/// </summary>
/// <typeparam name="T">The type that the generic list contains.</typeparam>
/// <typeparam name="S">The type that the selector function will return.</typeparam>
/// <param name="list">The generic list reference.</param>
/// <param name="predicate">The predicate used to find the desired element.</param>
/// <param name="selector">The selector function used to retrieve a value from the matched item. determined by the <see cref="predicate"/> argument.</param>
/// <param name="item">The item to be returned if the <see cref="predicate"/> argument finds a match.</param>
/// <returns>true if a item was found; otherwise false.</returns>
public static bool TryGet<T, S>(this IList<T> list, Func<T, bool> predicate, Func<T, S> selector, out S item)
{
    var result = list.Where(predicate).ToArray();
    item = selector(result.FirstOrDefault());
    return result.Length != 0;
}

Created by: X

Just another personal website in this crazy online world

Name of author Dean Lunz (aka Created by: X)
Computer programming nerd, and tech geek.
About Me -- Resume