![]() |
Mixxx
|
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 }