BSE: move Category and CategorySeq into bseapi.idl and switch to Icon
authorTim Janik <timj@gnu.org>
Sat, 28 May 2016 20:29:17 +0000 (22:29 +0200)
committerTim Janik <timj@gnu.org>
Wed, 12 Oct 2016 23:10:43 +0000 (01:10 +0200)
Signed-off-by: Tim Janik <timj@gnu.org>
19 files changed:
bse/Makefile.am
bse/bseapi.idl
bse/bsebasics.idl
bse/bsecategories.cc
bse/bsecategories.hh
bse/bsecategories.proc [deleted file]
bse/bseglue.cc
bse/bseitem.cc
bse/bsemain.cc
bse/bseobject.cc
bse/bseobject.hh
bse/bseprocidl.cc
bse/bseserver.cc
bse/bseserver.hh
bse/bsetool.cc
bse/bseutils.cc
bse/bseutils.hh
plugins/bseadder.cc
plugins/bseadder.hh

index 367c894..50b1f24 100644 (file)
@@ -115,7 +115,7 @@ idl_dummy_files = $(strip   \
 )
 # BSE procedure sources
 bse_proc_sources = $(strip \
-       bsecategories.proc      bseeditablesample.proc  \
+       bseeditablesample.proc  \
        bsejanitor.proc                                                         bseproject.proc         \
                                bsesong.proc                                    bsesource.proc          \
                                bseitem.proc                                    bsewaveosc.proc         \
index 9efed38..b93df61 100644 (file)
@@ -864,6 +864,22 @@ interface Project : Container {
 interface PcmWriter : Item {
 };
 
+/// Categories describe useful type entities.
+record Category
+{
+  int32  category_id = Num ("Category ID", "", ":readwrite");
+  String category;
+  int32  mindex;
+  int32  lindex;
+  String otype;
+  Icon   icon;
+};
+
+/// Sequence of Category records.
+sequence CategorySeq {
+  Category cats;
+};
+
 /** Main Bse remote origin object.
  * The Bse::Server object controls the main BSE thread and keeps track of all objects
  * used in the BSE context.
@@ -912,6 +928,9 @@ interface Server : Object {
   /// Retrieve the frequency of a certain note.
   float64         note_to_freq (MusicalTuning musical_tuning, int32 note, int32 fine_tune);
 
+  CategorySeq category_match_typed (String pattern, String type_name); ///< List BSE categories according to a pattern and type match.
+  CategorySeq category_match       (String pattern);                   ///< List BSE categories according to a pattern match.
+
   // *** Old Janitor ***
   // void   trigger_action   (String action); ///< Trigger an installed user action of this janitor.
   // String get_script_name  (); ///< Retrieve the script name of this janitor.
index fa5c35f..dd41261 100644 (file)
@@ -262,25 +262,6 @@ record NoteSequence
 sequence P1xelSeq {
   Int  pixels;
 };
-record Ic0n
-{
-  Info     blurb     = "BSE icon representation.";
-  Int      width     = SfiInt ("Width", "Width in pixels or 0 for no icon", 0, 0, MAXINT, 1, ":readwrite");
-  Int      height    = SfiInt ("Height", "Height in pixels or 0 for no icon", 0, 0, MAXINT, 1, ":readwrite");
-  P1xelSeq pixel_seq = SfiSeq ("Pixels", "Pixel array of width*height ARGB pixels", ":readwrite");
-};
-record Category
-{
-  Int    category_id = SfiInt ("Category ID", "", 1, 1, G_MAXINT, 1, ":readwrite");
-  SfiString category;
-  Int    mindex;
-  Int    lindex;
-  SfiString otype;
-  Ic0n   icon;
-};
-sequence CategorySeq {
-  Category cats;
-};
 /* BSE Part structures */
 interface Part;
 interface Track;
index 3472dc9..c1e5672 100644 (file)
@@ -2,6 +2,7 @@
 #include "bsecategories.hh"
 #include "bseutils.hh"
 #include "bseserver.hh"
+#include <algorithm>
 #include <string.h>
 
 
 #define CATEGORIES_PRE_ALLOC  (16)
 
 
-/* --- structures --- */
-typedef struct _CEntry CEntry;
-struct _CEntry
-{
-  CEntry  *next;
-  guint    category_id;
-  GQuark   category;
-  guint    mindex, lindex;
-  GType    type;
-  BseIc0n *icon;
-};
-
-
-/* --- variables --- */
-static CEntry    *cat_entries = NULL;
-static gboolean   cats_need_sort = FALSE;
-static guint      global_category_id = 1;
-static SfiUStore *category_ustore = NULL;
+// == CategoryEntry ==
+static bool categories_need_sorting = false;
+static uint category_id_counter = 1;
 
-
-/* --- functions --- */
-void
-_bse_init_categories (void)
+// == functions ==
+static inline std::vector<Bse::Category>&
+category_entries()
 {
-  assert_return (category_ustore == NULL);
-
-  category_ustore = sfi_ustore_new ();
+  static std::vector<Bse::Category> global_entries;
+  return global_entries;
 }
 
-static inline CEntry*
-centry_find (GQuark quark)
+static inline const Bse::Category*
+centry_find (const String &category)
 {
-  CEntry *centry;
-
-  for (centry = cat_entries; centry; centry = centry->next)
-    if (centry->category == quark)
-      return centry;
-
+  for (const auto &centry : category_entries())
+    if (centry.category == category)
+      return &centry;
   return NULL;
 }
 
-static inline guint
-category_strip_toplevels (const gchar *category,
-                          GType        type)
+static inline uint
+category_strip_toplevels (const String &category, GType type)
 {
-  static const struct { guint length; const gchar *prefix; } scripts[] = {
+  static const struct { uint length; const char *prefix; } scripts[] = {
     {  9, "/Project/", },
     {  6, "/SNet/", },
     {  6, "/Song/", },
@@ -64,19 +44,19 @@ category_strip_toplevels (const gchar *category,
     { 10, "/WaveRepo/", },
     {  6, "/Proc/", },
   };
-  guint l = strlen (category);
+  const uint l = category.size();
 
-  if (l > 10 && strncmp (category, "/Methods/", 8) == 0)
+  if (l > 10 && strncmp (category.c_str(), "/Methods/", 8) == 0)
     {
-      const gchar *p = category + 8;
+      const char *p = category.c_str() + 8;
 
       if (!BSE_TYPE_IS_PROCEDURE (type))
         return 0;
       p = strchr (p, '/');
       if (p && p[1])
-       return p - category + 1;
+       return p - category.c_str() + 1;
     }
-  else if (l > 8 && strncmp (category, "/Modules/", 9) == 0)
+  else if (l > 8 && strncmp (category.c_str(), "/Modules/", 9) == 0)
     {
       if (!G_TYPE_IS_OBJECT (type))
         return 0;
@@ -88,76 +68,51 @@ category_strip_toplevels (const gchar *category,
       guint i;
       for (i = 0; i < G_N_ELEMENTS (scripts); i++)
         if (l > scripts[i].length &&
-            strncmp (category, scripts[i].prefix, scripts[i].length) == 0)
+            strncmp (category.c_str(), scripts[i].prefix, scripts[i].length) == 0)
           return scripts[i].length;
     }
 
   return 0;
 }
 
-static guint
-leaf_index (const gchar *string)
+static uint
+leaf_index (const String &string)
 {
-  gboolean in_quote = FALSE;
-  guint pos = 0;
-  const gchar *p;
-
-  for (p = string; *p; p++)
+  bool in_quote = false;
+  uint pos = 0;
+  for (const char *p = string.c_str(); *p; p++)
     switch (*p)
       {
-      case '\\':       in_quote = TRUE;                        break;
-      case '/':                pos = in_quote ? pos : p - string;      /* fall through */
-      default:         in_quote = FALSE;
+      case '\\':       in_quote = true;                        break;
+      case '/':                pos = in_quote ? pos : p - string.c_str();      // fall through
+      default:         in_quote = false;
       }
   return pos;
 }
 
-static inline CEntry*
-centry_new (const gchar *caller,
-           const gchar *category,
-            GType        type)
+static inline Bse::Category*
+centry_new (const char *caller, const String &category, GType type)
 {
-  static GTrashStack *free_entries = NULL;
-  CEntry *centry;
-  GQuark quark;
-  guint mindex;
-
-  mindex = category_strip_toplevels (category, type);
+  const uint mindex = category_strip_toplevels (category, type);
   if (!mindex)
     {
-      g_warning ("%s(): refusing to add non-conforming category `%s'", caller, category);
+      critical ("%s: refusing to add non-conforming category '%s'", caller, category);
       return NULL;
     }
-  quark = g_quark_try_string (category);
-  if (quark && centry_find (quark))
+  if (centry_find (category))
     {
-      g_warning ("%s(): unable to add category duplicate `%s'", caller, category);
+      critical ("%s: unable to add category duplicate '%s'", caller, category);
       return NULL;
     }
 
-  if (!g_trash_stack_peek (&free_entries))
-    {
-      CEntry *limit;
-
-      centry = g_new (CEntry, CATEGORIES_PRE_ALLOC);
-      limit = centry + CATEGORIES_PRE_ALLOC - 1;
-      while (centry < limit)
-       g_trash_stack_push (&free_entries, centry++);
-    }
-  else
-    centry = (CEntry*) g_trash_stack_pop (&free_entries);
-
-  centry->next = cat_entries;
-  cat_entries = centry;
-  centry->category_id = global_category_id++;
-  sfi_ustore_insert (category_ustore, centry->category_id, centry);
-  centry->mindex = mindex - 1;
-  centry->lindex = leaf_index (category);
-  centry->category = g_quark_from_string (category);
-
-  cats_need_sort = TRUE;
-
-  return centry;
+  categories_need_sorting = TRUE;
+  Bse::Category centry;
+  centry.category_id = category_id_counter++;
+  centry.mindex = mindex - 1;
+  centry.lindex = leaf_index (category);
+  centry.category = category;
+  category_entries().push_back (centry);
+  return &category_entries().back();
 }
 
 static void
@@ -175,27 +130,21 @@ check_type (GType type)
 }
 
 void
-bse_categories_register (const gchar  *category,
-                         const gchar  *i18n_category,
-                         GType         type,
-                         const guint8 *pixstream)
+bse_categories_register (const String &category, const char *i18n_category, GType type, const uint8 *pixstream)
 {
-  CEntry *centry;
-  assert_return (category != NULL);
-  centry = centry_new (RAPICORN_SIMPLE_FUNCTION, category, type);
+  assert_return (!category.empty());
+  Bse::Category *centry = centry_new (RAPICORN_SIMPLE_FUNCTION, category, type);
   check_type (type);
   if (centry)
     {
-      centry->type = type;
+      centry->otype = g_type_name (type);
       if (pixstream)
-        centry->icon = bse_ic0n_from_pixstream (pixstream);
-      else
-        centry->icon = NULL;
+        centry->icon = bse_icon_from_pixstream (pixstream);
     }
-  if (g_type_is_a (centry->type, BSE_TYPE_SOURCE))
+  if (g_type_is_a (type, BSE_TYPE_SOURCE))
     {
       // parse "/Modules////tag1/tag2/tag3///Title" into tags and title
-      const char *name = i18n_category ? i18n_category : category;
+      const char *name = i18n_category ? i18n_category : category.c_str();
       if (strncmp (name, "/Modules/", 9) == 0)
         name += 9;
       while (name[0] == '/')
@@ -207,7 +156,7 @@ bse_categories_register (const gchar  *category,
       Rapicorn::StringVector tags;
       if (name < end)
         tags = Rapicorn::string_split (String (name, end - name), "/");
-      Bse::ServerImpl::register_source_module (g_type_name (centry->type), title,
+      Bse::ServerImpl::register_source_module (centry->otype, title,
                                                Rapicorn::string_join (";", tags),
                                                pixstream);
     }
@@ -224,118 +173,57 @@ bse_categories_register_stock_module (const gchar      *untranslated_category_tr
   bse_categories_register (category, i18n_category, type, pixstream);
 }
 
-static gint
-centries_strorder (gconstpointer a,
-                  gconstpointer b)
-{
-  const CEntry *e1 = (const CEntry*) a;
-  const CEntry *e2 = (const CEntry*) b;
-  const char *c1 = g_quark_to_string (e1->category);
-  const char *c2 = g_quark_to_string (e2->category);
-
-  return strcmp (c2, c1);
-}
-
 static void
 cats_sort (void)
 {
-  GSList *slist, *clist = NULL;
-  CEntry *centry, *last;
-
-  if (!cats_need_sort)
-    return;
-
-  for (centry = cat_entries; centry; centry = centry->next)
-    clist = g_slist_prepend (clist, centry);
-  clist = g_slist_sort (clist, centries_strorder);
-  last = NULL;
-  for (slist = clist; slist; slist = slist->next)
-    {
-      centry = (CEntry*) slist->data;
-      centry->next = last;
-      last = centry;
-    }
-  cat_entries = centry;
-  g_slist_free (clist);
-
-  cats_need_sort = FALSE;
+  return_unless (categories_need_sorting);
+  std::vector<Bse::Category> &entries = category_entries();
+  auto lesser_category = [] (const Bse::Category &a, const Bse::Category &b) -> bool {
+    return a.category < b.category;
+  };
+  std::sort (entries.begin(), entries.end(), lesser_category);
+  categories_need_sorting = false;
 }
 
-static inline BseCategorySeq*
-categories_match (const gchar      *pattern,
-                 GType             base_type,
-                  BseCategoryCheck  check,
-                  gpointer          data)
+static inline Bse::CategorySeq
+categories_match (const String &pattern, GType base_type, BseCategoryCheck check, gpointer data)
 {
-  BseCategorySeq *cseq = bse_category_seq_new ();
-  GPatternSpec *pspec = g_pattern_spec_new (pattern);
-  CEntry *centry;
-
-  for (centry = cat_entries; centry; centry = centry->next)
+  Bse::CategorySeq cseq;
+  GPatternSpec *pspec = g_pattern_spec_new (pattern.c_str());
+  for (const auto &centry : category_entries())
     {
-      const char *category = g_quark_to_string (centry->category);
-
-      if (g_pattern_match_string (pspec, category) &&
-         (!base_type || g_type_is_a (centry->type, base_type)))
+      if (g_pattern_match_string (pspec, centry.category.c_str()) &&
+         (!base_type || g_type_is_a (g_type_from_name (centry.otype.c_str()), base_type)))
        {
-         BseCategory cat = { 0, };
-
-         cat.category = const_cast<char*> (category);
-         cat.category_id = centry->category_id;
-         cat.mindex = centry->mindex;
-         cat.lindex = centry->lindex;
-         cat.otype = const_cast<char*>  (g_type_name (centry->type));
-         cat.icon = centry->icon ? centry->icon : NULL;
-          if (!check || check (&cat, data))
-            bse_category_seq_append (cseq, &cat);
+          if (!check || check (&centry, data))
+            cseq.push_back (centry);
        }
     }
   g_pattern_spec_free (pspec);
-
   return cseq;
 }
 
-BseCategorySeq*
-bse_categories_match (const gchar      *pattern,
-                      GType             base_type,
-                      BseCategoryCheck  check,
-                      gpointer          data)
+Bse::CategorySeq
+bse_categories_match (const String &pattern, GType base_type, BseCategoryCheck check, void *data)
 {
-  assert_return (pattern != NULL, NULL);
-
   cats_sort ();
-
   return categories_match (pattern, 0, check, data);
 }
 
-BseCategorySeq*
-bse_categories_match_typed (const gchar *pattern,
-                           GType        base_type)
+Bse::CategorySeq
+bse_categories_match_typed (const String &pattern, GType base_type)
 {
-  assert_return (pattern != NULL, NULL);
-
   cats_sort ();
-
   return categories_match (pattern, base_type, NULL, NULL);
 }
 
-BseCategorySeq*
+Bse::CategorySeq
 bse_categories_from_type (GType type)
 {
-  BseCategorySeq *cseq = bse_category_seq_new ();
-
-  for (CEntry *centry = cat_entries; centry; centry = centry->next)
-    if (centry->type == type)
-      {
-       BseCategory cat = { 0, };
-
-       cat.category = const_cast<char*> (g_quark_to_string (centry->category));
-       cat.category_id = centry->category_id;
-       cat.mindex = centry->mindex;
-       cat.lindex = centry->lindex;
-       cat.otype = const_cast<char*> (g_type_name (centry->type));
-       cat.icon = centry->icon ? centry->icon : NULL;
-       bse_category_seq_append (cseq, &cat);
-      }
+  Bse::CategorySeq cseq;
+  const char *type_name = g_type_name (type);
+  for (const auto &centry : category_entries())
+    if (centry.otype == type_name)
+      cseq.push_back (centry);
   return cseq;
 }
index 19ee96f..432d35e 100644 (file)
@@ -2,35 +2,21 @@
 #ifndef __BSE_CATEGORIES_H__
 #define __BSE_CATEGORIES_H__
 
-#include        <bse/bsetype.hh>
+#include <bse/bsetype.hh>
+#include <bse/bseutils.hh>
 
 G_BEGIN_DECLS
 
 
 /* --- typedefs --- */
-typedef gboolean (BseCategoryCheck) (BseCategory *category,
-                                     gpointer     data);
-
+typedef gboolean (BseCategoryCheck) (const Bse::Category *category, void *data);
 
 /* --- prototypes --- */
-void            bse_categories_register        (const gchar      *category,
-                                                const gchar      *i18n_category,
-                                                GType             type,
-                                                const guint8     *pixstream);
-BseCategorySeq* bse_categories_match           (const gchar      *pattern,
-                                                GType             base_type,
-                                                BseCategoryCheck  check,
-                                                gpointer          data);
-BseCategorySeq* bse_categories_match_typed     (const gchar      *pattern,
-                                                GType             base_type);
-BseCategorySeq* bse_categories_from_type       (GType             type);
-void      bse_categories_register_stock_module (const gchar      *untranslated_category_trunk,
-                                                GType             type,
-                                                const guint8     *pixstream);
-
-
-/* --- implementation --- */
-void           _bse_init_categories         (void);
+void             bse_categories_register              (const String &category, const char *i18n_category, GType type, const uint8 *pixstream);
+Bse::CategorySeq bse_categories_match                 (const String &pattern, GType base_type, BseCategoryCheck check, void *data);
+Bse::CategorySeq bse_categories_match_typed           (const String &pattern, GType base_type);
+Bse::CategorySeq bse_categories_from_type             (GType type);
+void             bse_categories_register_stock_module (const char *untranslated_category_trunk, GType type, const guint8 *pixstream);
 
 G_END_DECLS
 
diff --git a/bse/bsecategories.proc b/bse/bsecategories.proc
deleted file mode 100644 (file)
index f65f8e5..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
-#include <bse/bsecategories.hh>
-#include <bse/bseprocedure.hh>
-#include <bse/bseplugin.hh>
-#include "bsecxxplugin.hh"
-#include "bsebuiltin_externs.cc"
-
-
-AUTHORS        = "Tim Janik <timj@gtk.org>";
-LICENSE        = "GNU Lesser General Public License";
-
-
-PROCEDURE (bse-categories-match-typed, "Categories/Match Typed") {
-  HELP  = "List BSE categories according to a pattern and type match.";
-  IN   = sfi_pspec_string ("pattern", "Pattern", "Pattern to match category, supports '*' and '?' wildcards.",
-                           "*", SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_string ("type", "Type", "Base type for categories to conform to.",
-                           NULL, SFI_PARAM_STANDARD);
-  OUT   = bse_param_spec_boxed ("categories", "Categories", NULL, BSE_TYPE_CATEGORY_SEQ, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  const char *pattern   = sfi_value_get_string (in_values++);
-  const char *type_name = sfi_value_get_string (in_values++);
-  GType  type     = type_name ? g_type_from_name (type_name) : 0;
-  BseCategorySeq *cseq = NULL;
-
-  /* check parameters */
-  if (!pattern)
-    return Bse::Error::PROC_PARAM_INVAL;
-
-  if (type)
-    cseq = bse_categories_match_typed (pattern, type);
-  if (!cseq)
-    cseq = bse_category_seq_new ();
-
-  /* set output parameters */
-  bse_value_take_boxed (out_values++, cseq);
-
-  return Bse::Error::NONE;
-}
-
-PROCEDURE (bse-categories-match, "Categories/Match") {
-  HELP  = "List BSE categories according to a pattern match.";
-  IN   = sfi_pspec_string ("pattern", "Pattern", "Pattern to match category, supports '*' and '?' wildcards.",
-                           "*", SFI_PARAM_STANDARD);
-  OUT   = bse_param_spec_boxed ("categories", "Categories", NULL, BSE_TYPE_CATEGORY_SEQ, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  const char *pattern   = sfi_value_get_string (in_values++);
-  BseCategorySeq *cseq = NULL;
-
-  /* check parameters */
-  if (!pattern)
-    return Bse::Error::PROC_PARAM_INVAL;
-
-  cseq = bse_categories_match_typed (pattern, 0);
-  if (!cseq)
-    cseq = bse_category_seq_new ();
-
-  /* set output parameters */
-  bse_value_take_boxed (out_values++, cseq);
-
-  return Bse::Error::NONE;
-}
index 7ea7452..133107f 100644 (file)
@@ -526,15 +526,14 @@ bglue_describe_proc (SfiGlueContext *context,
 static char**
 bglue_list_proc_names (SfiGlueContext *context)
 {
-  BseCategorySeq *cseq = bse_categories_match_typed ("/Proc/""*", BSE_TYPE_PROCEDURE);
+  Bse::CategorySeq cseq = bse_categories_match_typed ("/Proc/""*", BSE_TYPE_PROCEDURE);
   char **p;
   uint i;
 
-  p = g_new (char*, cseq->n_cats + 1);
-  for (i = 0; i < cseq->n_cats; i++)
-    p[i] = g_strdup (cseq->cats[i]->otype);
+  p = g_new (char*, cseq.size() + 1);
+  for (i = 0; i < cseq.size(); i++)
+    p[i] = g_strdup (cseq[i].otype.c_str());
   p[i] = NULL;
-  bse_category_seq_free (cseq);
 
   return p;
 }
@@ -544,7 +543,6 @@ bglue_list_method_names (SfiGlueContext *context,
                          const char     *iface_name)
 {
   GType type = g_type_from_name (iface_name);
-  BseCategorySeq *cseq;
   char **p, *prefix;
   uint i, l, n_procs;
 
@@ -554,14 +552,13 @@ bglue_list_method_names (SfiGlueContext *context,
   prefix = g_strdup_format ("%s+", g_type_name (type));
   l = strlen (prefix);
 
-  cseq = bse_categories_match_typed ("/Methods/" "*", BSE_TYPE_PROCEDURE);
-  p = g_new (char*, cseq->n_cats + 1);
+  Bse::CategorySeq cseq = bse_categories_match_typed ("/Methods/" "*", BSE_TYPE_PROCEDURE);
+  p = g_new (char*, cseq.size() + 1);
   n_procs = 0;
-  for (i = 0; i < cseq->n_cats; i++)
-    if (strncmp (cseq->cats[i]->otype, prefix, l) == 0)
-      p[n_procs++] = g_strdup (cseq->cats[i]->otype + l);
+  for (i = 0; i < cseq.size(); i++)
+    if (strncmp (cseq[i].otype.c_str(), prefix, l) == 0)
+      p[n_procs++] = g_strdup (cseq[i].otype.c_str() + l);
   p[n_procs] = NULL;
-  bse_category_seq_free (cseq);
   g_free (prefix);
 
   return p;
index c49d4a0..2f4c18b 100644 (file)
@@ -1362,15 +1362,7 @@ Icon
 ItemImpl::icon () const
 {
   BseItem *self = const_cast<ItemImpl*> (this)->as<BseItem*>();
-  const BseIc0n *ic0n = bse_object_get_icon (self);
-  Icon icon;
-  if (ic0n && ic0n->width && ic0n->height && ic0n->width * ic0n->height == ssize_t (ic0n->pixel_seq->n_pixels))
-    {
-      icon.width = ic0n->width;
-      icon.height = ic0n->height;
-      icon.pixels.insert (icon.pixels.end(), &ic0n->pixel_seq->pixels[0], &ic0n->pixel_seq->pixels[ic0n->pixel_seq->n_pixels]);
-    }
-  return icon;
+  return bse_object_get_icon (self);
 }
 
 void
index 474871b..f014be1 100644 (file)
@@ -105,7 +105,6 @@ bse_init_intern()
   // basic components
   bse_globals_init ();
   _bse_init_signal();
-  _bse_init_categories ();
   bse_type_init ();
   bse_cxx_init ();
   // FIXME: global spawn dir is evil
index 158c451..4df911d 100644 (file)
@@ -59,7 +59,7 @@ enum
 enum
 {
   SIGNAL_RELEASE,
-  SIGNAL_IC0N_CHANGED,
+  SIGNAL_ICON_CHANGED,
   SIGNAL_LAST
 };
 
@@ -71,9 +71,9 @@ static gint           eclosure_equals                 (gconstpointer   c1,
 
 
 /* --- variables --- */
+GQuark             bse_quark_uname = 0;
+static GQuark     bse_quark_icon = 0;
 static gpointer           parent_class = NULL;
-GQuark            bse_quark_uname = 0;
-GQuark            bse_quark_icon = 0;
 static GQuark     quark_blurb = 0;
 static GHashTable *object_unames_ht = NULL;
 static GHashTable *eclosures_ht = NULL;
@@ -574,52 +574,39 @@ bse_object_notify_icon_changed (BseObject *object)
 {
   assert_return (BSE_IS_OBJECT (object));
 
-  g_signal_emit (object, object_signals[SIGNAL_IC0N_CHANGED], 0);
+  g_signal_emit (object, object_signals[SIGNAL_ICON_CHANGED], 0);
 }
 
-BseIc0n*
+Bse::Icon
 bse_object_get_icon (BseObject *object)
 {
-  BseIc0n *icon;
-
-  assert_return (BSE_IS_OBJECT (object), NULL);
-
+  assert_return (BSE_IS_OBJECT (object), Bse::Icon());
   g_object_ref (object);
-
-  icon = BSE_OBJECT_GET_CLASS (object)->get_icon (object);
-
+  Bse::Icon icon = BSE_OBJECT_GET_CLASS (object)->get_icon (object);
   g_object_unref (object);
-
   return icon;
 }
 
-static BseIc0n*
+static Bse::Icon
 bse_object_do_get_icon (BseObject *object)
 {
-  BseIc0n *icon;
-
-  assert_return (BSE_IS_OBJECT (object), NULL);
-
-  icon = (BseIc0n*) g_object_get_qdata (G_OBJECT (object), bse_quark_icon);
+  assert_return (BSE_IS_OBJECT (object), Bse::Icon());
+  Bse::Icon *icon = (Bse::Icon*) g_object_get_qdata (G_OBJECT (object), bse_quark_icon);
   if (!icon)
     {
-      BseCategorySeq *cseq;
-      guint i;
-
       /* FIXME: this is a bit of a hack, we could store the first per-type
        * category icon as static type-data and fetch that from here
        */
-      cseq = bse_categories_from_type (G_OBJECT_TYPE (object));
-      for (i = 0; i < cseq->n_cats; i++)
-       if (cseq->cats[i]->icon)
+      Bse::CategorySeq cseq = bse_categories_from_type (G_OBJECT_TYPE (object));
+      for (uint i = 0; i < cseq.size(); i++)
+       if (cseq[i].icon.pixels.size())
          {
-           icon = bse_ic0n_copy_shallow (cseq->cats[i]->icon);
-           g_object_set_qdata_full (G_OBJECT (object), bse_quark_icon, icon, (GDestroyNotify) bse_ic0n_free);
+            icon = new Bse::Icon (cseq[i].icon);
+           g_object_set_qdata_full (G_OBJECT (object), bse_quark_icon, icon, [] (void *d) { delete (Bse::Icon*) d; });
            break;
          }
-      bse_category_seq_free (cseq);
     }
-  return icon;
+  return icon ? *icon : Bse::Icon();
 }
 
 static void
@@ -879,10 +866,8 @@ bse_object_class_init (BseObjectClass *klass)
                                                "",
                                                SFI_PARAM_STANDARD ":skip-default"));
 
-  object_signals[SIGNAL_RELEASE] = bse_object_class_add_signal (klass, "release",
-                                                               G_TYPE_NONE, 0);
-  object_signals[SIGNAL_IC0N_CHANGED] = bse_object_class_add_signal (klass, "icon_changed",
-                                                                    G_TYPE_NONE, 0);
+  object_signals[SIGNAL_RELEASE] = bse_object_class_add_signal (klass, "release", G_TYPE_NONE, 0);
+  object_signals[SIGNAL_ICON_CHANGED] = bse_object_class_add_signal (klass, "icon_changed", G_TYPE_NONE, 0);
 }
 
 BSE_BUILTIN_TYPE (BseObject)
index 5efa248..a376946 100644 (file)
@@ -112,7 +112,7 @@ struct BseObjectClass : GObjectClass {
                                                  guint            vminor,
                                                  guint            vmicro);
   void                 (*unlocked)             (BseObject      *object);
-  BseIc0n*             (*get_icon)             (BseObject      *object);
+  Bse::Icon            (*get_icon)             (BseObject      *object);
 };
 
 /* --- object class API ---*/
@@ -148,7 +148,7 @@ void                bse_object_lock                 (gpointer        object);
 void           bse_object_unlock               (gpointer        object);
 gboolean        bse_object_editable_property   (gpointer        object,
                                                  const gchar    *property);
-BseIc0n*       bse_object_get_icon             (BseObject      *object);
+Bse::Icon      bse_object_get_icon             (BseObject      *object);
 void           bse_object_notify_icon_changed  (BseObject      *object);
 BseObject*     bse_object_from_id              (guint           unique_id);
 GList*         bse_objects_list                (GType           type);
index 9438956..da6c593 100644 (file)
@@ -216,18 +216,15 @@ void printPSpec (const char *dir, GParamSpec *pspec)
 
 void printMethods (const std::string& iface)
 {
-  BseCategorySeq *cseq;
-  guint i;
-
-  cseq = bse_categories_match_typed ("*", BSE_TYPE_PROCEDURE);
-  for (i = 0; i < cseq->n_cats; i++)
+  Bse::CategorySeq cseq = bse_categories_match_typed ("*", BSE_TYPE_PROCEDURE);
+  for (size_t i = 0; i < cseq.size(); i++)
     {
-      GType type_id = g_type_from_name (cseq->cats[i]->otype);
+      GType type_id = g_type_from_name (cseq[i].otype.c_str());
       const gchar *blurb = bse_type_get_blurb (type_id);
       BseProcedureClass *klass = (BseProcedureClass *)g_type_class_ref (type_id);
 
       /* procedures */
-      std::string t = cseq->cats[i]->otype;
+      std::string t = cseq[i].otype;
       std::string iname = getInterface (t);
       std::string mname = getMethod (t);
       std::string rtype = klass->n_out_pspecs ?
@@ -271,7 +268,6 @@ void printMethods (const std::string& iface)
        }
       g_type_class_unref (klass);
     }
-  bse_category_seq_free (cseq);
 }
 
 /* FIXME: we might want to have a sfi_glue_iface_parent () method */
index 600c539..7046008 100644 (file)
@@ -1611,4 +1611,16 @@ ServerImpl::note_to_freq (MusicalTuning musical_tuning, int note, int fine_tune)
   return info.name.empty() ? 0 : info.freq;
 }
 
+CategorySeq
+ServerImpl::category_match_typed (const String &pattern, const String &type_name)
+{
+  return bse_categories_match_typed (pattern, g_type_from_name (type_name.c_str()));
+}
+
+CategorySeq
+ServerImpl::category_match (const String &pattern)
+{
+  return bse_categories_match_typed (pattern, 0);
+}
+
 } // Bse
index 56f2236..0c5b3cc 100644 (file)
@@ -138,6 +138,8 @@ public:
   virtual NoteDescription note_from_string (MusicalTuning musical_tuning, const String &name) override;
   virtual int             note_from_freq   (MusicalTuning musical_tuning, double frequency) override;
   virtual double          note_to_freq     (MusicalTuning musical_tuning, int note, int fine_tune) override;
+  virtual CategorySeq     category_match_typed (const String &pattern, const String &type_name) override;
+  virtual CategorySeq     category_match       (const String &pattern) override;
   void               send_user_message      (const UserMessage &umsg);
   static void        register_source_module (const String &type, const String &title, const String &tags, const uint8 *pixstream);
   static ServerImpl& instance               ();
index 70b9842..0d2987e 100644 (file)
@@ -255,10 +255,9 @@ static ArgDescription dump_categories_options[] = {
 static String
 dump_categories (const ArgParser &ap)
 {
-  BseCategorySeq *cseq = bse_categories_match_typed ("*", 0);
-  for (uint i = 0; i < cseq->n_cats; i++)
-    printout ("%s\t(%s)\n", cseq->cats[i]->category, cseq->cats[i]->otype);
-  bse_category_seq_free (cseq);
+  Bse::CategorySeq cseq = bse_categories_match_typed ("*", 0);
+  for (size_t i = 0; i < cseq.size(); i++)
+    printout ("%s\t(%s)\n", cseq[i].category, cseq[i].otype);
   return "";
 }
 
index c2a7e9d..07a818f 100644 (file)
@@ -175,8 +175,7 @@ bse_balance_set (double balance,
   *level2 = l2;
 }
 
-
-/* --- icons --- */
+// == BseIcon ==
 typedef enum                    /*< skip >*/
 {
   BSE_PIXDATA_RGB               = 3,
@@ -192,41 +191,34 @@ typedef struct
   guint          height : 12;
   const guint8  *encoded_pix_data;
 } BsePixdata;
-static BseIc0n*
-bse_ic0n_from_pixdata (const BsePixdata *pixdata)
+static Bse::Icon
+bse_icon_from_pixdata (const BsePixdata *pixdata)
 {
-  BseIc0n *icon;
-  guint bpp, encoding;
-
-  assert_return (pixdata != NULL, NULL);
-
+  Bse::Icon icon;
   if (pixdata->width < 1 || pixdata->width > 128 ||
       pixdata->height < 1 || pixdata->height > 128)
     {
-      g_warning ("%s(): `pixdata' exceeds dimension limits (%ux%u)",
-                 RAPICORN_SIMPLE_FUNCTION, pixdata->width, pixdata->height);
-      return NULL;
+      critical ("%s: `pixdata' exceeds dimension limits (%ux%u)", RAPICORN_SIMPLE_FUNCTION, pixdata->width, pixdata->height);
+      return icon;
     }
-  bpp = pixdata->type & BSE_PIXDATA_RGB_MASK;
-  encoding = pixdata->type & BSE_PIXDATA_ENCODING_MASK;
+  const uint bpp = pixdata->type & BSE_PIXDATA_RGB_MASK;
+  const uint encoding = pixdata->type & BSE_PIXDATA_ENCODING_MASK;
   if ((bpp != BSE_PIXDATA_RGB && bpp != BSE_PIXDATA_RGBA) ||
       (encoding && encoding != BSE_PIXDATA_1BYTE_RLE))
     {
-      g_warning ("%s(): `pixdata' format/encoding unrecognized",
-                 RAPICORN_SIMPLE_FUNCTION);
-      return NULL;
+      critical ("%s: `pixdata' format/encoding unrecognized", RAPICORN_SIMPLE_FUNCTION);
+      return icon;
     }
   if (!pixdata->encoded_pix_data)
-    return NULL;
-  icon = bse_ic0n_new ();
-  icon->width = pixdata->width;
-  icon->height = pixdata->height;
-  bse_p1xel_seq_resize (icon->pixel_seq, icon->width * icon->height);
-  guint8 *image_buffer = (guint8*) icon->pixel_seq->pixels;
+    return icon;
+  icon.width = pixdata->width;
+  icon.height = pixdata->height;
+  icon.pixels.resize (icon.width * icon.height);
+  uint8 *image_buffer = (uint8*) &icon.pixels[0];
   if (encoding == BSE_PIXDATA_1BYTE_RLE)
     {
       const guint8 *rle_buffer = pixdata->encoded_pix_data;
-      guint8 *image_limit = image_buffer + icon->width * icon->height * bpp;
+      guint8 *image_limit = image_buffer + icon.width * icon.height * bpp;
       while (image_buffer < image_limit)
        {
          guint length = *(rle_buffer++);
@@ -274,43 +266,46 @@ bse_ic0n_from_pixdata (const BsePixdata *pixdata)
         }
     }
   else
-    memcpy (image_buffer, pixdata->encoded_pix_data, icon->width * icon->height * bpp);
+    memcpy (image_buffer, pixdata->encoded_pix_data, icon.width * icon.height * bpp);
   return icon;
 }
-static inline const guint8 *
-get_uint32 (const guint8 *stream, guint *result)
+static inline const uint8*
+get_uint32 (const uint8 *stream, uint *result)
 {
   *result = (stream[0] << 24) + (stream[1] << 16) + (stream[2] << 8) + stream[3];
   return stream + 4;
 }
-BseIc0n*
-bse_ic0n_from_pixstream (const guint8 *pixstream)
+
+Bse::Icon
+bse_icon_from_pixstream (const guint8 *pixstream)
 {
+  Bse::Icon icon;
   BsePixdata pixd;
-  const guint8 *s = pixstream;
-  guint len, type, rowstride, width, height;
-  assert_return (pixstream != NULL, NULL);
+  const uint8 *s = pixstream;
+  uint len, type, rowstride, width, height;
+  assert_return (pixstream != NULL, icon);
   if (strncmp ((const char*) s, "GdkP", 4) != 0)
-    return NULL;
+    return icon;
   s += 4;
   s = get_uint32 (s, &len);
   if (len < 24)
-    return NULL;
+    return icon;
   s = get_uint32 (s, &type);
   if (type != 0x02010002 &&     /* RLE/8bit/RGBA */
       type != 0x01010002)       /* RAW/8bit/RGBA */
-    return NULL;
+    return icon;
   s = get_uint32 (s, &rowstride);
   s = get_uint32 (s, &width);
   s = get_uint32 (s, &height);
   if (width < 1 || height < 1)
-    return NULL;
+    return icon;
   pixd.type = BsePixdataType (BSE_PIXDATA_RGBA | (type >> 24 == 2 ? BSE_PIXDATA_1BYTE_RLE : 0));
   pixd.width = width;
   pixd.height = height;
   pixd.encoded_pix_data = s;
-  return bse_ic0n_from_pixdata (&pixd);
+  return bse_icon_from_pixdata (&pixd);
 }
+
 /* --- ID allocator --- */
 #define        ID_WITHHOLD_BUFFER_SIZE         59
 static gulong  id_counter = 1;
index d5eaa25..03f7053 100644 (file)
@@ -45,7 +45,7 @@ void    bse_balance_set         (double  balance,
 
 
 /* --- icons --- */
-BseIc0n* bse_ic0n_from_pixstream (const guint8     *pixstream);
+Bse::Icon bse_icon_from_pixstream (const uint8 *pixstream);
 
 
 /* --- ID allocator --- */
index ed23a2d..f9905be 100644 (file)
@@ -26,7 +26,7 @@ static void    bse_adder_get_property         (GObject        *object,
                                                 guint           param_id,
                                                 GValue         *value,
                                                 GParamSpec     *pspec);
-static BseIc0n*         bse_adder_do_get_icon          (BseObject      *object);
+static Bse::Icon bse_adder_do_get_icon         (BseObject      *object);
 static void      bse_adder_context_create       (BseSource      *source,
                                                 guint           context_handle,
                                                 BseTrans       *trans);
@@ -64,7 +64,7 @@ bse_adder_class_init (BseAdderClass *klass)
 
   source_class->context_create = bse_adder_context_create;
 
-  klass->sub_icon = bse_ic0n_from_pixstream (sub_pixstream);
+  klass->sub_icon = bse_icon_from_pixstream (sub_pixstream);
 
   bse_object_class_add_param (object_class, "Features",
                              PARAM_SUBTRACT,
@@ -88,11 +88,10 @@ bse_adder_init (BseAdder *self)
   self->subtract = FALSE;
 }
 
-static BseIc0n*
+static Bse::Icon
 bse_adder_do_get_icon (BseObject *object)
 {
   BseAdder *self = BSE_ADDER (object);
-
   if (self->subtract)
     return BSE_ADDER_GET_CLASS (self)->sub_icon;
   else /* chain parent class' handler */
index daa0ae4..df935e2 100644 (file)
@@ -22,7 +22,7 @@ struct BseAdder : BseSource {
   gboolean       subtract;
 };
 struct BseAdderClass : BseSourceClass {
-  BseIc0n      *sub_icon;
+  Bse::Icon     sub_icon;
 };
 
 enum