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 information which influence the major program progress directly.<br>
31 * Warning messages hold information which can influence minor program progresses, however they are not critical.<br>
32 * Information messages hold interesting information 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 information
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 using Message = std::pair<std::string, std::string>;
143
144 /**
145 * Definition of a message queue.
146 */
147 using MessageQueue = std::queue<Message>;
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, information.
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 /**
343 * Queues a message.
344 * @param messageType The type of the message
345 * @param locationAndTime The location and time, may be empty
346 * @param message The message to queue, must be valid
347 */
348 void queueMessage(const MessageType messageType, std::string&& locationAndTime, std::string&& message);
349
350#ifdef OCEAN_PLATFORM_BUILD_ANDROID
351
352 /**
353 * Writes a message to the Android log system (logcat).
354 * @param messageType The type of the message
355 * @param locationAndTime The location and time, may be empty
356 * @param message The message to write, must be valid
357 */
358 static void writeMessageToLogAndroid(const MessageType messageType, const std::string& locationAndTime, const std::string& message);
359
360#endif // OCEAN_PLATFORM_BUILD_ANDROID
361
362#ifdef OCEAN_PLATFORM_BUILD_APPLE
363
364 /**
365 * Writes a message to Apple's log system.
366 * @param messageType The type of the message
367 * @param message The message to write, must be valid
368 */
369 static void writeMessageToLogApple(const MessageType messageType, const std::string& message);
370
371#endif // OCEAN_PLATFORM_BUILD_APPLE
372
373 protected:
374
375 /// Message output type.
376 MessageOutput outputType_ = OUTPUT_STANDARD;
377
378#ifdef OCEAN_DEBUG
379
380 /// Debug message queue.
382
383 /// Last debug message.
384 std::string lastDebugMessage_;
385#endif
386
387 /// Information message queue.
389
390 /// Warning message queue.
392
393 /// Error message queue.
395
396 /// Last information message.
398
399 /// Last warning message.
401
402 /// Last error message.
403 std::string lastErrorMessage_;
404
405 /// File output stream
406 std::ofstream fileOutputStream_;
407
408 /// Explicit output stream, if any
409 std::ostream* outputStream_ = nullptr;
410
411 /// Date and time integration state.
412 bool integrateDateTime_ = false;
413
414 /// Messenger lock.
415 mutable Lock lock_;
416
417 /// Maximum number of messages.
418 static constexpr unsigned int maxMessages_ = 5000u;
419};
420
421constexpr bool Messenger::isActive()
422{
423#ifdef OCEAN_DEACTIVATED_MESSENGER
424 return false;
425#else
426 return true;
427#endif
428}
429
431{
432#ifdef OCEAN_DEBUG
433 return true;
434#else
435 return false;
436#endif
437}
438
439/**
440 * Messenger object, one object for each message.
441 * This class is a helper class only, therefore there is no need to use it directly.<br>
442 * @tparam tActive True, if the message object is active; False, e.g., on builds in which messages must not appear in binary files
443 * @see Messenger.
444 * @ingroup base
445 */
446template <bool tActive>
448{
449 public:
450
451 /**
452 * Re-definition of MessageType
453 */
455
456 public:
457
458 /**
459 * Creates a new message object.
460 * @param type The type of the message object
461 */
462 inline explicit MessageObject(const MessageType type);
463
464 /**
465 * Creates a new message object.
466 * @param type The type of the message object
467 * @param location The location of the message
468 */
469 inline MessageObject(const MessageType type, std::string&& location);
470
471 /**
472 * Copy-constructs a new message object.
473 * @param messageObject Another instance that will be used to create this instance, must be valid
474 */
475 MessageObject(const MessageObject& messageObject) = default;
476
477 /**
478 * Destructs a message object.
479 */
480 inline ~MessageObject();
481
482 /**
483 * Adds a new line to this message object if a specified condition holds.
484 * @param condition True, to add the line; False, to do nothing
485 * @return Reference to this object
486 */
487 inline MessageObject& newLine(const bool condition = true);
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<<(std::string&& 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 std::string& 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 char* 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 double 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 float 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 int 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 int 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 message);
544
545 /**
546 * Pushes another information message.
547 * @param message The message to push
548 * @return Reference to this object
549 */
550 inline MessageObject& operator<<(const long long message);
551
552 /**
553 * Pushes another information message.
554 * @param message The message to push
555 * @return Reference to this object
556 */
557 inline MessageObject& operator<<(const unsigned long long message);
558
559 /**
560 * Pushes another information message.
561 * @param message The message to push
562 * @return Reference to this object
563 */
564 inline MessageObject& operator<<(const long unsigned int message);
565
566 /**
567 * Pushes another information message.
568 * @param message The message to push
569 */
570 inline void operator<<(const MessageObject& message);
571
572 /**
573 * Assign operator
574 * @param messageObject Another instance that will assigned to this instance, must be valid
575 */
576 MessageObject& operator=(const MessageObject& messageObject) = default;
577
578 protected:
579
580 /**
581 * Creates a new message object.
582 * @param type The type of the message object
583 * @param location The location of the message object
584 * @param message The message of the object
585 */
586 inline MessageObject(const MessageType type, std::string&& location, std::string&& message);
587
588 protected:
589
590 /// Entire message.
591 std::string message_;
592
593 /// Location of the message.
594 std::string location_;
595
596 /// Type of this messenger.
598};
599
600/**
601 * Specialization of MessageObject.
602 * Inactive messenger object to strip away any messenger related information in binary.
603 * @see Messenger.
604 * @ingroup base
605 */
606template <>
607class MessageObject<false>
608{
609 public:
610
611 /**
612 * Re-definition of MessageType
613 */
615
616 public:
617
618 /**
619 * Creates a new message object.
620 */
621 explicit inline MessageObject(const MessageType /*type*/)
622 {
623 // nothing to do here
624 }
625
626 /**
627 * Creates a new message object.
628 */
629 inline MessageObject(const MessageType /*type*/, std::string&& /*location*/)
630 {
631 // nothing to do here
632 }
633
634 /**
635 * Copy-constructs a new message object.
636 * @param messageObject Another instance that will be used to create this instance, must be valid
637 */
638 MessageObject(const MessageObject& messageObject) = default;
639
640 /**
641 * Destructs a message object.
642 */
643 ~MessageObject() = default;
644
645 /**
646 * Adds a new line to this message object if a specified condition holds.
647 * @return Reference to this object
648 */
650 {
651 return *this;
652 }
653
654 /**
655 * Adds a new line to this message object if a specified condition holds.
656 * @return Reference to this object
657 */
658 inline MessageObject& newLine(const bool /*condition*/)
659 {
660 return *this;
661 }
662
663 /**
664 * Pushes another information message.
665 * @return Reference to this object
666 */
667 inline MessageObject& operator<<(std::string&& /*message*/)
668 {
669 return *this;
670 }
671
672 /**
673 * Pushes another information message.
674 * @return Reference to this object
675 */
676 inline MessageObject& operator<<(const std::string& /*message*/)
677 {
678 return *this;
679 }
680
681 /**
682 * Pushes another information message.
683 * @return Reference to this object
684 */
685 inline MessageObject& operator<<(const char* /*message*/)
686 {
687 return *this;
688 }
689
690 /**
691 * Pushes another information message.
692 * @return Reference to this object
693 */
694 inline MessageObject& operator<<(const double /*message*/)
695 {
696 return *this;
697 }
698
699 /**
700 * Pushes another information message.
701 * @return Reference to this object
702 */
703 inline MessageObject& operator<<(const float /*message*/)
704 {
705 return *this;
706 }
707
708 /**
709 * Pushes another information message.
710 * @return Reference to this object
711 */
712 inline MessageObject& operator<<(const int /*message*/)
713 {
714 return *this;
715 }
716
717 /**
718 * Pushes another information message.
719 * @return Reference to this object
720 */
721 inline MessageObject& operator<<(const unsigned int /*message*/)
722 {
723 return *this;
724 }
725
726 /**
727 * Pushes another information message.
728 * @return Reference to this object
729 */
730 inline MessageObject& operator<<(const long /*message*/)
731 {
732 return *this;
733 }
734
735 /**
736 * Pushes another information message.
737 * @return Reference to this object
738 */
739 inline MessageObject& operator<<(const long long /*message*/)
740 {
741 return *this;
742 }
743
744 /**
745 * Pushes another information message.
746 * @return Reference to this object
747 */
748 inline MessageObject& operator<<(const unsigned long long /*message*/)
749 {
750 return *this;
751 }
752
753 /**
754 * Pushes another information message.
755 * @return Reference to this object
756 */
757 inline MessageObject& operator<<(const long unsigned int /*message*/)
758 {
759 return *this;
760 }
761
762 /**
763 * Pushes another information message.
764 */
765 inline void operator<<(const MessageObject& /*message*/)
766 {
767 // nothing to do here
768 }
769
770 /**
771 * Assign operator
772 * @param messageObject Another instance that will assigned to this instance, must be valid
773 */
774 MessageObject& operator=(const MessageObject& messageObject) = default;
775
776 protected:
777
778 /**
779 * Creates a new message object.
780 */
781 inline MessageObject(const MessageType /*type*/, std::string&& /*location*/, std::string&& /*message*/)
782 {
783 // nothing to do here
784 }
785};
786
787/**
788 * This class provides access to three different Message objects, e.g., for regular information, warnings, or errors.
789 * @ingroup base
790 */
791class OCEAN_BASE_EXPORT Log
792{
793 public:
794
795 /**
796 * Definition of a default message object, only active if `Messenger::isActive() == true`.
797 */
798 using MessageObject = Ocean::MessageObject<Messenger::isActive()>;
799
800 /**
801 * Definition of a debug message object, only active on debug builds and if `Messenger::isActive() == true`.
802 */
803 using DebugMessageObject = Ocean::MessageObject<Messenger::isActive() && Messenger::isDebugBuild()>;
804
805 protected:
806
807 /**
808 * Helper class allowing to specify a specific message object or stream type.
809 * @tparam TStream The data type of the message object (or stream) to be checked
810 */
811 template <typename TStream>
813 {
814 /**
815 * Helper class to check whether a message object or a stream provides a shift operator for an object with specific data type.
816 * @tparam TObject The data type to check
817 */
818 template <typename TObject, typename = void>
820 {
821 /// False, if the message object or stream does not provide a shift operator for the data type 'TObject'.
822 static constexpr bool value = false;
823 };
824
825 /**
826 * Helper class to check whether a message object or a stream provides a shift operator for an object with specific data type.
827 * Specialization of ShiftOperatorChecker.
828 * @tparam TObject The data type to check
829 */
830 template <typename TObject>
831 struct ShiftOperatorChecker<TObject, std::void_t<decltype( std::declval<TStream&>() << std::declval<TObject>())>>
832 {
833 /// True, if the message object or stream does provides a shift operator for the data type 'TObject'.
834 static constexpr bool value = true;
835 };
836 };
837
838 public:
839
840 /**
841 * Returns the message for debug messages.
842 * Debug messages do not show up on release builds.<br>
843 * The debug log is intended to simplify code like this:
844 * @code
845 * #ifdef OCEAN_DEBUG
846 * info() << "<debug> This message shows up on debug builds only."
847 * #endif
848 * @endcode
849 * @return The message object that will be stripped away on release builds
850 */
851 static inline DebugMessageObject debug();
852
853 /**
854 * Returns the message for information messages.
855 * @return The message object
856 */
857 static inline MessageObject info();
858
859 /**
860 * Returns the message for warning messages.
861 * @return The message object
862 */
863 static inline MessageObject warning();
864
865 /**
866 * Returns the message for error messages.
867 * @return The message object
868 */
869 static inline MessageObject error();
870
871 /**
872 * Returns whether a specific data type can be written to a message object (or an arbitrary stream).
873 * The function returns whether the shift operator of MessageObject (or of an arbitrary stream) supports the specified data type.
874 * Usage:
875 * @code
876 * void function()
877 * {
878 * int value = 9;
879 *
880 * if constexpr (Log::isSupported<int>())
881 * {
882 * Log::info() << "Value is: " << value;
883 * }
884 * else
885 * {
886 * Log::info() << "Value cannot be written to log.";
887 * }
888 * }
889 * @endcode
890 * @return True, if so
891 * @tparam T The data type to be checked
892 * @tparam TStream The data type of the message object (or stream) to be checked
893 */
894 template <typename T, typename TStream = MessageObject>
895 static constexpr bool isSupported();
896};
897
898inline Messenger::MessageOutput Messenger::outputType() const
899{
900 const ScopedLock scopedLock(lock_);
901 return outputType_;
902}
903
904inline size_t Messenger::informations() const
905{
906 const ScopedLock scopedLock(lock_);
907 return informationMessageQueue_.size();
908}
909
910inline size_t Messenger::warnings() const
911{
912 const ScopedLock scopedLock(lock_);
913 return warningMessageQueue_.size();
914}
915
916inline size_t Messenger::errors() const
917{
918 const ScopedLock scopedLock(lock_);
919 return errorMessageQueue_.size();
920}
921
922inline bool Messenger::integrateDateTime() const
923{
924 const ScopedLock scopedLock(lock_);
925 return integrateDateTime_;
926}
927
928inline bool Messenger::empty() const
929{
930 const ScopedLock scopedLock(lock_);
931 return informationMessageQueue_.empty() && warningMessageQueue_.empty() && errorMessageQueue_.empty();
932}
933
934template <bool tActive>
935inline MessageObject<tActive>::MessageObject(const MessageType type) :
936 type_(type)
937{
938 // nothing to do here
939}
940
941template <bool tActive>
942inline MessageObject<tActive>::MessageObject(const MessageType type, std::string&& location) :
943 location_(std::move(location)),
944 type_(type)
945{
946 // nothing to do here
947}
948
949template <bool tActive>
950inline MessageObject<tActive>::MessageObject(const MessageType type, std::string&& location, std::string&& message) :
951 message_(std::move(message)),
952 location_(std::move(location)),
953 type_(type)
954{
955 // nothing to do here
956}
957
958template <bool tActive>
959inline MessageObject<tActive>::~MessageObject()
960{
961 if (!message_.empty())
962 {
963 Messenger::get().push(type_, std::move(location_), std::move(message_));
964 }
965}
966
967template <bool tActive>
968inline MessageObject<tActive>& MessageObject<tActive>::newLine(const bool condition)
969{
970 if (condition)
971 {
972 message_ += "\n";
973 }
974
975 return *this;
976}
977
978template <bool tActive>
979inline MessageObject<tActive>& MessageObject<tActive>::operator<<(std::string&& message)
980{
981 if (message_.empty())
982 {
983 message_ = std::move(message);
984 }
985 else
986 {
987 message_ += message;
988 }
989
990 return *this;
991}
992
993template <bool tActive>
994inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const std::string& message)
995{
996 message_ += message;
997 return *this;
998}
999
1000template <bool tActive>
1001inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const char* message)
1002{
1003 if (message != nullptr)
1004 {
1005 message_ += std::string(message);
1006 }
1007
1008 return *this;
1009}
1010
1011template <bool tActive>
1012inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const double message)
1013{
1014 message_ += String::toAString(message);
1015 return *this;
1016}
1017
1018template <bool tActive>
1019inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const float message)
1020{
1021 message_ += String::toAString(message);
1022 return *this;
1023}
1024
1025template <bool tActive>
1026inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const int message)
1027{
1028 message_ += String::toAString(message);
1029 return *this;
1030}
1031
1032template <bool tActive>
1033inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const unsigned int message)
1034{
1035 message_ += String::toAString(message);
1036 return *this;
1037}
1038
1039template <bool tActive>
1040inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const long message)
1041{
1042 message_ += String::toAString(message);
1043 return *this;
1044}
1045
1046template <bool tActive>
1047inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const long long message)
1048{
1049 message_ += String::toAString(message);
1050 return *this;
1051}
1052
1053template <bool tActive>
1054inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const unsigned long long message)
1055{
1056 message_ += String::toAString(message);
1057 return *this;
1058}
1059
1060template <bool tActive>
1061inline MessageObject<tActive>& MessageObject<tActive>::operator<<(const long unsigned int message)
1062{
1063 message_ += String::toAString(message);
1064 return *this;
1065}
1066
1067template <bool tActive>
1068inline void MessageObject<tActive>::operator<<(const MessageObject<tActive>& messageObject)
1069{
1070 ocean_assert_and_suppress_unused(messageObject.type_ == Messenger::TYPE_UNDEFINED, messageObject);
1071
1072 if (!message_.empty())
1073 {
1074 Messenger::get().push(type_, std::string(location_), std::move(message_));
1075 }
1076
1077 message_.clear();
1078}
1079
1080inline Log::DebugMessageObject Log::debug()
1081{
1082 return DebugMessageObject(Messenger::TYPE_DEBUG);
1083}
1084
1085inline Log::MessageObject Log::info()
1086{
1087 return MessageObject(Messenger::TYPE_INFORMATION);
1088}
1089
1090inline Log::MessageObject Log::warning()
1091{
1092 return MessageObject(Messenger::TYPE_WARNING);
1093}
1094
1095inline Log::MessageObject Log::error()
1096{
1097 return MessageObject(Messenger::TYPE_ERROR);
1098}
1099
1100template <typename T, typename TStream>
1101constexpr bool Log::isSupported()
1102{
1103 return StreamHelper<TStream>::template ShiftOperatorChecker<T>::value;
1104}
1105
1106}
1107
1108#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:792
MessageObject & operator<<(std::string &&)
Pushes another information message.
Definition Messenger.h:667
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:658
MessageObject(const MessageType)
Creates a new message object.
Definition Messenger.h:621
MessageObject & operator<<(const long long)
Pushes another information message.
Definition Messenger.h:739
MessageObject & operator<<(const long unsigned int)
Pushes another information message.
Definition Messenger.h:757
void operator<<(const MessageObject &)
Pushes another information message.
Definition Messenger.h:765
MessageObject & operator=(const MessageObject &messageObject)=default
Assign operator.
MessageObject & operator<<(const long)
Pushes another information message.
Definition Messenger.h:730
MessageObject & operator<<(const float)
Pushes another information message.
Definition Messenger.h:703
MessageObject & operator<<(const std::string &)
Pushes another information message.
Definition Messenger.h:676
MessageObject & newLine()
Adds a new line to this message object if a specified condition holds.
Definition Messenger.h:649
MessageObject & operator<<(const int)
Pushes another information message.
Definition Messenger.h:712
~MessageObject()=default
Destructs a message object.
MessageObject & operator<<(const char *)
Pushes another information message.
Definition Messenger.h:685
MessageObject(const MessageType, std::string &&)
Creates a new message object.
Definition Messenger.h:629
MessageObject & operator<<(const double)
Pushes another information message.
Definition Messenger.h:694
MessageObject(const MessageType, std::string &&, std::string &&)
Creates a new message object.
Definition Messenger.h:781
MessageObject & operator<<(const unsigned long long)
Pushes another information message.
Definition Messenger.h:748
MessageObject & operator<<(const unsigned int)
Pushes another information message.
Definition Messenger.h:721
Messenger object, one object for each message.
Definition Messenger.h:448
std::string message_
Entire message.
Definition Messenger.h:591
std::string location_
Location of the message.
Definition Messenger.h:594
MessageObject & newLine(const bool condition=true)
Adds a new line to this message object if a specified condition holds.
Definition Messenger.h:968
MessageObject & operator<<(std::string &&message)
Pushes another information message.
Definition Messenger.h:979
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:959
Messenger::MessageType type_
Type of this messenger.
Definition Messenger.h:597
This class implements a messenger for information, warning or error messages.
Definition Messenger.h:93
static void writeMessageToLogApple(const MessageType messageType, const std::string &message)
Writes a message to Apple's log system.
static constexpr bool isActive()
Returns whether the messenger is active on this build.
Definition Messenger.h:421
void queueMessage(const MessageType messageType, std::string &&locationAndTime, std::string &&message)
Queues a message.
std::string lastErrorMessage_
Last error message.
Definition Messenger.h:403
static constexpr bool isDebugBuild()
Returns whether the messenger is used on a debug build.
Definition Messenger.h:430
MessageQueue informationMessageQueue_
Information message queue.
Definition Messenger.h:388
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:415
MessageQueue errorMessageQueue_
Error message queue.
Definition Messenger.h:394
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:400
bool setOutputStream(std::ostream &stream)
Sets the message output to an output stream.
void clear()
Clears all message queues.
std::queue< Message > MessageQueue
Definition of a message queue.
Definition Messenger.h:147
std::ofstream fileOutputStream_
File output stream.
Definition Messenger.h:406
MessageQueue debugMessageQueue_
Debug message queue.
Definition Messenger.h:381
std::pair< std::string, std::string > Message
Definition of a message.
Definition Messenger.h:142
static void writeToDebugOutput(const std::string &message)
Writes a message to the most suitable debug output of the current platform.
MessageQueue warningMessageQueue_
Warning message queue.
Definition Messenger.h:391
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:384
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:397
bool popInformation(std::string &location, std::string &message, bool *isNew=nullptr)
Pops the first information message from the message queue.
static void writeMessageToLogAndroid(const MessageType messageType, const std::string &locationAndTime, const std::string &message)
Writes a message to the Android log system (logcat).
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:820
Helper class allowing to specify a specific message object or stream type.
Definition Messenger.h:813