Initial import
This commit is contained in:
commit
0d42589648
7 changed files with 299 additions and 0 deletions
4
.envrc
Normal file
4
.envrc
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
watch_file devenv.nix
|
||||||
|
watch_file devenv.yaml
|
||||||
|
watch_file devenv.lock
|
||||||
|
eval "$(devenv print-dev-env)"
|
||||||
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
# Devenv
|
||||||
|
.devenv*
|
||||||
|
devenv.local.nix
|
||||||
|
|
||||||
20
CMakeLists.txt
Normal file
20
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
cmake_minimum_required (VERSION 3.15)
|
||||||
|
|
||||||
|
project (elm CXX)
|
||||||
|
|
||||||
|
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||||
|
add_compile_options(-fcolor-diagnostics)
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
add_compile_options(-fdiagnostics-color=always)
|
||||||
|
else()
|
||||||
|
message(STATUS "No colored compiler diagnostic set for '${CMAKE_CXX_COMPILER_ID}' compiler.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Link this 'library' to set the c++ standard / compile-time options requested
|
||||||
|
add_library(project_options INTERFACE)
|
||||||
|
target_compile_features(project_options INTERFACE cxx_std_17)
|
||||||
|
|
||||||
|
add_executable (elmarch main.cpp)
|
||||||
|
target_link_libraries (elmarch PRIVATE project_options)
|
||||||
138
devenv.lock
Normal file
138
devenv.lock
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"devenv": {
|
||||||
|
"locked": {
|
||||||
|
"dir": "src/modules",
|
||||||
|
"lastModified": 1677763711,
|
||||||
|
"narHash": "sha256-Zki/zzU3890JGZvDcAAv83soyGqDnP/15KZrAsJt7rI=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"rev": "8489b4d98c0144a4d58a51ab5a857fede4c45f42",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"dir": "src/modules",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1673956053,
|
||||||
|
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1667395993,
|
||||||
|
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gitignore": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"pre-commit-hooks",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1660459072,
|
||||||
|
"narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1677655566,
|
||||||
|
"narHash": "sha256-I8G8Lmpp3YduYl4+pkiIJFGT1WKw+8ZMH2QwANkTu2U=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "ae8bdd2de4c23b239b5a771501641d2ef5e027d0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1673800717,
|
||||||
|
"narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-22.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pre-commit-hooks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"gitignore": "gitignore",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-stable": "nixpkgs-stable"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1677722096,
|
||||||
|
"narHash": "sha256-7mjVMvCs9InnrRybBfr5ohqcOz+pyEX8m22C1XsDilg=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "pre-commit-hooks.nix",
|
||||||
|
"rev": "61a3511668891c68ebd19d40122150b98dc2fe3b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "pre-commit-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"devenv": "devenv",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"pre-commit-hooks": "pre-commit-hooks"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
14
devenv.nix
Normal file
14
devenv.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
packages = [ pkgs.git ]; #pkgs.clang pkgs.clang-tidy ];
|
||||||
|
|
||||||
|
# https://devenv.sh/languages/
|
||||||
|
languages.cplusplus.enable = true;
|
||||||
|
|
||||||
|
# https://devenv.sh/pre-commit-hooks/
|
||||||
|
# pre-commit.hooks.shellcheck.enable = true;
|
||||||
|
|
||||||
|
# https://devenv.sh/processes/
|
||||||
|
# processes.ping.exec = "ping example.com";
|
||||||
|
}
|
||||||
4
devenv.yaml
Normal file
4
devenv.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
inputs:
|
||||||
|
nixpkgs:
|
||||||
|
url: github:NixOS/nixpkgs/nixpkgs-unstable
|
||||||
|
# can't point to the local modules here as it's used as a template
|
||||||
114
main.cpp
Normal file
114
main.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <functional>
|
||||||
|
#include <tuple>
|
||||||
|
#include <variant>
|
||||||
|
#include <thread>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
template <typename Message> struct ConsoleIO {
|
||||||
|
static auto ReadlineS(std::istream& is, std::function<Message(std::string)> f) {
|
||||||
|
return [=,&is] {
|
||||||
|
std::string line;
|
||||||
|
std::getline(is, line);
|
||||||
|
return f(line);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::function<Message()>
|
||||||
|
Readline(std::function<Message(std::string)> f) {
|
||||||
|
return ReadlineS (std::ref(std::cin), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::function<Message()>
|
||||||
|
Prompt(std::string prompt, std::function<Message(std::string)> f) {
|
||||||
|
return [=] {
|
||||||
|
std::cout << prompt << std::flush;
|
||||||
|
return Readline (f)();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ModelT, typename MessageT> struct AppT {
|
||||||
|
using Model = ModelT;
|
||||||
|
using Message = MessageT;
|
||||||
|
using Command = std::function<Message()>;
|
||||||
|
using InitResult = std::tuple<Model, std::list<Command>>;
|
||||||
|
using UpdateResult = InitResult;
|
||||||
|
using ViewResult = std::string;
|
||||||
|
using ReadLine = std::function<Message (std::string)>;
|
||||||
|
using Console = ConsoleIO<Message>;
|
||||||
|
|
||||||
|
using Init = std::function<InitResult ()>;
|
||||||
|
using Update = std::function<UpdateResult (Model, const Message&)>;
|
||||||
|
using View = std::function<ViewResult (const Model&)>;
|
||||||
|
using Done = std::function<bool (const Model&)>;
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
Init init;
|
||||||
|
Update update;
|
||||||
|
View view;
|
||||||
|
Done done;
|
||||||
|
};
|
||||||
|
|
||||||
|
int run (const Config & cfg) {
|
||||||
|
auto const& [init, update, view, done] = cfg;
|
||||||
|
auto [state, cmds] = init();
|
||||||
|
|
||||||
|
while (! done (state)) {
|
||||||
|
std::cout << view(state) << "\n";
|
||||||
|
|
||||||
|
if (!cmds.empty()) {
|
||||||
|
auto [newstate, newcmds] = update (state, cmds.front()());
|
||||||
|
cmds.erase (cmds.begin());
|
||||||
|
cmds.insert (cmds.end(), std::begin(newcmds), std::end (newcmds));
|
||||||
|
|
||||||
|
state = newstate;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for (100ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "app finished with " << cmds.size() << " pending commands and final state: \n" << view(state) << '\n';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// user defined
|
||||||
|
|
||||||
|
using Model = int;
|
||||||
|
|
||||||
|
struct SetState {
|
||||||
|
Model s;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Message = std::variant<SetState>;
|
||||||
|
|
||||||
|
auto strToState (const std::string& s) -> Message {
|
||||||
|
std::stringstream sstr(s);
|
||||||
|
int r;
|
||||||
|
sstr >> r;
|
||||||
|
return SetState { r };
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
using App = AppT<int, Message>;
|
||||||
|
App app;
|
||||||
|
return app.run(App::Config{
|
||||||
|
[]() -> App::InitResult {
|
||||||
|
return {23, {App::Console::Prompt("> ", strToState)}};
|
||||||
|
}, // init
|
||||||
|
[](const App::Model &state,
|
||||||
|
const App::Message &msg) -> App::UpdateResult {
|
||||||
|
return {std::get<SetState>(msg).s,
|
||||||
|
{App::Console::Prompt("> ", strToState)}};
|
||||||
|
}, // update
|
||||||
|
[](const App::Model &state) -> App::ViewResult {
|
||||||
|
return "Model " + std::to_string(state);
|
||||||
|
}, // view
|
||||||
|
[](const App::Model &state) -> bool { return state == 42; } // done
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue