Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
class.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_CORE_CLASS_H_)
21 #define __MITSUBA_CORE_CLASS_H_
22 
24 
25 /**
26  * \headerfile mitsuba/core/class.h mitsuba/mitsuba.h
27  * \brief Stores meta-information about \ref Object instances.
28  *
29  * This class provides a thin layer of RTTI (run-time type information),
30  * which is useful for doing things like:
31  *
32  * <ul>
33  * <li> Checking if an object derives from a certain class </li>
34  * <li> Determining the parent of a class at runtime </li>
35  * <li> Instantiating a class by name </li>
36  * <li> Unserializing a class from a binary data stream </li>
37  * </ul>
38  *
39  * \sa ref, Object
40  * \ingroup libcore
41  * \ingroup librender
42  */
44 public:
45  /**
46  * \brief Construct a new class descriptor
47  *
48  * This method should never be called manually. Instead, use
49  * one of the \ref MTS_IMPLEMENT_CLASS, \ref MTS_IMPLEMENT_CLASS_S,
50  * \ref MTS_IMPLEMENT_CLASS_I or \ref MTS_IMPLEMENT_CLASS_IS macros
51  * to automatically do this for you.
52  *
53  * \param name Name of the class
54  * \param abstract \c true if the class contains pure virtual methods
55  * \param superClassName Name of the parent class
56  * \param instPtr Pointer to an instantiation function
57  * \param unSerPtr Pointer to an unserialization function
58  */
59  Class(const std::string &name, bool abstract, const std::string &superClassName,
60  void *instPtr = NULL, void *unSerPtr = NULL);
61 
62  /// Return the name of the represented class
63  inline const std::string &getName() const { return m_name; }
64 
65  /**
66  * \brief Return whether or not the class represented
67  * by this Class object contains pure virtual methods
68  */
69  inline bool isAbstract() const { return m_abstract; }
70 
71  /// Does the class support instantiation over RTTI?
72  inline bool isInstantiable() const { return m_instPtr != NULL; }
73 
74  /// Does the class support serialization?
75  inline bool isSerializable() const { return m_unSerPtr != NULL; }
76 
77  /** \brief Return the Class object associated with the parent
78  * class of NULL if it does not have one.
79  */
80  inline const Class *getSuperClass() const { return m_superClass; }
81 
82  /// Check whether this class derives from \a theClass
83  bool derivesFrom(const Class *theClass) const;
84 
85  /// Look up a class by its name
86  static const Class *forName(const std::string &name);
87 
88  /** \brief Look up a class by its name. Avoids allocating
89  * heap space by taking a character array as parameter
90  */
91  static const Class *forName(const char *name);
92 
93  /** \brief Unserialize an instance of the class (if this is
94  * supported).
95  */
96  Object *unserialize(Stream *stream = NULL, InstanceManager *manager = NULL) const;
97 
98  /// Generate an instance of this class (if this is supported)
99  Object *instantiate() const;
100 
101  /// Check if the RTTI layer has been initialized
102  static inline bool rttiIsInitialized() { return m_isInitialized; }
103 
104  /** \brief Initializes the built-in RTTI and creates
105  * a list of all compiled classes
106  */
107  static void staticInitialization();
108 
109  /// Free the memory taken by staticInitialization()
110  static void staticShutdown();
111 private:
112  /** \brief Initialize a class - called by
113  * staticInitialization()
114  */
115  static void initializeOnce(Class *theClass);
116 private:
117  std::string m_name;
118  bool m_abstract;
119  Class *m_superClass;
120  std::string m_superClassName;
121  void *m_instPtr, *m_unSerPtr;
122  static bool m_isInitialized;
123 };
124 
125 /*! \addtogroup libcore */
126 
127 /*! @{ */
128 
129 /**
130  * \brief Return the \ref Class object corresponding to a named class.
131  *
132  * Call the Macro without quotes, e.g. \c MTS_CLASS(SerializableObject)
133  */
134 #define MTS_CLASS(x) x::m_theClass
135 
136 /**
137  * \brief This macro must be used in the initial definition in
138  * classes that derive from \ref Object.
139  *
140  * This is needed for the basic RTTI support provided by Mitsuba objects.
141  * For instance, a class definition might look like the following:
142  *
143  * \code
144  * class MyObject : public Object {
145  * public:
146  * MyObject();
147  *
148  * /// Important: declare RTTI data structures
149  * MTS_DECLARE_CLASS()
150  * protected:
151  * /// Important: needs to declare a protected virtual destructor
152  * virtual ~MyObject();
153  *
154  * };
155  * \endcode
156  *
157  */
158 #define MTS_DECLARE_CLASS() \
159  virtual const Class *getClass() const; \
160 public: \
161  static Class *m_theClass;
162 
163 /**
164  * \brief Creates basic RTTI support for a class
165  *
166  * This macro or one of its variants should be invoked in the main
167  * implementation \c .cpp file of any class that derives from \ref Object.
168  * This is needed for the basic RTTI support provided by Mitsuba objects.
169  * For instance, the corresponding piece for the example shown in the
170  * documentation of \ref MTS_DECLARE_CLASS might look like this:
171  *
172  * \code
173  * MTS_IMPLEMENT_CLASS(MyObject, false, Object)
174  * \endcode
175  *
176  * \param name Name of the class
177  * \param abstract \c true if the class contains pure virtual methods
178  * \param super Name of the parent class
179  */
180 #define MTS_IMPLEMENT_CLASS(name, abstract, super) \
181  Class *name::m_theClass = new Class(#name, abstract, #super); \
182  const Class *name::getClass() const { \
183  return m_theClass;\
184  }
185 
186 /**
187  * \brief Creates basic RTTI support for a class. To be used when the class
188  * has a \a simple constructor (i.e. one wich does not take any arguments)
189  *
190  * This macro or one of its variants should be invoked in the main
191  * implementation \c .cpp file of any class that derives from \ref Object.
192  * This is needed for the basic RTTI support provided by Mitsuba objects.
193  *
194  * \param name Name of the class
195  * \param abstract \c true if the class contains pure virtual methods
196  * \param super Name of the parent class
197  */
198 #define MTS_IMPLEMENT_CLASS_I(name, abstract, super) \
199  Object *__##name ##_inst() { \
200  return new name(); \
201  } \
202  Class *name::m_theClass = new Class(#name, abstract, #super, (void *) &__##name ##_inst, NULL); \
203  const Class *name::getClass() const { \
204  return m_theClass;\
205  }
206 
207 /**
208  * \brief Creates basic RTTI support for a class. To be used when the class
209  * can be unserialized from a binary data stream.
210  *
211  * This macro or one of its variants should be invoked in the main
212  * implementation \c .cpp file of any class that derives from \ref Object.
213  * This is needed for the basic RTTI support provided by Mitsuba objects.
214  *
215  * \param name Name of the class
216  * \param abstract \c true if the class contains pure virtual methods
217  * \param super Name of the parent class
218  */
219 #define MTS_IMPLEMENT_CLASS_S(name, abstract, super) \
220  Object *__##name ##_unSer(Stream *stream, InstanceManager *manager) { \
221  return new name(stream, manager); \
222  } \
223  Class *name::m_theClass = new Class(#name, abstract, #super, NULL, (void *) &__##name ##_unSer); \
224  const Class *name::getClass() const { \
225  return m_theClass;\
226  }
227 
228 /**
229  * \brief Creates basic RTTI support for a class. To be used when the class
230  * can be unserialized from a binary data stream as well as instantiated
231  * by a constructor that does not take any arguments.
232  *
233  * This macro or one of its variants should be invoked in the main
234  * implementation \c .cpp file of any class that derives from \ref Object.
235  * This is needed for the basic RTTI support provided by Mitsuba objects.
236  *
237  * \param name Name of the class
238  * \param abstract \c true if the class contains pure virtual methods
239  * \param super Name of the parent class
240  */
241 #define MTS_IMPLEMENT_CLASS_IS(name, abstract, super) \
242  Object *__##name ##_unSer(Stream *stream, InstanceManager *manager) { \
243  return new name(stream, manager); \
244  } \
245  Object *__##name ##_inst() { \
246  return new name(); \
247  } \
248  Class *name::m_theClass = new Class(#name, abstract, #super, (void *) &__##name ##_inst, (void *) &__##name ##_unSer); \
249  const Class *name::getClass() const { \
250  return m_theClass;\
251  }
252 
253 /*! @} */
254 
256 
257 #endif /* __MITSUBA_CORE_CLASS_H_ */
258 
const Class * getSuperClass() const
Return the Class object associated with the parent class of NULL if it does not have one...
Definition: class.h:80
bool isAbstract() const
Return whether or not the class represented by this Class object contains pure virtual methods...
Definition: class.h:69
const std::string & getName() const
Return the name of the represented class.
Definition: class.h:63
#define MTS_EXPORT_CORE
Definition: getopt.h:29
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
static bool rttiIsInitialized()
Check if the RTTI layer has been initialized.
Definition: class.h:102
bool isInstantiable() const
Does the class support instantiation over RTTI?
Definition: class.h:72
bool isSerializable() const
Does the class support serialization?
Definition: class.h:75
Stores meta-information about Object instances.
Definition: class.h:43
Parent of all Mitsuba classes.
Definition: object.h:38
#define MTS_NAMESPACE_END
Definition: platform.h:138