Jypeli  5
The simple game programming library
SynchronousList.cs
Siirry tämän tiedoston dokumentaatioon.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Collections;
6 
7 namespace Jypeli
8 {
15  public class SynchronousList<T> : IEnumerable<T>, Updatable
16  {
17  #region Item actions
18 
19  protected abstract class ListAction
20  {
22 
24  {
25  this.list = list;
26  }
27 
28  public abstract void Execute();
29  }
30 
31  protected sealed class AddItemAction : ListAction
32  {
33  internal T newItem;
34 
35  public AddItemAction( SynchronousList<T> list, T itemToAdd )
36  : base( list )
37  {
38  this.newItem = itemToAdd;
39  }
40 
41  public override void Execute()
42  {
43  if ( list.Contains( newItem ) )
44  //throw new ArgumentException( "The object has already been added." );
45  return;
46 
47  list.items.Add( newItem );
48  list.OnItemAdded( newItem );
49  }
50  }
51 
52  protected sealed class RemoveItemAction : ListAction
53  {
54  internal T removeItem;
55 
56  public RemoveItemAction( SynchronousList<T> items, T itemToRemove )
57  : base( items )
58  {
59  this.removeItem = itemToRemove;
60  }
61 
62  public override void Execute()
63  {
64  if ( list.items.Remove( removeItem ) )
65  list.OnItemRemoved( removeItem );
66  }
67  }
68 
69  protected sealed class ClearAction : ListAction
70  {
72  : base( items )
73  {
74  }
75 
76  public override void Execute()
77  {
78  foreach ( var item in list )
79  {
80  list.OnItemRemoved( item );
81  }
82 
83  list.items.Clear();
84  }
85  }
86 
87  #endregion
88 
89  internal List<T> items = new List<T>();
90  Queue<ListAction> actions = new Queue<ListAction>();
91 
97  public T this[int index]
98  {
99  get { return items[index - FirstIndex]; }
100  set { items[index - FirstIndex] = value; }
101  }
102 
106  public int FirstIndex { get; set; }
107 
111  public int LastIndex
112  {
113  get { return FirstIndex + items.Count - 1; }
114  }
115 
120  public int Count
121  {
122  get { return items.Count; }
123  }
124 
125  public bool IsUpdated
126  {
127  get { return true; }
128  }
129 
133  public event Action<T> ItemAdded;
134 
138  public event Action<T> ItemRemoved;
139 
144  public SynchronousList( int firstIndex )
145  {
146  FirstIndex = firstIndex;
147  }
148 
153  : this( 0 )
154  {
155  }
156 
157  private void OnItemAdded( T item )
158  {
159  if ( ItemAdded != null )
160  ItemAdded( item );
161  }
162 
163  private void OnItemRemoved( T item )
164  {
165  if ( ItemRemoved != null )
166  ItemRemoved( item );
167  }
168 
169  #region INotifyList<T> Members
170 
174  public event Action Changed;
175 
176  private void OnChanged()
177  {
178  if ( Changed != null )
179  Changed();
180  }
181 
182  #endregion
183 
184  #region IEnumerable Members
185 
186  public IEnumerator<T> GetEnumerator()
187  {
188  return items.GetEnumerator();
189  }
190 
191  IEnumerator IEnumerable.GetEnumerator()
192  {
193  return items.GetEnumerator();
194  }
195 
196  #endregion
197 
198  public void Add( T item )
199  {
200  actions.Enqueue( new AddItemAction( this, item ) );
201  }
202 
203  public void Remove( T item )
204  {
205  actions.Enqueue( new RemoveItemAction( this, item ) );
206  }
207 
208  public void Clear()
209  {
210  actions.Enqueue( new ClearAction( this ) );
211  }
212 
213  public bool Contains( T item )
214  {
215  return items.Contains( item );
216  }
217 
218  public bool WillContain( T item )
219  {
220  ListAction[] actionArray = actions.ToArray();
221  bool exists = Contains(item);
222 
223  for (int i = 0; i < actionArray.Length; i++)
224  {
225  if (actionArray[i] is AddItemAction && ((AddItemAction)actionArray[i]).newItem.Equals( item ))
226  exists = true;
227 
228  else if (actionArray[i] is RemoveItemAction && ((RemoveItemAction)actionArray[i]).removeItem.Equals( item ))
229  exists = false;
230 
231  else if (actionArray[i] is ClearAction)
232  exists = false;
233  }
234 
235  return exists;
236  }
237 
238  public int IndexOf( T item )
239  {
240  return FirstIndex + items.IndexOf( item );
241  }
242 
243  public T Find( Predicate<T> pred )
244  {
245  return items.Find( pred );
246  }
247 
248  public List<T> FindAll( Predicate<T> pred )
249  {
250  return items.FindAll( pred );
251  }
252 
258  public bool UpdateChanges()
259  {
260  if ( actions.Count == 0 ) return false;
261 
262  while ( actions.Count > 0 )
263  actions.Dequeue().Execute();
264 
265  return true;
266  }
267 
273  public void Update( Time time )
274  {
275  bool changed = UpdateChanges();
276 
277  foreach ( var item in items )
278  {
279  var DestroyableItem = item as Destroyable;
280  var UpdatableItem = item as Updatable;
281 
282  if ( DestroyableItem != null && DestroyableItem.IsDestroyed )
283  Remove( item );
284  else if ( UpdatableItem != null && UpdatableItem.IsUpdated )
285  UpdatableItem.Update( time );
286  }
287 
288  changed |= UpdateChanges();
289  if ( changed ) OnChanged();
290  }
291 
297  public void Update( Time time, Predicate<T> isUpdated )
298  {
299  bool changed = UpdateChanges();
300 
301  foreach ( var item in items )
302  {
303  var DestroyableItem = item as Destroyable;
304  var UpdatableItem = item as Updatable;
305 
306  if ( DestroyableItem != null && DestroyableItem.IsDestroyed )
307  Remove( item );
308  else if ( UpdatableItem != null && UpdatableItem.IsUpdated && isUpdated(item) )
309  UpdatableItem.Update( time );
310  }
311 
312  changed |= UpdateChanges();
313  if ( changed ) OnChanged();
314  }
315 
320  public void ForEach( Action<T> action )
321  {
322  for ( int i = 0; i < items.Count; i++ )
323  {
324  action( items[i] );
325  }
326  }
327 
334  public void ForEach<T1>( Action<T, T1> action, T1 p1 )
335  {
336  for ( int i = 0; i < items.Count; i++ )
337  {
338  action( items[i], p1 );
339  }
340  }
341 
342  internal IEnumerable<T> GetObjectsAboutToBeAdded()
343  {
344  return from a in actions
345  where a is AddItemAction
346  select (a as AddItemAction).newItem;
347  }
348  }
349 }
int LastIndex
Viimeisen elementin indeksi.
void Update(Time time)
Lisää ja poistaa jonossa olevat elementit sekä kutsuu niiden Update-metodia.
void ForEach(Action< T > action)
Suorittaa annetun toimenpiteen kaikille (nykyisille) listan alkioille.
Rajapinta päivittyville olioille.
Definition: Updatable.cs:6
IEnumerator< T > GetEnumerator()
Sisältää tiedon ajasta, joka on kulunut pelin alusta ja viime päivityksestä.
Definition: Time.cs:13
void ForEach< T1 >(Action< T, T1 > action, T1 p1)
Suorittaa annetun toimenpiteen kaikille (nykyisille) listan alkioille.
T Find(Predicate< T > pred)
ListAction(SynchronousList< T > list)
RemoveItemAction(SynchronousList< T > items, T itemToRemove)
Action Changed
Tapahtuu kun lista on muuttunut.
Action< T > ItemAdded
Tapahtuu kun uusi elementti on lisätty listaan.
int Count
Kuinka monta elementtiä listassa nyt on. Ei laske mukaan samalla päivityskierroksella tehtyjä muutoks...
Synkroninen lista, eli lista joka päivittyy vasta kun sen Update-metodia kutsutaan. Jos listalle lisätään IUpdatable-rajapinnan toteuttavia olioita, kutsutaan myös niiden Update-metodeja samalla.
List< T > FindAll(Predicate< T > pred)
ClearAction(SynchronousList< T > items)
void Update(Time time, Predicate< T > isUpdated)
Lisää ja poistaa jonossa olevat elementit sekä kutsuu niiden Update-metodia tietyllä ehdolla...
Action< T > ItemRemoved
Tapahtuu kun elementti on poistettu listasta.
SynchronousList()
Luo uuden synkronisen listan.
AddItemAction(SynchronousList< T > list, T itemToAdd)
int FirstIndex
Ensimmäisen elementin indeksi. Muutettavissa.
bool UpdateChanges()
Lisää ja poistaa jonossa olevat elementit, mutta ei kutsu elementtien Update-metodia.
SynchronousList(int firstIndex)
Luo uuden synkronisen listan.
Rajapinta olioille, jotka ovat tuhottavissa.
Definition: Destroyable.cs:8