]> git.sesse.net Git - casparcg/blobdiff - shell/main.cpp
Manually merged 44adc50 from master
[casparcg] / shell / main.cpp
index 10f6b5be80618f3d8ad0f9240aa3fc7369a90460..c10c2a6f719a48442dcddee7c8ffa01da914daa8 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,111 +178,135 @@ 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")
-                       break;
-                               
-               // This is just dummy code for testing.
-               if(wcmd.substr(0, 1) == L"1")
-                       wcmd = L"LOADBG 1-1 " + wcmd.substr(1, wcmd.length()-1) + L" SLIDE 100 LOOP \r\nPLAY 1-1";
-               else if(wcmd.substr(0, 1) == L"2")
-                       wcmd = L"MIXER 1-0 VIDEO IS_KEY 1";
-               else if(wcmd.substr(0, 1) == L"3")
-                       wcmd = L"CG 1-2 ADD 1 BBTELEFONARE 1";
-               else if(wcmd.substr(0, 1) == L"4")
-                       wcmd = L"PLAY 1-1 DV FILTER yadif=1:-1 LOOP";
-               else if(wcmd.substr(0, 1) == L"5")
+               if(boost::iequals(wcmd, L"EXIT") || boost::iequals(wcmd, L"Q") || boost::iequals(wcmd, L"QUIT") || boost::iequals(wcmd, L"BYE"))
                {
-                       auto file = wcmd.substr(2, wcmd.length()-1);
-                       wcmd = L"PLAY 1-1 " + file + L" LOOP\r\n" 
-                                       L"PLAY 1-2 " + file + L" LOOP\r\n" 
-                                       L"PLAY 1-3 " + file + L" LOOP\r\n"
-                                       L"PLAY 2-1 " + file + L" LOOP\r\n" 
-                                       L"PLAY 2-2 " + file + L" LOOP\r\n" 
-                                       L"PLAY 2-3 " + file + L" LOOP\r\n";
-               }
-               else if(wcmd.substr(0, 1) == L"7")
-               {
-                       wcmd = L"";
-                       wcmd += L"CLEAR 1\r\n";
-                       wcmd += L"MIXER 1 CLEAR\r\n";
-                       wcmd += L"PLAY 1-0 GREEN\r\n";
-                       wcmd += L"PLAY 1-1 BLUE\r\n";
-                       wcmd += L"CG 1-2 ADD 1 ECS_TEST 1\r\n";
-                       wcmd += L"MIXER 1-2 FILL 0 -1 1 2\r\n";
-               }
-               else if(wcmd.substr(0, 1) == L"8")
-               {
-                       wcmd = L"";
-                       wcmd += L"MIXER 1-1 FILL 0.0 0.5 1.0 1.0 500 linear DEFER\r\n";
-                       wcmd += L"MIXER 1-2 FILL 0.0 0.0 1.0 1.0 500 linear DEFER\r\n";
-                       wcmd += L"MIXER 1 COMMIT\r\n";
+                       shutdown_server_now.set_value(true);    //true to wait for keypress
+                       break;
                }
-               else if(wcmd.substr(0, 1) == L"X")
+
+               try
                {
-                       int num = 0;
-                       std::wstring file;
-                       try
+                       // This is just dummy code for testing.
+                       if(wcmd.substr(0, 1) == L"1")
+                               wcmd = L"LOADBG 1-1 " + wcmd.substr(1, wcmd.length()-1) + L" SLIDE 100 LOOP \r\nPLAY 1-1";
+                       else if(wcmd.substr(0, 1) == L"2")
+                               wcmd = L"MIXER 1-0 VIDEO IS_KEY 1";
+                       else if(wcmd.substr(0, 1) == L"3")
+                               wcmd = L"CG 1-2 ADD 1 BBTELEFONARE 1";
+                       else if(wcmd.substr(0, 1) == L"4")
+                               wcmd = L"PLAY 1-1 DV FILTER yadif=1:-1 LOOP";
+                       else if(wcmd.substr(0, 1) == L"5")
                        {
-                               num = boost::lexical_cast<int>(wcmd.substr(1, 2));
-                               file = wcmd.substr(4, wcmd.length()-1);
+                               auto file = wcmd.substr(2, wcmd.length()-1);
+                               wcmd = L"PLAY 1-1 " + file + L" LOOP\r\n" 
+                                               L"PLAY 1-2 " + file + L" LOOP\r\n" 
+                                               L"PLAY 1-3 " + file + L" LOOP\r\n"
+                                               L"PLAY 2-1 " + file + L" LOOP\r\n" 
+                                               L"PLAY 2-2 " + file + L" LOOP\r\n" 
+                                               L"PLAY 2-3 " + file + L" LOOP\r\n";
                        }
-                       catch(...)
+                       else if(wcmd.substr(0, 1) == L"7")
                        {
-                               num = boost::lexical_cast<int>(wcmd.substr(1, 1));
-                               file = wcmd.substr(3, wcmd.length()-1);
+                               wcmd = L"";
+                               wcmd += L"CLEAR 1\r\n";
+                               wcmd += L"MIXER 1 CLEAR\r\n";
+                               wcmd += L"PLAY 1-0 GREEN\r\n";
+                               wcmd += L"PLAY 1-1 BLUE\r\n";
+                               wcmd += L"CG 1-2 ADD 1 ECS_TEST 1\r\n";
+                               wcmd += L"MIXER 1-2 FILL 0 -1 1 2\r\n";
                        }
-
-                       int n = 0;
-                       int num2 = num;
-                       while(num2 > 0)
+                       else if(wcmd.substr(0, 1) == L"8")
                        {
-                               num2 >>= 1;
-                               n++;
+                               wcmd = L"";
+                               wcmd += L"MIXER 1-1 FILL 0.0 0.5 1.0 1.0 500 linear DEFER\r\n";
+                               wcmd += L"MIXER 1-2 FILL 0.0 0.0 1.0 1.0 500 linear DEFER\r\n";
+                               wcmd += L"MIXER 1 COMMIT\r\n";
+                       }
+                       else if(wcmd.substr(0, 1) == L"X")
+                       {
+                               int num = 0;
+                               std::wstring file;
+                               try
+                               {
+                                       num = boost::lexical_cast<int>(wcmd.substr(1, 2));
+                                       file = wcmd.substr(4, wcmd.length()-1);
+                               }
+                               catch(...)
+                               {
+                                       num = boost::lexical_cast<int>(wcmd.substr(1, 1));
+                                       file = wcmd.substr(3, wcmd.length()-1);
+                               }
+
+                               int n = 0;
+                               int num2 = num;
+                               while(num2 > 0)
+                               {
+                                       num2 >>= 1;
+                                       n++;
+                               }
+
+                               wcmd = L"MIXER 1 GRID " + boost::lexical_cast<std::wstring>(n);
+
+                               for(int i = 1; i <= num; ++i)
+                                       wcmd += L"\r\nPLAY 1-" + boost::lexical_cast<std::wstring>(i) + L" " + file + L" LOOP";// + L" SLIDE 100 LOOP";
                        }
-
-                       wcmd = L"MIXER 1 GRID " + boost::lexical_cast<std::wstring>(n);
-
-                       for(int i = 1; i <= num; ++i)
-                               wcmd += L"\r\nPLAY 1-" + boost::lexical_cast<std::wstring>(i) + L" " + file + L" LOOP";// + L" SLIDE 100 LOOP";
+               }
+               catch (...)
+               {
+                       CASPAR_LOG_CURRENT_EXCEPTION();
+                       continue;
                }
 
                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)
@@ -363,9 +391,12 @@ 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();
+               auto wait = run();
                
-               system("pause");        
+               Sleep(500);
+               CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";
+
+               if(wait) system("pause");       
        }
        catch(boost::property_tree::file_parser_error&)
        {