예제 #1
0
        public void TestMoveNotifiesBoundListSubscriptions()
        {
            bindableStringList.AddRange(new[] { "0", "1", "2" });
            var listA = new BindableList <string>();

            listA.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgsA1 = null;
            NotifyCollectionChangedEventArgs triggeredArgsA2 = null;

            listA.CollectionChanged += (_, args) => triggeredArgsA1 = args;
            listA.CollectionChanged += (_, args) => triggeredArgsA2 = args;

            var listB = new BindableList <string>();

            listB.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgsB1 = null;
            NotifyCollectionChangedEventArgs triggeredArgsB2 = null;

            listB.CollectionChanged += (_, args) => triggeredArgsB1 = args;
            listB.CollectionChanged += (_, args) => triggeredArgsB2 = args;

            bindableStringList.Move(0, 1);

            Assert.That(triggeredArgsA1, Is.Not.Null);
            Assert.That(triggeredArgsA2, Is.Not.Null);
            Assert.That(triggeredArgsB1, Is.Not.Null);
            Assert.That(triggeredArgsB2, Is.Not.Null);
        }
예제 #2
0
        public void TestRemoveNotifiesBoundListSubscriptions()
        {
            const string item = "item";

            bindableStringList.Add(item);
            var listA = new BindableList <string>();

            listA.BindTo(bindableStringList);
            bool wasRemovedA1 = false;
            bool wasRemovedA2 = false;

            listA.ItemsRemoved += s => wasRemovedA1 = true;
            listA.ItemsRemoved += s => wasRemovedA2 = true;
            var listB = new BindableList <string>();

            listB.BindTo(bindableStringList);
            bool wasRemovedB1 = false;
            bool wasRemovedB2 = false;

            listB.ItemsRemoved += s => wasRemovedB1 = true;
            listB.ItemsRemoved += s => wasRemovedB2 = true;

            bindableStringList.Remove(item);

            Assert.Multiple(() =>
            {
                Assert.IsTrue(wasRemovedA1);
                Assert.IsTrue(wasRemovedA2);
                Assert.IsTrue(wasRemovedB1);
                Assert.IsTrue(wasRemovedB2);
            });
        }
예제 #3
0
        public void TestRemoveNotifiesBoundListSubscriptions()
        {
            const string item = "item";

            bindableStringList.Add(item);
            var listA = new BindableList <string>();

            listA.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgsA1 = null;
            NotifyCollectionChangedEventArgs triggeredArgsA2 = null;

            listA.CollectionChanged += (_, args) => triggeredArgsA1 = args;
            listA.CollectionChanged += (_, args) => triggeredArgsA2 = args;

            var listB = new BindableList <string>();

            listB.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgsB1 = null;
            NotifyCollectionChangedEventArgs triggeredArgsB2 = null;

            listB.CollectionChanged += (_, args) => triggeredArgsB1 = args;
            listB.CollectionChanged += (_, args) => triggeredArgsB2 = args;

            bindableStringList.Remove(item);

            Assert.That(triggeredArgsA1, Is.Not.Null);
            Assert.That(triggeredArgsA2, Is.Not.Null);
            Assert.That(triggeredArgsB1, Is.Not.Null);
            Assert.That(triggeredArgsB2, Is.Not.Null);
        }
예제 #4
0
        private void load()
        {
            // For non-pooled rulesets, hitobjects are already present in the playfield which allows the blueprints to be loaded in the async context.
            if (Composer != null)
            {
                foreach (var obj in Composer.HitObjects)
                {
                    AddBlueprintFor(obj.HitObject);
                }
            }

            selectedHitObjects.BindTo(Beatmap.SelectedHitObjects);
            selectedHitObjects.CollectionChanged += (selectedObjects, args) =>
            {
                switch (args.Action)
                {
                case NotifyCollectionChangedAction.Add:
                    foreach (var o in args.NewItems)
                    {
                        SelectionBlueprints.FirstOrDefault(b => b.Item == o)?.Select();
                    }
                    break;

                case NotifyCollectionChangedAction.Remove:
                    foreach (var o in args.OldItems)
                    {
                        SelectionBlueprints.FirstOrDefault(b => b.Item == o)?.Deselect();
                    }

                    break;
                }
            };
        }
예제 #5
0
        protected sealed override void OnApply(HitObjectLifetimeEntry entry)
        {
            // LifetimeStart is already computed using HitObjectLifetimeEntry's InitialLifetimeOffset.
            // We override this with DHO's InitialLifetimeOffset for a non-pooled DHO.
            if (entry is SyntheticHitObjectEntry)
                LifetimeStart = HitObject.StartTime - InitialLifetimeOffset;

            ensureEntryHasResult();

            foreach (var h in HitObject.NestedHitObjects)
            {
                var pooledDrawableNested = pooledObjectProvider?.GetPooledDrawableRepresentation(h, this);
                var drawableNested = pooledDrawableNested
                                     ?? CreateNestedHitObject(h)
                                     ?? throw new InvalidOperationException($"{nameof(CreateNestedHitObject)} returned null for {h.GetType().ReadableName()}.");

                // Only invoke the event for non-pooled DHOs, otherwise the event will be fired by the playfield.
                if (pooledDrawableNested == null)
                    OnNestedDrawableCreated?.Invoke(drawableNested);

                drawableNested.OnNewResult += onNewResult;
                drawableNested.OnRevertResult += onRevertResult;
                drawableNested.ApplyCustomUpdateState += onApplyCustomUpdateState;

                // This is only necessary for non-pooled DHOs. For pooled DHOs, this is handled inside GetPooledDrawableRepresentation().
                // Must be done before the nested DHO is added to occur before the nested Apply()!
                drawableNested.ParentHitObject = this;

                nestedHitObjects.Add(drawableNested);
                AddNestedHitObject(drawableNested);
            }

            StartTimeBindable.BindTo(HitObject.StartTimeBindable);
            StartTimeBindable.BindValueChanged(onStartTimeChanged);

            if (HitObject is IHasComboInformation combo)
                comboIndexBindable.BindTo(combo.ComboIndexBindable);

            samplesBindable.BindTo(HitObject.SamplesBindable);
            samplesBindable.BindCollectionChanged(onSamplesChanged, true);

            HitObject.DefaultsApplied += onDefaultsApplied;

            OnApply();
            HitObjectApplied?.Invoke(this);

            // If not loaded, the state update happens in LoadComplete().
            if (IsLoaded)
            {
                if (Result.IsHit)
                    updateState(ArmedState.Hit, true);
                else if (Result.HasResult)
                    updateState(ArmedState.Miss, true);
                else
                    updateState(ArmedState.Idle, true);
            }
        }
예제 #6
0
        public void TestDisabledNotifiesBoundLists()
        {
            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            bindableStringList.Disabled = true;

            Assert.IsTrue(list.Disabled);
        }
예제 #7
0
        public void TestAddWithStringNotifiesBoundList(string str)
        {
            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            bindableStringList.Add(str);

            Assert.Contains(str, list);
        }
예제 #8
0
        public void TestMoveNotifiesBoundList()
        {
            bindableStringList.AddRange(new[] { "0", "1", "2" });
            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            bindableStringList.Move(0, 1);

            Assert.That(list, Is.EquivalentTo(new[] { "1", "0", "2" }));
        }
예제 #9
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            controlPoints.BindTo(HitObject.Path.ControlPoints);

            pathVersion.BindTo(HitObject.Path.Version);
            pathVersion.BindValueChanged(_ => editorBeatmap?.Update(HitObject));

            BodyPiece.UpdateFrom(HitObject);
        }
예제 #10
0
        public void TestRemoveNotifiesBoundList()
        {
            const string item = "item";

            bindableStringList.Add(item);
            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            bindableStringList.Remove(item);

            Assert.IsEmpty(list);
        }
예제 #11
0
        public void TestRemoveRangeDoesNotNotifyBoundListsWhenCountIsZero()
        {
            bindableStringList.Add("0");

            bool notified = false;
            var  list     = new BindableList <string>();

            list.BindTo(bindableStringList);
            list.ItemsRemoved += i => notified = true;

            bindableStringList.RemoveRange(0, 0);

            Assert.IsFalse(notified);
        }
예제 #12
0
        public DrawableRoomPlaylistItem(PlaylistItem item)
            : base(item)
        {
            Item = item;

            beatmap.BindTo(item.Beatmap);
            valid.BindTo(item.Valid);
            ruleset.BindTo(item.Ruleset);
            requiredMods.BindTo(item.RequiredMods);

            if (item.Expired)
            {
                Colour = OsuColour.Gray(0.5f);
            }
        }
예제 #13
0
        public void TestRemoveAllNotifiesBoundLists()
        {
            bindableStringList.Add("0");
            bindableStringList.Add("0");

            List <string> itemsRemoved = null;
            var           list         = new BindableList <string>();

            list.BindTo(bindableStringList);
            list.ItemsRemoved += i => itemsRemoved = i.ToList();

            bindableStringList.RemoveAll(m => m == "0");

            Assert.AreEqual(2, itemsRemoved.Count);
        }
예제 #14
0
        public void TestRemoveAtNotifiesBoundLists()
        {
            bindableStringList.Add("abc");

            bool wasRemoved = false;

            var list = new BindableList <string>();

            list.BindTo(bindableStringList);
            list.ItemsRemoved += s => wasRemoved = true;

            bindableStringList.RemoveAt(0);

            Assert.IsTrue(wasRemoved);
        }
예제 #15
0
        private void onSelectedRoomChanged(ValueChangedEvent <Room> room)
        {
            if (room.OldValue != null)
            {
                playlist.UnbindFrom(room.OldValue.Playlist);
            }

            if (room.NewValue != null)
            {
                playlist.BindTo(room.NewValue.Playlist);
            }
            else
            {
                playlist.Clear();
            }
        }
예제 #16
0
        public void TestInsertNotifiesBoundLists()
        {
            bindableStringList.Add("0");
            bindableStringList.Add("2");

            bool wasAdded = false;

            var list = new BindableList <string>();

            list.BindTo(bindableStringList);
            list.ItemsAdded += _ => wasAdded = true;

            bindableStringList.Insert(1, "1");

            Assert.IsTrue(wasAdded);
        }
예제 #17
0
        public void TestRemoveNotifiesBoundListSubscription()
        {
            const string item = "item";

            bindableStringList.Add(item);
            var list = new BindableList <string>();

            list.BindTo(bindableStringList);
            bool wasRemoved = false;

            list.ItemsRemoved += s => wasRemoved = true;

            bindableStringList.Remove(item);

            Assert.True(wasRemoved);
        }
예제 #18
0
        public void TestRemoveRangeDoesNotNotifyBoundListsWhenCountIsZero()
        {
            bindableStringList.Add("0");

            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgs = null;

            list.CollectionChanged += (_, args) => triggeredArgs = args;

            bindableStringList.RemoveRange(0, 0);

            Assert.That(triggeredArgs, Is.Null);
        }
예제 #19
0
        private void load()
        {
            SelectionHandler             = CreateSelectionHandler();
            SelectionHandler.DeselectAll = deselectAll;

            AddRangeInternal(new[]
            {
                DragBox = CreateDragBox(selectBlueprintsFromDragRectangle),
                SelectionHandler,
                SelectionBlueprints = CreateSelectionBlueprintContainer(),
                SelectionHandler.CreateProxy(),
                DragBox.CreateProxy().With(p => p.Depth = float.MinValue)
            });

            // For non-pooled rulesets, hitobjects are already present in the playfield which allows the blueprints to be loaded in the async context.
            if (Composer != null)
            {
                foreach (var obj in Composer.HitObjects)
                {
                    addBlueprintFor(obj.HitObject);
                }
            }

            selectedHitObjects.BindTo(Beatmap.SelectedHitObjects);
            selectedHitObjects.CollectionChanged += (selectedObjects, args) =>
            {
                switch (args.Action)
                {
                case NotifyCollectionChangedAction.Add:
                    foreach (var o in args.NewItems)
                    {
                        SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select();
                    }
                    break;

                case NotifyCollectionChangedAction.Remove:
                    foreach (var o in args.OldItems)
                    {
                        SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect();
                    }

                    break;
                }
            };
        }
예제 #20
0
        public void TestRemoveAtNotifiesBoundLists()
        {
            bindableStringList.Add("abc");

            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgs = null;

            list.CollectionChanged += (_, args) => triggeredArgs = args;

            bindableStringList.RemoveAt(0);

            Assert.That(triggeredArgs.Action, Is.EqualTo(NotifyCollectionChangedAction.Remove));
            Assert.That(triggeredArgs.OldItems, Has.One.Items.EqualTo("abc"));
            Assert.That(triggeredArgs.OldStartingIndex, Is.EqualTo(0));
        }
예제 #21
0
        public void TestRemoveAllNotifiesBoundLists()
        {
            bindableStringList.Add("0");
            bindableStringList.Add("0");

            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgs = null;

            list.CollectionChanged += (_, args) => triggeredArgs = args;

            bindableStringList.RemoveAll(m => m == "0");

            Assert.That(triggeredArgs.Action, Is.EqualTo(NotifyCollectionChangedAction.Remove));
            Assert.That(triggeredArgs.OldItems, Is.EquivalentTo(new[] { "0", "0" }));
        }
예제 #22
0
        public void TestInsertInsertsItemAtIndexInBoundList()
        {
            bindableStringList.Add("0");
            bindableStringList.Add("2");

            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            bindableStringList.Insert(1, "1");

            Assert.Multiple(() =>
            {
                Assert.AreEqual("0", list[0]);
                Assert.AreEqual("1", list[1]);
                Assert.AreEqual("2", list[2]);
            });
        }
예제 #23
0
        public void TestSetNotifiesBoundLists()
        {
            bindableStringList.Add("0");

            IEnumerable <string> addedItem   = null;
            IEnumerable <string> removedItem = null;

            var list = new BindableList <string>();

            list.BindTo(bindableStringList);
            list.ItemsAdded   += v => addedItem = v;
            list.ItemsRemoved += v => removedItem = v;

            bindableStringList[0] = "1";

            Assert.AreEqual(removedItem.Single(), "0");
            Assert.AreEqual(addedItem.Single(), "1");
        }
예제 #24
0
        public void TestClearNotifiesBoundBindable()
        {
            var bindableList = new BindableList <string>();

            bindableList.BindTo(bindableStringList);
            for (int i = 0; i < 5; i++)
            {
                bindableStringList.Add("testA");
            }
            for (int i = 0; i < 5; i++)
            {
                bindableList.Add("testA");
            }

            bindableStringList.Clear();

            Assert.IsEmpty(bindableList);
        }
예제 #25
0
        public void TestMoveNotifiesBoundListSubscription()
        {
            bindableStringList.AddRange(new[] { "0", "1", "2" });
            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgs = null;

            list.CollectionChanged += (_, args) => triggeredArgs = args;

            bindableStringList.Move(0, 1);

            Assert.That(triggeredArgs.Action, Is.EqualTo(NotifyCollectionChangedAction.Move));
            Assert.That(triggeredArgs.OldItems, Is.EquivalentTo("0".Yield()));
            Assert.That(triggeredArgs.NewItems, Is.EquivalentTo("0".Yield()));
            Assert.That(triggeredArgs.OldStartingIndex, Is.EqualTo(0));
            Assert.That(triggeredArgs.NewStartingIndex, Is.EqualTo(1));
        }
예제 #26
0
        public void TestAddRangeNotifiesBoundLists()
        {
            string[] items = { "test1", "test2", "test3" };
            var      list  = new BindableList <string>();

            bindableStringList.BindTo(list);
            IEnumerable <string> addedItems = null;

            list.ItemsAdded += e => addedItems = e;

            bindableStringList.AddRange(items);

            Assert.Multiple(() =>
            {
                Assert.NotNull(addedItems);
                CollectionAssert.AreEquivalent(items, addedItems);
                CollectionAssert.AreEquivalent(items, list);
            });
        }
예제 #27
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            // BindableList handles binding in a really bad way (Clear then AddRange) so we need to do this manually..
            foreach (int userId in playingUsers)
            {
                if (!multiplayerClient.CurrentMatchPlayingUserIds.Contains(userId))
                {
                    usersChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new[] { userId }));
                }
            }

            playingUsers.BindTo(multiplayerClient.CurrentMatchPlayingUserIds);
            playingUsers.BindCollectionChanged(usersChanged);

            // this leaderboard should be guaranteed to be completely loaded before the gameplay starts (is a prerequisite in MultiplayerPlayer).
            spectatorClient.OnNewFrames += handleIncomingFrames;
        }
예제 #28
0
        /// <summary>
        /// Applies a new <see cref="HitObject"/> to be represented by this <see cref="DrawableHitObject"/>.
        /// </summary>
        /// <param name="hitObject">The <see cref="HitObject"/> to apply.</param>
        public void Apply(HitObject hitObject)
        {
            free();

            HitObject = hitObject ?? throw new InvalidOperationException($"Cannot apply a null {nameof(HitObject)}.");

            // Ensure this DHO has a result.
            Result ??= CreateResult(HitObject.CreateJudgement())
            ?? throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}.");

            foreach (var h in HitObject.NestedHitObjects)
            {
                var drawableNested = CreateNestedHitObject(h) ?? throw new InvalidOperationException($"{nameof(CreateNestedHitObject)} returned null for {h.GetType().ReadableName()}.");

                drawableNested.OnNewResult            += onNewResult;
                drawableNested.OnRevertResult         += onRevertResult;
                drawableNested.ApplyCustomUpdateState += onApplyCustomUpdateState;

                nestedHitObjects.Value.Add(drawableNested);
                AddNestedHitObject(drawableNested);
            }

            startTimeBindable.BindTo(HitObject.StartTimeBindable);
            if (HitObject is IHasComboInformation combo)
            {
                comboIndexBindable.BindTo(combo.ComboIndexBindable);
            }

            samplesBindable.BindTo(HitObject.SamplesBindable);
            samplesBindable.BindCollectionChanged(onSamplesChanged, true);

            HitObject.DefaultsApplied += onDefaultsApplied;

            OnApply(hitObject);

            // If not loaded, the state update happens in LoadComplete(). Otherwise, the update is scheduled to allow for lifetime updates.
            if (IsLoaded)
            {
                Schedule(() => updateState(ArmedState.Idle, true));
            }

            hasHitObjectApplied = true;
        }
예제 #29
0
        public void TestRemoveNotifiesBoundListSubscription()
        {
            const string item = "item";

            bindableStringList.Add(item);
            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgs = null;

            list.CollectionChanged += (_, args) => triggeredArgs = args;

            bindableStringList.Remove(item);

            Assert.That(triggeredArgs.Action, Is.EqualTo(NotifyCollectionChangedAction.Remove));
            Assert.That(triggeredArgs.OldItems, Has.One.Items.EqualTo(item));
            Assert.That(triggeredArgs.OldStartingIndex, Is.EqualTo(0));
        }
예제 #30
0
        public void TestInsertNotifiesBoundLists()
        {
            bindableStringList.Add("0");
            bindableStringList.Add("2");

            var list = new BindableList <string>();

            list.BindTo(bindableStringList);

            NotifyCollectionChangedEventArgs triggeredArgs = null;

            list.CollectionChanged += (_, args) => triggeredArgs = args;

            bindableStringList.Insert(1, "1");

            Assert.That(triggeredArgs.Action, Is.EqualTo(NotifyCollectionChangedAction.Add));
            Assert.That(triggeredArgs.NewItems, Has.One.Items.EqualTo("1"));
            Assert.That(triggeredArgs.NewStartingIndex, Is.EqualTo(1));
        }