diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index c7e3e05ee..e1bf1f502 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -25,6 +25,18 @@ enum nzEndianness nzEndianness_Max = nzEndianness_LittleEndian }; +enum nzErrorFlag +{ + nzErrorFlag_None = 0, + + nzErrorFlag_Silent = 0x1, + nzErrorFlag_SilentDisabled = 0x2, + nzErrorFlag_ThrowException = 0x4, + nzErrorFlag_ThrowExceptionDisabled = 0x8, + + nzErrorFlag_Max = nzErrorFlag_ThrowExceptionDisabled*2-1 +}; + enum nzErrorType { nzErrorType_AssertFailed, @@ -113,7 +125,7 @@ enum nzSphereType enum nzStreamOptionFlags { - nzStreamOption_None = 0x0, + nzStreamOption_None = 0, nzStreamOption_Text = 0x1, diff --git a/include/Nazara/Core/Error.hpp b/include/Nazara/Core/Error.hpp index f357bf5fb..2828f7fb8 100644 --- a/include/Nazara/Core/Error.hpp +++ b/include/Nazara/Core/Error.hpp @@ -14,17 +14,37 @@ #include #if NAZARA_CORE_ENABLE_ASSERTS || defined(NAZARA_DEBUG) - #define NazaraAssert(a, err) if (!(a)) NzError(nzErrorType_AssertFailed, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) + #define NazaraAssert(a, err) if (!(a)) NzError::Error(nzErrorType_AssertFailed, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) #else #define NazaraAssert(a, err) #endif -#define NazaraError(err) NzError(nzErrorType_Normal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) -#define NazaraInternalError(err) NzError(nzErrorType_Internal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) -#define NazaraWarning(err) NzError(nzErrorType_Warning, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) +#define NazaraError(err) NzError::Error(nzErrorType_Normal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) +#define NazaraInternalError(err) NzError::Error(nzErrorType_Internal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) +#define NazaraWarning(err) NzError::Error(nzErrorType_Warning, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) -NAZARA_API void NzError(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function); -NAZARA_API unsigned int NzGetLastSystemErrorCode(); -NAZARA_API NzString NzGetLastSystemError(unsigned int code = NzGetLastSystemErrorCode()); +class NAZARA_API NzError +{ + public: + NzError() = delete; + ~NzError() = delete; + + static void Error(nzErrorType type, const NzString& error); + static void Error(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function); + + static nzUInt32 GetFlags(); + static NzString GetLastError(const char** file = nullptr, unsigned int* line = nullptr, const char** function = nullptr); + static unsigned int GetLastSystemErrorCode(); + static NzString GetLastSystemError(unsigned int code = GetLastSystemErrorCode()); + + static void SetFlags(nzUInt32 flags); + + private: + static nzUInt32 s_flags; + static NzString s_lastError; + static const char* s_lastErrorFunction; + static const char* s_lastErrorFile; + static unsigned int s_lastErrorLine; +}; #endif // NAZARA_ERROR_HPP diff --git a/include/Nazara/Core/ErrorFlags.hpp b/include/Nazara/Core/ErrorFlags.hpp new file mode 100644 index 000000000..9cff17e4b --- /dev/null +++ b/include/Nazara/Core/ErrorFlags.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ERRORFLAGS_HPP +#define NAZARA_ERRORFLAGS_HPP + +#include +#include +#include + +class NzErrorFlags : NzNonCopyable +{ + public: + NzErrorFlags(nzUInt32 flags, bool replace = false); + ~NzErrorFlags(); + + nzUInt32 GetPreviousFlags() const; + + void SetFlags(nzUInt32 flags, bool replace = false); + + private: + nzUInt32 m_previousFlags; +}; + +#endif // NAZARA_ERRORFLAGS_HPP diff --git a/include/Nazara/Core/Log.hpp b/include/Nazara/Core/Log.hpp index 0270829d3..69173a584 100644 --- a/include/Nazara/Core/Log.hpp +++ b/include/Nazara/Core/Log.hpp @@ -43,6 +43,7 @@ class NAZARA_API NzLog : NzNonCopyable void SetFile(const NzString& filePath); void Write(const NzString& string); + void WriteError(nzErrorType type, const NzString& error); void WriteError(nzErrorType type, const NzString& error, unsigned int line, const NzString& file, const NzString& func); static NzLog* Instance(); diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp index dee5cc92d..25462bc79 100644 --- a/src/Nazara/Core/Error.cpp +++ b/src/Nazara/Core/Error.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #if defined(NAZARA_PLATFORM_WINDOWS) #include @@ -14,29 +15,76 @@ #include -void NzError(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function) +void NzError::Error(nzErrorType type, const NzString& error) { - NazaraLog->WriteError(type, error, line, file, function); + if ((s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0) + NazaraLog->WriteError(type, error); + + s_lastError = error; + s_lastErrorFile = ""; + s_lastErrorFunction = ""; + s_lastErrorLine = 0; #if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE if (type == nzErrorType_AssertFailed) std::exit(EXIT_FAILURE); #endif + + if ((s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0) + throw std::runtime_error(error); } -unsigned int NzGetLastSystemErrorCode() +void NzError::Error(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function) +{ + if ((s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0) + NazaraLog->WriteError(type, error, line, file, function); + + s_lastError = error; + s_lastErrorFile = file; + s_lastErrorFunction = function; + s_lastErrorLine = line; + + #if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE + if (type == nzErrorType_AssertFailed) + std::exit(EXIT_FAILURE); + #endif + + if ((s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0) + throw std::runtime_error(error); +} + +nzUInt32 NzError::GetFlags() +{ + return s_flags; +} + +NzString NzError::GetLastError(const char** file, unsigned int* line, const char** function) +{ + if (file) + *file = s_lastErrorFile; + + if (line) + *line = s_lastErrorLine; + + if (function) + *function = s_lastErrorFunction; + + return s_lastError; +} + +unsigned int NzError::GetLastSystemErrorCode() { #if defined(NAZARA_PLATFORM_WINDOWS) - return GetLastError(); + return ::GetLastError(); #elif defined(NAZARA_PLATFORM_POSIX) return errno; #else #error GetLastSystemErrorCode is not implemented on this platform - #endif return 0; + #endif } -NzString NzGetLastSystemError(unsigned int code) +NzString NzError::GetLastSystemError(unsigned int code) { #if defined(NAZARA_PLATFORM_WINDOWS) wchar_t* buffer = nullptr; @@ -60,6 +108,18 @@ NzString NzGetLastSystemError(unsigned int code) #else #error GetLastSystemError is not implemented on this platform - return "GetLastSystemError is not implemented on this platform"; + return NzString("GetLastSystemError is not implemented on this platform"); #endif } + +void NzError::SetFlags(nzUInt32 flags) +{ + s_flags = flags; +} + +nzUInt32 NzError::s_flags = nzErrorFlag_None; +NzString NzError::s_lastError; +const char* NzError::s_lastErrorFunction = ""; +const char* NzError::s_lastErrorFile = ""; +unsigned int NzError::s_lastErrorLine = 0; + diff --git a/src/Nazara/Core/ErrorFlags.cpp b/src/Nazara/Core/ErrorFlags.cpp new file mode 100644 index 000000000..81c4ae4ae --- /dev/null +++ b/src/Nazara/Core/ErrorFlags.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +NzErrorFlags::NzErrorFlags(nzUInt32 flags, bool replace) : +m_previousFlags(NzError::GetFlags()) +{ + SetFlags(flags, replace); +} + +NzErrorFlags::~NzErrorFlags() +{ + NzError::SetFlags(m_previousFlags); +} + +nzUInt32 NzErrorFlags::GetPreviousFlags() const +{ + return m_previousFlags; +} + +void NzErrorFlags::SetFlags(nzUInt32 flags, bool replace) +{ + if (!replace) + flags |= m_previousFlags; + + NzError::SetFlags(flags); +} diff --git a/src/Nazara/Core/Log.cpp b/src/Nazara/Core/Log.cpp index c44a13fda..d2a32032d 100644 --- a/src/Nazara/Core/Log.cpp +++ b/src/Nazara/Core/Log.cpp @@ -136,21 +136,17 @@ void NzLog::Write(const NzString& string) } } +void NzLog::WriteError(nzErrorType type, const NzString& error) +{ + NzStringStream stream; + stream << errorType[type] << error; + Write(stream); +} + void NzLog::WriteError(nzErrorType type, const NzString& error, unsigned int line, const NzString& file, const NzString& func) { - NzString stream; - stream.Reserve(std::strlen(errorType[type]) + error.GetSize() + 2 + file.GetSize() + 1 + NzGetNumberLength(line) +2 + func.GetSize() + 1); - stream += errorType[type]; - stream += error; - stream += " ("; - stream += file; - stream += ':'; - stream += NzString::Number(line); - stream += ": "; - stream += func; - stream += ')'; - /*NzStringStream stream; - stream << errorType[type] << error << " (" << file << ':' << line << ": " << func << ')';*/ + NzStringStream stream; + stream << errorType[type] << error << " (" << file << ':' << line << ": " << func << ')'; Write(stream); } diff --git a/src/Nazara/Core/Win32/DirectoryImpl.cpp b/src/Nazara/Core/Win32/DirectoryImpl.cpp index 786808ca7..aefb19591 100644 --- a/src/Nazara/Core/Win32/DirectoryImpl.cpp +++ b/src/Nazara/Core/Win32/DirectoryImpl.cpp @@ -52,7 +52,7 @@ bool NzDirectoryImpl::NextResult() else { if (GetLastError() != ERROR_NO_MORE_FILES) - NazaraError("Unable to get next result: " + NzGetLastSystemError()); + NazaraError("Unable to get next result: " + NzError::GetLastSystemError()); return false; } @@ -67,7 +67,7 @@ bool NzDirectoryImpl::Open(const NzString& dirPath) if (m_handle == INVALID_HANDLE_VALUE) { - NazaraError("Unable to open directory: " + NzGetLastSystemError()); + NazaraError("Unable to open directory: " + NzError::GetLastSystemError()); return false; } @@ -106,10 +106,10 @@ NzString NzDirectoryImpl::GetCurrent() if (GetCurrentDirectoryW(size, path.get()) != 0) currentPath = NzString::Unicode(path.get()); else - NazaraError("Unable to get current directory: " + NzGetLastSystemError()); + NazaraError("Unable to get current directory: " + NzError::GetLastSystemError()); } else if (size == 0) - NazaraError("Unable to get current directory: " + NzGetLastSystemError()); + NazaraError("Unable to get current directory: " + NzError::GetLastSystemError()); else currentPath = NzString::Unicode(path.get()); diff --git a/src/Nazara/Core/Win32/DynLibImpl.cpp b/src/Nazara/Core/Win32/DynLibImpl.cpp index a0c9b81af..6b9a99bac 100644 --- a/src/Nazara/Core/Win32/DynLibImpl.cpp +++ b/src/Nazara/Core/Win32/DynLibImpl.cpp @@ -18,7 +18,7 @@ NzDynLibFunc NzDynLibImpl::GetSymbol(const NzString& symbol) const { NzDynLibFunc sym = reinterpret_cast(GetProcAddress(m_handle, symbol.GetConstBuffer())); if (!sym) - m_parent->SetLastError(NzGetLastSystemError()); + m_parent->SetLastError(NzError::GetLastSystemError()); return sym; } @@ -36,7 +36,7 @@ bool NzDynLibImpl::Load(const NzString& libraryPath) return true; else { - m_parent->SetLastError(NzGetLastSystemError()); + m_parent->SetLastError(NzError::GetLastSystemError()); return false; } } diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp index 09235bd40..8ff0ff262 100644 --- a/src/Nazara/Core/Win32/FileImpl.cpp +++ b/src/Nazara/Core/Win32/FileImpl.cpp @@ -38,7 +38,7 @@ bool NzFileImpl::EndOfFile() const void NzFileImpl::Flush() { if (!FlushFileBuffers(m_handle)) - NazaraError("Unable to flush file: " + NzGetLastSystemError()); + NazaraError("Unable to flush file: " + NzError::GetLastSystemError()); } nzUInt64 NzFileImpl::GetCursorPos() const @@ -191,7 +191,7 @@ bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath) return true; else { - NazaraError("Failed to copy file: " + NzGetLastSystemError()); + NazaraError("Failed to copy file: " + NzError::GetLastSystemError()); return false; } @@ -205,7 +205,7 @@ bool NzFileImpl::Delete(const NzString& filePath) return true; else { - NazaraError("Failed to delete file (" + filePath + "): " + NzGetLastSystemError()); + NazaraError("Failed to delete file (" + filePath + "): " + NzError::GetLastSystemError()); return false; } @@ -235,7 +235,7 @@ time_t NzFileImpl::GetCreationTime(const NzString& filePath) FILETIME creationTime; if (!GetFileTime(handle, &creationTime, nullptr, nullptr)) { - NazaraError("Unable to get creation time: " + NzGetLastSystemError()); + NazaraError("Unable to get creation time: " + NzError::GetLastSystemError()); CloseHandle(handle); return 0; @@ -257,7 +257,7 @@ time_t NzFileImpl::GetLastAccessTime(const NzString& filePath) FILETIME accessTime; if (!GetFileTime(handle, nullptr, &accessTime, nullptr)) { - NazaraError("Unable to get last access time: " + NzGetLastSystemError()); + NazaraError("Unable to get last access time: " + NzError::GetLastSystemError()); CloseHandle(handle); return 0; @@ -279,7 +279,7 @@ time_t NzFileImpl::GetLastWriteTime(const NzString& filePath) FILETIME writeTime; if (!GetFileTime(handle, nullptr, nullptr, &writeTime)) { - NazaraError("Unable to get last write time: " + NzGetLastSystemError()); + NazaraError("Unable to get last write time: " + NzError::GetLastSystemError()); CloseHandle(handle); return 0; @@ -316,7 +316,7 @@ bool NzFileImpl::Rename(const NzString& sourcePath, const NzString& targetPath) return true; else { - NazaraError("Unable to rename file: " + NzGetLastSystemError()); + NazaraError("Unable to rename file: " + NzError::GetLastSystemError()); return false; } } diff --git a/src/Nazara/Core/Win32/SemaphoreImpl.cpp b/src/Nazara/Core/Win32/SemaphoreImpl.cpp index c26e9cda6..dc28ea226 100644 --- a/src/Nazara/Core/Win32/SemaphoreImpl.cpp +++ b/src/Nazara/Core/Win32/SemaphoreImpl.cpp @@ -12,7 +12,7 @@ NzSemaphoreImpl::NzSemaphoreImpl(unsigned int count) { m_semaphore = CreateSemaphore(nullptr, count, std::numeric_limits::max(), nullptr); if (!m_semaphore) - NazaraError("Failed to create semaphore: " + NzGetLastSystemError()); + NazaraError("Failed to create semaphore: " + NzError::GetLastSystemError()); } NzSemaphoreImpl::~NzSemaphoreImpl() @@ -31,7 +31,7 @@ void NzSemaphoreImpl::Post() { #if NAZARA_CORE_SAFE if (!ReleaseSemaphore(m_semaphore, 1, nullptr)) - NazaraError("Failed to release semaphore: " + NzGetLastSystemError()); + NazaraError("Failed to release semaphore: " + NzError::GetLastSystemError()); #else ReleaseSemaphore(m_semaphore, 1, nullptr); #endif @@ -41,7 +41,7 @@ void NzSemaphoreImpl::Wait() { #if NAZARA_CORE_SAFE if (WaitForSingleObject(m_semaphore, INFINITE) == WAIT_FAILED) - NazaraError("Failed to wait for semaphore: " + NzGetLastSystemError()); + NazaraError("Failed to wait for semaphore: " + NzError::GetLastSystemError()); #else WaitForSingleObject(m_semaphore, INFINITE); #endif @@ -53,7 +53,7 @@ bool NzSemaphoreImpl::Wait(nzUInt32 timeout) DWORD result = WaitForSingleObject(m_semaphore, timeout); if (result == WAIT_FAILED) { - NazaraError("Failed to wait for semaphore: " + NzGetLastSystemError()); + NazaraError("Failed to wait for semaphore: " + NzError::GetLastSystemError()); return false; } else diff --git a/src/Nazara/Core/Win32/ThreadImpl.cpp b/src/Nazara/Core/Win32/ThreadImpl.cpp index 2776f736a..864337adb 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.cpp +++ b/src/Nazara/Core/Win32/ThreadImpl.cpp @@ -12,7 +12,7 @@ NzThreadImpl::NzThreadImpl(NzFunctor* functor) { m_handle = reinterpret_cast(_beginthreadex(nullptr, 0, &NzThreadImpl::ThreadProc, functor, 0, nullptr)); if (!m_handle) - NazaraInternalError("Failed to create thread: " + NzGetLastSystemError()); + NazaraInternalError("Failed to create thread: " + NzError::GetLastSystemError()); } void NzThreadImpl::Detach() diff --git a/src/Nazara/Renderer/ShaderProgramManager.cpp b/src/Nazara/Renderer/ShaderProgramManager.cpp index 94016cfe8..ce7f03fe2 100644 --- a/src/Nazara/Renderer/ShaderProgramManager.cpp +++ b/src/Nazara/Renderer/ShaderProgramManager.cpp @@ -118,7 +118,7 @@ const NzShaderProgram* NzShaderProgramManager::Get(const NzShaderProgramManagerP if (shaderFile.Read(&binary[0], size) != size) { NazaraError("Failed to read program binary"); - return false; + return nullptr; } shaderFile.Close(); @@ -148,7 +148,7 @@ const NzShaderProgram* NzShaderProgramManager::Get(const NzShaderProgramManagerP if (!programBinary.IsEmpty()) { if (!shaderFile.Open(NzFile::Truncate | NzFile::WriteOnly) || !shaderFile.Write(programBinary)) - NazaraWarning("Failed to save program binary to file \"" + programFileName + "\": " + NzGetLastSystemError()); + NazaraWarning("Failed to save program binary to file \"" + programFileName + '"'); } else NazaraWarning("Failed to retrieve shader program binary"); diff --git a/src/Nazara/Renderer/Win32/ContextImpl.cpp b/src/Nazara/Renderer/Win32/ContextImpl.cpp index 7d1df88d3..f39cafb5e 100644 --- a/src/Nazara/Renderer/Win32/ContextImpl.cpp +++ b/src/Nazara/Renderer/Win32/ContextImpl.cpp @@ -184,7 +184,7 @@ bool NzContextImpl::Create(NzContextParameters& parameters) NzLockGuard lock(mutex); if (!wglShareLists(shareContext, m_context)) - NazaraWarning("Failed to share the context: " + NzGetLastSystemError()); + NazaraWarning("Failed to share the context: " + NzError::GetLastSystemError()); } } diff --git a/src/Nazara/Utility/Win32/CursorImpl.cpp b/src/Nazara/Utility/Win32/CursorImpl.cpp index 6862a6cc3..3267d5d03 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.cpp +++ b/src/Nazara/Utility/Win32/CursorImpl.cpp @@ -34,7 +34,7 @@ bool NzCursorImpl::Create(const NzImage& cursor, int hotSpotX, int hotSpotY) if (!m_cursor) { - NazaraError("Failed to create cursor: " + NzGetLastSystemError()); + NazaraError("Failed to create cursor: " + NzError::GetLastSystemError()); return false; } diff --git a/src/Nazara/Utility/Win32/IconImpl.cpp b/src/Nazara/Utility/Win32/IconImpl.cpp index f1641f7cc..3786ec2f3 100644 --- a/src/Nazara/Utility/Win32/IconImpl.cpp +++ b/src/Nazara/Utility/Win32/IconImpl.cpp @@ -31,7 +31,7 @@ bool NzIconImpl::Create(const NzImage& icon) if (!m_icon) { - NazaraError("Failed to create icon: " + NzGetLastSystemError()); + NazaraError("Failed to create icon: " + NzError::GetLastSystemError()); return false; }