[rkward-cvs] SF.net SVN: rkward-code:[4752] trunk/rkward/rkward

tfry at users.sf.net tfry at users.sf.net
Thu May 16 08:10:36 UTC 2013


Revision: 4752
          http://sourceforge.net/p/rkward/code/4752
Author:   tfry
Date:     2013-05-16 08:10:35 +0000 (Thu, 16 May 2013)
Log Message:
-----------
Allow plugins to run R commands from UI script code.

Modified Paths:
--------------
    trunk/rkward/rkward/plugins/testing/test1.xml
    trunk/rkward/rkward/scriptbackends/rkcomponentscripting.cpp
    trunk/rkward/rkward/scriptbackends/rkcomponentscripting.h
    trunk/rkward/rkward/scriptbackends/rkcomponentscripting.js

Modified: trunk/rkward/rkward/plugins/testing/test1.xml
===================================================================
--- trunk/rkward/rkward/plugins/testing/test1.xml	2013-05-16 07:34:59 UTC (rev 4751)
+++ trunk/rkward/rkward/plugins/testing/test1.xml	2013-05-16 08:10:35 UTC (rev 4752)
@@ -6,6 +6,7 @@
 	<logic>
 		<script><![CDATA[
 			call_num = 0;
+ 			last_command_id = -1;
 			gui.setValue ("text.text", "Select a dependent variable!");
 
 			f = Kross.module('forms');
@@ -20,7 +21,13 @@
 				text += "That has length " + obj.dimensions() + " and classes " + obj.classes() + "!\n";
 				text += "Updates of this text so far: " + call_num;
 				gui.setValue ("text.text", text);
+
+				if (obj.objectname != "") last_command_id = doRCommand ("levels (" + obj.objectname + ")", "levelsCommandFinished");
 			}
+			levelsCommandFinished = function (value, id) {
+				otext = gui.getValue ("text.text");
+				gui.setValue ("text.text", otext + "\n" + last_command_id + "-" + id + "\nadas" + value.join ("-"));
+			}
 			]]></script>
 	</logic>
 

Modified: trunk/rkward/rkward/scriptbackends/rkcomponentscripting.cpp
===================================================================
--- trunk/rkward/rkward/scriptbackends/rkcomponentscripting.cpp	2013-05-16 07:34:59 UTC (rev 4751)
+++ trunk/rkward/rkward/scriptbackends/rkcomponentscripting.cpp	2013-05-16 08:10:35 UTC (rev 4752)
@@ -24,6 +24,8 @@
 #include "../plugin/rkcomponent.h"
 #include "../core/robjectlist.h"
 #include "../misc/rkcommonfunctions.h"
+#include "../rkglobals.h"
+#include "../rbackend/rinterface.h"
 
 #include "../debug.h"
 
@@ -40,6 +42,10 @@
 
 RKComponentScriptingProxy::~RKComponentScriptingProxy () {
 	RK_TRACE (PHP);
+
+	for (int i = 0; i < outstanding_commands.size (); ++i) {
+		RKGlobals::rInterface ()->cancelCommand (outstanding_commands[i].command);
+	}
 }
 
 void RKComponentScriptingProxy::initialize (const QString& file, const QString& command) {
@@ -129,6 +135,86 @@
 	}
 }
 
+QVariant RKComponentScriptingProxy::doRCommand (const QString& command, const QString& callback) {
+	RK_TRACE (PHP);
+
+	// purge duplicate commands
+	for (int i = 0; i < outstanding_commands.size (); ++i) {
+		const OutstandingCommand &oc = outstanding_commands[i];
+		if (oc.callback == callback) {
+			if (RKGlobals::rInterface ()->softCancelCommand (oc.command)) {
+				outstanding_commands.removeAt (i);
+				--i;
+				continue;
+			}
+		}
+	}
+
+	OutstandingCommand com;
+	com.command = new RCommand (command, RCommand::PriorityCommand | RCommand::GetStructuredData | RCommand::Plugin);
+	connect (com.command->notifier (), SIGNAL (commandFinished(RCommand*)), this, SLOT (scriptRCommandFinished(RCommand*)));
+	com.callback = callback;
+	outstanding_commands.append (com);
+
+	RKGlobals::rInterface ()->issueCommand (com.command);
+	return (QVariant (com.command->id ()));
+}
+
+static QVariant marshall (RData *data) {
+	RK_TRACE (PHP);
+
+	if (data->getDataType () == RData::StringVector) {
+		return (QVariant (data->stringVector()));
+	} else if (data->getDataType () == RData::IntVector) {
+		const RData::IntStorage& is = data->intVector ();
+		QVariantList ret;
+		for (int i = 0; i < is.size (); ++i) {
+			ret.append (QVariant (is[i]));
+		}
+		return ret;
+	} else if (data->getDataType () == RData::RealVector) {
+		const RData::RealStorage& rs = data->realVector ();
+		QVariantList ret;
+		for (int i = 0; i < rs.size (); ++i) {
+			ret.append (QVariant (rs[i]));
+		}
+		return ret;
+	} else if (data->getDataType () == RData::StructureVector) {
+		const RData::RDataStorage& rs = data->structureVector ();
+		QVariantList ret;
+		for (int i = 0; i < rs.size (); ++i) {
+			ret.append (marshall (rs[i]));
+		}
+		return ret;
+	} else {
+		RK_ASSERT (false);
+	}
+	return QVariant ();
+}
+
+void RKComponentScriptingProxy::scriptRCommandFinished (RCommand* command) {
+	RK_TRACE (PHP);
+
+	QString callback;
+	for (int i = 0; i < outstanding_commands.size (); ++i) {
+		const OutstandingCommand& oc = outstanding_commands[i];
+		if (oc.command == command) {
+			callback = oc.callback;
+			outstanding_commands.removeAt (i);
+			break;
+		}
+	}
+	RK_ASSERT (!callback.isNull ());
+
+	if (command->wasCanceled ()) return;
+	if (command->failed ()) RK_DEBUG (PHP, DL_ERROR, "Plugin script R command %s failed. Full output wsa %s", qPrintable (command->command ()), qPrintable (command->fullOutput ()));
+
+	QVariantList args;
+	args.append (marshall (command));
+	args.append (QVariant (command->id ()));
+	script->callFunction (callback, args);
+}
+
 void RKComponentScriptingProxy::componentChanged (RKComponent* changed) {
 	RK_TRACE (PHP);
 	handleChange (changed);

Modified: trunk/rkward/rkward/scriptbackends/rkcomponentscripting.h
===================================================================
--- trunk/rkward/rkward/scriptbackends/rkcomponentscripting.h	2013-05-16 07:34:59 UTC (rev 4751)
+++ trunk/rkward/rkward/scriptbackends/rkcomponentscripting.h	2013-05-16 08:10:35 UTC (rev 4752)
@@ -2,7 +2,7 @@
                           rkcomponentscripting  -  description
                              -------------------
     begin                : Thu Jun 17 2010
-    copyright            : (C) 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -22,6 +22,7 @@
 #include <QHash>
 
 #include <kross/core/action.h>
+#include "../rbackend/rcommand.h"
 
 class RKComponent;
 class RKComponentBase;
@@ -48,6 +49,8 @@
 // these are meant to be called from the script
 	void include (const QString& filename);
 	void addChangeCommand (const QString& changed_id, const QString& command);
+/** @returns id of the command issued. */
+	QVariant doRCommand (const QString& command, const QString& callback);
 
 	QVariant getValue (const QString &id) const;
 	QVariant getString (const QString &id) const;
@@ -60,9 +63,16 @@
 	QString getObjectChild (const QString &name);
 signals:
 	void haveError ();
+private slots:
+	void scriptRCommandFinished (RCommand* command);
 private:
 	RKComponent* component;
 	Kross::Action* script;
+	struct OutstandingCommand {
+		RCommand *command;
+		QString callback;
+	};
+	QList<OutstandingCommand> outstanding_commands;
 	QString _scriptfile;
 /** helper function for compatibility with KDE < 4.3 */
 	void evaluate (const QByteArray &code);

Modified: trunk/rkward/rkward/scriptbackends/rkcomponentscripting.js
===================================================================
--- trunk/rkward/rkward/scriptbackends/rkcomponentscripting.js	2013-05-16 07:34:59 UTC (rev 4751)
+++ trunk/rkward/rkward/scriptbackends/rkcomponentscripting.js	2013-05-16 08:10:35 UTC (rev 4752)
@@ -2,7 +2,7 @@
                           rkcomponentscripting  -  description
                              -------------------
     begin                : Thu Jun 17 2010
-    copyright            : (C) 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -59,6 +59,9 @@
 	return (new Component (id));
 }
 gui = new Component ("");
+doRCommand = function (command, callback) {
+	return (_rkward.doRCommand (command, callback));
+}
 
 function RObject(objectname) {
 	this.objectname = objectname;





More information about the rkward-tracker mailing list