コード例 #1
0
void format_terminal_message(TerminalData *data, TerminalText *text) {
  struct tm *local = localtime(&(data->time));

  char date_string[20];
  char day_string[20];
  char time_string[20];

  format_date(date_string, 20, local);
  strftime(day_string, 20, "%A", local);
  clock_copy_time_string(time_string, 20);

  make_upper_case(date_string, 20);
  make_upper_case(day_string, 20);
  make_upper_case(time_string, 20);

  const char * format_string = "%s\n" //City
                               "%s\n" //Temperature
                               "%s\n" //Forecast
                               "%s\n" //Date
                               "%s\n" //Day of week
                               "BATTERY %u\n" //Battery
                               "%u STEPS\n" //Step count
                               "%s"; //Time

  snprintf(text->text_buffer, TERMINAL_BUFFER_SIZE, format_string, data->city,
                                                                   data->temperature,
                                                                   data->forecast,
                                                                   date_string,
                                                                   day_string,
                                                                   data->battery_level,
                                                                   data->step_count,
                                                                   time_string);
}
コード例 #2
0
int main(int argc, wchar_t* argv[])
{	
	static_assert(sizeof(void*) == 4, "64-bit code generation is not supported.");
	
	SetUnhandledExceptionFilter(UserUnhandledExceptionFilter);

	setup_global_locale();

	std::wcout << L"Type \"q\" to close application." << std::endl;
	
	// Set debug mode.
	#ifdef _DEBUG
		HANDLE hLogFile;
		hLogFile = CreateFile(L"crt_log.txt", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		std::shared_ptr<void> crt_log(nullptr, [](HANDLE h){::CloseHandle(h);});

		_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
		_CrtSetReportMode(_CRT_WARN,	_CRTDBG_MODE_FILE);
		_CrtSetReportFile(_CRT_WARN,	hLogFile);
		_CrtSetReportMode(_CRT_ERROR,	_CRTDBG_MODE_FILE);
		_CrtSetReportFile(_CRT_ERROR,	hLogFile);
		_CrtSetReportMode(_CRT_ASSERT,	_CRTDBG_MODE_FILE);
		_CrtSetReportFile(_CRT_ASSERT,	hLogFile);
	#endif

	// Increase process priotity.
	SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);

	// Install structured exception handler.
	caspar::win32_exception::install_handler();
				
	// Increase time precision. This will increase accuracy of function like Sleep(1) from 10 ms to 1 ms.
	struct inc_prec
	{
		inc_prec(){timeBeginPeriod(1);}
		~inc_prec(){timeEndPeriod(1);}
	} inc_prec;	

	// Install unstructured exception handlers into all tbb threads.
	struct tbb_thread_installer : public tbb::task_scheduler_observer
	{
		tbb_thread_installer(){observe(true);}
		void on_scheduler_entry(bool is_worker)
		{
			//caspar::detail::SetThreadName(GetCurrentThreadId(), "tbb-worker-thread");
			caspar::win32_exception::install_handler();
		}
	} tbb_thread_installer;

	tbb::task_scheduler_init init;
	
	try 
	{
		// Configure environment properties from configuration.
		caspar::env::configure(L"casparcg.config");
				
		caspar::log::set_log_level(caspar::env::properties().get(L"configuration.log-level", L"debug"));

	#ifdef _DEBUG
		if(caspar::env::properties().get(L"configuration.debugging.remote", false))
			MessageBox(nullptr, TEXT("Now is the time to connect for remote debugging..."), TEXT("Debug"), MB_OK | MB_TOPMOST);
	#endif	 

		// Start logging to file.
		caspar::log::add_file_sink(caspar::env::log_folder());			
		std::wcout << L"Logging [info] or higher severity to " << caspar::env::log_folder() << std::endl << std::endl;
		
		// Setup console window.
		setup_console_window();

		// Print environment information.
		print_info();
			
		std::wstringstream str;
		boost::property_tree::xml_writer_settings<wchar_t> w(' ', 3);
		boost::property_tree::write_xml(str, caspar::env::properties(), w);
		CASPAR_LOG(info) << L"casparcg.config:\n-----------------------------------------\n" << str.str().c_str() << L"-----------------------------------------";
		bool wait_for_keypress;

		{
			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.
			caspar::server caspar_server(shutdown_server_now);

			// Use separate thread for the blocking console input, will be terminated 
			// anyway when the main thread terminates.
			boost::thread stdin_thread([&caspar_server, &shutdown_server_now]
			{
				// Create a amcp parser for console commands.
				caspar::protocol::amcp::AMCPProtocolStrategy amcp(
						caspar_server.get_channels(),
						caspar_server.get_thumbnail_generator(),
						shutdown_server_now);

				// Create a dummy client which prints amcp responses to console.
				auto console_client = std::make_shared<caspar::IO::ConsoleClientInfo>();
				std::wstring wcmd;
	
				while(true)
				{
					std::getline(std::wcin, wcmd); // TODO: It's blocking...
				
					//boost::to_upper(wcmd);  // TODO COMPILER crashes on this line, Strange!
					make_upper_case(wcmd);

					if(wcmd == L"EXIT" || wcmd == L"Q" || wcmd == L"QUIT" || wcmd == L"BYE")
					{
						shutdown_server_now.set_value(true); // True to wait for keypress
						break;
					}
				
					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")
						{
							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"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";
						}
					}
					catch (...)
					{
						CASPAR_LOG_CURRENT_EXCEPTION();
						continue;
					}

					wcmd += L"\r\n";
					amcp.Parse(wcmd.c_str(), wcmd.length(), console_client);
				}	
			});
			stdin_thread.detach();
			wait_for_keypress = shutdown_server.get();
		}
		Sleep(500);
		CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";

		if (wait_for_keypress)
			system("pause");	
	}