#include #include #include #include #include #include "renderive/state/State_Strategy.hpp" struct Triple_State_Test_Base {}; struct Triple_State_Test_State { int value{}; }; TEST(triple_state_strategy_test, publishes_then_acquires_render_state) { Triple_State_Strategy strategy; strategy.set<&Triple_State_Test_State::value>(7); strategy.publish(); EXPECT_EQ(strategy.render_use_state().value, 0); EXPECT_EQ(strategy.acquire_render_state(), 1); EXPECT_EQ(strategy.render_use_state().value, 7); } TEST(triple_state_strategy_test, returns_render_state_snapshot) { Triple_State_Strategy strategy; const auto snapshot = strategy.render_use_state(); strategy.set<&Triple_State_Test_State::value>(7); strategy.publish(); strategy.acquire_render_state(); EXPECT_EQ(snapshot.value, 0); EXPECT_EQ(strategy.render_use_state().value, 7); } struct Multi_State_A_Base {}; struct Multi_State_B_Base {}; struct Multi_State_A { int value{}; }; struct Multi_State_B { int value{}; }; struct Multi_State_A_Strategy : Double_State_Strategy {}; struct Multi_State_B_Strategy : Double_State_Strategy {}; struct Multi_State_Product : Multi_State_A_Strategy, Multi_State_B_Strategy {}; TEST(double_state_strategy_test, supports_named_base_access_in_multiple_inheritance) { Multi_State_Product product; product.Multi_State_A_Strategy::set<&Multi_State_A::value>(3); product.Multi_State_B_Strategy::set<&Multi_State_B::value>(8); product.Multi_State_A_Strategy::publish(); product.Multi_State_B_Strategy::publish(); EXPECT_EQ(product.Multi_State_A_Strategy::render_use_state().value, 3); EXPECT_EQ(product.Multi_State_B_Strategy::render_use_state().value, 8); } TEST(triple_state_strategy_test, concurrently_acquires_render_revision_without_data_race) { Triple_State_Strategy strategy; std::atomic finished{}; auto acquire = [&] { while (!finished.load(std::memory_order_acquire)) { strategy.acquire_render_state(); } strategy.acquire_render_state(); }; std::thread first(acquire); std::thread second(acquire); for (int value = 1; value <= 1000; ++value) { strategy.set<&Triple_State_Test_State::value>(value); strategy.publish(); } finished.store(true, std::memory_order_release); first.join(); second.join(); EXPECT_EQ(strategy.acquire_render_state(), 1000); EXPECT_EQ(strategy.render_use_state().value, 1000); }