Stop the application on EOF
This commit is contained in:
parent
0d42589648
commit
342c6069a2
1 changed files with 43 additions and 23 deletions
62
main.cpp
62
main.cpp
|
|
@ -6,25 +6,28 @@
|
|||
#include <variant>
|
||||
#include <thread>
|
||||
#include <sstream>
|
||||
#include <optional>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
template <typename Message> struct ConsoleIO {
|
||||
static auto ReadlineS(std::istream& is, std::function<Message(std::string)> f) {
|
||||
static auto ReadlineS(std::istream& is, std::function<Message(std::optional<std::string>)> f) {
|
||||
return [=,&is] {
|
||||
std::string line;
|
||||
std::getline(is, line);
|
||||
return f(line);
|
||||
if (std::string line; std::getline(is, line)) {
|
||||
return f(std::make_optional(line));
|
||||
} else {
|
||||
return f(std::nullopt);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static std::function<Message()>
|
||||
Readline(std::function<Message(std::string)> f) {
|
||||
Readline(std::function<Message(std::optional<std::string>)> f) {
|
||||
return ReadlineS (std::ref(std::cin), f);
|
||||
}
|
||||
|
||||
static std::function<Message()>
|
||||
Prompt(std::string prompt, std::function<Message(std::string)> f) {
|
||||
Prompt(std::string prompt, std::function<Message(std::optional<std::string>)> f) {
|
||||
return [=] {
|
||||
std::cout << prompt << std::flush;
|
||||
return Readline (f)();
|
||||
|
|
@ -79,36 +82,53 @@ template <typename ModelT, typename MessageT> struct AppT {
|
|||
|
||||
// user defined
|
||||
|
||||
using Model = int;
|
||||
|
||||
struct SetState {
|
||||
Model s;
|
||||
struct Model {
|
||||
bool done{false};
|
||||
int value{0};
|
||||
};
|
||||
|
||||
using Message = std::variant<SetState>;
|
||||
struct SetValue {
|
||||
int s;
|
||||
};
|
||||
|
||||
auto strToState (const std::string& s) -> Message {
|
||||
std::stringstream sstr(s);
|
||||
struct Stop {
|
||||
};
|
||||
|
||||
using Message = std::variant<SetValue, Stop>;
|
||||
|
||||
auto userInputToMsg(const std::optional<std::string>& s) -> Message {
|
||||
|
||||
if (s) {
|
||||
std::stringstream sstr(*s);
|
||||
int r;
|
||||
sstr >> r;
|
||||
return SetState { r };
|
||||
return SetValue { r };
|
||||
} else {
|
||||
return Stop{};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
using App = AppT<int, Message>;
|
||||
using App = AppT<Model, Message>;
|
||||
App app;
|
||||
return app.run(App::Config{
|
||||
[]() -> App::InitResult {
|
||||
return {23, {App::Console::Prompt("> ", strToState)}};
|
||||
return {{false, 23}, {App::Console::Prompt("> ", userInputToMsg)}};
|
||||
}, // init
|
||||
[](const App::Model &state,
|
||||
[](App::Model state,
|
||||
const App::Message &msg) -> App::UpdateResult {
|
||||
return {std::get<SetState>(msg).s,
|
||||
{App::Console::Prompt("> ", strToState)}};
|
||||
if (auto stop = std::get_if<Stop>(&msg); stop) {
|
||||
state.done = true;
|
||||
return {state, {}};
|
||||
} else {
|
||||
state.value = std::get<SetValue>(msg).s;
|
||||
return {state, {App::Console::Prompt("> ", userInputToMsg)}};
|
||||
}
|
||||
}, // update
|
||||
[](const App::Model &state) -> App::ViewResult {
|
||||
return "Model " + std::to_string(state);
|
||||
return "Model " + std::to_string(state.value);
|
||||
}, // view
|
||||
[](const App::Model &state) -> bool { return state == 42; } // done
|
||||
[](const App::Model &state) -> bool { return state.done; } // done
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue