fixed spelling in us

added async to us
This commit is contained in:
Green Sky 2021-04-24 02:03:11 +02:00
parent 5d785b54d6
commit 337df23d12
9 changed files with 64 additions and 19 deletions

View File

@ -1,6 +1,7 @@
#include "./default_strategy.hpp" #include "./default_strategy.hpp"
#include <cassert> #include <cassert>
#include <functional>
namespace MM::UpdateStrategies { namespace MM::UpdateStrategies {
@ -206,17 +207,27 @@ void SingleThreadedDefault::doUpdate(MM::Engine& engine) {
// post // post
runType(engine, update_phase_t::POST); runType(engine, update_phase_t::POST);
if (!_defered_queue.empty()) { // simulate async
for (auto&& fn : _defered_queue) { for (size_t i = 0; !_async_queue.empty() && i < _max_async_per_tick; i++) {
_async_queue.back()(engine);
_async_queue.pop_back();
}
if (!_deferred_queue.empty()) {
for (auto&& fn : _deferred_queue) {
fn(engine); fn(engine);
} }
_defered_queue.clear(); _deferred_queue.clear();
} }
} }
void SingleThreadedDefault::addDefered(std::function<void(Engine&)> function) { void SingleThreadedDefault::addDeferred(std::function<void(Engine&)> function) {
_defered_queue.emplace_back(std::move(function)); _deferred_queue.emplace_back(std::move(function));
}
void SingleThreadedDefault::addAsync(std::function<void(Engine&)> function) {
_async_queue.emplace_back(std::move(function));
} }
#undef __L_ASSERT #undef __L_ASSERT

View File

@ -44,7 +44,9 @@ class SingleThreadedDefault : public MM::UpdateStrategies::UpdateStrategy {
std::set<update_key_t> _main_active; std::set<update_key_t> _main_active;
std::set<update_key_t> _post_active; std::set<update_key_t> _post_active;
std::vector<std::function<void(Engine&)>> _defered_queue; std::vector<std::function<void(Engine&)>> _deferred_queue;
std::vector<std::function<void(Engine&)>> _async_queue;
const size_t _max_async_per_tick = 5; // prevent blocking, this should be finetuned
private: private:
Graph& getGraph(update_phase_t phase); Graph& getGraph(update_phase_t phase);
@ -72,7 +74,9 @@ class SingleThreadedDefault : public MM::UpdateStrategies::UpdateStrategy {
bool depend(const update_key_t A, const update_key_t B) override; bool depend(const update_key_t A, const update_key_t B) override;
void addDefered(std::function<void(Engine&)> function) override; void addDeferred(std::function<void(Engine&)> function) override;
void addAsync(std::function<void(Engine&)> function) override;
}; };
} // MM::UpdateStrategies } // MM::UpdateStrategies

View File

@ -69,10 +69,13 @@ class UpdateStrategy {
// WIP: // WIP:
// dont use, if you are not using it to modify the engine. // dont use, if you are not using it to modify the engine.
// you usualy dont need to use this, if you think you need to use this, you probably dont. // you usually dont need to use this, if you think you need to use this, you probably dont.
//virtual void addFixedDefered(std::function<void(Engine&)> function) = 0; virtual void addDeferred(std::function<void(Engine&)> function) = 0; // called after everything
virtual void addDefered(std::function<void(Engine&)> function) = 0; // called after everything
// adds a task, which does not need to be completed on the end of the tick.
// warning: in a single-threaded environment, they will still be done on the main thread, so blocking is not a option
// note: the US might decide to limit the amount of executed asyncs per tick (eg. when single-threaded)
virtual void addAsync(std::function<void(Engine&)> function) = 0;
//virtual std::future addAsync(std::function<void(Engine&)> function) = 0; //virtual std::future addAsync(std::function<void(Engine&)> function) = 0;
}; };

View File

@ -29,6 +29,33 @@ TEST(default_update_strategy, simple_update) {
engine.update(); engine.update();
} }
// note: we test pure single-threaded behaviour, so nothing needs to be thread save
TEST(default_update_strategy, async) {
int counter = 1;
MM::Engine engine(std::make_unique<MM::UpdateStrategies::SingleThreadedDefault>());
ASSERT_EQ(counter, 1);
engine.getUpdateStrategy().addAsync([&counter](MM::Engine&) { counter++; });
engine.update();
ASSERT_EQ(counter, 2);
for (size_t i = 0; i < 100; i++) {
engine.getUpdateStrategy().addAsync([&counter](MM::Engine&) { counter++; });
}
// make sure we dont have an infinity loop in case something is wrong
size_t max_loop_safety_count = 0;
do {
engine.update();
max_loop_safety_count++;
} while (counter != 102 && max_loop_safety_count < 10000);
ASSERT_EQ(counter, 102);
}
TEST(default_update_strategy, service) { TEST(default_update_strategy, service) {
class TmpMockService : public MockService { class TmpMockService : public MockService {
public: public:
@ -56,7 +83,6 @@ TEST(default_update_strategy, service) {
} }
} }
TEST(default_update_strategy, run_1) { TEST(default_update_strategy, run_1) {
class TmpMockService : public MockService { class TmpMockService : public MockService {
int& _counter; int& _counter;
@ -96,7 +122,7 @@ TEST(default_update_strategy, run_1) {
ASSERT_TRUE(engine.enableService<TmpMockService>()); ASSERT_TRUE(engine.enableService<TmpMockService>());
ASSERT_EQ(counter, 1); ASSERT_EQ(counter, 1);
engine.getUpdateStrategy().addDefered([](MM::Engine& e) { e.stop(); }); engine.getUpdateStrategy().addDeferred([](MM::Engine& e) { e.stop(); });
engine.run(); engine.run();

View File

@ -1,4 +1,3 @@
#include "mm/services/service.hpp"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gmock/gmock.h> #include <gmock/gmock.h>
@ -36,7 +35,8 @@ class MockUpdateStrategy : public MM::UpdateStrategies::UpdateStrategy {
MOCK_METHOD(bool, depend, (const MM::UpdateStrategies::update_key_t A, const MM::UpdateStrategies::update_key_t B), (override)); MOCK_METHOD(bool, depend, (const MM::UpdateStrategies::update_key_t A, const MM::UpdateStrategies::update_key_t B), (override));
MOCK_METHOD(void, addDefered, (std::function<void(MM::Engine&)> function), (override)); MOCK_METHOD(void, addDeferred, (std::function<void(MM::Engine&)> function), (override));
MOCK_METHOD(void, addAsync, (std::function<void(MM::Engine&)> function), (override));
}; };
class MockService : public MM::Services::Service { class MockService : public MM::Services::Service {

View File

@ -39,7 +39,7 @@ std::vector<UpdateStrategies::UpdateCreationInfo> ScreenDirector::registerUpdate
void ScreenDirector::update(MM::Engine& engine) { void ScreenDirector::update(MM::Engine& engine) {
if (curr_screen_id != queued_screen_id) { if (curr_screen_id != queued_screen_id) {
engine.getUpdateStrategy().addDefered([this](MM::Engine& e) { engine.getUpdateStrategy().addDeferred([this](MM::Engine& e) {
changeScreenTo(e, queued_screen_id); changeScreenTo(e, queued_screen_id);
}); });
} }

View File

@ -104,7 +104,7 @@ TEST(sdl_service, event_handle_reg) {
}; };
// register forge // register forge
engine.getUpdateStrategy().addDefered(event_forge_f); engine.getUpdateStrategy().addDeferred(event_forge_f);
// register sdl event handler to just stop the engine // register sdl event handler to just stop the engine
auto* stop_event_hook_h = sdl_ss_ptr->addEventHandler([&engine](const SDL_Event&){ engine.stop(); return true; }); auto* stop_event_hook_h = sdl_ss_ptr->addEventHandler([&engine](const SDL_Event&){ engine.stop(); return true; });

View File

@ -61,7 +61,7 @@ TEST(simple_scene, change_scene) {
ASSERT_TRUE(sss->getScene().valid(e)); ASSERT_TRUE(sss->getScene().valid(e));
//engine.fixedUpdate(); //engine.fixedUpdate();
engine.getUpdateStrategy().addDefered([](MM::Engine& eng) {eng.stop();}); engine.getUpdateStrategy().addDeferred([](MM::Engine& eng) {eng.stop();});
engine.run(); engine.run();
ASSERT_FALSE(sss->getScene().valid(e)); ASSERT_FALSE(sss->getScene().valid(e));

View File

@ -37,8 +37,9 @@ TEST(player_velocity, basic_run) {
//v.velocity = { 1.f, 1.f }; //v.velocity = { 1.f, 1.f };
//v.rotation = 0.f; //v.rotation = 0.f;
engine.getUpdateStrategy().addDefered([](auto& e) { e.stop(); }); //engine.getUpdateStrategy().addDeferred([](auto& e) { e.stop(); });
engine.run(); //engine.run();
engine.update();
//ASSERT_EQ(t.position.x, 1.f * delta); //ASSERT_EQ(t.position.x, 1.f * delta);
// TODO: TEST // TODO: TEST