| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- #include <cstddef>
- #include <memory>
- #include <utility>
- #include <gtest/gtest.h>
- #include <entt/core/hashed_string.hpp>
- #include <entt/graph/flow.hpp>
- #include "../common/config.h"
- #include "../common/throwing_allocator.hpp"
- TEST(Flow, Constructors) {
- entt::flow flow{};
- ASSERT_EQ(flow.size(), 0u);
- flow = entt::flow{std::allocator<entt::id_type>{}};
- ASSERT_EQ(flow.size(), 0u);
- flow.bind(0);
- flow.bind(3);
- flow.bind(99);
- ASSERT_EQ(flow.size(), 3u);
- const entt::flow temp{flow, flow.get_allocator()};
- const entt::flow other{std::move(flow), flow.get_allocator()};
- ASSERT_EQ(flow.size(), 0u); // NOLINT
- ASSERT_EQ(other.size(), 3u);
- ASSERT_EQ(other[0u], 0u);
- ASSERT_EQ(other[1u], 3u);
- ASSERT_EQ(other[2u], 99u);
- }
- TEST(Flow, Copy) {
- entt::flow flow{};
- flow.bind(0);
- flow.bind(3);
- flow.bind(99);
- entt::flow other{flow};
- ASSERT_EQ(flow.size(), 3u);
- ASSERT_EQ(other.size(), 3u);
- ASSERT_EQ(other[0u], 0u);
- ASSERT_EQ(other[1u], 3u);
- ASSERT_EQ(other[2u], 99u);
- flow.bind(1);
- other.bind(2);
- other = flow;
- ASSERT_EQ(other.size(), 4u);
- ASSERT_EQ(flow.size(), 4u);
- ASSERT_EQ(other[0u], 0u);
- ASSERT_EQ(other[1u], 3u);
- ASSERT_EQ(other[2u], 99u);
- ASSERT_EQ(other[3u], 1u);
- }
- TEST(Flow, Move) {
- entt::flow flow{};
- flow.bind(0);
- flow.bind(3);
- flow.bind(99);
- entt::flow other{std::move(flow)};
- ASSERT_EQ(flow.size(), 0u); // NOLINT
- ASSERT_EQ(other.size(), 3u);
- ASSERT_EQ(other[0u], 0u);
- ASSERT_EQ(other[1u], 3u);
- ASSERT_EQ(other[2u], 99u);
- flow = {};
- flow.bind(1);
- other.bind(2);
- other = std::move(flow);
- ASSERT_EQ(other.size(), 1u);
- ASSERT_EQ(flow.size(), 0u); // NOLINT
- ASSERT_EQ(other[0u], 1u);
- }
- TEST(Flow, Swap) {
- entt::flow flow{};
- entt::flow other{};
- flow.bind(7);
- ASSERT_EQ(other.size(), 0u);
- ASSERT_EQ(flow.size(), 1u);
- ASSERT_EQ(flow[0u], 7u);
- flow.swap(other);
- ASSERT_EQ(other.size(), 1u);
- ASSERT_EQ(flow.size(), 0u);
- ASSERT_EQ(other[0u], 7u);
- }
- TEST(Flow, Clear) {
- entt::flow flow{};
- flow.bind(0);
- flow.bind(99);
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow[0u], 0u);
- ASSERT_EQ(flow[1u], 99u);
- flow.clear();
- ASSERT_EQ(flow.size(), 0u);
- }
- TEST(Flow, Set) {
- entt::flow flow{};
- flow.bind(0).set(10, true).bind(1).set(10, true).set(11, false);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
- ASSERT_TRUE(graph.contains(0u, 1u));
- ASSERT_FALSE(graph.contains(1u, 0u));
- }
- TEST(Flow, RO) {
- entt::flow flow{};
- flow.bind(0).ro(10).bind(1).ro(10).ro(11);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_EQ(graph.edges().cbegin(), graph.edges().cend());
- }
- TEST(Flow, RangeRO) {
- entt::flow flow{};
- const entt::id_type res[2u]{10, 11};
- flow.bind(0).ro(res, res + 1).bind(1).ro(res, res + 2);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_EQ(graph.edges().cbegin(), graph.edges().cend());
- }
- TEST(Flow, RW) {
- entt::flow flow{};
- flow.bind(0).rw(10).bind(1).rw(10).rw(11);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
- ASSERT_TRUE(graph.contains(0u, 1u));
- ASSERT_FALSE(graph.contains(1u, 0u));
- }
- TEST(Flow, RangeRW) {
- entt::flow flow{};
- const entt::id_type res[2u]{10, 11};
- flow.bind(0).rw(res, res + 1).bind(1).rw(res, res + 2);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
- ASSERT_TRUE(graph.contains(0u, 1u));
- ASSERT_FALSE(graph.contains(1u, 0u));
- }
- TEST(Flow, Graph) {
- using namespace entt::literals;
- entt::flow flow{};
- flow.bind("task_0"_hs)
- .ro("resource_0"_hs)
- .rw("resource_1"_hs);
- flow.bind("task_1"_hs)
- .ro("resource_0"_hs)
- .rw("resource_2"_hs);
- flow.bind("task_2"_hs)
- .ro("resource_1"_hs)
- .rw("resource_3"_hs);
- flow.bind("task_3"_hs)
- .rw("resource_1"_hs)
- .ro("resource_2"_hs);
- flow.bind("task_4"_hs)
- .rw("resource_0"_hs);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 5u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_EQ(flow[0u], "task_0"_hs);
- ASSERT_EQ(flow[1u], "task_1"_hs);
- ASSERT_EQ(flow[2u], "task_2"_hs);
- ASSERT_EQ(flow[3u], "task_3"_hs);
- ASSERT_EQ(flow[4u], "task_4"_hs);
- auto it = graph.edges().cbegin();
- const auto last = graph.edges().cend();
- ASSERT_NE(it, last);
- ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{2u}));
- ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{4u}));
- ASSERT_EQ(*it++, std::make_pair(std::size_t{1u}, std::size_t{3u}));
- ASSERT_EQ(*it++, std::make_pair(std::size_t{1u}, std::size_t{4u}));
- ASSERT_EQ(*it++, std::make_pair(std::size_t{2u}, std::size_t{3u}));
- ASSERT_EQ(it, last);
- }
- TEST(Flow, Sync) {
- using namespace entt::literals;
- entt::flow flow{};
- flow.bind("task_0"_hs)
- .ro("resource_0"_hs);
- flow.bind("task_1"_hs)
- .rw("resource_1"_hs);
- flow.bind("task_2"_hs)
- .sync();
- flow.bind("task_3"_hs)
- .ro("resource_0"_hs)
- .rw("resource_2"_hs);
- flow.bind("task_4"_hs)
- .ro("resource_2"_hs);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 5u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_EQ(flow[0u], "task_0"_hs);
- ASSERT_EQ(flow[1u], "task_1"_hs);
- ASSERT_EQ(flow[2u], "task_2"_hs);
- ASSERT_EQ(flow[3u], "task_3"_hs);
- ASSERT_EQ(flow[4u], "task_4"_hs);
- auto it = graph.edges().cbegin();
- const auto last = graph.edges().cend();
- ASSERT_NE(it, last);
- ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{2u}));
- ASSERT_EQ(*it++, std::make_pair(std::size_t{1u}, std::size_t{2u}));
- ASSERT_EQ(*it++, std::make_pair(std::size_t{2u}, std::size_t{3u}));
- ASSERT_EQ(*it++, std::make_pair(std::size_t{3u}, std::size_t{4u}));
- ASSERT_EQ(it, last);
- }
- ENTT_DEBUG_TEST(FlowDeathTest, NoBind) {
- entt::flow flow{};
- ASSERT_DEATH(flow.ro(42), "");
- ASSERT_DEATH(flow.rw(42), "");
- flow.bind(0);
- ASSERT_NO_THROW(flow.ro(1));
- ASSERT_NO_THROW(flow.rw(2));
- }
- TEST(Flow, DirectRebind) {
- entt::flow flow{};
- flow.bind(0).ro(10).rw(10).bind(1).ro(10);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
- ASSERT_TRUE(graph.contains(0u, 1u));
- ASSERT_FALSE(graph.contains(1u, 0u));
- }
- TEST(Flow, DeferredRebind) {
- entt::flow flow{};
- flow.bind(0).ro(10).bind(1).ro(10).bind(0).rw(10);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
- ASSERT_FALSE(graph.contains(0u, 1u));
- ASSERT_TRUE(graph.contains(1u, 0u));
- }
- TEST(Flow, Loop) {
- entt::flow flow{};
- flow.bind(0).rw(10).bind(1).ro(10).bind(0).rw(10);
- auto graph = flow.graph();
- ASSERT_EQ(flow.size(), 2u);
- ASSERT_EQ(flow.size(), graph.size());
- ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
- ASSERT_TRUE(graph.contains(0u, 1u));
- ASSERT_TRUE(graph.contains(1u, 0u));
- }
- TEST(Flow, ThrowingAllocator) {
- entt::basic_flow<test::throwing_allocator<entt::id_type>> flow{};
- flow.get_allocator().throw_counter<std::pair<std::size_t, entt::id_type>>(0u);
- ASSERT_EQ(flow.size(), 0u);
- ASSERT_THROW(flow.bind(1), test::throwing_allocator_exception);
- ASSERT_EQ(flow.size(), 0u);
- flow.bind(1);
- ASSERT_EQ(flow.size(), 1u);
- }
|