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);
                }
            }
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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;
        }
Example #4
0
        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);
        }
Example #5
0
        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;
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
 private void OnScanned(IReadOnlyBuyer buyer, Product product, int remainingAmount)
 {
     Scanned?.Invoke(this, new CashboxScanEventArgs(buyer, this, product, remainingAmount));
 }
Example #9
0
 private void OnProductTaked(IReadOnlyBuyer buyer, Product product, int remainingAmount)
 {
     ProductTaked?.Invoke(this, new ShelfTakedProductEventArgs(buyer, this, product, remainingAmount));
 }