Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/midi/midiscriptengine.h

Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines