IMP  2.0.1
The Integrative Modeling Platform
declare_Object.h
Go to the documentation of this file.
1 /**
2  * \file IMP/base/declare_Object.h
3  * \brief A shared base class to help in debugging and things.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPBASE_DECLARE_OBJECT_H
10 #define IMPBASE_DECLARE_OBJECT_H
11 
12 #include <IMP/base/base_config.h>
13 #include "RefCounted.h"
14 #include "ref_counted_macros.h"
15 #include "enums.h"
16 #include "hash_macros.h"
17 #include "warning_macros.h"
18 #include "showable_macros.h"
19 #include "VersionInfo.h"
20 #include "utility_macros.h"
21 #include <IMP/base/hash.h>
22 #include "hash.h"
23 #include <boost/scoped_array.hpp>
24 
25 #if !defined(IMP_HAS_CHECKS)
26  #error "IMP_HAS_CHECKS not defined, something is broken"
27 #endif
28 #if !defined(IMP_NONE)
29  #error "IMP_NONE not defined, something is broken"
30 #endif
31 #if !defined(IMP_HAS_LOG)
32  #error "IMP_HAS_LOG not defined, something is broken"
33 #endif
34 #if !defined(IMP_SILENT)
35  #error "IMP_SILENT not defined, something is broken"
36 #endif
37 IMPBASE_BEGIN_NAMESPACE
38 
39 //! Common base class for heavy weight \imp objects.
40 /** The base class for non value-type objects in \imp.
41  Anything inheriting from IMP::Object has the following
42  properties:
43  - has a method Object::show() which writes one or more lines of text
44  to a stream
45  - has embedded information about the module and version which can be
46  accessed using Object::get_version_info(). This information can be
47  used to log what version of software is used to compute a result.
48  - it has a local logging level which can override the global one
49  allowing fine grained logging control.
50  - in python, there is a method Class::get_from(Object *o) that attempts
51  to case o to an object of type Class and throws and exception if it
52  fails.
53  - the object keeps track of whether it has been been used. See the
54  IMP::Object::set_was_used() method for an explanation.
55 
56  Objects can be outputted to standard streams using operator<<()
57  which will call the Object::show() method.
58 
59  \headerfile Object.h "IMP/base/Object.h"
60 
61  \advanceddoc Types inheriting from Object should always be created using
62  \c new in C++ and passed using pointers and stored using
63  IMP::Pointer objects. Note that you have to be careful of cycles
64  and so must use IMP::WeakPointer objects to break cycles. See
65  IMP::RefCounted for more information on reference counting. IMP_NEW()
66  can help shorten creating a ref counted pointer. See IMP::Pointer for
67  more information.
68  */
69 class IMPBASEEXPORT Object: public RefCounted
70 {
71  std::string name_;
72  boost::scoped_array<char> quoted_name_;
73  int compare(const Object &o) const {
74  if (&o < this) return 1;
75  else if (&o > this) return -1;
76  else return 0;
77  }
79 protected:
80  //! Construct an object with the given name
81  /** An instance of "%1%" in the string will be replaced by a unique
82  index.
83  */
84  Object(std::string name);
85 public:
86  // needed for python to make sure all wrapper objects are equivalent
87  IMP_HASHABLE_INLINE(Object, return boost::hash_value(this););
88 
89  //! Set the logging level used in this object
90  /** Each object can be assigned a different log level in order to,
91  for example, suppress messages for verbose and uninteresting
92  objects. If set to DEFAULT, the global level as returned by
93  IMP::get_log_level() is used, otherwise
94  the local one is used. Methods in classes inheriting from
95  Object should start with IMP_OBJECT_LOG to change the log
96  level to the local one for this object and increase
97  the current indent.
98  */
99  void set_log_level(LogLevel l);
100 
101  /** Each object can be assigned a different check level too.
102  */
104  IMP_CHECK_VARIABLE(l);
105 #if IMP_HAS_CHECKS != IMP_NONE
106  check_level_=l;
107 #endif
108  }
109 
110 #ifndef IMP_DOXYGEN
111  LogLevel get_log_level() const {
112 #if IMP_HAS_LOG == IMP_SILENT
113  return SILENT;
114 #else
115  return log_level_;
116 #endif
117  }
118  CheckLevel get_check_level() const {
119 #if IMP_HAS_CHECKS == IMP_NONE
120  return NONE;
121 #else
122  return check_level_;
123 #endif
124  }
125 #endif // IMP_DOXYGEN
126 
127 #ifndef IMP_DOXYGEN
128  void _debugger_show() const {
129  show(std::cout);
130  }
131 
132  //! Return a string version of the object, can be used in the debugger
133  std::string get_string() const {
134  std::ostringstream oss;
135  show(oss);
136  return oss.str();
137  }
138 #endif // IMP_DOXYGEN
139 
140  //! Get information about the module and version of the object
141  virtual IMP::base::VersionInfo get_version_info() const=0;
142 
143  /** @name Names
144  All objects have names to aid in debugging and inspection
145  of the state of the system. These names are not necessarily unique
146  and should not be used to store data or as keys into a table. Use
147  the address of the object instead since objects cannot be copied.
148  @{
149  */
150  const std::string& get_name() const {
151  return name_;
152  }
153 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
154  const char* get_quoted_name_c_string() const {
155  return quoted_name_.get();
156  }
157 #endif
158  void set_name(std::string name);
159  /* @} */
160 
161 
162  /** \imp provides warnings when objects are never used before they are
163  destroyed. Examples of use include adding an IMP::Restraint to an
164  IMP::Model. If an object is not properly marked as used, or your
165  code is the one using it, call set_was_used(true) on the object.
166  */
167  void set_was_used(bool tf) const {
168  IMP_CHECK_VARIABLE(tf);
169 #if IMP_HAS_CHECKS >= IMP_USAGE
170  was_owned_=tf;
171 #endif
172  }
173 
175 
176 #ifndef IMP_DOXYGEN
177  void _on_destruction();
178 #endif
179 
180  /** Objects can have internal caches. This method resets them returning
181  the object to its just-initialized state.
182  */
183  virtual void clear_caches() {}
184 
185  private:
186 #if IMP_HAS_CHECKS >= IMP_INTERNAL
187  static void add_live_object(Object*o);
188  static void remove_live_object(Object*o);
189 #endif
190 #if IMP_HAS_LOG != IMP_NONE
191  LogLevel log_level_;
192 #endif
193 #if IMP_HAS_CHECKS >= IMP_USAGE
194  CheckLevel check_level_;
195  mutable bool was_owned_;
196 #endif
197 };
198 
199 
200 IMPBASE_END_NAMESPACE
201 
202 #endif /* IMPBASE_DECLARE_OBJECT_H */