[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