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
A handy wrapper around a NotifyCategory pointer.
NotifyCategory & operator*()
This operator handles the case of dereferencing the proxy object as if it were a pointer,...
NotifyCategory * get_unsafe_ptr()
Returns a pointer which is assumed to have been already initialized.
NotifyCategory * init()
Initializes the proxy object by calling get_category() on the template class.
NotifyCategory * get_safe_ptr()
Returns a pointer which is *not* assumed to have been already initialized; if necessary,...
NotifyCategory * operator->()
This magic operator function defines the syntax proxy->info(), etc., for all of the methods that are ...
A particular category of error messages.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.