Towards fixing AU preset invalidation
[ardour.git] / libs / ardour / session_events.cc
index 92b9e88fa66740ed66c010762ff12bb924a1f1c2..479b96ad97c97cfa6427f052ae58756d2b2c37a2 100644 (file)
@@ -28,7 +28,7 @@
 #include "ardour/debug.h"
 #include "ardour/session_event.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
@@ -42,6 +42,12 @@ SessionEvent::init_event_pool ()
        pool = new PerThreadPool;
 }
 
+bool
+SessionEvent::has_per_thread_pool ()
+{
+       return pool->has_per_thread_pool ();
+}
+
 void
 SessionEvent::create_per_thread_pool (const std::string& name, uint32_t nitems)
 {
@@ -52,11 +58,11 @@ SessionEvent::create_per_thread_pool (const std::string& name, uint32_t nitems)
        pool->create_per_thread_pool (name, sizeof (SessionEvent), nitems);
 }
 
-SessionEvent::SessionEvent (Type t, Action a, framepos_t when, framepos_t where, double spd, bool yn, bool yn2, bool yn3)
+SessionEvent::SessionEvent (Type t, Action a, samplepos_t when, samplepos_t where, double spd, bool yn, bool yn2, bool yn3)
        : type (t)
        , action (a)
-       , action_frame (when)
-       , target_frame (where)
+       , action_sample (when)
+       , target_sample (where)
        , speed (spd)
        , yes_or_no (yn)
        , second_yes_or_no (yn2)
@@ -73,12 +79,7 @@ SessionEvent::operator new (size_t)
        SessionEvent* ev = static_cast<SessionEvent*> (p->alloc ());
        DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("%1 Allocating SessionEvent from %2 ev @ %3 pool size %4 free %5 used %6\n", pthread_name(), p->name(), ev,
                                                           p->total(), p->available(), p->used()));
-                                                          
-#ifndef NDEBUG
-       if (DEBUG::SessionEvents & PBD::debug_bits) {
-               // stacktrace (cerr, 40);
-       }
-#endif
+
        ev->own_pool = p;
        return ev;
 }
@@ -86,7 +87,7 @@ SessionEvent::operator new (size_t)
 void
 SessionEvent::operator delete (void *ptr, size_t /*size*/)
 {
-       Pool* p = pool->per_thread_pool ();
+       Pool* p = pool->per_thread_pool (false);
        SessionEvent* ev = static_cast<SessionEvent*> (ptr);
 
        DEBUG_TRACE (DEBUG::SessionEvents, string_compose (
@@ -94,15 +95,10 @@ SessionEvent::operator delete (void *ptr, size_t /*size*/)
                             pthread_name(), ev, enum_2_string (ev->type), enum_2_string (ev->action), p->name(), ev->own_pool->name(), ev->own_pool->total(), ev->own_pool->available(), ev->own_pool->used()
                             ));
 
-#ifndef NDEBUG
-       if (DEBUG::SessionEvents & PBD::debug_bits) {
-               // stacktrace (cerr, 40);
-       }
-#endif
-
-       if (p == ev->own_pool) {
+       if (p && p == ev->own_pool) {
                p->release (ptr);
        } else {
+               assert(ev->own_pool);
                ev->own_pool->push (ev);
                DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("%1 was wrong thread for this pool, pushed event onto pending list, will be deleted on next alloc from %2 pool size %3 free %4 used %5 pending %6\n",
                                                                   pthread_name(), ev->own_pool->name(),
@@ -112,23 +108,23 @@ SessionEvent::operator delete (void *ptr, size_t /*size*/)
 }
 
 void
-SessionEventManager::add_event (framepos_t frame, SessionEvent::Type type, framepos_t target_frame)
+SessionEventManager::add_event (samplepos_t sample, SessionEvent::Type type, samplepos_t target_sample)
 {
-       SessionEvent* ev = new SessionEvent (type, SessionEvent::Add, frame, target_frame, 0);
+       SessionEvent* ev = new SessionEvent (type, SessionEvent::Add, sample, target_sample, 0);
        queue_event (ev);
 }
 
 void
-SessionEventManager::remove_event (framepos_t frame, SessionEvent::Type type)
+SessionEventManager::remove_event (samplepos_t sample, SessionEvent::Type type)
 {
-       SessionEvent* ev = new SessionEvent (type, SessionEvent::Remove, frame, 0, 0);
+       SessionEvent* ev = new SessionEvent (type, SessionEvent::Remove, sample, 0, 0);
        queue_event (ev);
 }
 
 void
-SessionEventManager::replace_event (SessionEvent::Type type, framepos_t frame, framepos_t target)
+SessionEventManager::replace_event (SessionEvent::Type type, samplepos_t sample, samplepos_t target)
 {
-       SessionEvent* ev = new SessionEvent (type, SessionEvent::Replace, frame, target, 0);
+       SessionEvent* ev = new SessionEvent (type, SessionEvent::Replace, sample, target, 0);
        queue_event (ev);
 }
 
@@ -164,20 +160,20 @@ SessionEventManager::dump_events () const
        cerr << "EVENT DUMP" << endl;
        for (Events::const_iterator i = events.begin(); i != events.end(); ++i) {
 
-               cerr << "\tat " << (*i)->action_frame << ' ' << enum_2_string ((*i)->type) << " target = " << (*i)->target_frame << endl;
+               cerr << "\tat " << (*i)->action_sample << ' ' << enum_2_string ((*i)->type) << " target = " << (*i)->target_sample << endl;
        }
        cerr << "Next event: ";
 
        if ((Events::const_iterator) next_event == events.end()) {
                cerr << "none" << endl;
        } else {
-               cerr << "at " << (*next_event)->action_frame << ' '
+               cerr << "at " << (*next_event)->action_sample << ' '
                     << enum_2_string ((*next_event)->type) << " target = "
-                    << (*next_event)->target_frame << endl;
+                    << (*next_event)->target_sample << endl;
        }
        cerr << "Immediate events pending:\n";
        for (Events::const_iterator i = immediate_events.begin(); i != immediate_events.end(); ++i) {
-               cerr << "\tat " << (*i)->action_frame << ' ' << enum_2_string((*i)->type) << " target = " << (*i)->target_frame << endl;
+               cerr << "\tat " << (*i)->action_sample << ' ' << enum_2_string((*i)->type) << " target = " << (*i)->target_sample << endl;
        }
        cerr << "END EVENT_DUMP" << endl;
 }
@@ -197,8 +193,10 @@ SessionEventManager::merge_event (SessionEvent* ev)
 
        case SessionEvent::Clear:
                _clear_event_type (ev->type);
-               /* run any additional realtime callback */
-               ev->rt_slot ();
+               /* run any additional realtime callback, if any */
+               if (ev->rt_slot) {
+                       ev->rt_slot ();
+               }
                if (ev->event_loop) {
                        /* run non-realtime callback (in some other thread) */
                        ev->event_loop->call_slot (MISSING_INVALIDATOR, boost::bind (ev->rt_return, ev));
@@ -213,23 +211,26 @@ SessionEventManager::merge_event (SessionEvent* ev)
 
        /* try to handle immediate events right here */
 
-       if (ev->action_frame == SessionEvent::Immediate) {
+       if (ev->type == SessionEvent::Locate || ev->type == SessionEvent::LocateRoll) {
+               /* remove any existing Locates that are waiting to execute */
+               _clear_event_type (ev->type);
+       }
+
+       if (ev->action_sample == SessionEvent::Immediate) {
                process_event (ev);
                return;
        }
 
        switch (ev->type) {
        case SessionEvent::AutoLoop:
-       case SessionEvent::AutoLoopDeclick:
        case SessionEvent::StopOnce:
                _clear_event_type (ev->type);
                break;
-
        default:
                for (Events::iterator i = events.begin(); i != events.end(); ++i) {
-                       if ((*i)->type == ev->type && (*i)->action_frame == ev->action_frame) {
-                         error << string_compose(_("Session: cannot have two events of type %1 at the same frame (%2)."),
-                                                 enum_2_string (ev->type), ev->action_frame) << endmsg;
+                       if ((*i)->type == ev->type && (*i)->action_sample == ev->action_sample) {
+                         error << string_compose(_("Session: cannot have two events of type %1 at the same sample (%2)."),
+                                                 enum_2_string (ev->type), ev->action_sample) << endmsg;
                                return;
                        }
                }
@@ -252,8 +253,8 @@ SessionEventManager::_replace_event (SessionEvent* ev)
 
        for (i = events.begin(); i != events.end(); ++i) {
                if ((*i)->type == ev->type) {
-                       (*i)->action_frame = ev->action_frame;
-                       (*i)->target_frame = ev->target_frame;
+                       (*i)->action_sample = ev->action_sample;
+                       (*i)->target_sample = ev->target_sample;
                        if ((*i) == ev) {
                                ret = true;
                        }
@@ -281,7 +282,7 @@ SessionEventManager::_remove_event (SessionEvent* ev)
        Events::iterator i;
 
        for (i = events.begin(); i != events.end(); ++i) {
-               if ((*i)->type == ev->type && (*i)->action_frame == ev->action_frame) {
+               if ((*i)->type == ev->type && (*i)->action_sample == ev->action_sample) {
                        if ((*i) == ev) {
                                ret = true;
                        }
@@ -338,4 +339,3 @@ SessionEventManager::_clear_event_type (SessionEvent::Type type)
 
        set_next_event ();
 }
-