Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/script/scriptcontrolqueue.cpp

Go to the documentation of this file.
00001 #include "scriptcontrolqueue.h"
00002 #include "numbercontrolevent.h"
00003 #include "trackcontrolevent.h"
00004 
00005 ScriptControlQueue::ScriptControlQueue(ScriptEngine* parent) : QObject() {
00006         connect(&m_timer, SIGNAL(timeout()), this, SLOT(timerCallback()));
00007 
00008         m_parent = parent;
00009 }
00010 
00011 ScriptControlQueue::~ScriptControlQueue() {
00012 }
00013 
00014 void ScriptControlQueue::setupCallbacks() {
00015         //qDebug("setupCallbacks()");
00016         if (m_timer.isActive()) {
00017                 m_timer.stop();
00018         }
00019         //qDebug("Test 1");
00020         if (m_q.isEmpty()) {
00021                 //qDebug("Queue is empty");
00022                 return;
00023         }
00024         //qDebug("Test 2");
00025         ScriptControlEvent* ev = m_q.first();
00026         //qDebug("Test 3");
00027         const QDateTime* evtime = ev->getTime();
00028         //qDebug("Test 4");
00029         QDateTime now = QDateTime::currentDateTime();
00030         //qDebug("Test 5");
00031         int delta = 0;
00032         //qDebug("evtime: %x", evtime);
00033         //qDebug("Event: %i", evtime->toTime_t());
00034         //qDebug("Now: %i", now.toTime_t());
00035         
00036         if (*evtime <= now) {
00037                 // Theres an event on the queue which we should be executing now
00038                 //qDebug("Test: %i %i", evtime->time().msec(), now.time().msec());
00039                 //qDebug("Test: %f", ev->getValue());
00040                 m_q.removeFirst();
00041                 //qDebug("Ptr: %x", ev);
00042                 ev->execute();
00043                 delete ev;
00044         } else {
00045                 // Theres an event, but not for a while so sleep until then
00046                 delta = now.secsTo(*evtime) * 1000;
00047                 int msecsnow = now.time().msec();
00048                 int msecsev = evtime->time().msec();
00049                 //qDebug("msecsnow %i", msecsnow);
00050                 //qDebug("msecsev %i", msecsev);
00051                 if (msecsev > msecsnow) {
00052                         delta += msecsev - msecsnow;
00053                 } else if (msecsev < msecsnow) {
00054                         delta -= (msecsnow - msecsev);
00055                 }
00056                 // Try to compensate for the fact the triggering the event takes
00057                 // a few ms
00058                 //delta -= 10;
00059                 
00060                 // Never sleep for 0ms, as that means just return immediately
00061                 // Sleep for 1ms which will give us some minimum delay
00062                 if (delta < 1) { delta = 1; }
00063         }
00064         
00065         // Ring me back when it's time to process another event
00066         //qDebug("Sleep time %i", delta);
00067         //qDebug("Event: %i", evtime->toTime_t());
00068         m_timer.start(delta, TRUE);
00069 }
00070 
00071 void ScriptControlQueue::timerCallback() {
00072         //qDebug("timerCallback()");
00073         setupCallbacks();
00074 }
00075 
00076 // This is probably turbo-unthread-safe because of the way it uses qptrlist
00077 // But it's only running in one thread at a time for now, so it's ok
00078 void ScriptControlQueue::schedule(ScriptControlEvent *event) {
00079         const QDateTime* newtime = event->getTime();
00080         //qDebug("----");
00081         //qDebug(QDateTime::currentDateTime().toString());
00082         //qDebug(newtime->toString());
00083         QLinkedList<ScriptControlEvent*>::iterator qit = m_q.begin();
00084         
00085         //Qt3 code:
00086         //ScriptControlEvent* ev = m_q.first();
00087         while(qit != m_q.end()) {
00088                 const QDateTime* evtime = (*qit)->getTime();
00089                 //qDebug(evtime->toString());
00090                 if (*newtime < *evtime) {
00091                         //qDebug("%s:%i < %s:%i", (const char*)newtime->toString(), newtime->time().msec(), (const char*)evtime->toString(), evtime->time().msec());
00092                         //if (newtime->time() < evtime->time()) {
00093                         //      qDebug("Yep");
00094                         //}
00095                         m_q.insert(qit, event);
00096                         return;
00097                 }
00098                         //qDebug("%s >= %s", (const char*)newtime->toString(), (const char*)evtime->toString());
00099                 qit++;
00100         }
00101         // If we got to the end, it's last
00102         m_q.append(event);
00103         //qDebug("Event is at %i in queue", m_q.findRef(event));
00104         m_timer.start(0, TRUE);
00105 }
00106 
00107 QDateTime ScriptControlQueue::getWhen(const QDateTime* base, int offset) {
00108         int days = 0;
00109         //qDebug(base->toString());
00110         //qDebug("+ %i", offset);
00111         if (base->time().addMSecs(offset) < base->time()) {
00112                 days = 1;
00113         }
00114 
00115         QDateTime when(base->date().addDays(days), base->time().addMSecs(offset));
00116         return when;
00117 }
00118 
00119 
00120 void ScriptControlQueue::schedule(int channel, QString path, 
00121                 QDateTime base, int offset, int process, int tag) {
00122         TrackControlEvent* ev = new TrackControlEvent(m_parent, channel, path,\
00123                         getWhen(&base, offset), process, tag);
00124         schedule(ev);
00125 }
00126 
00127 void ScriptControlQueue::schedule(const char* group, const char* name, \
00128                 double value, const QDateTime *base, int offset, \
00129                 int process, int tag) {
00130         // This is wierd code, that's because QDateTime does wierd things, like 
00131         // deallocate memory you're still using
00132         
00133         // TODO: For now this doesn't support macros longer than 1 day 
00134         // (not an immediate problem :)
00135         //qDebug("+%i->%i:%f", offset, when, (float)value);
00136         schedule(new NumberControlEvent(group, name, value, \
00137                                 getWhen(base, offset), process, tag));
00138 }
00139 
00140 void ScriptControlQueue::interpolate(const char* group, const char* name, \
00141                 const QDateTime *base, int time1, double val1, int time2, \
00142                 double val2, int process, int tag, bool addLast, int minres) {
00143         
00144         //qDebug("%i %f -> %i %f", time1, val1, time2, val2);
00145                         
00146         int diff = time2 - time1;
00147         double dv = val2 - val1;
00148         int chunks = ((diff) / minres);
00149         if ((chunks * minres) < diff) { chunks++; }
00150         int max = chunks;
00151         if (addLast) { max++; }
00152         
00153         for (int i = 0; i < max; i++) {
00154                 int time = ((diff*i)/chunks) + time1;
00155                 //qDebug("At time %i", time);
00156                 //qDebug("%f", ((double)i/(double)max));
00157                 double val = val1 + (((double)i/(double)chunks) * dv);
00158                 schedule(group, name, val, base, time, process, tag);
00159                 //qDebug("Schedule at %i => %f", time, val);
00160                 //qDebug("Value %f", val);
00161         }
00162 }
00163 
00164 void ScriptControlQueue::killProcess(int process) {
00165         QLinkedList<ScriptControlEvent*>::iterator qit = m_q.begin();
00166         //ScriptControlEvent *ev = m_q.first();
00167         while (qit != m_q.end()) {
00168                 if ((*qit)->getProcess() == process) {
00169                         delete (*qit);
00170                         qit = m_q.erase(qit);
00171                 } else {
00172                         qit++;
00173                 }
00174         }
00175 }
00176 
00177 void ScriptControlQueue::killTag(int process, int tag) {
00178         
00179         QLinkedList<ScriptControlEvent*>::iterator qit = m_q.begin();
00180         //ScriptControlEvent *ev = m_q.first();
00181         while (qit != m_q.end()) {
00182                 if ((*qit)->getProcess() == process && (*qit)->getTag() == tag) {
00183                         delete (*qit);
00184                         qit = m_q.erase(qit);
00185                 } else {
00186                         qit++;
00187                 }
00188         }
00189 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines