switch transport masters to use properties and notify via PropertyChanged

This commit is contained in:
Paul Davis
2018-09-20 11:30:28 -04:00
parent 5ffd2078da
commit 9cdbeaa07d
6 changed files with 127 additions and 50 deletions

View 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)
{

View File

@@ -28,16 +28,19 @@
#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 {

View 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)

View 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

View 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) \

View File

@@ -19,6 +19,7 @@
#include <vector>
#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<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;
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);
}
}