Ocean
Loading...
Searching...
No Matches
Messenger.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_BASE_MESSENGER_H
9#define META_OCEAN_BASE_MESSENGER_H
10
11#include "ocean/base/Base.h"
12#include "ocean/base/Lock.h"
14#include "ocean/base/String.h"
15
16#include <fstream>
17#include <iostream>
18#include <queue>
19#include <ostream>
20
21namespace Ocean
22{
23
24/**
25 * This class implements a messenger for information, warning or error messages.
26 * Posted messages are stored in internal message queues or referred to a specified output file.<br>
27 * Therefore, applications interested in live messaging have to pop the queued messages recurrently.
28 *
29 * There different message types are supported dividing all messages related to their magnitude:
30 * Error messages hold critical informations which influence the major program progress directly.<br>
31 * Warning messages hold informations which can influence minor program progresses, however they are not critical.<br>
32 * Information messages hold interesting informations for the user only.<br>
33 * Meaning that error messages should be informed to the user immediately, instead information messages can be informed to the user.<br>
34 * Additionally, each message can provide a location specifying e.g. the sender module.
35 *
36 * Applications interested in messages use the Messenger object implemented as singleton to receive messages.
37 * Modules use the MessageObject objects to post new messages.<br>
38 * Three basic message types are defined: error, warning and info.
39 * @see SpecificMessenger.
40 *
41 * Tutorial explaining the usage on application side:
42 * @code
43 * #include "ocean/base/Messenger.h"
44 *
45 * // Function called by e.g. a timer recurrently.
46 * void timer()
47 * {
48 * if (Messenger::get().empty() == false)
49 * {
50 * // Strings which will receive the popped informations
51 * std::string message, location;
52 *
53 * // Boolean which will receive whether the information has been posted more than one time.
54 * bool isNew;
55 *
56 * // Pop all error messages
57 * while (Messenger::get().popError(location, message, isNew))
58 * {
59 * // Writes the error message to any application output window.
60 * writeToErrorOutputWindow(location, message);
61 * }
62 *
63 * // Pop all warning messages
64 * while (Messenger::get().popWarning(location, message, isNew))
65 * {
66 * // Writes the warning message to any application output window.
67 * writeToWarningOutputWindow(location, message);
68 * }
69 * }
70 * }
71 * @endcode
72 *
73 * Tutorial explaining the usage on module side:
74 * @code
75 * #include "ocean/base/Messenger.h"
76 *
77 * // Any function which will post a message.
78 * void anyFunction()
79 * {
80 * // A function calculating something
81 * int value = calculate();
82 *
83 * // suppose a resulting value of '0' is a failure
84 * if (value == 0)
85 * Log::error() << "The calculation failed.";
86 * else
87 * Log::info() << "The calculation returned \"" << value << \" which is great!";
88 * }
89 * @endcode
90 * @ingroup base
91 */
92class OCEAN_BASE_EXPORT Messenger : public Singleton<Messenger>
93{
94 /// Friend class
95 friend class Singleton<Messenger>;
96
97 public:
98
99 /**
100 * Definition of different message types.
101 */
102 enum MessageType : uint32_t
103 {
104 /// Invalid message type.
105 TYPE_UNDEFINED = 0u,
106 /// Debug message, which are not used on release builds (optimized out of the code).
108 /// Information message.
110 /// Warning message.
112 /// Error message.
113 TYPE_ERROR
114 };
115
116 /**
117 * Definition of different message output types.
118 */
119 enum MessageOutput : uint32_t
120 {
121 /// All messages will be discarded.
122 OUTPUT_DISCARDED = 0u,
123 /// All messages are directed to the standard output immediately.
124 OUTPUT_STANDARD = 1u << 0u,
125 /// All messages are queued and must be popped from the message stack explicitly.
126 OUTPUT_QUEUED = 1u << 1u,
127 /// All messages are directed to a debug window.
128 OUTPUT_DEBUG_WINDOW = 1u << 2u,
129 /// All messages are directed to a file immediately.
130 OUTPUT_FILE = 1u << 3u,
131 /// All messages are directed to an arbitrary stream immediately.
132 OUTPUT_STREAM = 1u << 4u,
133 /// All messages are directed to the maintenance manager.
134 OUTPUT_MAINTENANCE = 1u << 5u
135 };
136
137 protected:
138
139 /**
140 * Definition of a message.
141 */
142 typedef std::pair<std::string, std::string> Message;
143
144 /**
145 * Definition of a message queue.
146 */
147 typedef std::queue<Message> MessageQueue;
148
149 public:
150
151 /**
152 * Pushes a new message into the message queue.
153 * @param type The type of the message
154 * @param location The location of the message
155 * @param message The text message
156 */
157 void push(const MessageType type, std::string&& location, std::string&& message);
158
159 /**
160 * Pops the first debug message from the message queue.
161 * @param location The resulting location of the message
162 * @param message The resulting text message
163 * @param isNew Optional returning flag determining whether this message is not identical to the last one
164 * @return True, if a message could be popped
165 */
166 bool popDebug(std::string& location, std::string& message, bool* isNew = nullptr);
167
168 /**
169 * Pops the first information message from the message queue.
170 * @param location The resulting location of the message
171 * @param message The resulting text message
172 * @param isNew Optional returning flag determining whether this message is not identical to the last one
173 * @return True, if a message could be popped
174 */
175 bool popInformation(std::string& location, std::string& message, bool* isNew = nullptr);
176
177 /**
178 * Pops the first warning message from the message queue.
179 * @param location The resulting location of the message
180 * @param message The resulting test message
181 * @param isNew Returning flag determining whether this message is not identical to the last one
182 * @return True, if a message could be popped
183 */
184 bool popWarning(std::string& location, std::string& message, bool* isNew = nullptr);
185
186 /**
187 * Pops the first error message from the message queue.
188 * @param location The resulting location of the message
189 * @param message The resulting text message
190 * @param isNew Returning flag determining whether this message is not identical to the last one
191 * @return True, if a message could be popped
192 */
193 bool popError(std::string& location, std::string& message, bool* isNew = nullptr);
194
195 /**
196 * Pops any first message available of a given type or of any type.<br>
197 * If several messages with different types are available and an undefined type is defined the pop order is: errors, warnings, informations.
198 * @param type The type of the message to pop, may be TYPE_UNDEFINED to return any message while 'type' will be set to the type of the message which is returned
199 * @param location The resulting location of the message
200 * @param message The resulting text message
201 * @param isNew Optional returning flag determining whether this message is not identical to the previous one
202 * @return True, if a message existed
203 */
204 bool popMessage(MessageType& type, std::string& location, std::string& message, bool* isNew = nullptr);
205
206 /**
207 * Pops the oldest message available of a specified type.
208 * @param type The type of the message to return, TYPE_UNDEFINED to return a message with any type
209 * @param isNew Optional resulting state determining whether the message is not identical to the previous one
210 * @return The resulting message with format "Type: Location, Message", an empty string if no message is available
211 */
212 std::string popMessage(const MessageType type = TYPE_UNDEFINED, bool* isNew = nullptr);
213
214 /**
215 * Sets the output type of the messenger.
216 * @param type Output type to set
217 * @return True, if succeeded
218 * @see setFileOutput(), setOutputStream().
219 */
220 bool setOutputType(const MessageOutput type);
221
222 /**
223 * Sets the message output to a file.
224 * All messages will be redirected to the specified file instead of inserted into the message queue.
225 * @param filename Name of the output file, use an empty filename to disable file output
226 * @return True, if succeeded
227 * @see setOutputType().
228 */
229 bool setFileOutput(const std::string& filename);
230
231 /**
232 * Sets the message output to an output stream.
233 * All messages will be redirected to the specified output stream instead of inserted into the message queue.
234 * @param stream Output stream
235 * @return True, if succeeded
236 * @see setOutputType().
237 */
238 bool setOutputStream(std::ostream& stream);
239
240 /**
241 * Enables or disables the integration of local date/time information into the location information of messages.
242 * @param state True, to enable the integration of the date/time information
243 * @see integrateDateTime().
244 */
245 void setIntegrateDateTime(const bool state);
246
247 /**
248 * Flushes the current message stack to a given output stream, the output type is unchanged.
249 * @param stream Output stream
250 */
251 void flush(std::ostream& stream);
252
253 /**
254 * Clears all message queues.
255 */
256 void clear();
257
258 /**
259 * Clears the information message queue.
260 */
262
263 /**
264 * Clears the warning message queue.
265 */
267
268 /**
269 * Clears the error message queue.
270 */
272
273 /**
274 * Returns the output type of the messenger.
275 * @return Current output type
276 */
277 inline MessageOutput outputType() const;
278
279 /**
280 * Returns the number of waiting information messages.
281 * @return Number of messages
282 */
283 inline size_t informations() const;
284
285 /**
286 * Returns the number of waiting information messages.
287 * @return Number of messages
288 */
289 inline size_t warnings() const;
290
291 /**
292 * Returns the number of waiting information messages.
293 * @return Number of messages
294 */
295 inline size_t errors() const;
296
297 /**
298 * Returns whether the date/time integration is activated.
299 * By default the date time integration is deactivated.
300 * @return True, if so
301 * @see setIntegrateDateTime().
302 */
303 inline bool integrateDateTime() const;
304
305 /**
306 * Returns whether no message exists.
307 * @return True, if so
308 */
309 inline bool empty() const;
310
311 /**
312 * Writes a message to the most suitable debug output of the current platform.
313 * This function is just a simple way to create a debug message without needing to configure the Messenger.
314 * @param message The message to write
315 */
316 static void writeToDebugOutput(const std::string& message);
317
318 /**
319 * Returns whether the messenger is active on this build.
320 * @return True, if so; False, to strip away every message related information in the binary
321 */
322 static constexpr bool isActive();
323
324 /**
325 * Returns whether the messenger is used on a debug build.
326 * @return True, if so
327 */
328 static constexpr bool isDebugBuild();
329
330 protected:
331
332 /**
333 * Creates a new messenger object queuing all messages as default.
334 */
336
337 /**
338 * Destructs a messenger object.
339 */
341
342 protected:
343
344 /// Message output type.
345 MessageOutput outputType_ = OUTPUT_STANDARD;
346
347#ifdef OCEAN_DEBUG
348 /// Debug message queue.
350
351 /// Last debug message.
352 std::string lastDebugMessage_;
353#endif
354
355 /// Information message queue.
357
358 /// Warning message queue.
360
361 /// Error message queue.
363
364 /// Last information message.
366
367 /// Last warning message.
369
370 /// Last error message.
371 std::string lastErrorMessage_;
372
373 /// File output stream
374 std::ofstream fileOutputStream_;
375
376 /// Explicit output stream, if any
377 std::ostream* outputStream_ = nullptr;
378
379 /// Date and time integration state.
380 bool integrateDateTime_ = false;
381
382 /// Messenger lock.
383 mutable Lock lock_;
384
385 /// Maximum number of messages.
386 static constexpr unsigned int maxMessages_ = 5000u;
387
388#if defined(__APPLE__)
389
390 /**
391 * Write message to Apple-specific log facility.
392 * @sa push()
393 * @param message The message to be written into NSLog
394 */
395 static void writeMessageToDebugWindowApple(const std::string& message);
396
397#endif // defined(__APPLE__)
398};
399
400constexpr bool Messenger::isActive()
401{
402#ifdef OCEAN_DEACTIVATED_MESSENGER
403 return false;
404#else
405 return true;
406#endif
407}
408
410{
411#ifdef OCEAN_DEBUG
412 return true;
413#else
414 return false;
415#endif
416}
417
418/**
419 * Messenger object, one object for each message.
420 * This class is a helper class only, therefore there is no need to use it directly.<br>
421 * @tparam tActive True, if the message object is active; False, e.g., on builds in which messages must not appear in binary files
422 * @see Messenger.
423 * @ingroup base
424 */
425template <bool tActive>
427{
428 public:
429
430 /**
431 * Re-definition of MessageType
432 */
434
435 public:
436
437 /**
438 * Creates a new message object.
439 * @param type The type of the message object
440 */
441 inline explicit MessageObject(const MessageType type);
442
443 /**
444 * Creates a new message object.
445 * @param type The type of the message object
446 * @param location The location of the message
447 */
448 inline MessageObject(const MessageType type, std::string&& location);
449
450 /**
451 * Copy-constructs a new message object.
452 * @param messageObject Another instance that will be used to create this instance, must be valid
453 */
454 MessageObject(const MessageObject& messageObject) = default;
455
456 /**
457 * Destructs a message object.
458 */
459 inline ~MessageObject();
460
461 /**
462 * Adds a new line to this message object if a specified condition holds.
463 * @param condition True, to add the line; False, to do nothing
464 * @return Reference to this object
465 */
466 inline MessageObject& newLine(const bool condition = true);
467
468 /**
469 * Pushes another information message.
470 * @param message The message to push
471 * @return Reference to this object
472 */
473 inline MessageObject& operator<<(std::string&& message);
474
475 /**
476 * Pushes another information message.
477 * @param message The message to push
478 * @return Reference to this object
479 */
480 inline MessageObject& operator<<(const std::string& message);
481
482 /**
483 * Pushes another information message.
484 * @param message The message to push
485 * @return Reference to this object
486 */
487 inline MessageObject& operator<<(const char* message);
488
489 /**
490 * Pushes another information message.
491 * @param message The message to push
492 * @return Reference to this object
493 */
494 inline MessageObject& operator<<(const double message);
495
496 /**
497 * Pushes another information message.
498 * @param message The message to push
499 * @return Reference to this object
500 */
501 inline MessageObject& operator<<(const float message);
502
503 /**
504 * Pushes another information message.
505 * @param message The message to push
506 * @return Reference to this object
507 */
508 inline MessageObject& operator<<(const int message);
509
510 /**
511 * Pushes another information message.
512 * @param message The message to push
513 * @return Reference to this object
514 */
515 inline MessageObject& operator<<(const unsigned int message);
516
517 /**
518 * Pushes another information message.
519 * @param message The message to push
520 * @return Reference to this object
521 */
522 inline MessageObject& operator<<(const long message);
523
524 /**
525 * Pushes another information message.
526 * @param message The message to push
527 * @return Reference to this object
528 */
529 inline MessageObject& operator<<(const long long message);
530
531 /**
532 * Pushes another information message.
533 * @param message The message to push
534 * @return Reference to this object
535 */
536 inline MessageObject& operator<<(const unsigned long long message);
537
538 /**
539 * Pushes another information message.
540 * @param message The message to push
541 * @return Reference to this object
542 */
543 inline MessageObject& operator<<(const long unsigned int message);
544
545 /**
546 * Pushes another information message.
547 * @param message The message to push
548 */
549 inline void operator<<(const MessageObject& message);
550
551 /**
552 * Assign operator
553 * @param messageObject Another instance that will assigned to this instance, must be valid
554 */
555 MessageObject& operator=(const MessageObject& messageObject) = default;
556
557 protected:
558
559 /**
560 * Creates a new message object.
561 * @param type The type of the message object
562 * @param location The location of the message object
563 * @param message The message of the object
564 */
565 inline MessageObject(const MessageType type, std::string&& location, std::string&& message);
566
567 protected:
568
569 /// Entire message.
570 std::string message_;
571
572 /// Location of the message.
573 std::string location_;
574
575 /// Type of this messenger.
577};
578
579/**
580 * Specialization of MessageObject.
581 * Inactive messenger object to strip away any messenger related information in binary.
582 * @see Messenger.
583 * @ingroup base
584 */
585template <>
586class MessageObject<false>
587{
588 public:
589
590 /**
591 * Re-definition of MessageType
592 */
594
595 public:
596
597 /**
598 * Creates a new message object.
599 */
600 explicit inline MessageObject(const MessageType /*type*/)
601 {
602 // nothing to do here
603 }
604
605 /**
606 * Creates a new message object.
607 */
608 inline MessageObject(const MessageType /*type*/, std::string&& /*location*/)
609 {
610 // nothing to do here
611 }
612
613 /**
614 * Copy-constructs a new message object.
615 * @param messageObject Another instance that will be used to create this instance, must be valid
616 */
617 MessageObject(const MessageObject& messageObject) = default;
618
619 /**
620 * Destructs a message object.
621 */
622 ~MessageObject() = default;
623
624 /**
625 * Adds a new line to this message object if a specified condition holds.
626 * @return Reference to this object
627 */
629 {
630 return *this;
631 }
632
633 /**
634 * Adds a new line to this message object if a specified condition holds.
635 * @return Reference to this object
636 */
637 inline MessageObject& newLine(const bool /*condition*/)
638 {
639 return *this;
640 }
641
642 /**
643 * Pushes another information message.
644 * @return Reference to this object
645 */
646 inline MessageObject& operator<<(std::string&& /*message*/)
647 {
648 return *this;
649 }
650
651 /**
652 * Pushes another information message.
653 * @return Reference to this object
654 */
655 inline MessageObject& operator<<(const std::string& /*message*/)
656 {
657 return *this;
658 }
659
660 /**
661 * Pushes another information message.
662 * @return Reference to this object
663 */
664 inline MessageObject& operator<<(const char* /*message*/)
665 {
666 return *this;
667 }
668
669 /**
670 * Pushes another information message.
671 * @return Reference to this object
672 */
673 inline MessageObject& operator<<(const double /*message*/)
674 {
675 return *this;
676 }
677
678 /**
679 * Pushes another information message.
680 * @return Reference to this object
681 */
682 inline MessageObject& operator<<(const float /*message*/)
683 {
684 return *this;
685 }
686
687 /**
688 * Pushes another information message.
689 * @return Reference to this object
690 */
691 inline MessageObject& operator<<(const int /*message*/)
692 {
693 return *this;
694 }
695
696 /**
697 * Pushes another information message.
698 * @return Reference to this object
699 */
700 inline MessageObject& operator<<(const unsigned int /*message*/)
701 {
702 return *this;
703 }
704
705 /**
706 * Pushes another information message.
707 * @return Reference to this object
708 */
709 inline MessageObject& operator<<(const long /*message*/)
710 {
711 return *this;
712 }
713
714 /**
715 * Pushes another information message.
716 * @return Reference to this object
717 */
718 inline MessageObject& operator<<(const long long /*message*/)
719 {
720 return *this;
721 }
722
723 /**
724 * Pushes another information message.
725 * @return Reference to this object
726 */
727 inline MessageObject& operator<<(const unsigned long long /*message*/)
728 {
729 return *this;
730 }
731
732 /**
733 * Pushes another information message.
734 * @return Reference to this object
735 */
736 inline MessageObject& operator<<(const long unsigned int /*message*/)
737 {
738 return *this;
739 }
740
741 /**
742 * Pushes another information message.
743 */
744 inline void operator<<(const MessageObject& /*message*/)
745 {
746 // nothing to do here
747 }
748
749 /**
750 * Assign operator
751 * @param messageObject Another instance that will assigned to this instance, must be valid
752 */
753 MessageObject& operator=(const MessageObject& messageObject) = default;
754
755 protected:
756
757 /**
758 * Creates a new message object.
759 */
760 inline MessageObject(const MessageType /*type*/, std::string&& /*location*/, std::string&& /*message*/)
761 {
762 // nothing to do here
763 }
764};
765
766/**
767 * This class provides access to three different Message objects, e.g., for regular information, warnings, or errors.
768 * @ingroup base
769 */
770class OCEAN_BASE_EXPORT Log
771{
772 public:
773
774 /**
775 * Definition of a default message object, only active if `Messenger::isActive() == true`.
776 */
777 typedef Ocean::MessageObject<Messenger::isActive()> MessageObject;
778
779 /**
780 * Definition of a debug message object, only active on debug builds and if `Messenger::isActive() == true`.
781 */
782 typedef Ocean::MessageObject<Messenger::isActive() && Messenger::isDebugBuild()> DebugMessageObject;
783
784 protected:
785
786 /**
787 * Helper class allowing to specify a specific message object or stream type.
788 * @tparam TStream The data type of the message object (or stream) to be checked
789 */
790 template <typename TStream>
792 {
793 /**
794 * Helper class to check whether a message object or a stream provides a shift operator for an object with specific data type.
795 * @tparam TObject The data type to check
796 */
797 template <typename TObject, typename = void>
799 {
800 /// False, if the message object or stream does not provide a shift operator for the data type 'TObject'.
801 static constexpr bool value = false;
802 };
803
804 /**
805 * Helper class to check whether a message object or a stream provides a shift operator for an object with specific data type.
806 * Specialization of ShiftOperatorChecker.
807 * @tparam TObject The data type to check
808 */
809 template <typename TObject>
810 struct ShiftOperatorChecker<TObject, std::void_t<decltype( std::declval<TStream&>() << std::declval<TObject>())>>
811 {
812 /// True, if the message object or stream does provides a shift operator for the data type 'TObject'.
813 static constexpr bool value = true;
814 };
815 };
816
817 public:
818
819 /**
820 * Returns the message for debug messages.
821 * Debug messages do not show up on release builds.<br>
822 * The debug log is intended to simplify code like this:
823 * @code
824 * #ifdef OCEAN_DEBUG
825 * info() << "<debug> This message shows up on debug builds only."
826 * #endif
827 * @endcode
828 * @return The message object that will be stripped away on release builds
829 */
830 static inline DebugMessageObject debug();
831
832 /**
833 * Returns the message for information messages.
834 * @return The message object
835 */
836 static inline MessageObject info();
837
838 /**
839 * Returns the message for warning messages.
840 * @return The message object
841 */
842 static inline MessageObject warning();
843
844 /**
845 * Returns the message for error messages.
846 * @return The message object
847 */
848 static inline MessageObject error();
849
850 /**
851 * Returns whether a specific data type can be written to a message object (or an arbitrary stream).
852 * The function returns whether the shift operator of MessageObject (or of an arbitrary stream) supports the specified data type.
853 * Usage:
854 * @code
855 * void function()
856 * {
857 * int value = 9;
858 *
859 * if constexpr (Log::isSupported<int>())
860 * {
861 * Log::info() << "Value is: " << value;
862 * }
863 * else
864 * {
865 * Log::info() << "Value cannot be written to log.";
866 * }
867 * }
868 * @endcode
869 * @return True, if so
870 * @tparam T The data type to be checked
871 * @tparam TStream The data type of the message object (or stream) to be checked
872 */
873 template <typename T, typename TStream = MessageObject>
874 static constexpr bool isSupported();
875};
876
877inline Messenger::MessageOutput Messenger::outputType() const
878{
879 const ScopedLock scopedLock(lock_);
880 return outputType_;
881}
882
883inline size_t Messenger::informations() const
884{
885 const ScopedLock scopedLock(lock_);
886 return informationMessageQueue_.size();
887}
888
889inline size_t Messenger::warnings() const
890{
891 const ScopedLock scopedLock(lock_);
892 return warningMessageQueue_.size();
893}
894
895inline size_t Messenger::errors() const
896{
897 const ScopedLock scopedLock(lock_);
898 return errorMessageQueue_.size();
899}
900
901inline bool Messenger::integrateDateTime() const
902{
903 const ScopedLock scopedLock(lock_);
904 return integrateDateTime_;
905}
906
907inline bool Messenger::empty() const
908{
909 const ScopedLock scopedLock(lock_);
910 return informationMessageQueue_.empty() && warningMessageQueue_.empty() && errorMessageQueue_.empty();
911}
912
913template <bool tActive>
914inline MessageObject<tActive>::MessageObject(const MessageType type) :
915 type_(type)
916{
917 // nothing to do here
918}
919
920template <bool tActive>
921inline MessageObject<tActive>::MessageObject(const MessageType type, std::string&& location) :
922 location_(std::move(location)),
923 type_(type)
924{
925 // nothing to do here
926}
927
928template <bool tActive>
929inline MessageObject<tActive>::MessageObject(const MessageType type, std::string&& location, std::string&& message) :
930 message_(std::move(message)),
931 location_(std::move(location)),
932 type_(type)
933{
934 // nothing to do here
935}
936
937template <bool tActive>
938inline MessageObject<tActive>::~MessageObject()
939{
940 if (!message_.empty())
941 {
942 Messenger::get().push(type_, std::move(location_), std::move(message_));
943 }
944}
945
946template <bool tActive>
947inline MessageObject<tActive>& MessageObject<tActive>::newLine(const bool condition)
948{
949 if (condition)
950 {
951 message_ += "\n";
952 }
953
954 return *this;
955}
956
957template <bool tActive>
958inline MessageObject<tActive>& MessageObject<tActive>::operator<<(std::string&& message)
959{
960 if (message_.empty())
961 {
962 message_ = std::move(message);
963 }
964 else
965 {
966 message_ += message;
967 }
968
969 return *this;
970}
971
972template <bool tActive>
973inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const std::string& message)
974{
975 message_ += message;
976 return *this;
977}
978
979template <bool tActive>
980inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const char* message)
981{
982 if (message != nullptr)
983 {
984 message_ += std::string(message);
985 }
986
987 return *this;
988}
989
990template <bool tActive>
991inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const double message)
992{
993 message_ += String::toAString(message);
994 return *this;
995}
996
997template <bool tActive>
998inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const float message)
999{
1000 message_ += String::toAString(message);
1001 return *this;
1002}
1003
1004template <bool tActive>
1005inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const int message)
1006{
1007 message_ += String::toAString(message);
1008 return *this;
1009}
1010
1011template <bool tActive>
1012inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const unsigned int message)
1013{
1014 message_ += String::toAString(message);
1015 return *this;
1016}
1017
1018template <bool tActive>
1019inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const long message)
1020{
1021 message_ += String::toAString(message);
1022 return *this;
1023}
1024
1025template <bool tActive>
1026inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const long long message)
1027{
1028 message_ += String::toAString(message);
1029 return *this;
1030}
1031
1032template <bool tActive>
1033inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const unsigned long long message)
1034{
1035 message_ += String::toAString(message);
1036 return *this;
1037}
1038
1039template <bool tActive>
1040inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const long unsigned int message)
1041{
1042 message_ += String::toAString(message);
1043 return *this;
1044}
1045
1046template <bool tActive>
1047inline void MessageObject<tActive>::operator<<(const MessageObject<tActive>& messageObject)
1048{
1049 ocean_assert_and_suppress_unused(messageObject.type_ == Messenger::TYPE_UNDEFINED, messageObject);
1050
1051 if (!message_.empty())
1052 {
1053 Messenger::get().push(type_, std::string(location_), std::move(message_));
1054 }
1055
1056 message_.clear();
1057}
1058
1059inline Log::DebugMessageObject Log::debug()
1060{
1061 return DebugMessageObject(Messenger::TYPE_DEBUG);
1062}
1063
1064inline Log::MessageObject Log::info()
1065{
1066 return MessageObject(Messenger::TYPE_INFORMATION);
1067}
1068
1069inline Log::MessageObject Log::warning()
1070{
1071 return MessageObject(Messenger::TYPE_WARNING);
1072}
1073
1074inline Log::MessageObject Log::error()
1075{
1076 return MessageObject(Messenger::TYPE_ERROR);
1077}
1078
1079template <typename T, typename TStream>
1080constexpr bool Log::isSupported()
1081{
1082 return StreamHelper<TStream>::template ShiftOperatorChecker<T>::value;
1083}
1084
1085}
1086
1087#endif // META_OCEAN_BASE_MESSENGER_H
This class implements a recursive lock object.
Definition Lock.h:31
This class provides access to three different Message objects, e.g., for regular information,...
Definition Messenger.h:771
Ocean::MessageObject< Messenger::isActive() &&Messenger::isDebugBuild()> DebugMessageObject
Definition of a debug message object, only active on debug builds and if Messenger::isActive() == tru...
Definition Messenger.h:782
Ocean::MessageObject< Messenger::isActive()> MessageObject
Definition of a default message object, only active if Messenger::isActive() == true.
Definition Messenger.h:777
MessageObject & operator<<(std::string &&)
Pushes another information message.
Definition Messenger.h:646
MessageObject(const MessageObject &messageObject)=default
Copy-constructs a new message object.
MessageObject & newLine(const bool)
Adds a new line to this message object if a specified condition holds.
Definition Messenger.h:637
MessageObject(const MessageType)
Creates a new message object.
Definition Messenger.h:600
MessageObject & operator<<(const long long)
Pushes another information message.
Definition Messenger.h:718
MessageObject & operator<<(const long unsigned int)
Pushes another information message.
Definition Messenger.h:736
void operator<<(const MessageObject &)
Pushes another information message.
Definition Messenger.h:744
MessageObject & operator=(const MessageObject &messageObject)=default
Assign operator.
MessageObject & operator<<(const long)
Pushes another information message.
Definition Messenger.h:709
MessageObject & operator<<(const float)
Pushes another information message.
Definition Messenger.h:682
MessageObject & operator<<(const std::string &)
Pushes another information message.
Definition Messenger.h:655
MessageObject & newLine()
Adds a new line to this message object if a specified condition holds.
Definition Messenger.h:628
MessageObject & operator<<(const int)
Pushes another information message.
Definition Messenger.h:691
~MessageObject()=default
Destructs a message object.
MessageObject & operator<<(const char *)
Pushes another information message.
Definition Messenger.h:664
MessageObject(const MessageType, std::string &&)
Creates a new message object.
Definition Messenger.h:608
MessageObject & operator<<(const double)
Pushes another information message.
Definition Messenger.h:673
MessageObject(const MessageType, std::string &&, std::string &&)
Creates a new message object.
Definition Messenger.h:760
MessageObject & operator<<(const unsigned long long)
Pushes another information message.
Definition Messenger.h:727
MessageObject & operator<<(const unsigned int)
Pushes another information message.
Definition Messenger.h:700
Messenger object, one object for each message.
Definition Messenger.h:427
std::string message_
Entire message.
Definition Messenger.h:570
std::string location_
Location of the message.
Definition Messenger.h:573
MessageObject & newLine(const bool condition=true)
Adds a new line to this message object if a specified condition holds.
Definition Messenger.h:947
MessageObject & operator<<(std::string &&message)
Pushes another information message.
Definition Messenger.h:958
MessageObject(const MessageObject &messageObject)=default
Copy-constructs a new message object.
MessageObject & operator=(const MessageObject &messageObject)=default
Assign operator.
~MessageObject()
Destructs a message object.
Definition Messenger.h:938
Messenger::MessageType type_
Type of this messenger.
Definition Messenger.h:576
This class implements a messenger for information, warning or error messages.
Definition Messenger.h:93
static constexpr bool isActive()
Returns whether the messenger is active on this build.
Definition Messenger.h:400
std::string lastErrorMessage_
Last error message.
Definition Messenger.h:371
static constexpr bool isDebugBuild()
Returns whether the messenger is used on a debug build.
Definition Messenger.h:409
MessageQueue informationMessageQueue_
Information message queue.
Definition Messenger.h:356
bool popMessage(MessageType &type, std::string &location, std::string &message, bool *isNew=nullptr)
Pops any first message available of a given type or of any type.
Lock lock_
Messenger lock.
Definition Messenger.h:383
std::queue< Message > MessageQueue
Definition of a message queue.
Definition Messenger.h:147
MessageQueue errorMessageQueue_
Error message queue.
Definition Messenger.h:362
void setIntegrateDateTime(const bool state)
Enables or disables the integration of local date/time information into the location information of m...
void clearInformations()
Clears the information message queue.
void clearWarnings()
Clears the warning message queue.
bool popDebug(std::string &location, std::string &message, bool *isNew=nullptr)
Pops the first debug message from the message queue.
MessageOutput
Definition of different message output types.
Definition Messenger.h:120
std::string lastWarningMessage_
Last warning message.
Definition Messenger.h:368
bool setOutputStream(std::ostream &stream)
Sets the message output to an output stream.
void clear()
Clears all message queues.
std::ofstream fileOutputStream_
File output stream.
Definition Messenger.h:374
MessageQueue debugMessageQueue_
Debug message queue.
Definition Messenger.h:349
static void writeToDebugOutput(const std::string &message)
Writes a message to the most suitable debug output of the current platform.
std::pair< std::string, std::string > Message
Definition of a message.
Definition Messenger.h:142
MessageQueue warningMessageQueue_
Warning message queue.
Definition Messenger.h:359
MessageType
Definition of different message types.
Definition Messenger.h:103
@ TYPE_INFORMATION
Information message.
Definition Messenger.h:109
@ TYPE_WARNING
Warning message.
Definition Messenger.h:111
@ TYPE_DEBUG
Debug message, which are not used on release builds (optimized out of the code).
Definition Messenger.h:107
@ TYPE_UNDEFINED
Invalid message type.
Definition Messenger.h:105
std::string popMessage(const MessageType type=TYPE_UNDEFINED, bool *isNew=nullptr)
Pops the oldest message available of a specified type.
~Messenger()
Destructs a messenger object.
std::string lastDebugMessage_
Last debug message.
Definition Messenger.h:352
static void writeMessageToDebugWindowApple(const std::string &message)
Write message to Apple-specific log facility.
void flush(std::ostream &stream)
Flushes the current message stack to a given output stream, the output type is unchanged.
void push(const MessageType type, std::string &&location, std::string &&message)
Pushes a new message into the message queue.
bool setOutputType(const MessageOutput type)
Sets the output type of the messenger.
bool popWarning(std::string &location, std::string &message, bool *isNew=nullptr)
Pops the first warning message from the message queue.
bool setFileOutput(const std::string &filename)
Sets the message output to a file.
void clearErrors()
Clears the error message queue.
Messenger()
Creates a new messenger object queuing all messages as default.
std::string lastInformationMessage_
Last information message.
Definition Messenger.h:365
bool popInformation(std::string &location, std::string &message, bool *isNew=nullptr)
Pops the first information message from the message queue.
bool popError(std::string &location, std::string &message, bool *isNew=nullptr)
Pops the first error message from the message queue.
This template class is the base class for all singleton objects.
Definition Singleton.h:71
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
Helper class to check whether a message object or a stream provides a shift operator for an object wi...
Definition Messenger.h:799
Helper class allowing to specify a specific message object or stream type.
Definition Messenger.h:792