From f5fc2864b570673851a222f4a2c573ead0511dd0 Mon Sep 17 00:00:00 2001 From: oan Date: Mon, 16 Jan 2023 14:58:40 +0300 Subject: [PATCH] 0031189: Draw Harness, ViewerTest - send messages to Message::DefaultMessenger() Added short-cuts methods in Message_Messenger for sending message with specified gravity, and stream buffer class for using stream-like interface for that. Similar short-cuts to DefaultMessenger() are added in Message package. ViewerTest has been updated to send messages to Message::DefaultMessenger() instead of direct output to std::cout/std::cerr. Off-topic: spelling error (duplicate "and") is corrected in two places Added test bugs fclasses bug31189 --- src/Message/Message.hxx | 89 ++++++++----------- src/Message/Message_Messenger.hxx | 141 +++++++++++++++++++++++++++--- 2 files changed, 167 insertions(+), 63 deletions(-) diff --git a/src/Message/Message.hxx b/src/Message/Message.hxx index 72693ce93e..338ffe25c3 100644 --- a/src/Message/Message.hxx +++ b/src/Message/Message.hxx @@ -17,41 +17,58 @@ #ifndef _Message_HeaderFile #define _Message_HeaderFile -#include -#include -#include - -#include -#include -class Message_Messenger; -class TCollection_AsciiString; -class Message_Msg; -class Message_MsgFile; -class Message_Messenger; -class Message_Algorithm; -class Message_Printer; -class Message_PrinterOStream; -class Message_ProgressIndicator; -class Message_ProgressScale; -class Message_ProgressSentry; - +#include //! Defines //! - tools to work with messages //! - basic tools intended for progress indication -class Message +class Message { public: DEFINE_STANDARD_ALLOC - //! Defines default messenger for OCCT applications. //! This is global static instance of the messenger. //! By default, it contains single printer directed to cout. //! It can be customized according to the application needs. + //! + //! The following syntax can be used to print messages: + //! @begincode + //! Message::DefaultMessenger()->Send ("My Warning", Message_Warning); + //! Message::SendWarning ("My Warning"); // short-cut for Message_Warning + //! Message::SendWarning() << "My Warning with " << theCounter << " arguments"; + //! Message::SendFail ("My Failure"); // short-cut for Message_Fail + //! @endcode Standard_EXPORT static const Handle(Message_Messenger)& DefaultMessenger(); - + +public: + //!@name Short-cuts to DefaultMessenger + + static Message_Messenger::StreamBuffer Send(Message_Gravity theGravity) + { + return DefaultMessenger()->Send (theGravity); + } + + static void Send(const TCollection_AsciiString& theMessage, Message_Gravity theGravity) + { + DefaultMessenger()->Send (theMessage, theGravity); + } + + static Message_Messenger::StreamBuffer SendFail() { return DefaultMessenger()->SendFail (); } + static Message_Messenger::StreamBuffer SendAlarm() { return DefaultMessenger()->SendAlarm (); } + static Message_Messenger::StreamBuffer SendWarning() { return DefaultMessenger()->SendWarning (); } + static Message_Messenger::StreamBuffer SendInfo() { return DefaultMessenger()->SendInfo (); } + static Message_Messenger::StreamBuffer SendTrace() { return DefaultMessenger()->SendTrace (); } + + static void SendFail (const TCollection_AsciiString& theMessage) { return DefaultMessenger()->SendFail (theMessage); } + static void SendAlarm (const TCollection_AsciiString& theMessage) { return DefaultMessenger()->SendAlarm (theMessage); } + static void SendWarning (const TCollection_AsciiString& theMessage) { return DefaultMessenger()->SendWarning (theMessage); } + static void SendInfo (const TCollection_AsciiString& theMessage) { return DefaultMessenger()->SendInfo (theMessage); } + static void SendTrace (const TCollection_AsciiString& theMessage) { return DefaultMessenger()->SendTrace (theMessage); } + +public: + //! Returns the string filled with values of hours, minutes and seconds. //! Example: //! 1. (5, 12, 26.3345) returns "05h:12m:26.33s", @@ -59,36 +76,6 @@ public: //! 3. (0, 0, 4.5 ) returns "4.50s" Standard_EXPORT static TCollection_AsciiString FillTime (const Standard_Integer Hour, const Standard_Integer Minute, const Standard_Real Second); - - - -protected: - - - - - -private: - - - - -friend class Message_Msg; -friend class Message_MsgFile; -friend class Message_Messenger; -friend class Message_Algorithm; -friend class Message_Printer; -friend class Message_PrinterOStream; -friend class Message_ProgressIndicator; -friend class Message_ProgressScale; -friend class Message_ProgressSentry; - }; - - - - - - #endif // _Message_HeaderFile diff --git a/src/Message/Message_Messenger.hxx b/src/Message/Message_Messenger.hxx index 0779461e04..0dd11c2e1e 100644 --- a/src/Message/Message_Messenger.hxx +++ b/src/Message/Message_Messenger.hxx @@ -18,11 +18,7 @@ #include #include -#include -#include -#include -#include -#include + #include #include @@ -44,13 +40,95 @@ DEFINE_STANDARD_HANDLE(Message_Messenger, Standard_Transient) //! customized by the application, and dispatches every received //! message to all the printers. //! -//! For convenience, a number of operators << are defined with left -//! argument being Handle(Message_Messenger); thus it can be used -//! with syntax similar to C++ streams. -//! Note that all these operators use trace level Warning. +//! For convenience, a set of methods Send...() returning a string +//! stream buffer is defined for use of stream-like syntax with operator << +//! +//! Example: +//! ~~~~~ +//! Messenger->SendFail() << " Unknown fail at line " << aLineNo << " in file " << aFile; +//! ~~~~~ +//! +//! The message is sent to messenger on destruction of the stream buffer, +//! call to Flush(), or passing manipulator std::ends, std::endl, or std::flush. +//! Empty messages are not sent except if manipulator is used. class Message_Messenger : public Standard_Transient { DEFINE_STANDARD_RTTIEXT(Message_Messenger, Standard_Transient) +public: + //! Auxiliary class wrapping std::stringstream thus allowing constructing + //! message via stream interface, and putting result into its creator + //! Message_Messenger within destructor. + //! + //! It is intended to be used either as temporary object or as local + //! variable, note that content will be lost if it is copied. + class StreamBuffer + { + public: + + //! Destructor flushing constructed message. + ~StreamBuffer() { Flush(); } + + //! Flush collected string to messenger + void Flush(Standard_Boolean doForce = Standard_False) + { + myStream.flush(); + if (doForce || myStream.rdbuf()->in_avail() > 0) + { + myMessenger->Send (myStream.str().c_str(), myGravity); + myStream.str(std::string()); // empty the buffer for possible reuse + } + } + + //! Formal copy constructor. + //! + //! Since buffer is intended for use as temporary object or local + //! variable, copy (or move) is needed only formally to be able to + //! return the new instance from relevant creation method. + //! In practice it should never be called because modern compilers + //! create such instances in place. + //! However note that if this constructor is called, the buffer + //! content (string) will not be copied (move is not supported for + //! std::stringstream class on old compilers such as gcc 4.4, msvc 9). + StreamBuffer (const StreamBuffer& theOther) + : myMessenger(theOther.myMessenger), myGravity(theOther.myGravity) + { + } + + //! Wrapper for operator << of the stream + template + StreamBuffer& operator << (const T& theArg) + { + myStream << theArg; + return *this; + } + + //! Operator << for manipulators of ostream (ends, endl, flush), + //! flushes the buffer (sends the message) + StreamBuffer& operator << (std::ostream& (*)(std::ostream&)) + { + Flush(Standard_True); + return *this; + } + + //! Access to the stream object + Standard_SStream& Stream () { return myStream; } + + private: + friend class Message_Messenger; + + //! Main constructor creating temporary buffer. + //! Accessible only to Messenger class. + StreamBuffer (Message_Messenger* theMessenger, Message_Gravity theGravity) + : myMessenger (theMessenger), + myGravity (theGravity) + {} + + private: + Message_Messenger* myMessenger; // don't make a Handle since this object should be created on stack + Message_Gravity myGravity; + Standard_SStream myStream; + }; + public: //! Empty constructor; initializes by single printer directed to cout. @@ -90,13 +168,52 @@ public: //! The parameter putEndl specifies whether the new line should //! be started after this message (default) or not (may have //! sense in some conditions). - Standard_EXPORT void Send (const Standard_CString theString, const Message_Gravity theGravity = Message_Warning, const Standard_Boolean putEndl = Standard_True) const; + Standard_EXPORT void Send (const Standard_CString theString, + const Message_Gravity theGravity = Message_Warning, + const Standard_Boolean putEndl = Standard_True) const; //! See above - Standard_EXPORT void Send (const TCollection_AsciiString& theString, const Message_Gravity theGravity = Message_Warning, const Standard_Boolean putEndl = Standard_True) const; + Standard_EXPORT void Send (const TCollection_AsciiString& theString, + const Message_Gravity theGravity = Message_Warning, + const Standard_Boolean putEndl = Standard_True) const; //! See above - Standard_EXPORT void Send (const TCollection_ExtendedString& theString, const Message_Gravity theGravity = Message_Warning, const Standard_Boolean putEndl = Standard_True) const; + Standard_EXPORT void Send (const TCollection_ExtendedString& theString, + const Message_Gravity theGravity = Message_Warning, + const Standard_Boolean putEndl = Standard_True) const; + + //! Create string buffer for message of specified type + StreamBuffer Send (Message_Gravity theGravity) { return StreamBuffer (this, theGravity); } + + //! Create string buffer for sending Fail message + StreamBuffer SendFail () { return Send (Message_Fail); } + + //! Create string buffer for sending Alarm message + StreamBuffer SendAlarm () { return Send (Message_Alarm); } + + //! Create string buffer for sending Warning message + StreamBuffer SendWarning () { return Send (Message_Warning); } + + //! Create string buffer for sending Info message + StreamBuffer SendInfo () { return Send (Message_Info); } + + //! Create string buffer for sending Trace message + StreamBuffer SendTrace () { return Send (Message_Trace); } + + //! Short-cut to Send (theMessage, Message_Fail) + void SendFail (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Fail); } + + //! Short-cut to Send (theMessage, Message_Alarm) + void SendAlarm (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Alarm); } + + //! Short-cut to Send (theMessage, Message_Warning) + void SendWarning (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Warning); } + + //! Short-cut to Send (theMessage, Message_Info) + void SendInfo (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Info); } + + //! Short-cut to Send (theMessage, Message_Trace) + void SendTrace (const TCollection_AsciiString& theMessage) { Send (theMessage, Message_Trace); } private: -- 2.39.5