1 #pragma once
2 
3 #include <mbgl/util/event.hpp>
4 
5 #include <mbgl/util/noncopyable.hpp>
6 
7 #include <memory>
8 #include <string>
9 
10 namespace mbgl {
11 
12 class Log {
13 public:
14     class Observer : private util::noncopyable {
15     public:
16         virtual ~Observer() = default;
17 
18         // When an observer is set, this function will be called for every log
19         // message. Returning true will consume the message.
20         virtual bool onRecord(EventSeverity severity, Event event, int64_t code, const std::string &msg) = 0;
21     };
22 
23     class NullObserver : public Observer {
onRecord(EventSeverity,Event,int64_t,const std::string &)24         bool onRecord(EventSeverity, Event, int64_t, const std::string&) override {
25             return true;
26         }
27     };
28 
29     static void setObserver(std::unique_ptr<Observer> Observer);
30     static std::unique_ptr<Observer> removeObserver();
31 
32 private:
33     template <typename T, size_t N>
includes(const T e,const T (& l)[N],const size_t i=0)34     constexpr static bool includes(const T e, const T (&l)[N], const size_t i = 0) {
35         return i < N && (l[i] == e || includes(e, l, i + 1));
36     }
37 
38 public:
39     template <typename ...Args>
Debug(Event event,Args &&...args)40     static void Debug(Event event, Args&& ...args) {
41         Record(EventSeverity::Debug, event, ::std::forward<Args>(args)...);
42     }
43 
44     template <typename ...Args>
Info(Event event,Args &&...args)45     static void Info(Event event, Args&& ...args) {
46         Record(EventSeverity::Info, event, ::std::forward<Args>(args)...);
47     }
48 
49     template <typename ...Args>
Warning(Event event,Args &&...args)50     static void Warning(Event event, Args&& ...args) {
51         Record(EventSeverity::Warning, event, ::std::forward<Args>(args)...);
52     }
53 
54     template <typename ...Args>
Error(Event event,Args &&...args)55     static void Error(Event event, Args&& ...args) {
56         Record(EventSeverity::Error, event, ::std::forward<Args>(args)...);
57     }
58 
59     template <typename ...Args>
Record(EventSeverity severity,Event event,Args &&...args)60     static void Record(EventSeverity severity, Event event, Args&& ...args) {
61         if (!includes(severity, disabledEventSeverities) &&
62             !includes(event, disabledEvents) &&
63             !includes({ severity, event }, disabledEventPermutations)) {
64                 record(severity, event, ::std::forward<Args>(args)...);
65         }
66     }
67 
68 private:
69     static void record(EventSeverity severity, Event event, const std::string &msg);
70     static void record(EventSeverity severity, Event event, const char* format = "", ...);
71     static void record(EventSeverity severity, Event event, int64_t code, const char* format = "", ...);
72     static void record(EventSeverity severity, Event event, int64_t code, const std::string &msg);
73 
74     // This method is the data sink that must be implemented by each platform we
75     // support. It should ideally output the error message in a human readable
76     // format to the developer.
77     static void platformRecord(EventSeverity severity, const std::string &msg);
78 };
79 
80 } // namespace mbgl
81