morph
0.1.0
Asynchronous bridge between GUI thread and business models
Toggle main menu visibility
Loading...
Searching...
No Matches
loop_executor.hpp
Go to the documentation of this file.
1
// SPDX-License-Identifier: Apache-2.0
2
3
#pragma once
4
#include <core/net/EventLoop.hpp>
5
#include <functional>
6
#include <memory>
7
8
#include "../attributes.hpp"
9
#include "../core/executor.hpp"
10
11
/// @file
12
/// @brief `morph::tui::LoopExecutor`: a morph executor whose tasks run in turns of a core-cpp event loop.
13
///
14
/// Specified in `docs/spec/tui/frontend.md`, "The loop executor".
15
16
namespace
morph::tui {
17
18
/// @brief Runs every posted task in a later turn of one `core::net::EventLoop`, with this executor current.
19
///
20
/// The TUI frontend's reactive `Runtime` is owned by one, and every `BridgeHandler` an application builds receives
21
/// it as its callback executor, so model replies, timers, sockets and input all run on the thread that turns the
22
/// loop. `post()` may be called from any thread. A task still queued when the executor is destroyed is dropped,
23
/// and a task that throws is logged and does not stop the loop.
24
///
25
/// Destroy it on the thread that turns the loop, between turns or from inside one of its own tasks, never from
26
/// another thread: a task already running there would go on using an owner (the reactive `Runtime`) that is gone.
27
/// Nothing guards against that, because a lock held across a task would deadlock a task that destroys its own
28
/// executor.
29
class
LoopExecutor
final :
public
exec::IExecutor
{
30
public
:
31
/// @param loop The loop to post to. Borrowed: it must outlive this executor.
32
explicit
LoopExecutor
(::core::net::EventLoop& loop MORPH_LIFETIMEBOUND);
33
34
/// @brief Destroys the executor; tasks it posted that have not run yet are dropped when the loop reaches them.
35
~LoopExecutor
()
override
;
36
37
LoopExecutor
(
LoopExecutor
const
&) =
delete
;
38
LoopExecutor
& operator=(
LoopExecutor
const
&) =
delete
;
39
LoopExecutor
(
LoopExecutor
&&) =
delete
;
40
LoopExecutor
& operator=(
LoopExecutor
&&) =
delete
;
41
42
/// @brief Queues @p task for a later turn of the loop.
43
/// @param task What to run; inside it `exec::runningOn(*this)` holds.
44
void
post
(std::function<
void
()> task)
override
;
45
46
private
:
47
::core::net::EventLoop* _loop;
48
/// Read by each queued task: once this executor is gone the task is dropped. A box rather than the executor,
49
/// because a task outlives the executor that posted it.
50
std::shared_ptr<LoopExecutor*> _alive;
51
};
52
53
}
// namespace morph::tui
morph::tui::LoopExecutor::LoopExecutor
LoopExecutor(::core::net::EventLoop &loop)
morph::tui::LoopExecutor::post
void post(std::function< void()> task) override
Queues task for a later turn of the loop.
morph::tui::LoopExecutor::~LoopExecutor
~LoopExecutor() override
Destroys the executor; tasks it posted that have not run yet are dropped when the loop reaches them.
morph::exec::IExecutor
Abstract executor interface.
Definition
executor.hpp:70
morph
tui
loop_executor.hpp
Generated by
1.17.0