bddfdcf6ca513beb448c70bff9b6906e43890e83
[ardour.git] / libs / glibmm2 / glibmm / objectbase.h
1 // -*- c++ -*-
2 #ifndef _GLIBMM_OBJECTBASE_H
3 #define _GLIBMM_OBJECTBASE_H
4
5 /* $Id$ */
6
7 /* Copyright 2002 The gtkmm Development Team
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the Free
21  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include <glibmm/signalproxy.h>
25 #include <glibmm/propertyproxy.h>
26 #include <sigc++/trackable.h>
27 #include <typeinfo>
28 #include <glibmmconfig.h>
29 #include <glibmm/debug.h>
30
31 GLIBMM_USING_STD(type_info)
32
33 #ifndef DOXYGEN_SHOULD_SKIP_THIS
34 extern "C" { typedef struct _GObject GObject; }
35 #endif
36
37
38 namespace Glib
39 {
40
41 #ifndef DOXYGEN_SHOULD_SKIP_THIS
42 class GSigConnectionNode;
43 #endif
44
45 //This inherits virtually from sigc::trackable so that people can multiply inherit glibmm classes from other sigc::trackable-derived classes.
46 //See bugzilla.gnome.org bug # 116280
47 class ObjectBase : virtual public sigc::trackable
48 {
49 protected:
50   // Glib::ObjectBase is used as virtual base class.  This means the ObjectBase
51   // ctor runs before all others -- either implicitly or explicitly.  Each of
52   // the available ctors initializes custom_type_name_ in a different way:
53   //
54   // 1) default:      custom_type_name_ = "gtkmm__anonymous_custom_type"
55   // 2) const char*:  custom_type_name_ = custom_type_name
56   // 3) type_info:    custom_type_name_ = custom_type_info.name()
57   //
58   // All classes generated by gtkmmproc use ctor 2) with custom_type_name = 0,
59   // which essentially means it's not a custom type.  This is used to optimize
60   // vfunc and signal handler callbacks -- since the C++ virtual methods are
61   // not overridden, invocation can be skipped.
62   //
63   // The default ctor 1) is called implicitly from the ctor of user-derived
64   // classes -- yes, even if e.g. Gtk::Button calls ctor 2), a derived ctor
65   // always overrides this choice.  The language itself ensures that the ctor
66   // is only invoked once.
67   //
68   // Ctor 3) is a special feature to allow creation of derived types on the
69   // fly, without having to use g_object_new() manually.  This feature is
70   // sometimes necessary, e.g. to implement a custom Gtk::CellRenderer.  The
71   // neat trick with the virtual base class ctor makes it possible to reuse
72   // the same direct base class' ctor as with non-custom types.
73
74   ObjectBase();
75   explicit ObjectBase(const char* custom_type_name);
76   explicit ObjectBase(const std::type_info& custom_type_info);
77
78   virtual ~ObjectBase() = 0;
79
80   // Called by Glib::Object and Glib::Interface constructors. See comments there.
81   void initialize(GObject* castitem);
82
83 public:
84
85   /// You probably want to use a specific property_*() accessor method instead.
86   void set_property_value(const Glib::ustring& property_name, const Glib::ValueBase& value);
87
88   /// You probably want to use a specific property_*() accessor method instead.
89   void get_property_value(const Glib::ustring& property_name, Glib::ValueBase& value) const;
90
91   /// You probably want to use a specific property_*() accessor method instead.
92   template <class PropertyType>
93   void set_property(const Glib::ustring& property_name, const PropertyType& value);
94
95   /// You probably want to use a specific property_*() accessor method instead.
96   template <class PropertyType>
97   void get_property(const Glib::ustring& property_name, PropertyType& value) const;
98
99   
100   virtual void reference()   const;
101   virtual void unreference() const;
102
103   inline GObject*       gobj()       { return gobject_; }
104   inline const GObject* gobj() const { return gobject_; }
105
106   // Give a ref-ed copy to someone. Use for direct struct access.
107   GObject* gobj_copy() const;
108
109 #ifndef DOXYGEN_SHOULD_SKIP_THIS
110   static ObjectBase* _get_current_wrapper(GObject* object);
111   bool _cpp_destruction_is_in_progress() const;
112 #endif
113
114 protected:
115   GObject*            gobject_; // the GLib/GDK/GTK+ object instance
116   const char*         custom_type_name_;
117   bool                cpp_destruction_in_progress_;
118
119   bool is_anonymous_custom_() const;
120   bool is_derived_() const;
121
122   static  void destroy_notify_callback_(void* data);
123   virtual void destroy_notify_();
124
125   void _set_current_wrapper(GObject* object);
126
127 private:
128   // noncopyable
129   ObjectBase(const ObjectBase&);
130   ObjectBase& operator=(const ObjectBase&);
131
132   virtual void set_manage(); // calls g_error()
133
134 #ifndef DOXYGEN_SHOULD_SKIP_THIS
135   friend class Glib::GSigConnectionNode; // for GSigConnectionNode::notify()
136 #endif
137 };
138
139 #ifndef DOXYGEN_SHOULD_SKIP_THIS
140
141 template <class PropertyType>
142 void ObjectBase::set_property(const Glib::ustring& property_name, const PropertyType& value)
143 {
144   Glib::Value<PropertyType> property_value;
145   property_value.init(Glib::Value<PropertyType>::value_type());
146
147   property_value.set(value);
148   this->set_property_value(property_name, property_value);
149 }
150
151 template <class PropertyType>
152 void ObjectBase::get_property(const Glib::ustring& property_name, PropertyType& value) const
153 {
154   Glib::Value<PropertyType> property_value;
155   property_value.init(Glib::Value<PropertyType>::value_type());
156
157   this->get_property_value(property_name, property_value);
158
159   value = property_value.get();
160 }
161
162 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
163
164
165 bool _gobject_cppinstance_already_deleted(GObject* gobject);
166
167 } // namespace Glib
168
169
170 #endif /* _GLIBMM_OBJECTBASE_H */
171