public event Action FinishWork; //работа магазина окончена public PetShop() { PurchaseQueue = new Queue <Purchase>(); PurchaseCreation = new PurchaseQueueCreation(PurchaseQueue); DepartmentChain = CreateDepartments(); Cart = new ShoppingCart(DepartmentChain, PurchaseQueue); //подключаем обработчики событий добавления покупки в корзину (откуда она пойдет в отделы), //откладывания покупки (если отдел занят) и окончания работы магазина Cart.PurchaseInProcess += purchase => PurchaseToDep?.Invoke(purchase); Cart.PostponePurchase += purchase => PostponePurchase?.Invoke(purchase); Cart.FinishWork += () => FinishWork?.Invoke(); //подключаем обработчики событий добавления/откладывания (если доставщик занят)/изменений на складе/доставки покупки для отделов PurchaseCreation.AddPurchase += purchase => NewPurchase?.Invoke(purchase); DepartmentChain.AddStockChanges(department => StockChanges?.Invoke(department)); DepartmentChain.AddContractionAction((purchase, contractor) => ContractionFinished?.Invoke(purchase, contractor)); DepartmentChain.AddDeliveryAtion((purchase, deliverer) => DeliveryFinished?.Invoke(purchase, deliverer)); }
//обработка заявки на покупку public bool HandlePurchase(Purchase purchase, SynchronizationContext context) { //если в этом отделе ее обработать нельзя, она идет в следующий if (!CanHandle(purchase)) { return(Next != null && Next.HandlePurchase(purchase, context)); } //иначе пытаемся отправить ее на обработку if (Animals.Amount <= purchase.animalAmount || Houses.Amount <= purchase.houseAmount) { if (!contractor.Contract(purchase, context)) { return(false); } else { if (Animals.Amount <= purchase.animalAmount) { Animals.SetMax(); } if (Houses.Amount <= purchase.houseAmount) { Houses.SetMax(); } StockChanges?.Invoke(this); } } //возвращаем результат - была ли доставлена покупка, если нет, заказ вернется обратно в очередь if (deliverer.Deliver(purchase, context)) { //если доставлена, то убираем проданный товар Animals.Amount -= purchase.animalAmount; Houses.Amount -= purchase.houseAmount; StockChanges?.Invoke(this); return(true); } else { return(false); } }