int main() { std::ios_base::sync_with_stdio(false); string confPath = std::getenv("HOME"); if(!confPath.empty()) { confPath += "/.config/ctudc/"; } AppSettings appSettings; try { appSettings.load(confPath + "CtudcServer.conf"); } catch(const std::exception& e) { fatal(StringBuilder() << "Failed parse CtudcServer.conf: " << e.what()); } ChannelsConfigParser channelParser; try { channelParser.load(confPath + "channels.conf"); } catch(std::exception& e) { fatal(StringBuilder() << "Failed parse channels.conf: " << e.what()); } auto caentdc = make_shared<CaenV2718>(0xEE00); auto emisstdc = make_shared<EmissTdc>(); auto ftd = make_shared<ftdi::Module>(0x28); auto vlt = make_shared<Amplifier>(); vlt->setTimeout(5000); try { ftd->open("C232HM-EDHSL-0"); ftd->initialize({ftdi::I2C_CLOCK_STANDARD_MODE, 1, 0}); } catch(std::exception& e) { std::cerr << "FTD: " << e.what() << std::endl; } auto tdcController = make_shared<Caen2718Contr>("tdc", caentdc); auto emissController= make_shared<EmissContr>("emiss", emisstdc); auto vltController = make_shared<VoltageContr>("vlt", vlt, ftd, appSettings.voltConfig); auto expoController = make_shared<ExpoContr>("expo", emisstdc, appSettings.expoConfig, channelParser.getConfig()); expoController->onNewRun() = [&](unsigned nRun) { appSettings.expoConfig.nRun = nRun; appSettings.save(confPath + "CtudcServer.conf"); }; trek::net::Server server({emissController, expoController, vltController}, appSettings.ip, appSettings.port); server.onStart() = [](const auto&) { std::cout << system_clock::now() << " Server start" << endl; }; server.onStop() = [](const auto&) { std::cout << system_clock::now() << " Server stop" << endl; }; server.onSessionStart() = [](const trek::net::Session & session) { std::cout << system_clock::now() << " Connected: " << session.remoteAddress() << endl; }; server.onSessionClose() = [](const trek::net::Session & session) { std::cout << system_clock::now() << " Disconnected: " << session.remoteAddress() << endl; }; server.onRecv() = [](const auto & session, const auto & message) { std::cout << system_clock::now() << " Recv " << session.remoteAddress() << ": " << message << endl; }; server.onSend() = [](const auto & session, const auto & message) { std::cout << system_clock::now() << " Send " << session.remoteAddress() << ": " << message << endl; }; std::atomic_bool runnig(true); auto future = std::async(std::launch::async, [&] { while(runnig.load()) { try { server.run(); } catch(exception& e) { std::cout << system_clock::now() << " Server failed: " << e.what() << std::endl; server.stop(); } } }); string command; while(true) { std::getline(cin, command); if(command == "exit") { if(future.valid()) { runnig.store(false); server.stop(); future.get(); } break; } } return 0; }
int main( int argc, char* argv[] ) { QApplication app(argc, argv); LOGGER.setLevel( 3 ); LOGGER.setOutput( Logger::Console ); LOG( 1, "Pixout ArtNet Viewer" ); LOG( 1, "viewer Version: %s ", VERSION ); const QString settings_path = QDir::fromNativeSeparators( QStandardPaths::writableLocation( QStandardPaths::AppLocalDataLocation ) + QDir::separator() ); // create settings location if not exists QDir ().mkdir( settings_path ); AppSettings settings; if( argc < 3 ) { if( !settings.load( settings_path + "app.data") ) { WARN("Can't open or empty fixture file: %s", qPrintable(settings_path + "app.data") ); } } else { settings.setProperty("port", atoi( argv[1] )); settings.setProperty("fixturePath", argv[2]); settings.setProperty("position", argv[3]); } QQmlApplicationEngine engine; app.setWindowIcon(QIcon(":favicon.png")); engine.addImportPath( QStringLiteral("qrc:/")); qmlRegisterType<PainterOutput>("Painter", 1, 0, "PainterItem"); qmlRegisterUncreatableType<AppSettings,1>("AppSettings",1,0,"AppSettings","AppSettings couldn't be created from QML"); engine.rootContext()->setContextProperty("settings", &settings); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); QObject *rootObject = engine.rootObjects().first(); Q_ASSERT( rootObject ); PainterOutput *output( rootObject->findChild<PainterOutput*>( "painter" ) ); Q_ASSERT( output ); Painter painter( output, &settings ); PixelMapperWithError mapper( &settings ); painter.SetPixelMapper( &mapper ); Receiver receiver( &settings ); QObject::connect( &receiver, &Receiver::Received, &painter, &Painter::Draw ); QObject::connect( &painter, &Painter::ReadyToOutput, output, &PainterOutput::Process ); QObject::connect( &mapper, &PixelMapper::OnResize, &painter, &Painter::Resize ); QObject::connect( &mapper, &PixelMapper::OnResize, output, &PainterOutput::setCellSize ); QObject::connect( &settings, &AppSettings::fixturePathChanged, &mapper, &PixelMapperWithError::Reload ); QObject::connect( &settings, &AppSettings::portChanged, &receiver, &Receiver::Reconnect ); QObject::connect( &settings, &AppSettings::positionChanged, &painter, &Painter::RePosition ); if( !settings.fixturePath().isEmpty() ) mapper.Reload(); else WARN("Pixel mapping empty, skip" ); LOG(1, "Listening on port %u with pixel-mapping file %s and orientation %s", settings.port(), qPrintable(settings.fixturePath()), painter.Orientation() == Painter::Vertical ? "vertical" : "horizontal" ); QQuickWindow *window = qobject_cast<QQuickWindow *>(rootObject); Q_ASSERT( window ); window->show(); const int res = app.exec(); settings.Save( settings_path + "app.data" ); return res; }