diff --git a/main.cpp b/main.cpp index 1579ce9..e10f1e1 100644 --- a/main.cpp +++ b/main.cpp @@ -6,25 +6,28 @@ #include #include #include +#include using namespace std::chrono_literals; template struct ConsoleIO { - static auto ReadlineS(std::istream& is, std::function f) { + static auto ReadlineS(std::istream& is, std::function)> 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 - Readline(std::function f) { + Readline(std::function)> f) { return ReadlineS (std::ref(std::cin), f); } static std::function - Prompt(std::string prompt, std::function f) { + Prompt(std::string prompt, std::function)> f) { return [=] { std::cout << prompt << std::flush; return Readline (f)(); @@ -79,36 +82,53 @@ template struct AppT { // user defined -using Model = int; - -struct SetState { - Model s; +struct Model { +bool done{false}; + int value{0}; }; -using Message = std::variant; +struct SetValue { + int s; +}; + +struct Stop { +}; + +using Message = std::variant; + +auto userInputToMsg(const std::optional& s) -> Message { + + if (s) { + std::stringstream sstr(*s); + int r; + sstr >> r; + return SetValue { r }; + } else { + return Stop{}; + } -auto strToState (const std::string& s) -> Message { - std::stringstream sstr(s); - int r; - sstr >> r; - return SetState { r }; } int main() { - using App = AppT; + using App = AppT; 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(msg).s, - {App::Console::Prompt("> ", strToState)}}; + if (auto stop = std::get_if(&msg); stop) { + state.done = true; + return {state, {}}; + } else { + state.value = std::get(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 }); }