summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-10-24 12:18:40 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2014-10-24 12:18:46 -0400
commitf90071113654c5d788e90196db5ee1dedd11172f (patch)
tree54e708b10f4df0687db03bda9feb3d16dc83ff38 /libs/ardour/ardour
parent2f4a8cf69394d4c6442381297136662af923f577 (diff)
port changes to ARDOUR::Location and ARDOUR::Locations APIs from Tracks to Ardour.
Fixes deadlocks caused by mutex on Locations list, and clarifies the purposes and uses of the class-level and object-level change-related signals.
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/location.h41
-rw-r--r--libs/ardour/ardour/midi_scene_changer.h2
-rw-r--r--libs/ardour/ardour/session.h15
3 files changed, 32 insertions, 26 deletions
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
index 754ebb8075..f809dbf280 100644
--- a/libs/ardour/ardour/location.h
+++ b/libs/ardour/ardour/location.h
@@ -53,6 +53,7 @@ class LIBARDOUR_API Location : public SessionHandleRef, public PBD::StatefulDest
IsRangeMarker = 0x20,
IsSessionRange = 0x40,
IsSkip = 0x80,
+ IsSkipping = 0x100, /* skipping is active (or not) */
};
Location (Session &);
@@ -78,7 +79,7 @@ class LIBARDOUR_API Location : public SessionHandleRef, public PBD::StatefulDest
int move_to (framepos_t pos);
const std::string& name() const { return _name; }
- void set_name (const std::string &str) { _name = str; name_changed(this); }
+ void set_name (const std::string &str);
void set_auto_punch (bool yn, void *src);
void set_auto_loop (bool yn, void *src);
@@ -86,6 +87,7 @@ class LIBARDOUR_API Location : public SessionHandleRef, public PBD::StatefulDest
void set_cd (bool yn, void *src);
void set_is_range_marker (bool yn, void* src);
void set_skip (bool yn);
+ void set_skipping (bool yn);
bool is_auto_punch () const { return _flags & IsAutoPunch; }
bool is_auto_loop () const { return _flags & IsAutoLoop; }
@@ -95,6 +97,7 @@ class LIBARDOUR_API Location : public SessionHandleRef, public PBD::StatefulDest
bool is_session_range () const { return _flags & IsSessionRange; }
bool is_range_marker() const { return _flags & IsRangeMarker; }
bool is_skip() const { return _flags & IsSkip; }
+ bool is_skipping() const { return (_flags & IsSkip) && (_flags & IsSkipping); }
bool matches (Flags f) const { return _flags & f; }
Flags flags () const { return _flags; }
@@ -197,28 +200,26 @@ class LIBARDOUR_API Locations : public SessionHandleRef, public PBD::StatefulDes
void find_all_between (framepos_t start, framepos_t, LocationList&, Location::Flags);
- enum Change {
- ADDITION, ///< a location was added, but nothing else changed
- REMOVAL, ///< a location was removed, but nothing else changed
- OTHER ///< something more complicated happened
- };
-
PBD::Signal1<void,Location*> current_changed;
- /** something changed about the location list; the parameter gives some idea as to what */
- PBD::Signal1<void,Change> changed;
- /** a location has been added to the end of the list */
- PBD::Signal1<void,Location*> added;
- PBD::Signal1<void,Location*> removed;
- PBD::Signal1<void,const PBD::PropertyChange&> StateChanged;
- template<class T> void apply (T& obj, void (T::*method)(LocationList&)) {
- Glib::Threads::Mutex::Lock lm (lock);
- (obj.*method)(locations);
- }
+ /* Objects that care about individual addition and removal of Locations should connect to added/removed.
+ If an object additionally cares about potential mass clearance of Locations, they should connect to changed.
+ */
- template<class T1, class T2> void apply (T1& obj, void (T1::*method)(LocationList&, T2& arg), T2& arg) {
- Glib::Threads::Mutex::Lock lm (lock);
- (obj.*method)(locations, arg);
+ PBD::Signal1<void,Location*> added;
+ PBD::Signal1<void,Location*> removed;
+ PBD::Signal0<void> changed; /* emitted when any action that could have added/removed more than 1 location actually removed 1 or more */
+
+ template<class T> void apply (T& obj, void (T::*method)(const LocationList&)) const {
+ /* We don't want to hold the lock while the given method runs, so take a copy
+ of the list and pass that instead.
+ */
+ Locations::LocationList copy;
+ {
+ Glib::Threads::Mutex::Lock lm (lock);
+ copy = locations;
+ }
+ (obj.*method)(copy);
}
private:
diff --git a/libs/ardour/ardour/midi_scene_changer.h b/libs/ardour/ardour/midi_scene_changer.h
index e2c62a2656..a87ea17da4 100644
--- a/libs/ardour/ardour/midi_scene_changer.h
+++ b/libs/ardour/ardour/midi_scene_changer.h
@@ -65,7 +65,7 @@ class MIDISceneChanger : public SceneChanger
void bank_change_input (MIDI::Parser&, unsigned short, int channel);
void program_change_input (MIDI::Parser&, MIDI::byte, int channel);
- void locations_changed (Locations::Change);
+ void locations_changed ();
PBD::ScopedConnectionList incoming_connections;
};
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 2c0ac05bda..61f57a6cc6 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1169,10 +1169,15 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void reset_rf_scale (framecnt_t frames_moved);
Locations* _locations;
- void locations_changed ();
- void locations_added (Location*);
- void handle_locations_changed (Locations::LocationList&);
- void sync_locations_to_skips (Locations::LocationList&);
+ void location_added (Location*);
+ void location_removed (Location*);
+ void locations_changed ();
+ void _locations_changed (const Locations::LocationList&);
+
+ void update_skips (Location*, bool consolidate);
+ Locations::LocationList consolidate_skips (Location*);
+ void sync_locations_to_skips (const Locations::LocationList&);
+ PBD::ScopedConnectionList skip_connections;
PBD::ScopedConnectionList punch_connections;
void auto_punch_start_changed (Location *);
@@ -1634,7 +1639,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
/** true if timecode transmission by the transport is suspended, otherwise false */
mutable gint _suspend_timecode_transmission;
- void update_locations_after_tempo_map_change (Locations::LocationList &);
+ void update_locations_after_tempo_map_change (const Locations::LocationList &);
void start_time_changed (framepos_t);
void end_time_changed (framepos_t);