pla-01/Life/Automaton/BasicField.cs
2019-10-26 16:47:08 +02:00

64 lines
1.8 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using Life.Annotations;
using Life.Misc;
namespace Life.Automaton
{
public abstract class BasicField : IField, INotifyPropertyChanged
{
List<IObserver<IField>> _observers = new List<IObserver<IField>>();
protected BasicField(int width, int height)
{
Size = new Size(width, height);
_cells = new Cell[width, height];
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
_cells[x, y] = new Cell();
}
private Cell[,] _cells;
public Size Size { get; }
public Cell this[int x, int y]
{
get => _cells[x, y];
set
{
_cells[x, y] = value;
_observers.ForEach(observer => observer.OnNext(this));
}
}
public IEnumerable<Cell> Cells => _cells.Cast<Cell>();
public abstract IEnumerable<Cell> Neighbours(int x, int y);
public void Transform(Rule transform)
{
_cells = transform(this);
_observers.ForEach(observer => observer.OnNext(this));
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public IDisposable Subscribe(IObserver<IField> observer)
{
_observers.Add(observer);
return new DelegateUnsubscriber(() => _observers.Remove(observer));
}
}
}