using System; using System.Collections.Generic; /// ///This class holds the model of our Shop. It contains an inventory, a price modifier, and an index to select the items. ///In its current setup, view and controller need to get data via polling. Advisable is, to apply observer pattern or ///set up an event system for better integration with View and Controller. /// public abstract class ShopModel : IModelObservable { public Inventory inventory { get; } // Getter of the inventory, the views might need this to set up the display. protected float priceModifier; //Modifies the item's price based on its base price protected int selectedItemIndex = 0; //selected item index private List> observers = new List>(); //------------------------------------------------------------------------------------------------------------------------ // ShopModel() //------------------------------------------------------------------------------------------------------------------------ public ShopModel(float pPriceModifier, int pItemCount, int pMoney) { inventory = new Inventory(pItemCount, pMoney); } //------------------------------------------------------------------------------------------------------------------------ // GetSelectedItem() //------------------------------------------------------------------------------------------------------------------------ //Returns the selected item public Item GetSelectedItem() { if (selectedItemIndex >= 0 && selectedItemIndex < inventory.GetItemCount()) { return inventory.GetItemByIndex(selectedItemIndex); } else { return null; } } //------------------------------------------------------------------------------------------------------------------------ // SelectItemByIndex() //------------------------------------------------------------------------------------------------------------------------ //Attempts to select the item, specified by 'index', fails silently public void SelectItemByIndex(int index) { if (index >= 0 && index < inventory.GetItemCount()) { selectedItemIndex = index; OnSelect(GetSelectedItem()); } else { throw new ArgumentOutOfRangeException(); } } //------------------------------------------------------------------------------------------------------------------------ // SelectItem(Item item) //------------------------------------------------------------------------------------------------------------------------ //Attempts to select the given item, fails silently public void SelectItem(Item item) { if (item != null) { int index = inventory.GetItems().IndexOf(item); if (index >= 0) { SelectItemByIndex(index); } } } //------------------------------------------------------------------------------------------------------------------------ // GetSelectedItemIndex() //------------------------------------------------------------------------------------------------------------------------ //returns the index of the current selected item public int GetSelectedItemIndex() { return selectedItemIndex; } //------------------------------------------------------------------------------------------------------------------------ // Confirm() //------------------------------------------------------------------------------------------------------------------------ //Concrete classes to implement public abstract void ConfirmSelectedItem(); // Observer pattern. Anything that wants to know what happens regarding item selection subscribes to this. // This could mean all items of this model and its views do it, or all views do it. public IDisposable RegisterObserver(IShopModelObserver observer) { // Check whether observer is already registered. If not, add it if (! observers.Contains(observer)) { observers.Add(observer); // Provide observer with existing data. observer.OnSelected(GetSelectedItem()); } return new Unsubscriber(observers, observer); } public void RemoveObserver(IShopModelObserver observer) { if (observers.Contains(observer)) observers.Remove(observer); } public void OnRemove(Item val) { // We copy the list so we don't break it while iterating, as it's likely OnRemove will cause an object to unsub var observerCopy = observers.ToArray(); foreach (var observer in observerCopy) observer.OnRemoved(val); } public void OnSelect(Item val) { foreach (var observer in observers) observer.OnSelected(val); } }