[dss-commits] r8763 - in dss/trunk: core core/sim data tests

dss-commits at forum.digitalstrom.org dss-commits at forum.digitalstrom.org
Tue Sep 15 18:15:02 CEST 2009


Author: pstaehlin
Date: 2009-09-15 18:15:02 +0200 (Tue, 15 Sep 2009)
New Revision: 8763

Added:
   dss/trunk/core/sim/dsid_js.cpp
   dss/trunk/core/sim/dsid_js.h
   dss/trunk/core/sim/dsid_plugin.cpp
   dss/trunk/core/sim/dsid_plugin.h
   dss/trunk/data/simulated_device.js
Modified:
   dss/trunk/core/jshandler.cpp
   dss/trunk/core/jshandler.h
   dss/trunk/core/sim/dssim.cpp
   dss/trunk/data/config.xml
   dss/trunk/tests/jshandlertests.cpp
Log:
- Use Logger to implement print in javascript
- Support for calling functions on ScriptObject
- Moved plugin implementation out of core/sim/dssim.cpp
- Support for implementing simulated devices in javascript


Modified: dss/trunk/core/jshandler.cpp
===================================================================
--- dss/trunk/core/jshandler.cpp	2009-09-15 07:49:05 UTC (rev 8762)
+++ dss/trunk/core/jshandler.cpp	2009-09-15 16:15:02 UTC (rev 8763)
@@ -22,7 +22,10 @@
 #include "jshandler.h"
 
 #include <cstring>
+#include <sstream>
 
+#include "core/logger.h"
+
 namespace dss {
 
   //============================================= ScriptEnvironment
@@ -123,21 +126,23 @@
 
   JSBool global_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){
     if (argc < 1){
-      /* No arguments passed in, so do nothing. */
-      /* We still want to return JS_TRUE though, other wise an exception will be thrown by the engine. */
-      *rval = INT_TO_JSVAL(0); /* Send back a return value of 0. */
+      /* No arguments passed in, so do nothing.
+        We still want to return JS_TRUE though, other wise an exception will be
+        thrown by the engine. */
+      *rval = INT_TO_JSVAL(0);
     } else {
-      unsigned int i;
-      size_t amountWritten=0;
-      for (i=0; i<argc; i++){
-        JSString *val = JS_ValueToString(cx, argv[i]); /* Convert the value to a javascript std::string. */
-        char *str = JS_GetStringBytes(val); /* Then convert it to a C-style std::string. */
-        size_t length = JS_GetStringLength(val); /* Get the length of the std::string, # of chars. */
-        amountWritten = fwrite(str, sizeof(*str), length, stdout); /* write the std::string to stdout. */
+      std::stringstream sstream;
+      sstream << "JS: ";
+      for(unsigned int i = 0; i < argc; i++) {
+        JSString *val = JS_ValueToString(cx, argv[i]);
+        char *str = JS_GetStringBytes(val);
+        size_t length = JS_GetStringLength(val);
+        std::string stdStr(str, length);
+        sstream << stdStr;
       }
-      *rval = INT_TO_JSVAL(amountWritten); /* Set the return value to be the number of bytes/chars written */
+      *rval = BOOLEAN_TO_JSVAL(true);
+      Logger::getInstance()->log(sstream.str());
     }
-    fwrite("\n", 1, 1, stdout);
     return JS_TRUE;
   }
 
@@ -362,8 +367,50 @@
     return convertTo<bool>(evaluateScript<jsval>(_script));
   } // evaluateScript<bool>
 
+
   //================================================== ScriptExtension
 
+
+  //================================================== ScriptFunctionParameterList
+
+  template<>
+  void ScriptFunctionParameterList::add(jsval _value) {
+    m_Parameter.push_back(_value);
+  } // add<jsval>
+
+  template<>
+  void ScriptFunctionParameterList::add(int _value) {
+    m_Parameter.push_back(INT_TO_JSVAL(_value));
+  } // add<int>
+
+  template<>
+  void ScriptFunctionParameterList::add(unsigned short _value) {
+    m_Parameter.push_back(INT_TO_JSVAL(_value));
+  } // add<unsigned short>
+
+  template<>
+  void ScriptFunctionParameterList::add(double _value) {
+    m_Parameter.push_back(DOUBLE_TO_JSVAL(_value));
+  } // add<double>
+
+  template<>
+  void ScriptFunctionParameterList::add(bool _value) {
+    m_Parameter.push_back(BOOLEAN_TO_JSVAL(_value));
+  } // add<bool>
+
+  template<>
+  void ScriptFunctionParameterList::add(const std::string& _value) {
+    JSString* str = JS_NewStringCopyN(m_Context.getJSContext(), _value.c_str(), _value.size());
+    m_Parameter.push_back(STRING_TO_JSVAL(str));
+  } // add<const std::string&>
+
+  template<>
+  void ScriptFunctionParameterList::add(std::string _value) {
+    JSString* str = JS_NewStringCopyN(m_Context.getJSContext(), _value.c_str(), _value.size());
+    m_Parameter.push_back(STRING_TO_JSVAL(str));
+  } // add<std::string&>
+
+
   //================================================== ScriptObject
 
   ScriptObject::ScriptObject(JSObject* _pObject, ScriptContext& _context)
@@ -415,6 +462,18 @@
   } // getProperty<string>
 
   template<>
+  double ScriptObject::getProperty(const std::string& _name) {
+    jsval value = getProperty<jsval>(_name);
+    return m_Context.convertTo<double>(value);
+  } // getProperty<double>
+
+  template<>
+  bool ScriptObject::getProperty(const std::string& _name) {
+    jsval value = getProperty<jsval>(_name);
+    return m_Context.convertTo<bool>(value);
+  } // getProperty<bool>
+
+  template<>
   void ScriptObject::setProperty(const std::string& _name, jsval _value) {
     JS_SetProperty(m_Context.getJSContext(), m_pObject, _name.c_str(), &_value);
   } // setProperty<jsval>
@@ -454,4 +513,53 @@
     return getProperty<std::string>("className");
   } // getClassName
 
-}
+  template<>
+  jsval ScriptObject::callFunctionByName<jsval>(const std::string& _functionName,
+                                                ScriptFunctionParameterList& _parameter) {
+    int paramc = _parameter.size();
+    jsval* paramv = (jsval*)malloc(sizeof(jsval) * paramc);
+    for(int iParam = 0; iParam < paramc; iParam++) {
+      paramv[iParam] = _parameter.get(iParam);
+    }
+    jsval rval;
+    JSBool ok = JS_CallFunctionName(m_Context.getJSContext(), m_pObject, _functionName.c_str(), paramc, paramv, &rval);
+    free(paramv);
+    if(ok) {
+      return rval;
+    } else {
+      m_Context.raisePendingExceptions();
+      throw ScriptException("Error running function");
+    }
+  } // callFunctionByName<jsval>
+
+  template<>
+  void ScriptObject::callFunctionByName(const std::string& _functionName,
+                                                ScriptFunctionParameterList& _parameter) {
+    callFunctionByName<jsval>(_functionName, _parameter);
+  } // callFunctionByName<void>
+
+  template<>
+  int ScriptObject::callFunctionByName(const std::string& _functionName,
+                                                ScriptFunctionParameterList& _parameter) {
+    return m_Context.convertTo<int>(callFunctionByName<jsval>(_functionName, _parameter));
+  } // callFunctionByName<int>
+
+  template<>
+  double ScriptObject::callFunctionByName(const std::string& _functionName,
+                                                ScriptFunctionParameterList& _parameter) {
+    return m_Context.convertTo<double>(callFunctionByName<jsval>(_functionName, _parameter));
+  } // callFunctionByName<double>
+
+  template<>
+  bool ScriptObject::callFunctionByName(const std::string& _functionName,
+                                                ScriptFunctionParameterList& _parameter) {
+    return m_Context.convertTo<bool>(callFunctionByName<jsval>(_functionName, _parameter));
+  } // callFunctionByName<bool>
+
+  template<>
+  std::string ScriptObject::callFunctionByName(const std::string& _functionName,
+                                                ScriptFunctionParameterList& _parameter) {
+    return m_Context.convertTo<std::string>(callFunctionByName<jsval>(_functionName, _parameter));
+  } // callFunctionByName<std::string>
+
+} // namespace dss

Modified: dss/trunk/core/jshandler.h
===================================================================
--- dss/trunk/core/jshandler.h	2009-09-15 07:49:05 UTC (rev 8762)
+++ dss/trunk/core/jshandler.h	2009-09-15 16:15:02 UTC (rev 8763)
@@ -83,7 +83,6 @@
     ScriptEnvironment& m_Environment;
     JSContext* m_pContext;
     static void jsErrorHandler(JSContext *ctx, const char *msg, JSErrorReport *er);
-    bool raisePendingExceptions();
   public:
     ScriptContext(ScriptEnvironment& _env, JSContext* _pContext);
     virtual ~ScriptContext();
@@ -116,6 +115,7 @@
     const ScriptEnvironment& getEnvironment() const { return m_Environment; }
     ScriptEnvironment& getEnvironment() { return m_Environment; }
     ScriptObject& getRootObject() { return *m_RootObject; }
+    bool raisePendingExceptions();
   public:
 
     /** Helper function to convert a jsval to a t. */
@@ -171,6 +171,22 @@
   }; // ScriptExtension
 
 
+  class ScriptFunctionParameterList {
+  public:
+    ScriptFunctionParameterList(ScriptContext& _context)
+    : m_Context(_context)
+    {} // ctor
+
+    template<class t>
+    void add(t _value);
+
+    int size() { return m_Parameter.size(); }
+    jsval get(const int _index) { return m_Parameter.at(_index); }
+  private:
+    ScriptContext& m_Context;
+    std::vector<jsval> m_Parameter;
+  }; // ScriptFunctionParameterList
+
   /** A ScriptObject is a wrapper for a JavaScript object. */
   class ScriptObject {
   private:
@@ -196,6 +212,9 @@
     /** Sets the property named \a _name to \a _value */
     template<class t>
     void setProperty(const std::string& _name, t _value);
+
+    template<class t>
+    t callFunctionByName(const std::string& _functionName, ScriptFunctionParameterList& _parameter);
   }; // ScriptObject
 
 } // namespace dss

Added: dss/trunk/core/sim/dsid_js.cpp
===================================================================
--- dss/trunk/core/sim/dsid_js.cpp	                        (rev 0)
+++ dss/trunk/core/sim/dsid_js.cpp	2009-09-15 16:15:02 UTC (rev 8763)
@@ -0,0 +1,279 @@
+/*
+    Copyright (c) 2009 digitalSTROM.org, Zurich, Switzerland
+    Copyright (c) 2009 futureLAB AG, Winterthur, Switzerland
+
+    This file is part of digitalSTROM Server.
+
+    digitalSTROM Server is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    digitalSTROM Server is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with digitalSTROM Server. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "dsid_js.h"
+#include "core/jshandler.h"
+
+namespace dss {
+
+  class DSIDJS : public DSIDInterface {
+  public:
+    DSIDJS(const DSModulatorSim& _simulator, dsid_t _dsid,
+           devid_t _shortAddress, boost::shared_ptr<ScriptContext> _pContext)
+    : DSIDInterface(_simulator, _dsid, _shortAddress),
+      m_pContext(_pContext)
+    {}
+
+    virtual ~DSIDJS() {}
+
+    virtual void initialize() {
+      try {
+        jsval res = m_pContext->evaluate<jsval>();
+        if(JSVAL_IS_OBJECT(res)) {
+          m_pJSThis = JSVAL_TO_OBJECT(res);
+          m_pSelf.reset(new ScriptObject(m_pJSThis, *m_pContext));
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(getDSID().toString());
+          param.add(getShortAddress());
+          param.add(getZoneID());
+          try {
+            m_pSelf->callFunctionByName<void>("initialize", param);
+          } catch(ScriptException& e) {
+            Logger::getInstance()->log(std::string("DSIDJS: Error calling 'initialize'") + e.what(), lsError);
+          }
+        }
+      } catch(ScriptException& e) {
+        Logger::getInstance()->log("DSIDJS: Could not get 'self' object");
+      }
+    }
+
+    virtual void callScene(const int _sceneNr) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(_sceneNr);
+          m_pSelf->callFunctionByName<void>("callScene", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'callScene'") + e.what(), lsError);
+        }
+      }
+    } // callScene
+
+    virtual void saveScene(const int _sceneNr) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(_sceneNr);
+          m_pSelf->callFunctionByName<void>("saveScene", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'saveScene'") + e.what(), lsError);
+        }
+      }
+    } // saveScene
+
+    virtual void undoScene(const int _sceneNr) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(_sceneNr);
+          m_pSelf->callFunctionByName<void>("undoScene", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'undoScene'") + e.what(), lsError);
+        }
+      }
+    } // undoScene
+
+    virtual void increaseValue(const int _parameterNr = -1) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          m_pSelf->callFunctionByName<void>("increaseValue", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'increaseValue'") + e.what(), lsError);
+        }
+      }
+    } // increaseValue
+
+    virtual void decreaseValue(const int _parameterNr = -1) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          m_pSelf->callFunctionByName<void>("decreaseValue", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'decreaseValue'") + e.what(), lsError);
+        }
+      }
+    } // decreaseValue
+
+    virtual void enable() {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          m_pSelf->callFunctionByName<void>("enable", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'enable'") + e.what(), lsError);
+        }
+      }
+    } // enable
+
+    virtual void disable() {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          m_pSelf->callFunctionByName<void>("disable", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'disable'") + e.what(), lsError);
+        }
+      }
+    } // disable
+
+    virtual int getConsumption() {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          return m_pSelf->callFunctionByName<int>("getConsumption", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'getConsumption'") + e.what(), lsError);
+        }
+      }
+      return 0;
+    } // getConsumption
+
+    virtual void startDim(bool _directionUp, const int _parameterNr = -1) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(_directionUp);
+          m_pSelf->callFunctionByName<void>("startDim", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'startDim'") + e.what(), lsError);
+        }
+      }
+    } // startDim
+
+    virtual void endDim(const int _parameterNr = -1) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          m_pSelf->callFunctionByName<void>("endDim", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'endDim'") + e.what(), lsError);
+        }
+      }
+    } // endDim
+
+    virtual void setValue(const double _value, int _parameterNr = -1) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(int(_value));
+          param.add(_parameterNr);
+          m_pSelf->callFunctionByName<void>("setValue", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'setValue'") + e.what(), lsError);
+        }
+      }
+    } // setValue
+
+    virtual double getValue(int _parameterNr = -1) const {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(_parameterNr);
+          return m_pSelf->callFunctionByName<int>("getValue", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'getValue'") + e.what(), lsError);
+        }
+      }
+      return 0;
+    } // getValue
+
+    virtual uint16_t getFunctionID() {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          m_pSelf->callFunctionByName<int>("getFunctionID", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'getFunctionID'") + e.what(), lsError);
+        }
+      }
+      return 0;
+    } // getFunctionID
+
+    virtual void setConfigParameter(const string& _name, const string& _value) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(_name);
+          param.add(_value);
+          m_pSelf->callFunctionByName<void>("setConfigParameter", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'setConfigParameter'") + e.what(), lsError);
+        }
+      }
+    } // setConfigParameter
+
+    virtual string getConfigParameter(const string& _name) const {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(_name);
+          return m_pSelf->callFunctionByName<std::string>("getConfigParameter", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'getConfigParameter'") + e.what(), lsError);
+        }
+      }
+      return "";
+    } // getConfigParameter
+
+    virtual uint8_t dsLinkSend(uint8_t _value, uint8_t _flags) {
+      if(m_pSelf != NULL) {
+        try {
+          ScriptFunctionParameterList param(*m_pContext);
+          param.add(int(_value));
+          param.add(int(_flags));
+          return m_pSelf->callFunctionByName<int>("dSLinkSend", param);
+        } catch(ScriptException& e) {
+          Logger::getInstance()->log(std::string("DSIDJS: Error calling 'dSLinkSend'") + e.what(), lsError);
+        }
+      }
+      return 0;
+    } // dsLinkSend
+  private:
+    boost::shared_ptr<ScriptContext> m_pContext;
+    JSObject* m_pJSThis;
+    boost::shared_ptr<ScriptObject> m_pSelf;
+  }; // DSIDJS
+
+
+  //================================================== DSIDJSCreator
+
+  DSIDJSCreator::DSIDJSCreator(const std::string& _fileName, const std::string& _pluginName)
+  : DSIDCreator(_pluginName),
+    m_pScriptEnvironment(new ScriptEnvironment()),
+    m_FileName(_fileName)
+  {
+    m_pScriptEnvironment->initialize();
+  } // ctor
+
+  DSIDInterface* DSIDJSCreator::createDSID(const dsid_t _dsid, const devid_t _shortAddress, const DSModulatorSim& _modulator) {
+    boost::shared_ptr<ScriptContext> pContext(m_pScriptEnvironment->getContext());
+    try {
+      pContext->loadFromFile(m_FileName);
+    } catch(ScriptException& e) {
+      Logger::getInstance()->log("DSIDJSCreator: Could not parse file: " + m_FileName + "(" + e.what() + ")", lsError);
+    }
+    DSIDJS* result = new DSIDJS(_modulator, _dsid, _shortAddress, pContext);
+    return result;
+  } // createDSID
+
+
+} // namespace dss

Added: dss/trunk/core/sim/dsid_js.h
===================================================================
--- dss/trunk/core/sim/dsid_js.h	                        (rev 0)
+++ dss/trunk/core/sim/dsid_js.h	2009-09-15 16:15:02 UTC (rev 8763)
@@ -0,0 +1,45 @@
+/*
+    Copyright (c) 2009 digitalSTROM.org, Zurich, Switzerland
+    Copyright (c) 2009 futureLAB AG, Winterthur, Switzerland
+
+    This file is part of digitalSTROM Server.
+
+    digitalSTROM Server is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    digitalSTROM Server is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with digitalSTROM Server. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DSSIMJS_H_
+#define DSSIMJS_H_
+
+#include <string>
+
+#include <boost/scoped_ptr.hpp>
+
+#include "dssim.h"
+#include "core/jshandler.h"
+
+namespace dss {
+
+  class DSIDJSCreator : public DSIDCreator {
+  public:
+    DSIDJSCreator(const std::string& _fileName, const std::string& _pluginName);
+    virtual DSIDInterface* createDSID(const dsid_t _dsid, const devid_t _shortAddress, const DSModulatorSim& _modulator);
+  private:
+    boost::scoped_ptr<ScriptEnvironment> m_pScriptEnvironment;
+    std::string m_FileName;
+  }; // DSIDPluginCreator
+
+}
+
+#endif /* DSSIMJS_H_ */

Added: dss/trunk/core/sim/dsid_plugin.cpp
===================================================================
--- dss/trunk/core/sim/dsid_plugin.cpp	                        (rev 0)
+++ dss/trunk/core/sim/dsid_plugin.cpp	2009-09-15 16:15:02 UTC (rev 8763)
@@ -0,0 +1,184 @@
+/*
+    Copyright (c) 2009 digitalSTROM.org, Zurich, Switzerland
+    Copyright (c) 2009 futureLAB AG, Winterthur, Switzerland
+
+    This file is part of digitalSTROM Server.
+
+    digitalSTROM Server is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    digitalSTROM Server is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with digitalSTROM Server. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "dsid_plugin.h"
+
+#include <dlfcn.h>
+
+#include "include/dsid_plugin.h"
+
+namespace dss {
+
+  //================================================== DSIDPlugin
+
+  class DSIDPlugin : public DSIDInterface {
+  private:
+    void* m_SOHandle;
+    const int m_Handle;
+    struct dsid_interface* m_Interface;
+  public:
+    DSIDPlugin(const DSModulatorSim& _simulator, const dsid_t _dsid, const devid_t _shortAddress, void* _soHandle, const int _handle)
+    : DSIDInterface(_simulator, _dsid, _shortAddress),
+      m_SOHandle(_soHandle),
+      m_Handle(_handle)
+    {
+      struct dsid_interface* (*get_interface)();
+      *(void**)(&get_interface) = dlsym(m_SOHandle, "dsid_get_interface");
+      char* error;
+      if((error = dlerror()) != NULL) {
+        Logger::getInstance()->log("sim: error getting interface");
+      }
+
+      m_Interface = (*get_interface)();
+      if(m_Interface == NULL) {
+        Logger::getInstance()->log("sim: got a null interface");
+      }
+    }
+
+    virtual int getConsumption() {
+      return 0;
+    }
+
+    virtual void callScene(const int _sceneNr) {
+      if(m_Interface->call_scene != NULL) {
+        (*m_Interface->call_scene)(m_Handle, _sceneNr);
+      }
+    }
+
+    virtual void saveScene(const int _sceneNr) {
+      if(m_Interface->save_scene != NULL) {
+        (*m_Interface->save_scene)(m_Handle, _sceneNr);
+      }
+    }
+
+    virtual void undoScene(const int _sceneNr) {
+      if(m_Interface->undo_scene != NULL) {
+        (*m_Interface->undo_scene)(m_Handle, _sceneNr);
+      }
+    }
+
+    virtual void increaseValue(const int _parameterNr = -1) {
+      if(m_Interface->increase_value != NULL) {
+        (*m_Interface->increase_value)(m_Handle, _parameterNr);
+      }
+    }
+
+    virtual void decreaseValue(const int _parameterNr = -1) {
+      if(m_Interface->decrease_value != NULL) {
+        (*m_Interface->decrease_value)(m_Handle, _parameterNr);
+      }
+    }
+
+    virtual void enable() {
+      if(m_Interface->enable != NULL) {
+        (*m_Interface->enable)(m_Handle);
+      }
+    }
+
+    virtual void disable() {
+      if(m_Interface->disable != NULL) {
+        (*m_Interface->disable)(m_Handle);
+      }
+    }
+
+    virtual void startDim(bool _directionUp, const int _parameterNr = -1) {
+      if(m_Interface->start_dim != NULL) {
+        (*m_Interface->start_dim)(m_Handle, _directionUp, _parameterNr);
+      }
+    }
+
+    virtual void endDim(const int _parameterNr = -1) {
+      if(m_Interface->end_dim != NULL) {
+        (*m_Interface->end_dim)(m_Handle, _parameterNr);
+      }
+    }
+
+    virtual void setValue(const double _value, int _parameterNr = -1) {
+      if(m_Interface->set_value != NULL) {
+        (*m_Interface->set_value)(m_Handle, _parameterNr, _value);
+      }
+    }
+
+    virtual double getValue(int _parameterNr = -1) const {
+      if(m_Interface->get_value != NULL) {
+        return (*m_Interface->get_value)(m_Handle, _parameterNr);
+      } else {
+        return 0.0;
+      }
+    }
+
+    virtual uint16_t getFunctionID() {
+      if(m_Interface->get_function_id != NULL) {
+        return (m_Interface->get_function_id)(m_Handle);
+      }
+      return 0;
+    } // getFunctionID
+
+    virtual void setConfigParameter(const std::string& _name, const std::string& _value) {
+      if(m_Interface->set_configuration_parameter != NULL) {
+        (*m_Interface->set_configuration_parameter)(m_Handle, _name.c_str(), _value.c_str());
+      }
+    } // setConfigParameter
+
+    virtual std::string getConfigParameter(const std::string& _name) const {
+      if(m_Interface->get_configuration_parameter != NULL) {
+        const int bufferSize = 256;
+        char buffer[bufferSize];
+        memset(&buffer, '\0', bufferSize);
+        int len = (*m_Interface->get_configuration_parameter)(m_Handle, _name.c_str(), &buffer[0], bufferSize - 1);
+
+        if(len > 0 && len < bufferSize) {
+          buffer[len] = '\0';
+          return std::string(&buffer[0]);
+        }
+      }
+      return "";
+    } // getConfigParameter
+
+    virtual uint8_t dsLinkSend(uint8_t _value, uint8_t _flags) {
+      if(m_Interface->udi_send != NULL) {
+        return  (*m_Interface->udi_send)(m_Handle, _value, _flags);
+      }
+      return 0;
+    } // dsLinkSend
+
+  }; // DSIDPlugin
+
+
+  //================================================== DSIDPluginCreator
+
+  DSIDPluginCreator::DSIDPluginCreator(void* _soHandle, const char* _pluginName)
+  : DSIDCreator(_pluginName),
+    m_SOHandle(_soHandle)
+  {
+    *(void**)(&createInstance) = dlsym(m_SOHandle, "dsid_create_instance");
+    char* error;
+    if((error = dlerror()) != NULL) {
+      Logger::getInstance()->log("sim: error getting pointer to dsid_create_instance");
+    }
+  } // ctor
+
+  DSIDInterface* DSIDPluginCreator::createDSID(const dsid_t _dsid, const devid_t _shortAddress, const DSModulatorSim& _modulator) {
+    int handle = (*createInstance)();
+    return new DSIDPlugin(_modulator, _dsid, _shortAddress, m_SOHandle, handle);
+  } // createDSID
+
+} // namespace dss

Added: dss/trunk/core/sim/dsid_plugin.h
===================================================================
--- dss/trunk/core/sim/dsid_plugin.h	                        (rev 0)
+++ dss/trunk/core/sim/dsid_plugin.h	2009-09-15 16:15:02 UTC (rev 8763)
@@ -0,0 +1,41 @@
+/*
+    Copyright (c) 2009 digitalSTROM.org, Zurich, Switzerland
+    Copyright (c) 2009 futureLAB AG, Winterthur, Switzerland
+
+    This file is part of digitalSTROM Server.
+
+    digitalSTROM Server is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    digitalSTROM Server is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with digitalSTROM Server. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DSID_PLUGIN_H_INCLUDED
+#define DSID_PLUGIN_H_INCLUDED
+
+#include "dssim.h"
+
+namespace dss {
+
+  class DSIDPluginCreator : public DSIDCreator {
+  private:
+    void* m_SOHandle;
+    int (*createInstance)();
+  public:
+    DSIDPluginCreator(void* _soHandle, const char* _pluginName);
+
+    virtual DSIDInterface* createDSID(const dsid_t _dsid, const devid_t _shortAddress, const DSModulatorSim& _modulator);
+  }; // DSIDPluginCreator
+
+} // namespace dss
+
+#endif /* DSID_PLUGIN_H_INCLUDED */

Modified: dss/trunk/core/sim/dssim.cpp
===================================================================
--- dss/trunk/core/sim/dssim.cpp	2009-09-15 07:49:05 UTC (rev 8762)
+++ dss/trunk/core/sim/dssim.cpp	2009-09-15 16:15:02 UTC (rev 8763)
@@ -21,24 +21,27 @@
 
 #include "dssim.h"
 
+#include <dlfcn.h>
+
+#include <string>
+#include <stdexcept>
+#include <iostream>
+
+#include <boost/filesystem.hpp>
+
 #include "core/ds485const.h"
 #include "core/base.h"
 #include "core/logger.h"
-#include "include/dsid_plugin.h"
 #include "core/dss.h"
+#include "include/dsid_plugin.h"
 #include "core/DS485Interface.h"
 #include "core/foreach.h"
 #include "core/propertysystem.h"
 #include "external/slaves/sensornest.h"
+#include "dsid_js.h"
+#include "dsid_plugin.h"
 
-#include <dlfcn.h>
 
-#include <string>
-#include <stdexcept>
-#include <iostream>
-
-#include <boost/filesystem.hpp>
-
 namespace fs = boost::filesystem;
 
 namespace dss {
@@ -73,166 +76,6 @@
     }
   };
 
-  //================================================== DSIDPlugin
-
-  class DSIDPlugin : public DSIDInterface {
-  private:
-    void* m_SOHandle;
-    const int m_Handle;
-    struct dsid_interface* m_Interface;
-  public:
-    DSIDPlugin(const DSModulatorSim& _simulator, const dsid_t _dsid, const devid_t _shortAddress, void* _soHandle, const int _handle)
-    : DSIDInterface(_simulator, _dsid, _shortAddress),
-      m_SOHandle(_soHandle),
-      m_Handle(_handle)
-    {
-      struct dsid_interface* (*get_interface)();
-      *(void**)(&get_interface) = dlsym(m_SOHandle, "dsid_get_interface");
-      char* error;
-      if((error = dlerror()) != NULL) {
-        Logger::getInstance()->log("sim: error getting interface");
-      }
-
-      m_Interface = (*get_interface)();
-      if(m_Interface == NULL) {
-        Logger::getInstance()->log("sim: got a null interface");
-      }
-    }
-
-    virtual int getConsumption() {
-      return 0;
-    }
-
-    virtual void callScene(const int _sceneNr) {
-      if(m_Interface->call_scene != NULL) {
-        (*m_Interface->call_scene)(m_Handle, _sceneNr);
-      }
-    }
-
-    virtual void saveScene(const int _sceneNr) {
-      if(m_Interface->save_scene != NULL) {
-        (*m_Interface->save_scene)(m_Handle, _sceneNr);
-      }
-    }
-
-    virtual void undoScene(const int _sceneNr) {
-      if(m_Interface->undo_scene != NULL) {
-        (*m_Interface->undo_scene)(m_Handle, _sceneNr);
-      }
-    }
-
-    virtual void increaseValue(const int _parameterNr = -1) {
-      if(m_Interface->increase_value != NULL) {
-        (*m_Interface->increase_value)(m_Handle, _parameterNr);
-      }
-    }
-
-    virtual void decreaseValue(const int _parameterNr = -1) {
-      if(m_Interface->decrease_value != NULL) {
-        (*m_Interface->decrease_value)(m_Handle, _parameterNr);
-      }
-    }
-
-    virtual void enable() {
-      if(m_Interface->enable != NULL) {
-        (*m_Interface->enable)(m_Handle);
-      }
-    }
-
-    virtual void disable() {
-      if(m_Interface->disable != NULL) {
-        (*m_Interface->disable)(m_Handle);
-      }
-    }
-
-    virtual void startDim(bool _directionUp, const int _parameterNr = -1) {
-      if(m_Interface->start_dim != NULL) {
-        (*m_Interface->start_dim)(m_Handle, _directionUp, _parameterNr);
-      }
-    }
-
-    virtual void endDim(const int _parameterNr = -1) {
-      if(m_Interface->end_dim != NULL) {
-        (*m_Interface->end_dim)(m_Handle, _parameterNr);
-      }
-    }
-
-    virtual void setValue(const double _value, int _parameterNr = -1) {
-      if(m_Interface->set_value != NULL) {
-        (*m_Interface->set_value)(m_Handle, _parameterNr, _value);
-      }
-    }
-
-    virtual double getValue(int _parameterNr = -1) const {
-      if(m_Interface->get_value != NULL) {
-        return (*m_Interface->get_value)(m_Handle, _parameterNr);
-      } else {
-        return 0.0;
-      }
-    }
-
-    virtual uint16_t getFunctionID() {
-      if(m_Interface->get_function_id != NULL) {
-        return (m_Interface->get_function_id)(m_Handle);
-      }
-      return 0;
-    } // getFunctionID
-
-    virtual void setConfigParameter(const std::string& _name, const std::string& _value) {
-      if(m_Interface->set_configuration_parameter != NULL) {
-        (*m_Interface->set_configuration_parameter)(m_Handle, _name.c_str(), _value.c_str());
-      }
-    } // setConfigParameter
-
-    virtual std::string getConfigParameter(const std::string& _name) const {
-      if(m_Interface->get_configuration_parameter != NULL) {
-        const int bufferSize = 256;
-        char buffer[bufferSize];
-        memset(&buffer, '\0', bufferSize);
-        int len = (*m_Interface->get_configuration_parameter)(m_Handle, _name.c_str(), &buffer[0], bufferSize - 1);
-
-        if(len > 0 && len < bufferSize) {
-          buffer[len] = '\0';
-          return std::string(&buffer[0]);
-        }
-      }
-      return "";
-    } // getConfigParameter
-    
-    virtual uint8_t dsLinkSend(uint8_t _value, uint8_t _flags) {
-      if(m_Interface->udi_send != NULL) {
-        return  (*m_Interface->udi_send)(m_Handle, _value, _flags);
-      }
-      return 0;
-    } // dsLinkSend
-
-  }; // DSIDPlugin
-
-
-  //================================================== DSIDPluginCreator
-
-  class DSIDPluginCreator : public DSIDCreator {
-  private:
-    void* m_SOHandle;
-    int (*createInstance)();
-  public:
-    DSIDPluginCreator(void* _soHandle, const char* _pluginName)
-    : DSIDCreator(_pluginName),
-      m_SOHandle(_soHandle)
-    {
-      *(void**)(&createInstance) = dlsym(m_SOHandle, "dsid_create_instance");
-      char* error;
-      if((error = dlerror()) != NULL) {
-        Logger::getInstance()->log("sim: error getting pointer to dsid_create_instance");
-      }
-    }
-
-    virtual DSIDInterface* createDSID(const dsid_t _dsid, const devid_t _shortAddress, const DSModulatorSim& _modulator) {
-      int handle = (*createInstance)();
-      return new DSIDPlugin(_modulator, _dsid, _shortAddress, m_SOHandle, handle);
-    }
-  }; // DSIDPluginCreator
-
   //================================================== DSSim
 
   DSSim::DSSim(DSS* _pDSS)
@@ -245,16 +88,38 @@
     m_DSIDFactory.registerCreator(new DSIDSimSwitchCreator());
     m_DSIDFactory.registerCreator(new DSIDSimSensornestCreator());
 
+    PropertyNodePtr pNode = getDSS().getPropertySystem().getProperty(getConfigPropertyBasePath() + "js-devices");
+    if(pNode != NULL) {
+      for(int iNode = 0; iNode < pNode->getChildCount(); iNode++) {
+        PropertyNodePtr pChildNode = pNode->getChild(iNode);
+        PropertyNodePtr scriptFileNode = pChildNode->getPropertyByName("script-file");
+        PropertyNodePtr simIDNode = pChildNode->getPropertyByName("id");
+        if(scriptFileNode != NULL) {
+          if(simIDNode != NULL) {
+            std::string scriptFile = scriptFileNode->getAsString();
+            if(!fileExists(scriptFile)) {
+              log("DSSim::initialize: cannot find script file '" + scriptFile + "', skipping", lsError);
+              continue;
+            }
+            log("Found js-device with script '" + scriptFile + "' and id: '" + simIDNode->getAsString() + "'", lsInfo);
+            m_DSIDFactory.registerCreator(new DSIDJSCreator(scriptFile, simIDNode->getAsString()));
+          } else {
+            log("DSSim::initialize: Missing property id", lsError);
+          }
+        } else {
+          log("DSSim::initialize: Missing property script-file", lsError);
+        }
+      }
+    }
+
     getDSS().getPropertySystem().setStringValue(getConfigPropertyBasePath() + "configfile", getDSS().getDataDirectory() + "sim.xml", true, false);
 
-
     loadPlugins();
     loadFromConfig();
 
     m_Initialized = true;
   } // initialize
 
-
   void DSSim::loadFromConfig() {
     const int theConfigFileVersion = 1;
     std::string filename = getConfigPropertyBasePath() + "configfile";

Modified: dss/trunk/data/config.xml
===================================================================
--- dss/trunk/data/config.xml	2009-09-15 07:49:05 UTC (rev 8762)
+++ dss/trunk/data/config.xml	2009-09-15 16:15:02 UTC (rev 8763)
@@ -4,6 +4,16 @@
     <property name="subsystems/DS485Proxy/rs485devicename" type="string">
       <value>/dev/ttyUSB0</value>
     </property>
+    <property name="subsystems/DSSim/js-devices">
+      <property name="example">
+        <property name="script-file" type="string">
+          <value>data/simulated_device.js</value>
+        </property>
+        <property name="id" type="string">
+          <value>example.js-device</value>
+        </property>
+      </property>
+    </property>
  <!--
     <property name="sensornest/interface" type="string">
       <value>wlan0</value>
@@ -21,12 +31,14 @@
       <value>/mnt/webroot/</value>
     </property>
 -->    
-    <property name="subsystems/WebServer/plugins/testplugin/file" type="string">
-      <value>data/webplugins/webserver_plugin.so</value>
-    </property>
-    <property name="subsystems/WebServer/plugins/testplugin/uri" type="string">
-      <value>/test/*</value>
-    </property>
+    <property name="subsystems/WebServer/plugins/testplugin">
+      <property name="file" type="string">
+        <value>data/webplugins/webserver_plugin.so</value>
+      </property>
+      <property name="uri" type="string">
+        <value>/test/*</value>
+      </property>
+    </property>    
     <property name="subsystems/FakeMeter/enabled" type="boolean">
       <value>false</value>
     </property>

Added: dss/trunk/data/simulated_device.js
===================================================================
--- dss/trunk/data/simulated_device.js	                        (rev 0)
+++ dss/trunk/data/simulated_device.js	2009-09-15 16:15:02 UTC (rev 8763)
@@ -0,0 +1,69 @@
+var dev = {
+  initialize: function(dsid, shortaddress, zoneid) {
+    print('initializing js device', dsid, ' ', shortaddress, ' ', zoneid);
+  },
+
+  callScene: function(nr) {
+    print('called scene ', nr);
+  },
+
+  saveScene: function(nr) {
+    print('save scene ', nr);
+  },
+
+  undoScene: function(nr) {
+    print('undo scene');
+  },
+
+  increaseValue: function() {
+    print('increase value');
+  },
+
+  decreaseValue: function() {
+    print('decrease value');
+  },
+
+  enable: function() {
+    print('enable');
+  },
+
+  disable: function() {
+    print('disable');
+  },
+
+  getConsumption: function() {
+    print('getConsumption');
+    return 0;
+  },
+
+  startDim: function(direction) {
+    print('startDim ', direction);
+  },
+
+  endDim: function() {
+    print('endDim');
+  },
+
+  setValue: function(value) {
+    print('setValue ', value);
+  },
+
+  getValue: function() {
+    print('getValue');
+    return 0;
+  },
+
+  getFunctionID: function() {
+    print('getFunctionID');
+    return 0;
+  },
+
+  setConfigParameter: function(name, value) {
+    print('setConfigParameter ', name, '=', value);
+  },
+
+  getConfigParameter: function(name) {
+    print('getConfigParameter ', name);
+  }
+};
+dev;

Modified: dss/trunk/tests/jshandlertests.cpp
===================================================================
--- dss/trunk/tests/jshandlertests.cpp	2009-09-15 07:49:05 UTC (rev 8762)
+++ dss/trunk/tests/jshandlertests.cpp	2009-09-15 16:15:02 UTC (rev 8763)
@@ -51,4 +51,29 @@
   BOOST_CHECK_EQUAL(ctx->evaluateScript<std::string>("obj.testing2"), "test");
 } // testSimpleObject
 
+BOOST_AUTO_TEST_CASE(testCallingFunctions) {
+  boost::scoped_ptr<ScriptEnvironment> env(new ScriptEnvironment());
+  env->initialize();
+
+  boost::scoped_ptr<ScriptContext> ctx(env->getContext());
+  jsval res = ctx->evaluateScript<jsval>("dev = { func: function(a,b,c) { return { e: a, f: b, g: c }; } }; dev");
+
+  BOOST_ASSERT(JSVAL_IS_OBJECT(res));
+
+  ScriptObject obj(JSVAL_TO_OBJECT(res), *ctx);
+
+  ScriptFunctionParameterList list(*ctx);
+  list.add<const std::string&>(std::string("testing"));
+  list.add<int>(1);
+  list.add<bool>(false);
+
+  res = obj.callFunctionByName<jsval>("func", list);
+
+  BOOST_ASSERT(JSVAL_IS_OBJECT(res));
+  ScriptObject resObj(JSVAL_TO_OBJECT(res), *ctx);
+  BOOST_CHECK_EQUAL(resObj.getProperty<std::string>("e"), "testing");
+  BOOST_CHECK_EQUAL(resObj.getProperty<int>("f"), 1);
+  BOOST_CHECK_EQUAL(resObj.getProperty<bool>("g"), false);
+}
+
 BOOST_AUTO_TEST_SUITE_END()



More information about the dss-commits mailing list