triggerbox: start of "pending" architecture to allow for thread-safe swapping of slot contents (Triggers)
This commit is contained in:
parent
c18d175f55
commit
75699e384f
@ -483,6 +483,8 @@ class LIBARDOUR_API TriggerBox : public Processor
|
||||
bool unbang_trigger (TriggerPtr);
|
||||
void add_trigger (TriggerPtr);
|
||||
|
||||
void set_pending (uint32_t slot, TriggerPtr);
|
||||
|
||||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode&, int version);
|
||||
|
||||
@ -511,6 +513,7 @@ class LIBARDOUR_API TriggerBox : public Processor
|
||||
void set_pass_thru (bool yn);
|
||||
|
||||
void request_reload (int32_t slot, void*);
|
||||
void set_region (uint32_t slot, boost::shared_ptr<Region> region);
|
||||
|
||||
enum TriggerMidiMapMode {
|
||||
AbletonPush,
|
||||
@ -554,6 +557,7 @@ class LIBARDOUR_API TriggerBox : public Processor
|
||||
int32_t _order;
|
||||
Glib::Threads::RWLock trigger_lock; /* protects all_triggers */
|
||||
Triggers all_triggers;
|
||||
Triggers pending;
|
||||
PBD::RingBuffer<uint32_t> explicit_queue; /* user queued triggers */
|
||||
TriggerPtr _currently_playing;
|
||||
Requests _requests;
|
||||
|
@ -274,7 +274,13 @@ Trigger::set_quantization (Temporal::BBT_Offset const & q)
|
||||
void
|
||||
Trigger::set_region (boost::shared_ptr<Region> r)
|
||||
{
|
||||
TriggerBox::worker->set_region (_box, index(), r);
|
||||
if (!r) {
|
||||
/* clear operation, no need to talk to the worker thread */
|
||||
_box.set_pending (_index, TriggerPtr());
|
||||
} else {
|
||||
/* load data, do analysis in another thread */
|
||||
TriggerBox::worker->set_region (_box, index(), r);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1681,6 +1687,8 @@ TriggerBox::TriggerBox (Session& s, DataType dt)
|
||||
}
|
||||
}
|
||||
|
||||
pending.reserve (all_triggers.size());
|
||||
|
||||
Config->ParameterChanged.connect_same_thread (*this, boost::bind (&TriggerBox::parameter_changed, this, _1));
|
||||
|
||||
StopAllTriggers.connect_same_thread (stop_all_connection, boost::bind (&TriggerBox::request_stop_all, this));
|
||||
@ -1693,6 +1701,35 @@ TriggerBox::scene_bang (uint32_t n)
|
||||
_pending_scene = n;
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBox::set_region (uint32_t slot, boost::shared_ptr<Region> region)
|
||||
{
|
||||
/* This is called from our worker thread */
|
||||
|
||||
TriggerPtr t;
|
||||
|
||||
switch (_data_type) {
|
||||
case DataType::AUDIO:
|
||||
t = boost::make_shared<AudioTrigger> (slot, *this);
|
||||
break;
|
||||
case DataType::MIDI:
|
||||
t = boost::make_shared<MIDITrigger> (slot, *this);
|
||||
break;
|
||||
}
|
||||
|
||||
t->set_region_threaded (region);
|
||||
|
||||
/* XXX what happens if pending is already set? */
|
||||
|
||||
set_pending (slot, t);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBox::set_pending (uint32_t slot, TriggerPtr t)
|
||||
{
|
||||
pending[slot] = t;
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBox::scene_unbang (uint32_t n)
|
||||
{
|
||||
@ -2700,7 +2737,7 @@ TriggerBoxThread::thread_work ()
|
||||
while (requests.read (&req, 1) == 1) {
|
||||
switch (req->type) {
|
||||
case SetRegion:
|
||||
req->box->trigger (req->slot)->set_region_threaded (req->region);
|
||||
req->box->set_region (req->slot, req->region);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user