osu-framework
osu-framework copied to clipboard
NullReferenceException when accessing ScreenSpaceDrawQuad
not being able to access ScreenSpaceDrawQuad
when IsLoaded == true
seems like a bug to me.
Parent is null, I assume it gets initialized too late?
Relevant stacktrace:
System.NullReferenceException: Object reference not set to an instance of an object.
at osu.Framework.Graphics.Containers.CompositeDrawable.get_BoundingBox()
at osu.Framework.Graphics.Drawable.computeRequiredParentSizeToFit()
at osu.Framework.Graphics.Containers.CompositeDrawable.computeAutoSize()
at osu.Framework.Graphics.Containers.CompositeDrawable.updateAutoSize()
at osu.Framework.Graphics.Containers.CompositeDrawable.updateChildrenSizeDependencies()
at osu.Framework.Graphics.Containers.CompositeDrawable.get_Size()
at osu.Framework.Graphics.Drawable.get_DrawSize()
at osu.Framework.Graphics.Drawable.ComputeScreenSpaceDrawQuad()
at osu.Framework.Graphics.Drawable.get_ScreenSpaceDrawQuad()
How/where are you seeing this come up?
It's running inside Scheduler.AddDelayed(f, dt, repeat: true)
's handler f
The Drawable gets added to the list used inside f
at the end of it's [BackgroundDependencyLoader] load
Can f
be ran after IsLoaded = true
but before Parent = xx
due to threading perhaps?
I'm not entirely seeing how this is possible. Are you working on a personal project with osu!framework and hitting this? If so, can you post a trimmed down example that causes it to happen?
I haven't been able to reproduce with this simple test:
public partial class TestSceneTesting : FrameworkTestScene
{
[Test]
public void TestAddDrawable()
{
AddStep("add drawable", () => Add(new TestDrawable()));
}
private partial class TestDrawable : CompositeDrawable
{
[BackgroundDependencyLoader]
private void load()
{
Drawable autoSizedDrawable;
InternalChild = autoSizedDrawable = new Container
{
AutoSizeAxes = Axes.Both,
Child = new Container
{
AutoSizeAxes = Axes.Both,
Child = new Box { Size = new Vector2(100) }
}
};
Scheduler.Add(() => Trace.Assert(autoSizedDrawable.DrawSize.X == 100));
}
}
}
Can
f
be ran afterIsLoaded = true
but beforeParent = xx
due to threading perhaps?
I don't believe so. There's definitely some weirdness around when o!f considers a Drawable
to be IsLoaded = true
- a parent is always IsLoaded = true
and invokes LoadComplete()
before its children, however children receive a Parent
during that parent's load.
This would happen here: https://github.com/ppy/osu-framework/blob/9f689c541b7c58459a63caf6487e36c82b34fd2b/osu.Framework/Graphics/Containers/CompositeDrawable.cs#L247-L262