BEAST/BSE - Better Audio System and Sound Engine
0.8.2
|
00001 // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html 00002 #ifndef __BSE_CXX_BASE_H__ 00003 #define __BSE_CXX_BASE_H__ 00004 00005 #include <bse/bsesource.hh> 00006 #include <bse/bsecxxvalue.hh> 00007 #include <bse/bsecxxclosure.hh> 00008 00009 namespace Bse { 00010 #define BSE_CXX_INSTANCE_OFFSET BSE_CXX_SIZEOF (BseSource) 00011 00012 #define BSE_TYPE_CXX_BASE (BSE_CXX_TYPE_GET_REGISTERED (Bse, CxxBase)) 00013 00014 class CxxBaseClass : public BseSourceClass { 00015 public: 00016 void add_param (const char *group, 00017 guint prop_id, 00018 GParamSpec *pspec); 00019 void add_param (guint prop_id, 00020 GParamSpec *grouped_pspec); 00021 void set_accessors (void (*get_property) (GObject*, guint, GValue*, GParamSpec*), 00022 void (*set_property) (GObject*, guint, const GValue*, GParamSpec*) = NULL, 00023 gboolean (*editable_property) (BseObject*, guint, GParamSpec*) = NULL, 00024 void (*get_candidates) (BseItem*, guint, BsePropertyCandidates*, GParamSpec*) = NULL, 00025 void (*property_updated) (BseSource*, guint, guint64, double, GParamSpec*) = NULL); 00026 guint add_signal (const gchar *signal_name, 00027 GSignalFlags flags, 00028 guint n_params, 00029 ...); 00030 void add_ochannel (const char *ident, 00031 const char *label, 00032 const char *blurb, 00033 int assert_id = -1); 00034 void add_ichannel (const char *ident, 00035 const char *label, 00036 const char *blurb, 00037 int assert_id = -1); 00038 void add_jchannel (const char *ident, 00039 const char *label, 00040 const char *blurb, 00041 int assert_id = -1); 00042 }; 00043 class CxxBase { 00044 void* cast_to_gobject (); 00045 static CxxBase* cast_from_gobject (void *o); 00046 public: 00047 static CxxBase* base_from_gobject (GObject *o) { return cast_from_gobject (o); } 00048 protected: 00049 GObject* gobject () const; 00050 BseItem* item (); 00051 public: 00052 /*Con*/ CxxBase (); 00053 CxxBase* ref (); 00054 void unref (); 00055 void freeze_notify (); 00056 void notify (const gchar *property); 00057 void thaw_notify (); 00058 void set (const gchar *first_property_name, 00059 ...) G_GNUC_NULL_TERMINATED; 00060 void get (const gchar *first_property_name, 00061 ...) G_GNUC_NULL_TERMINATED; 00062 void set_property (guint prop_id, 00063 const Value &value, 00064 GParamSpec *pspec); 00065 void get_property (guint prop_id, 00066 Value &value, 00067 GParamSpec *pspec); 00068 #if 0 00069 gulong connect (const gchar *signal, 00070 GClosure *closure, 00071 bool after); 00072 gulong connect (const gchar *signal, 00073 GClosure *closure) { return connect (signal, closure, false); } 00074 #endif 00075 gulong connect (const gchar *signal, 00076 CxxClosure *closure, 00077 bool after); 00078 gulong connect (const gchar *signal, 00079 CxxClosure *closure) { return connect (signal, closure, false); } 00080 const String tokenize_signal (const gchar *signal); 00081 GType type (); 00082 virtual void compat_setup (guint vmajor, 00083 guint vminor, 00084 guint vmicro); 00085 virtual void restore_finished (guint vmajor, 00086 guint vminor, 00087 guint vmicro); 00088 virtual ~CxxBase (); 00089 00090 static void class_init (CxxBaseClass *klass); 00091 00092 static inline bool instance_is_a (CxxBase *cbase, 00093 GType iface_type) 00094 { 00095 if (cbase) 00096 { 00097 GObject *gobject = cbase->gobject(); 00098 return G_TYPE_CHECK_INSTANCE_TYPE (gobject, iface_type); 00099 } 00100 else 00101 return FALSE; 00102 } 00103 00104 template<class OType> static inline OType* 00105 value_get_gobject (const GValue *v) 00106 { 00107 gpointer p; 00108 if (SFI_VALUE_HOLDS_PROXY (v)) 00109 p = bse_object_from_id (sfi_value_get_proxy (v)); 00110 else 00111 p = g_value_get_object (v); 00112 return (OType*) p; 00113 } 00114 template<class CxxType> static inline CxxType 00115 value_get_object (const GValue *v) 00116 { 00117 assert_derived_from<CxxType, CxxBase*>(); 00118 GObject *p = value_get_gobject<GObject> (v); 00119 CxxBase *b = CxxBase::base_from_gobject (p); 00120 CxxType to = static_cast<CxxType> (b); 00121 return to; 00122 } 00123 static inline void 00124 value_set_gobject (GValue *value, 00125 gpointer object) 00126 { 00127 if (SFI_VALUE_HOLDS_PROXY (value)) 00128 sfi_value_set_proxy (value, BSE_IS_OBJECT (object) ? ((BseObject*) object)->unique_id : 0); 00129 else 00130 g_value_set_object (value, object); 00131 } 00132 static inline void 00133 value_set_object (GValue *value, 00134 const CxxBase *self) 00135 { 00136 value_set_gobject (value, self->gobject()); 00137 } 00138 template<class Accepted, class Casted> 00139 static inline void 00140 value_set_casted (GValue *value, 00141 const Accepted *obj) 00142 { 00143 const Casted *self = static_cast<const Casted*> (obj); 00144 value_set_object (value, self); 00145 } 00146 00147 class Pointer { 00148 CxxBase *p; 00149 public: 00150 Pointer (CxxBase *t) { p = t; } 00151 /* second part of to-GObject* casts: */ 00152 operator GObject* () { return (GObject*) p->cast_to_gobject (); } 00153 operator BseObject* () { return (BseObject*) p->cast_to_gobject (); } 00154 operator BseItem* () { return (BseItem*) p->cast_to_gobject (); } 00155 operator BseSource* () { return (BseSource*) p->cast_to_gobject (); } 00156 }; 00157 /* first part of to-GObject* casts: */ 00158 static inline CxxBase::Pointer cast (CxxBase *c) { return CxxBase::Pointer (c); } 00159 /* from-GObject* casts: */ 00160 static CxxBase* cast (GObject *o) { return cast_from_gobject (o); } 00161 static CxxBase* cast (BseSource *o) { return cast_from_gobject (o); } 00162 static CxxBase* cast (BseItem *o) { return cast_from_gobject (o); } 00163 static CxxBase* cast (BseObject *o) { return cast_from_gobject (o); } 00164 }; 00165 /* first part of to-GObject* casts: */ 00166 static inline CxxBase::Pointer cast (CxxBase *c) { return CxxBase::Pointer (c); } 00167 /* match from-GObject* casts: */ 00168 template<class T> CxxBase* cast (T *t) { return CxxBase::cast (t); } 00169 00170 /* --- trampoline templates --- */ 00171 template<class ObjectType> static void 00172 cxx_class_init_trampoline (CxxBaseClass *klass) 00173 { 00174 ObjectType::class_init (klass); 00175 } 00176 00177 template<class ObjectType> static void 00178 cxx_instance_init_trampoline (GTypeInstance *instance, 00179 gpointer g_class) 00180 { /* invoke C++ constructor upon _init of destination type */ 00181 if (G_TYPE_FROM_INSTANCE (instance) == G_TYPE_FROM_CLASS (g_class)) 00182 new (BSE_CXX_INSTANCE_OFFSET + (char*) instance) ObjectType (); 00183 } 00184 00185 template<class ObjectType, typename PropertyID> static void 00186 cxx_get_property_trampoline (GObject *o, 00187 guint prop_id, 00188 GValue *value, 00189 GParamSpec *pspec) 00190 { 00191 CxxBase *cbase = cast (o); 00192 Value *v = (Value*) value; 00193 ObjectType *instance = static_cast<ObjectType*> (cbase); 00194 if (0) // check ObjectType::get_property() member and prototype 00195 (void) static_cast<void (ObjectType::*) (PropertyID, Value&, GParamSpec*)> (&ObjectType::get_property); 00196 instance->get_property (static_cast<PropertyID> (prop_id), *v, pspec); 00197 } 00198 00199 template<class ObjectType, typename PropertyID> static void 00200 cxx_set_property_trampoline (GObject *o, 00201 guint prop_id, 00202 const GValue *value, 00203 GParamSpec *pspec) 00204 { 00205 CxxBase *cbase = cast (o); 00206 const Value *v = (const Value*) value; 00207 ObjectType *instance = static_cast<ObjectType*> (cbase); 00208 if (0) // check ObjectType::set_property() member and prototype 00209 (void) static_cast<void (ObjectType::*) (PropertyID, const Value&, GParamSpec*)> (&ObjectType::set_property); 00210 instance->set_property (static_cast<PropertyID> (prop_id), *v, pspec); 00211 } 00212 00213 template<class ObjectType, typename PropertyID> static gboolean 00214 cxx_editable_property_trampoline (BseObject *o, 00215 guint prop_id, 00216 GParamSpec *pspec) 00217 { 00218 CxxBase *cbase = cast (o); 00219 ObjectType *instance = static_cast<ObjectType*> (cbase); 00220 if (0) // check ObjectType::editable_property() member and prototype 00221 (void) static_cast<bool (ObjectType::*) (PropertyID, GParamSpec*)> (&ObjectType::editable_property); 00222 return instance->editable_property (static_cast<PropertyID> (prop_id), pspec); 00223 } 00224 00225 template<class ObjectType, typename PropertyID> static void 00226 cxx_get_candidates_trampoline (BseItem *item, 00227 guint prop_id, 00228 BsePropertyCandidates *pc, 00229 GParamSpec *pspec); /* defined in bsecxxplugin.hh */ 00230 00231 template<class ObjectType, typename PropertyID> static void 00232 cxx_property_updated_trampoline (BseSource *source, 00233 guint prop_id, 00234 guint64 tick_stamp, 00235 double prop_value, 00236 GParamSpec *pspec) 00237 { 00238 CxxBase *cbase = cast (source); 00239 ObjectType *instance = static_cast<ObjectType*> (cbase); 00240 if (0) // check ObjectType::property_updated() member and prototype 00241 (void) static_cast<void (ObjectType::*) (PropertyID, guint64, double, GParamSpec*)> (&ObjectType::property_updated); 00242 instance->property_updated (static_cast<PropertyID> (prop_id), tick_stamp, prop_value, pspec); 00243 } 00244 00245 } // Bse 00246 00247 00248 #endif /* __BSE_CXX_BASE_H__ */