diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/ErrorHandling.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/ErrorHandling.h index b5100b25..847ae008 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/ErrorHandling.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/ErrorHandling.h @@ -68,16 +68,19 @@ freely, subject to the following restrictions: namespace PolyVox { + namespace Impl + { + std::ostream*& getTraceStreamInstance(); + std::ostream*& getDebugStreamInstance(); + std::ostream*& getInfoStreamInstance(); + std::ostream*& getWarningStreamInstance(); + std::ostream*& getErrorStreamInstance(); + std::ostream*& getFatalStreamInstance(); + } + /// Get a stream which will consume all input without outputting anything. std::ostream* getNullStream(void); - std::ostream& logTrace(void); - std::ostream& logDebug(void); - std::ostream& logInfo(void); - std::ostream& logWarning(void); - std::ostream& logError(void); - std::ostream& logFatal(void); - // These take pointers rather than references to emphasise that the // user needs to keep the target alive as long as PolyVox is writing data. void setTraceStream(std::ostream* pStream); @@ -86,6 +89,90 @@ namespace PolyVox void setWarningStream(std::ostream* pStream); void setErrorStream(std::ostream* pStream); void setFatalStream(std::ostream* pStream); + + // Automatically appending 'std::endl' as described here: http://stackoverflow.com/a/2179782 + struct logTrace + { + logTrace(){} + ~logTrace(){*(Impl::getTraceStreamInstance()) << std::endl;} + + template + logTrace &operator<<(const T &x) + { + *(Impl::getTraceStreamInstance()) << x; + return *this; + } + }; + + // Automatically appending 'std::endl' as described here: http://stackoverflow.com/a/2179782 + struct logDebug + { + logDebug(){} + ~logDebug(){*(Impl::getDebugStreamInstance()) << std::endl;} + + template + logDebug &operator<<(const T &x) + { + *(Impl::getDebugStreamInstance()) << x; + return *this; + } + }; + + // Automatically appending 'std::endl' as described here: http://stackoverflow.com/a/2179782 + struct logInfo + { + logInfo(){} + ~logInfo(){*(Impl::getInfoStreamInstance()) << std::endl;} + + template + logInfo &operator<<(const T &x) + { + *(Impl::getInfoStreamInstance()) << x; + return *this; + } + }; + + // Automatically appending 'std::endl' as described here: http://stackoverflow.com/a/2179782 + struct logWarning + { + logWarning(){} + ~logWarning(){*(Impl::getWarningStreamInstance()) << std::endl;} + + template + logWarning &operator<<(const T &x) + { + *(Impl::getWarningStreamInstance()) << x; + return *this; + } + }; + + // Automatically appending 'std::endl' as described here: http://stackoverflow.com/a/2179782 + struct logError + { + logError(){} + ~logError(){*(Impl::getErrorStreamInstance()) << std::endl;} + + template + logError &operator<<(const T &x) + { + *(Impl::getErrorStreamInstance()) << x; + return *this; + } + }; + + // Automatically appending 'std::endl' as described here: http://stackoverflow.com/a/2179782 + struct logFatal + { + logFatal(){} + ~logFatal(){*(Impl::getFatalStreamInstance()) << std::endl;} + + template + logFatal &operator<<(const T &x) + { + *(Impl::getFatalStreamInstance()) << x; + return *this; + } + }; } /* @@ -108,12 +195,13 @@ namespace PolyVox { \ if (!(condition)) \ { \ - PolyVox::logFatal() << std::endl << std::endl; \ - PolyVox::logFatal() << " PolyVox Assertion Failed!" << std::endl; \ - PolyVox::logFatal() << " =========================" << std::endl; \ - PolyVox::logFatal() << " Condition: " << #condition << std::endl; \ - PolyVox::logFatal() << " Message: " << (message) << std::endl; \ - PolyVox::logFatal() << " Location: " << "Line " << __LINE__ << " of " << __FILE__ << std::endl << std::endl; \ + PolyVox::logFatal() << "\n"; \ + PolyVox::logFatal() << " PolyVox Assertion Failed!"; \ + PolyVox::logFatal() << " ========================="; \ + PolyVox::logFatal() << " Condition: " << #condition; \ + PolyVox::logFatal() << " Message: " << (message); \ + PolyVox::logFatal() << " Location: " << "Line " << __LINE__ << " of " << __FILE__; \ + PolyVox::logFatal() << "\n"; \ POLYVOX_HALT(); \ } \ } while(0) \ diff --git a/library/PolyVoxCore/source/Impl/ErrorHandling.cpp b/library/PolyVoxCore/source/Impl/ErrorHandling.cpp index a3c2dedc..baeae6be 100644 --- a/library/PolyVoxCore/source/Impl/ErrorHandling.cpp +++ b/library/PolyVoxCore/source/Impl/ErrorHandling.cpp @@ -36,89 +36,69 @@ namespace PolyVox return &s_NullStream; } - // Trace stream for logging - std::ostream*& getTraceStreamInstance() + // These create the global stream instances, created on demand. + namespace Impl { - static std::ostream* s_pTraceStream = getNullStream(); - return s_pTraceStream; + std::ostream*& getTraceStreamInstance() + { + static std::ostream* s_pTraceStream = getNullStream(); + return s_pTraceStream; + } + + std::ostream*& getDebugStreamInstance() + { + static std::ostream* s_pDebugStream = getNullStream(); + return s_pDebugStream; + } + + std::ostream*& getInfoStreamInstance() + { + static std::ostream* s_pInfoStream = &(std::cout); + return s_pInfoStream; + } + + std::ostream*& getWarningStreamInstance() + { + static std::ostream* s_pWarningStream = &(std::cerr); + return s_pWarningStream; + } + + std::ostream*& getErrorStreamInstance() + { + static std::ostream* s_pErrorStream = &(std::cerr); + return s_pErrorStream; + } + + std::ostream*& getFatalStreamInstance() + { + static std::ostream* s_pFatalStream = &(std::cerr); + return s_pFatalStream; + } } void setTraceStream(std::ostream* pStream) { - getTraceStreamInstance() = pStream; - } - - std::ostream& logTrace(void) - { - return *(getTraceStreamInstance()); - } - - // Debug stream for logging - std::ostream*& getDebugStreamInstance() - { - static std::ostream* s_pDebugStream = getNullStream(); - return s_pDebugStream; + Impl::getTraceStreamInstance() = pStream; } void setDebugStream(std::ostream* pStream) { - getDebugStreamInstance() = pStream; - } - - std::ostream& logDebug(void) - { - return *(getDebugStreamInstance()); - } - - // Info stream for logging - std::ostream*& getInfoStreamInstance() - { - static std::ostream* s_pInfoStream = &(std::cout); - return s_pInfoStream; + Impl::getDebugStreamInstance() = pStream; } void setInfoStream(std::ostream* pStream) { - getInfoStreamInstance() = pStream; - } - - std::ostream& logInfo(void) - { - return *(getInfoStreamInstance()); - } - - // Warning stream for logging - std::ostream*& getWarningStreamInstance() - { - static std::ostream* s_pWarningStream = &(std::cerr); - return s_pWarningStream; + Impl::getInfoStreamInstance() = pStream; } void setWarningStream(std::ostream* pStream) { - getWarningStreamInstance() = pStream; - } - - std::ostream& logWarning(void) - { - return *(getWarningStreamInstance()); - } - - // Error stream for logging - std::ostream*& getErrorStreamInstance() - { - static std::ostream* s_pErrorStream = &(std::cerr); - return s_pErrorStream; + Impl::getWarningStreamInstance() = pStream; } void setErrorStream(std::ostream* pStream) { - getErrorStreamInstance() = pStream; - } - - std::ostream& logError(void) - { - return *(getErrorStreamInstance()); + Impl::getErrorStreamInstance() = pStream; } // Fatal stream for logging @@ -133,35 +113,30 @@ namespace PolyVox getFatalStreamInstance() = pStream; } - std::ostream& logFatal(void) - { - return *(getFatalStreamInstance()); - } - #ifndef POLYVOX_THROW_ENABLED void defaultThrowHandler(std::exception& e, const char* file, int line) { - logFatal() << std::endl << std::endl; \ - logFatal() << " PolyVox exception thrown!" << std::endl; \ - logFatal() << " =========================" << std::endl; \ - logFatal() << " PolyVox has tried to throw an exception but it was built without support" << std::endl; \ - logFatal() << " for exceptions. In this scenario PolyVox will call a 'throw handler'" << std::endl; \ - logFatal() << " and this message is being printed by the default throw handler." << std::endl << std::endl; \ - - logFatal() << " If you don't want to enable exceptions then you should try to determine why" << std::endl; \ - logFatal() << " this exception was thrown and make sure it doesn't happen again. If it was" << std::endl; \ - logFatal() << " due to something like an invalid argument to a function then you should be" << std::endl; \ - logFatal() << " able to fix it quite easily by validating parameters as appropriate. More" << std::endl; \ - logFatal() << " complex exception scenarios (out of memory, etc) might be harder to fix and" << std::endl; \ - logFatal() << " you should replace this default handler with something which is more" << std::endl; \ - logFatal() << " meaningful to your users." << std::endl << std::endl; \ - - logFatal() << " Exception details" << std::endl; \ - logFatal() << " -----------------" << std::endl; \ - logFatal() << " Line: " << line << std::endl; \ - logFatal() << " File: " << file << std::endl; \ - logFatal() << " Message: " << e.what() << std::endl << std::endl; \ - + logFatal() << "\n"; \ + logFatal() << " PolyVox exception thrown!"; \ + logFatal() << " ========================="; \ + logFatal() << " PolyVox has tried to throw an exception but it was built without support"; \ + logFatal() << " for exceptions. In this scenario PolyVox will call a 'throw handler'"; \ + logFatal() << " and this message is being printed by the default throw handler."; \ + logFatal() << "\n"; \ + logFatal() << " If you don't want to enable exceptions then you should try to determine why"; \ + logFatal() << " this exception was thrown and make sure it doesn't happen again. If it was"; \ + logFatal() << " due to something like an invalid argument to a function then you should be"; \ + logFatal() << " able to fix it quite easily by validating parameters as appropriate. More"; \ + logFatal() << " complex exception scenarios (out of memory, etc) might be harder to fix and"; \ + logFatal() << " you should replace this default handler with something which is more"; \ + logFatal() << " meaningful to your users."; \ + logFatal() << "\n"; \ + logFatal() << " Exception details"; \ + logFatal() << " -----------------"; \ + logFatal() << " Line: " << line; \ + logFatal() << " File: " << file; \ + logFatal() << " Message: " << e.what(); \ + logFatal() << "\n"; \ POLYVOX_HALT(); \ }