コード例 #1
0
 public void RegisterEventHandler(EventHandler <TEventArgs> handler)
 {
     lock (weakReferences)
     {
         weakReferences.Clear(true);
         weakReferences.Add(handler);
     }
 }
コード例 #2
0
        public void TestUnloadViaScroll()
        {
            WeakList <Container> references = new WeakList <Container>();

            AddStep("populate panels", () =>
            {
                references.Clear();

                for (int i = 0; i < 16; i++)
                {
                    flow.Add(new Container
                    {
                        Size     = new Vector2(128),
                        Children = new Drawable[]
                        {
                            new DelayedLoadUnloadWrapper(() =>
                            {
                                var container = new Container
                                {
                                    RelativeSizeAxes = Axes.Both,
                                    Children         = new Drawable[]
                                    {
                                        new TestBox {
                                            RelativeSizeAxes = Axes.Both
                                        }
                                    },
                                };

                                references.Add(container);

                                return(container);
                            }, 500, 2000),
                            new SpriteText {
                                Text = i.ToString()
                            },
                        }
                    });
                }

                flow.Add(
                    new Container
                {
                    Size = new Vector2(128, 1280),
                });
            });

            AddUntilStep("references loaded", () => references.Count() == 16 && references.All(c => c.IsLoaded));

            AddStep("scroll to end", () => scroll.ScrollToEnd());

            AddUntilStep("references lost", () =>
            {
                GC.Collect();
                return(!references.Any());
            });

            AddStep("scroll to start", () => scroll.ScrollToStart());

            AddUntilStep("references restored", () => references.Count() == 16);
        }
コード例 #3
0
        public void Test()
        {
            Random rand = new Random(3);

            List <string>     list1 = new List <string>();
            WeakList <string> list2 = new WeakList <string>();

            for (int x = 0; x < 1000; x++)
            {
                string str = x.ToString();
                list1.Add(str);
                list2.Add(str);

                if (!list1.SequenceEqual(list2))
                {
                    throw new Exception("Lists are not the same.");
                }
            }

            for (int x = 1000; x < 2000; x++)
            {
                string str        = x.ToString();
                string removeItem = list1[rand.Next(list1.Count)];
                list1.Remove(removeItem);
                list2.Remove(removeItem);

                if (!list1.SequenceEqual(list2))
                {
                    throw new Exception("Lists are not the same.");
                }

                list1.Add(str);
                list2.Add(str);

                if (!list1.SequenceEqual(list2))
                {
                    throw new Exception("Lists are not the same.");
                }
            }

            for (int x = 0; x < 100; x++)
            {
                list1.RemoveAt(rand.Next(list1.Count));
                GC.Collect();

                if (!list1.SequenceEqual(list2))
                {
                    throw new Exception("Lists are not the same.");
                }
            }


            list2.Clear();
            foreach (string data in list2)
            {
                throw new Exception();
            }
        }
コード例 #4
0
        public void TestRemovedStillUnload()
        {
            WeakList <Container> references = new WeakList <Container>();

            AddStep("populate panels", () =>
            {
                references.Clear();

                for (int i = 0; i < 16; i++)
                {
                    flow.Add(new Container
                    {
                        Size     = new Vector2(128),
                        Children = new Drawable[]
                        {
                            new DelayedLoadUnloadWrapper(() =>
                            {
                                var container = new Container
                                {
                                    RelativeSizeAxes = Axes.Both,
                                    Children         = new Drawable[]
                                    {
                                        new TestBox {
                                            RelativeSizeAxes = Axes.Both
                                        }
                                    },
                                };

                                references.Add(container);

                                return(container);
                            }, 500, 2000),
                            new SpriteText {
                                Text = i.ToString()
                            },
                        }
                    });
                }
            });

            AddUntilStep("references loaded", () => references.Count() == 16 && references.All(c => c.IsLoaded));

            AddAssert("check schedulers present", () => scroll.Scheduler.HasPendingTasks);

            AddStep("Remove all panels", () => flow.Clear(false));

            AddUntilStep("repeating schedulers removed", () => !scroll.Scheduler.HasPendingTasks);

            AddUntilStep("references lost", () =>
            {
                GC.Collect();
                return(!references.Any());
            });
        }
コード例 #5
0
        public void Test_GcCollect()
        {
            var weakList = new WeakList <object>();

            weakList.Add(new Object());


            GC.Collect();
            GC.WaitForPendingFinalizers();

            weakList.Clear(true);

            Assert.IsTrue(weakList.Count == 0, "Item must be collected by the GC collector");
        }
コード例 #6
0
        public void Test()
        {
            var rand = new Random(3);

            List<string> list1 = new List<string>();
            WeakList<string> list2 = new WeakList<string>();

            for (int x = 0; x < 1000; x++)
            {
                var str = x.ToString();
                list1.Add(str);
                list2.Add(str);

                if (!list1.SequenceEqual(list2))
                    throw new Exception("Lists are not the same.");
            }

            for (int x = 1000; x < 2000; x++)
            {
                var str = x.ToString();
                var removeItem = list1[rand.Next(list1.Count)];
                list1.Remove(removeItem);
                list2.Remove(removeItem);

                if (!list1.SequenceEqual(list2))
                    throw new Exception("Lists are not the same.");

                list1.Add(str);
                list2.Add(str);

                if (!list1.SequenceEqual(list2))
                    throw new Exception("Lists are not the same.");
            }

            for (int x = 0; x < 100; x++)
            {
                list1.RemoveAt(rand.Next(list1.Count));
                GC.Collect();

                if (!list1.SequenceEqual(list2))
                    throw new Exception("Lists are not the same.");
            }


            list2.Clear();
            foreach (var data in list2)
                throw new Exception();
        }
コード例 #7
0
        public void TestCountIsZeroAfterClear()
        {
            object obj     = new object();
            var    weakRef = new WeakReference <object>(obj);
            var    list    = new WeakList <object> {
                obj, weakRef
            };

            list.Clear();

            Assert.That(list.Count(), Is.Zero);
            Assert.That(list, Does.Not.Contain(obj));
            Assert.That(list.Contains(weakRef), Is.False);

            GC.KeepAlive(obj);
        }
コード例 #8
0
        public void Test_GcCannotCollect()
        {
            var weakList = new WeakList <object>();

            //holding strong reference
            var item = new Object();

            TestContext.Properties.Add("item", item);

            weakList.Add(item);

            GC.Collect();
            GC.WaitForPendingFinalizers();

            weakList.Clear(true);

            Assert.AreEqual(1, weakList.Count);

            TestContext.Properties.Remove("item");
        }
コード例 #9
0
        public void Test_GCCannotCollectWholeList()
        {
            var items = new Object[10000];

            for (int i = 0; i < 10000; i++)
            {
                items.SetValue(new Object(), i);
            }

            TestContext.Properties.Add("items", items);
            var weakList = new WeakList <object>(items);


            GC.Collect();
            GC.WaitForPendingFinalizers();

            weakList.Clear(true);

            Assert.AreEqual(10000, weakList.Count);

            TestContext.Properties.Remove("items");
        }
コード例 #10
0
        public static void LogAndFlush()
        {
            if (!DebugUtils.IsDebugBuild)
            {
                return;
            }

            lock (loading_components)
            {
                Logger.Log($"⏳ Currently loading components ({loading_components.Count()})");

                foreach (var c in loading_components.OrderBy(c => c.LoadThread?.Name).ThenBy(c => c.LoadState))
                {
                    Logger.Log(c.ToString());
                    Logger.Log($"- thread: {c.LoadThread?.Name ?? "none"}");
                    Logger.Log($"- state:  {c.LoadState}");
                }

                loading_components.Clear();

                Logger.Log("🧵 Task schedulers");

                Logger.Log(CompositeDrawable.SCHEDULER_STANDARD.GetStatusString());
                Logger.Log(CompositeDrawable.SCHEDULER_LONG_LOAD.GetStatusString());
            }

            ThreadPool.GetAvailableThreads(out int workerAvailable, out int completionAvailable);
            ThreadPool.GetMinThreads(out int workerMin, out int completionMin);
            ThreadPool.GetMaxThreads(out int workerMax, out int completionMax);

            Logger.Log("🎱 Thread pool");
            // TODO: use after net6
            // Logger.Log($"threads:         {ThreadPool.ThreadCount:#,0}");
            // Logger.Log($"work pending:    {ThreadPool.PendingWorkItemCount:#,0}");
            // Logger.Log($"work completed:  {ThreadPool.CompletedWorkItemCount:#,0}");
            Logger.Log($"worker:          min {workerMin,-6:#,0} max {workerMax,-6:#,0} available {workerAvailable,-6:#,0}");
            Logger.Log($"completion:      min {completionMin,-6:#,0} max {completionMax,-6:#,0} available {completionAvailable,-6:#,0}");
        }
コード例 #11
0
        public void TestTasksCanceledDuringLoadSequence()
        {
            var references = new WeakList <TestBox>();

            AddStep("populate panels", () =>
            {
                references.Clear();

                for (int i = 0; i < 16; i++)
                {
                    DelayedLoadUnloadWrapper loadUnloadWrapper;

                    flow.Add(new Container
                    {
                        Size  = new Vector2(128),
                        Child = loadUnloadWrapper = new DelayedLoadUnloadWrapper(() =>
                        {
                            var content = new TestBox {
                                RelativeSizeAxes = Axes.Both
                            };
                            references.Add(content);
                            return(content);
                        }, 0),
                    });

                    // cancel load tasks after the delayed load has started.
                    loadUnloadWrapper.DelayedLoadStarted += _ => game.Schedule(() => loadUnloadWrapper.UnbindAllBindables());
                }
            });

            AddStep("remove all panels", () => flow.Clear(false));

            AddUntilStep("references lost", () =>
            {
                GC.Collect();
                return(!references.Any());
            });
        }
コード例 #12
0
        public void TestAddAfterClear()
        {
            var objects = new List <object>
            {
                new object(),
                new object(),
                new object(),
            };

            object newObject = new object();

            var list = new WeakList <object>();

            foreach (object o in objects)
            {
                list.Add(o);
            }

            list.Clear();
            list.Add(newObject);

            Assert.That(list.Count(), Is.EqualTo(1));
            Assert.That(list, Does.Contain(newObject));
        }
コード例 #13
0
ファイル: Bindable.cs プロジェクト: ekrctb/osu-framework
 /// <summary>
 /// Remove all bound <see cref="Bindable{T}"/>s via <see cref="GetBoundCopy"/> or <see cref="BindTo"/>.
 /// </summary>
 public void UnbindBindings()
 {
     Bindings?.ForEachAlive(b => b.Unbind(this));
     Bindings?.Clear();
 }
コード例 #14
0
ファイル: Bindable.cs プロジェクト: markweadock/osu-framework
 /// <summary>
 /// Unbind any events bound to <see cref="ValueChanged"/> and <see cref="DisabledChanged"/>, along with
 /// removing all bound <see cref="Bindable{T}"/>s via <see cref="GetBoundCopy"/> or <see cref="BindTo"/>.
 /// </summary>
 public void UnbindAll()
 {
     ValueChanged    = null;
     DisabledChanged = null;
     bindings.Clear();
 }
コード例 #15
0
ファイル: Bindable.cs プロジェクト: thomastanck/osu-framework
 /// <summary>
 /// Remove all bound <see cref="Bindable{T}"/>s via <see cref="GetBoundCopy"/> or <see cref="BindTo"/>.
 /// </summary>
 public void UnbindBindings()
 {
     Bindings?.Clear();
 }
コード例 #16
0
        public void TestRemoveThenAdd()
        {
            WeakList <Container> references = new WeakList <Container>();

            int loadCount = 0;

            AddStep("populate panels", () =>
            {
                references.Clear();
                loadCount = 0;

                for (int i = 0; i < 16; i++)
                {
                    flow.Add(new Container
                    {
                        Size     = new Vector2(128),
                        Children = new Drawable[]
                        {
                            new DelayedLoadUnloadWrapper(() =>
                            {
                                TestBox testBox;
                                var container = new Container
                                {
                                    RelativeSizeAxes = Axes.Both,
                                    Children         = new Drawable[]
                                    {
                                        testBox = new TestBox {
                                            RelativeSizeAxes = Axes.Both
                                        }
                                    },
                                };

                                testBox.OnLoadComplete += _ =>
                                {
                                    references.Add(container);
                                    loadCount++;
                                };

                                return(container);
                            }, 500, 2000),
                            new SpriteText {
                                Text = i.ToString()
                            },
                        }
                    });
                }
            });

            IReadOnlyList <Container> previousChildren = null;

            AddUntilStep("all loaded", () => loadCount == 16);

            AddStep("Remove all panels", () =>
            {
                previousChildren = flow.Children.ToList();
                flow.Clear(false);
            });

            AddStep("Add panels back", () => flow.Children = previousChildren);

            AddWaitStep("wait for potential unload", 20);

            AddAssert("load count hasn't changed", () => loadCount == 16);
        }