switch transport masters to use properties and notify via PropertyChanged
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 20 Sep 2018 15:30:28 +0000 (11:30 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 20 Sep 2018 15:30:28 +0000 (11:30 -0400)
gtk2_ardour/transport_masters_dialog.cc
libs/ardour/ardour/transport_master.h
libs/ardour/ardour/types_convert.h
libs/ardour/globals.cc
libs/ardour/region.cc
libs/ardour/transport_master.cc

index e0ede3e91951b60df0ff3fc54bf264b475ffd800..ca4722fd02858d2f9c85a116bc744c178557b89b 100644 (file)
@@ -153,7 +153,6 @@ TransportMastersWidget::rebuild ()
                }
 
                r->port_combo.signal_changed().connect (sigc::mem_fun (*r, &TransportMastersWidget::Row::port_choice_changed));
-               ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (*r, invalidator (*this), boost::bind (&TransportMastersWidget::Row::connection_handler, r), gui_context());
 
                r->collect_button.set_active (r->tm->collect());
 
@@ -220,11 +219,6 @@ TransportMastersWidget::Row::build_request_options ()
        i->set_active (tm->request_mask() & TR_Locate);
 }
 
-void
-TransportMastersWidget::Row::connection_handler ()
-{
-}
-
 Glib::RefPtr<Gtk::ListStore>
 TransportMastersWidget::Row::build_port_list (vector<string> const & ports)
 {
index ecb6f280238589a7e54ac74d39d4c8f4e1ab1af3..b41d1070150180e338ca2178a0097666a9d8d0ad 100644 (file)
 
 #include <ltc.h>
 
+#include "pbd/properties.h"
 #include "pbd/signals.h"
+#include "pbd/stateful.h"
 
 #include "temporal/time.h"
 
 #include "ardour/libardour_visibility.h"
+#include "ardour/region.h" /* for Properties::locked */
 #include "ardour/types.h"
+
 #include "midi++/parser.h"
 #include "midi++/types.h"
 
-
 /* used for delta_string(): */
 #define PLUSMINUS(A) ( ((A)<0) ? "-" : (((A)>0) ? "+" : "\u00B1") )
 #define LEADINGZERO(A) ( (A)<10 ? "   " : (A)<100 ? "  " : (A)<1000 ? " " : "" )
@@ -52,6 +55,13 @@ class MidiPort;
 class AudioPort;
 class Port;
 
+namespace Properties {
+       LIBARDOUR_API extern PBD::PropertyDescriptor<bool> fr2997;
+       LIBARDOUR_API extern PBD::PropertyDescriptor<bool> collect;
+       LIBARDOUR_API extern PBD::PropertyDescriptor<bool> connected;
+       LIBARDOUR_API extern PBD::PropertyDescriptor<bool> sclock_synced;
+       LIBARDOUR_API extern PBD::PropertyDescriptor<ARDOUR::TransportRequestType> allowed_transport_requests;
+};
 
 /**
  * @class TransportMaster
@@ -62,7 +72,7 @@ class Port;
  * Ardour (GUI, control surfaces, OSC, etc.)
  *
  */
-class LIBARDOUR_API TransportMaster {
+class LIBARDOUR_API TransportMaster : public PBD::Stateful {
   public:
 
        TransportMaster (SyncSource t, std::string const & name);
@@ -218,6 +228,7 @@ class LIBARDOUR_API TransportMaster {
        XMLNode& get_state();
 
        static const std::string state_node_name;
+       static void make_property_quarks ();
 
        virtual void set_session (Session*);
 
@@ -240,14 +251,15 @@ class LIBARDOUR_API TransportMaster {
        void set_request_mask (TransportRequestType);
   protected:
        SyncSource      _type;
-       std::string     _name;
+       PBD::Property<std::string>   _name;
        Session*        _session;
-       bool            _connected;
        sampleoffset_t  _current_delta;
-       bool            _collect;
        bool            _pending_collect;
-       TransportRequestType _request_mask; /* lists transport requests still accepted when we're in control */
-       bool            _sclock_synced;
+       PBD::Property<TransportRequestType> _request_mask; /* lists transport requests still accepted when we're in control */
+       PBD::Property<bool> _locked;
+       PBD::Property<bool> _sclock_synced;
+       PBD::Property<bool> _collect;
+       PBD::Property<bool> _connected;
 
        /* DLL - chase incoming data */
 
@@ -265,6 +277,8 @@ class LIBARDOUR_API TransportMaster {
        bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
 
        PBD::ScopedConnection backend_connection;
+
+       virtual void register_properties ();
 };
 
 struct LIBARDOUR_API SafeTime {
@@ -300,7 +314,7 @@ class LIBARDOUR_API TransportMasterViaMIDI {
 
 class LIBARDOUR_API TimecodeTransportMaster : public TransportMaster {
   public:
-       TimecodeTransportMaster (std::string const & name, SyncSource type) : TransportMaster (type, name) {}
+       TimecodeTransportMaster (std::string const & name, SyncSource type);
 
        virtual Timecode::TimecodeFormat apparent_timecode_format() const = 0;
        samplepos_t        timecode_offset;
@@ -309,9 +323,11 @@ class LIBARDOUR_API TimecodeTransportMaster : public TransportMaster {
        bool fr2997() const { return _fr2997; }
        void set_fr2997 (bool);
 
-  private:
-       bool               _fr2997;
+  protected:
+       void register_properties ();
 
+  private:
+       PBD::Property<bool> _fr2997;
 };
 
 class LIBARDOUR_API MTC_TransportMaster : public TimecodeTransportMaster, public TransportMasterViaMIDI {
index dcdc49fae3033e230ee44a9e4c420d4d1ee44495..8c3c87a6517f700f1d492f12adc4c62406b89003 100644 (file)
@@ -64,17 +64,15 @@ DEFINE_ENUM_CONVERT(ARDOUR::NoteMode)
 DEFINE_ENUM_CONVERT(ARDOUR::ChannelMode)
 DEFINE_ENUM_CONVERT(ARDOUR::MonitorChoice)
 DEFINE_ENUM_CONVERT(ARDOUR::PluginType)
-
 DEFINE_ENUM_CONVERT(ARDOUR::AlignStyle)
 DEFINE_ENUM_CONVERT(ARDOUR::AlignChoice)
-
 DEFINE_ENUM_CONVERT(ARDOUR::RegionEquivalence)
 DEFINE_ENUM_CONVERT(ARDOUR::WaveformScale)
 DEFINE_ENUM_CONVERT(ARDOUR::WaveformShape)
 DEFINE_ENUM_CONVERT(ARDOUR::VUMeterStandard)
 DEFINE_ENUM_CONVERT(ARDOUR::MeterLineUp)
-
 DEFINE_ENUM_CONVERT(ARDOUR::MidiPortFlags)
+DEFINE_ENUM_CONVERT(ARDOUR::TransportRequestType)
 
 DEFINE_ENUM_CONVERT(MusicalMode::Type)
 
index a806b693b4a072c153a80ba55cc80b866d4dd314..e3e24378c5d832836366a5759b161b76da30a8f1 100644 (file)
@@ -460,6 +460,7 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir
         Playlist::make_property_quarks ();
         AudioPlaylist::make_property_quarks ();
         PresentationInfo::make_property_quarks ();
+        TransportMaster::make_property_quarks ();
 
        /* this is a useful ready to use PropertyChange that many
           things need to check. This avoids having to compose
index d4afb7d9c404729690d98021ac89f22c10d6f4a1..3abc6d4ff6b434a7df525675c29bc5912921b65d 100644 (file)
@@ -187,7 +187,7 @@ Region::register_properties ()
        , _muted (Properties::muted, false) \
        , _opaque (Properties::opaque, true) \
        , _locked (Properties::locked, false) \
-  , _video_locked (Properties::video_locked, false) \
+       , _video_locked (Properties::video_locked, false) \
        , _automatic (Properties::automatic, false) \
        , _whole_file (Properties::whole_file, false) \
        , _import (Properties::import, false) \
index 284a0a8537b3f4837080a0b9f007929053e3da14..4ebdbbf50bccacbd4198e235aa0fe7bd4ca31f3e 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <vector>
 
+#include "pbd/debug.h"
 #include "pbd/i18n.h"
 
 #include "ardour/audioengine.h"
 #include "ardour/session.h"
 #include "ardour/transport_master.h"
 #include "ardour/transport_master_manager.h"
+#include "ardour/types_convert.h"
 #include "ardour/utils.h"
 
+namespace ARDOUR {
+       namespace Properties {
+               PBD::PropertyDescriptor<bool> fr2997;
+               PBD::PropertyDescriptor<bool> sclock_synced;
+               PBD::PropertyDescriptor<bool> collect;
+               PBD::PropertyDescriptor<bool> connected;
+               PBD::PropertyDescriptor<TransportRequestType> allowed_transport_requests;
+       }
+}
+
 using namespace ARDOUR;
+using namespace PBD;
 
-const std::string TransportMaster::state_node_name = X_("TransportMaster");
+void
+TransportMaster::make_property_quarks ()
+{
+       Properties::fr2997.property_id = g_quark_from_static_string (X_("fr2997"));
+       DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fr2997 = %1\n", Properties::fr2997.property_id));
+       Properties::sclock_synced.property_id = g_quark_from_static_string (X_("sclock_synced"));
+       DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sclock_synced = %1\n", Properties::sclock_synced.property_id));
+       Properties::collect.property_id = g_quark_from_static_string (X_("collect"));
+       DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for collect = %1\n", Properties::collect.property_id));
+       Properties::connected.property_id = g_quark_from_static_string (X_("connected"));
+       DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for connected = %1\n", Properties::connected.property_id));
+}
 
+const std::string TransportMaster::state_node_name = X_("TransportMaster");
 
 TransportMaster::TransportMaster (SyncSource t, std::string const & name)
        : _type (t)
-       , _name (name)
+       , _name (Properties::name, name)
        , _session (0)
-       , _connected (false)
        , _current_delta (0)
-       , _collect (true)
        , _pending_collect (true)
-       , _request_mask (TransportRequestType (0))
-       , _sclock_synced (false)
+       , _request_mask (Properties::allowed_transport_requests, TransportRequestType (0))
+       , _locked (Properties::locked, false)
+       , _sclock_synced (Properties::sclock_synced, false)
+       , _collect (Properties::collect, true)
+       , _connected (Properties::connected, false)
 {
+       register_properties ();
+
        ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect_same_thread (port_connection, boost::bind (&TransportMaster::connection_handler, this, _1, _2, _3, _4, _5));
        ARDOUR::AudioEngine::instance()->Running.connect_same_thread (backend_connection, boost::bind (&TransportMaster::check_backend, this));
 }
@@ -53,6 +81,31 @@ TransportMaster::~TransportMaster()
        delete _session;
 }
 
+void
+TransportMaster::register_properties ()
+{
+       _xml_node_name = state_node_name;
+
+       add_property (_name);
+       add_property (_locked);
+       add_property (_collect);
+       add_property (_sclock_synced);
+       add_property (_request_mask);
+
+       /* we omit _connected since it is derived from port state, and merely
+        * used for signalling
+        */
+}
+
+void
+TransportMaster::set_name (std::string const & str)
+{
+       if (_name != str) {
+               _name = str;
+               PropertyChange (Properties::name);
+       }
+}
+
 bool
 TransportMaster::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
 {
@@ -66,12 +119,19 @@ TransportMaster::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string
 
                /* it's about us */
 
+               /* XXX technically .. if the user makes an N->1 connection to
+                * this transport master's port, this simple minded logic is
+                * not sufficient. But the user shouldn't do that ...
+                */
+
                if (yn) {
                        _connected = true;
                } else {
                        _connected = false;
                }
 
+               PropertyChanged (Properties::connected);
+
                return true;
        }
 
@@ -97,8 +157,8 @@ TransportMaster::check_collect()
                                }
                        }
                }
-               std::cerr << name() << " pc = " << _pending_collect << " c = " << _collect << std::endl;
                _collect = _pending_collect;
+               PropertyChanged (Properties::collect);
        }
 
        return _collect;
@@ -113,7 +173,10 @@ TransportMaster::set_collect (bool yn)
 void
 TransportMaster::set_sample_clock_synced (bool yn)
 {
-       _sclock_synced = yn;
+       if (yn != _sclock_synced) {
+               _sclock_synced = yn;
+               PropertyChanged (Properties::sclock_synced);
+       }
 }
 
 void
@@ -125,20 +188,9 @@ TransportMaster::set_session (Session* s)
 int
 TransportMaster::set_state (XMLNode const & node, int /* version */)
 {
-       if (!node.get_property (X_("collect"), _collect)) {
-               _collect = false;
-       }
+       PropertyChange what_changed;
 
-       if (!node.get_property (X_("clock-synced"), _sclock_synced)) {
-               _sclock_synced = false;
-       }
-
-       TimecodeTransportMaster* ttm = dynamic_cast<TimecodeTransportMaster*> (this);
-       if (ttm) {
-               bool val;
-               node.get_property (X_("fr2997"), val);
-               ttm->set_fr2997 (val);
-       }
+       what_changed = set_values (node);
 
        XMLNode* pnode = node.child (X_("Port"));
 
@@ -157,6 +209,8 @@ TransportMaster::set_state (XMLNode const & node, int /* version */)
                }
        }
 
+       PropertyChanged (what_changed);
+
        return 0;
 }
 
@@ -165,14 +219,8 @@ TransportMaster::get_state ()
 {
        XMLNode* node = new XMLNode (state_node_name);
        node->set_property (X_("type"), _type);
-       node->set_property (X_("name"), _name);
-       node->set_property (X_("collect"), _collect);
-       node->set_property (X_("clock-synced"), _sclock_synced);
 
-       TimecodeTransportMaster* ttm = dynamic_cast<TimecodeTransportMaster*> (this);
-       if (ttm) {
-               node->set_property (X_("fr2997"), ttm->fr2997());
-       }
+       add_properties (*node);
 
        if (_port) {
                std::vector<std::string> connections;
@@ -271,11 +319,31 @@ TransportMaster::allow_request (TransportRequestSource src, TransportRequestType
 void
 TransportMaster::set_request_mask (TransportRequestType t)
 {
-       _request_mask = t;
+       if (_request_mask != t) {
+               _request_mask = t;
+               PropertyChanged (Properties::allowed_transport_requests);
+       }
+}
+
+TimecodeTransportMaster::TimecodeTransportMaster (std::string const & name, SyncSource type)
+       : TransportMaster (type, name)
+       , _fr2997 (Properties::fr2997, false)
+{
+       register_properties ();
+}
+
+void
+TimecodeTransportMaster::register_properties ()
+{
+       TransportMaster::register_properties ();
+       add_property (_fr2997);
 }
 
 void
 TimecodeTransportMaster::set_fr2997 (bool yn)
 {
-       _fr2997 = yn;
+       if (yn != _fr2997) {
+               _fr2997 = yn;
+               PropertyChanged (Properties::fr2997);
+       }
 }