Files
Renderive/Kernel/tests/renderive/scene/Scene3D_Context_Test.cpp
T

102 lines
4.2 KiB
C++

#include <gtest/gtest.h>
#include <atomic>
#include <memory>
#include "renderive/renderable/Renderable.hpp"
#include "renderive/scene/Scene.hpp"
#include "Scene_Test_Helpers.hpp"
struct Scene3D_Context_Test_Renderable : Renderable_Base {
explicit Scene3D_Context_Test_Renderable() : Renderable_Base() {}
void prepare(const Prepare_Render_Context&) override {
scene_is_3d = dynamic_cast<Scene_3D_Base*>(&scene()) != nullptr;
++render_count;
}
std::atomic<int> render_count{};
bool scene_is_3d{};
};
TEST(scene3d_context_test, uses_scene_3d_base_contract) {
Scene3D_Context<> scene;
auto renderable = renderive_Owner<Scene3D_Context_Test_Renderable>::make();
attach_initial(scene, renderable);
scene.render();
scene.wait_for_render();
EXPECT_EQ(renderable->render_count.load(), 1);
EXPECT_TRUE(renderable->scene_is_3d);
}
struct Scene3D_Dependency_Cache_Test_Renderable : Renderable_Base {
explicit Scene3D_Dependency_Cache_Test_Renderable() : Renderable_Base({.cache_enabled = true}) {}
void prepare(const Prepare_Render_Context&) override {
++render_count;
}
int render_count{};
};
TEST(scene3d_context_test, propagates_cache_invalidation_through_unsorted_dependency_chain) {
Scene3D_Context<> scene;
auto leaf = renderive_Owner<Scene3D_Dependency_Cache_Test_Renderable>::make();
auto middle = renderive_Owner<Scene3D_Dependency_Cache_Test_Renderable>::make();
auto root = renderive_Owner<Scene3D_Dependency_Cache_Test_Renderable>::make();
with_attach_builder(scene, [&](auto& attach) {
attach.attach(leaf);
attach.attach(middle);
attach.attach(root);
attach.set_parent(Scene_Base::Relationship::dependency, leaf, middle);
attach.set_parent(Scene_Base::Relationship::dependency, middle, root);
});
scene.render();
scene.wait_for_render();
EXPECT_EQ(root->render_count, 1);
EXPECT_EQ(middle->render_count, 1);
EXPECT_EQ(leaf->render_count, 1);
root->invalidate_prepare();
scene.render();
scene.wait_for_render();
EXPECT_EQ(root->render_count, 2);
EXPECT_EQ(middle->render_count, 2);
EXPECT_EQ(leaf->render_count, 2);
}
TEST(scene3d_context_test, runtime_edit_explicitly_reparents_children_before_detach) {
Scene3D_Context<> scene;
auto grandparent = renderive_Owner<Scene3D_Dependency_Cache_Test_Renderable>::make();
auto parent = renderive_Owner<Scene3D_Dependency_Cache_Test_Renderable>::make();
auto child = renderive_Owner<Scene3D_Dependency_Cache_Test_Renderable>::make();
with_attach_builder(scene, [&](auto& attach) {
attach.attach(grandparent);
attach.attach(parent);
attach.attach(child);
attach.set_parent(Scene_Base::Relationship::display, parent, grandparent);
attach.set_parent(Scene_Base::Relationship::display, child, parent);
attach.set_parent(Scene_Base::Relationship::dependency, parent, grandparent);
attach.set_parent(Scene_Base::Relationship::dependency, child, parent);
});
scene.render();
scene.wait_for_render();
EXPECT_EQ(child->render_count, 1);
wait_renderable_edit(scene, [grandparent, parent, child](auto& editor) {
editor.set_parent(Scene_Base::Relationship::display, child, grandparent);
editor.set_parent(Scene_Base::Relationship::dependency, child, grandparent);
editor.clear_parents(Scene_Base::Relationship::display, parent);
editor.clear_parents(Scene_Base::Relationship::dependency, parent);
editor.detach(parent);
});
const auto topology = scene.topology_snapshot();
bool display_checked{};
bool dependency_checked{};
for (const auto& relation : topology.display) {
if (relation.child.get() == child.get()) {
EXPECT_EQ(relation.parent.get(), grandparent.get());
display_checked = true;
}
}
for (const auto& relation : topology.dependency) {
if (relation.child.get() == child.get()) {
EXPECT_EQ(relation.parent.get(), grandparent.get());
dependency_checked = true;
}
}
EXPECT_TRUE(display_checked);
EXPECT_TRUE(dependency_checked);
scene.render();
scene.wait_for_render();
EXPECT_EQ(parent->render_count, 1);
EXPECT_EQ(child->render_count, 2);
}