Panda3D
notifyCategoryProxy.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file notifyCategoryProxy.h
10  * @author drose
11  * @date 2000-03-04
12  */
13 
14 #ifndef NOTIFYCATEGORYPROXY_H
15 #define NOTIFYCATEGORYPROXY_H
16 
17 #include "dtoolbase.h"
18 
19 #include "notifyCategory.h"
20 #include "notifySeverity.h"
21 #include "pnotify.h"
22 
23 /**
24  * A handy wrapper around a NotifyCategory pointer. This wrapper pretends to
25  * be a NotifyCategory object itself, except that it is capable of
26  * initializing its pointer if it is NULL.
27  *
28  * The advantage to this over a normal pointer is that it can be used in
29  * functions that run at static init time, without worrying about ordering
30  * issues among static init routines. If the pointer hasn't been initialized
31  * yet, no sweat; it can initialize itself.
32  *
33  * This must be a template class so it can do this magic; it templates on a
34  * class with a static method called get_category() that returns a new pointer
35  * to the NotifyCategory. This way the compiler can generate correct static-
36  * init-independent code to initialize the proxy.
37  *
38  * In general, if the proxy object is treated as if it were itself a
39  * NotifyCategory object, then it doesn't check whether its category is
40  * initialized, and so may not be run at static init time. That is, you may
41  * call proxy.info(), but only when you are not running at static init time.
42  * This is an optimization so you can avoid this unnecessary check when you
43  * know (as in most cases) the code does not run at static init.
44  *
45  * On the other hand, if the proxy object is treated as if it were a *pointer*
46  * to a NotifyCategory object, then it *does* check whether its category is
47  * initialized; you may safely use it in this way at static init time. Thus,
48  * you may call proxy->info() safely whenever you like.
49  */
50 template<class GetCategory>
52 public:
53  // This should be set to be called at static init time; it initializes the
54  // pointer if it is not already.
56 
57 /*
58  * You don't normally need to call these directly, but they're here anyway.
59  * get_unsafe_ptr() assumes the pointer has been initialized; it should be
60  * called only when you know static init has completed (i.e. in any function
61  * that is not executing at static init time). get_safe_ptr() should be
62  * called when it is possible that static init has not yet completed (i.e. in
63  * a function that might execute at static init time); it calls init() first.
64  */
66  INLINE NotifyCategory *get_safe_ptr();
67 
68  // The following functions, which may be accessed using the proxy.function()
69  // syntax, call get_unsafe_ptr(). They should be used only in non-static-
70  // init functions.
71 
72  INLINE bool is_on(NotifySeverity severity);
73 
74  INLINE bool is_spam();
75  INLINE bool is_debug();
76  INLINE bool is_info();
77  INLINE bool is_warning();
78  INLINE bool is_error();
79  INLINE bool is_fatal();
80 
81  INLINE std::ostream &out(NotifySeverity severity, bool prefix = true);
82  INLINE std::ostream &spam(bool prefix = true);
83  INLINE std::ostream &debug(bool prefix = true);
84  INLINE std::ostream &info(bool prefix = true);
85  INLINE std::ostream &warning(bool prefix = true);
86  INLINE std::ostream &error(bool prefix = true);
87  INLINE std::ostream &fatal(bool prefix = true);
88 
89  // The same functions as above, when accessed using proxy->function()
90  // syntax, call get_safe_ptr(). These can be used safely either in static-
91  // init or non-static-init functions.
92  INLINE NotifyCategory *operator -> ();
93  INLINE NotifyCategory &operator * ();
94  INLINE operator NotifyCategory * ();
95 
96 private:
97  NotifyCategory *_ptr;
98 };
99 
100 template<class GetCategory>
101 INLINE std::ostream &operator << (std::ostream &out, NotifyCategoryProxy<GetCategory> &proxy) {
102  return out << proxy->get_fullname();
103 }
104 
105 // Finally, here is a set of handy macros to define and reference a
106 // NotifyCategoryProxy object in each package.
107 
108 // Following the config convention, this macro defines an external reference
109 // to a suitable NotifyCategoryProxy object; it should appear in the
110 // config_*.h file. The proxy object will be named basename_cat.
111 
112 #ifdef CPPPARSER
113 #define NotifyCategoryDecl(basename, expcl, exptp)
114 #else
115 #define NotifyCategoryDecl(basename, expcl, exptp) \
116  class expcl NotifyCategoryGetCategory_ ## basename { \
117  public: \
118  NotifyCategoryGetCategory_ ## basename(); \
119  static NotifyCategory *get_category(); \
120  }; \
121  EXPORT_TEMPLATE_CLASS(expcl, exptp, NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename>); \
122  extern expcl NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat;
123 #endif
124 
125 // This macro is the same as the above, except that it declares a category
126 // that is not intended to be exported from any DLL.
127 
128 #define NotifyCategoryDeclNoExport(basename) \
129  class NotifyCategoryGetCategory_ ## basename { \
130  public: \
131  NotifyCategoryGetCategory_ ## basename(); \
132  static NotifyCategory *get_category(); \
133  }; \
134  extern NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat;
135 
136 // This macro defines the actual declaration of the NotifyCategoryProxy object
137 // defined above; it should appear in the config_*.C file. In this macro,
138 // parent_category may either be the NotifyCategoryProxy object of the parent
139 // category (e.g. parent_cat), or it may be the quoted fullname of the
140 // parent.
141 
142 #ifdef CPPPARSER
143 #define NotifyCategoryDefName(basename, actual_name, parent_category)
144 #define NotifyCategoryDef(basename, parent_category)
145 
146 #else
147 #define NotifyCategoryDefName(basename, actual_name, parent_category) \
148  template class NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename>; \
149  NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat; \
150  static NotifyCategoryGetCategory_ ## basename force_init_ ## basename ## _cat; \
151  NotifyCategoryGetCategory_ ## basename:: \
152  NotifyCategoryGetCategory_ ## basename() { \
153  basename ## _cat.init(); \
154  } \
155  NotifyCategory *NotifyCategoryGetCategory_ ## basename:: \
156  get_category() { \
157  return Notify::ptr()->get_category(std::string(actual_name), parent_category); \
158  }
159 #define NotifyCategoryDef(basename, parent_category) \
160  NotifyCategoryDefName(basename, #basename, parent_category);
161 
162 #endif // CPPPARSER
163 
164 
165 #include "notifyCategoryProxy.I"
166 
167 #endif
notifySeverity.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NotifyCategoryProxy::operator->
NotifyCategory * operator->()
This magic operator function defines the syntax proxy->info(), etc., for all of the methods that are ...
Definition: notifyCategoryProxy.I:200
pnotify.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NotifyCategoryProxy::get_safe_ptr
NotifyCategory * get_safe_ptr()
Returns a pointer which is *not* assumed to have been already initialized; if necessary,...
Definition: notifyCategoryProxy.I:52
NotifyCategoryProxy::operator*
NotifyCategory & operator*()
This operator handles the case of dereferencing the proxy object as if it were a pointer,...
Definition: notifyCategoryProxy.I:211
dtoolbase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NotifyCategoryProxy::init
NotifyCategory * init()
Initializes the proxy object by calling get_category() on the template class.
Definition: notifyCategoryProxy.I:20
NotifyCategoryProxy
A handy wrapper around a NotifyCategory pointer.
Definition: notifyCategoryProxy.h:51
notifyCategoryProxy.I
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
notifyCategory.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NotifyCategoryProxy::get_unsafe_ptr
NotifyCategory * get_unsafe_ptr()
Returns a pointer which is assumed to have been already initialized.
Definition: notifyCategoryProxy.I:35
NotifyCategory
A particular category of error messages.
Definition: notifyCategory.h:32