Sunshine/sunshine/main.cpp

149 lines
3.6 KiB
C++
Raw Normal View History

//
// Created by loki on 5/30/19.
//
2020-01-01 17:47:34 +00:00
#include "process.h"
#include <thread>
#include <filesystem>
#include <iostream>
2020-01-19 23:22:13 +00:00
#include <csignal>
#include <boost/log/common.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sources/severity_logger.hpp>
2020-03-15 20:22:42 +00:00
#include "input.h"
#include "nvhttp.h"
2020-02-08 15:26:38 +00:00
#include "rtsp.h"
#include "config.h"
2019-12-22 22:34:12 +00:00
#include "thread_pool.h"
#include "platform/common.h"
extern "C" {
#include <rs.h>
}
using namespace std::literals;
namespace bl = boost::log;
2019-12-22 22:34:12 +00:00
util::ThreadPool task_pool;
bl::sources::severity_logger<int> verbose(0); // Dominating output
bl::sources::severity_logger<int> debug(1); // Follow what is happening
bl::sources::severity_logger<int> info(2); // Should be informed about
bl::sources::severity_logger<int> warning(3); // Strange events
bl::sources::severity_logger<int> error(4); // Recoverable errors
bl::sources::severity_logger<int> fatal(5); // Unrecoverable errors
bool display_cursor;
using text_sink = bl::sinks::asynchronous_sink<bl::sinks::text_ostream_backend>;
boost::shared_ptr<text_sink> sink;
struct NoDelete {
void operator()(void *) {}
};
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)
void log_flush() {
sink->flush();
}
2020-01-19 23:22:13 +00:00
std::map<int, std::function<void()>> signal_handlers;
void on_signal_forwarder(int sig) {
signal_handlers.at(sig)();
}
template<class FN>
void on_signal(int sig, FN &&fn) {
signal_handlers.emplace(sig, std::forward<FN>(fn));
std::signal(sig, on_signal_forwarder);
}
int main(int argc, char *argv[]) {
const char *config_file = SUNSHINE_ASSETS_DIR "/sunshine.conf";
2019-12-03 22:19:00 +00:00
if(argc > 1) {
config_file = argv[1];
}
if(!std::filesystem::exists(config_file)) {
std::cout << "Warning: Couldn't find configuration file ["sv << config_file << ']' << std::endl;
}
else {
config::parse_file(config_file);
2019-12-03 22:19:00 +00:00
}
sink = boost::make_shared<text_sink>();
boost::shared_ptr<std::ostream> stream { &std::cout, NoDelete {} };
sink->locked_backend()->add_stream(stream);
sink->set_filter(severity >= config::sunshine.min_log_level);
sink->set_formatter([severity="Severity"s](const bl::record_view &view, bl::formatting_ostream &os) {
auto log_level = view.attribute_values()[severity].extract<int>().get();
std::string_view log_type;
switch(log_level) {
case 0:
log_type = "Verbose: "sv;
break;
case 1:
log_type = "Debug: "sv;
break;
case 2:
log_type = "Info: "sv;
break;
case 3:
log_type = "Warning: "sv;
break;
case 4:
log_type = "Error: "sv;
break;
case 5:
log_type = "Fatal: "sv;
break;
};
os << log_type << view.attribute_values()["Message"].extract<std::string>();
});
bl::core::get()->add_sink(sink);
auto fg = util::fail_guard(log_flush);
2020-01-19 23:22:13 +00:00
// Create signal handler after logging has been initialized
auto shutdown_event = std::make_shared<safe::event_t<bool>>();
on_signal(SIGINT, [shutdown_event]() {
BOOST_LOG(info) << "Interrupt handler called"sv;
shutdown_event->raise(true);
});
auto proc_opt = proc::parse(config::stream.file_apps);
2019-12-15 18:36:22 +00:00
if(!proc_opt) {
return 7;
}
2020-02-08 15:26:38 +00:00
{
proc::ctx_t ctx;
ctx.name = "Desktop"s;
proc_opt->get_apps().emplace(std::begin(proc_opt->get_apps()), std::move(ctx));
}
2019-12-15 18:36:22 +00:00
proc::proc = std::move(*proc_opt);
auto deinit_guard = platf::init();
2020-03-15 20:22:42 +00:00
input::init();
reed_solomon_init();
2019-12-22 22:34:12 +00:00
task_pool.start(1);
2020-01-19 23:22:13 +00:00
std::thread httpThread { nvhttp::start, shutdown_event };
stream::rtpThread(shutdown_event);
httpThread.join();
return 0;
}