[dss-commits] r8808 - in dss/trunk: core core/scripting core/sim tests
dss-commits at forum.digitalstrom.org
dss-commits at forum.digitalstrom.org
Tue Sep 29 16:08:06 CEST 2009
Author: pstaehlin
Date: 2009-09-29 16:08:06 +0200 (Tue, 29 Sep 2009)
New Revision: 8808
Modified:
dss/trunk/core/eventinterpreterplugins.cpp
dss/trunk/core/jshandler.cpp
dss/trunk/core/jshandler.h
dss/trunk/core/scripting/modeljs.cpp
dss/trunk/core/scripting/modeljs.h
dss/trunk/core/sim/dsid_js.cpp
dss/trunk/tests/jshandlertests.cpp
dss/trunk/tests/modeljstests.cpp
dss/trunk/tests/scriptstest.cpp
Log:
Work on javascript integration:
* Fixed crash in PropertyListener => JS code
* Made evaluate execute a JS string and evaluateScript execute a script w/o precompiling it
* Raise simulated dSLinkInterrupt from own thread
* Store JS-PropertyListeners on the context to ensure they will be removed if the context gets invalid
Modified: dss/trunk/core/eventinterpreterplugins.cpp
===================================================================
--- dss/trunk/core/eventinterpreterplugins.cpp 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/core/eventinterpreterplugins.cpp 2009-09-29 14:08:06 UTC (rev 8808)
@@ -107,8 +107,7 @@
raisedEvent.setProperty("subscription", &subscriptionObj);
subscriptionObj.setProperty<const std::string&>("name", _subscription.getEventName());
- ctx->loadFromFile(scriptName);
- ctx->evaluate<void>();
+ ctx->evaluateScript<void>(scriptName);
if(ctx->getKeepContext()) {
m_KeptContexts.push_back(ctx);
Modified: dss/trunk/core/jshandler.cpp
===================================================================
--- dss/trunk/core/jshandler.cpp 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/core/jshandler.cpp 2009-09-29 14:08:06 UTC (rev 8808)
@@ -23,6 +23,8 @@
#include <cstring>
#include <sstream>
+#include <fstream>
+#include <iostream>
#include "core/logger.h"
@@ -60,7 +62,6 @@
JSContext* context = JS_NewContext(m_pRuntime, 8192);
ScriptContext* pResult = new ScriptContext(*this, context);
- JS_SetContextPrivate(context, pResult);
for(boost::ptr_vector<ScriptExtension>::iterator ipExtension = m_Extensions.begin(); ipExtension != m_Extensions.end(); ++ipExtension) {
ipExtension->extendContext(*pResult);
}
@@ -103,8 +104,7 @@
line = (char*)malloc(len);
strncpy(line, er->linebuf, len);
line[len-1] = '\0';
- }
- else {
+ } else {
len=0;
pointer = (char*)malloc(1);
line = (char*)malloc(1);
@@ -167,8 +167,7 @@
};
ScriptContext::ScriptContext(ScriptEnvironment& _env, JSContext* _pContext)
- : m_pScriptToExecute(NULL),
- m_Environment(_env),
+ : m_Environment(_env),
m_pContext(_pContext),
m_KeepContext(false)
{
@@ -190,54 +189,33 @@
throw ScriptException("InitStandardClasses failed");
}
+ JS_SetContextPrivate(m_pContext, this);
} // ctor
ScriptContext::~ScriptContext() {
+ scrubVector(m_AttachedObjects);
JS_SetContextPrivate(m_pContext, NULL);
-// JS_RemoveRoot(m_pContext, m_pSourceObject);
- if(m_pScriptToExecute != NULL) {
- JS_DestroyScript(m_pContext, m_pScriptToExecute);
- }
JS_DestroyContext(m_pContext);
+ m_pContext = NULL;
} // dtor
- void ScriptContext::loadFromFile(const std::string& _fileName) {
- if(m_pScriptToExecute != NULL) {
- JS_DestroyScript(m_pContext, m_pScriptToExecute);
- }
- m_FileName = _fileName;
- if(!fileExists(_fileName)) {
- throw ScriptException(std::string("File \"") + _fileName + "\" not found");
- }
+ void ScriptContext::attachObject(ScriptContextAttachedObject* _pObject) {
+ m_AttachedObjects.push_back(_pObject);
+ } // attachObject
- m_pScriptToExecute = JS_CompileFile(m_pContext, m_pRootObject, _fileName.c_str());
- if(m_pScriptToExecute == NULL) {
- throw ScriptException(std::string("Could not parse file \"") + _fileName + "\"");
+ void ScriptContext::removeAttachedObject(ScriptContextAttachedObject* _pObject) {
+ std::vector<ScriptContextAttachedObject*>::iterator it =
+ std::find(m_AttachedObjects.begin(), m_AttachedObjects.end(), _pObject);
+ if(it != m_AttachedObjects.end()) {
+ m_AttachedObjects.erase(it);
+ delete _pObject;
}
- /*
- // protect newly allocated script from garbage-collection
- m_pSourceObject = JS_NewScriptObject(m_pContext, m_pScriptToExecute);
- if (m_pSourceObject == NULL
- || !JS_AddNamedRoot(m_pContext, &m_pSourceObject, "scrobj")) {
- throw ScriptException("Could not add named root for script");
- }
- */
- } // loadFromFile
+ } // removeAttachedObject
- void ScriptContext::loadFromMemory(const char* _script) {
- if(m_pScriptToExecute != NULL) {
- JS_DestroyScript(m_pContext, m_pScriptToExecute);
- }
- m_pScriptToExecute = JS_CompileScript(m_pContext, m_pRootObject, _script, strlen(_script), "memory", 1);
- if(m_pScriptToExecute == NULL) {
- throw ScriptException(std::string("Could not parse in-memory script"));
- }
- } // loadFromMemory
-
template<>
jsval ScriptContext::convertTo(const jsval& _val) {
return _val;
- }
+ } // convertTo<jsval>
template<>
int ScriptContext::convertTo(const jsval& _val) {
@@ -298,48 +276,58 @@
}
return false;
} // raisePendingExceptions
-
+
template <>
- jsval ScriptContext::evaluate() {
+ jsval ScriptContext::evaluateScript(const std::string& _fileName) {
AssertLocked(this);
+
+ std::ifstream in(_fileName.c_str());
+ std::string line;
+ std::stringstream sstream;
+ while(std::getline(in,line)) {
+ sstream << line << "\n";
+ }
jsval rval;
- JSBool ok = JS_ExecuteScript(m_pContext, m_pRootObject, m_pScriptToExecute, &rval);
+ std::string script = sstream.str();
+ JSBool ok = JS_EvaluateScript(m_pContext, m_pRootObject, script.c_str(), script.size(),
+ _fileName.c_str(), 0, &rval);
if(ok) {
return rval;
} else {
raisePendingExceptions();
throw ScriptException("Error executing script");
}
- } // evaluate<jsval>
-
+ } // evaluateScript
+
template <>
- void ScriptContext::evaluate() {
- evaluate<jsval>();
- } // evaluate<void>
-
+ void ScriptContext::evaluateScript(const std::string& _script) {
+ evaluateScript<jsval>(_script);
+ } // evaluateScript<void>
+
template <>
- double ScriptContext::evaluate() {
- return convertTo<double>(evaluate<jsval>());
- } // evaluate<double>
+ int ScriptContext::evaluateScript(const std::string& _script) {
+ return convertTo<int>(evaluateScript<jsval>(_script));
+ } // evaluateScript<int>
template <>
- int ScriptContext::evaluate() {
- return convertTo<int>(evaluate<jsval>());
- } // evaluate<int>
+ double ScriptContext::evaluateScript(const std::string& _script) {
+ return convertTo<double>(evaluateScript<jsval>(_script));
+ } // evaluateScript<double>
template <>
- bool ScriptContext::evaluate() {
- return convertTo<bool>(evaluate<jsval>());
- } // evaluate<bool>
+ std::string ScriptContext::evaluateScript(const std::string& _script) {
+ return convertTo<std::string>(evaluateScript<jsval>(_script));
+ } // evaluateScript<std::string>
template <>
- std::string ScriptContext::evaluate() {
- return convertTo<std::string>(evaluate<jsval>());
- } // evaluate<string>
+ bool ScriptContext::evaluateScript(const std::string& _script) {
+ return convertTo<bool>(evaluateScript<jsval>(_script));
+ } // evaluateScript<bool>
template <>
- jsval ScriptContext::evaluateScript(const std::string& _script) {
+ jsval ScriptContext::evaluate(const std::string& _script) {
AssertLocked(this);
+
const char* filename = "temporary_script";
jsval rval;
JSBool ok = JS_EvaluateScript(m_pContext, m_pRootObject, _script.c_str(), _script.size(),
@@ -350,32 +338,32 @@
raisePendingExceptions();
throw ScriptException("Error executing script");
}
- } // evaluateScript
+ } // evaluate
template <>
- void ScriptContext::evaluateScript(const std::string& _script) {
- evaluateScript<jsval>(_script);
- } // evaluateScript<void>
+ void ScriptContext::evaluate(const std::string& _script) {
+ evaluate<jsval>(_script);
+ } // evaluate<void>
template <>
- int ScriptContext::evaluateScript(const std::string& _script) {
- return convertTo<int>(evaluateScript<jsval>(_script));
- } // evaluateScript<int>
+ int ScriptContext::evaluate(const std::string& _script) {
+ return convertTo<int>(evaluate<jsval>(_script));
+ } // evaluate<int>
template <>
- double ScriptContext::evaluateScript(const std::string& _script) {
- return convertTo<double>(evaluateScript<jsval>(_script));
- } // evaluateScript<double>
+ double ScriptContext::evaluate(const std::string& _script) {
+ return convertTo<double>(evaluate<jsval>(_script));
+ } // evaluate<double>
template <>
- std::string ScriptContext::evaluateScript(const std::string& _script) {
- return convertTo<std::string>(evaluateScript<jsval>(_script));
- } // evaluateScript<std::string>
+ std::string ScriptContext::evaluate(const std::string& _script) {
+ return convertTo<std::string>(evaluate<jsval>(_script));
+ } // evaluate<std::string>
template <>
- bool ScriptContext::evaluateScript(const std::string& _script) {
- return convertTo<bool>(evaluateScript<jsval>(_script));
- } // evaluateScript<bool>
+ bool ScriptContext::evaluate(const std::string& _script) {
+ return convertTo<bool>(evaluate<jsval>(_script));
+ } // evaluate<bool>
//================================================== ScriptExtension
Modified: dss/trunk/core/jshandler.h
===================================================================
--- dss/trunk/core/jshandler.h 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/core/jshandler.h 2009-09-29 14:08:06 UTC (rev 8808)
@@ -26,6 +26,10 @@
#include "config.h"
#endif
+#include <iostream>
+
+#define JS_THREADSAFE
+
#ifdef HAVE_MOZJS_JSAPI_H
#include <mozjs/jsapi.h>
#else
@@ -43,6 +47,7 @@
class ScriptContext;
class ScriptExtension;
class ScriptObject;
+ class ScriptContextAttachedObject;
/** Wrapper for a script runtime environment. The ScriptEnvironment
* is also responsible for creating Contexts and enhancing them with
@@ -76,40 +81,25 @@
* a std::string contained in memory. */
class ScriptContext : public LockableObject {
private:
- JSScript* m_pScriptToExecute;
std::string m_FileName;
JSObject* m_pRootObject;
boost::scoped_ptr<ScriptObject> m_RootObject;
- JSObject* m_pSourceObject;
ScriptEnvironment& m_Environment;
JSContext* m_pContext;
bool m_KeepContext;
+ std::vector<ScriptContextAttachedObject*> m_AttachedObjects;
static void jsErrorHandler(JSContext *ctx, const char *msg, JSErrorReport *er);
public:
ScriptContext(ScriptEnvironment& _env, JSContext* _pContext);
virtual ~ScriptContext();
- /** Loads the script from File
- * @throw runtime_error if _fileName does not exist
- * @throw ScriptException if there is something wrong with the script
- */
- void loadFromFile(const std::string& _fileName);
- /** Loads the script from Memory.
- * @throw ScriptException if there is something wrong with the script
- */
- void loadFromMemory(const char* _script);
-
- /** Evaluates the previously loaded script. The result of the script
- * will be casted to typeof t.
- * @throw ScriptRuntimeException if the script raised an exception
- * @throw SciptException
- */
+ /** Evaluates the given script */
template <class t>
- t evaluate();
+ t evaluate(const std::string& _script);
- /** Evaluates the given script */
+ /** Evaluates the given file */
template <class t>
- t evaluateScript(const std::string& _script);
+ t evaluateScript(const std::string& _fileName);
/** Returns a pointer to the JSContext */
JSContext* getJSContext() { return m_pContext; }
@@ -120,12 +110,15 @@
bool raisePendingExceptions();
bool getKeepContext() { return m_KeepContext; };
void setKeepContext(bool _value) { m_KeepContext = _value; }
+
+ void attachObject(ScriptContextAttachedObject* _pObject);
+ void removeAttachedObject(ScriptContextAttachedObject* _pObject);
public:
/** Helper function to convert a jsval to a t. */
template<class t>
t convertTo(const jsval& _val);
- };
+ }; // ScriptContext
/** Exception class that will be raised if anything out of the
* ordinary should happen. */
@@ -222,8 +215,15 @@
template<class t>
t callFunctionByReference(jsval _function, ScriptFunctionParameterList& _parameter);
-}; // ScriptObject
+ }; // ScriptObject
+ class ScriptContextAttachedObject {
+ public:
+ ~ScriptContextAttachedObject() {
+ std::cout << "destroying attached object" << std::endl;
+ }
+ }; // ScriptContextAttachedObject
+
} // namespace dss
#endif
Modified: dss/trunk/core/scripting/modeljs.cpp
===================================================================
--- dss/trunk/core/scripting/modeljs.cpp 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/core/scripting/modeljs.cpp 2009-09-29 14:08:06 UTC (rev 8808)
@@ -985,6 +985,8 @@
new PropertyScriptListener(ext, ctx, obj, argv[1], ident);
ext->addListener(listener);
node->addListener(listener);
+ ctx->attachObject(listener);
+
JSString* str = JS_NewStringCopyZ(cx, ident.c_str());
*rval = STRING_TO_JSVAL(str);
}
@@ -1034,14 +1036,15 @@
} // addListener
void PropertyScriptExtension::removeListener(const std::string& _identifier) {
- for(boost::ptr_vector<PropertyScriptListener>::iterator it = m_Listeners.begin(), e = m_Listeners.end();
+ for(std::vector<PropertyScriptListener*>::iterator it = m_Listeners.begin(), e = m_Listeners.end();
it != e; ++it) {
- if(it->getIdentifier() == _identifier) {
- it->unsubscribe();
+ if((*it)->getIdentifier() == _identifier) {
+ (*it)->unsubscribe();
+ m_Listeners.erase(it);
return;
}
}
- }
+ } // removeListener
//================================================== PropertyScriptListener
@@ -1056,8 +1059,15 @@
m_pFunctionObject(_functionObj),
m_Function(_function),
m_Identifier(_identifier)
- { } // ctor
+ {
+ JS_AddRoot(_pContext->getJSContext(), &m_Function);
+ } // ctor
+ PropertyScriptListener::~PropertyScriptListener() {
+ m_pExtension->removeListener(m_Identifier);
+ JS_RemoveRoot(m_pContext->getJSContext(), &m_Function);
+ } // dtor
+
void PropertyScriptListener::createScriptObject() {
if(m_pScriptObject == NULL) {
m_pScriptObject.reset(new ScriptObject(m_pFunctionObject, *m_pContext));
@@ -1076,10 +1086,15 @@
} // propertyAdded
void PropertyScriptListener::doOnChange(PropertyNodePtr _changedNode) {
+ AssertLocked locked(m_pContext);
createScriptObject();
ScriptFunctionParameterList list(*m_pContext);
list.add(_changedNode->getDisplayName());
- m_pScriptObject->callFunctionByReference<void>(m_Function, list);
+ try {
+ m_pScriptObject->callFunctionByReference<void>(m_Function, list);
+ } catch(ScriptRuntimeException& e) {
+ Logger::getInstance()->log("PropertyScriptListener::doOnChange: Caught exception while calling handler: " + std::string(e.what()), lsFatal);
+ }
} // doOnChange
} // namespace
Modified: dss/trunk/core/scripting/modeljs.h
===================================================================
--- dss/trunk/core/scripting/modeljs.h 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/core/scripting/modeljs.h 2009-09-29 14:08:06 UTC (rev 8808)
@@ -91,9 +91,11 @@
class PropertyNode;
class PropertyScriptExtension;
- class PropertyScriptListener : public PropertyListener {
+ class PropertyScriptListener : public PropertyListener,
+ public ScriptContextAttachedObject {
public:
PropertyScriptListener(PropertyScriptExtension* _pExtension, ScriptContext* _pContext, JSObject* _functionObj, jsval _function, const std::string& _identifier);
+ virtual ~PropertyScriptListener();
virtual void propertyChanged(PropertyNodePtr _changedNode);
virtual void propertyRemoved(PropertyNodePtr _parent, PropertyNodePtr _child);
@@ -127,7 +129,7 @@
void removeListener(const std::string& _identifier);
private:
PropertySystem& m_PropertySystem;
- boost::ptr_vector<PropertyScriptListener> m_Listeners;
+ std::vector<PropertyScriptListener*> m_Listeners;
int m_NextListenerID;
}; // PropertyScriptExtension
Modified: dss/trunk/core/sim/dsid_js.cpp
===================================================================
--- dss/trunk/core/sim/dsid_js.cpp 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/core/sim/dsid_js.cpp 2009-09-29 14:08:06 UTC (rev 8808)
@@ -23,22 +23,25 @@
#include "core/jshandler.h"
#include "core/scripting/modeljs.h"
#include "core/dss.h"
+#include "core/thread.h"
namespace dss {
class DSIDJS : public DSIDInterface {
public:
DSIDJS(const DSModulatorSim& _simulator, dsid_t _dsid,
- devid_t _shortAddress, boost::shared_ptr<ScriptContext> _pContext)
+ devid_t _shortAddress, boost::shared_ptr<ScriptContext> _pContext,
+ const std::string& _fileName)
: DSIDInterface(_simulator, _dsid, _shortAddress),
- m_pContext(_pContext)
+ m_pContext(_pContext),
+ m_FileName(_fileName)
{}
virtual ~DSIDJS() {}
virtual void initialize() {
try {
- jsval res = m_pContext->evaluate<jsval>();
+ jsval res = m_pContext->evaluateScript<jsval>(m_FileName);
if(JSVAL_IS_OBJECT(res)) {
m_pJSThis = JSVAL_TO_OBJECT(res);
m_pSelf.reset(new ScriptObject(m_pJSThis, *m_pContext));
@@ -253,6 +256,7 @@
boost::shared_ptr<ScriptContext> m_pContext;
JSObject* m_pJSThis;
boost::shared_ptr<ScriptObject> m_pSelf;
+ std::string m_FileName;
}; // DSIDJS
@@ -282,6 +286,23 @@
DSSim& m_Simulation;
}; // PropertyScriptExtension
+ class DSLinkInterrupSender : public Thread {
+ public:
+ DSLinkInterrupSender(dsid_t _dsid, DSIDScriptExtension* _ext)
+ : Thread("DSLinkInterruptSender"),
+ m_DSID(_dsid), m_Ext(_ext)
+ {
+ setFreeAtTermination(true);
+ }
+ virtual void execute() {
+ sleepMS(rand() % 3000);
+ m_Ext->dSLinkInterrupt(m_DSID);
+ }
+ private:
+ dsid_t m_DSID;
+ DSIDScriptExtension* m_Ext;
+ };
+
JSBool global_dsid_dSLinkInterrupt(JSContext* cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
if(argc < 1) {
Logger::getInstance()->log("JS: glogal_dsid_dSLinkInterrupt: need argument dsid", lsError);
@@ -293,7 +314,8 @@
try {
dsid_t dsid = dsid_t::fromString(dsidString);
- ext->dSLinkInterrupt(dsid);
+ DSLinkInterrupSender* sender = new DSLinkInterrupSender(dsid, ext);
+ sender->run();
} catch(std::runtime_error&) {
Logger::getInstance()->log("Could not parse DSID");
}
@@ -329,12 +351,7 @@
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);
+ DSIDJS* result = new DSIDJS(_modulator, _dsid, _shortAddress, pContext, m_FileName);
return result;
} // createDSID
Modified: dss/trunk/tests/jshandlertests.cpp
===================================================================
--- dss/trunk/tests/jshandlertests.cpp 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/tests/jshandlertests.cpp 2009-09-29 14:08:06 UTC (rev 8808)
@@ -42,13 +42,13 @@
BOOST_CHECK_EQUAL(obj.getProperty<int>("testing"), 1);
ctx->getRootObject().setProperty("obj", &obj);
- BOOST_CHECK_EQUAL(ctx->evaluateScript<int>("obj.testing"), 1);
+ BOOST_CHECK_EQUAL(ctx->evaluate<int>("obj.testing"), 1);
obj.setProperty("testing", 0);
- BOOST_CHECK_EQUAL(ctx->evaluateScript<int>("obj.testing"), 0);
+ BOOST_CHECK_EQUAL(ctx->evaluate<int>("obj.testing"), 0);
obj.setProperty("testing2", "test");
BOOST_CHECK_EQUAL(obj.getProperty<std::string>("testing2"), "test");
- BOOST_CHECK_EQUAL(ctx->evaluateScript<std::string>("obj.testing2"), "test");
+ BOOST_CHECK_EQUAL(ctx->evaluate<std::string>("obj.testing2"), "test");
} // testSimpleObject
BOOST_AUTO_TEST_CASE(testCallingFunctions) {
@@ -56,7 +56,7 @@
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");
+ jsval res = ctx->evaluate<jsval>("dev = { func: function(a,b,c) { return { e: a, f: b, g: c }; } }; dev");
BOOST_ASSERT(JSVAL_IS_OBJECT(res));
Modified: dss/trunk/tests/modeljstests.cpp
===================================================================
--- dss/trunk/tests/modeljstests.cpp 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/tests/modeljstests.cpp 2009-09-29 14:08:06 UTC (rev 8808)
@@ -47,17 +47,12 @@
env->addExtension(ext);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->loadFromMemory("getName()");
- string name = ctx->evaluate<string>();
+ string name = ctx->evaluate<string>("getName()");
BOOST_CHECK_EQUAL(apt.getName(), name);
- ctx.reset(env->getContext());
- ctx->loadFromMemory("setName('hello'); getName()");
+ name = ctx->evaluate<string>("setName('hello'); getName()");
- name = ctx->evaluate<string>();
- ctx.reset();
-
BOOST_CHECK_EQUAL(string("hello"), name);
BOOST_CHECK_EQUAL(string("hello"), apt.getName());
} // testBasics
@@ -77,14 +72,11 @@
env->addExtension(ext);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->loadFromMemory("var devs = getDevices(); devs.length()");
- int length = ctx->evaluate<int>();
+ int length = ctx->evaluate<int>("var devs = getDevices(); devs.length()");
BOOST_CHECK_EQUAL(2, length);
- ctx.reset(env->getContext());
- ctx->loadFromMemory("var devs = getDevices(); var devs2 = getDevices(); devs.combine(devs2)");
- ctx->evaluate<void>();
+ ctx->evaluate<void>("var devs = getDevices(); var devs2 = getDevices(); devs.combine(devs2)");
} // testSets
BOOST_AUTO_TEST_CASE(testDevices) {
@@ -104,10 +96,9 @@
env->addExtension(ext);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->loadFromMemory("var devs = getDevices();\n"
+ ctx->evaluate<void>("var devs = getDevices();\n"
"var f = function(dev) { print(dev.name); }\n"
"devs.perform(f)\n");
- ctx->evaluate<void>();
} // testDevices
BOOST_AUTO_TEST_CASE(testEvents) {
@@ -139,10 +130,10 @@
BOOST_CHECK_EQUAL(interpreter.getNumberOfSubscriptions(), 0);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->loadFromMemory("var evt = new event('test');\n"
+ ctx->evaluate<void>("var evt = new event('test');\n"
"evt.raise()\n"
"\n");
- ctx->evaluate<void>();
+ // TODO: add subscription to confirm the event actually got raised
} // testEvents
BOOST_AUTO_TEST_CASE(testSubscriptions) {
@@ -174,10 +165,9 @@
BOOST_CHECK_EQUAL(interpreter.getNumberOfSubscriptions(), 0);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->loadFromMemory("var s = new subscription('test', 'test', { 'param1': 1, 'param2': 2, 'string': 'string'} );\n"
+ ctx->evaluate<void>("var s = new subscription('test', 'test', { 'param1': 1, 'param2': 2, 'string': 'string'} );\n"
"s.subscribe();\n"
"\n");
- ctx->evaluate<void>();
BOOST_CHECK_EQUAL(interpreter.getNumberOfSubscriptions(), 1);
} // testSubscriptions
@@ -190,12 +180,12 @@
env->addExtension(ext);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->evaluateScript<void>("setProperty('/testing', 1)");
- BOOST_CHECK_EQUAL(ctx->evaluateScript<int>("getProperty('/testing')"), 1);
+ ctx->evaluate<void>("setProperty('/testing', 1)");
+ BOOST_CHECK_EQUAL(ctx->evaluate<int>("getProperty('/testing')"), 1);
BOOST_CHECK_EQUAL(propSys.getIntValue("/testing"), 1);
propSys.setIntValue("/testing", 2);
- BOOST_CHECK_EQUAL(ctx->evaluateScript<int>("getProperty('/testing')"), 2);
+ BOOST_CHECK_EQUAL(ctx->evaluate<int>("getProperty('/testing')"), 2);
}
BOOST_AUTO_TEST_CASE(testPropertyListener) {
@@ -206,8 +196,8 @@
env->addExtension(ext);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->evaluateScript<void>("setProperty('/testing', 1); setProperty('/triggered', false); "
- "listener_ident = setListener('/testing', function(changedNode) { setProperty('/triggered', true); }); "
+ ctx->evaluate<void>("setProperty('/testing', 1); setProperty('/triggered', false); "
+ "listener_ident = setListener('/testing', function(changedNode) { setProperty('/triggered', true); }); "
);
BOOST_CHECK_EQUAL(propSys.getBoolValue("/triggered"), false);
@@ -219,7 +209,7 @@
BOOST_CHECK_EQUAL(propSys.getIntValue("/testing"), 2);
// check that removing works
- ctx->evaluateScript<void>("removeListener(listener_ident);");
+ ctx->evaluate<void>("removeListener(listener_ident);");
propSys.setBoolValue("/triggered", false);
BOOST_CHECK_EQUAL(propSys.getBoolValue("/triggered"), false);
@@ -230,8 +220,8 @@
BOOST_CHECK_EQUAL(propSys.getIntValue("/testing"), 2);
// check that closures are working as expected
- ctx->evaluateScript<void>("setProperty('/triggered', false); "
- "var ident = setListener('/testing', function(changedNode) { setProperty('/triggered', true); removeListener(ident); }); "
+ ctx->evaluate<void>("setProperty('/triggered', false); "
+ "var ident = setListener('/testing', function(changedNode) { setProperty('/triggered', true); removeListener(ident); }); "
);
BOOST_CHECK_EQUAL(propSys.getBoolValue("/triggered"), false);
@@ -258,14 +248,21 @@
env->addExtension(ext);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->evaluateScript<void>("setProperty('/testing', 1); setProperty('/triggered', false); "
- "setListener('/triggered', function() { setProperty('/itWorks', true); } ); "
+ ctx->evaluate<void>("setProperty('/testing', 1); setProperty('/triggered', false); "
+ "other_ident = setListener('/triggered', function() { setProperty('/itWorks', true); } ); "
"listener_ident = setListener('/testing', function(changedNode) { setProperty('/triggered', true); }); "
);
propSys.setBoolValue("/testing", true);
BOOST_CHECK_EQUAL(propSys.getBoolValue("/itWorks"), true);
+
+ // TODO: find out why it crashes w/o those lines
+ ctx->evaluate<void>("removeListener(other_ident); "
+ "removeListener(listener_ident); "
+ );
+
+ ctx.reset();
} // testReentrancy
class TestThreadingThread : public Thread {
@@ -294,9 +291,9 @@
env->addExtension(ext);
boost::scoped_ptr<ScriptContext> ctx(env->getContext());
- ctx->evaluateScript<void>("var func = setProperty('/testing1', 1); setProperty('/testing2', 1); "
- "setListener('/testing1', function() { setProperty('/itWorks', true); } ); "
- "setListener('/testing2', function() { setProperty('/itWorks', true); } ); "
+ ctx->evaluate<void>("var func = setProperty('/testing1', 1); setProperty('/testing2', 1); "
+ "l1 = setListener('/testing1', function() { setProperty('/itWorks', true); } ); "
+ "l2 = setListener('/testing2', function() { setProperty('/itWorks', true); } ); "
);
PropertyNodePtr node1 = propSys.getProperty("/testing1");
@@ -329,6 +326,9 @@
t2.terminate();
sleepMS(500);
}
+
+ // TODO: find out why it crashes w/o those lines
+ ctx->evaluate<void>("removeListener(l1); removeListener(l2);");
} // testThreading
BOOST_AUTO_TEST_SUITE_END()
Modified: dss/trunk/tests/scriptstest.cpp
===================================================================
--- dss/trunk/tests/scriptstest.cpp 2009-09-29 13:57:47 UTC (rev 8807)
+++ dss/trunk/tests/scriptstest.cpp 2009-09-29 14:08:06 UTC (rev 8808)
@@ -35,34 +35,26 @@
BOOST_AUTO_TEST_CASE(testSimpleScripts) {
ScriptEnvironment env;
env.initialize();
- ScriptContext* ctx = env.getContext();
- ctx->loadFromMemory("x = 10; print(x); x = x * x;");
- double result = ctx->evaluate<double>();
+ boost::scoped_ptr<ScriptContext> ctx(env.getContext());
+ double result = ctx->evaluate<double>("x = 10; print(x); x = x * x;");
BOOST_CHECK_EQUAL(result, 100.0);
- delete ctx;
- ctx = env.getContext();
- ctx->loadFromFile("data/test.js");
- result = ctx->evaluate<double>();
+ ctx.reset(env.getContext());
+ result = ctx->evaluateScript<double>("data/test.js");
BOOST_CHECK_EQUAL(result, 100.0);
- delete ctx;
- ctx = env.getContext();
- ctx->loadFromMemory("x = 'bla'; x = x + 'bla';");
- string sres = ctx->evaluate<string>();
+ ctx.reset(env.getContext());
+ string sres = ctx->evaluate<string>("x = 'bla'; x = x + 'bla';");
BOOST_CHECK_EQUAL(sres, string("blabla"));
- delete ctx;
} // testSimpleScripts
BOOST_AUTO_TEST_CASE(testMultipleIterations) {
ScriptEnvironment env;
env.initialize();
for(int i = 0; i < 100; i++) {
- ScriptContext* ctx = env.getContext();
- ctx->loadFromFile("data/test3.js");
- ctx->evaluate<void>();
+ boost::scoped_ptr<ScriptContext> ctx(env.getContext());
+ ctx->evaluateScript<void>("data/test3.js");
cout << ".";
- delete ctx;
}
cout << endl;
} // testMultipleIterations
@@ -71,9 +63,8 @@
ScriptEnvironment* env = new ScriptEnvironment();
env->initialize();
ScriptContext* ctx = env->getContext();
- ctx->loadFromMemory("x = {}; x.what = 'bla'; x.toString = function() { return 'bla'; }; throw x; x = 10;");
try {
- ctx->evaluate<double>();
+ ctx->evaluate<double>("x = {}; x.what = 'bla'; x.toString = function() { return 'bla'; }; throw x; x = 10;");
BOOST_CHECK(false);
} catch(ScriptRuntimeException& _ex) {
BOOST_CHECK_EQUAL(_ex.getExceptionMessage(), string("bla"));
More information about the dss-commits
mailing list