public void TestChangingSceneGraphForEntity() { var entity = new MockEntity(0); entity.Initialize(); var root1 = new SceneGraphRoot(); var root2 = new SceneGraphRoot(); root1.AddAsync(entity); entity.Parent.Should().Be(root1); new Action(() => root1.AddAsync(entity)).Should().Throw <NotSupportedException>(); root1.RemoveAsync(entity); entity.Parent.Should().Be(root1, "because RemoveScheduled will only be called in the next update"); root1.Update(new GameTime()); entity.Parent.Should().BeNull("because update now removed the entity from the scene"); root2.AddAsync(entity); entity.Parent.Should().Be(root2); root1.IsRegistered(entity).Should().BeFalse("because it will only be registered in the update call"); new Action(() => entity.ChangeParent(root1)).Should().Throw <NotSupportedException>(); // call update so entity is actually registered with the root2 root2.Update(new GameTime()); // only now is the alternative method possible entity.ChangeParent(root1); entity.Parent.Should().Be(root1); }
public void ChildParentRelationBetweenEntityAndGraphShouldExist() { var root = new SceneGraphRoot(); root.Parent.Should().BeNull(); var node = new MockEntity(0); node.Parent.Should().BeNull(); node.Initialize(); node.Initialized.Should().BeTrue(); root.AddAsync(node); node.Parent.Should().Be(root, "because add scheduled added the node right away as it was already initialized"); const int sleep = 1000; var lazyNode = new MockEntity(sleep); lazyNode.Initialized.Should().BeFalse(); var before = DateTime.Now; root.AddAsync(lazyNode); lazyNode.Initialized.Should().BeFalse(); lazyNode.Parent.Should().Be(root); // wait longer than init would take while (DateTime.Now < before + TimeSpan.FromMilliseconds(sleep + 1000)) { Thread.Sleep(10); } // assert that it was infact executed lazyNode.Initialized.Should().BeTrue(); }
public void TestSceneGraphNesting() { var root1 = new SceneGraphRoot(); var root2 = new SceneGraphRoot(); root1.Initialize(); root2.Initialize(); root1.AddAsync(root2); root2.Parent.Should().Be(root1); }
/// <summary> /// When called will add a temporary loading scene to the <see cref="SceneGraphRoot"/>. /// The progress scene will automatically update remove itself when the Initialize function of the scene is finished. /// </summary> /// <param name="root"></param> /// <param name="scene">The actual scene that has heavy loading in its Initialize function.</param> /// <param name="renderContext"></param> public static void AddAsyncWithLoadingScreen <TScene>(this SceneGraphRoot root, TScene scene, IRenderContext renderContext) where TScene : SceneGraphEntity, ISceneGraphEntityInitializeProgressReporter { var progressScene = new LoadingProgressScene(renderContext); EventHandler <int> func = null; func = (s, p) => { progressScene.SetProgress(p); // remove once completed if (p == 100) { scene.InitializeProgress -= func; } }; scene.InitializeProgress += func; // add the progress reporter which is listening in root.AddAsync(progressScene); root.AddAsync(scene); }