[beast: 45/49] BSE: bseapi.idl: introduce Track



commit 66310165fc43a8049c7c36d9f45419c434c8fab0
Author: Tim Janik <timj gnu org>
Date:   Thu Jun 25 04:18:17 2015 +0200

    BSE: bseapi.idl: introduce Track

 beast-gtk/bsttrackrollctrl.cc |   15 ++++++--
 bse/bseapi.idl                |    6 +++
 bse/bseobject.cc              |    3 ++
 bse/bsetrack.cc               |   64 +++++++++++++++++++++++++++++++++---
 bse/bsetrack.hh               |   14 +++++++-
 bse/bsetrack.proc             |   72 -----------------------------------------
 6 files changed, 91 insertions(+), 83 deletions(-)
---
diff --git a/beast-gtk/bsttrackrollctrl.cc b/beast-gtk/bsttrackrollctrl.cc
index eee369f..17aaf70 100644
--- a/beast-gtk/bsttrackrollctrl.cc
+++ b/beast-gtk/bsttrackrollctrl.cc
@@ -425,7 +425,9 @@ insert_start (BstTrackRollController *self,
          SfiProxy song = bse_item_get_parent (drag->current_track);
           bse_item_group_undo (song, "Insert part");
          item = bse_song_create_part (song);
-         if (item && bse_track_insert_part (drag->current_track, tick, item) > 0)
+          Bse::PartH part = Bse::PartH::down_cast (bse_server.from_proxy (item));
+          Bse::TrackH track = Bse::TrackH::down_cast (bse_server.from_proxy (drag->current_track));
+         if (item && track.insert_part (tick, part) > 0)
            gxk_status_set (GXK_STATUS_DONE, _("Insert Part"), NULL);
          else
            gxk_status_set (GXK_STATUS_ERROR, _("Insert Part"), _("Lost Part"));
@@ -452,7 +454,8 @@ delete_start (BstTrackRollController *self,
   if (self->obj_part)  /* got part to delete */
     {
       bse_item_group_undo (self->song, "Delete Part");
-      bse_track_remove_tick (self->obj_track, self->obj_tick);
+      Bse::TrackH track = Bse::TrackH::down_cast (bse_server.from_proxy (self->obj_track));
+      track.remove_tick (self->obj_tick);
       if (!bse_song_find_any_track_for_part (self->song, self->obj_part.proxy_id()))
         bse_song_remove_part (self->song, self->obj_part.proxy_id());
       bse_item_ungroup_undo (self->song);
@@ -510,10 +513,14 @@ move_motion (BstTrackRollController *self, BstTrackRollDrag *drag)
   if (new_tick != self->obj_tick || self->obj_track != drag->current_track)
     {
       bse_item_group_undo (drag->current_track, "Move part");
-      if (bse_track_insert_part (drag->current_track, new_tick, self->obj_part.proxy_id()) > 0)
+      Bse::TrackH track = Bse::TrackH::down_cast (bse_server.from_proxy (drag->current_track));
+      if (track.insert_part (new_tick, self->obj_part) > 0)
        {
          if (!self->skip_deletion)
-           bse_track_remove_tick (self->obj_track, self->obj_tick);
+            {
+              Bse::TrackH track = Bse::TrackH::down_cast (bse_server.from_proxy (self->obj_track));
+              track.remove_tick (self->obj_tick);
+            }
          else
            {
              self->skip_deletion = FALSE;
diff --git a/bse/bseapi.idl b/bse/bseapi.idl
index b560ac8..0b28503 100644
--- a/bse/bseapi.idl
+++ b/bse/bseapi.idl
@@ -400,6 +400,12 @@ interface Source : Item {
 interface ContextMerger : Source {
 };
 
+/// Data object containing sequencing information and links to Part objects.
+interface Track : ContextMerger {
+  int32 insert_part (int32 tick, Part part); ///< Insert Part into Track at @a tick, returns the 
corresponding link id.
+  void  remove_tick (int32 tick);            ///< Remove Part at specified @a tick from a track.
+};
+
 /// Base type for objects that can be added to a container.
 interface Container : Source {
   Item lookup_item (String uname); ///< Find an immediate child of a container by name (unique per container 
child).
diff --git a/bse/bseobject.cc b/bse/bseobject.cc
index fade938..787db95 100644
--- a/bse/bseobject.cc
+++ b/bse/bseobject.cc
@@ -917,6 +917,7 @@ bse_object_new (GType object_type, const gchar *first_property_name, ...)
 
 #include "bseserver.hh"
 #include "bseproject.hh"
+#include "bsetrack.hh"
 #include "bsecontextmerger.hh"
 #include "bsesnet.hh"
 #include "bsepart.hh"
@@ -943,6 +944,8 @@ bse_object_new_valist (GType object_type, const gchar *first_property_name, va_l
     cxxo = new Bse::SuperImpl (object);
   else if (g_type_is_a (object_type, BSE_TYPE_CONTAINER))
     cxxo = new Bse::ContainerImpl (object);
+  else if (g_type_is_a (object_type, BSE_TYPE_TRACK))
+    cxxo = new Bse::TrackImpl (object);
   else if (g_type_is_a (object_type, BSE_TYPE_CONTEXT_MERGER))
     cxxo = new Bse::ContextMergerImpl (object);
   else if (g_type_is_a (object_type, BSE_TYPE_PART))
diff --git a/bse/bsetrack.cc b/bse/bsetrack.cc
index f41fb90..a09cc5f 100644
--- a/bse/bsetrack.cc
+++ b/bse/bsetrack.cc
@@ -242,8 +242,9 @@ track_uncross_part (BseItem *owner,
       {
         guint tick = self->entries_SL[i].tick;
        XREF_DEBUG ("uncrossing[start]: %p %p (%d)", self, part, tick);
-        /* delete track via procedure so deletion is recorded to undo */
-        bse_item_exec_void (owner, "remove-tick", tick);
+        // delete track via TrackImpl so deletion is recorded to undo
+        Bse::TrackImpl *track = owner->as<Bse::TrackImpl*>();
+        track->remove_tick (tick);
        XREF_DEBUG ("uncrossing[done]: %p %p (%d)", self, part, tick);
        return;
       }
@@ -579,8 +580,8 @@ bse_track_insert_part (BseTrack *self,
 {
   BseTrackEntry *entry;
 
-  g_return_val_if_fail (BSE_IS_TRACK (self), Bse::ERROR_INTERNAL);
-  g_return_val_if_fail (BSE_IS_PART (part), Bse::ERROR_INTERNAL);
+  g_return_val_if_fail (BSE_IS_TRACK (self), 0);
+  g_return_val_if_fail (BSE_IS_PART (part), 0);
 
   entry = track_lookup_entry (self, tick);
   if (entry && entry->tick == tick)
@@ -635,9 +636,9 @@ bse_track_list_parts_intern (BseTrack *self,
          tp.part = entry->part;
          if (song)
            bse_song_get_timing (song, tp.tick, &timing);
-         tp.duration = MAX (timing.tpt, entry->part->last_tick_SL);
+         tp.duration = MAX (uint (timing.tpt), entry->part->last_tick_SL);
          if (i + 1 < self->n_entries_SL)
-           tp.duration = MIN (tp.duration, entry[1].tick - entry->tick);
+           tp.duration = MIN (uint (tp.duration), entry[1].tick - entry->tick);
          bse_track_part_seq_append (tps, &tp);
        }
     }
@@ -1056,3 +1057,54 @@ bse_track_class_init (BseTrackClass *klass)
                                                     BSE_TYPE_ITEM_SEQ, SFI_PARAM_GUI ":item-sequence"));
   signal_changed = bse_object_class_add_asignal (object_class, "changed", G_TYPE_NONE, 0);
 }
+
+namespace Bse {
+
+TrackImpl::TrackImpl (BseObject *bobj) :
+  ContextMergerImpl (bobj)
+{}
+
+TrackImpl::~TrackImpl ()
+{}
+
+int
+TrackImpl::insert_part (int tick, PartIface &parti)
+{
+  BseTrack *self = as<BseTrack*>();
+  PartImpl &part = dynamic_cast<PartImpl&> (parti);
+  assert_return (parent() != NULL && parent() == part.parent(), 0); // parent is SongImpl
+  uint id = bse_track_insert_part (self, tick, part.as<BsePart*>());
+  if (id)
+    {
+      // can't use remove_link() here, since id will have changed after undo
+      push_undo ("Insert Part", *this, &TrackImpl::remove_tick, tick);
+    }
+  return id;
+}
+
+void
+TrackImpl::remove_tick (int tick)
+{
+  BseTrack *self = as<BseTrack*>();
+  BseTrackEntry *entry = bse_track_lookup_tick (self, tick);
+  if (entry)
+    {
+      // undoing part removal needs an undo_descriptor b/c future deletions may invalidate the part handle
+      const char *blurb = "Remove Tick";
+      BseUndoStack *ustack = bse_item_undo_open (self, blurb);
+      const String part_descriptor = undo_stack_to_descriptor (ustack, *entry->part->as<PartImpl*>());
+      const uint utick = entry->tick;
+      UndoErrorLambda lambda = [utick, part_descriptor] (ItemImpl &item, BseUndoStack *ustack) {
+        TrackImpl &self = dynamic_cast<TrackImpl&> (item);
+        ItemImpl *part_item = undo_stack_item_from_descriptor (ustack, part_descriptor);
+        PartImpl &part = dynamic_cast<PartImpl&> (*part_item);
+        const uint id = self.insert_part (utick, part);
+        return id ? ERROR_NONE : ERROR_INVALID_OVERLAP;
+      };
+      bse_track_remove_tick (self, tick);
+      push_undo (blurb, lambda);
+      bse_item_undo_close (ustack);
+    }
+}
+
+} // Bse
diff --git a/bse/bsetrack.hh b/bse/bsetrack.hh
index 83a06a7..488b811 100644
--- a/bse/bsetrack.hh
+++ b/bse/bsetrack.hh
@@ -77,7 +77,19 @@ BsePart*      bse_track_get_part_SL  (BseTrack               *self,
                                         guint                   tick,
                                         guint                  *start,
                                         guint                  *next);
-
 G_END_DECLS
 
+namespace Bse {
+
+class TrackImpl : public ContextMergerImpl, public virtual TrackIface {
+protected:
+  virtual              ~TrackImpl       ();
+public:
+  explicit              TrackImpl       (BseObject*);
+  virtual int           insert_part     (int tick, PartIface &part) override;
+  virtual void          remove_tick     (int tick) override;
+};
+
+} // Bse
+
 #endif /* __BSE_TRACK_H__ */
diff --git a/bse/bsetrack.proc b/bse/bsetrack.proc
index d6fe943..41c4dfb 100644
--- a/bse/bsetrack.proc
+++ b/bse/bsetrack.proc
@@ -13,78 +13,6 @@ AUTHORS      = "Tim Janik <timj gtk org>";
 LICENSE = "Copyright (C) 2003 Tim Janik";
 
 
-METHOD (BseTrack, insert-part) {
-  HELP  = "Insert a part into a track and retrieve the corresponding link id.";
-  IN    = bse_param_spec_object ("track", "Track", NULL,
-                                BSE_TYPE_TRACK, SFI_PARAM_STANDARD);
-  IN    = sfi_pspec_int ("tick", "Tick", NULL,
-                        0, 0, BSE_PART_MAX_TICK - 1, 384, SFI_PARAM_STANDARD);
-  IN    = bse_param_spec_object ("part", "Part", NULL,
-                                BSE_TYPE_PART, SFI_PARAM_STANDARD);
-  OUT   = sfi_pspec_int ("id", "Link ID", NULL,
-                         0, 0, SFI_MAXINT, 1, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  BseTrack *self = (BseTrack*) bse_value_get_object (in_values++);
-  guint tick = sfi_value_get_int (in_values++);
-  BsePart *part = (BsePart*) bse_value_get_object (in_values++);
-  guint id;
-
-  /* check parameters */
-  if (!BSE_IS_TRACK (self) || !BSE_IS_PART (part) ||
-      !BSE_ITEM (self)->parent ||
-      BSE_ITEM (self)->parent != BSE_ITEM (part)->parent)
-    return Bse::ERROR_PROC_PARAM_INVAL;
-
-  /* action */
-  id = bse_track_insert_part (self, tick, part);
-  if (id)
-    {
-      /* can't use remove-link() here, since id will have changed after undo */
-      bse_item_push_undo_proc (self, "remove-tick", tick);
-    }
-
-  /* set output parameters */
-  g_value_set_int (out_values++, id);
-
-  return Bse::ERROR_NONE;
-}
-
-METHOD (BseTrack, remove-tick) {
-  HELP  = "Remove a part at specified tick from a track.";
-  IN    = bse_param_spec_object ("track", "Track", NULL,
-                                BSE_TYPE_TRACK, SFI_PARAM_STANDARD);
-  IN    = sfi_pspec_int ("tick", "Tick", NULL,
-                        0, 0, BSE_PART_MAX_TICK - 1, 384, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  BseTrack *self = (BseTrack*) bse_value_get_object (in_values++);
-  guint     tick = sfi_value_get_int (in_values++);
-  BseTrackEntry *entry;
-
-  /* check parameters */
-  if (!BSE_IS_TRACK (self))
-    return Bse::ERROR_PROC_PARAM_INVAL;
-
-  /* action */
-  entry = bse_track_lookup_tick (self, tick);
-  if (entry)
-    {
-      bse_item_push_undo_proc (self, "insert-part", entry->tick, entry->part);
-      bse_track_remove_tick (self, tick);
-    }
-
-  return Bse::ERROR_NONE;
-}
-
 METHOD (BseTrack, remove-link) {
   HELP  = "Remove a specific part link by ID from a track.";
   IN    = bse_param_spec_object ("track", "Track", NULL,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]