예제 #1
0
        public void GetCityBytes_WhenPlayersInRegionArentInOrder_ShouldSucceed(
            [Frozen] DefaultMultiObjectLock.Factory lockerFactory,
            IMultiObjectLock locker,
            IMiniMapRegionObject obj1,
            IMiniMapRegionObject obj2,
            MiniMapRegion miniMapRegion)
        {
            obj1.Hash.Returns(1);
            obj2.Hash.Returns(2);

            lockerFactory().Lock(Arg.Is <ILockable[]>(p => p.SequenceEqual(new[] { obj2, obj1 })))
            .Returns(locker);

            locker.When(p => p.SortLocks(Arg.Is <ILockable[]>(a => a.SequenceEqual(new[] { obj2, obj1 }))))
            .Do(args => Array.Sort((ILockable[])args[0], DefaultMultiObjectLock.CompareObject));

            locker.Do(Arg.Any <Func <bool> >()).Returns(callInfo =>
            {
                var action = callInfo.Arg <Func <bool> >();
                return(action());
            });

            miniMapRegion.Add(obj2);
            miniMapRegion.Add(obj1);

            miniMapRegion.GetCityBytes().Should().NotBeNull();
        }
예제 #2
0
        public IMultiObjectLock Lock(CallbackLockHandler lockHandler,
                                     object[] lockHandlerParams,
                                     params ILockable[] baseLocks)
        {
            int attempts = 0;

            while (currentLock == null)
            {
                if ((++attempts) % 10 == 0)
                {
                    logger.Warn(string.Format("CallbackLock has iterated {0} times {1}", attempts, Environment.StackTrace));
                }

                if (attempts > 300)
                {
                    throw new LockException("Callback lock exceeded maximum count");
                }

                var toBeLocked = new List <ILockable>(baseLocks);

                // Lock the base objects
                multiObjectLockFactory().Lock(baseLocks)
                .Do(() => toBeLocked.AddRange(lockHandler(lockHandlerParams)));

                // Lock all of the objects we believe should be locked
                currentLock = multiObjectLockFactory();
                currentLock.Lock(toBeLocked.ToArray());

                // Grab the current list of objects we need to lock from the callback
                var newToBeLocked = new List <ILockable>(baseLocks);
                newToBeLocked.AddRange(lockHandler(lockHandlerParams));

                // Make sure they are still all the same
                if (newToBeLocked.Count != toBeLocked.Count)
                {
                    currentLock.UnlockAll();
                    currentLock = null;
                    Thread.Sleep(GetWaitRetrySleep(attempts));
                    continue;
                }

                if (!newToBeLocked.Where((t, i) => t.Hash != toBeLocked[i].Hash).Any())
                {
                    continue;
                }

                currentLock.UnlockAll();
                currentLock = null;
                Thread.Sleep(GetWaitRetrySleep(attempts));
            }

            return(currentLock);
        }
예제 #3
0
        public void Lock_CityIdTroopId_WhenTroopIsNotFound_ShouldReturnEmptyLockAndNullCity(
            [Frozen] IGameObjectLocator locator,
            [FrozenMock] DefaultMultiObjectLock.Factory lockFactory,
            IMultiObjectLock cityLock,
            IMultiObjectLock emptyLock,
            ICity city,
            ITroopObject troop,
            DefaultLocker locker)
        {
            lockFactory().Returns(cityLock, emptyLock);

            ICity outCity;

            locator.TryGetObjects(1, out outCity).Returns(call =>
            {
                call[1] = city;
                return(true);
            });

            ITroopObject outTroop;

            city.TryGetTroop(2, out outTroop).Returns(false);

            ICity        lockedCity;
            ITroopObject lockedTroop;
            var          multiObjLock = locker.Lock(1, 2, out lockedCity, out lockedTroop);

            ((object)lockedCity).Should().BeNull();
            lockedTroop.Should().BeNull();
            multiObjLock.Should().Be(emptyLock);
            emptyLock.Received(1)
            .Lock(Arg.Is <ILockable[]>(itemsLocked => !itemsLocked.Any()));
            cityLock.Received(1)
            .Lock(Arg.Is <ILockable[]>(itemsLocked => itemsLocked.SequenceEqual(new[] { city })));
            cityLock.Received(1).UnlockAll();
        }