]> git.sesse.net Git - casparcg/blobdiff - shell/main.cpp
manually merged 4a2171b from master
[casparcg] / shell / main.cpp
index 47739e9dcea6fd53262c7e669af6799772072a5c..fc86da8c0ec2c2ee2d820750d99cdf97bd322aae 100644 (file)
@@ -42,6 +42,7 @@
 #include <mmsystem.h>
 #include <atlbase.h>
 
+#include <protocol/util/strategy_adapters.h>
 #include <protocol/amcp/AMCPProtocolStrategy.h>
 #include <protocol/osc/server.h>
 
@@ -53,7 +54,6 @@
 
 #include <common/env.h>
 #include <common/except.h>
-#include <common/except.h>
 #include <common/log.h>
 #include <common/gl/gl_check.h>
 #include <common/os/windows/current_version.h>
 #include <boost/property_tree/xml_parser.hpp>
 #include <boost/foreach.hpp>
 #include <boost/locale.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
 
 #include <signal.h>
 
@@ -174,41 +178,30 @@ LONG WINAPI UserUnhandledExceptionFilter(EXCEPTION_POINTERS* info)
        }
        catch(...){}
 
-    return EXCEPTION_CONTINUE_EXECUTION;
+       return EXCEPTION_CONTINUE_EXECUTION;
 }
 
-void run()
+void do_run(server& caspar_server, boost::promise<bool>& shutdown_server_now)
 {
-       // Create server object which initializes channels, protocols and controllers.
-       server caspar_server;
-                               
-       auto server = spl::make_shared<protocol::osc::server>(5253);
-       caspar_server.subscribe(server);
-                                               
-       //auto console_obs = reactive::make_observer([](const monitor::event& e)
-       //{
-       //      std::stringstream str;
-       //      str << e;
-       //      CASPAR_LOG(trace) << str.str().c_str();
-       //});
-
-       //caspar_server.subscribe(console_obs);
-                                               
+       // Create a dummy client which prints amcp responses to console.
+       auto console_client = spl::make_shared<IO::ConsoleClientInfo>();
+       
        // Create a amcp parser for console commands.
-       protocol::amcp::AMCPProtocolStrategy amcp(caspar_server.channels());
+       //protocol::amcp::AMCPProtocolStrategy amcp(caspar_server.channels());
+       auto amcp = spl::make_shared<caspar::IO::delimiter_based_chunking_strategy_factory<wchar_t>>(L"\r\n", spl::make_shared<caspar::IO::legacy_strategy_adapter_factory>(spl::make_shared<protocol::amcp::AMCPProtocolStrategy>(caspar_server.channels(), caspar_server.get_thumbnail_generator(), shutdown_server_now)))->create(console_client);
 
-       // Create a dummy client which prints amcp responses to console.
-       auto console_client = std::make_shared<IO::ConsoleClientInfo>();
-                       
        std::wstring wcmd;
        while(true)
        {
                std::getline(std::wcin, wcmd); // TODO: It's blocking...
                                
-               boost::to_upper(wcmd);
+               //boost::to_upper(wcmd);
 
-               if(wcmd == L"EXIT" || wcmd == L"Q" || wcmd == L"QUIT" || wcmd == L"BYE")
+               if(boost::iequals(wcmd, L"EXIT") || boost::iequals(wcmd, L"Q") || boost::iequals(wcmd, L"QUIT") || boost::iequals(wcmd, L"BYE"))
+               {
+                       shutdown_server_now.set_value(true);    //true to wait for keypress
                        break;
+               }
 
                try
                {
@@ -284,9 +277,36 @@ void run()
                }
 
                wcmd += L"\r\n";
-               amcp.Parse(wcmd.c_str(), static_cast<int>(wcmd.length()), console_client);
-       }       
-       CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";
+               amcp->parse(wcmd);
+       }
+};
+
+bool run()
+{
+       boost::promise<bool> shutdown_server_now;
+       boost::unique_future<bool> shutdown_server = shutdown_server_now.get_future();
+
+       // Create server object which initializes channels, protocols and controllers.
+       server caspar_server(shutdown_server_now);
+                               
+       auto server = spl::make_shared<protocol::osc::server>(5253);
+       caspar_server.subscribe(server);
+                                               
+       //auto console_obs = reactive::make_observer([](const monitor::event& e)
+       //{
+       //      std::stringstream str;
+       //      str << e;
+       //      CASPAR_LOG(trace) << str.str().c_str();
+       //});
+
+       //caspar_server.subscribe(console_obs);
+
+
+       // Use separate thread for the blocking console input, will be terminated 
+       // anyway when the main thread terminates.
+       boost::thread stdin_thread(std::bind(do_run, std::ref(caspar_server), std::ref(shutdown_server_now)));  //compiler didn't like lambda here...
+       stdin_thread.detach();
+       return shutdown_server.get();
 }
 
 void on_abort(int)
@@ -296,6 +316,7 @@ void on_abort(int)
 
 int main(int argc, wchar_t* argv[])
 {      
+       int return_code = 0;
        SetUnhandledExceptionFilter(UserUnhandledExceptionFilter);
        signal(SIGABRT, on_abort);
 
@@ -371,9 +392,10 @@ int main(int argc, wchar_t* argv[])
                boost::property_tree::write_xml(str, env::properties(), w);
                CASPAR_LOG(info) << L"casparcg.config:\n-----------------------------------------\n" << str.str().c_str() << L"-----------------------------------------";
                
-               run();
+               return_code = run() ? 5 : 0;
                
-               system("pause");        
+               Sleep(500);
+               CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";
        }
        catch(boost::property_tree::file_parser_error&)
        {
@@ -390,5 +412,5 @@ int main(int argc, wchar_t* argv[])
                Sleep(4000);
        }               
        
-       return 0;
+       return return_code;
 }
\ No newline at end of file