| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- #include <cstdint>
- #include <functional>
- #include <memory>
- #include <utility>
- #include <gtest/gtest.h>
- #include <entt/process/process.hpp>
- #include <entt/process/scheduler.hpp>
- class foo_process: public entt::process {
- void update(const delta_type, void *) override {
- on_update();
- }
- void aborted() override {
- on_aborted();
- }
- public:
- using allocator_type = entt::process::allocator_type;
- foo_process(const allocator_type &allocator, std::function<void()> upd, std::function<void()> abort)
- : entt::process{allocator},
- on_update{std::move(upd)},
- on_aborted{std::move(abort)} {}
- private:
- std::function<void()> on_update;
- std::function<void()> on_aborted;
- };
- class succeeded_process: public entt::process {
- void update(const delta_type, void *data) override {
- ++static_cast<std::pair<int, int> *>(data)->first;
- succeed();
- }
- public:
- using entt::process::process;
- };
- class failed_process: public entt::process {
- void update(const delta_type, void *data) override {
- ++static_cast<std::pair<int, int> *>(data)->second;
- fail();
- }
- public:
- using entt::process::process;
- };
- TEST(Scheduler, Functionalities) {
- entt::scheduler scheduler{};
- entt::scheduler other{std::move(scheduler)};
- scheduler = std::move(other);
- bool updated = false;
- bool aborted = false;
- ASSERT_EQ(scheduler.size(), 0u);
- ASSERT_TRUE(scheduler.empty());
- scheduler.attach<foo_process>([&updated]() { updated = true; }, [&aborted]() { aborted = true; });
- ASSERT_NE(scheduler.size(), 0u);
- ASSERT_FALSE(scheduler.empty());
- scheduler.update(0);
- scheduler.abort(true);
- ASSERT_TRUE(updated);
- ASSERT_TRUE(aborted);
- ASSERT_NE(scheduler.size(), 0u);
- ASSERT_FALSE(scheduler.empty());
- scheduler.clear();
- ASSERT_EQ(scheduler.size(), 0u);
- ASSERT_TRUE(scheduler.empty());
- }
- TEST(Scheduler, Swap) {
- entt::scheduler scheduler{};
- entt::scheduler other{};
- int counter{};
- scheduler.attach([&counter](entt::process &, std::uint32_t, void *) { ++counter; });
- ASSERT_EQ(scheduler.size(), 1u);
- ASSERT_EQ(other.size(), 0u);
- ASSERT_EQ(counter, 0);
- scheduler.update({});
- ASSERT_EQ(counter, 1);
- scheduler.swap(other);
- scheduler.update({});
- ASSERT_EQ(scheduler.size(), 0u);
- ASSERT_EQ(other.size(), 1u);
- ASSERT_EQ(counter, 1);
- other.update({});
- ASSERT_EQ(counter, 2);
- }
- TEST(Scheduler, SharedFromThis) {
- entt::scheduler scheduler{};
- auto &process = scheduler.attach<succeeded_process>();
- const auto &then = process.then<failed_process>();
- auto other = process.shared_from_this();
- ASSERT_TRUE(other);
- ASSERT_NE(&process, &then);
- ASSERT_EQ(&process, other.get());
- ASSERT_EQ(process.get_allocator(), scheduler.get_allocator());
- ASSERT_EQ(process.get_allocator(), other->get_allocator());
- ASSERT_EQ(then.get_allocator(), scheduler.get_allocator());
- }
- TEST(Scheduler, AttachThen) {
- entt::scheduler scheduler{};
- std::pair<int, int> counter{};
- // failing process with successor
- scheduler.attach<succeeded_process>()
- .then<succeeded_process>()
- .then<failed_process>()
- .then<succeeded_process>();
- // failing process without successor
- scheduler.attach<succeeded_process>()
- .then<succeeded_process>()
- .then<failed_process>();
- // non-failing process
- scheduler.attach<succeeded_process>()
- .then<succeeded_process>();
- while(!scheduler.empty()) {
- scheduler.update(0, &counter);
- }
- ASSERT_EQ(counter.first, 6u);
- ASSERT_EQ(counter.second, 2u);
- }
- TEST(Scheduler, Functor) {
- entt::scheduler scheduler{};
- bool first_functor = false;
- bool second_functor = false;
- scheduler
- .attach([&first_functor](entt::process &proc, std::uint32_t, void *) {
- ASSERT_FALSE(first_functor);
- first_functor = true;
- proc.succeed();
- })
- .then([&second_functor](entt::process &proc, std::uint32_t, void *) {
- ASSERT_FALSE(second_functor);
- second_functor = true;
- proc.fail();
- })
- .then([](entt::process &, std::uint32_t, void *) { FAIL(); });
- while(!scheduler.empty()) {
- scheduler.update(0);
- }
- ASSERT_TRUE(first_functor);
- ASSERT_TRUE(second_functor);
- ASSERT_TRUE(scheduler.empty());
- }
- TEST(Scheduler, SpawningProcess) {
- entt::scheduler scheduler{};
- std::pair<int, int> counter{};
- scheduler.attach([&scheduler](entt::process &proc, std::uint32_t, void *) {
- scheduler.attach<succeeded_process>().then<failed_process>();
- proc.succeed();
- });
- while(!scheduler.empty()) {
- scheduler.update(0, &counter);
- }
- ASSERT_EQ(counter.first, 1u);
- ASSERT_EQ(counter.second, 1u);
- }
- TEST(Scheduler, CustomAllocator) {
- const std::allocator<void> allocator{};
- entt::scheduler scheduler{allocator};
- ASSERT_EQ(scheduler.get_allocator(), allocator);
- ASSERT_FALSE(scheduler.get_allocator() != allocator);
- scheduler.attach([](entt::process &, std::uint32_t, void *) {});
- const decltype(scheduler) other{std::move(scheduler), allocator};
- ASSERT_EQ(other.size(), 1u);
- }
|