BEAST/BSE - Better Audio System and Sound Engine  0.8.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
bsecxxbase.hh
Go to the documentation of this file.
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__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines