91 lines
3.7 KiB
C++
91 lines
3.7 KiB
C++
#include <gtest/gtest.h>
|
|
#include <atomic>
|
|
#include <memory>
|
|
#include "renderive/renderable/Renderable.hpp"
|
|
#include "renderive/scene/Scene.hpp"
|
|
struct Scene3D_Context_Test_Renderable : Renderable_Base {
|
|
explicit Scene3D_Context_Test_Renderable(Scene_Base& scene) : Renderable_Base(scene) {}
|
|
void render(const Scene_Render_Context& context) override {
|
|
scene_is_3d = dynamic_cast<Scene_3D_Base*>(context.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 = std::make_shared<Scene3D_Context_Test_Renderable>(scene);
|
|
scene.attach_renderable(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(Scene_Base& scene) : Renderable_Base(scene, {.cache_enabled = true}) {}
|
|
void render(const Scene_Render_Context&) override {
|
|
++render_count;
|
|
}
|
|
int render_count{};
|
|
};
|
|
TEST(scene3d_context_test, propagates_cache_invalidation_through_unsorted_dependency_chain) {
|
|
Scene3D_Context<> scene;
|
|
auto leaf = std::make_shared<Scene3D_Dependency_Cache_Test_Renderable>(scene);
|
|
auto middle = std::make_shared<Scene3D_Dependency_Cache_Test_Renderable>(scene);
|
|
auto root = std::make_shared<Scene3D_Dependency_Cache_Test_Renderable>(scene);
|
|
scene.attach_renderable(leaf);
|
|
scene.attach_renderable(middle);
|
|
scene.attach_renderable(root);
|
|
scene.set_dependency_parent(*leaf, middle.get());
|
|
scene.set_dependency_parent(*middle, root.get());
|
|
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_cache();
|
|
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, detach_parent_promotes_children_and_invalidates_dependency_cache) {
|
|
Scene3D_Context<> scene;
|
|
auto grandparent = std::make_shared<Scene3D_Dependency_Cache_Test_Renderable>(scene);
|
|
auto parent = std::make_shared<Scene3D_Dependency_Cache_Test_Renderable>(scene);
|
|
auto child = std::make_shared<Scene3D_Dependency_Cache_Test_Renderable>(scene);
|
|
scene.attach_renderable(grandparent);
|
|
scene.attach_renderable(parent);
|
|
scene.attach_renderable(child);
|
|
scene.set_display_parent(*parent, grandparent.get());
|
|
scene.set_display_parent(*child, parent.get());
|
|
scene.set_dependency_parent(*parent, grandparent.get());
|
|
scene.set_dependency_parent(*child, parent.get());
|
|
scene.render();
|
|
scene.wait_for_render();
|
|
EXPECT_EQ(child->render_count, 1);
|
|
scene.detach_renderable(*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);
|
|
}
|