[Kst] branches/work/kst/1.6/kst/src

Andrew Walker arwalker at sumusltd.com
Thu Jan 10 22:14:20 CET 2008


SVN commit 759559 by arwalker:

first draft of allowing c-style plugins to be used from javaScript

 M  +2 -2      extensions/js/bind_colorsequence.h  
 M  +156 -2    extensions/js/bind_plugin.cpp  
 M  +14 -0     extensions/js/bind_plugin.h  
 M  +1 -1      libkst/kstdatasource.cpp  
 M  +99 -7     libkstmath/kstcplugin.cpp  
 M  +2 -2      libkstmath/kstcplugin.h  
 M  +1 -1      libkstmath/plugin.cpp  


--- branches/work/kst/1.6/kst/src/extensions/js/bind_colorsequence.h #759558:759559
@@ -51,13 +51,13 @@
        @description Returns the next color in the color sequence.
     */
     KJS::Value next(KJS::ExecState *exec, const KJS::List& args);
-   
+
     /* @method tooClose
        @arg string firstColor The first of two colors to compare.
        @arg string secondColor The second of two colors to compare.
        @returns boolean
        @description Returns true if colors are too close.
-    */   
+    */
     KJS::Value tooClose(KJS::ExecState *exec, const KJS::List& args);
 
     // properties
--- branches/work/kst/1.6/kst/src/extensions/js/bind_plugin.cpp #759558:759559
@@ -17,6 +17,8 @@
 
 #include "bind_plugin.h"
 #include "bind_pluginmodule.h"
+#include "bind_scalar.h"
+#include "bind_string.h"
 
 #include <kstdatacollection.h>
 
@@ -95,7 +97,9 @@
 };
 
 
-static PluginBindings pluginBindings[] = {
+static PluginBindings pluginBindings[] = {\
+  { "validate", &KstBindPlugin::validate },
+  { "setInput", &KstBindPlugin::setInput },
   { 0L, 0L }
 };
 
@@ -206,6 +210,156 @@
 
 #define makePlugin(X) dynamic_cast<KstCPlugin*>(const_cast<KstObject*>(X.data()))
 
+KJS::Value KstBindPlugin::validate(KJS::ExecState *exec, const KJS::List& args) {
+  if (args.size() != 0) {
+    KJS::Object eobj = KJS::Error::create(exec, KJS::SyntaxError);
+    exec->setException(eobj);
+    return KJS::Undefined();
+  }
+
+  KstCPluginPtr d = makePlugin(_d);
+  if (d) {
+    KstReadLocker rl(d);
+    if (d->validate()) {
+      return KJS::Boolean(true);
+    }
+  }
+
+  return KJS::Boolean(false);
+}
+
+
+KJS::Value KstBindPlugin::setInput(KJS::ExecState *exec, const KJS::List& args) {
+  if (args.size() != 2) {
+    KJS::Object eobj = KJS::Error::create(exec, KJS::SyntaxError);
+    exec->setException(eobj);
+    return KJS::Undefined();
+  }
+
+  KstCPluginPtr d = makePlugin(_d);
+  if (d) {
+    KstReadLocker rl(d);
+
+    if (!d->plugin()) {
+      KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Plugin module must be set first.");
+      exec->setException(eobj);
+      return KJS::Undefined();
+    }
+
+    QString input;
+    unsigned int index;
+
+    if (args[0].type() == KJS::NumberType) {
+      index = args[0].toUInt32(exec);
+      if (index < d->plugin()->data()._inputs.size()) {
+        input = d->plugin()->data()._inputs[index]._name;
+      } else {
+        KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Index is out of range.");
+        exec->setException(eobj);
+        return KJS::Undefined();
+      }
+    } else if (args[0].type() == KJS::StringType) {
+      input = args[0].toString(exec).qstring();
+      for (index = 0; index < d->plugin()->data()._inputs.size(); ++index ) {
+        if (d->plugin()->data()._inputs[index]._name.compare(input) == 0) {
+          break;
+        }
+      }
+      if (index >= d->plugin()->data()._inputs.size()) {
+        KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Invalid argument name.");
+        exec->setException(eobj);
+        return KJS::Undefined();
+      }
+    } else {
+      KJS::Object eobj = KJS::Error::create(exec, KJS::TypeError);
+      exec->setException(eobj);
+      return KJS::Undefined();
+    }
+
+    if (!input.isEmpty()) {
+      if (index < d->plugin()->data()._inputs.size()) {
+        Plugin::Data::IOValue::ValueType type = d->plugin()->data()._inputs[index]._type;
+
+        //
+        // ensure that the argument is of the right type...
+        //
+        if (type == Plugin::Data::IOValue::TableType) {
+          KstVectorPtr vp = extractVector(exec, args[1]);
+          if (vp) {
+            d->inputVectors().insert(d->plugin()->data()._inputs[index]._name, vp);
+          } else {
+            KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Argument was not of the expected type.");
+            exec->setException(eobj);
+            return KJS::Undefined();
+          }
+        } else if (type == Plugin::Data::IOValue::StringType) {
+          KstStringPtr sp;
+
+          if (args[1].type() == KJS::ObjectType) {
+            KstBindString *imp = dynamic_cast<KstBindString*>(args[1].toObject(exec).imp());
+            if (imp) {
+              sp = kst_cast<KstString>(imp->_d);
+            }
+           } else if (args[1].type() ==  KJS::StringType) {
+            KST::stringList.lock().readLock();
+            sp = *KST::stringList.findTag(args[0].toString(exec).qstring());
+            KST::stringList.lock().unlock();
+          }
+
+          if (sp) {
+            d->inputStrings().insert(input, sp);
+          } else {
+            KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Argument was not of the expected type.");
+            exec->setException(eobj);
+            return KJS::Undefined();
+          }
+        } else if (type == Plugin::Data::IOValue::FloatType ||
+                   type == Plugin::Data::IOValue::PidType ) {
+          KstScalarPtr sp;
+
+          if (args[1].type() == KJS::ObjectType) {
+            KstBindScalar *imp = dynamic_cast<KstBindScalar*>(args[1].toObject(exec).imp());
+            if (imp) {
+              sp = kst_cast<KstScalar>(imp->_d);
+            }
+          } else if (args[1].type() == KJS::StringType) {
+            KST::scalarList.lock().readLock();
+            sp = *KST::scalarList.findTag(args[0].toString(exec).qstring());
+            KST::scalarList.lock().unlock();
+          }
+
+          if (sp) {
+            d->inputScalars().insert(input, sp);
+          } else {
+            KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Argument was not of the expected type.");
+            exec->setException(eobj);
+            return KJS::Undefined();
+          }
+        } else {
+          KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Argument was not of the expected type.");
+          exec->setException(eobj);
+          return KJS::Undefined();
+        }
+      } else {
+        KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Argument was not of the expected type.");
+        exec->setException(eobj);
+        return KJS::Undefined();
+      }
+    } else {
+      KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Argument was not of the expected type.");
+      exec->setException(eobj);
+      return KJS::Undefined();
+    }
+  } else {
+    KJS::Object eobj = KJS::Error::create(exec, KJS::SyntaxError);
+    exec->setException(eobj);
+    return KJS::Undefined();
+  }
+
+  return KJS::Boolean(true);
+}
+
+
 KJS::Value KstBindPlugin::module(KJS::ExecState *exec) const {
   KstCPluginPtr d = makePlugin(_d);
   if (d) {
@@ -229,7 +383,7 @@
     KstCPluginPtr d = makePlugin(_d);
     if (d) {
       KstWriteLocker wl(d);
-      d->setPlugin(m);
+      d->setModule(m);
 
       if (!d->plugin()) {
         KJS::Object eobj = KJS::Error::create(exec, KJS::GeneralError, "Failed to set module");
--- branches/work/kst/1.6/kst/src/extensions/js/bind_plugin.h #759558:759559
@@ -53,18 +53,32 @@
 
     // member functions
 
+    /* @method setInput
+       @arg index or name of the input argument to be set.
+       @arg input argument.
+       @description Sets the input argument at the specified index or name.
+    */
+    KJS::Value setInput(KJS::ExecState *exec, const KJS::List& args);
+
+    /* @method validate
+       @description Validates the plugin.
+    */
+    KJS::Value validate(KJS::ExecState *exec, const KJS::List& args);
+
     /* @property PluginModule module
        @description The library or module that is used for data processing by
                     this plugin object.
      */
     void setModule(KJS::ExecState *exec, const KJS::Value& value);
     KJS::Value module(KJS::ExecState *exec) const;
+
     /* @property string lastError
        @description A string containing details of the last error that
                     occurred while running the plugin.
        @readonly
      */
     KJS::Value lastError(KJS::ExecState *exec) const;
+
     /* @property boolean valid
        @description True if this plugin object is valid.  If false, there is
                     probably an invalid setting somewhere that needs to be
--- branches/work/kst/1.6/kst/src/libkst/kstdatasource.cpp #759558:759559
@@ -57,7 +57,7 @@
 
 static QString obtainFile(const QString& source) {
   KURL url;
-  
+
   if (QFile::exists(source) && QFileInfo(source).isRelative()) {
     url.setPath(source);
   } else {
--- branches/work/kst/1.6/kst/src/libkstmath/kstcplugin.cpp #759558:759559
@@ -158,14 +158,14 @@
   _outStrings = 0L;
 
   _inScalarCnt = 0;
+  _inStringCnt = 0;
+  _inArrayCnt = 0;
   _outScalarCnt = 0;
-  _inArrayCnt = 0;
   _outArrayCnt = 0;
   _typeString = i18n("Plugin");
   _type = "Plugin";
   _plugin = 0L;
   _localData = 0L;
-  //kstdDebug() << "Creating KSTPlugin: " << long(this) << endl;
 }
 
 
@@ -177,7 +177,6 @@
     }
     _localData = 0L;
   }
-  //kstdDebug() << "Destroying KSTPlugin: " << long(this) << endl;
 }
 
 
@@ -524,10 +523,16 @@
 
 
 bool KstCPlugin::isValid() const {
-  return _inputVectors.count() == _inArrayCnt &&
+  bool rc = false;
+
+  if (_inArrayCnt > 0 || _inScalarCnt > 0 || _inStringCnt > 0) {
+    rc = _inputVectors.count() == _inArrayCnt &&
          _inputScalars.count() == _inScalarCnt - _inPid &&
          _inputStrings.count() == _inStringCnt &&
          _plugin.data() != 0L;
+  }
+
+  return rc;
 }
 
 
@@ -546,7 +551,96 @@
   return str;
 }
 
+//
+// to be used only from javaScript...
+//
+bool KstCPlugin::validate( ) {
+  bool rc = false;
 
+  if (_plugin) {
+    if (_plugin.data()) {
+      Plugin::countScalarsVectorsAndStrings(_plugin->data()._inputs, _inScalarCnt, _inArrayCnt, _inStringCnt, _inPid);
+      if (_inArrayCnt > 0 || _inScalarCnt > 0 || _inStringCnt > 0) {
+        if (_inputVectors.count() == _inArrayCnt &&
+          _inputScalars.count() == _inScalarCnt - _inPid &&
+          _inputStrings.count() == _inStringCnt) {
+
+          _outScalarCnt = 0;
+          _outArrayCnt = 0;
+          _outStringCnt = 0;
+          _outputVectors.clear();
+          _outputScalars.clear();
+          _outputStrings.clear();
+
+          const QValueList<Plugin::Data::IOValue>& otable = _plugin->data()._outputs;
+          for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin(); it != otable.end(); ++it) {
+            if ((*it)._type == Plugin::Data::IOValue::TableType) {
+              KstWriteLocker blockVectorUpdates(&KST::vectorList.lock());
+              KstVectorPtr v;
+
+              if ((*it)._subType == Plugin::Data::IOValue::FloatNonVectorSubType) {
+                v = new KstVector(KstObjectTag((*it)._name, tag()), 0, this, true);
+              } else {
+                v = new KstVector(KstObjectTag((*it)._name, tag()), 0, this, false);
+              }
+              _outputVectors.insert((*it)._name, v);
+              ++_outArrayCnt;
+            } else if ((*it)._type == Plugin::Data::IOValue::FloatType) {
+              KstWriteLocker blockScalarUpdates(&KST::scalarList.lock());
+              KstScalarPtr s = new KstScalar(KstObjectTag((*it)._name, tag()), this);
+              _outputScalars.insert((*it)._name, s);
+              ++_outScalarCnt;
+            } else if ((*it)._type == Plugin::Data::IOValue::StringType) {
+              KstWriteLocker blockStringUpdates(&KST::stringList.lock());
+              KstStringPtr s = new KstString(KstObjectTag((*it)._name, tag()), this);
+              _outputStrings.insert((*it)._name, s);
+              ++_outStringCnt;
+            }
+          }
+
+          allocateParameters();
+
+          rc = true;
+        }
+      }
+    }
+  }
+
+  return rc;
+}
+
+
+//
+// to be used only from javaScript...
+//
+bool KstCPlugin::setModule(KstSharedPtr<Plugin> plugin) {
+  // Assumes that this is called with a write lock in place on this object
+  Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED);
+
+  if (plugin != _plugin) {
+    freeParameters();
+
+    if (_localData) {
+      if (!_plugin || !_plugin->freeLocalData(&_localData)) {
+        free(_localData);
+      }
+      _localData = 0L;
+    }
+
+    _inputVectors.clear();
+    _inputScalars.clear();
+    _inputStrings.clear();
+    _outputVectors.clear();
+    _outputScalars.clear();
+    _outputStrings.clear();
+
+    _plugin = plugin;
+  }
+
+  return true;
+}
+
+
 bool KstCPlugin::setPlugin(KstSharedPtr<Plugin> plugin) {
   // Assumes that this is called with a write lock in place on this object
   Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED);
@@ -592,9 +686,7 @@
   _outputStrings.clear();
 
   const QValueList<Plugin::Data::IOValue>& otable = plugin->data()._outputs;
-  for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin();
-                                                         it != otable.end();
-                                                                        ++it) {
+  for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin(); it != otable.end(); ++it) {
     if ((*it)._type == Plugin::Data::IOValue::TableType) {
       KstWriteLocker blockVectorUpdates(&KST::vectorList.lock());
       KstVectorPtr v;
--- branches/work/kst/1.6/kst/src/libkstmath/kstcplugin.h #759558:759559
@@ -41,6 +41,8 @@
     virtual bool slaveVectorsUsed() const;
     virtual bool isValid() const;
 
+    virtual bool validate();
+    virtual bool setModule(KstSharedPtr<Plugin> plugin);
     virtual bool setPlugin(KstSharedPtr<Plugin> plugin);
     KstSharedPtr<Plugin> plugin() const;
 
@@ -52,8 +54,6 @@
     QString lastError() const;
 
     virtual Kind kind() const;
-
-    // FIXME: remove this
     void createFitScalars();
 
     virtual KstDataObjectPtr makeDuplicate(KstDataObjectDataObjectMap& duplicatedMap);
--- branches/work/kst/1.6/kst/src/libkstmath/plugin.cpp #759558:759559
@@ -131,7 +131,7 @@
   if (parameter.isEmpty()) {
     parameter = i18n("Param%1").arg(idx);
   }
-  
+
   return parameter;
 }
 


More information about the Kst mailing list