Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

dtool/src/dconfig/notifyCategoryProxy.h

Go to the documentation of this file.
00001 // Filename: notifyCategoryProxy.h
00002 // Created by:  drose (04Mar00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #ifndef NOTIFYCATEGORYPROXY_H
00020 #define NOTIFYCATEGORYPROXY_H
00021 
00022 #include <dtoolbase.h>
00023 
00024 #include "notifyCategory.h"
00025 #include "notifySeverity.h"
00026 #include "notify.h"
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //       Class : NotifyCategoryProxy
00030 // Description : A handy wrapper around a NotifyCategory pointer.
00031 //               This wrapper pretends to be a NotifyCategory object
00032 //               itself, except that it is capable of initializing its
00033 //               pointer if it is NULL.
00034 //
00035 //               The advantage to this over a normal pointer is that
00036 //               it can be used in functions that run at static init
00037 //               time, without worrying about ordering issues among
00038 //               static init routines.  If the pointer hasn't been
00039 //               initialized yet, no sweat; it can initialize itself.
00040 //
00041 //               This must be a template class so it can do this
00042 //               magic; it templates on a class with a static method
00043 //               called get_category() that returns a new pointer to
00044 //               the NotifyCategory.  This way the compiler can
00045 //               generate correct static-init-independent code to
00046 //               initialize the proxy.
00047 //
00048 //               In general, if the proxy object is treated as if it
00049 //               were itself a NotifyCategory object, then it doesn't
00050 //               check whether its category is initialized, and so may
00051 //               not be run at static init time.  That is, you may
00052 //               call proxy.info(), but only when you are not running
00053 //               at static init time.  This is an optimization so you
00054 //               can avoid this unnecessary check when you know (as in
00055 //               most cases) the code does not run at static init.
00056 //
00057 //               On the other hand, if the proxy object is treated as
00058 //               if it were a *pointer* to a NotifyCategory object,
00059 //               then it *does* check whether its category is
00060 //               initialized; you may safely use it in this way at
00061 //               static init time.  Thus, you may call proxy->info()
00062 //               safely whenever you like.
00063 ////////////////////////////////////////////////////////////////////
00064 template<class GetCategory>
00065 class NotifyCategoryProxy {
00066 public:
00067   // This should be set to be called at static init time; it
00068   // initializes the pointer if it is not already.
00069   NotifyCategory *init();
00070 
00071   // You don't normally need to call these directly, but they're here
00072   // anyway.  get_unsafe_ptr() assumes the pointer has been
00073   // initialized; it should be called only when you know static init
00074   // has completed (i.e. in any function that is not executing at
00075   // static init time).  get_safe_ptr() should be called when it is
00076   // possible that static init has not yet completed (i.e. in a
00077   // function that might execute at static init time); it calls init()
00078   // first.
00079   INLINE NotifyCategory *get_unsafe_ptr();
00080   INLINE NotifyCategory *get_safe_ptr();
00081 
00082   // The following functions, which may be accessed using the
00083   // proxy.function() syntax, call get_unsafe_ptr().  They should be
00084   // used only in non-static-init functions.
00085 
00086   INLINE bool is_on(NotifySeverity severity);
00087 
00088   INLINE bool is_spam();
00089   INLINE bool is_debug();
00090   INLINE bool is_info();
00091   INLINE bool is_warning();
00092   INLINE bool is_error();
00093   INLINE bool is_fatal();
00094 
00095   INLINE ostream &out(NotifySeverity severity, bool prefix = true);
00096   INLINE ostream &spam(bool prefix = true);
00097   INLINE ostream &debug(bool prefix = true);
00098   INLINE ostream &info(bool prefix = true);
00099   INLINE ostream &warning(bool prefix = true);
00100   INLINE ostream &error(bool prefix = true);
00101   INLINE ostream &fatal(bool prefix = true);
00102 
00103   // The same functions as above, when accessed using
00104   // proxy->function() syntax, call get_safe_ptr().  These can be used
00105   // safely either in static-init or non-static-init functions.
00106   INLINE NotifyCategory *operator -> ();
00107   INLINE NotifyCategory &operator * ();
00108   INLINE operator NotifyCategory * ();
00109 
00110 private:
00111   NotifyCategory *_ptr;
00112 };
00113 
00114 template<class GetCategory>
00115 INLINE ostream &operator << (ostream &out, NotifyCategoryProxy<GetCategory> &proxy) {
00116   return out << proxy->get_fullname();
00117 }
00118 
00119 // Finally, here is a set of handy macros to define and reference a
00120 // NotifyCategoryProxy object in each package.
00121 
00122 // Following the config convention, this macro defines an external
00123 // reference to a suitable NotifyCategoryProxy object; it should
00124 // appear in the config_*.h file.  The proxy object will be named
00125 // basename_cat.
00126 
00127 #if defined(WIN32_VC) && !defined(CPPPARSER)
00128 
00129 #define NotifyCategoryDecl(basename, expcl, exptp) \
00130   class expcl NotifyCategoryGetCategory_ ## basename { \
00131   public: \
00132     NotifyCategoryGetCategory_ ## basename(); \
00133     static NotifyCategory *get_category(); \
00134   }; \
00135   exptp template class expcl NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename>; \
00136   extern expcl NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat;
00137 
00138 #else // WIN32_VC
00139 
00140 #define NotifyCategoryDecl(basename, expcl, exptp) \
00141   class NotifyCategoryGetCategory_ ## basename { \
00142   public: \
00143     NotifyCategoryGetCategory_ ## basename(); \
00144     static NotifyCategory *get_category(); \
00145   }; \
00146   extern NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat;
00147 
00148 #endif  // WIN32_VC
00149 
00150 // This macro is the same as the above, except that it declares a category
00151 // that is not intended to be exported from any DLL.
00152 
00153 #define NotifyCategoryDeclNoExport(basename) \
00154   class NotifyCategoryGetCategory_ ## basename { \
00155   public: \
00156     NotifyCategoryGetCategory_ ## basename(); \
00157     static NotifyCategory *get_category(); \
00158   }; \
00159   extern NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat;
00160 
00161 // This macro defines the actual declaration of the
00162 // NotifyCategoryProxy object defined above; it should appear in the
00163 // config_*.C file.  In this macro, parent_category may either be the
00164 // NotifyCategoryProxy object of the parent category
00165 // (e.g. parent_cat), or it may be the quoted fullname of the parent.
00166 
00167 #ifdef CPPPARSER
00168 #define NotifyCategoryDefName(basename, actual_name, parent_category)
00169 #define NotifyCategoryDef(basename, parent_category)
00170 
00171 #else
00172 #define NotifyCategoryDefName(basename, actual_name, parent_category) \
00173   NotifyCategoryProxy<NotifyCategoryGetCategory_ ## basename> basename ## _cat; \
00174   static NotifyCategoryGetCategory_ ## basename force_init_ ## basename ## _cat; \
00175   NotifyCategoryGetCategory_ ## basename:: \
00176   NotifyCategoryGetCategory_ ## basename() { \
00177     basename ## _cat.init(); \
00178   } \
00179   NotifyCategory *NotifyCategoryGetCategory_ ## basename:: \
00180   get_category() { \
00181     return Notify::ptr()->get_category(string(actual_name), parent_category); \
00182   }
00183 #define NotifyCategoryDef(basename, parent_category) \
00184   NotifyCategoryDefName(basename, #basename, parent_category);
00185 
00186 #endif // CPPPARSER
00187 
00188 
00189 #include "notifyCategoryProxy.I"
00190 
00191 #endif

Generated on Thu May 1 22:12:57 2003 for DTool by doxygen1.3