mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-12 01:26:31 +01:00
next iteration of changes to handle time domain bounces as undoable
This commit is contained in:
parent
5e3cdf285e
commit
076cb86912
28 changed files with 286 additions and 235 deletions
|
|
@ -161,12 +161,12 @@ class LIBARDOUR_API AudioRegion : public Region, public AudioReadable
|
||||||
/* automation */
|
/* automation */
|
||||||
|
|
||||||
std::shared_ptr<Evoral::Control>
|
std::shared_ptr<Evoral::Control>
|
||||||
control(const Evoral::Parameter& id, bool create=false) {
|
control(const Evoral::Parameter& id, bool create=false) {
|
||||||
return _automatable.control(id, create);
|
return _automatable.control(id, create);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::shared_ptr<const Evoral::Control>
|
virtual std::shared_ptr<const Evoral::Control>
|
||||||
control(const Evoral::Parameter& id) const {
|
control(const Evoral::Parameter& id) const {
|
||||||
return _automatable.control(id);
|
return _automatable.control(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "evoral/ControlSet.h"
|
#include "evoral/ControlSet.h"
|
||||||
|
|
||||||
|
#include "temporal/domain_swap.h"
|
||||||
#include "temporal/domain_provider.h"
|
#include "temporal/domain_provider.h"
|
||||||
|
|
||||||
#include "ardour/libardour_visibility.h"
|
#include "ardour/libardour_visibility.h"
|
||||||
|
|
@ -50,7 +51,7 @@ class AutomationControl;
|
||||||
/* The inherited ControlSet is virtual because AutomatableSequence inherits
|
/* The inherited ControlSet is virtual because AutomatableSequence inherits
|
||||||
* from this AND EvoralSequence, which is also a ControlSet
|
* from this AND EvoralSequence, which is also a ControlSet
|
||||||
*/
|
*/
|
||||||
class LIBARDOUR_API Automatable : virtual public Evoral::ControlSet, public Slavable, public Temporal::TimeDomainProvider
|
class LIBARDOUR_API Automatable : virtual public Evoral::ControlSet, public Slavable, public Temporal::TimeDomainProvider, public Temporal::TimeDomainSwapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Automatable(Session&, Temporal::TimeDomainProvider const &);
|
Automatable(Session&, Temporal::TimeDomainProvider const &);
|
||||||
|
|
@ -119,6 +120,9 @@ public:
|
||||||
|
|
||||||
PBD::Signal0<void> AutomationStateChanged;
|
PBD::Signal0<void> AutomationStateChanged;
|
||||||
|
|
||||||
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Session& _a_session;
|
Session& _a_session;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@
|
||||||
#include "pbd/stateful.h"
|
#include "pbd/stateful.h"
|
||||||
#include "pbd/statefuldestructible.h"
|
#include "pbd/statefuldestructible.h"
|
||||||
|
|
||||||
|
#include "temporal/domain_provider.h"
|
||||||
|
#include "temporal/domain_swap.h"
|
||||||
#include "temporal/types.h"
|
#include "temporal/types.h"
|
||||||
|
|
||||||
#include "ardour/ardour.h"
|
#include "ardour/ardour.h"
|
||||||
|
|
@ -173,8 +175,12 @@ public:
|
||||||
|
|
||||||
Temporal::TimeDomain position_time_domain() const { return _start.time_domain(); }
|
Temporal::TimeDomain position_time_domain() const { return _start.time_domain(); }
|
||||||
|
|
||||||
void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
/* Similar to, but not identical to the Temporal::TimeDomainSwapper API */
|
||||||
void change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
|
||||||
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
|
void set_time_domain (Temporal::TimeDomain);
|
||||||
|
|
||||||
class ChangeSuspender {
|
class ChangeSuspender {
|
||||||
public:
|
public:
|
||||||
|
|
@ -209,7 +215,7 @@ private:
|
||||||
Lock,
|
Lock,
|
||||||
Cue,
|
Cue,
|
||||||
Scene,
|
Scene,
|
||||||
Domain
|
Domain,
|
||||||
};
|
};
|
||||||
|
|
||||||
void emit_signal (Signal);
|
void emit_signal (Signal);
|
||||||
|
|
@ -233,7 +239,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A collection of session locations including unique dedicated locations (loop, punch, etc) */
|
/** A collection of session locations including unique dedicated locations (loop, punch, etc) */
|
||||||
class LIBARDOUR_API Locations : public SessionHandleRef, public PBD::StatefulDestructible
|
class LIBARDOUR_API Locations : public SessionHandleRef, public PBD::StatefulDestructible, public Temporal::TimeDomainProvider, public Temporal::TimeDomainSwapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::list<Location *> LocationList;
|
typedef std::list<Location *> LocationList;
|
||||||
|
|
@ -303,8 +309,11 @@ public:
|
||||||
|
|
||||||
void find_all_between (timepos_t const & start, timepos_t const & end, LocationList&, Location::Flags);
|
void find_all_between (timepos_t const & start, timepos_t const & end, LocationList&, Location::Flags);
|
||||||
|
|
||||||
void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
void set_time_domain (Temporal::TimeDomain);
|
||||||
void change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
|
void time_domain_changed ();
|
||||||
|
|
||||||
PBD::Signal1<void,Location*> current_changed;
|
PBD::Signal1<void,Location*> current_changed;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "temporal/beats.h"
|
#include "temporal/beats.h"
|
||||||
#include "temporal/domainswap.h"
|
|
||||||
#include "temporal/range.h"
|
#include "temporal/range.h"
|
||||||
|
|
||||||
#include "pbd/string_convert.h"
|
#include "pbd/string_convert.h"
|
||||||
|
|
@ -55,7 +54,7 @@ class ThawList;
|
||||||
|
|
||||||
template<typename T> class MidiRingBuffer;
|
template<typename T> class MidiRingBuffer;
|
||||||
|
|
||||||
class LIBARDOUR_API MidiRegion : public Region, public Temporal::TimeDomainSwapper
|
class LIBARDOUR_API MidiRegion : public Region
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~MidiRegion();
|
~MidiRegion();
|
||||||
|
|
@ -117,8 +116,8 @@ class LIBARDOUR_API MidiRegion : public Region, public Temporal::TimeDomainSwapp
|
||||||
timecnt_t const & read_length,
|
timecnt_t const & read_length,
|
||||||
MidiChannelFilter* filter) const;
|
MidiChannelFilter* filter) const;
|
||||||
|
|
||||||
void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
void swap_domain (Temporal::TimeDomain, Temporal::TimeDomain);
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@ public:
|
||||||
|
|
||||||
bool has_state() const { return _has_state; }
|
bool has_state() const { return _has_state; }
|
||||||
|
|
||||||
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual XMLNode& state () const;
|
virtual XMLNode& state () const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,8 @@ public:
|
||||||
void set_capture_insertion_in_progress (bool yn);
|
void set_capture_insertion_in_progress (bool yn);
|
||||||
|
|
||||||
void time_domain_changed ();
|
void time_domain_changed ();
|
||||||
void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Session;
|
friend class Session;
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
|
#include "temporal/domain_swap.h"
|
||||||
#include "temporal/timeline.h"
|
#include "temporal/timeline.h"
|
||||||
#include "temporal/range.h"
|
#include "temporal/range.h"
|
||||||
|
|
||||||
|
|
@ -96,6 +97,7 @@ class LIBARDOUR_API Region
|
||||||
, public std::enable_shared_from_this<Region>
|
, public std::enable_shared_from_this<Region>
|
||||||
, public Trimmable
|
, public Trimmable
|
||||||
, public Movable
|
, public Movable
|
||||||
|
, public Temporal::TimeDomainSwapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<std::shared_ptr<Source> > SourceList;
|
typedef std::vector<std::shared_ptr<Source> > SourceList;
|
||||||
|
|
@ -115,8 +117,8 @@ public:
|
||||||
|
|
||||||
const DataType& data_type () const { return _type; }
|
const DataType& data_type () const { return _type; }
|
||||||
Temporal::TimeDomain time_domain() const;
|
Temporal::TimeDomain time_domain() const;
|
||||||
virtual void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
virtual void change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
/** How the region parameters play together:
|
/** How the region parameters play together:
|
||||||
*
|
*
|
||||||
|
|
@ -386,7 +388,7 @@ public:
|
||||||
/* automation */
|
/* automation */
|
||||||
|
|
||||||
virtual std::shared_ptr<Evoral::Control>
|
virtual std::shared_ptr<Evoral::Control>
|
||||||
control (const Evoral::Parameter& id, bool create=false) = 0;
|
control (const Evoral::Parameter& id, bool create=false) = 0;
|
||||||
|
|
||||||
virtual std::shared_ptr<const Evoral::Control>
|
virtual std::shared_ptr<const Evoral::Control>
|
||||||
control (const Evoral::Parameter& id) const = 0;
|
control (const Evoral::Parameter& id) const = 0;
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
#include "pbd/controllable.h"
|
#include "pbd/controllable.h"
|
||||||
#include "pbd/destructible.h"
|
#include "pbd/destructible.h"
|
||||||
|
|
||||||
|
#include "temporal/domain_swap.h"
|
||||||
#include "temporal/types.h"
|
#include "temporal/types.h"
|
||||||
|
|
||||||
#include "ardour/ardour.h"
|
#include "ardour/ardour.h"
|
||||||
|
|
@ -612,7 +613,6 @@ public:
|
||||||
|
|
||||||
virtual void use_captured_sources (SourceList& srcs, CaptureInfos const &) {}
|
virtual void use_captured_sources (SourceList& srcs, CaptureInfos const &) {}
|
||||||
|
|
||||||
void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Session;
|
friend class Session;
|
||||||
|
|
|
||||||
|
|
@ -1387,7 +1387,8 @@ public:
|
||||||
bool bang_trigger_at(int32_t route_index, int32_t row_index);
|
bool bang_trigger_at(int32_t route_index, int32_t row_index);
|
||||||
bool unbang_trigger_at(int32_t route_index, int32_t row_index);
|
bool unbang_trigger_at(int32_t route_index, int32_t row_index);
|
||||||
|
|
||||||
PBD::Command* globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class AudioEngine;
|
friend class AudioEngine;
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,8 @@ public:
|
||||||
std::vector<std::shared_ptr<Playlist> > get_unused () const;
|
std::vector<std::shared_ptr<Playlist> > get_unused () const;
|
||||||
uint32_t n_playlists() const;
|
uint32_t n_playlists() const;
|
||||||
|
|
||||||
void globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to);
|
void start_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
void finish_domain_bounce (Temporal::DomainBounceInfo&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Session;
|
friend class Session;
|
||||||
|
|
|
||||||
|
|
@ -743,3 +743,13 @@ Automatable::find_prev_ac_event (std::shared_ptr<AutomationControl> c, timepos_t
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Automatable::start_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Automatable::finish_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,22 +92,8 @@ Location::Location (Session& s, timepos_t const & start, timepos_t const & end,
|
||||||
set_position_time_domain (_session.time_domain());
|
set_position_time_domain (_session.time_domain());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Location::set_position_time_domain (TimeDomain domain)
|
|
||||||
{
|
|
||||||
if (_start.time_domain() == domain) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_start.set_time_domain (domain);
|
|
||||||
_end.set_time_domain (domain);
|
|
||||||
|
|
||||||
emit_signal (Domain); /* EMIT SIGNAL */
|
|
||||||
}
|
|
||||||
|
|
||||||
Location::Location (const Location& other)
|
Location::Location (const Location& other)
|
||||||
: SessionHandleRef (other._session)
|
: SessionHandleRef (other._session)
|
||||||
, StatefulDestructible()
|
|
||||||
, _name (other._name)
|
, _name (other._name)
|
||||||
, _start (other._start)
|
, _start (other._start)
|
||||||
, _end (other._end)
|
, _end (other._end)
|
||||||
|
|
@ -253,6 +239,26 @@ Location::actually_emit_signal (Signal s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Location::set_position_time_domain (TimeDomain domain)
|
||||||
|
{
|
||||||
|
if (_start.time_domain() == domain) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_start.set_time_domain (domain);
|
||||||
|
_end.set_time_domain (domain);
|
||||||
|
|
||||||
|
// emit_signal (Domain); /* EMIT SIGNAL */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Location::set_time_domain (TimeDomain domain)
|
||||||
|
{
|
||||||
|
set_position_time_domain (domain);
|
||||||
|
}
|
||||||
|
|
||||||
/** Set location name */
|
/** Set location name */
|
||||||
void
|
void
|
||||||
Location::set_name (const std::string& str)
|
Location::set_name (const std::string& str)
|
||||||
|
|
@ -777,32 +783,53 @@ Location::set_scene_change (std::shared_ptr<SceneChange> sc)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Location::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
Location::start_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
assert (domain_swap);
|
if (_start.time_domain() == cmd.to) {
|
||||||
|
/* has the right domain to begin with */
|
||||||
if (_start.time_domain() == from) {
|
return;
|
||||||
|
|
||||||
_start.set_time_domain (to);
|
|
||||||
_end.set_time_domain (to);
|
|
||||||
|
|
||||||
domain_swap->add (_start);
|
|
||||||
domain_swap->add (_end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timepos_t s (_start);
|
||||||
|
timepos_t e (_end);
|
||||||
|
|
||||||
|
s.set_time_domain (cmd.to);
|
||||||
|
e.set_time_domain (cmd.to);
|
||||||
|
|
||||||
|
cmd.positions.insert (std::make_pair (&_start, s));
|
||||||
|
cmd.positions.insert (std::make_pair (&_end, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Location::change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
Location::finish_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
if (_start.time_domain() == from) {
|
if (_start.time_domain() == cmd.to) {
|
||||||
set_position_time_domain (to);
|
/* had the right domain to begin with */
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimeDomainPosChanges::iterator tpc;
|
||||||
|
timepos_t s;
|
||||||
|
timepos_t e;
|
||||||
|
|
||||||
|
tpc = cmd.positions.find (&_start);
|
||||||
|
assert (tpc != cmd.positions.end());
|
||||||
|
s = tpc->second;
|
||||||
|
s.set_time_domain (cmd.from);
|
||||||
|
|
||||||
|
tpc = cmd.positions.find (&_end);
|
||||||
|
assert (tpc != cmd.positions.end());
|
||||||
|
e = tpc->second;
|
||||||
|
e.set_time_domain (cmd.from);
|
||||||
|
|
||||||
|
set (s, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------- */
|
/*---------------------------------------------------------------------- */
|
||||||
|
|
||||||
Locations::Locations (Session& s)
|
Locations::Locations (Session& s)
|
||||||
: SessionHandleRef (s)
|
: SessionHandleRef (s)
|
||||||
|
, Temporal::TimeDomainProvider (s, false) /* session is our parent */
|
||||||
{
|
{
|
||||||
current_location = 0;
|
current_location = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1890,21 +1917,28 @@ Locations::clear_cue_markers (samplepos_t start, samplepos_t end)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Locations::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
Locations::start_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
Glib::Threads::RWLock::WriterLock lm (_lock);
|
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||||
for (auto & l : locations) {
|
|
||||||
l->globally_change_time_domain (from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (auto & l : locations) {
|
||||||
|
l->start_domain_bounce (cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Locations::change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
Locations::finish_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
|
{
|
||||||
|
for (auto & l : locations) {
|
||||||
|
l->finish_domain_bounce (cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Locations::time_domain_changed ()
|
||||||
{
|
{
|
||||||
Glib::Threads::RWLock::WriterLock lm (_lock);
|
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||||
for (auto & l : locations) {
|
for (auto & l : locations) {
|
||||||
l->change_time_domain (from, to);
|
l->set_time_domain (time_domain());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1793,18 +1793,17 @@ MidiModel::create_mapping_stash (Temporal::Beats const & src_pos_offset)
|
||||||
Event<Beats>& off (n->off_event());
|
Event<Beats>& off (n->off_event());
|
||||||
audio_time = tmap->superclock_at (src_pos_offset + off.time());
|
audio_time = tmap->superclock_at (src_pos_offset + off.time());
|
||||||
tempo_mapping_stash.insert (std::make_pair (&off, audio_time));
|
tempo_mapping_stash.insert (std::make_pair (&off, audio_time));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const & s : sysexes()) {
|
for (auto const & s : sysexes()) {
|
||||||
superclock_t audio_time = tmap->superclock_at (src_pos_offset + s->time());
|
superclock_t audio_time = tmap->superclock_at (src_pos_offset + s->time());
|
||||||
tempo_mapping_stash.insert (std::make_pair ((void*)s.get(), audio_time));
|
tempo_mapping_stash.insert (std::make_pair (s.get(), audio_time));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t chan = 0; chan < 16; ++chan) {
|
for (uint8_t chan = 0; chan < 16; ++chan) {
|
||||||
for (auto const & p : pitches(chan)) {
|
for (auto const & p : pitches(chan)) {
|
||||||
superclock_t audio_time = tmap->superclock_at (src_pos_offset + p->time());
|
superclock_t audio_time = tmap->superclock_at (src_pos_offset + p->time());
|
||||||
tempo_mapping_stash.insert (std::make_pair ((void*) &p, audio_time));
|
tempo_mapping_stash.insert (std::make_pair (p.get(), audio_time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1827,6 +1826,7 @@ MidiModel::rebuild_from_mapping_stash (Temporal::Beats const & src_pos_offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
TempoMap::SharedPtr tmap (TempoMap::use());
|
TempoMap::SharedPtr tmap (TempoMap::use());
|
||||||
|
NoteDiffCommand* note_cmd = new_note_diff_command (_("conform to tempo map"));
|
||||||
|
|
||||||
for (auto & n : notes()) {
|
for (auto & n : notes()) {
|
||||||
|
|
||||||
|
|
@ -1836,17 +1836,21 @@ MidiModel::rebuild_from_mapping_stash (Temporal::Beats const & src_pos_offset)
|
||||||
TempoMappingStash::iterator tms (tempo_mapping_stash.find (&on));
|
TempoMappingStash::iterator tms (tempo_mapping_stash.find (&on));
|
||||||
assert (tms != tempo_mapping_stash.end());
|
assert (tms != tempo_mapping_stash.end());
|
||||||
Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset);
|
Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset);
|
||||||
on.set_time (beat_time);
|
|
||||||
|
note_cmd->change (n, NoteDiffCommand::StartTime, beat_time);
|
||||||
|
|
||||||
tms = tempo_mapping_stash.find (&off);
|
tms = tempo_mapping_stash.find (&off);
|
||||||
assert (tms != tempo_mapping_stash.end());
|
assert (tms != tempo_mapping_stash.end());
|
||||||
beat_time = tmap->quarters_at_superclock (tms->second) - src_pos_offset;
|
beat_time = tmap->quarters_at_superclock (tms->second) - src_pos_offset;
|
||||||
off.set_time (beat_time);
|
off.set_time (beat_time);
|
||||||
|
|
||||||
|
note_cmd->change (n, NoteDiffCommand::Length, beat_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply_diff_command_as_subcommand (_midi_source.session(), note_cmd);
|
||||||
|
|
||||||
for (auto & s : sysexes()) {
|
for (auto & s : sysexes()) {
|
||||||
TempoMappingStash::iterator tms (tempo_mapping_stash.find ((void*) &s));
|
TempoMappingStash::iterator tms (tempo_mapping_stash.find (s.get()));
|
||||||
assert (tms != tempo_mapping_stash.end());
|
assert (tms != tempo_mapping_stash.end());
|
||||||
Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset);
|
Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset);
|
||||||
s->set_time (beat_time);
|
s->set_time (beat_time);
|
||||||
|
|
@ -1854,7 +1858,7 @@ MidiModel::rebuild_from_mapping_stash (Temporal::Beats const & src_pos_offset)
|
||||||
|
|
||||||
for (uint8_t chan = 0; chan < 16; ++chan) {
|
for (uint8_t chan = 0; chan < 16; ++chan) {
|
||||||
for (auto & p : pitches(chan)) {
|
for (auto & p : pitches(chan)) {
|
||||||
TempoMappingStash::iterator tms (tempo_mapping_stash.find ((void*) &p));
|
TempoMappingStash::iterator tms (tempo_mapping_stash.find (p.get()));
|
||||||
assert (tms != tempo_mapping_stash.end());
|
assert (tms != tempo_mapping_stash.end());
|
||||||
Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset);
|
Beats beat_time (tmap->quarters_at_superclock (tms->second) - src_pos_offset);
|
||||||
p->set_time (beat_time);
|
p->set_time (beat_time);
|
||||||
|
|
|
||||||
|
|
@ -614,23 +614,24 @@ MidiRegion::merge (std::shared_ptr<MidiRegion const> other_region)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiRegion::swap_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
MidiRegion::start_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
if (from == Temporal::BeatTime) {
|
/* Deal with the region position & length */
|
||||||
model()->create_mapping_stash (source_position().beats());
|
|
||||||
} else {
|
|
||||||
model()->rebuild_from_mapping_stash (source_position().beats());
|
|
||||||
|
|
||||||
_model_changed_connection.disconnect ();
|
Region::start_domain_bounce (cmd);
|
||||||
model()->ContentsChanged ();
|
if (cmd.from == Temporal::BeatTime) {
|
||||||
model()->ContentsChanged.connect_same_thread (_model_changed_connection, boost::bind (&MidiRegion::model_contents_changed, this));
|
model()->create_mapping_stash (source_position().beats());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiRegion::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
MidiRegion::finish_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
Region::globally_change_time_domain (from, to);
|
Region::finish_domain_bounce (cmd);
|
||||||
swap_domain (from, to);
|
|
||||||
Temporal::domain_swap->add (*this);
|
model()->rebuild_from_mapping_stash (source_position().beats());
|
||||||
|
|
||||||
|
_model_changed_connection.disconnect ();
|
||||||
|
model()->ContentsChanged ();
|
||||||
|
model()->ContentsChanged.connect_same_thread (_model_changed_connection, boost::bind (&MidiRegion::model_contents_changed, this));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -266,3 +266,14 @@ Pannable::set_state (const XMLNode& root, int version)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Pannable::start_domain_bounce (Temporal::DomainBounceInfo&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Pannable::finish_domain_bounce (Temporal::DomainBounceInfo&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3530,17 +3530,38 @@ Playlist::rdiff_and_add_command (Session* session)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Playlist::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
Playlist::start_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
RegionReadLock rlock (this);
|
RegionReadLock rlock (this);
|
||||||
for (auto & region : regions) {
|
for (auto & region : regions) {
|
||||||
region->globally_change_time_domain (from, to);
|
region->start_domain_bounce (cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Playlist::finish_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
|
{
|
||||||
|
ThawList thawlist;
|
||||||
|
|
||||||
|
clear_changes ();
|
||||||
|
|
||||||
|
{
|
||||||
|
RegionWriteLock rlock (this);
|
||||||
|
for (auto & region : regions) {
|
||||||
|
thawlist.add (region);
|
||||||
|
region->finish_domain_bounce (cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thawlist.release ();
|
||||||
|
rdiff_and_add_command (&_session);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Playlist::time_domain_changed ()
|
Playlist::time_domain_changed ()
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
using namespace Temporal;
|
using namespace Temporal;
|
||||||
|
|
||||||
TimeDomainProvider::time_domain_changed ();
|
TimeDomainProvider::time_domain_changed ();
|
||||||
|
|
@ -3549,8 +3570,8 @@ Playlist::time_domain_changed ()
|
||||||
Temporal::TimeDomain from = (to == AudioTime ? BeatTime : AudioTime);
|
Temporal::TimeDomain from = (to == AudioTime ? BeatTime : AudioTime);
|
||||||
|
|
||||||
for (auto & region : regions) {
|
for (auto & region : regions) {
|
||||||
region->change_time_domain (from, to);
|
region->swap_time_domain (from, to);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2270,27 +2270,39 @@ Region::time_domain() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Region::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
Region::start_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
assert (Temporal::domain_swap);
|
if (locked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* recall that the _length member is a timecnt_t, and so holds both
|
/* recall that the _length member is a timecnt_t, and so holds both
|
||||||
* position *and* length.
|
* position *and* length.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (_length.val().time_domain() == from) {
|
if (_length.val().time_domain() != cmd.from) {
|
||||||
timecnt_t& l (_length.non_const_val());
|
return;
|
||||||
l.set_time_domain (to);
|
|
||||||
Temporal::domain_swap->add (l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timecnt_t& l (_length.non_const_val());
|
||||||
|
|
||||||
|
timecnt_t saved (l);
|
||||||
|
saved.set_time_domain (cmd.to);
|
||||||
|
|
||||||
|
cmd.counts.insert (std::make_pair (&l, saved));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Region::change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
Region::finish_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
std::cerr << name() << " change td to " << to << std::endl;
|
clear_changes ();
|
||||||
if (_length.val().time_domain() == from) {
|
|
||||||
timecnt_t& l (_length.non_const_val());
|
Temporal::TimeDomainCntChanges::iterator tc = cmd.counts.find (&_length.non_const_val());
|
||||||
l.set_time_domain (to);
|
assert (tc != cmd.counts.end());
|
||||||
}
|
|
||||||
|
/* switch domains back (but with modified TempoMap, presumably */
|
||||||
|
tc->second.set_time_domain (cmd.from);
|
||||||
|
_length = tc->second;
|
||||||
|
|
||||||
|
send_change (Properties::length);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6349,8 +6349,3 @@ Route::tempo_map_changed ()
|
||||||
_triggerbox->tempo_map_changed ();
|
_triggerbox->tempo_map_changed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Route::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7787,15 +7787,3 @@ Session::foreach_route (void (Route::*method)())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Session::time_domain_changed ()
|
|
||||||
{
|
|
||||||
using namespace Temporal;
|
|
||||||
|
|
||||||
TimeDomainProvider::time_domain_changed ();
|
|
||||||
|
|
||||||
Temporal::TimeDomain to = time_domain();
|
|
||||||
Temporal::TimeDomain from = (to == AudioTime ? BeatTime : AudioTime);
|
|
||||||
|
|
||||||
_locations->change_time_domain (from, to);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -689,11 +689,31 @@ SessionPlaylists::foreach (boost::function<void(std::shared_ptr<const Playlist>)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SessionPlaylists::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
SessionPlaylists::start_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
Glib::Threads::Mutex::Lock lm (lock);
|
Glib::Threads::Mutex::Lock lm (lock);
|
||||||
|
|
||||||
for (auto & pl : playlists) {
|
for (auto & pl : playlists) {
|
||||||
pl->globally_change_time_domain (from, to);
|
pl->start_domain_bounce (cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SessionPlaylists::finish_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
|
{
|
||||||
|
/* We cannot hold the playlist lock while finishing a domain bounce
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Playlist> > copy;
|
||||||
|
|
||||||
|
{
|
||||||
|
Glib::Threads::Mutex::Lock lm (lock);
|
||||||
|
for (auto & pl : playlists) {
|
||||||
|
copy.push_back (pl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & pl : copy) {
|
||||||
|
pl->finish_domain_bounce (cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3346,6 +3346,7 @@ Session::add_stateful_diff_command (std::shared_ptr<PBD::StatefulDestructible> s
|
||||||
void
|
void
|
||||||
Session::begin_reversible_command (const string& name)
|
Session::begin_reversible_command (const string& name)
|
||||||
{
|
{
|
||||||
|
std::cerr << "begin REV-C [" << name << "]\n";
|
||||||
begin_reversible_command (g_quark_from_string (name.c_str ()));
|
begin_reversible_command (g_quark_from_string (name.c_str ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3395,6 +3396,7 @@ Session::abort_reversible_command ()
|
||||||
if (_current_trans != 0) {
|
if (_current_trans != 0) {
|
||||||
DEBUG_UNDO_HISTORY (
|
DEBUG_UNDO_HISTORY (
|
||||||
string_compose ("Abort Reversible Command: %1", _current_trans->name ()));
|
string_compose ("Abort Reversible Command: %1", _current_trans->name ()));
|
||||||
|
std::cerr << "abort REV-C [" << _current_trans->name() << "]\n";
|
||||||
_current_trans->clear();
|
_current_trans->clear();
|
||||||
delete _current_trans;
|
delete _current_trans;
|
||||||
_current_trans = 0;
|
_current_trans = 0;
|
||||||
|
|
@ -3421,6 +3423,7 @@ Session::commit_reversible_command (Command *cmd)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cerr << "commit REV-C [" << _current_trans->name() << "]\n";
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
|
|
@ -3460,6 +3463,8 @@ Session::commit_reversible_command (Command *cmd)
|
||||||
gettimeofday (&now, 0);
|
gettimeofday (&now, 0);
|
||||||
_current_trans->set_timestamp (now);
|
_current_trans->set_timestamp (now);
|
||||||
|
|
||||||
|
std::cerr << "Add command with " << _current_trans->size() << std::endl;
|
||||||
|
|
||||||
_history.add (_current_trans);
|
_history.add (_current_trans);
|
||||||
_current_trans = 0;
|
_current_trans = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -299,21 +299,42 @@ Session::any_duration_to_samples (samplepos_t position, AnyTime const & duration
|
||||||
return duration.samples;
|
return duration.samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
PBD::Command*
|
void
|
||||||
Session::globally_change_time_domain (Temporal::TimeDomain from, Temporal::TimeDomain to)
|
Session::start_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
{
|
{
|
||||||
PBD::Command* undo_command = new Temporal::TimeDomainCommand (from, to);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<RouteList const> rl (routes.reader());
|
std::shared_ptr<RouteList const> rl (routes.reader());
|
||||||
|
|
||||||
for (auto const& r : *rl) {
|
for (auto const& r : *rl) {
|
||||||
r->globally_change_time_domain (from, to);
|
r->start_domain_bounce (cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_playlists->globally_change_time_domain (from, to);
|
_playlists->start_domain_bounce(cmd);
|
||||||
_locations->globally_change_time_domain (from, to);
|
_locations->start_domain_bounce (cmd);
|
||||||
|
|
||||||
return undo_command;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Session::finish_domain_bounce (Temporal::DomainBounceInfo& cmd)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::shared_ptr<RouteList const> rl (routes.reader());
|
||||||
|
|
||||||
|
for (auto const& r : *rl) {
|
||||||
|
r->finish_domain_bounce (cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_playlists->finish_domain_bounce (cmd);
|
||||||
|
_locations->finish_domain_bounce (cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Session::time_domain_changed ()
|
||||||
|
{
|
||||||
|
TimeDomainProvider::time_domain_changed ();
|
||||||
|
|
||||||
|
// _playlists->set_time_domain (time_domain());
|
||||||
|
// _locations->set_time_domain (time_domain());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ public:
|
||||||
void add_command (PBD::Command* const);
|
void add_command (PBD::Command* const);
|
||||||
void remove_command (PBD::Command* const);
|
void remove_command (PBD::Command* const);
|
||||||
|
|
||||||
|
std::list<PBD::Command*>::size_type size() const { return actions.size(); }
|
||||||
|
|
||||||
void operator() ();
|
void operator() ();
|
||||||
void undo ();
|
void undo ();
|
||||||
void redo ();
|
void redo ();
|
||||||
|
|
|
||||||
|
|
@ -16,39 +16,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "temporal/domainswap.h"
|
#include "temporal/domain_swap.h"
|
||||||
|
|
||||||
using namespace Temporal;
|
using namespace Temporal;
|
||||||
|
|
||||||
void
|
|
||||||
TimeDomainCommand::add (TimeDomainSwapper& tds)
|
|
||||||
{
|
|
||||||
tds.DropReferences.connect_same_thread (tds_connections, boost::bind (&TimeDomainCommand::going_away, this, &tds));
|
|
||||||
swappers.insert (&tds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TimeDomainCommand::going_away (TimeDomainSwapper* tds)
|
|
||||||
{
|
|
||||||
Swappers::iterator i = swappers.find (tds);
|
|
||||||
|
|
||||||
if (i != swappers.end()) {
|
|
||||||
swappers.erase (i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TimeDomainCommand::operator() ()
|
|
||||||
{
|
|
||||||
for (auto & swapper : swappers) {
|
|
||||||
swapper->swap_domain (from, to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TimeDomainCommand::undo ()
|
|
||||||
{
|
|
||||||
for (auto & swapper : swappers) {
|
|
||||||
swapper->swap_domain (to, from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4864,49 +4864,6 @@ TempoCommand::operator() ()
|
||||||
TempoMap::update (map);
|
TempoMap::update (map);
|
||||||
}
|
}
|
||||||
|
|
||||||
DomainSwapInformation* Temporal::domain_swap (0);
|
|
||||||
|
|
||||||
DomainSwapInformation*
|
|
||||||
DomainSwapInformation::start(TimeDomain prev)
|
|
||||||
{
|
|
||||||
TEMPO_MAP_ASSERT (!domain_swap);
|
|
||||||
domain_swap = new DomainSwapInformation (prev);
|
|
||||||
return domain_swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
DomainSwapInformation::~DomainSwapInformation ()
|
|
||||||
{
|
|
||||||
TEMPO_MAP_ASSERT (this == domain_swap);
|
|
||||||
undo ();
|
|
||||||
domain_swap = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DomainSwapInformation::clear ()
|
|
||||||
{
|
|
||||||
counts.clear ();
|
|
||||||
positions.clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DomainSwapInformation::undo ()
|
|
||||||
{
|
|
||||||
std::cerr << "DSI::undo on " << counts.size() << " lengths and " << positions.size() << " positions\n";
|
|
||||||
for (auto & c : counts) {
|
|
||||||
c->set_time_domain (previous);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto & p : positions) {
|
|
||||||
p->set_time_domain (previous);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto & tt : time_things) {
|
|
||||||
tt->swap_domain (previous == AudioTime ? BeatTime : AudioTime, previous);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
TempoMapCutBuffer::TempoMapCutBuffer (timecnt_t const & dur)
|
TempoMapCutBuffer::TempoMapCutBuffer (timecnt_t const & dur)
|
||||||
: _start_tempo (nullptr)
|
: _start_tempo (nullptr)
|
||||||
, _end_tempo (nullptr)
|
, _end_tempo (nullptr)
|
||||||
|
|
|
||||||
|
|
@ -30,56 +30,38 @@
|
||||||
|
|
||||||
namespace Temporal {
|
namespace Temporal {
|
||||||
|
|
||||||
|
typedef std::map<timepos_t*,timepos_t> TimeDomainPosChanges;
|
||||||
|
typedef std::map<timecnt_t*,timecnt_t> TimeDomainCntChanges;
|
||||||
|
|
||||||
|
struct LIBTEMPORAL_API DomainBounceInfo;
|
||||||
|
|
||||||
struct LIBTEMPORAL_API TimeDomainSwapper : public virtual PBD::Destructible {
|
struct LIBTEMPORAL_API TimeDomainSwapper : public virtual PBD::Destructible {
|
||||||
virtual ~TimeDomainSwapper() {}
|
|
||||||
virtual void swap_domain (Temporal::TimeDomain from, Temporal::TimeDomain to) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct LIBTEMPORAL_API TimeDomainCommand : public PBD::Command {
|
|
||||||
public:
|
public:
|
||||||
TimeDomainCommand (TimeDomain f, TimeDomain t) : from (f), to (t) {}
|
virtual ~TimeDomainSwapper() {}
|
||||||
void add (TimeDomainSwapper&);
|
virtual void start_domain_bounce (DomainBounceInfo&) = 0;
|
||||||
|
virtual void finish_domain_bounce (DomainBounceInfo&) = 0;
|
||||||
void operator() ();
|
|
||||||
void undo ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
TimeDomain from;
|
|
||||||
TimeDomain to;
|
|
||||||
|
|
||||||
typedef std::set<TimeDomainSwapper*> Swappers;
|
|
||||||
Swappers swappers;
|
|
||||||
PBD::ScopedConnectionList tds_connections;
|
|
||||||
|
|
||||||
void going_away (TimeDomainSwapper*);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LIBTEMPORAL_API DomainSwapInformation {
|
/* A DomainBounceInfo functions in two roles:
|
||||||
public:
|
*
|
||||||
static DomainSwapInformation* start (TimeDomain prev);
|
* 1. as part of an UndoTransaction reflecting actions taken by a user that
|
||||||
|
* modified time domains of one or more objects.
|
||||||
|
*
|
||||||
|
* 2. as a standalone object used during temporary domain swaps that records
|
||||||
|
* (perhaps opaquely) what was changed and provides a way to revert it.
|
||||||
|
*/
|
||||||
|
|
||||||
~DomainSwapInformation ();
|
struct LIBTEMPORAL_API DomainBounceInfo
|
||||||
|
{
|
||||||
|
DomainBounceInfo (TimeDomain f, TimeDomain t) : from (f), to (t) {}
|
||||||
|
|
||||||
void add (timecnt_t& t) { counts.push_back (&t); }
|
const TimeDomain from;
|
||||||
void add (timepos_t& p) { positions.push_back (&p); }
|
const TimeDomain to;
|
||||||
void add (TimeDomainSwapper& tt) { time_things.push_back (&tt); }
|
|
||||||
void clear ();
|
|
||||||
|
|
||||||
private:
|
TimeDomainPosChanges positions;
|
||||||
DomainSwapInformation (TimeDomain prev) : previous (prev) {}
|
TimeDomainCntChanges counts;
|
||||||
|
|
||||||
std::vector<timecnt_t*> counts;
|
|
||||||
std::vector<timepos_t*> positions;
|
|
||||||
std::vector<TimeDomainSwapper*> time_things;
|
|
||||||
TimeDomain previous;
|
|
||||||
|
|
||||||
void undo ();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern LIBTEMPORAL_API DomainSwapInformation* domain_swap;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __tmeporal_domain_swap_h__ */
|
#endif /* __tmeporal_domain_swap_h__ */
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
#include "temporal/beats.h"
|
#include "temporal/beats.h"
|
||||||
#include "temporal/bbt_argument.h"
|
#include "temporal/bbt_argument.h"
|
||||||
#include "temporal/bbt_time.h"
|
#include "temporal/bbt_time.h"
|
||||||
#include "temporal/domainswap.h"
|
#include "temporal/domain_swap.h"
|
||||||
#include "temporal/superclock.h"
|
#include "temporal/superclock.h"
|
||||||
#include "temporal/timeline.h"
|
#include "temporal/timeline.h"
|
||||||
#include "temporal/types.h"
|
#include "temporal/types.h"
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ temporal_sources = [
|
||||||
'debug.cc',
|
'debug.cc',
|
||||||
'bbt_time.cc',
|
'bbt_time.cc',
|
||||||
'beats.cc',
|
'beats.cc',
|
||||||
'domainswap.cc',
|
'domain_swap.cc',
|
||||||
'enums.cc',
|
'enums.cc',
|
||||||
'range.cc',
|
'range.cc',
|
||||||
'superclock.cc',
|
'superclock.cc',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue