Beispiel #1
0
void StatusCallback(void *param)
{
#ifdef USE_VLD
    VLDEnable();
#endif

    HWND hwnd = (HWND)param;

    plString statusUrl = GetServerStatusUrl();
    CURL *hCurl = curl_easy_init();

    // For reporting errors
    char curlError[CURL_ERROR_SIZE];
    curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, curlError);

    while(s_loginDlgRunning)
    {
        curl_easy_setopt(hCurl, CURLOPT_URL, statusUrl.c_str());
        curl_easy_setopt(hCurl, CURLOPT_USERAGENT, "UruClient/1.0");
        curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, &CurlCallback);
        curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, param);

        if (!statusUrl.IsEmpty() && curl_easy_perform(hCurl) != 0) // only perform request if there's actually a URL set
            PostMessage(hwnd, WM_USER_SETSTATUSMSG, 0, (LPARAM) curlError);

        for(unsigned i = 0; i < UPDATE_STATUSMSG_SECONDS && s_loginDlgRunning; ++i)
        {
            Sleep(1000);
        }
    }

    curl_easy_cleanup(hCurl);

    s_statusEvent.Signal(); // Signal the semaphore
}
Beispiel #2
0
static unsigned int __stdcall gEntryPointBT(void* param)
{
#ifdef USE_VLD
    // Needs to be enabled for each thread except the WinMain
    VLDEnable();
#endif

    WinThreadParam* wtp = (WinThreadParam*)param;
    unsigned int result = wtp->fThread->Run();
    ::ReleaseSemaphore(wtp->fQuitSemaH, 1, nil); // signal that we've quit
    delete param;
    return result;
}
Beispiel #3
0
//===========================================================================
static unsigned CALLBACK CreateThreadProc (LPVOID param) {

#ifdef USE_VLD
    VLDEnable();
#endif

    PerfAddCounter(kAsyncPerfThreadsTotal, 1);
    PerfAddCounter(kAsyncPerfThreadsCurr, 1);

    // Initialize thread
    AsyncThread * thread = (AsyncThread *) param;

    // Call thread procedure
    unsigned result = thread->proc(thread);

    // Cleanup thread
    delete thread;

    PerfSubCounter(kAsyncPerfThreadsCurr, 1);
    return result;
}
Beispiel #4
0
int main(int argc, char **argv)
{
	//See http://doc.qt.io/qt-5/qopenglwidget.html#opengl-function-calls-headers-and-qopenglfunctions
	/** Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory
		on some platforms (for example, OS X) when an OpenGL core profile context is requested. This is to
		ensure that resource sharing between contexts stays functional as all internal contexts are created
		using the correct version and profile.
	**/
	{
		QSurfaceFormat format = QSurfaceFormat::defaultFormat();
		format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
		format.setOption(QSurfaceFormat::StereoBuffers, true);
		format.setStencilBufferSize(0);
#ifdef CC_GL_WINDOW_USE_QWINDOW
		format.setStereo(true);
#endif
#ifdef Q_OS_MAC
		format.setStereo(false);
		format.setVersion( 2, 1 );
		format.setProfile( QSurfaceFormat::CoreProfile );
#endif
#ifdef QT_DEBUG
		format.setOption(QSurfaceFormat::DebugContext, true);
#endif
		QSurfaceFormat::setDefaultFormat(format);
	}

	//The 'AA_ShareOpenGLContexts' attribute must be defined BEFORE the creation of the Q(Gui)Application
	//DGM: this is mandatory to enable exclusive full screen for ccGLWidget (at least on Windows)
	QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);

	//QT initialiation
	qccApplication app(argc, argv);

	//Locale management
	{
		//Force 'english' locale so as to get a consistent behavior everywhere
		QLocale locale = QLocale(QLocale::English);
		locale.setNumberOptions(QLocale::c().numberOptions());
		QLocale::setDefault(locale);

#ifdef Q_OS_UNIX
		//We reset the numeric locale for POSIX functions
		//See http://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings
		setlocale(LC_NUMERIC, "C");
#endif
	}

#ifdef USE_VLD
	VLDEnable();
#endif

#ifdef Q_OS_MAC	
	// This makes sure that our "working directory" is not within the application bundle
	QDir  appDir = QCoreApplication::applicationDirPath();
	
	if ( appDir.dirName() == "MacOS" )
	{
		appDir.cdUp();
		appDir.cdUp();
		appDir.cdUp();
		
		QDir::setCurrent( appDir.absolutePath() );
	}
#endif
	
	//splash screen
	QSplashScreen* splash = 0;
	QTime splashStartTime;

	//restore some global parameters
	{
		QSettings settings;
		settings.beginGroup(ccPS::GlobalShift());
		double maxAbsCoord = settings.value(ccPS::MaxAbsCoord(), ccGlobalShiftManager::MaxCoordinateAbsValue()).toDouble();
		double maxAbsDiag = settings.value(ccPS::MaxAbsDiag(), ccGlobalShiftManager::MaxBoundgBoxDiagonal()).toDouble();
		settings.endGroup();

		ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2").arg(maxAbsCoord, 0, 'e', 0).arg(maxAbsDiag, 0, 'e', 0));
		
		ccGlobalShiftManager::SetMaxCoordinateAbsValue(maxAbsCoord);
		ccGlobalShiftManager::SetMaxBoundgBoxDiagonal(maxAbsDiag);
	}
	
	//Command line mode?
	bool commandLine = (argc > 1 && argv[1][0] == '-');
	
	//specific case: translation file selection
	int lastArgumentIndex = 1;
	QTranslator translator;
	if (commandLine && QString(argv[1]).toUpper() == "-LANG")
	{
		QString langFilename = QString(argv[2]);
		
		//Load translation file
		if (translator.load(langFilename, QCoreApplication::applicationDirPath()))
		{
			qApp->installTranslator(&translator);
		}
		else
		{
			QMessageBox::warning(0, QObject::tr("Translation"), QObject::tr("Failed to load language file '%1'").arg(langFilename));
		}
		commandLine = false;
		lastArgumentIndex = 3;
	}

	//command line mode
	if (!commandLine)
	{
		if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_1) == 0)
		{
			QMessageBox::critical(0, "Error", "This application needs OpenGL 2.1 at least to run!");
			return EXIT_FAILURE;
		}

		//splash screen
		splashStartTime.start();
		QPixmap pixmap(QString::fromUtf8(":/CC/images/imLogoV2Qt.png"));
		splash = new QSplashScreen(pixmap, Qt::WindowStaysOnTopHint);
		splash->show();
		QApplication::processEvents();
	}

	//global structures initialization
	ccTimer::Init();
	FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!)
	ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization
	ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization

	int result = 0;

	if (commandLine)
	{
		//command line processing (no GUI)
		result = ccCommandLineParser::Parse(argc, argv);
	}
	else
	{
		//main window init.
		MainWindow* mainWindow = MainWindow::TheInstance();
		if (!mainWindow)
		{
			QMessageBox::critical(0, "Error", "Failed to initialize the main application window?!");
			return EXIT_FAILURE;
		}
		mainWindow->show();
		QApplication::processEvents();

		//show current Global Shift parameters in Console
		{
			ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2")
				.arg(ccGlobalShiftManager::MaxCoordinateAbsValue(), 0, 'e', 0)
				.arg(ccGlobalShiftManager::MaxBoundgBoxDiagonal(), 0, 'e', 0));
		}


		if (argc > lastArgumentIndex)
		{
			if (splash)
				splash->close();

			//any additional argument is assumed to be a filename --> we try to load it/them
			QStringList filenames;
			for (int i = lastArgumentIndex; i<argc; ++i)
				filenames << QString(argv[i]);

			mainWindow->addToDB(filenames);
		}
		
		if (splash)
		{
			//we want the splash screen to be visible a minimum amount of time (1000 ms.)
			while (splashStartTime.elapsed() < 1000)
			{
				splash->raise();
				QApplication::processEvents(); //to let the system breath!
			}

			splash->close();
			QApplication::processEvents();

			delete splash;
			splash = 0;
		}

		//let's rock!
		try
		{
			result = app.exec();
		}
		catch(...)
		{
			QMessageBox::warning(0, "CC crashed!","Hum, it seems that CC has crashed... Sorry about that :)");
		}
	}

	//release global structures
	MainWindow::DestroyInstance();
	FileIOFilter::UnregisterAll();

#ifdef CC_TRACK_ALIVE_SHARED_OBJECTS
	//for debug purposes
	unsigned alive = CCShareable::GetAliveCount();
	if (alive > 1)
	{
		printf("Error: some shared objects (%u) have not been released on program end!",alive);
		system("PAUSE");
	}
#endif

	return result;
}
Beispiel #5
0
int main(int argc, char** argv)
#endif
{

#ifdef HAVE_VISUAL_LEAK_DETECTOR
	VLDEnable();
#endif

#ifdef _WIN32
	(void)argc;
	(void)argv;

	//windows argv is ansi encoded by default
	std::vector<std::string> args = parse_commandline_arguments(unicode_cast<std::string>(std::wstring(GetCommandLineW())));

	// HACK: we don't parse command line arguments using program_options until
	//       the startup banner is printed. We need to get a console up and
	//       running before then if requested, so just perform a trivial search
	//       here and let program_options ignore the switch later.
	for(size_t k = 0; k < args.size(); ++k) {
		if(args[k] == "--wconsole" || args[k] == "--help" || args[k] == "--nogui" || args[k] == "--logdomains" || args[k] == "--path" || args[k] == "--render-image" || args[k] == "--screenshot" || args[k] == "--data-path" || args[k] == "--userdata-path" || args[k] == "--userconfig-path" || args[k] == "--version") {
			lg::enable_native_console_output();
			break;
		}
	}

	lg::early_log_file_setup();
#else
	std::vector<std::string> args;
	for(int i = 0; i < argc; ++i)
	{
		args.push_back(std::string(argv[i]));
	}
#endif
	assert(!args.empty());

#ifdef _OPENMP
	// Wesnoth is a special case for OMP
	// OMP wait strategy is to have threads busy-loop for 100ms
	// if there is nothing to do, they then go to sleep.
	// this avoids the scheduler putting the thread to sleep when work
	// is about to be available
	//
	// However Wesnoth has a lot of very small jobs that need to be done
	// at each redraw => 50fps every 2ms.
	// All the threads are thus busy-waiting all the time, hogging the CPU
	// To avoid that problem, we need to set the OMP_WAIT_POLICY env var
	// but that var is read by OMP at library loading time (before main)
	// thus the relaunching of ourselves after setting the variable.
#if !defined(_WIN32) && !defined(__APPLE__)
	if (!getenv("OMP_WAIT_POLICY")) {
		setenv("OMP_WAIT_POLICY", "PASSIVE", 1);
		execv(argv[0], argv);
	}
#elif _MSC_VER >= 1600
	if (!getenv("OMP_WAIT_POLICY")) {
		_putenv_s("OMP_WAIT_POLICY", "PASSIVE");
		args[0] = utils::quote(args[0]);
		restart_process(args);
	}
#endif
#endif //_OPENMP

	if(SDL_Init(SDL_INIT_TIMER) < 0) {
		fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
		return(1);
	}

#ifndef _WIN32
	struct sigaction terminate_handler;
	terminate_handler.sa_handler = wesnoth_terminate_handler;
	terminate_handler.sa_flags = 0;
	sigemptyset(&terminate_handler.sa_mask);
	sigaction(SIGTERM, &terminate_handler, nullptr);
	sigaction(SIGINT, &terminate_handler, nullptr);
#endif

	//declare this here so that it will always be at the front of the event queue.
	events::event_context global_context;

	try {
		std::cerr << "Battle for Wesnoth v" << game_config::revision << '\n';
		const time_t t = time(nullptr);
		std::cerr << "Started on " << ctime(&t) << "\n";

		const std::string& exe_dir = filesystem::get_exe_dir();
		if(!exe_dir.empty()) {
			// Try to autodetect the location of the game data dir. Note that
			// the root of the source tree currently doubles as the data dir.
			std::string auto_dir;

			// scons leaves the resulting binaries at the root of the source
			// tree by default.
			if(filesystem::file_exists(exe_dir + "/data/_main.cfg")) {
				auto_dir = exe_dir;
			}
			// cmake encourages creating a subdir at the root of the source
			// tree for the build, and the resulting binaries are found in it.
			else if(filesystem::file_exists(exe_dir + "/../data/_main.cfg")) {
				auto_dir = filesystem::normalize_path(exe_dir + "/..");
			}
			// In Windows debug builds, the EXE is placed away from the game data dir
			// (in projectfiles\VCx\Debug), but the working directory is set to the
			// game data dir. Thus, check if the working dir is the game data dir.
			else if(filesystem::file_exists(filesystem::get_cwd() + "/data/_main.cfg")) {
				auto_dir = filesystem::get_cwd();
			}

			if(!auto_dir.empty()) {
				std::cerr << "Automatically found a possible data directory at "
						  << auto_dir << '\n';
				game_config::path = auto_dir;
			}
		}

		const int res = do_gameloop(args);
		safe_exit(res);
	} catch(boost::program_options::error& e) {
		std::cerr << "Error in command line: " << e.what() << '\n';
		return 1;
	} catch(CVideo::error&) {
		std::cerr << "Could not initialize video. Exiting.\n";
		return 1;
	} catch(font::manager::error&) {
		std::cerr << "Could not initialize fonts. Exiting.\n";
		return 1;
	} catch(config::error& e) {
		std::cerr << e.message << "\n";
		return 1;
	} catch(gui::button::error&) {
		std::cerr << "Could not create button: Image could not be found\n";
		return 1;
	} catch(CVideo::quit&) {
		//just means the game should quit
	} catch(return_to_play_side_exception&) {
		std::cerr << "caught return_to_play_side_exception, please report this bug (quitting)\n";
	} catch(quit_game_exception&) {
		std::cerr << "caught quit_game_exception (quitting)\n";
	} catch(twml_exception& e) {
		std::cerr << "WML exception:\nUser message: "
			<< e.user_message << "\nDev message: " << e.dev_message << '\n';
		return 1;
	} catch(game_logic::formula_error& e) {
		std::cerr << e.what()
			<< "\n\nGame will be aborted.\n";
		return 1;
	} catch(const sdl::texception& e) {
		std::cerr << e.what();
		return 1;
	} catch(game::error &) {
		// A message has already been displayed.
		return 1;
	} catch(std::bad_alloc&) {
		std::cerr << "Ran out of memory. Aborted.\n";
		return ENOMEM;
#if !defined(NO_CATCH_AT_GAME_END)
	} catch(std::exception & e) {
		// Try to catch unexpected exceptions.
		std::cerr << "Caught general exception:\n" << e.what() << std::endl;
		return 1;
	} catch(std::string & e) {
		std::cerr << "Caught a string thrown as an exception:\n" << e << std::endl;
		return 1;
	} catch(const char * e) {
		std::cerr << "Caught a string thrown as an exception:\n" << e << std::endl;
		return 1;
	} catch(...) {
		// Ensure that even when we terminate with `throw 42`, the exception
		// is caught and all destructors are actually called. (Apparently,
		// some compilers will simply terminate without calling destructors if
		// the exception isn't caught.)
		std::cerr << "Caught unspecified general exception. Terminating." << std::endl;
		return 1;
#endif
	}

	return 0;
} // end main
Beispiel #6
0
void startup(PROGRESSCALLBACKPROC pProgressCallbackProc, void* pProgressParam, GUIINITPROC pGuiInitProc, void *pGuiParam)
{
	CFlyCrashReportMarker l_marker(_T("StartCore"));
	
#ifdef FLYLINKDC_USE_GATHER_STATISTICS
	CFlyTickDelta l_delta(g_fly_server_stat.m_time_mark[CFlyServerStatistics::TIME_START_CORE]);
#endif
	
	WSADATA wsaData = {0};
	uint8_t i = 0;
	do
	{
		if (WSAStartup(MAKEWORD(2, 2), &wsaData))
			i++;
		else
			break;
	}
	while (i < 6);
#ifdef FLYLINKDC_USE_SYSLOG
	syslog_loghost("syslog.fly-server.ru");
	openlog("flylinkdc", 0 , LOG_USER | LOG_INFO);
#endif
	
	CFlyLog l_StartUpLog("[StartUp]");
	
	// [+] IRainman fix.
#define LOAD_STEP(component_name, load_function)\
	{\
		pProgressCallbackProc(pProgressParam, _T(component_name));\
		const string l_componentName(component_name);\
		l_StartUpLog.loadStep(l_componentName);\
		load_function;\
		l_StartUpLog.loadStep(l_componentName, false);\
	}
	
#define LOAD_STEP_L(locale_key, load_function)\
	{\
		pProgressCallbackProc(pProgressParam, TSTRING(locale_key));\
		const auto& l_componentName = STRING(locale_key);\
		l_StartUpLog.loadStep(l_componentName);\
		load_function;\
		l_StartUpLog.loadStep(l_componentName, false);\
	}
	// [~] IRainman fix.
	
	dcassert(pProgressCallbackProc != nullptr);
	
	// Загрузку конфига нужно делать раньше
	// LOAD_STEP("Fly server", g_fly_server_config.loadConfig());
	
	LOAD_STEP("SQLite database init... Please wait!!!", CFlylinkDBManager::newInstance());
#ifdef FLYLINKDC_USE_ANTIVIRUS_DB
#ifdef _DEBUG
	CFlyServerConfig::SyncAntivirusDBSafe();
#endif
	LOAD_STEP("Antivirus DB", CFlylinkDBManager::getInstance()->load_avdb());
#endif
	
#ifdef FLYLINKDC_USE_GEO_IP
	LOAD_STEP("Geo IP", Util::loadGeoIp());
#endif
	LOAD_STEP("P2P Guard", Util::loadP2PGuard()); // Этот грузить всегда первым - выполняет зачистку базы
	LOAD_STEP("iblocklist.com", Util::loadIBlockList());
	
	LOAD_STEP("Custom Locations", Util::loadCustomlocations());
	
#ifdef FLYLINKDC_USE_GPU_TTH
	LOAD_STEP("TTH on GPU", GPGPUTTHManager::newInstance());
#endif
	HashManager::newInstance();
#ifdef USE_FLYLINKDC_VLD
	VLDDisable(); // TODO VLD показывает там лики - не понял пока как победить OpenSSL
#endif
// FLYLINKDC_CRYPTO_DISABLE
	LOAD_STEP("SSL", CryptoManager::newInstance());
#ifdef USE_FLYLINKDC_VLD
	VLDEnable(); // TODO VLD показывает там лики - не понял пока как победить OpenSSL
#endif
	SearchManager::newInstance();
	ConnectionManager::newInstance();
	DownloadManager::newInstance();
	UploadManager::newInstance();
	
#ifdef STRONG_USE_DHT
	LOAD_STEP("DHT", dht::DHT::newInstance());
#endif
	LOAD_STEP("Ensure list path", QueueManager::newInstance());
	LOAD_STEP("Create empty share", ShareManager::newInstance());
	LOAD_STEP("Ensure fav path", FavoriteManager::newInstance());
	LOAD_STEP("Ignore list", UserManager::newInstance()); // [+] IRainman core
	//HistoryManager::newInstance();//[-] FlylinkDC this functional released in DB Manager
	if (pGuiInitProc)
	{
		LOAD_STEP("Gui and FlyFeatures", pGuiInitProc(pGuiParam));
	}
	LOAD_STEP_L(SETTINGS, SettingsManager::getInstance()->loadOtherSettings());
	LOAD_STEP("IPGuard.xml", IpGuard::load());
	LOAD_STEP("IPTrus.ini", PGLoader::load());
#ifdef SSA_IPGRANT_FEATURE
	LOAD_STEP("IPGrant.ini", IpGrant::load());
#endif
	
	FinishedManager::newInstance();
	LOAD_STEP("ADLSearch", ADLSearchManager::newInstance());
	ConnectivityManager::newInstance();
	MappingManager::newInstance();
	//DebugManager::newInstance(); [-] IRainman opt.
	
	LOAD_STEP_L(FAVORITE_HUBS, FavoriteManager::load());
	
// FLYLINKDC_CRYPTO_DISABLE
	LOAD_STEP_L(CERTIFICATES, CryptoManager::getInstance()->loadCertificates());
	
	LOAD_STEP_L(WAITING_USERS, UploadManager::getInstance()->load()); // !SMT!-S
	
	WebServerManager::newInstance();
	
	LOAD_STEP_L(HASH_DATABASE, HashManager::getInstance()->startup());
	
	LOAD_STEP_L(SHARED_FILES, ShareManager::getInstance()->refresh_share(true, false));
	
	LOAD_STEP_L(DOWNLOAD_QUEUE, QueueManager::getInstance()->loadQueue());
#ifdef IRAINMAN_USE_STRING_POOL
	StringPool::newInstance(); // [+] IRainman opt.
#endif
	
#undef LOAD_STEP
#undef LOAD_STEP_L
}
Beispiel #7
0
void shutdown(GUIINITPROC pGuiInitProc, void *pGuiParam)
{
	// Сохраним маркеры времени завершения
#ifndef _DEBUG
	extern crash_rpt::CrashRpt g_crashRpt;
	g_crashRpt.SetCustomInfo(_T("StopCore"));
#endif
	
	{
#ifdef FLYLINKDC_COLLECT_UNKNOWN_TAG
		string l_debugTag;
		{
			CFlyFastLock(NmdcSupports::g_debugCsUnknownNmdcTagParam);
			//dcassert(NmdcSupports::g_debugUnknownNmdcTagParam.empty());
			const auto& l_debugUnknownNmdcTagParam = NmdcSupports::g_debugUnknownNmdcTagParam;
			for (auto i = l_debugUnknownNmdcTagParam.begin(); i != l_debugUnknownNmdcTagParam.end(); ++i)
			{
				l_debugTag += i->first + "(" + Util::toString(i->second) + ")" + ',';
			}
			NmdcSupports::g_debugUnknownNmdcTagParam.clear();
		}
		if (!l_debugTag.empty())
		{
			LogManager::message("Founded unknown NMDC tag param: " + l_debugTag);
		}
#endif
		
#ifdef FLYLINKDC_COLLECT_UNKNOWN_FEATURES
		// [!] IRainman fix: supports cleanup.
		string l_debugFeatures;
		string l_debugConnections;
		{
			CFlyFastLock(AdcSupports::g_debugCsUnknownAdcFeatures);
			// dcassert(AdcSupports::g_debugUnknownAdcFeatures.empty());
			const auto& l_debugUnknownFeatures = AdcSupports::g_debugUnknownAdcFeatures;
			for (auto i = l_debugUnknownFeatures.begin(); i != l_debugUnknownFeatures.end(); ++i)
			{
				l_debugFeatures += i->first + "[" + i->second + "]" + ',';
			}
			AdcSupports::g_debugUnknownAdcFeatures.clear();
		}
		{
			CFlyFastLock(NmdcSupports::g_debugCsUnknownNmdcConnection);
			dcassert(NmdcSupports::g_debugUnknownNmdcConnection.empty());
			const auto& l_debugUnknownConnections = NmdcSupports::g_debugUnknownNmdcConnection;
			for (auto i = l_debugUnknownConnections.begin(); i != l_debugUnknownConnections.end(); ++i)
			{
				l_debugConnections += *i + ',';
			}
			NmdcSupports::g_debugUnknownNmdcConnection.clear();
		}
		if (!l_debugFeatures.empty())
		{
			LogManager::message("Founded unknown ADC supports: " + l_debugFeatures);
		}
		if (!l_debugConnections.empty())
		{
			LogManager::message("Founded unknown NMDC connections: " + l_debugConnections);
		}
#endif // FLYLINKDC_COLLECT_UNKNOWN_FEATURES
		
#ifdef FLYLINKDC_USE_GATHER_STATISTICS
		CFlyTickDelta l_delta(g_fly_server_stat.m_time_mark[CFlyServerStatistics::TIME_SHUTDOWN_CORE]);
#endif
#ifdef _DEBUG
		dcdebug("shutdown start - User::g_user_counts = %d OnlineUser::g_online_user_counts = %d\n", int(User::g_user_counts), int(OnlineUser::g_online_user_counts));
#endif
#ifdef STRONG_USE_DHT
		dht::DHT::getInstance()->stop(true); // [+] IRainman fix.
#ifdef _DEBUG
		dcdebug("shutdown (after closing last hub (DHT::stop) - User::g_user_counts = %d OnlineUser::g_online_user_counts = %d\n", int(User::g_user_counts), int(OnlineUser::g_online_user_counts)); // [+] IRainman fix.
#endif
#endif
#ifdef FLYLINKDC_USE_TORRENT
		DownloadManager::getInstance()->shutdown_torrent();
#endif
		QueueManager::getInstance()->saveQueue(true);
		SettingsManager::getInstance()->save();
		ConnectionManager::getInstance()->shutdown();
		MappingManager::getInstance()->close();
		
		preparingCoreToShutdown(); // Зовем тут второй раз т.к. вероятно при автообновлении оно не зовется.
		
#ifdef FLYLINKDC_USE_DNS
		Socket::dnsCache.waitShutdown(); // !SMT!-IP
#endif
#ifdef FLYLINKDC_USE_SOCKET_COUNTER
		BufferedSocket::waitShutdown();
#endif
		
#ifdef IRAINMAN_USE_STRING_POOL
		StringPool::deleteInstance(); // [+] IRainman opt.
#endif
		MappingManager::deleteInstance();
		ConnectivityManager::deleteInstance();
		WebServerManager::deleteInstance();
		if (pGuiInitProc)
		{
			pGuiInitProc(pGuiParam);
		}
		ADLSearchManager::deleteInstance();
		FinishedManager::deleteInstance();
		ShareManager::deleteInstance();
#ifdef STRONG_USE_DHT
		dht::DHT::deleteInstance();
#endif
#ifdef USE_FLYLINKDC_VLD
		VLDDisable(); // TODO VLD показывает там лики - не понял пока как победить OpenSSL
#endif
// FLYLINKDC_CRYPTO_DISABLE
		CryptoManager::deleteInstance();
#ifdef USE_FLYLINKDC_VLD
		VLDEnable(); // TODO VLD показывает там лики - не понял пока как победить OpenSSL
#endif
		ThrottleManager::deleteInstance();
		DownloadManager::deleteInstance();
		UploadManager::deleteInstance();
		QueueManager::deleteInstance();
		ConnectionManager::deleteInstance();
		SearchManager::deleteInstance();
		UserManager::deleteInstance(); // [+] IRainman core
		FavoriteManager::deleteInstance();
		ClientManager::deleteInstance();
		HashManager::deleteInstance();
#ifdef FLYLINKDC_USE_GPU_TTH
		GPGPUTTHManager::deleteInstance();
#endif // FLYLINKDC_USE_GPU_TTH
		
		CFlylinkDBManager::deleteInstance();
		CFlylinkDBManager::shutdown_engine();
		TimerManager::deleteInstance();
		SettingsManager::deleteInstance();
		ToolbarManager::shutdown();
		extern SettingsManager* g_settings;
		g_settings = nullptr;
		
#ifdef FLYLINKDC_USE_SYSLOG
		closelog();
#endif
		
		::WSACleanup();
#ifdef _DEBUG
		dcdebug("shutdown end - User::g_user_counts = %d OnlineUser::g_online_user_counts = %d\n", int(User::g_user_counts), int(OnlineUser::g_online_user_counts));
		//dcassert(User::g_user_counts == 2);
		// ClientManager::g_uflylinkdc and ClientManager::g_me destroyed only with the full completion of the program, all the other user must be destroyed already by this time.
		dcassert(OnlineUser::g_online_user_counts == 0);
		dcassert(UploadQueueItem::g_upload_queue_item_count == 0);
		dcdebug("shutdown start - UploadQueueItem::g_upload_queue_item_count = %d \n", int(UploadQueueItem::g_upload_queue_item_count));
#endif
		
		// [~] IRainman fix.
	}
	
#ifdef FLYLINKDC_USE_GATHER_STATISTICS
	g_fly_server_stat.saveShutdownMarkers();
#endif
}
Beispiel #8
0
int main(int argc, char *argv[])
{
	//See http://doc.qt.io/qt-5/qopenglwidget.html#opengl-function-calls-headers-and-qopenglfunctions
	/** Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory
	on some platforms (for example, OS X) when an OpenGL core profile context is requested. This is to
	ensure that resource sharing between contexts stays functional as all internal contexts are created
	using the correct version and profile.
	**/
	{
		QSurfaceFormat format = QSurfaceFormat::defaultFormat();
		format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
		format.setStencilBufferSize(0);
#ifdef CC_GL_WINDOW_USE_QWINDOW
		format.setStereo(true);
#endif
#ifdef Q_OS_MAC
		format.setStereo(false);
		format.setVersion( 2, 1 );
		format.setProfile( QSurfaceFormat::CoreProfile );
#endif
#ifdef QT_DEBUG
		format.setOption(QSurfaceFormat::DebugContext);
#endif
		QSurfaceFormat::setDefaultFormat(format);
	}

	ccApplication a(argc, argv);
	
	//Locale management
	{
		//Force 'english' locale so as to get a consistent behavior everywhere
		QLocale locale = QLocale(QLocale::English);
		locale.setNumberOptions(QLocale::c().numberOptions());
		QLocale::setDefault(locale);

#ifdef Q_OS_UNIX
		//We reset the numeric locale for POSIX functions
		//See http://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings
		setlocale(LC_NUMERIC, "C");
#endif
	}

#ifdef USE_VLD
	VLDEnable();
#endif
	
#ifdef Q_OS_MAC	
	// This makes sure that our "working directory" is not within the application bundle
	QDir  appDir = QCoreApplication::applicationDirPath();
	
	if ( appDir.dirName() == "MacOS" )
	{
		appDir.cdUp();
		appDir.cdUp();
		appDir.cdUp();
		
		QDir::setCurrent( appDir.absolutePath() );
	}
#endif
	
	if (!QGLFormat::hasOpenGL())
	{
		QMessageBox::critical(0, "Error", "This application needs OpenGL to run!");
		return EXIT_FAILURE;
	}
	if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_1) == 0)
	{
		QMessageBox::critical(0, "Error", "This application needs OpenGL 2.1 at least to run!");
		return EXIT_FAILURE;
	}

	//common data initialization
	FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!)
	ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization
	ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization

	ccViewer w/*(0,Qt::Window|Qt::CustomizeWindowHint)*/;
#ifdef Q_OS_MAC
	a.setViewer( &w );
#endif

	//register minimal logger to display errors
	ccViewerLog logger(&w);
	ccLog::RegisterInstance(&logger);

	w.show();

	//files to open are passed as argument
	if (argc > 1)
	{
		//parse arguments
		QStringList filenames;
		int i = 1;
		while ( i < argc)
		{
			QString argument = QString(argv[i++]).toUpper();

			//Argument '-WIN X Y W H' (to set window size and position)
			if (argument.toUpper() == "-WIN")
			{
				bool ok = true;
				if (i+3 < argc)
				{
					bool converionOk;
					int x      = QString(argv[i  ]).toInt(&converionOk); ok &= converionOk;
					int y      = QString(argv[i+1]).toInt(&converionOk); ok &= converionOk;
					int width  = QString(argv[i+2]).toInt(&converionOk); ok &= converionOk;
					int height = QString(argv[i+3]).toInt(&converionOk); ok &= converionOk;
					i += 4;

					if (ok)
					{
						//change window position and size
						w.move(x,y);
						w.resize(width,height);
					}
				}
				if (!ok)
				{
					ccLog::Warning("Invalid arguments! 4 integer values are expected after '-win' (X Y W H)");
					break;
				}
			}
			else if (argument == "-TOP")
			{
				w.setWindowFlags(w.windowFlags() | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
				w.show();
			}
			else //any other argument is assumed to be a filename (that will we try to load)
			{
				filenames << argument;
			}
		}

		if (!filenames.empty())
			w.addToDB(filenames);
	}

#ifdef Q_OS_MAC
	// process events to load any files on the command line
	QCoreApplication::processEvents();
#endif

	w.checkForLoadedEntities();

	int result = a.exec();

	//release global structures
	FileIOFilter::UnregisterAll();

	return result;
}
Beispiel #9
0
 virtual void TearDown()
 {
     VLDEnable();
 }
Beispiel #10
0
//entry point for any windows program
int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPSTR lpCmdLine,
					int nCmdShow)
{
	//void* myP = (void*)(new Packet(1, 5, 5));
	//Packet myPack;
	//short id;
	//memcpy( &id, myP, sizeof(short));


	//Create console
	AllocConsole();
	//std::cout << "Test console!!!";
	

	//start timer
	TIM->Start();
	D3DApp dapp;
	//gTextureMan = new TextureManager();

	//the handle for the window, filled by a function
	HWND hWnd;
	//this struct holds info for the window  class
	WNDCLASSEX wc;



	//clear out the window class for use
	ZeroMemory(&wc, sizeof(WNDCLASSEX) );

	//fill in the struct with the needed information
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WindowProc;
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
	wc.lpszClassName = "WindowClass1";

	//register the window class
	RegisterClassEx(&wc);

	// create the window and use the result as the handle
    hWnd = CreateWindowEx(NULL,
                          "WindowClass1",    // name of the window class
                          "DirectX by Jimmy Roland",   // title of the window
                          WS_OVERLAPPEDWINDOW,    // window style
                          300,    // x-position of the window
                          300,    // y-position of the window
                          SCREEN_WIDTH,    // width of the window
                          SCREEN_HEIGHT,    // height of the window
                          NULL,    // we have no parent window, NULL
                          NULL,    // we aren't using menus, NULL
                          hInstance,    // application handle
                          NULL);    // used with multiple windows, NULL

    // display the window on the screen
    ShowWindow(hWnd, nCmdShow);

	//start Visual Leak Detector
	VLDEnable();

	//create global for DirectInput pointer
	gDInput = new DirectInput(hInstance, hWnd, 
		DISCL_NONEXCLUSIVE |
		DISCL_FOREGROUND,
		DISCL_NONEXCLUSIVE |
		DISCL_FOREGROUND);


	//set up and initialize Direct3D
	dapp.InitD3D(hWnd,hInstance, true);
	dapp.CreateFPSDisplay();
	// enter the main loop:
	gD3DDev = *dapp.GetDevice();
	dapp.VertexDeclarations();
    // this struct holds Windows event messages
    MSG msg;


    // Enter the infinite message loop
    while(TRUE)
    {
        // Check to see if any messages are waiting in the queue
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            // translate keystroke messages into the right format
            TranslateMessage(&msg);

            // send the message to the WindowProc function
            DispatchMessage(&msg);
        }

        // If the message is WM_QUIT, exit the while loop
        if(msg.message == WM_QUIT)
            break;

		//DirectInput polling
		gDInput->poll();
		//dapp.SetMousePos(hWnd);

        // Run game code here
		dapp.Update( (float)TIM->GetTimeElapsed() );
    }

	VLDReportLeaks();
	//clean up DirectX and COM
	dapp.CleanDirect3D();

	//delete global
	delete gDInput;

    // return this part of the WM_QUIT message to Windows
    return msg.wParam;
}
Beispiel #11
0
int main(int argc, char **argv)
{
	//QT initialiation
	qccApplication app(argc, argv);

	//Force 'english' local so as to get a consistent behavior everywhere
	QLocale::setDefault(QLocale::English);

#ifdef Q_OS_LINUX
    // we reset the numeric locale. As suggested in documetation
    // see http://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings
    // Basically - from doc: - "On Unix/Linux Qt is configured to use the system locale settings by default.
    // This can cause a conflict when using POSIX functions, for instance,
    // when converting between data types such as floats and strings"
    setlocale(LC_NUMERIC,"C");
#endif

#ifdef USE_VLD
	VLDEnable();
#endif

	//splash screen
	QSplashScreen* splash = 0;
	QTime splashStartTime;

	//Command line mode?
	bool commandLine = (argc > 1 && argv[1][0] == '-');
	if (!commandLine)
	{
		//OpenGL?
		if (!QGLFormat::hasOpenGL())
		{
			QMessageBox::critical(0, "Error", "This application needs OpenGL to run!");
			return EXIT_FAILURE;
		}

		//splash screen
		splashStartTime.start();
		QPixmap pixmap(QString::fromUtf8(":/CC/images/imLogoV2Qt.png"));
		splash = new QSplashScreen(pixmap,Qt::WindowStaysOnTopHint);
		splash->show();
		QApplication::processEvents();
	}

	//global structures initialization
	ccTimer::Init();
	FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!)
	ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization
	ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization

	int result = 0;

	if (commandLine)
	{
		//command line processing (no GUI)
		result = ccCommandLineParser::Parse(argc,argv);
	}
	else
	{
		//main window init.
		MainWindow* mainWindow = MainWindow::TheInstance();
		if (!mainWindow)
		{
			QMessageBox::critical(0, "Error", "Failed to initialize the main application window?!");
			return EXIT_FAILURE;
		}
		mainWindow->show();
		QApplication::processEvents();

		if (argc > 1)
		{
			if (splash)
				splash->close();

			//any additional argument is assumed to be a filename --> we try to load it/them
			QStringList filenames;
			for (int i=1; i<argc; ++i)
				filenames << QString(argv[i]);

			mainWindow->addToDB(filenames);
		}
		
		if (splash)
		{
			//we want the splash screen to be visible a minimum amount of time (1000 ms.)
			while (splashStartTime.elapsed() < 1000)
			{
				splash->raise();
				QApplication::processEvents(); //to let the system breath!
			}

			splash->close();
			QApplication::processEvents();

			delete splash;
			splash = 0;
		}

		//let's rock!
		try
		{
			result = app.exec();
		}
		catch(...)
		{
			QMessageBox::warning(0, "CC crashed!","Hum, it seems that CC has crashed... Sorry about that :)");
		}
	}

	//release global structures
	MainWindow::DestroyInstance();
	FileIOFilter::UnregisterAll();

#ifdef CC_TRACK_ALIVE_SHARED_OBJECTS
	//for debug purposes
	unsigned alive = CCShareable::GetAliveCount();
	if (alive > 1)
	{
		printf("Error: some shared objects (%u) have not been released on program end!",alive);
		system("PAUSE");
	}
#endif

	return result;
}
Beispiel #12
0
int main(int argc, char **argv)
{
	//See http://doc.qt.io/qt-5/qopenglwidget.html#opengl-function-calls-headers-and-qopenglfunctions
	/** Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory
		on some platforms (for example, OS X) when an OpenGL core profile context is requested. This is to
		ensure that resource sharing between contexts stays functional as all internal contexts are created
		using the correct version and profile.
	**/
	{
		QSurfaceFormat format = QSurfaceFormat::defaultFormat();
		format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
		format.setOption(QSurfaceFormat::StereoBuffers, true);
		format.setStencilBufferSize(0);
#ifdef CC_GL_WINDOW_USE_QWINDOW
		format.setStereo(true);
#endif
#ifdef Q_OS_MAC
		format.setStereo(false);
		format.setVersion( 2, 1 );
		format.setProfile( QSurfaceFormat::CoreProfile );
#endif
#ifdef QT_DEBUG
		format.setOption(QSurfaceFormat::DebugContext, true);
#endif
		QSurfaceFormat::setDefaultFormat(format);
	}

	//The 'AA_ShareOpenGLContexts' attribute must be defined BEFORE the creation of the Q(Gui)Application
	//DGM: this is mandatory to enable exclusive full screen for ccGLWidget (at least on Windows)
	QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);

	//QT initialiation
	qccApplication app(argc, argv);

	//Locale management
	{
		//Force 'english' locale so as to get a consistent behavior everywhere
		QLocale locale = QLocale(QLocale::English);
		locale.setNumberOptions(QLocale::c().numberOptions());
		QLocale::setDefault(locale);

#ifdef Q_OS_UNIX
		//We reset the numeric locale for POSIX functions
		//See http://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings
		setlocale(LC_NUMERIC, "C");
#endif
	}

#ifdef USE_VLD
	VLDEnable();
#endif

#ifdef Q_OS_MAC	
	// This makes sure that our "working directory" is not within the application bundle
	QDir  appDir = QCoreApplication::applicationDirPath();
	
	if ( appDir.dirName() == "MacOS" )
	{
		appDir.cdUp();
		appDir.cdUp();
		appDir.cdUp();
		
		QDir::setCurrent( appDir.absolutePath() );
	}
#endif

	//store the log message until a valid logging instance is registered
	ccLog::EnableMessageBackup(true);
	
	//restore some global parameters
	{
		QSettings settings;
		settings.beginGroup(ccPS::GlobalShift());
		double maxAbsCoord = settings.value(ccPS::MaxAbsCoord(), ccGlobalShiftManager::MaxCoordinateAbsValue()).toDouble();
		double maxAbsDiag = settings.value(ccPS::MaxAbsDiag(), ccGlobalShiftManager::MaxBoundgBoxDiagonal()).toDouble();
		settings.endGroup();

		ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2").arg(maxAbsCoord, 0, 'e', 0).arg(maxAbsDiag, 0, 'e', 0));
		
		ccGlobalShiftManager::SetMaxCoordinateAbsValue(maxAbsCoord);
		ccGlobalShiftManager::SetMaxBoundgBoxDiagonal(maxAbsDiag);
	}

	//Command line mode?
	bool commandLine = (argc > 1 && argv[1][0] == '-');
	
	//specific commands
	int lastArgumentIndex = 1;
	QTranslator translator;
	if (commandLine)
	{
		//translation file selection
		if (QString(argv[lastArgumentIndex]).toUpper() == "-LANG")
		{
			QString langFilename = QString(argv[2]);

			//Load translation file
			if (translator.load(langFilename, QCoreApplication::applicationDirPath()))
			{
				qApp->installTranslator(&translator);
			}
			else
			{
				QMessageBox::warning(0, QObject::tr("Translation"), QObject::tr("Failed to load language file '%1'").arg(langFilename));
			}
			commandLine = false;
			lastArgumentIndex += 2;
		}
	}

	//splash screen
	QSplashScreen* splash = 0;
	QTime splashStartTime;

	//standard mode
	if (!commandLine)
	{
		if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_1) == 0)
		{
			QMessageBox::critical(0, "Error", "This application needs OpenGL 2.1 at least to run!");
			return EXIT_FAILURE;
		}

		//splash screen
		splashStartTime.start();
		QPixmap pixmap(QString::fromUtf8(":/CC/images/imLogoV2Qt.png"));
		splash = new QSplashScreen(pixmap, Qt::WindowStaysOnTopHint);
		splash->show();
		QApplication::processEvents();
	}

	//global structures initialization
	FileIOFilter::InitInternalFilters(); //load all known I/O filters (plugins will come later!)
	ccNormalVectors::GetUniqueInstance(); //force pre-computed normals array initialization
	ccColorScalesManager::GetUniqueInstance(); //force pre-computed color tables initialization

	//load the plugins
	tPluginInfoList plugins;
	QStringList dirFilters;
	QStringList pluginPaths;
	{
		QString appPath = QCoreApplication::applicationDirPath();

#if defined(Q_OS_MAC)
		dirFilters << "*.dylib";

		// plugins are in the bundle
		appPath.remove("MacOS");

		pluginPaths += (appPath + "Plugins/ccPlugins");
#if defined(CC_MAC_DEV_PATHS)
		// used for development only - this is the path where the plugins are built
		// this avoids having to install into the application bundle when developing
		pluginPaths += (appPath + "../../../ccPlugins");
#endif
#elif defined(Q_OS_WIN)
		dirFilters << "*.dll";

		//plugins are in bin/plugins
		pluginPaths << (appPath + "/plugins");
#elif defined(Q_OS_LINUX)
		dirFilters << "*.so";

		// Plugins are relative to the bin directory where the executable is found
		QDir  binDir(appPath);

		if (binDir.dirName() == "bin")
		{
			binDir.cdUp();

			pluginPaths << (binDir.absolutePath() + "/lib/cloudcompare/plugins");
		}
		else
		{
			// Choose a reasonable default to look in
			pluginPaths << "/usr/lib/cloudcompare/plugins";
		}
#else
		#warning Need to specify the plugin path for this OS.
#endif

#ifdef Q_OS_MAC
		// Add any app data paths
		// Plugins in these directories take precendence over the included ones
		QStringList appDataPaths = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);

		for (const QString &appDataPath : appDataPaths)
		{
			pluginPaths << (appDataPath + "/plugins");
		}
#endif
	}

	ccPlugins::LoadPlugins(plugins, pluginPaths, dirFilters);
	
	int result = 0;

	//command line mode
	if (commandLine)
	{
		//command line processing (no GUI)
		result = ccCommandLineParser::Parse(argc, argv);
	}
	else
	{
		//main window init.
		MainWindow* mainWindow = MainWindow::TheInstance();
		if (!mainWindow)
		{
			QMessageBox::critical(0, "Error", "Failed to initialize the main application window?!");
			return EXIT_FAILURE;
		}
		mainWindow->dispatchPlugins(plugins, pluginPaths);
		mainWindow->show();
		QApplication::processEvents();

		//show current Global Shift parameters in Console
		{
			ccLog::Print(QString("[Global Shift] Max abs. coord = %1 / max abs. diag = %2")
				.arg(ccGlobalShiftManager::MaxCoordinateAbsValue(), 0, 'e', 0)
				.arg(ccGlobalShiftManager::MaxBoundgBoxDiagonal(), 0, 'e', 0));
		}

		if (argc > lastArgumentIndex)
		{
			if (splash)
				splash->close();

			//any additional argument is assumed to be a filename --> we try to load it/them
			QStringList filenames;
			for (int i = lastArgumentIndex; i < argc; ++i)
			{
				QString arg(argv[i]);
				//special command: auto start a plugin
				if (arg.startsWith(":start-plugin:"))
				{
					QString pluginName = arg.mid(14);
					QString pluginNameUpper = pluginName.toUpper();
					//look for this plugin
					bool found = false;
					for (const tPluginInfo &plugin : plugins)
					{
						if (plugin.object->getName().replace(' ', '_').toUpper() == pluginNameUpper)
						{
							found = true;
							bool success = plugin.object->start();
							if (!success)
							{
								ccLog::Error(QString("Failed to start the plugin '%1'").arg(plugin.object->getName()));
							}
							break;
						}
					}

					if (!found)
					{
						ccLog::Error(QString("Couldn't find the plugin '%1'").arg(pluginName.replace('_', ' ')));
					}
				}
				else
				{
					filenames << arg;
				}
			}

			mainWindow->addToDB(filenames);
		}
		
		if (splash)
		{
			//we want the splash screen to be visible a minimum amount of time (1000 ms.)
			while (splashStartTime.elapsed() < 1000)
			{
				splash->raise();
				QApplication::processEvents(); //to let the system breath!
			}

			splash->close();
			QApplication::processEvents();

			delete splash;
			splash = 0;
		}

		//let's rock!
		try
		{
			result = app.exec();
		}
		catch (...)
		{
			QMessageBox::warning(0, "CC crashed!", "Hum, it seems that CC has crashed... Sorry about that :)");
		}

		//release the plugins
		for (tPluginInfo &plugin : plugins)
		{
			plugin.object->stop(); //just in case
			if (!plugin.qObject->parent())
			{
				delete plugin.object;
				plugin.object = 0;
				plugin.qObject = 0;
			}
		}

	}

	//release global structures
	MainWindow::DestroyInstance();
	FileIOFilter::UnregisterAll();

#ifdef CC_TRACK_ALIVE_SHARED_OBJECTS
	//for debug purposes
	unsigned alive = CCShareable::GetAliveCount();
	if (alive > 1)
	{
		printf("Error: some shared objects (%u) have not been released on program end!",alive);
		system("PAUSE");
	}
#endif

	return result;
}