#include <mmsystem.h>
#include <atlbase.h>
+#include <protocol/util/strategy_adapters.h>
#include <protocol/amcp/AMCPProtocolStrategy.h>
#include <protocol/osc/server.h>
#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>
}
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)
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&)
{