Collections/RingCollection.cs
author sl
Sun, 03 Feb 2013 18:01:50 +0100
changeset 391 ca4c0e7ae75d
parent 298 96263190189a
permissions -rw-r--r--
Converted project to VisualStudio 2012.
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2011 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections;
    13 using System.Collections.Generic;
    14 
    15 namespace OpenHardwareMonitor.Collections {
    16   public class RingCollection<T> : IEnumerable<T> {
    17 
    18     private T[] array;
    19 
    20     // first item of collection
    21     private int head;
    22 
    23     // index after the last item of the collection
    24     private int tail;
    25 
    26     // number of items in the collection
    27     private int size;
    28 
    29     public RingCollection() : this(0) { }
    30 
    31     public RingCollection(int capacity) {
    32       if (capacity < 0)
    33         throw new ArgumentOutOfRangeException("capacity");
    34       this.array = new T[capacity];
    35       this.head = 0; 
    36       this.tail = 0;
    37       this.size = 0;
    38     }
    39 
    40     public int Capacity {
    41       get {
    42         return array.Length;
    43       }
    44       set {
    45         T[] newArray = new T[value];
    46         if (size > 0) {
    47           if (head < tail) {
    48             Array.Copy(array, head, newArray, 0, size);
    49           } else {
    50             Array.Copy(array, head, newArray, 0, array.Length - head);
    51             Array.Copy(array, 0, newArray, array.Length - head, tail);
    52           }
    53         }
    54         this.array = newArray;
    55         this.head = 0;
    56         this.tail = size == value ? 0 : size;
    57       }
    58     }
    59 
    60     public void Clear() {
    61       
    62       // remove potential references 
    63       if (head < tail) {
    64         Array.Clear(array, head, size);
    65       } else {
    66         Array.Clear(array, 0, tail);
    67         Array.Clear(array, head, array.Length - head);
    68       }
    69 
    70       this.head = 0;
    71       this.tail = 0;
    72       this.size = 0;
    73     }
    74 
    75     public void Append(T item) {
    76       if (size == array.Length) {
    77         int newCapacity = array.Length * 3 / 2;
    78         if (newCapacity < array.Length + 8)
    79           newCapacity = array.Length + 8;
    80         Capacity = newCapacity;
    81       }
    82 
    83       array[tail] = item;
    84       tail = tail + 1 == array.Length ? 0 : tail + 1;
    85       size++;
    86     }
    87 
    88     public T Remove() {
    89       if (size == 0)
    90         throw new InvalidOperationException();
    91 
    92       T result = array[head];
    93       array[head] = default(T);
    94       head = head + 1 == array.Length ? 0 : head + 1;
    95       size--;
    96 
    97       return result;
    98     }
    99 
   100     public int Count {
   101       get {
   102         return size;
   103       }
   104     }
   105 
   106     public T this[int index] {
   107       get {
   108         if (index < 0 || index >= size)
   109           throw new IndexOutOfRangeException();
   110         int i = head + index;
   111         if (i >= array.Length)
   112           i -= array.Length;
   113         return array[i];
   114       }
   115       set {
   116         if (index < 0 || index >= size)
   117           throw new IndexOutOfRangeException();
   118         int i = head + index;
   119         if (i >= array.Length)
   120           i -= array.Length;
   121         array[i] = value;
   122       }
   123     }
   124 
   125     public T First {
   126       get {
   127         if (size == 0)
   128           throw new InvalidOperationException();
   129         return array[head];
   130       }
   131       set {
   132         if (size == 0)
   133           throw new InvalidOperationException();
   134         array[head] = value;
   135       }
   136     }
   137 
   138     public T Last {
   139       get {
   140         if (size == 0)
   141           throw new InvalidOperationException();
   142         return array[tail == 0 ? array.Length - 1 : tail - 1];
   143       }
   144       set {
   145         if (size == 0)
   146           throw new InvalidOperationException();
   147         array[tail == 0 ? array.Length - 1 : tail - 1] = value;
   148       }
   149     }
   150 
   151     IEnumerator<T> IEnumerable<T>.GetEnumerator() {
   152       return new RingCollection<T>.Enumerator(this);
   153     }
   154 
   155     IEnumerator IEnumerable.GetEnumerator() {
   156       return new RingCollection<T>.Enumerator(this);
   157     }
   158 
   159     private struct Enumerator : IEnumerator<T>, IEnumerator {
   160 
   161       private RingCollection<T> collection;
   162       private int index;
   163 
   164       public Enumerator(RingCollection<T> collection) {
   165         this.collection = collection;
   166         this.index = -1;
   167       }
   168 
   169       public void Dispose() {
   170         this.index = -2;
   171       }
   172 
   173       public void Reset() {
   174         this.index = -1;
   175       }
   176 
   177       public T Current {
   178         get {
   179           if (index < 0)
   180             throw new InvalidOperationException();
   181           return collection[index];
   182         }
   183       }
   184 
   185       object IEnumerator.Current {
   186         get {
   187           if (index < 0)
   188             throw new InvalidOperationException();
   189           return collection[index];
   190         }
   191       }
   192 
   193       public bool MoveNext() {
   194         if (index == -2)
   195           return false;
   196 
   197         index++;
   198 
   199         if (index == collection.size) {
   200           index = -2;
   201           return false;
   202         }
   203 
   204         return true;
   205       }
   206     }
   207   }
   208 }