From 9cdbeaa07d916da8ee84e2172895b38965740604 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 20 Sep 2018 11:30:28 -0400 Subject: switch transport masters to use properties and notify via PropertyChanged --- gtk2_ardour/transport_masters_dialog.cc | 6 -- libs/ardour/ardour/transport_master.h | 36 ++++++--- libs/ardour/ardour/types_convert.h | 4 +- libs/ardour/globals.cc | 1 + libs/ardour/region.cc | 2 +- libs/ardour/transport_master.cc | 128 ++++++++++++++++++++++++-------- 6 files changed, 127 insertions(+), 50 deletions(-) diff --git a/gtk2_ardour/transport_masters_dialog.cc b/gtk2_ardour/transport_masters_dialog.cc index e0ede3e919..ca4722fd02 100644 --- a/gtk2_ardour/transport_masters_dialog.cc +++ b/gtk2_ardour/transport_masters_dialog.cc @@ -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 TransportMastersWidget::Row::build_port_list (vector const & ports) { diff --git a/libs/ardour/ardour/transport_master.h b/libs/ardour/ardour/transport_master.h index ecb6f28023..b41d107015 100644 --- a/libs/ardour/ardour/transport_master.h +++ b/libs/ardour/ardour/transport_master.h @@ -28,16 +28,19 @@ #include +#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 fr2997; + LIBARDOUR_API extern PBD::PropertyDescriptor collect; + LIBARDOUR_API extern PBD::PropertyDescriptor connected; + LIBARDOUR_API extern PBD::PropertyDescriptor sclock_synced; + LIBARDOUR_API extern PBD::PropertyDescriptor 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 _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 _request_mask; /* lists transport requests still accepted when we're in control */ + PBD::Property _locked; + PBD::Property _sclock_synced; + PBD::Property _collect; + PBD::Property _connected; /* DLL - chase incoming data */ @@ -265,6 +277,8 @@ class LIBARDOUR_API TransportMaster { bool connection_handler (boost::weak_ptr, std::string name1, boost::weak_ptr, 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 _fr2997; }; class LIBARDOUR_API MTC_TransportMaster : public TimecodeTransportMaster, public TransportMasterViaMIDI { diff --git a/libs/ardour/ardour/types_convert.h b/libs/ardour/ardour/types_convert.h index dcdc49fae3..8c3c87a651 100644 --- a/libs/ardour/ardour/types_convert.h +++ b/libs/ardour/ardour/types_convert.h @@ -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) diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index a806b693b4..e3e24378c5 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -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 diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index d4afb7d9c4..3abc6d4ff6 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -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) \ diff --git a/libs/ardour/transport_master.cc b/libs/ardour/transport_master.cc index 284a0a8537..4ebdbbf50b 100644 --- a/libs/ardour/transport_master.cc +++ b/libs/ardour/transport_master.cc @@ -19,6 +19,7 @@ #include +#include "pbd/debug.h" #include "pbd/i18n.h" #include "ardour/audioengine.h" @@ -26,24 +27,51 @@ #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 fr2997; + PBD::PropertyDescriptor sclock_synced; + PBD::PropertyDescriptor collect; + PBD::PropertyDescriptor connected; + PBD::PropertyDescriptor 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, std::string name1, boost::weak_ptr, std::string name2, bool yn) { @@ -66,12 +119,19 @@ TransportMaster::connection_handler (boost::weak_ptr, 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 (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 (this); - if (ttm) { - node->set_property (X_("fr2997"), ttm->fr2997()); - } + add_properties (*node); if (_port) { std::vector 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); + } } -- cgit v1.2.3