A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5using NUnit.Framework;
6using osu.Framework.Graphics;
7using osu.Framework.Graphics.Containers;
8using osu.Framework.Graphics.Shapes;
9using osu.Framework.Graphics.Sprites;
10using osu.Framework.Graphics.Transforms;
11using osu.Framework.Testing;
12using osuTK;
13using osuTK.Graphics;
14
15namespace osu.Framework.Tests.Visual.Drawables
16{
17 public class TestSceneModelBackedDrawableWithUnloading : FrameworkTestScene
18 {
19 private TestUnloadingModelBackedDrawable backedDrawable;
20 private Drawable initialDrawable;
21
22 [SetUpSteps]
23 public void SetUpSteps()
24 {
25 AddStep("setup drawable", () =>
26 {
27 Child = backedDrawable = new TestUnloadingModelBackedDrawable(TimePerAction)
28 {
29 Anchor = Anchor.Centre,
30 Origin = Anchor.Centre,
31 Size = new Vector2(200f),
32 RelativePositionAxes = Axes.Both,
33 };
34 });
35
36 AddUntilStep("wait for load", () => backedDrawable.DisplayedDrawable != null);
37 AddStep("get displayed drawable", () => initialDrawable = backedDrawable.DisplayedDrawable);
38 }
39
40 [Test]
41 public void TestUnloading()
42 {
43 AddStep("mask away", () => backedDrawable.Position = new Vector2(-2));
44 AddUntilStep("drawable unloaded", () => initialDrawable.IsDisposed && backedDrawable.DisplayedDrawable == null);
45
46 AddStep("return back", () => backedDrawable.Position = Vector2.Zero);
47 AddUntilStep("new drawable displayed", () => backedDrawable.DisplayedDrawable != null && backedDrawable.DisplayedDrawable != initialDrawable);
48 }
49
50 [Test]
51 public void TestChangeWhileMaskedAway()
52 {
53 AddStep("mask away", () => backedDrawable.Position = new Vector2(-2));
54 AddUntilStep("wait for drawable unload", () => backedDrawable.DisplayedDrawable == null);
55
56 AddStep("change model", () => backedDrawable.Model = 1);
57 AddWaitStep("wait a bit", 5);
58 AddAssert("no drawable loaded", () => backedDrawable.DisplayedDrawable == null);
59
60 AddStep("return back", () => backedDrawable.Position = Vector2.Zero);
61 AddUntilStep("new drawable displayed", () => backedDrawable.DisplayedDrawable != null);
62 }
63
64 [Test]
65 public void TestTransformsAppliedOnReloading()
66 {
67 AddStep("mask away", () => backedDrawable.Position = new Vector2(-2));
68 AddUntilStep("wait for drawable unload", () => backedDrawable.DisplayedDrawable == null);
69
70 AddStep("reset transform counters", () => backedDrawable.ResetTransformCounters());
71 AddStep("return back", () => backedDrawable.Position = Vector2.Zero);
72 AddUntilStep("wait for new drawable", () => backedDrawable.DisplayedDrawable?.IsLoaded == true);
73
74 // on loading, ModelBackedDrawable applies immediate hide transform on new drawable then applies show transform.
75 AddAssert("initial hide transform applied", () => backedDrawable.HideTransforms == 1);
76 AddAssert("show transform applied", () => backedDrawable.ShowTransforms == 1);
77 AddUntilStep("new drawable alpha = 1", () => backedDrawable.DisplayedDrawable.Alpha == 1);
78 }
79
80 private class TestUnloadingModelBackedDrawable : ModelBackedDrawable<int>
81 {
82 public new Drawable DisplayedDrawable => base.DisplayedDrawable;
83
84 public new int Model
85 {
86 get => base.Model;
87 set => base.Model = value;
88 }
89
90 public int ShowTransforms { get; private set; }
91 public int HideTransforms { get; private set; }
92
93 protected override double LoadDelay { get; }
94 protected double UnloadDelay { get; }
95
96 public TestUnloadingModelBackedDrawable(double timePerAction)
97 {
98 LoadDelay = timePerAction;
99 UnloadDelay = timePerAction;
100 }
101
102 public void ResetTransformCounters() => ShowTransforms = HideTransforms = 0;
103
104 protected override DelayedLoadWrapper CreateDelayedLoadWrapper(Func<Drawable> createContentFunc, double timeBeforeLoad)
105 {
106 return new DelayedLoadUnloadWrapper(createContentFunc, timeBeforeLoad, UnloadDelay);
107 }
108
109 protected override TransformSequence<Drawable> ApplyShowTransforms(Drawable drawable)
110 {
111 ShowTransforms++;
112 return base.ApplyShowTransforms(drawable);
113 }
114
115 protected override TransformSequence<Drawable> ApplyHideTransforms(Drawable drawable)
116 {
117 HideTransforms++;
118 return base.ApplyHideTransforms(drawable);
119 }
120
121 protected override Drawable CreateDrawable(int model)
122 {
123 return new Container
124 {
125 RelativeSizeAxes = Axes.Both,
126 Children = new Drawable[]
127 {
128 new Box
129 {
130 RelativeSizeAxes = Axes.Both,
131 Colour = Color4.Gray,
132 },
133 new SpriteText
134 {
135 Anchor = Anchor.Centre,
136 Origin = Anchor.Centre,
137 Text = $"unload-wrapped model {model}",
138 }
139 }
140 };
141 }
142 }
143 }
144}