Panda3D
Loading...
Searching...
No Matches
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 */
50template<class GetCategory>
52public:
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 */
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.
94 INLINE operator NotifyCategory * ();
95
96private:
97 NotifyCategory *_ptr;
98};
99
100template<class GetCategory>
101INLINE 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.