source: branches/eraser6/CodeReview/Eraser.Manager/IRegistrar.cs @ 1792

Revision 1792, 5.6 KB checked in by lowjoel, 4 years ago (diff)

Implemented an IRegistrar interface for all registrars, and an IRegisterable interface for all classes which need to be registered with IRegistrar, and migrated the Entropy and Erasure Method classes to the new interfaces. Addresses #276: Implement Eraser Registrar Interface

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
RevLine 
[1792]1/*
2 * $Id$
3 * Copyright 2008-2010 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Linq;
24using System.Collections.Generic;
25using System.Text;
26
27namespace Eraser.Manager
28{
29    /// <summary>
30    /// The abstract registrar interface.
31    /// </summary>
32    public interface IRegistrar<T> : IList<T> where T: IRegisterable
33    {
34        /// <summary>
35        /// Gets the registerable object from its Guid.
36        /// </summary>
37        /// <param name="key">The Guid of the registerable object to find.</param>
38        /// <returns>The registerable object.</returns>
39        /// <exception cref="KeyNotFoundException">When the Guid provided is not of
40        /// any registered object.</exception>
41        T this[Guid key] { get; }
42
43        /// <summary>
44        /// Gets whether a registerable object with the given Guid is registered.
45        /// </summary>
46        /// <param name="key">The Guid of the object to find.</param>
47        /// <returns>True if such an object is registered, otherwise false</returns>
48        bool Contains(Guid key);
49
50        /// <summary>
51        /// Unregisters the registerable object with the given Guid.
52        /// </summary>
53        /// <param name="key">The Guid to unregister.</param>
54        /// <returns>True if an object was unregistered.</returns>
55        bool Remove(Guid key);
56
57        /// <summary>
58        /// The event raised when an <see cref="IRegisterable"/> object is
59        /// registered.
60        /// </summary>
61        EventHandler<EventArgs> Registered { get; set; }
62
63        /// <summary>
64        /// The event raised when an <see cref="IRegisterable"/> object is
65        /// unregistered.
66        /// </summary>
67        EventHandler<EventArgs> Unregistered { get; set; }
68    }
69
70    /// <summary>
71    /// Represents an object registerable to an <see cref="IRegistrar"/>
72    /// </summary>
73    public interface IRegisterable
74    {
75        /// <summary>
76        /// The GUID of the current object.
77        /// </summary>
78        Guid Guid { get; }
79    }
80
81    /// <summary>
82    /// Provides a simple Registrar implementation.
83    /// </summary>
84    /// <typeparam name="T">The registerable's type.</typeparam>
85    public class Registrar<T> : IRegistrar<T> where T: IRegisterable
86    {
87        #region IList<T> Members
88
89        public int IndexOf(T item)
90        {
91            lock (List)
92                return List.IndexOf(item);
93        }
94
95        public void Insert(int index, T item)
96        {
97            lock (List)
98            {
99                List.Insert(index, item);
100                Dictionary.Add(item.Guid, item);
101            }
102
103            if (Registered != null)
104                Registered(item, EventArgs.Empty);
105        }
106
107        public void RemoveAt(int index)
108        {
109            T value = default(T);
110            lock (List)
111            {
112                value = List[index];
113                List.RemoveAt(index);
114                Dictionary.Remove(value.Guid);
115            }
116
117            if (Unregistered != null)
118                Unregistered(value, EventArgs.Empty);
119        }
120
121        public T this[int index]
122        {
123            get
124            {
125                lock (List)
126                    return List[index];
127            }
128            set
129            {
130                lock (List)
131                    List[index] = value;
132            }
133        }
134
135        #endregion
136
137        #region ICollection<T> Members
138
139        /// <remarks>If the registerable object is added twice, the second registration
140        /// is ignored.</remarks>
141        public void Add(T item)
142        {
143            lock (List)
144            {
145                if (Dictionary.ContainsKey(item.Guid))
146                    return;
147
148                List.Add(item);
149                Dictionary.Add(item.Guid, item);
150            }
151
152            if (Registered != null)
153                Registered(item, EventArgs.Empty);
154        }
155
156        public void Clear()
157        {
158            lock (List)
159            {
160                if (Unregistered != null)
161                    List.ForEach(item => Unregistered(item, EventArgs.Empty));
162                List.Clear();
163                Dictionary.Clear();
164            }
165        }
166
167        public bool Contains(T item)
168        {
169            lock (List)
170                return List.Contains(item);
171        }
172
173        public void CopyTo(T[] array, int arrayIndex)
174        {
175            lock (List)
176                List.CopyTo(array, arrayIndex);
177        }
178
179        public int Count
180        {
181            get
182            {
183                lock (List)
184                    return Count;
185            }
186        }
187
188        public bool IsReadOnly
189        {
190            get { return false; }
191        }
192
193        public bool Remove(T item)
194        {
195            bool result = false;
196            lock (List)
197            {
198                result = List.Remove(item);
199                Dictionary.Remove(item.Guid);
200            }
201
202            if (result && Unregistered != null)
203                Unregistered(item, EventArgs.Empty);
204            return result;
205        }
206
207        #endregion
208
209        #region IEnumerable<T> Members
210
211        public IEnumerator<T> GetEnumerator()
212        {
213            return List.GetEnumerator();
214        }
215
216        #endregion
217
218        #region IEnumerable Members
219
220        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
221        {
222            return List.GetEnumerator();
223        }
224
225        #endregion
226
227        #region IRegistrar<T> Members
228
229        public T this[Guid key]
230        {
231            get
232            {
233                lock (List)
234                    return Dictionary[key];
235            }
236        }
237
238        public bool Contains(Guid key)
239        {
240            lock (List)
241                return Dictionary.ContainsKey(key);
242        }
243
244        public bool Remove(Guid key)
245        {
246            lock (List)
247            {
248                if (!Dictionary.ContainsKey(key))
249                    return false;
250                return Remove(Dictionary[key]);
251            }
252        }
253
254        public EventHandler<EventArgs> Registered { get; set; }
255
256        public EventHandler<EventArgs> Unregistered { get; set; }
257
258        #endregion
259
260        /// <summary>
261        /// The backing list for this object.
262        /// </summary>
263        private List<T> List = new List<T>();
264
265        /// <summary>
266        /// The backing dictionary for this object.
267        /// </summary>
268        private Dictionary<Guid, T> Dictionary = new Dictionary<Guid, T>();
269    }
270}
Note: See TracBrowser for help on using the repository browser.