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