#pragma once #include #include #include #include #include #include #include #include #include #include namespace trygvis { namespace apps { template using o = std::optional; namespace po = boost::program_options; using namespace log4cplus; using json = nlohmann::json; class missing_key : public std::runtime_error { public: missing_key(const json::string_t key) : runtime_error("Missing key: " + key), key(key) { } const json::string_t key; }; class waitable { protected: std::condition_variable cv; std::mutex mutex; waitable() { } virtual ~waitable() { } public: void wait() { std::unique_lock lock(mutex); cv.wait(lock); } template void wait(Predicate predicate) { std::unique_lock lock(mutex); cv.wait(lock, predicate); } template std::cv_status wait_for(const std::chrono::duration &rel_time) { std::unique_lock lock(mutex); return cv.wait_for(lock, rel_time); } template bool wait_for(const std::chrono::duration &rel_time, Predicate predicate) { std::unique_lock lock(mutex); return cv.wait_for(lock, rel_time, predicate); } template std::cv_status wait_until(const std::chrono::time_point &timeout_time) { std::unique_lock lock(mutex); return cv.wait_until(lock, timeout_time); }; template bool wait_until(const std::chrono::time_point &timeout_time, Predicate predicate) { std::unique_lock lock(mutex); return cv.wait_until(lock, timeout_time, predicate); } }; template T get(json j, std::string key) { auto ref = j[key]; if (ref.is_null()) { throw missing_key(key); } return ref; } class app_execution { public: app_execution(po::options_description desc, po::variables_map vm, Logger logger) : desc(desc), vm(vm), logger(logger) { } const po::options_description desc; const po::variables_map vm; const log4cplus::Logger logger; void usage(); }; class app { public: app(std::string app_name) : app_name(app_name) { } app(const app &) = delete; app(app &&) = default; virtual ~app() = default; app &operator=(const app &) = delete; virtual void add_options(po::options_description_easy_init &options) { } virtual void add_extra_options(po::options_description &options) { } virtual int main(app_execution &execution) = 0; const std::string app_name; }; std::string get_hostname(); int real_main(app *app, int argc, const char *argv[]); static inline void noop_deleter(void *) { } } // namespace apps } // namespace trygvis