![]() |
Mixxx
|
00001 /*************************************************************************** 00002 midiscriptengine.h - description 00003 ------------------- 00004 begin : Fri Dec 12 2008 00005 copyright : (C) 2008-2010 by Sean M. Pappalardo 00006 email : spappalardo@mixxx.org 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 #ifndef MIDISCRIPTENGINE_H 00018 #define MIDISCRIPTENGINE_H 00019 00020 #include <QEvent> 00021 #include <QtScript> 00022 #include <QMessageBox> 00023 #include "configobject.h" 00024 #include "midimessage.h" 00025 #include "pitchfilter.h" 00026 #include "softtakeover.h" 00027 00028 class MidiDevice; 00029 00030 //Forward declaration(s) 00031 class ControlObjectThread; 00032 00033 class MidiScriptEngine : public QThread { 00034 Q_OBJECT 00035 public: 00036 MidiScriptEngine(MidiDevice* midiDevice); 00037 virtual ~MidiScriptEngine(); 00038 00039 bool isReady(); 00040 bool hasErrors(QString filename); 00041 const QStringList getErrors(QString filename); 00042 00043 void setMidiDebug(bool bDebug) { 00044 m_midiDebug = bDebug; 00045 } 00046 00047 void setMidiPopups(bool bPopups) { 00048 m_midiPopups = bPopups; 00049 } 00050 00051 // Lookup registered script functions 00052 QStringList getScriptFunctions(); 00053 00054 /* DO NOT CALL DIRECTLY, 00055 SHOULD ONLY BE CALLED FROM WITHIN SCRIPTS */ 00056 Q_INVOKABLE double getValue(QString group, QString name); 00057 Q_INVOKABLE void setValue(QString group, QString name, double newValue); 00058 Q_INVOKABLE bool connectControl(QString group, QString name, 00059 QString function, bool disconnect = false); 00060 Q_INVOKABLE void trigger(QString group, QString name); 00061 Q_INVOKABLE void log(QString message); 00062 Q_INVOKABLE int beginTimer(int interval, QScriptValue scriptCode, bool oneShot = false); 00063 Q_INVOKABLE void stopTimer(int timerId); 00064 Q_INVOKABLE void scratchEnable(int deck, int intervalsPerRev, float rpm, float alpha, float beta); 00065 Q_INVOKABLE void scratchTick(int deck, int interval); 00066 Q_INVOKABLE void scratchDisable(int deck); 00067 Q_INVOKABLE void softTakeover(QString group, QString name, bool set); 00068 00069 public slots: 00070 void slotValueChanged(double value); 00071 // Evaluate a script file 00072 bool evaluate(QString filepath); 00073 // Execute a particular function 00074 bool execute(QString function); 00075 // Execute a particular function with a data string (e.g. a device ID) 00076 bool execute(QString function, QString data); 00077 // Execute a particular function with a data buffer (e.g. a SysEx message) 00078 bool execute(QString function, const unsigned char data[], unsigned int length); 00079 // Execute a particular function with all the data 00080 bool execute(QString function, char channel, 00081 char control, char value, MidiStatusByte status, QString group); 00082 void loadScriptFiles(QList<QString> scriptFileNames); 00083 void initializeScripts(QList<QString> scriptFunctionPrefixes); 00084 void gracefulShutdown(QList<QString> scriptFunctionPrefixes); 00085 00086 signals: 00087 void initialized(); 00088 void resetController(); 00089 00090 protected: 00091 void run(); 00092 void timerEvent(QTimerEvent *event); 00093 00094 private slots: 00095 void errorDialogButton(QString key, QMessageBox::StandardButton button); 00096 00097 private: 00098 // Only call these with the scriptEngineLock 00099 bool safeEvaluate(QString scriptName, QList<QString> scriptPaths); 00100 bool internalExecute(QScriptValue thisObject, QString scriptCode); 00101 bool safeExecute(QString function); 00102 bool safeExecute(QString function, QString data); 00103 bool safeExecute(QString function, const unsigned char data[], unsigned int length); 00104 bool safeExecute(QString function, char channel, 00105 char control, char value, MidiStatusByte status, QString group); 00106 bool safeExecute(QScriptValue thisObject, QScriptValue functionObject); 00107 void initializeScriptEngine(); 00108 00109 void scriptErrorDialog(QString detailedError); 00110 void generateScriptFunctions(QString code); 00111 bool checkException(); 00112 void stopAllTimers(); 00113 00114 ControlObjectThread* getControlObjectThread(QString group, QString name); 00115 00116 MidiDevice* m_pMidiDevice; 00117 bool m_midiDebug; 00118 bool m_midiPopups; 00119 QMultiHash<ConfigKey, QString> m_connectedControls; 00120 QScriptEngine *m_pEngine; 00121 QStringList m_scriptFunctions; 00122 QMap<QString,QStringList> m_scriptErrors; 00123 QMutex m_scriptEngineLock; 00124 QHash<ConfigKey, ControlObjectThread*> m_controlCache; 00125 struct TimerInfo { 00126 QScriptValue callback; 00127 QScriptValue context; 00128 bool oneShot; 00129 }; 00130 QHash<int, TimerInfo> m_timers; 00131 SoftTakeover m_st; 00132 00133 // Scratching functions & variables 00134 void scratchProcess(int timerId); 00135 00136 // 256 (default) available virtual decks is enough I would think. 00137 // If more are needed at run-time, these will move to the heap automatically 00138 QVarLengthArray <int> m_intervalAccumulator; 00139 QVarLengthArray <float> m_dx, m_rampTo; 00140 QVarLengthArray <bool> m_ramp; 00141 QVarLengthArray <PitchFilter*> m_pitchFilter; 00142 QHash<int, int> m_scratchTimers; 00143 }; 00144 00145 #endif