Hello.
Attached is a patch that brings us closer to release. It allows users to
specify which script file(s) to load in the XML like so:
<controller id="SCS.3d MIDI 1" port="Port">
<scriptfiles>
<file functionprefix="StantonSCS3d">
<filename>Stanton-SCS3d-scripts.js</filename>
</file>
</scriptfiles>
<controls>
<control>
...
It also calls the correct <devicename>.init() function in each file at
the proper time so LEDs can be set correctly.
I'll update the Wiki with these changes.
It also adds the option to specify a specific XML file at load time with
the --loadXMLfile path/to/file.xml as a command line option. (For
developers only!!)
Sincerely,
Sean M. Pappalardo
"D.J. Pegasus"
<<--------------------------------------------------------------------------------->>
This E-Mail message has been scanned for viruses
and cleared by >>SmartMail<< from Smarter Technology, Inc.
<<--------------------------------------------------------------------------------->>
Index: src/midiobject.h
===================================================================
--- src/midiobject.h (revision 2458)
+++ src/midiobject.h (working copy)
@@ -85,6 +85,10 @@
void disableMidiLearn();
#ifdef __SCRIPT__
+ QList<QString> scriptFileNames;
+ QList<QString> scriptFunctionPrefixes;
+
+ void loadScripts();
MidiScriptEngine *getMidiScriptEngine();
#endif
Index: src/midiobject.cpp
===================================================================
--- src/midiobject.cpp (revision 2458)
+++ src/midiobject.cpp (working copy)
@@ -22,6 +22,7 @@
#include <signal.h>
#include "dlgprefmididevice.h"
#include "dlgprefmidibindings.h"
+
#ifdef __SCRIPT__
#include "script/midiscriptengine.h"
#endif
@@ -39,36 +40,6 @@
requestStop = false;
midiLearn = false;
debug = false;
-
-#ifdef __SCRIPT__
- m_pScriptEngine = new MidiScriptEngine();
- m_pScriptEngine->engineGlobalObject.setProperty("midi", m_pScriptEngine->getEngine()->newQObject(this));
-
- ConfigObject<ConfigValue> *m_pConfig = new ConfigObject<ConfigValue>(QDir::homePath().append("/").append(SETTINGS_FILE));
- m_pScriptEngine->loadScript(m_pConfig->getConfigPath().append("midi/midi-mappings-scripts.js"));
-// FIXME: this hack below has to be replaced with something better... even *.js is preferrable to a hard coded string switch statement.
-// switch (m_device) {
-// case "SCS.3d MIDI *":
-// m_pScriptEngine->loadScript(m_pConfig->getConfigPath().append("midi/Stanton-SCS3d-scripts.js"));
-// break;
-// case "Hercules MK2 *":
-// m_pScriptEngine->loadScript(m_pConfig->getConfigPath().append("midi/Hercules-MK2-scripts.js"));
-// break;
-// }
- qDebug() << "MidiObject: Evaluating all script code";
-
- m_pScriptEngine->evaluateScript();
- if (!m_pScriptEngine->checkException() && m_pScriptEngine->isGood()) qDebug() << "MidiObject: Script code evaluated successfully";
-
-/* // Call script's init function if it exists - First need deviceChannel and deviceName in this object
- QScriptValue scriptFunction = m_pScriptEngine->execute("init");
- if (!scriptFunction.isFunction()) qDebug() << "MidiObject: No init function in script";
- else {
- scriptFunction.call(QScriptValue());
- m_pScriptEngine->checkException();
- }
-*/
-#endif
}
/* -------- ------------------------------------------------------
@@ -80,6 +51,68 @@
{
}
+#ifdef __SCRIPT__
+/* -------- ------------------------------------------------------
+ Purpose: Loads and processes MIDI scripts
+ Input: -
+ Output: -
+ -------- ------------------------------------------------------ */
+void MidiObject::loadScripts()
+{
+ m_pScriptEngine = new MidiScriptEngine();
+ m_pScriptEngine->engineGlobalObject.setProperty("midi", m_pScriptEngine->getEngine()->newQObject(this));
+
+ ConfigObject<ConfigValue> *m_pConfig = new ConfigObject<ConfigValue>(QDir::homePath().append("/").append(SETTINGS_FILE));
+
+ // Individually load & evaluate script files in the QList (built by dlgPrefMidiBindings) to check for errors
+ // so line numbers will be accurate per file (for syntax errors at least) to make troubleshooting much easier
+ bool scriptError = false;
+
+ for (int i=0; i<scriptFileNames.size(); i++) {
+ m_pScriptEngine->clearCode(); // So line numbers will be correct
+
+ QString filename = scriptFileNames.at(i);
+ qDebug() << "MidiObject: Loading & testing MIDI script" << filename;
+ m_pScriptEngine->loadScript(m_pConfig->getConfigPath().append("midi/").append(filename));
+
+ m_pScriptEngine->evaluateScript();
+ if (!m_pScriptEngine->checkException() && m_pScriptEngine->isGood()) qDebug() << "MidiObject: Success";
+ else {
+ // This is only included for completeness since checkException should pop a qCritical() itself if there's a problem
+ qCritical() << "MidiObject: Failure evaluating MIDI script" << filename;
+ scriptError = true;
+ }
+ }
+
+ qDebug() << "MidiObject: Loading & evaluating all MIDI script code";
+ m_pScriptEngine->clearCode(); // Start from scratch
+
+ if (!scriptError) {
+ while (!scriptFileNames.isEmpty()) {
+ m_pScriptEngine->loadScript(m_pConfig->getConfigPath().append("midi/").append(scriptFileNames.takeFirst()));
+ }
+
+ m_pScriptEngine->evaluateScript();
+ if (!m_pScriptEngine->checkException() && m_pScriptEngine->isGood()) qDebug() << "MidiObject: Script code evaluated successfully";
+
+ // Call each script's init function if it exists
+ while (!scriptFunctionPrefixes.isEmpty()) {
+ QString initName = scriptFunctionPrefixes.takeFirst();
+ if (initName!="") {
+ initName.append(".init");
+ qDebug() << "MidiObject: Executing" << initName;
+ QScriptValue scriptFunction = m_pScriptEngine->execute(initName);
+ if (!scriptFunction.isFunction()) qWarning() << "MidiObject: No" << initName << "function in script";
+ else {
+ scriptFunction.call(QScriptValue());
+ m_pScriptEngine->checkException();
+ }
+ }
+ }
+ }
+}
+#endif
+
void MidiObject::setMidiConfig(ConfigObject<ConfigValueMidi> * pMidiConfig)
{
m_pMidiConfig = pMidiConfig;
@@ -189,11 +222,11 @@
}
/*
qDebug() << QString("MidiObject::receive from device: %1, type: %2, catagory: %3, ch: %4, ctrl: %5, val: %6").arg(device)
- .arg(QString::number(type))
- .arg(QString::number(category, 16).toUpper())
- .arg(QString::number(channel, 16).toUpper())
- .arg(QString::number(control, 16).toUpper())
- .arg(QString::number(value, 16).toUpper());
+ .arg(QString::number(type))
+ .arg(QString::number(category, 16).toUpper())
+ .arg(QString::number(channel, 16).toUpper())
+ .arg(QString::number(control, 16).toUpper())
+ .arg(QString::number(value, 16).toUpper());
*/
if (midiLearn) {
emit(midiEvent(new ConfigValueMidi(type,control,channel), device));
@@ -291,7 +324,6 @@
// qDebug() << "New Control Value: " << newValue << " ";
p->queueFromMidi(category, newValue);
}
-
}
void MidiObject::stop()
Index: src/dlgprefmidibindings.cpp
===================================================================
--- src/dlgprefmidibindings.cpp (revision 2458)
+++ src/dlgprefmidibindings.cpp (working copy)
@@ -65,8 +65,14 @@
connect(btnRemoveOutputBinding, SIGNAL(clicked()), this, SLOT(slotRemoveOutputBinding()));
connect(btnAddOutputBinding, SIGNAL(clicked()), this, SLOT(slotAddOutputBinding()));
- // Try to read in the current XML bindings file, or create one if nothing is available
- loadPreset(BINDINGS_PATH);
+ // Try to read in the current XML bindings file, one from the command line, or create one if nothing is available
+ QStringList commandLineArgs = QApplication::arguments();
+ int loadXML = commandLineArgs.indexOf("--loadXMLfile");
+ if (loadXML!=-1) {
+ qDebug() << "Loading custom MIDI mapping file:" << commandLineArgs.at(loadXML+1);
+ loadPreset(commandLineArgs.at(loadXML+1));
+ }
+ else loadPreset(BINDINGS_PATH);
applyPreset();
m_pMidi->disableMidiLearn();
}
@@ -97,14 +103,36 @@
// Get deviceid
QString device = controller.attribute("id","");
qDebug() << device << " settings found" << endl;
- QDomElement control = controller.firstChildElement("controls").firstChildElement("control");
+
+#ifdef __SCRIPT__
+ // Get a list of MIDI script files to load (loaded by MidiObject)
+ QDomElement scriptFile = controller.firstChildElement("scriptfiles").firstChildElement("file");
+
+ // Default currently required file
+ m_pMidi->scriptFileNames.append("midi-mappings-scripts.js");
+ m_pMidi->scriptFunctionPrefixes.append("");
+
+ // Look for additional ones
+ while (!scriptFile.isNull()) {
+
+ QString functionPrefix = scriptFile.attribute("functionprefix","");
+ QString filename = WWidget::selectNodeQString(scriptFile, "filename");
+ m_pMidi->scriptFileNames.append(filename);
+ m_pMidi->scriptFunctionPrefixes.append(functionPrefix);
+
+ scriptFile = scriptFile.nextSiblingElement("file");
+ }
-#ifdef __SCRIPT__
+ m_pMidi->loadScripts(); // This will halt execution if there's a problem with a script (qCritical)
+
MidiScriptEngine * ScriptEngine = m_pMidi->getMidiScriptEngine();
bool scriptGood = ScriptEngine->isGood();
QStringList scriptFunctions;
if (scriptGood) scriptFunctions = ScriptEngine->getFunctionList();
#endif
+
+ QDomElement control = controller.firstChildElement("controls").firstChildElement("control");
+
while (!control.isNull()) {
// For each control
QString group = WWidget::selectNodeQString(control, "group");
Index: src/script/midiscriptengine.cpp
===================================================================
--- src/script/midiscriptengine.cpp (revision 2458)
+++ src/script/midiscriptengine.cpp (working copy)
@@ -28,9 +31,6 @@
engineGlobalObject = m_engine.globalObject();
engineGlobalObject.setProperty("engine", m_engine.newQObject(this));
-// ControlObject* m_cobj;
-// m_cobj = ControlObject::getControl(ConfigKey("[Channel1]","back"));
-// engineGlobalObject.setProperty("revers", m_engine.newQObject(m_cobj));
}
MidiScriptEngine::~MidiScriptEngine() {
@@ -73,6 +73,8 @@
-------- ------------------------------------------------------ */
void MidiScriptEngine::clearCode() {
m_scriptCode.clear();
+ m_scriptGood=false;
+ m_result="";
return;
}
@@ -179,7 +181,7 @@
QString line = codeLines.takeAt(position); // Pull & remove the current match from the list.
- if (line.indexOf('#') != 0) { // ignore # hashed out comments
+ if (line.indexOf('#') != 0 && line.indexOf("//") != 0) { // ignore comments
QStringList field = line.split(" ");
qDebug() << "MidiScriptEngine: Found function:" << field[0] << "at line" << position;
functionList.append(field[0]);
------------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It is the best place to buy or sell services for
just about anything Open Source.
http://p.sf.net/sfu/Xq1LFB
_______________________________________________
Mixxx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mixxx-devel