#pragma once #include "3rdparty/backward-cpp/backward.hpp" #include "tasks/utils/ascii_banner.hpp" #include "wust_vl/common/concurrency/monitored_thread.hpp" #include "wust_vl/common/utils/signal.hpp" namespace wust_vision { template concept VisionLike = std::default_initializable && requires(T v, bool b) { { v.init(b) } -> std::same_as; { v.start() } -> std::same_as; { v.checkStateMatchMode() } -> std::same_as; }; template inline int runVisionMain(int argc, char** argv) { printBanner(); bool debug = false; if (argc > 1) { const std::string firstArg = argv[1]; debug = (firstArg == "true" || firstArg == "1"); std::cout << "debug: " << firstArg << std::endl; } std::set_terminate([]() { std::cerr << "Uncaught exception, terminating program.\n"; if (auto e = std::current_exception()) { try { std::rethrow_exception(e); } catch (const std::exception& ex) { std::cerr << "Exception: " << ex.what() << std::endl; } catch (...) { std::cerr << "Unknown exception" << std::endl; } } std::abort(); }); try { int exit_code = 0; { T v; v.init(debug); std::cout << "Starting program..." << std::endl; v.start(); wust_vl::common::utils::SignalHandler sig; sig.start([&] {}); bool exit_flag = false; while (!sig.shouldExit() && !exit_flag) { wust_vl::common::concurrency::ThreadManager::instance().printStatus(); const auto all_status = wust_vl::common::concurrency::ThreadManager::instance().getAllThreadStatuses(); v.checkStateMatchMode(); // for (auto& status: all_status) { // if (status.second // == wust_vl::common::concurrency::MonitoredThread::Status::Hung) { // std::cerr << status.first << " is Hunging! Exiting program..." << std::endl; // exit_code = -1; // std::exit(exit_code); // break; // } // } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } } std::cout << "Exiting program..." << std::endl; return exit_code; } catch (const std::exception& e) { std::cerr << "Caught exception in main: " << e.what() << "\n"; throw; return -1; } catch (...) { std::cerr << "Unknown exception caught in main!\n"; return -1; } } } // namespace wust_vision #define VISION_MAIN(VISION_TYPE) \ int main(int argc, char** argv) { \ return wust_vision::runVisionMain(argc, argv); \ } #define ENABLE_BACKWARD() \ namespace backward { \ static backward::SignalHandling sh; \ }