bool ResourceCompiler::Check_File_Timestamp(std::string path) { Platform* platform = Platform::Get(); std::string input_directory = platform->Extract_Directory(path); std::string input_filename = platform->Extract_Filename(path); std::string output_directory= Directory_To_Output_Directory(input_directory); std::string output_path = platform->Join_Path(output_directory, input_filename + ".timestamp"); // If input file dosen't exist, we can't compile. if (!platform->Is_File(path.c_str())) { return false; } // If output file dosen't exist, we need to compile. if (!platform->Is_File(output_path.c_str())) { return true; } // Check timestamps. u64 input_timestamp = StreamFactory::Get_Last_Modified(path.c_str()); u64 output_timestamp = StreamFactory::Get_Last_Modified(output_path.c_str()); return input_timestamp > output_timestamp; }
bool AtlasResourceCompiler::Should_Compile() { Platform* platform = Platform::Get(); // If input dosen't exist, the wtf. if (!platform->Is_File(m_input_path.c_str())) { DBG_ASSERT_STR(false, "Attempt to compile non-existing resource '%s'.", m_input_path.c_str()); return false; } // If input has been modified, compile is definitely required. if (Check_File_Timestamp(m_input_path)) { return true; } // Read in the XML, so we can determine if there are any other dependent files. if (!Load_Config()) { return false; } // Check dependent files. for (std::vector<std::string>::iterator iter = m_dependent_files.begin(); iter != m_dependent_files.end(); iter++) { std::string& path = *iter; if (Check_File_Timestamp(path.c_str())) { return true; } } return false; }
LONG WINAPI ExceptionHandler(struct _EXCEPTION_POINTERS *exceptionInfo) { Platform* platform = Platform::Get(); std::string dump_dir = platform->Get_Working_Dir() + "\\.crashes"; std::string dump_path = dump_dir + "\\00000000.dmp"; DBG_LOG("~~~~~~~~~~~~ UNHANDLED EXCEPTION OCCURRED ~~~~~~~~~~~"); // Make sure dump file exists. if (!platform->Is_Directory(dump_dir.c_str())) { DBG_LOG("Attempt to create dump folder ..."); DBG_LOG("Path: %s", dump_dir.c_str()); if (!platform->Create_Directory(dump_dir.c_str(), true)) { DBG_LOG("Failed to create dump folder. Aborting."); exit(0); } } // Find somewhere to dump the file. unsigned int index = 0; do { dump_path = dump_dir + "\\" + StringHelper::To_String(index) + ".dmp"; index++; } while (platform->Is_File(dump_path.c_str())); // Dump the file! DBG_LOG("Attempt to create dump file ..."); DBG_LOG("Path: %s", dump_path.c_str()); HANDLE fileHandle = CreateFileA(dump_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (fileHandle == NULL) { DBG_LOG("Failed to create open dump file. Aborting."); exit(0); } // Duuuuuuuuump. HANDLE process = GetCurrentProcess(); MINIDUMP_EXCEPTION_INFORMATION exceptionParam; exceptionParam.ThreadId = GetCurrentThreadId(); exceptionParam.ExceptionPointers = exceptionInfo; exceptionParam.ClientPointers = FALSE; EnterCriticalSection(&g_dbghelp_critical_section); BOOL result = MiniDumpWriteDump(process, GetCurrentProcessId(), fileHandle, MiniDumpNormal, exceptionInfo == NULL ? NULL : &exceptionParam, NULL, NULL); LeaveCriticalSection(&g_dbghelp_critical_section); // Close the dump file handle. CloseHandle(fileHandle); // Check a file was created. if (result == FALSE) { u32 ec = GetLastError(); DBG_LOG("Failed to create dump file, GetLastError()=%i (%s)", ec, FormatSystemError(ec).c_str()); } else { DBG_LOG("Success!"); } // Dump stack trace. DBG_LOG(""); DBG_LOG("Call Stack:"); StackFrame frames[256]; int frameCount = platform->Get_Stack_Trace(frames, 256, exceptionInfo); for (int i = 0; i < frameCount; i++) { StackFrame& frame = frames[i]; platform->Resolve_Stack_Frame_Info(frame); DBG_LOG("[%i] %s (%i): %s", i, frame.File, frame.Line, frame.Name); } DBG_LOG(""); // Bail the f**k out. // We use this to long jump back to the point after PlatformMain is called // so we can deinitialize everything. if (GetCurrentThreadId() == g_main_thread_id) { DBG_LOG("Attempting recovery through longjmp ..."); longjmp(g_error_recovery_longjmp, 1); } return EXCEPTION_EXECUTE_HANDLER; }