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> _observers = new List>(); 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 Cells => _cells.Cast(); public abstract IEnumerable 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 observer) { _observers.Add(observer); return new DelegateUnsubscriber(() => _observers.Remove(observer)); } } }