WIP
DirectOutput framework for virtual pinball cabinets WIP
Go to:
Overview 
TableElementList.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
4 using System.Linq;
5 
6 namespace DirectOutput.Table
7 {
11  public class TableElementList : ExtList<TableElement>
12  {
13  //Dictionary for fast lookups
14  private Dictionary<TableElementTypeEnum, Dictionary<int, TableElement>> _NumberedTableElementsDictionary;
15  private Dictionary<string, TableElement> _NamedTableElementsDictionary;
16 
21  {
22  foreach (TableElement TE in this)
23  {
24  TE.AssignedEffects.Init(Table);
25  }
26  }
27 
31  public void FinishAssignedEffects()
32  {
33  foreach (TableElement TE in this)
34  {
35  TE.AssignedEffects.Finish();
36  }
37  }
38 
39  #region Direct access to TableElementType Dictionaries
40 
44  //public Dictionary<int, TableElement> GetTableElementDictonaryForType(TableElementTypeEnum Type)
45  //{
46 
47  // return _NumberedTableElementsDictionary[Type];
48  //}
49 
50 
55  public List<TableElement> GetTableElementListForType(TableElementTypeEnum Type)
56  {
57  if (Type == TableElementTypeEnum.NamedElement)
58  {
59  return new List<TableElement>(_NamedTableElementsDictionary.Values);
60  }
61  else
62  {
63  return new List<TableElement>(_NumberedTableElementsDictionary[Type].Values);
64  }
65  }
66 
70  public Dictionary<int, TableElement> Switch
71  {
72  get
73  {
74  return _NumberedTableElementsDictionary[TableElementTypeEnum.Switch];
75  }
76  }
80  public Dictionary<int, TableElement> Solenoid
81  {
82  get
83  {
84  return _NumberedTableElementsDictionary[TableElementTypeEnum.Solenoid];
85  }
86  }
90  public Dictionary<int, TableElement> Lamp
91  {
92  get
93  {
94  return _NumberedTableElementsDictionary[TableElementTypeEnum.Lamp];
95  }
96  }
100  public Dictionary<int, TableElement> GIString
101  {
102  get
103  {
104  return _NumberedTableElementsDictionary[TableElementTypeEnum.GIString];
105  }
106  }
107 
111  public Dictionary<int, TableElement> Mech
112  {
113  get
114  {
115  return _NumberedTableElementsDictionary[TableElementTypeEnum.Mech];
116  }
117  }
118  #endregion
119 
120  #region Indexer
121  public TableElement this[TableElementTypeEnum TableElementType, int Number]
128  {
129  get
130  {
131  if (TableElementType == TableElementTypeEnum.NamedElement)
132  {
133  throw new IndexOutOfRangeException("Table element type NamedElement cant be retrieved by number.");
134  }
135  return _NumberedTableElementsDictionary[TableElementType][Number];
136  }
137  }
138 
139 
140 
141 
150  public TableElement this[string TableElementName]
151  {
152  get
153  {
154 
155  return _NamedTableElementsDictionary[TableElementName];
156  }
157  }
158 
159 
160  #endregion
161 
162  #region UpdateState()
163 
164 
169  public void UpdateState(TableElementData Data)
170  {
171  if (Data.TableElementType != TableElementTypeEnum.NamedElement)
172  {
173  if (Contains(Data.TableElementType, Data.Number))
174  {
175  _NumberedTableElementsDictionary[Data.TableElementType][Data.Number].Value = Data.Value;
176 
177  }
178  else
179  {
180  Add(Data.TableElementType, Data.Number, Data.Value);
181  }
182  }
183  else
184  {
185  //Update named element
186  //Log.Write("Update element: " + Data.Name);
187  if (Contains(Data.Name))
188  {
189  _NamedTableElementsDictionary[Data.Name.ToUpperInvariant()].Value = Data.Value;
190  }
191  else
192  {
193  Add(Data.Name.ToUpperInvariant(), Data.Value);
194  }
195  }
196 
197  }
198 
199  #endregion
200 
201  #region Add
202 
210  public new void Add(TableElement TableElement)
211  {
212  if (TableElement == null)
213  {
214  throw new Exception("Cant add null to the list of table elements.");
215  }
216 
217  if (TableElement.TableElementType != TableElementTypeEnum.NamedElement)
218  {
219  if (Contains(TableElement))
220  {
221  throw new Exception("The TableElement {0} {1} cant be added to the list. Another entry with the same type and number does already exist.".Build(TableElement.TableElementType, TableElement.Number));
222  }
223 
224  _NumberedTableElementsDictionary[TableElement.TableElementType].Add(TableElement.Number, TableElement);
225  }
226  else
227  {
228  //Log.Write("Adding element 2: " + TableElement.Name);
229 
230  if (TableElement.Name.IsNullOrWhiteSpace())
231  {
232  throw new Exception("Named TableElements cant have a empty name when they are added to the list.");
233  }
234 
235  if (Contains(TableElement))
236  {
237  throw new Exception("The TableElement named {0} cant be added to the list. Another entry with the same name does already exist.".Build(TableElement.Name));
238  }
239  _NamedTableElementsDictionary.Add(TableElement.Name, TableElement);
240  }
241 
242  base.Add(TableElement);
243  }
244 
245 
257  public void Add(TableElementTypeEnum TableElementType, int Number, int State)
258  {
259  Add(new TableElement(TableElementType, Number, State));
260  }
261 
262  public void Add(string TableElementName, int State)
263  {
264  //Log.Write("Adding element 1: " + TableElementName);
265  Add(new TableElement(TableElementName, State));
266  }
267 
268 
269 
270  #endregion
271  #region Contains
272 
273 
280  {
281  if (TableElement.TableElementType != TableElementTypeEnum.NamedElement)
282  {
283  return _NumberedTableElementsDictionary[TableElement.TableElementType].ContainsKey(TableElement.Number) || base.Contains(TableElement);
284  }
285  else
286  {
287  return _NamedTableElementsDictionary.ContainsKey(TableElement.Name.ToUpperInvariant()) || base.Contains(TableElement); ;
288  }
289  }
290 
297  public bool Contains(TableElementTypeEnum TableElementType, int Number)
298  {
299  return _NumberedTableElementsDictionary[TableElementType].ContainsKey(Number);
300  }
301 
309  public bool Contains(string TableElementName)
310  {
311  return _NamedTableElementsDictionary.ContainsKey(TableElementName.ToUpperInvariant());
312  }
313 
314 
315 
316 
317  #endregion
318  #region Remove
319 
326  {
327  if (TableElement == null) return false;
328 
329  if (!Contains(TableElement)) return false;
330 
331  if (TableElement.TableElementType != TableElementTypeEnum.NamedElement)
332  {
333  _NumberedTableElementsDictionary[TableElement.TableElementType].Remove(TableElement.Number);
334  }
335  else
336  {
337  _NamedTableElementsDictionary.Remove(TableElement.Name);
338  }
339 
340  return base.Remove(TableElement);
341 
342  }
343 
350  public bool Remove(TableElementTypeEnum TableElementType, int Number)
351  {
352  if (!Contains(TableElementType, Number)) return false;
353 
354  Remove(_NumberedTableElementsDictionary[TableElementType][Number]);
355 
356  _NumberedTableElementsDictionary[TableElementType].Remove(Number);
357 
358  return true;
359 
360  }
361 
362 
368  public bool Remove(string TableElementName)
369  {
370  if (!Contains(TableElementName)) return false;
371 
372  Remove(_NamedTableElementsDictionary[TableElementName]);
373 
374  _NamedTableElementsDictionary.Remove(TableElementName);
375 
376  return true;
377  }
378 
379  #endregion
380 
387  public string[] GetTableElementDescriptors()
388  {
389 
390  string[] X = this.Select(TE => "{0}{1}".Build(((char)TE.TableElementType).ToString(), (TE.TableElementType == TableElementTypeEnum.NamedElement ? TE.Name : TE.Number.ToString()))).ToArray();
391  return X;
392 
393  }
394 
395  #region Events & Event handling
396 
397 
398  //TODO: Review set event code. Disable set (throw error) or make sure all updates work as needed.
399  void TableElementList_AfterSet(object sender, SetEventArgs<TableElement> e)
400  {
401  _NumberedTableElementsDictionary[e.OldItem.TableElementType].Remove(e.OldItem.Number);
402  e.OldItem.ValueChanged -= new EventHandler<TableElementValueChangedEventArgs>(Item_ValueChanged);
403  _NumberedTableElementsDictionary[e.NewItem.TableElementType].Add(e.NewItem.Number, e.NewItem);
404  e.NewItem.ValueChanged += new EventHandler<TableElementValueChangedEventArgs>(Item_ValueChanged);
405  }
406 
407  void TableElementList_BeforeSet(object sender, SetEventArgs<TableElement> e)
408  {
409 
410 
411  if (!Contains(e.NewItem.TableElementType, e.NewItem.Number) || (e.NewItem.TableElementType == e.OldItem.TableElementType && e.NewItem.Number == e.OldItem.Number))
412  {
413 
414  }
415  else
416  {
417  throw new Exception("Another TableElement with type {0} and number {1} does already exist in the list.".Build(e.NewItem.TableElementType, e.NewItem.Number));
418  }
419  }
420 
421 
422  void TableElementList_AfterRemove(object sender, RemoveEventArgs<TableElement> e)
423  {
424  e.Item.ValueChanged -= new EventHandler<TableElementValueChangedEventArgs>(Item_ValueChanged);
425  }
426 
427  void TableElementList_AfterInsert(object sender, InsertEventArgs<TableElement> e)
428  {
429  e.Item.ValueChanged += new EventHandler<TableElementValueChangedEventArgs>(Item_ValueChanged);
430  }
431 
432  void Item_ValueChanged(object sender, TableElementValueChangedEventArgs e)
433  {
434  OnTableElementValueChanged(e);
435  }
436 
437  #region "TableElement Value Changed Event
438 
439 
440  private void OnTableElementValueChanged(TableElementValueChangedEventArgs e)
441  {
442  if (TableElementValueChanged != null)
443  {
444  TableElementValueChanged(this, e);
445  }
446  }
447 
448 
449 
453  public event TableElementValueChangedEventHandler TableElementValueChanged;
454 
460  public delegate void TableElementValueChangedEventHandler(object sender, TableElementValueChangedEventArgs e);
461 
462 
463  #endregion
464 
465  #endregion
466 
467  #region Constructor
468 
473  {
474  //Init internal dictionary
475  _NumberedTableElementsDictionary = new Dictionary<TableElementTypeEnum, Dictionary<int, TableElement>>();
476  foreach (TableElementTypeEnum T in Enum.GetValues(typeof(TableElementTypeEnum)))
477  {
478  if (T != TableElementTypeEnum.NamedElement)
479  {
480  _NumberedTableElementsDictionary.Add(T, new Dictionary<int, TableElement>());
481  }
482  }
483  _NamedTableElementsDictionary = new Dictionary<string, TableElement>();
484  this.AfterInsert += new EventHandler<InsertEventArgs<TableElement>>(TableElementList_AfterInsert);
485  this.AfterRemove += new EventHandler<RemoveEventArgs<TableElement>>(TableElementList_AfterRemove);
486  this.BeforeSet += new EventHandler<SetEventArgs<TableElement>>(TableElementList_BeforeSet);
487  this.AfterSet += new EventHandler<SetEventArgs<TableElement>>(TableElementList_AfterSet);
488  }
489 
490 
491 
492 
493 
494  #endregion
495 
500  {
501  foreach (TableElement TE in this)
502  {
503  TE.ValueChanged -= new EventHandler<TableElementValueChangedEventArgs>(Item_ValueChanged);
504 
505  }
506 
507  }
508  }
509 }
string[] GetTableElementDescriptors()
Gets the table element descriptors. NamedElements are returned as $Name. Numbered elemenst are return...
new void Add(TableElement TableElement)
Adds a TableElement to the list.
Ty Item
The value of the Item to remove from index.
Event args for Set events.
Definition: SetEventArgs.cs:9
TableElementTypeEnum TableElementType
The type of the table element.
void InitAssignedEffects(Table Table)
Initializes the AssignedEffects for all TableElements in this list.
AssignedEffectList AssignedEffects
List of effects which are assigned to the table element.
bool Contains(string TableElementName)
Determines whether a table element with the specified name is contained in the list.
bool Remove(TableElementTypeEnum TableElementType, int Number)
Removes the TableElement with the specified TableElementType and Number from the list.
int Number
Number of the TableElement.
Definition: TableElement.cs:43
EventHandler< TableElementValueChangedEventArgs > ValueChanged
Event is fired if the value of the property State is changed.
Ty NewItem
New item for the replacement.
Definition: SetEventArgs.cs:25
int Number
The number of the table element.
Ty Item
The new value of the element at Index.
Mech object.
General illumination.
TableElementTypeEnum
Enum for the different TableElement types.
bool Remove(string TableElementName)
Removes the table element with the specified name.
TableElementValueChangedEventHandler TableElementValueChanged
Is fired on changes of the value of any TableElement in this collection
int Value
The value of the table element.
void FinishAssignedEffects()
Finishes the AssignedEffects for all TableElements in this list.
EventArgs object for TableElementValueChanged events.
string Name
Name of the TableElement. Triggers NameChanged if value is changed.
Definition: TableElement.cs:65
new bool Contains(TableElement TableElement)
Checks if a specified TableElement is contained in the list.
TableElementList()
Initializes a new instance of the TableElementList class.
Data representing the state of a table emlement
List of TableElement objects.
List< TableElement > GetTableElementListForType(TableElementTypeEnum Type)
Returns a list of the TableElement objects with the specified type.
void UpdateState(TableElementData Data)
Method to update the state and/or add a entry to the list
void Add(string TableElementName, int State)
bool Contains(TableElementTypeEnum TableElementType, int Number)
Checks if a specified TableElement is contained in the list.
TableElementTypeEnum TableElementType
Type of the TableElement.
Definition: TableElement.cs:24
Holds all table specific information and handles all TableElements
Definition: Table.cs:20
Extended version of the generic List class supporting events for various actions on the list...
Definition: ExtList.cs:11
string Name
The name of the table element
Represents a element (e.g. Switch, Solenoid) of a pinball table
Definition: TableElement.cs:12
Eventargs of BeforeInsert and AfterInsert events.
void Add(TableElementTypeEnum TableElementType, int Number, int State)
Method for adding a entry to the list.
The namespace DirectOutput.General contains classes for general use.
new bool Remove(TableElement TableElement)
Removes the specified TableElement from the List.