public void ToGetInLine(IReadOnlyBuyer buyer) { if (buyer == null) { throw new ArgumentNullException(nameof(buyer)); } if (_buyers.Any(b => b.Id == buyer.Id)) { throw new BuyerAlreadyInQueueException(); } var lockTaken = false; try { _spinLock.Enter(ref lockTaken); _buyers.Enqueue(buyer); if (Object.IsAvailable(out var count)) { Notify(count); } } finally { if (lockTaken) { _spinLock.Exit(false); } } }
private void MakePurchasesInternal(IReadOnlyBuyer buyer) { var remainingAmount = buyer.Basket.Products.Count; foreach (var product in buyer.Basket.Products) { PunchProduct(product); remainingAmount--; OnScanned(buyer, product, remainingAmount); } }
public ShelfTakedProductEventArgs(IReadOnlyBuyer buyer, IReadOnlyShelf shelf, Product product, int remainingAmount) { if (buyer == null) { throw new ArgumentNullException(nameof(buyer)); } if (shelf == null) { throw new ArgumentNullException(nameof(shelf)); } if (product == null) { throw new ArgumentNullException(nameof(product)); } Buyer = buyer; Shelf = shelf; Product = product; RemainingAmount = remainingAmount; }
public IReadOnlyCollection <Product> TakeAnyProducts(int count, IReadOnlyBuyer buyer) { if (buyer == null) { throw new ArgumentNullException(nameof(buyer)); } if (!IsAvailable()) { throw new ShelfIsBusyException(); } _semaphoreSlim.Wait(); var result = TakeProductInternal(count, buyer); _semaphoreSlim.Release(); Availabled?.Invoke(this, EventArgs.Empty); return(result); }
public CashboxScanEventArgs(IReadOnlyBuyer buyer, IReadOnlyCashbox cashbox, Product product, int remainingAmount) { if (buyer == null) { throw new ArgumentNullException(nameof(buyer)); } if (cashbox == null) { throw new ArgumentNullException(nameof(cashbox)); } if (product == null) { throw new ArgumentNullException(nameof(product)); } Buyer = buyer; Cashbox = cashbox; Product = product; RemainingAmount = remainingAmount; }
private List <Product> TakeProductInternal(int count, IReadOnlyBuyer buyer) { if (_products.IsEmpty) { throw new ShelfIsEmptyException(); } var result = new List <Product>(); for (int i = 0; i < count; i++) { if (!_products.TryTake(out var product)) { return(result); } Task.Delay(TimeSpan.FromSeconds(2)).Wait(); result.Add(product); OnProductTaked(buyer, product, count - (i + 1)); } return(result); }
public Receipt MakePurchases(IReadOnlyBuyer buyer) { if (buyer == null) { throw new ArgumentNullException(nameof(buyer)); } if (!IsAvailable()) { throw new CashboxIsBusyException(); } _semaphoreSlim.Wait(); MakePurchasesInternal(buyer); var result = new Receipt(Supermarket, buyer.Basket.Products); _semaphoreSlim.Release(); Availabled?.Invoke(this, EventArgs.Empty); return(result); }
private void OnScanned(IReadOnlyBuyer buyer, Product product, int remainingAmount) { Scanned?.Invoke(this, new CashboxScanEventArgs(buyer, this, product, remainingAmount)); }
private void OnProductTaked(IReadOnlyBuyer buyer, Product product, int remainingAmount) { ProductTaked?.Invoke(this, new ShelfTakedProductEventArgs(buyer, this, product, remainingAmount)); }