Remove weird/pointless Automatable::data().
[ardour.git] / libs / ardour / ardour / session.h
index c9b2ba11a31bd7f9d2bcfe5fd877c35e00b5c516..de2dbaa14969240ae28b827472c3239d2c7dd538 100644 (file)
 #include "pbd/error.h"
 #include "pbd/rcu.h"
 #include "pbd/statefuldestructible.h"
+#include "pbd/signals.h"
 #include "pbd/undo.h"
 
 #include "midi++/mmc.h"
 #include "midi++/types.h"
 
-#include "pbd/destructible.h"
-#include "pbd/stateful.h"
-
 #include "ardour/ardour.h"
 #include "ardour/click.h"
 #include "ardour/chan_count.h"
@@ -66,6 +64,7 @@ namespace MIDI {
 
 namespace PBD {
        class Controllable;
+       class ControllableDescriptor;
 }
 
 namespace Evoral {
@@ -97,6 +96,7 @@ class MidiDiskstream;
 class MidiRegion;
 class MidiSource;
 class MidiTrack;
+class MidiControlUI;
 class NamedSelection;
 class Playlist;
 class PluginInsert;
@@ -119,14 +119,8 @@ class VSTPlugin;
 
 extern void setup_enum_writer ();
 
-class Session : public PBD::StatefulDestructible, public SessionEventManager, public boost::noncopyable
+class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
 {
-  private:
-       typedef std::pair<boost::weak_ptr<Route>,bool> RouteBooleanState;
-       typedef std::vector<RouteBooleanState> GlobalRouteBooleanState;
-       typedef std::pair<boost::weak_ptr<Route>,MeterPoint> RouteMeterState;
-       typedef std::vector<RouteMeterState> GlobalRouteMeterState;
-
   public:
        enum RecordState {
                Disabled = 0,
@@ -171,14 +165,14 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void set_deletion_in_progress ();
        void clear_deletion_in_progress ();
        bool deletion_in_progress() const { return _state_of_the_state & Deletion; }
-       sigc::signal<void> DirtyChanged;
+       PBD::Signal0<void> DirtyChanged;
 
        const SessionDirectory& session_directory () const { return *(_session_dir.get()); }
 
-       static sigc::signal<void> AutoBindingOn;
-       static sigc::signal<void> AutoBindingOff;
+       static PBD::Signal0<void> AutoBindingOn;
+       static PBD::Signal0<void> AutoBindingOff;
 
-       static sigc::signal<void,std::string> Dialog;
+       static PBD::Signal1<void,std::string> Dialog;
 
        std::string sound_dir (bool with_path = true) const;
        std::string peak_dir () const;
@@ -279,29 +273,31 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        /* Proxy signal for region hidden changes */
 
-       sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange;
+       PBD::Signal1<void,boost::shared_ptr<Region> > RegionHiddenChange;
 
        /* Emitted when all i/o connections are complete */
 
-       sigc::signal<void> IOConnectionsComplete;
+       PBD::Signal0<void> IOConnectionsComplete;
 
        /* Record status signals */
 
-       sigc::signal<void> RecordStateChanged;
+       PBD::Signal0<void> RecordStateChanged;
 
        /* Transport mechanism signals */
 
-       sigc::signal<void> TransportStateChange; /* generic */
-       sigc::signal<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
-       sigc::signal<void> DurationChanged;
-       sigc::signal<void,nframes64_t> Xrun;
-       sigc::signal<void> TransportLooped;
+       PBD::Signal0<void> TransportStateChange; /* generic */
+       PBD::Signal1<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
+       PBD::Signal0<void> DurationChanged;
+       PBD::Signal1<void,nframes64_t> Xrun;
+       PBD::Signal0<void> TransportLooped;
 
        /** emitted when a locate has occurred */
-       sigc::signal<void> Located;
+       PBD::Signal0<void> Located;
 
-       sigc::signal<void,RouteList&> RouteAdded;
-       sigc::signal<void> RouteGroupChanged;
+       PBD::Signal1<void,RouteList&> RouteAdded;
+       PBD::Signal0<void> RouteGroupChanged;
+
+       void queue_event (SessionEvent*);
 
        void request_roll_at_and_return (nframes_t start, nframes_t return_to);
        void request_bounded_roll (nframes_t start, nframes_t end);
@@ -353,9 +349,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        Locations *locations() { return &_locations; }
 
-       sigc::signal<void,Location*>    auto_loop_location_changed;
-       sigc::signal<void,Location*>    auto_punch_location_changed;
-       sigc::signal<void>              locations_modified;
+       PBD::Signal1<void,Location*>    auto_loop_location_changed;
+       PBD::Signal1<void,Location*>    auto_punch_location_changed;
+       PBD::Signal0<void>              locations_modified;
 
        void set_auto_punch_location (Location *);
        void set_auto_loop_location (Location *);
@@ -380,8 +376,8 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        static int rename_template (std::string old_name, std::string new_name);
        static int delete_template (std::string name);
 
-       sigc::signal<void,std::string> StateSaved;
-       sigc::signal<void> StateReady;
+       PBD::Signal1<void,std::string> StateSaved;
+       PBD::Signal0<void> StateReady;
 
        std::vector<std::string*>* possible_states() const;
        static std::vector<std::string*>* possible_states (std::string path);
@@ -411,12 +407,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        RouteGroup *route_group_by_name (std::string);
 
-       sigc::signal<void,RouteGroup*> route_group_added;
-       sigc::signal<void>             route_group_removed;
+       PBD::Signal1<void,RouteGroup*> route_group_added;
+       PBD::Signal0<void>             route_group_removed;
 
-       void foreach_route_group (sigc::slot<void,RouteGroup*> sl) {
+       void foreach_route_group (boost::function<void(RouteGroup*)> f) {
                for (std::list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); i++) {
-                       sl (*i);
+                       f (*i);
                }
        }
 
@@ -481,9 +477,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        nframes_t convert_to_frames_at (nframes_t position, AnyTime const &);
 
-       static sigc::signal<void> StartTimeChanged;
-       static sigc::signal<void> EndTimeChanged;
-       static sigc::signal<void> TimecodeOffsetChanged;
+       static PBD::Signal0<void> StartTimeChanged;
+       static PBD::Signal0<void> EndTimeChanged;
+       static PBD::Signal0<void> TimecodeOffsetChanged;
 
         std::vector<SyncSource> get_available_sync_options() const;
        void   request_sync_source (Slave*);
@@ -501,15 +497,15 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        TempoMap& tempo_map() { return *_tempo_map; }
 
        /// signals the current transport position in frames, bbt and timecode time (in that order)
-       sigc::signal<void, const nframes_t&, const BBT_Time&, const Timecode::Time&> tick;
+       PBD::Signal3<void,const nframes_t&, const BBT_Time&, const Timecode::Time&> tick;
 
        /* region info  */
 
        void add_regions (std::vector<boost::shared_ptr<Region> >&);
 
-       sigc::signal<void,boost::weak_ptr<Region> > RegionAdded;
-       sigc::signal<void,std::vector<boost::weak_ptr<Region> >& > RegionsAdded;
-       sigc::signal<void,boost::weak_ptr<Region> > RegionRemoved;
+       PBD::Signal1<void,boost::weak_ptr<Region> >              RegionAdded;
+       PBD::Signal1<void,std::vector<boost::weak_ptr<Region> >&> RegionsAdded;
+       PBD::Signal1<void,boost::weak_ptr<Region> >              RegionRemoved;
 
        int region_name (std::string& result, std::string base = std::string(""), bool newlevel = false);
        std::string new_region_name (std::string);
@@ -534,9 +530,8 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        int  start_audio_export (nframes_t position, bool realtime);
 
-       sigc::signal<int, nframes_t> ProcessExport;
-       sigc::signal<void> ExportReadFinished;
-       static sigc::signal<void, std::string, std::string> Exported;
+       PBD::Signal1<int,nframes_t> ProcessExport;
+       static PBD::Signal2<void,std::string, std::string> Exported;
 
        void add_source (boost::shared_ptr<Source>);
        void remove_source (boost::weak_ptr<Source>);
@@ -553,16 +548,16 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
            0 for "yes, delete this playlist",
            1 for "no, don't delete this playlist".
        */
-       sigc::signal<int,boost::shared_ptr<Playlist> > AskAboutPlaylistDeletion;
+       static PBD::Signal1<int,boost::shared_ptr<Playlist> >  AskAboutPlaylistDeletion;
 
        /** handlers should return 0 for "ignore the rate mismatch",
            !0 for "do not use this session"
        */
-       static sigc::signal<int,nframes_t, nframes_t> AskAboutSampleRateMismatch;
+       static PBD::Signal2<int,nframes_t, nframes_t> AskAboutSampleRateMismatch;
 
        /** handlers should return !0 for use pending state, 0 for ignore it.
        */
-       static sigc::signal<int> AskAboutPendingState;
+       static PBD::Signal0<int> AskAboutPendingState;
 
        boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
 
@@ -575,13 +570,13 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        /* named selections */
 
-       NamedSelection* named_selection_by_name (std::string name);
-       void add_named_selection (NamedSelection *);
-       void remove_named_selection (NamedSelection *);
+       boost::shared_ptr<NamedSelection> named_selection_by_name (std::string name);
+       void add_named_selection (boost::shared_ptr<NamedSelection>);
+       void remove_named_selection (boost::shared_ptr<NamedSelection>);
 
-       template<class T> void foreach_named_selection (T& obj, void (T::*func)(NamedSelection&));
-       sigc::signal<void> NamedSelectionAdded;
-       sigc::signal<void> NamedSelectionRemoved;
+       template<class T> void foreach_named_selection (T& obj, void (T::*func)(boost::shared_ptr<NamedSelection>));
+       PBD::Signal0<void> NamedSelectionAdded;
+       PBD::Signal0<void> NamedSelectionRemoved;
 
        /* Curves and AutomationLists (TODO when they go away) */
        void add_automation_list(AutomationList*);
@@ -600,7 +595,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void cancel_audition ();
        bool is_auditioning () const;
 
-       sigc::signal<void,bool> AuditionActive;
+       PBD::Signal1<void,bool> AuditionActive;
 
        /* flattening stuff */
 
@@ -614,15 +609,17 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        bool soloing() const { return _non_soloed_outs_muted; }
        bool listening() const { return _listen_cnt > 0; }
 
-       void set_all_solo (bool);
-       void set_all_mute (bool);
-       void set_all_listen (bool);
+       static const SessionEvent::RTeventCallback rt_cleanup;
 
-       sigc::signal<void,bool> SoloActive;
-       sigc::signal<void> SoloChanged;
+       void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+       void set_just_one_solo (boost::shared_ptr<Route>, bool, SessionEvent::RTeventCallback after = rt_cleanup);
+       void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+       void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+       void set_record_enable (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
 
-       void record_disenable_all ();
-       void record_enable_all ();
+       PBD::Signal1<void,bool> SoloActive;
+       PBD::Signal0<void> SoloChanged;
+       
 
        /* control/master out */
 
@@ -659,8 +656,8 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void remove_bundle (boost::shared_ptr<Bundle>);
        boost::shared_ptr<Bundle> bundle_by_name (std::string) const;
 
-       sigc::signal<void,boost::shared_ptr<Bundle> > BundleAdded;
-       sigc::signal<void,boost::shared_ptr<Bundle> > BundleRemoved;
+       PBD::Signal1<void,boost::shared_ptr<Bundle> > BundleAdded;
+       PBD::Signal1<void,boost::shared_ptr<Bundle> > BundleRemoved;
 
        /* MIDI control */
 
@@ -674,10 +671,10 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        MIDI::Port *midi_port() const { return _midi_port; }
        MIDI::Port *midi_clock_port() const { return _midi_clock_port; }
 
-       sigc::signal<void> MTC_PortChanged;
-       sigc::signal<void> MMC_PortChanged;
-       sigc::signal<void> MIDI_PortChanged;
-       sigc::signal<void> MIDIClock_PortChanged;
+       PBD::Signal0<void> MTC_PortChanged;
+       PBD::Signal0<void> MMC_PortChanged;
+       PBD::Signal0<void> MIDI_PortChanged;
+       PBD::Signal0<void> MIDIClock_PortChanged;
 
        void set_trace_midi_input (bool, MIDI::Port* port = 0);
        void set_trace_midi_output (bool, MIDI::Port* port = 0);
@@ -694,7 +691,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void stop_scrub ();
        void set_scrub_speed (float);
        nframes_t scrub_buffer_size() const;
-       sigc::signal<void> ScrubReady;
+       PBD::Signal0<void> ScrubReady;
 
        /* History (for editors, mixers, UIs etc.) */
 
@@ -719,83 +716,19 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void begin_reversible_command (const std::string& cmd_name);
        void commit_reversible_command (Command* cmd = 0);
 
+       UndoTransaction* start_reversible_command (const std::string& cmd_name);
+       void finish_reversible_command (UndoTransaction&);
+
        void add_command (Command *const cmd) {
                assert(!_current_trans.empty ());
                _current_trans.top()->add_command (cmd);
        }
 
-       std::map<PBD::ID, PBD::StatefulThingWithGoingAway*> registry;
+       std::map<PBD::ID,PBD::StatefulDestructible*> registry;
 
        // these commands are implemented in libs/ardour/session_command.cc
        Command* memento_command_factory(XMLNode* n);
-       void register_with_memento_command_factory(PBD::ID, PBD::StatefulThingWithGoingAway*);
-
-       Command* global_state_command_factory (const XMLNode& n);
-
-       class GlobalRouteStateCommand : public Command
-       {
-       public:
-               GlobalRouteStateCommand (Session&, void*);
-               GlobalRouteStateCommand (Session&, const XMLNode& node);
-               int set_state (const XMLNode&, int version);
-               XMLNode& get_state ();
-
-       protected:
-               GlobalRouteBooleanState before, after;
-               Session& sess;
-               void* src;
-       };
-
-       class GlobalSoloStateCommand : public GlobalRouteStateCommand
-       {
-       public:
-               GlobalSoloStateCommand (Session &, void *src);
-               GlobalSoloStateCommand (Session&, const XMLNode&);
-               void operator()(); //redo
-               void undo();
-               XMLNode &get_state();
-               void mark();
-       };
-
-       class GlobalMuteStateCommand : public GlobalRouteStateCommand
-       {
-       public:
-               GlobalMuteStateCommand(Session &, void *src);
-               GlobalMuteStateCommand (Session&, const XMLNode&);
-               void operator()(); // redo
-               void undo();
-               XMLNode &get_state();
-               void mark();
-       };
-
-       class GlobalRecordEnableStateCommand : public GlobalRouteStateCommand
-       {
-       public:
-               GlobalRecordEnableStateCommand(Session &, void *src);
-               GlobalRecordEnableStateCommand (Session&, const XMLNode&);
-               void operator()(); // redo
-               void undo();
-               XMLNode &get_state();
-               void mark();
-       };
-
-       class GlobalMeteringStateCommand : public Command
-       {
-       public:
-               GlobalMeteringStateCommand(Session &, void *src);
-               GlobalMeteringStateCommand (Session&, const XMLNode&);
-               void operator()();
-               void undo();
-               XMLNode &get_state();
-               int set_state (const XMLNode&, int version);
-               void mark();
-
-       protected:
-               Session& sess;
-               void* src;
-               GlobalRouteMeterState before;
-               GlobalRouteMeterState after;
-       };
+       void register_with_memento_command_factory(PBD::ID, PBD::StatefulDestructible*);
 
        /* clicking */
 
@@ -832,11 +765,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
                        void* ptr,
                        float opt);
 
-       static sigc::signal<void> SendFeedback;
+       static PBD::Signal0<void> SendFeedback;
 
        /* Controllables */
 
        boost::shared_ptr<PBD::Controllable> controllable_by_id (const PBD::ID&);
+       boost::shared_ptr<PBD::Controllable> controllable_by_descriptor (const PBD::ControllableDescriptor&);
 
        void add_controllable (boost::shared_ptr<PBD::Controllable>);
        void remove_controllable (PBD::Controllable*);
@@ -1001,7 +935,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        nframes_t post_export_position;
 
        bool _exporting;
-       bool _exporting_realtime;
+       bool _export_rolling;
 
        boost::shared_ptr<ExportHandler> export_handler;
        boost::shared_ptr<ExportStatus>  export_status;
@@ -1010,7 +944,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        int  stop_audio_export ();
        void finalize_audio_export ();
 
-       sigc::connection export_freewheel_connection;
+       PBD::ScopedConnection export_freewheel_connection;
 
        void prepare_diskstreams ();
        void commit_diskstreams (nframes_t, bool& session_requires_butler);
@@ -1134,16 +1068,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void              locations_added (Location*);
        void              handle_locations_changed (Locations::LocationList&);
 
-       sigc::connection auto_punch_start_changed_connection;
-       sigc::connection auto_punch_end_changed_connection;
-       sigc::connection auto_punch_changed_connection;
+       PBD::ScopedConnectionList punch_connections;
        void             auto_punch_start_changed (Location *);
        void             auto_punch_end_changed (Location *);
        void             auto_punch_changed (Location *);
 
-       sigc::connection auto_loop_start_changed_connection;
-       sigc::connection auto_loop_end_changed_connection;
-       sigc::connection auto_loop_changed_connection;
+       PBD::ScopedConnectionList loop_connections;
        void             auto_loop_changed (Location *);
 
        void first_stage_init (std::string path, std::string snapshot_name);
@@ -1179,7 +1109,6 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        /* SessionEventManager interface */
 
-       void queue_event (SessionEvent*);
        void process_event (SessionEvent*);
        void set_next_event ();
        void cleanup_event (SessionEvent*,int);
@@ -1209,7 +1138,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        struct timeval last_mmc_step;
        double step_speed;
 
-       typedef sigc::slot<bool> MidiTimeoutCallback;
+       typedef boost::function<bool()> MidiTimeoutCallback;
        typedef std::list<MidiTimeoutCallback> MidiTimeoutList;
 
        MidiTimeoutList midi_timeouts;
@@ -1250,25 +1179,11 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        bool non_realtime_work_pending() const { return static_cast<bool>(post_transport_work()); }
        bool process_can_proceed() const { return !(post_transport_work() & ProcessCannotProceedMask); }
 
-       struct MIDIRequest {
-               enum Type {
-                       PortChange,
-                       Quit
-               };
-               Type type;
-       };
-
-       Glib::Mutex  midi_lock;
-       pthread_t    midi_thread;
-       int          midi_request_pipe[2];
-       RingBuffer<MIDIRequest*> midi_requests;
+       MidiControlUI* midi_control_ui;
 
        int           start_midi_thread ();
        void          terminate_midi_thread ();
-       void          poke_midi_thread ();
-       static void *_midi_thread_work (void *arg);
-       void          midi_thread_work ();
-       void          change_midi_ports ();
+
        int           use_config_midi_ports ();
 
        void set_play_loop (bool yn);
@@ -1373,7 +1288,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        /* NAMED SELECTIONS */
 
        mutable Glib::Mutex named_selection_lock;
-       typedef std::set<NamedSelection *> NamedSelectionList;
+       typedef std::set<boost::shared_ptr<NamedSelection> > NamedSelectionList;
        NamedSelectionList named_selections;
 
        int load_named_selections (const XMLNode&);
@@ -1453,21 +1368,10 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        UndoHistory                  _history;
        std::stack<UndoTransaction*> _current_trans;
 
-       GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
-       GlobalRouteMeterState get_global_route_metering ();
-
-       void set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void *arg);
-       void set_global_route_metering (GlobalRouteMeterState s, void *arg);
-
-       void set_global_mute (GlobalRouteBooleanState s, void *src);
-       void set_global_solo (GlobalRouteBooleanState s, void *src);
-       void set_global_record_enable (GlobalRouteBooleanState s, void *src);
-
        void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int);
        int  jack_sync_callback (jack_transport_state_t, jack_position_t*);
        void reset_jack_connection (jack_client_t* jack);
-       void record_enable_change_all (bool yn);
-       void do_record_enable_change_all (RouteList*, bool);
+       void process_rtop (SessionEvent*);
 
        XMLNode& state(bool);
 
@@ -1560,6 +1464,18 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        void update_have_rec_enabled_diskstream ();
        gint _have_rec_enabled_diskstream;
+
+       static int ask_about_playlist_deletion (boost::shared_ptr<Playlist>);
+
+       /* realtime "apply to set of routes" operations */
+       SessionEvent* get_rt_event (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override, 
+               void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool));
+
+       void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
+       void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_set_record_enable (boost::shared_ptr<RouteList>, bool yn, bool group_override);
 };
 
 } // namespace ARDOUR