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
fbe ran afterIsLoaded = truebut beforeParent = xxdue 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