mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	VCMIDirs update #3
bfs = boost::filesystem; - Updateting filenames (std::string -> bfs::path) #1 - Added platform detection, and some specyfic boost::filesystem includes to Global.h - Updated CBasicLogConfigurator. Now class uses bfs::path pathes.
This commit is contained in:
		
							
								
								
									
										53
									
								
								Global.h
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								Global.h
									
									
									
									
									
								
							| @@ -49,6 +49,50 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size."); | ||||
| #  pragma warning (disable : 4800 ) /* disable conversion to bool warning -- I think it's intended in all places */ | ||||
| #endif | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* System detection. */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| // Based on: http://sourceforge.net/p/predef/wiki/OperatingSystems/ | ||||
| //	 and on: http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor | ||||
| // TODO?: Should be moved to vstd\os_detect.h (and then included by Global.h) | ||||
| #ifdef _WIN16			// Defined for 16-bit environments | ||||
| 	#error "16-bit Windows isn't supported" | ||||
| #elif defined(_WIN64)	// Defined for 64-bit environments | ||||
| 	#define VCMI_WINDOWS | ||||
| 	#define VCMI_WINDOWS_64 | ||||
| #elif defined(_WIN32)	// Defined for both 32-bit and 64-bit environments | ||||
| 	#define VCMI_WINDOWS | ||||
| 	#define VCMI_WINDOWS_32 | ||||
| #elif defined(_WIN32_WCE) | ||||
| 	#error "Windows CE isn't supported" | ||||
| #elif defined(__linux__) || defined(__gnu_linux__) || defined(linux) || defined(__linux) | ||||
| 	#define VCMI_UNIX | ||||
| 	#define VCMI_LINUX | ||||
| 	#ifdef __ANDROID__ | ||||
| 		#define VCMI_ANDROID  | ||||
| 	#endif | ||||
| #elif defined(__APPLE__) && defined(__MACH__) | ||||
| 	#define VCMI_UNIX | ||||
| 	#define VCMI_APPLE | ||||
| 	#include "TargetConditionals.h" | ||||
| 	#if TARGET_IPHONE_SIMULATOR | ||||
| 		#define VCMI_IOS | ||||
| 		#define VCMI_IOS_SIM | ||||
| 	#elif TARGET_OS_IPHONE | ||||
| 		#define VCMI_IOS | ||||
| 	#elif TARGET_OS_MAC | ||||
| 		#define VCMI_MAC | ||||
| 	#else | ||||
| 		//#warning "Unknown Apple target."? | ||||
| 	#endif | ||||
| #else | ||||
| 	#error "VCMI supports only Windows, OSX, Linux and Android targets" | ||||
| #endif | ||||
|  | ||||
| #ifdef VCMI_IOS | ||||
| 	#error "iOS system isn't yet supported." | ||||
| #endif | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Commonly used C++, Boost headers */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| @@ -99,6 +143,8 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size."); | ||||
| #include <boost/date_time/posix_time/posix_time.hpp> | ||||
| #include <boost/date_time/posix_time/posix_time_io.hpp> | ||||
| #include <boost/filesystem.hpp> | ||||
| #include <boost/filesystem/path.hpp> | ||||
| #include <boost/filesystem/fstream.hpp> | ||||
| #include <boost/format.hpp> | ||||
| #include <boost/functional/hash.hpp> | ||||
| #include <boost/lexical_cast.hpp> | ||||
| @@ -112,13 +158,12 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size."); | ||||
| #include <boost/variant.hpp> | ||||
| #include <boost/math/special_functions/round.hpp> | ||||
|  | ||||
|  | ||||
| #ifdef ANDROID | ||||
| #include <android/log.h> | ||||
| #ifdef VCMI_ANDROID | ||||
| 	#include <android/log.h> | ||||
| #endif | ||||
|  | ||||
| #ifndef M_PI | ||||
| #define M_PI 3.14159265358979323846 | ||||
| 	#define M_PI 3.14159265358979323846 | ||||
| #endif | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
|   | ||||
| @@ -51,6 +51,7 @@ | ||||
| #endif | ||||
|  | ||||
| namespace po = boost::program_options; | ||||
| namespace bfs = boost::filesystem; | ||||
|  | ||||
| /* | ||||
|  * CMT.cpp, part of VCMI engine | ||||
| @@ -72,13 +73,12 @@ int preferredDriverIndex = -1; | ||||
| SDL_Window * mainWindow = nullptr; | ||||
| SDL_Renderer * mainRenderer = nullptr; | ||||
| SDL_Texture * screenTexture = nullptr; | ||||
|  | ||||
| #endif // VCMI_SDL1 | ||||
|  | ||||
| extern boost::thread_specific_ptr<bool> inGuiThread; | ||||
|  | ||||
| SDL_Surface *screen = nullptr, //main screen surface | ||||
| 	*screen2 = nullptr,//and hlp surface (used to store not-active interfaces layer) | ||||
| 	*screen2 = nullptr, //and hlp surface (used to store not-active interfaces layer) | ||||
| 	*screenBuf = screen; //points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed | ||||
| 	 | ||||
| std::queue<SDL_Event> events; | ||||
| @@ -106,24 +106,23 @@ void endGame(); | ||||
| #include <getopt.h> | ||||
| #endif | ||||
|  | ||||
| void startGameFromFile(const std::string &fname) | ||||
| void startGameFromFile(const bfs::path &fname) | ||||
| { | ||||
| 	StartInfo si; | ||||
| 	try //attempt retrieving start info from given file | ||||
| 	{ | ||||
| 		if(!fname.size() || !boost::filesystem::exists(fname)) | ||||
| 			throw std::runtime_error("Startfile \"" + fname + "\" does not exist!"); | ||||
| 		if(fname.empty() || !bfs::exists(fname)) | ||||
| 			throw std::runtime_error("Startfile \"" + fname.string() + "\" does not exist!"); | ||||
|  | ||||
| 		CLoadFile out(fname); | ||||
| 		if(!out.sfile || !*out.sfile) | ||||
| 		{ | ||||
| 			throw std::runtime_error("Cannot read from startfile \"" + fname + "\"!"); | ||||
| 		} | ||||
| 		// TODO: CLoadFile should take boost::path as an argument | ||||
| 		CLoadFile out(fname.string()); | ||||
| 		if (!out.sfile || !*out.sfile) | ||||
| 			throw std::runtime_error("Cannot read from startfile \"" + fname.string() +"\"!"); | ||||
| 		out >> si; | ||||
| 	} | ||||
| 	catch(std::exception &e) | ||||
| 	{ | ||||
| 		logGlobal->errorStream() << "Failed to start from the file: " + fname << ". Error: " << e.what() | ||||
| 		logGlobal->errorStream() << "Failed to start from the file: " << fname << ". Error: " << e.what() | ||||
| 			<< " Falling back to main menu."; | ||||
| 		GH.curInt = CGPreGame::create(); | ||||
| 		return; | ||||
| @@ -218,7 +217,7 @@ int main(int argc, char** argv) | ||||
| 		("help,h", "display help and exit") | ||||
| 		("version,v", "display version information and exit") | ||||
| 		("battle,b", po::value<std::string>(), "runs game in duel mode (battle-only") | ||||
| 		("start", po::value<std::string>(), "starts game from saved StartInfo file") | ||||
| 		("start", po::value<bfs::path>(), "starts game from saved StartInfo file") | ||||
| 		("onlyAI", "runs without human player, all players will be default AI") | ||||
| 		("noGUI", "runs without GUI, implies --onlyAI") | ||||
| 		("ai", po::value<std::vector<std::string>>(), "AI to be used for the player, can be specified several times for the consecutive players") | ||||
| @@ -271,15 +270,15 @@ int main(int argc, char** argv) | ||||
| 	CStopWatch total, pomtime; | ||||
| 	std::cout.flags(std::ios::unitbuf); | ||||
| 	console = new CConsoleHandler; | ||||
| 	*console->cb = std::bind(&processCommand, _1); | ||||
| 	*console->cb = processCommand; | ||||
| 	console->start(); | ||||
| 	atexit(dispose); | ||||
|  | ||||
| 	const auto logPath = VCMIDirs::get().userCachePath() + "/VCMI_Client_log.txt"; | ||||
| 	CBasicLogConfigurator logConfig(logPath, console); | ||||
| 	const bfs::path log_path = VCMIDirs::get().userCachePath() / "VCMI_Client_log.txt"; | ||||
| 	CBasicLogConfigurator logConfig(log_path, console); | ||||
|     logConfig.configureDefault(); | ||||
| 	logGlobal->infoStream() << "Creating console and configuring logger: " << pomtime.getDiff(); | ||||
| 	logGlobal->infoStream() << "The log file will be saved to " << logPath; | ||||
| 	logGlobal->infoStream() << "The log file will be saved to " << log_path; | ||||
|  | ||||
| #ifdef __ANDROID__ | ||||
| 	// boost will crash without this | ||||
| @@ -430,15 +429,15 @@ int main(int argc, char** argv) | ||||
| 		session["autoSkip"].Bool()  = vm.count("autoSkip"); | ||||
| 		session["oneGoodAI"].Bool() = vm.count("oneGoodAI"); | ||||
|  | ||||
| 		std::string fileToStartFrom; //none by default | ||||
| 		bfs::path fileToStartFrom; //none by default | ||||
| 		if(vm.count("start")) | ||||
| 			fileToStartFrom = vm["start"].as<std::string>(); | ||||
| 			fileToStartFrom = vm["start"].as<bfs::path>(); | ||||
|  | ||||
| 		if(fileToStartFrom.size() && boost::filesystem::exists(fileToStartFrom)) | ||||
| 		if(!fileToStartFrom.empty() && bfs::exists(fileToStartFrom)) | ||||
| 			startGameFromFile(fileToStartFrom); //ommit pregame and start the game using settings from file | ||||
| 		else | ||||
| 		{ | ||||
| 			if(fileToStartFrom.size()) | ||||
| 			if(!fileToStartFrom.empty()) | ||||
| 			{ | ||||
|                 logGlobal->warnStream() << "Warning: cannot find given file to start from (" << fileToStartFrom | ||||
|                     << "). Falling back to main menu."; | ||||
| @@ -584,7 +583,8 @@ void processCommand(const std::string &message) | ||||
| 	{ | ||||
|         std::cout<<"Command accepted.\t"; | ||||
|  | ||||
| 		std::string outPath = VCMIDirs::get().userCachePath() + "/extracted/"; | ||||
| 		const bfs::path out_path = | ||||
| 			VCMIDirs::get().userCachePath() / "extracted"; | ||||
|  | ||||
| 		auto list = CResourceHandler::get()->getFilteredFiles([](const ResourceID & ident) | ||||
| 		{ | ||||
| @@ -593,18 +593,19 @@ void processCommand(const std::string &message) | ||||
|  | ||||
| 		for (auto & filename : list) | ||||
| 		{ | ||||
| 			std::string outName = outPath + filename.getName(); | ||||
| 			const bfs::path file_path = out_path / (filename.getName() + ".TXT"); | ||||
| 			std::string outName = file_path.string(); | ||||
| 			 | ||||
| 			boost::filesystem::create_directories(outName.substr(0, outName.find_last_of("/"))); | ||||
| 			bfs::create_directories(file_path.parent_path()); | ||||
|  | ||||
| 			std::ofstream file(outName + ".TXT"); | ||||
| 			bfs::ofstream file(file_path); | ||||
| 			auto text = CResourceHandler::get()->load(filename)->readAll(); | ||||
|  | ||||
| 			file.write((char*)text.first.get(), text.second); | ||||
| 		} | ||||
|  | ||||
|         std::cout << "\rExtracting done :)\n"; | ||||
|         std::cout << " Extracted files can be found in " << outPath << " directory\n"; | ||||
| 		std::cout << " Extracted files can be found in " << out_path << " directory\n"; | ||||
| 	} | ||||
| 	else if(cn=="crash") | ||||
| 	{ | ||||
| @@ -710,15 +711,13 @@ void processCommand(const std::string &message) | ||||
| 		{ | ||||
| 			CDefEssential * cde = CDefHandler::giveDefEss(URI); | ||||
|  | ||||
| 			std::string outName = URI; | ||||
| 			std::string outPath = VCMIDirs::get().userCachePath() + "/extracted/"; | ||||
| 			const bfs::path out_path = VCMIDirs::get().userCachePath() / "extraced" / URI; | ||||
| 			bfs::create_directories(out_path); | ||||
|  | ||||
| 			boost::filesystem::create_directories(outPath + outName); | ||||
|  | ||||
| 			for (size_t i=0; i<cde->ourImages.size(); i++) | ||||
| 			for (size_t i = 0; i < cde->ourImages.size(); ++i) | ||||
| 			{ | ||||
| 				std::string filename = outPath + outName + '/' + boost::lexical_cast<std::string>(i) + ".bmp"; | ||||
| 				SDL_SaveBMP(cde->ourImages[i].bitmap, filename.c_str()); | ||||
| 				const bfs::path file_path = out_path / (boost::lexical_cast<std::string>(i) + ".bmp"); | ||||
| 				SDL_SaveBMP(cde->ourImages[i].bitmap, file_path.string().c_str()); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| @@ -731,14 +730,12 @@ void processCommand(const std::string &message) | ||||
|  | ||||
| 		if (CResourceHandler::get()->existsResource(ResourceID(URI))) | ||||
| 		{ | ||||
| 			std::string outName = URI; | ||||
| 			std::string outPath = VCMIDirs::get().userCachePath() + "/extracted/"; | ||||
| 			std::string fullPath = outPath + outName; | ||||
| 			const bfs::path out_path = VCMIDirs::get().userCachePath() / "extracted" / URI; | ||||
|  | ||||
| 			auto data = CResourceHandler::get()->load(ResourceID(URI))->readAll(); | ||||
|  | ||||
| 			boost::filesystem::create_directories(fullPath.substr(0, fullPath.find_last_of("/"))); | ||||
| 			std::ofstream outFile(outPath + outName, std::ofstream::binary); | ||||
| 			bfs::create_directories(out_path.parent_path()); | ||||
| 			bfs::ofstream outFile(out_path, bfs::ofstream::binary); | ||||
| 			outFile.write((char*)data.first.get(), data.second); | ||||
| 		} | ||||
| 		else | ||||
|   | ||||
| @@ -777,8 +777,8 @@ std::string CClient::aiNameForPlayer(const PlayerSettings &ps, bool battleAI) | ||||
| { | ||||
| 	if(ps.name.size()) | ||||
| 	{ | ||||
| 		std::string filename = VCMIDirs::get().libraryPath() + "/AI/" + VCMIDirs::get().libraryName(ps.name); | ||||
| 		if(boost::filesystem::exists(filename)) | ||||
| 		boost::filesystem::path ai_path = VCMIDirs::get().libraryPath() / "AI" / VCMIDirs::get().libraryName(ps.name); | ||||
| 		if (boost::filesystem::exists(ai_path)) | ||||
| 			return ps.name; | ||||
| 	} | ||||
|  | ||||
| @@ -865,8 +865,9 @@ CServerHandler::~CServerHandler() | ||||
| void CServerHandler::callServer() | ||||
| { | ||||
| 	setThreadName("CServerHandler::callServer"); | ||||
| 	std::string logName = VCMIDirs::get().userCachePath() + "/server_log.txt"; | ||||
| 	std::string comm = VCMIDirs::get().serverPath() + " --port=" + port + " > " + logName; | ||||
| 	// TODO: Make more boost::filesystem::path based | ||||
| 	const std::string logName = (VCMIDirs::get().userCachePath() / "server_log.txt").string(); | ||||
| 	const std::string comm = VCMIDirs::get().serverPath().string() + " --port=" + port + " > " + logName; | ||||
| 	int result = std::system(comm.c_str()); | ||||
| 	if (result == 0) | ||||
|         logNetwork->infoStream() << "Server closed correctly"; | ||||
|   | ||||
| @@ -111,9 +111,10 @@ template<typename rett> | ||||
| shared_ptr<rett> createAnyAI(std::string dllname, std::string methodName) | ||||
| { | ||||
|     logGlobal->infoStream() << "Opening " << dllname; | ||||
| 	std::string filename = VCMIDirs::get().libraryName(dllname); | ||||
|  | ||||
| 	auto ret = createAny<rett>(VCMIDirs::get().libraryPath() + "/AI/" + filename, methodName); | ||||
| 	const boost::filesystem::path file_path = | ||||
| 		VCMIDirs::get().libraryPath() / "AI" / VCMIDirs::get().libraryName(dllname); | ||||
| 	// TODO: createAny Should take boost::filesystem::path in argument. | ||||
| 	auto ret = createAny<rett>(file_path.string(), methodName); | ||||
| 	ret->dllName = dllname; | ||||
| 	return ret; | ||||
| } | ||||
|   | ||||
							
								
								
									
										317
									
								
								lib/VCMIDirs.cpp
									
									
									
									
									
								
							
							
						
						
									
										317
									
								
								lib/VCMIDirs.cpp
									
									
									
									
									
								
							| @@ -11,11 +11,24 @@ | ||||
| #include "StdInc.h" | ||||
| #include "VCMIDirs.h" | ||||
|  | ||||
| namespace bfs = boost::filesystem; // Should be in each cpp file | ||||
| namespace bfs = boost::filesystem; | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| // File: VCMIDirs_win32.h | ||||
| //#include "IVCMIDirs.h" | ||||
| bfs::path IVCMIDirs::userSavePath() const { return userDataPath() / "Saves"; } | ||||
|  | ||||
| void IVCMIDirs::init() | ||||
| { | ||||
| 	// TODO: Log errors | ||||
| 	bfs::create_directory(userDataPath()); | ||||
| 	bfs::create_directory(userCachePath()); | ||||
| 	bfs::create_directory(userConfigPath()); | ||||
| 	bfs::create_directory(userSavePath()); | ||||
| } | ||||
|  | ||||
| #ifdef VCMI_WINDOWS | ||||
|  | ||||
| #include <Windows.h> | ||||
| #include <Shlobj.h> | ||||
| #include <Shellapi.h> | ||||
|  | ||||
| class VCMIDirs_win32 : public IVCMIDirs | ||||
| { | ||||
| @@ -23,7 +36,6 @@ class VCMIDirs_win32 : public IVCMIDirs | ||||
| 		boost::filesystem::path userDataPath() const override; | ||||
| 		boost::filesystem::path userCachePath() const override; | ||||
| 		boost::filesystem::path userConfigPath() const override; | ||||
| 		boost::filesystem::path userSavePath() const override; | ||||
|  | ||||
| 		std::vector<boost::filesystem::path> dataPaths() const override; | ||||
|  | ||||
| @@ -36,23 +48,69 @@ class VCMIDirs_win32 : public IVCMIDirs | ||||
| 		std::string libraryName(const std::string& basename) const override; | ||||
|  | ||||
| 		std::string genHelpString() const override; | ||||
|  | ||||
| 		void init() override; | ||||
| }; | ||||
| // End of file: VCMIDirs_win32.h | ||||
|  | ||||
| // File: VCMIDirs_win32.cpp | ||||
| //#include "StdInc.h" | ||||
| //#include "VCMIDirs_win32" | ||||
| // WinAPI | ||||
| #include <Windows.h>	// WideCharToMultiByte | ||||
| #include <Shlobj.h>		// SHGetSpecialFolderPathW | ||||
|  | ||||
| namespace VCMIDirs | ||||
| void VCMIDirs_win32::init() | ||||
| { | ||||
| 	const IVCMIDirs& get() | ||||
| 	// Call base (init dirs) | ||||
| 	IVCMIDirs::init(); | ||||
|  | ||||
| 	auto moveDirIfExists = [](const bfs::path& from, const bfs::path& to) | ||||
| 	{ | ||||
| 		static VCMIDirs_win32 singleton; | ||||
| 		return singleton; | ||||
| 	} | ||||
| 		if (!bfs::is_directory(from)) | ||||
| 			return; // Nothing to do here. Flies away. | ||||
|  | ||||
| 		if (bfs::is_empty(from)) | ||||
| 		{ | ||||
| 			bfs::remove(from); | ||||
| 			return; // Nothing to do here. Flies away. | ||||
| 		} | ||||
|  | ||||
| 		if (!bfs::is_directory(to)) | ||||
| 		{ | ||||
| 			// IVCMIDirs::init() should create all destination directories. | ||||
| 			// TODO: Log fact, that we shouldn't be here. | ||||
| 			bfs::create_directory(to); | ||||
| 		} | ||||
|  | ||||
| 		// Why the hell path strings should be end with double null :/ | ||||
| 		auto make_double_nulled = [](const bfs::path& path) -> std::unique_ptr<wchar_t[]> | ||||
| 		{ | ||||
| 			const std::wstring& path_str = path.native(); | ||||
| 			std::unique_ptr<wchar_t[]> result(new wchar_t[path_str.length() + 2]); | ||||
| 			 | ||||
| 			size_t i = 0; | ||||
| 			for (const wchar_t ch : path_str) | ||||
| 				result[i++] = ch; | ||||
| 			result[i++] = L'\0'; | ||||
| 			result[i++] = L'\0'; | ||||
|  | ||||
| 			return result; | ||||
| 		}; | ||||
|  | ||||
| 		auto from_dnulled = make_double_nulled(from / L"*.*"); | ||||
| 		auto to_dnulled = make_double_nulled(to); | ||||
|  | ||||
| 		SHFILEOPSTRUCTW file_op; | ||||
| 		file_op.hwnd = GetConsoleWindow(); | ||||
| 		file_op.wFunc = FO_MOVE; | ||||
| 		file_op.pFrom = from_dnulled.get(); | ||||
| 		file_op.pTo = to_dnulled.get(); | ||||
| 		file_op.fFlags = 0; | ||||
| 		file_op.hNameMappings = nullptr; | ||||
| 		file_op.lpszProgressTitle = nullptr; | ||||
|  | ||||
| 		const int error_code = SHFileOperationW(&file_op); | ||||
| 		if (error_code != 0); // TODO: Log error. User should try to move files. | ||||
| 		else if (file_op.fAnyOperationsAborted); // TODO: Log warn. User aborted operation. User should move files. | ||||
| 		else if (!bfs::is_empty(from)); // TODO: Log warn. Some files not moved. User should try to move files. | ||||
| 		else // TODO: Log fact that we moved files succefully. | ||||
| 			bfs::remove(from); | ||||
| 	}; | ||||
|  | ||||
| 	moveDirIfExists(userDataPath() / "Games", userSavePath()); | ||||
| } | ||||
|  | ||||
| bfs::path VCMIDirs_win32::userDataPath() const | ||||
| @@ -65,7 +123,12 @@ bfs::path VCMIDirs_win32::userDataPath() const | ||||
| 	// they should put their data under the locations referred to by CSIDL_APPDATA or CSIDL_LOCAL_APPDATA. | ||||
| 	if (SHGetSpecialFolderPathW(nullptr, profile_dir_w, CSIDL_PROFILE, FALSE) == FALSE) // WinAPI way failed | ||||
| 	{ | ||||
| 		// FIXME: Create macro for MS Visual Studio. | ||||
| 		// FIXME: Use _wdupenv_s on MS Visual Studio. | ||||
| 		//    or: define _CRT_SECURE_NO_WARNINGS in preprocessor global settings. | ||||
| 		// warning C4996: 'getenv': This function or variable may be unsafe. | ||||
| 		// Consider using _dupenv_s instead. | ||||
| 		// To disable deprecation, use _CRT_SECURE_NO_WARNINGS. | ||||
| 		// See online help for details. | ||||
| 		if (profile_dir_a = std::getenv("userprofile")) // STL way succeed | ||||
| 			return bfs::path(profile_dir_a) / "vcmi"; | ||||
| 		else | ||||
| @@ -78,7 +141,6 @@ bfs::path VCMIDirs_win32::userDataPath() const | ||||
| } | ||||
| bfs::path VCMIDirs_win32::userCachePath() const { return userDataPath(); } | ||||
| bfs::path VCMIDirs_win32::userConfigPath() const { return userDataPath() / "config"; } | ||||
| bfs::path VCMIDirs_win32::userSavePath() const { return userDataPath() / "Games"; } | ||||
|  | ||||
| std::vector<bfs::path> VCMIDirs_win32::dataPaths() const | ||||
| { | ||||
| @@ -93,61 +155,26 @@ bfs::path VCMIDirs_win32::binaryPath() const { return ".";  } | ||||
|  | ||||
| std::string VCMIDirs_win32::genHelpString() const | ||||
| { | ||||
| 	// I think this function should have multiple versions | ||||
| 	// 1. For various arguments | ||||
| 	// 2. Inverse functions | ||||
| 	// and should be moved to vstd | ||||
| 	// or use http://utfcpp.sourceforge.net/ | ||||
| 	auto utf8_convert = [](const bfs::path& path) -> std::string | ||||
| 	{ | ||||
| 		const auto& path_string = path.native(); | ||||
| 		auto perform_convert = [&path_string](LPSTR output, int output_size) | ||||
| 		{ | ||||
| 			return WideCharToMultiByte( | ||||
| 				CP_UTF8,				// Use wchar_t -> utf8 char_t | ||||
| 				WC_ERR_INVALID_CHARS,	// Fails when invalid char occur | ||||
| 				path_string.c_str(),	// String to convert | ||||
| 				path_string.size(),		// String to convert size | ||||
| 				output,					// Result | ||||
| 				output_size,			// Result size | ||||
| 				nullptr, nullptr);		// For the ... CP_UTF8 settings for CodePage, this parameter must be set to NULL | ||||
| 		}; | ||||
|  | ||||
| 		int char_count = perform_convert(nullptr, 0); // Result size (0 - obtain size) | ||||
| 		if (char_count > 0) | ||||
| 		{ | ||||
| 			std::unique_ptr<char[]> buffer(new char[char_count]); | ||||
| 			if ((char_count = perform_convert(buffer.get(), char_count)) > 0) | ||||
| 				return std::string(buffer.get(), char_count); | ||||
| 		} | ||||
|  | ||||
| 		// Conversion failed :C | ||||
| 		return path.string(); | ||||
| 	}; | ||||
|  | ||||
| 	std::vector<std::string> temp_vec; | ||||
| 	for (const bfs::path& path : dataPaths()) | ||||
| 		temp_vec.push_back(utf8_convert(path)); | ||||
| 	std::string gd_string_a = boost::algorithm::join(temp_vec, L";"); | ||||
| 		temp_vec.push_back(path.string()); | ||||
| 	std::string gd_string_a = boost::algorithm::join(temp_vec, ";"); | ||||
|  | ||||
|  | ||||
| 	return | ||||
| 		"  game data:   " + gd_string_a + "\n" + | ||||
| 		"  libraries:   " + utf8_convert(libraryPath()) + "\n" + | ||||
| 		"  server:      " + utf8_convert(serverPath()) + "\n" + | ||||
| 		"\n" + | ||||
| 		"  user data:   " + utf8_convert(userDataPath()) + "\n" + | ||||
| 		"  user cache:  " + utf8_convert(userCachePath()) + "\n" + | ||||
| 		"  user config: " + utf8_convert(userConfigPath()) + "\n" + | ||||
| 		"  user saves:  " + utf8_convert(userSavePath()) + "\n"; // Should end without new-line? | ||||
| 		"  game data:   " + gd_string_a + "\n" | ||||
| 		"  libraries:   " + libraryPath().string() + "\n" | ||||
| 		"  server:      " + serverPath().string() + "\n" | ||||
| 		"\n" | ||||
| 		"  user data:   " + userDataPath().string() + "\n" | ||||
| 		"  user cache:  " + userCachePath().string() + "\n" | ||||
| 		"  user config: " + userConfigPath().string() + "\n" | ||||
| 		"  user saves:  " + userSavePath().string() + "\n"; // Should end without new-line? | ||||
| } | ||||
|  | ||||
| std::string VCMIDirs_win32::libraryName(const std::string& basename) const { return basename + ".dll"; } | ||||
| // End of file: VCMIDirs_win32.cpp | ||||
| #else // UNIX | ||||
| // File: IVCMIDirs_UNIX.h | ||||
| //#include "IVCMIDirs.h" | ||||
|  | ||||
| #elif defined(VCMI_UNIX) | ||||
| class IVCMIDirs_UNIX : public IVCMIDirs | ||||
| { | ||||
| 	public: | ||||
| @@ -156,11 +183,6 @@ class IVCMIDirs_UNIX : public IVCMIDirs | ||||
|  | ||||
| 		std::string genHelpString() const override; | ||||
| }; | ||||
| // End of file: IVCMIDirs_UNIX.h | ||||
|  | ||||
| // File: IVCMIDirs_UNIX.cpp | ||||
| //#include "StdInc.h" | ||||
| //#include "IVCMIDirs_UNIX.h" | ||||
|  | ||||
| bfs::path IVCMIDirs_UNIX::clientPath() const { return binaryPath() / "vcmiclient"; } | ||||
| bfs::path IVCMIDirs_UNIX::clientPath() const { return binaryPath() / "vcmiserver"; } | ||||
| @@ -170,32 +192,27 @@ std::string IVCMIDirs_UNIX::genHelpString() const | ||||
| 	std::vector<std::string> temp_vec; | ||||
| 	for (const bfs::path& path : dataPaths()) | ||||
| 		temp_vec.push_back(path.string()); | ||||
| 	std::string gd_string_a = boost::algorithm::join(temp_vec, L";"); | ||||
| 	std::string gd_string_a = boost::algorithm::join(temp_vec, ":"); | ||||
|  | ||||
|  | ||||
| 	return | ||||
| 		"  game data:   " + gd_string_a + "\n" + | ||||
| 		"  libraries:   " + libraryPath().string() + "\n" + | ||||
| 		"  server:      " + serverPath().string() + "\n" + | ||||
| 		"\n" + | ||||
| 		"  user data:   " + userDataPath().string() + "\n" + | ||||
| 		"  user cache:  " + userCachePath().string() + "\n" + | ||||
| 		"  user config: " + userConfigPath().string() + "\n" + | ||||
| 		"  game data:   " + gd_string_a + "\n" | ||||
| 		"  libraries:   " + libraryPath().string() + "\n" | ||||
| 		"  server:      " + serverPath().string() + "\n" | ||||
| 		"\n" | ||||
| 		"  user data:   " + userDataPath().string() + "\n" | ||||
| 		"  user cache:  " + userCachePath().string() + "\n" | ||||
| 		"  user config: " + userConfigPath().string() + "\n" | ||||
| 		"  user saves:  " + userSavePath().string() + "\n"; // Should end without new-line? | ||||
| } | ||||
| // End of file: IVCMIDirs_UNIX.cpp | ||||
|  | ||||
| #ifdef __APPLE__ | ||||
| // File: VCMIDirs_OSX.h | ||||
| //#include "IVCMIDirs_UNIX.h" | ||||
|  | ||||
| #ifdef VCMI_APPLE | ||||
| class VCMIDirs_OSX : public IVCMIDirs_UNIX | ||||
| { | ||||
| 	public: | ||||
| 		boost::filesystem::path userDataPath() const override; | ||||
| 		boost::filesystem::path userCachePath() const override; | ||||
| 		boost::filesystem::path userConfigPath() const override; | ||||
| 		boost::filesystem::path userSavePath() const override; | ||||
|  | ||||
| 		std::vector<boost::filesystem::path> dataPaths() const override; | ||||
|  | ||||
| @@ -203,20 +220,50 @@ class VCMIDirs_OSX : public IVCMIDirs_UNIX | ||||
| 		boost::filesystem::path binaryPath() const override; | ||||
|  | ||||
| 		std::string libraryName(const std::string& basename) const override; | ||||
|  | ||||
| 		void init() override; | ||||
| }; | ||||
| // End of file: VCMIDirs_OSX.h | ||||
|  | ||||
| // File: VCMIDirs_OSX.cpp | ||||
| //#include "StdInc.h" | ||||
| //#include "VCMIDirs_OSX.h" | ||||
|  | ||||
| namespace VCMIDirs | ||||
| void VCMIDirs_OSX::init() | ||||
| { | ||||
| 	const IVCMIDirs& get() | ||||
| 	// Call base (init dirs) | ||||
| 	IVCMIDirs_UNIX::init(); | ||||
|  | ||||
| 	auto moveDirIfExists = [](const bfs::path& from, const bfs::path& to) | ||||
| 	{ | ||||
| 		static VCMIDirs_OSX singleton; | ||||
| 		return singleton; | ||||
| 	} | ||||
| 		if (!bfs::is_directory(from)) | ||||
| 			return; // Nothing to do here. Flies away. | ||||
|  | ||||
| 		if (bfs::is_empty(from)) | ||||
| 		{ | ||||
| 			bfs::remove(from); | ||||
| 			return; // Nothing to do here. Flies away. | ||||
| 		} | ||||
|  | ||||
| 		if (!bfs::is_directory(to)) | ||||
| 		{ | ||||
| 			// IVCMIDirs::init() should create all destination directories. | ||||
| 			// TODO: Log fact, that we shouldn't be here. | ||||
| 			bfs::create_directory(to); | ||||
| 		} | ||||
|  | ||||
| 		for (bfs::directory_iterator file(from); file != bfs::directory_iterator(); ++file) | ||||
| 		{ | ||||
| 			const boost::filesystem::path& src_file_path = file->path(); | ||||
| 			const boost::filesystem::path  dst_file_path = to / src_file_path.filename(); | ||||
|  | ||||
| 			// TODO: Aplication should ask user what to do when file exists: | ||||
| 			// replace/ignore/stop process/replace all/ignore all | ||||
| 			if (!boost::filesystem::exists(dst_file_path)) | ||||
| 				bfs::rename(src_file_path, dst_file_path); | ||||
| 		} | ||||
|  | ||||
| 		if (!bfs::is_empty(from)); // TODO: Log warn. Some files not moved. User should try to move files. | ||||
| 		else | ||||
| 			bfs::remove(from); | ||||
| 	}; | ||||
|  | ||||
| 	moveDirIfExists(userDataPath() / "Games", userSavePath()); | ||||
| } | ||||
|  | ||||
| bfs::path VCMIDirs_OSX::userDataPath() const | ||||
| @@ -234,7 +281,6 @@ bfs::path VCMIDirs_OSX::userDataPath() const | ||||
| } | ||||
| bfs::path VCMIDirs_OSX::userCachePath() const { return userDataPath(); } | ||||
| bfs::path VCMIDirs_OSX::userConfigPath() const { return userDataPath() / "config"; } | ||||
| bfs::path VCMIDirs_OSX::userSavePath() const { return userDataPath() / "Games"; } | ||||
|  | ||||
| std::vector<bfs::path> VCMIDirs_OSX::dataPaths() const | ||||
| { | ||||
| @@ -245,18 +291,13 @@ bfs::path VCMIDirs_OSX::libraryPath() const { return "."; } | ||||
| bfs::path VCMIDirs_OSX::binaryPath() const { return "."; } | ||||
|  | ||||
| std::string libraryName(const std::string& basename) { return "lib" + basename + ".dylib"; } | ||||
| // End of file: VCMIDirs_OSX.cpp | ||||
| #else | ||||
| // File: VCMIDirs_Linux.h | ||||
| //#include "IVCMIDirs_UNIX.h" | ||||
|  | ||||
| #elif defined(VCMI_LINUX) | ||||
| class VCMIDirs_Linux : public IVCMIDirs_UNIX | ||||
| { | ||||
| public: | ||||
| 	boost::filesystem::path userDataPath() const override; | ||||
| 	boost::filesystem::path userCachePath() const override; | ||||
| 	boost::filesystem::path userConfigPath() const override; | ||||
| 	boost::filesystem::path userSavePath() const override; | ||||
|  | ||||
| 	std::vector<boost::filesystem::path> dataPaths() const override; | ||||
|  | ||||
| @@ -265,20 +306,6 @@ public: | ||||
|  | ||||
| 	std::string libraryName(const std::string& basename) const override; | ||||
| }; | ||||
| // End of file: VCMIDirs_Linux.h | ||||
|  | ||||
| // File: VCMIDirs_Linux.cpp | ||||
| //#include "StdInc.h" | ||||
| //#include "VCMIDirs_Linux.h" | ||||
|  | ||||
| namespace VCMIDirs | ||||
| { | ||||
| 	const IVCMIDirs& get() | ||||
| 	{ | ||||
| 		static VCMIDirs_Linux singleton; | ||||
| 		return singleton; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bfs::path VCMIDirs_Linux::userDataPath() const | ||||
| { | ||||
| @@ -313,10 +340,6 @@ bfs::path VCMIDirs_Linux::userConfigPath() const | ||||
| 	else | ||||
| 		return "."; | ||||
| } | ||||
| bfs::path VCMIDirs_Linux::userSavePath() const | ||||
| { | ||||
| 	return userDataPath() / "Saves"; | ||||
| } | ||||
|  | ||||
| std::vector<bfs::path> VCMIDirs_Linux::dataPaths() const | ||||
| { | ||||
| @@ -328,8 +351,6 @@ std::vector<bfs::path> VCMIDirs_Linux::dataPaths() const | ||||
| 	std::vector<bfs::path> ret; | ||||
|  | ||||
| 	const char* home_dir; | ||||
| 	if (home_dir = getenv("HOME")) // compatibility, should be removed after 0.96 | ||||
| 		ret.push_back(bfs::path(home_dir) / ".vcmi"); | ||||
| 	ret.push_back(M_DATA_DIR); | ||||
|  | ||||
| 	if ((home_dir = getenv("XDG_DATA_DIRS")) != nullptr) | ||||
| @@ -353,46 +374,50 @@ bfs::path VCMIDirs_Linux::libraryPath() const { return M_LIB_PATH; } | ||||
| bfs::path VCMIDirs_Linux::binaryPath() const { return M_BIN_DIR; } | ||||
|  | ||||
| std::string VCMIDirs_Linux::libraryName(const std::string& basename) const { return "lib" + basename + ".so"; } | ||||
| // End of file VCMIDirs_Linux.cpp | ||||
| #ifdef __ANDROID__ | ||||
| // File: VCMIDirs_Android.h | ||||
| //#include "VCMIDirs_Linux.h" | ||||
| #ifdef VCMI_ANDROID | ||||
| class VCMIDirs_Android : public VCMIDirs_Linux | ||||
| { | ||||
| public: | ||||
| 	boost::filesystem::path userDataPath() const override; | ||||
| 	boost::filesystem::path userCachePath() const override; | ||||
| 	boost::filesystem::path userConfigPath() const override; | ||||
| 	boost::filesystem::path userSavePath() const override; | ||||
|  | ||||
| 	std::vector<boost::filesystem::path> dataPaths() const override; | ||||
| }; | ||||
| // End of file: VCMIDirs_Android.h | ||||
|  | ||||
| // File: VCMIDirs_Android.cpp | ||||
| //#include "StdInc.h" | ||||
| //#include "VCMIDirs_Android.h" | ||||
|  | ||||
| namespace VCMIDirs | ||||
| { | ||||
| 	const IVCMIDirs& get() | ||||
| 	{ | ||||
| 		static VCMIDirs_Android singleton; | ||||
| 		return singleton; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // on Android HOME will be set to something like /sdcard/data/Android/is.xyz.vcmi/files/ | ||||
| bfs::path VCMIDirs_Android::userDataPath() const { return getenv("HOME"); } | ||||
| bfs::path VCMIDirs_Android::userCachePath() const { return userDataPath() / "cache"; } | ||||
| bfs::path VCMIDirs_Android::userConfigPath() const { return userDataPath() / "config"; } | ||||
| bfs::path VCMIDirs_Android::userSavePath() const { return userDataPath() / "Saves"; } | ||||
|  | ||||
| std::vector<bfs::path> VCMIDirs_Android::dataPaths() const | ||||
| { | ||||
| 	return std::vector<bfs::path>(1, userDataPath()); | ||||
| } | ||||
| // End of file: VCMIDirs_Android.cpp | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
| #endif // VCMI_ANDROID | ||||
| #endif // VCMI_APPLE, VCMI_LINUX | ||||
| #endif // VCMI_WINDOWS, VCMI_UNIX | ||||
|  | ||||
| // Getters for interfaces are separated for clarity. | ||||
| namespace VCMIDirs | ||||
| { | ||||
| 	const IVCMIDirs& get() | ||||
| 	{ | ||||
| 		#ifdef VCMI_WINDOWS | ||||
| 			static VCMIDirs_win32 singleton; | ||||
| 		#elif defined(VCMI_ANDROID) | ||||
| 			static VCMIDirs_Android singleton; | ||||
| 		#elif defined(VCMI_LINUX) | ||||
| 			static VCMIDirs_Linux singleton; | ||||
| 		#elif defined(VCMI_APPLE) | ||||
| 			static VCMIDirs_OSX singleton; | ||||
| 		#endif | ||||
| 		static bool initialized = false; | ||||
| 		if (!initialized) | ||||
| 		{ | ||||
| 			singleton.init(); | ||||
| 			initialized = true; | ||||
| 		} | ||||
| 		return singleton; | ||||
| 	} | ||||
| } | ||||
| @@ -16,9 +16,9 @@ | ||||
| // Boost | ||||
| #include <boost/filesystem/path.hpp> | ||||
|  | ||||
| // TODO: File should be rename to IVCMIDirs.h | ||||
| // TODO: File should be renamed to IVCMIDirs.h | ||||
|  | ||||
| class IVCMIDirs | ||||
| class DLL_LINKAGE IVCMIDirs | ||||
| { | ||||
| 	public: | ||||
| 		// Path to user-specific data directory | ||||
| @@ -31,7 +31,7 @@ class IVCMIDirs | ||||
| 		virtual boost::filesystem::path userConfigPath() const = 0; | ||||
|  | ||||
| 		// Path to saved games | ||||
| 		virtual boost::filesystem::path userSavePath() const = 0; | ||||
| 		virtual boost::filesystem::path userSavePath() const; | ||||
|  | ||||
| 		// Paths to global system-wide data directories. First items have higher priority | ||||
| 		virtual std::vector<boost::filesystem::path> dataPaths() const = 0; | ||||
| @@ -54,6 +54,11 @@ class IVCMIDirs | ||||
| 		// virtual std::string libraryName(std::string&& basename) const = 0;? | ||||
|  | ||||
| 		virtual std::string genHelpString() const = 0; | ||||
| 		 | ||||
| 		// Creates not existed, but required directories. | ||||
| 		// Updates directories what change name/path between versions. | ||||
| 		// Function called automatically. | ||||
| 		virtual void init(); | ||||
| }; | ||||
|  | ||||
| namespace VCMIDirs | ||||
|   | ||||
| @@ -69,7 +69,7 @@ void CFilesystemGenerator::loadDirectory(const std::string &mountPoint, const Js | ||||
| 	std::string URI = prefix + config["path"].String(); | ||||
| 	int depth = 16; | ||||
| 	if (!config["depth"].isNull()) | ||||
| 		depth = config["depth"].Float(); | ||||
| 		depth = (int)config["depth"].Float(); | ||||
|  | ||||
| 	ResourceID resID(URI, EResType::DIRECTORY); | ||||
|  | ||||
| @@ -136,12 +136,13 @@ ISimpleResourceLoader * CResourceHandler::createInitial() | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	// TODO: CFilesystemLoader: Should take boost::filesystem::path in argument | ||||
| 	for (auto & path : VCMIDirs::get().dataPaths()) | ||||
| 	{ | ||||
| 		if (boost::filesystem::is_directory(path)) // some of system-provided paths may not exist | ||||
| 			initialLoader->addLoader(new CFilesystemLoader("", path, 0, true), false); | ||||
| 			initialLoader->addLoader(new CFilesystemLoader("", path.string(), 0, true), false); | ||||
| 	} | ||||
| 	initialLoader->addLoader(new CFilesystemLoader("", VCMIDirs::get().userDataPath(), 0, true), false); | ||||
| 	initialLoader->addLoader(new CFilesystemLoader("", VCMIDirs::get().userDataPath().string(), 0, true), false); | ||||
|  | ||||
| 	recurseInDir("CONFIG", 0);// look for configs | ||||
| 	recurseInDir("DATA", 0); // look for archives | ||||
| @@ -166,9 +167,10 @@ void CResourceHandler::initialize() | ||||
| 	//    |-saves | ||||
| 	//    |-config | ||||
|  | ||||
| 	// TODO: CFilesystemLoader should take boost::filesystem::path | ||||
| 	knownLoaders["root"] = new CFilesystemList(); | ||||
| 	knownLoaders["saves"] = new CFilesystemLoader("SAVES/", VCMIDirs::get().userSavePath()); | ||||
| 	knownLoaders["config"] = new CFilesystemLoader("CONFIG/", VCMIDirs::get().userConfigPath()); | ||||
| 	knownLoaders["saves"] = new CFilesystemLoader("SAVES/", VCMIDirs::get().userSavePath().string()); | ||||
| 	knownLoaders["config"] = new CFilesystemLoader("CONFIG/", VCMIDirs::get().userConfigPath().string()); | ||||
|  | ||||
| 	auto localFS = new CFilesystemList(); | ||||
| 	localFS->addLoader(knownLoaders["saves"], true); | ||||
|   | ||||
| @@ -3,16 +3,17 @@ | ||||
|  | ||||
| #include "../CConfigHandler.h" | ||||
|  | ||||
| CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console) : filePath(filePath), | ||||
| 	console(console), appendToLogFile(false) | ||||
| { | ||||
| CBasicLogConfigurator::CBasicLogConfigurator(const boost::filesystem::path & file_path, CConsoleHandler * const console) : | ||||
| 	file_path(file_path), console(console), appendToLogFile(false) {} | ||||
|  | ||||
| } | ||||
| CBasicLogConfigurator::CBasicLogConfigurator(boost::filesystem::path && file_path, CConsoleHandler * const console) : | ||||
| 	file_path(std::move(file_path)), console(console), appendToLogFile(false) {} | ||||
|  | ||||
| void CBasicLogConfigurator::configureDefault() | ||||
| { | ||||
| 	CLogger::getGlobalLogger()->addTarget(make_unique<CLogConsoleTarget>(console)); | ||||
| 	CLogger::getGlobalLogger()->addTarget(make_unique<CLogFileTarget>(filePath, appendToLogFile)); | ||||
| 	// TODO: CLogFileTarget should take boost::filesystem::path as an argument | ||||
| 	CLogger::getGlobalLogger()->addTarget(make_unique<CLogFileTarget>(file_path.string(), appendToLogFile)); | ||||
| 	appendToLogFile = true; | ||||
| } | ||||
|  | ||||
| @@ -21,7 +22,8 @@ void CBasicLogConfigurator::configure() | ||||
| 	try | ||||
| 	{ | ||||
| 		const JsonNode & loggingNode = settings["logging"]; | ||||
| 		if(loggingNode.isNull()) throw std::runtime_error("Settings haven't been loaded."); | ||||
| 		if(loggingNode.isNull()) | ||||
| 			throw std::runtime_error("Settings haven't been loaded."); | ||||
|  | ||||
| 		// Configure loggers | ||||
| 		const JsonNode & loggers = loggingNode["loggers"]; | ||||
| @@ -67,8 +69,9 @@ void CBasicLogConfigurator::configure() | ||||
| 		} | ||||
| 		CLogger::getGlobalLogger()->addTarget(std::move(consoleTarget)); | ||||
|  | ||||
| 		// TODO: CLogFileTarget should take boost::filesystem::path as an argument | ||||
| 		// Add file target | ||||
| 		auto fileTarget = make_unique<CLogFileTarget>(filePath, appendToLogFile); | ||||
| 		auto fileTarget = make_unique<CLogFileTarget>(file_path.string(), appendToLogFile); | ||||
| 		const JsonNode & fileNode = loggingNode["file"]; | ||||
| 		if(!fileNode.isNull()) | ||||
| 		{ | ||||
| @@ -87,7 +90,7 @@ void CBasicLogConfigurator::configure() | ||||
| 	logGlobal->infoStream() << "Initialized logging system based on settings successfully."; | ||||
| } | ||||
|  | ||||
| ELogLevel::ELogLevel CBasicLogConfigurator::getLogLevel(const std::string & level) const | ||||
| ELogLevel::ELogLevel CBasicLogConfigurator::getLogLevel(const std::string & level) | ||||
| { | ||||
| 	static const std::map<std::string, ELogLevel::ELogLevel> levelMap = boost::assign::map_list_of | ||||
| 			("trace", ELogLevel::TRACE) | ||||
| @@ -95,18 +98,15 @@ ELogLevel::ELogLevel CBasicLogConfigurator::getLogLevel(const std::string & leve | ||||
| 			("info", ELogLevel::INFO) | ||||
| 			("warn", ELogLevel::WARN) | ||||
| 			("error", ELogLevel::ERROR); | ||||
| 	 | ||||
| 	const auto & levelPair = levelMap.find(level); | ||||
| 	if(levelPair != levelMap.end()) | ||||
| 	{ | ||||
| 		return levelPair->second; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("Log level " + level + " unknown."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| EConsoleTextColor::EConsoleTextColor CBasicLogConfigurator::getConsoleColor(const std::string & colorName) const | ||||
| EConsoleTextColor::EConsoleTextColor CBasicLogConfigurator::getConsoleColor(const std::string & colorName) | ||||
| { | ||||
| 	static const std::map<std::string, EConsoleTextColor::EConsoleTextColor> colorMap = boost::assign::map_list_of | ||||
| 			("default", EConsoleTextColor::DEFAULT) | ||||
| @@ -117,13 +117,10 @@ EConsoleTextColor::EConsoleTextColor CBasicLogConfigurator::getConsoleColor(cons | ||||
| 			("white", EConsoleTextColor::WHITE) | ||||
| 			("gray", EConsoleTextColor::GRAY) | ||||
| 			("teal", EConsoleTextColor::TEAL); | ||||
|  | ||||
| 	const auto & colorPair = colorMap.find(colorName); | ||||
| 	if(colorPair != colorMap.end()) | ||||
| 	{ | ||||
| 		return colorPair->second; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		throw std::runtime_error("Color " + colorName + " unknown."); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -22,7 +22,8 @@ class JsonNode; | ||||
| class DLL_LINKAGE CBasicLogConfigurator | ||||
| { | ||||
| public: | ||||
| 	CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console); | ||||
| 	CBasicLogConfigurator(const boost::filesystem::path & file_path, CConsoleHandler * const console); | ||||
| 	CBasicLogConfigurator(boost::filesystem::path && file_path, CConsoleHandler * const console); | ||||
|  | ||||
| 	/// Configures the logging system by parsing the logging settings. It adds the console target and the file target to the global logger. | ||||
| 	/// Doesn't throw, but logs on success or fault. | ||||
| @@ -30,12 +31,15 @@ public: | ||||
|  | ||||
| 	/// Configures a default logging system by adding the console target and the file target to the global logger. | ||||
| 	void configureDefault(); | ||||
|  | ||||
| private: | ||||
| 	ELogLevel::ELogLevel getLogLevel(const std::string & level) const; | ||||
| 	EConsoleTextColor::EConsoleTextColor getConsoleColor(const std::string & colorName) const; | ||||
| 	// Gets ELogLevel enum from string. (Should be moved to CLogger as a separate function?) | ||||
| 	// Throws: std::runtime_error | ||||
| 	static ELogLevel::ELogLevel getLogLevel(const std::string & level); | ||||
| 	// Gets EConsoleTextColor enum from strings. (Should be moved to CLogger as a separate function?) | ||||
| 	// Throws: std::runtime_error | ||||
| 	static EConsoleTextColor::EConsoleTextColor getConsoleColor(const std::string & colorName); | ||||
|  | ||||
| 	std::string filePath; | ||||
| 	boost::filesystem::path file_path; | ||||
| 	CConsoleHandler * console; | ||||
| 	bool appendToLogFile; | ||||
| }; | ||||
|   | ||||
| @@ -596,7 +596,7 @@ int main(int argc, char** argv) | ||||
| 	#endif | ||||
|  | ||||
| 	console = new CConsoleHandler; | ||||
| 	CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Server_log.txt", console); | ||||
| 	CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() / "VCMI_Server_log.txt", console); | ||||
| 	logConfig.configureDefault(); | ||||
|  | ||||
| 	preinitDLL(console); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user