Fixed found important bugs.
#define dennco_DNUtils_h
#include <string>
+#include "TKLock.h"
void trimString(std::string& str);
std::string getJSEscapeString(const char *cstring);
std::string parseCellCodeForScriptEngine(std::string jname, std::string cellCode);
+class DNLocker
+{
+public:
+ DNLocker(TKLock *lock) : mLock(lock) {mLock->lock();}
+ ~DNLocker() { mLock->unlock();}
+private:
+ TKLock *mLock;
+};
+
#endif
ui->filePath->setText(contentPath);
ui->console->document()->setMaximumBlockCount(2000);
+ QFont monofont("Courier");
+ monofont.setStyleHint(QFont::Monospace);
+ ui->console->setFont(monofont);
TKLog::setDestination(this);
}
DNQSBasicCell::DNQSBasicCell(DNQSContainer *container, std::string location, std::string name, bool canInterface):
DNQSCellBase(container,location,name,canInterface)
{
- QScriptEngine *engine = container->getScriptEngine();
+ mEngine = container->getScriptEngine();
- mQSAPIInstance = engine->newObject();
+ mQSAPIInstance = mEngine->newObject();
mQSAPIInstance.setProperty("location", QScriptValue(QString::fromStdString(location)),QScriptValue::ReadOnly|QScriptValue::Undeletable);
mQSAPIInstance.setProperty("name", QScriptValue(QString::fromStdString(name)),QScriptValue::ReadOnly|QScriptValue::Undeletable);
- mQSAxon = QScriptValue(0.0);
- mQSAPIInstance.setProperty("axonValue",mQSAxon,QScriptValue::Undeletable);
- mQSReceptors = engine->newObject();
+ mQSReceptors = mEngine->newObject();
mQSAPIInstance.setProperty("receptors", mQSReceptors,QScriptValue::ReadOnly|QScriptValue::Undeletable);
+
+ mAxonValueHandle = mEngine->toStringHandle("axonValue");
}
DNQSBasicCell::~DNQSBasicCell()
}
-bool DNQSBasicCell::doTick(float time)
+//TODO: find better way
+void DNQSBasicCell::prepareValueForScript()
{
- if (!mCellCodeInstance) return false;
-
//update receptor values
for ( TKReceptorMap::iterator it = mReceptors.begin(); it != mReceptors.end(); ++it ) {
mQSReceptors.setProperty(QString::fromStdString(it->first), QScriptValue(it->second->getValue()),QScriptValue::ReadOnly);
}
+ //update axonValue
+ mQSAPIInstance.setProperty(mAxonValueHandle,QScriptValue(mAxon->getValue()));
+}
- bool r = mCellCodeInstance->doTick(time);
- if (r && mQSAxon.isNumber())
+//TODO: find better way
+void DNQSBasicCell::reflectValueFromScript()
+{
+ QScriptValue value = mQSAPIInstance.property(mAxonValueHandle);
+ mAxon->setValue(value.toNumber());
+}
+
+void DNQSBasicCell::handleScriptException(const char *funcName)
+{
+ TKLog::printf("Script Error! in %s#%s.%s", mLocation.c_str(), mName.c_str(), funcName);
+ if (mEngine->hasUncaughtException())
{
- mAxon->value = mQSAxon.toNumber();
+ QScriptValue error = mEngine->uncaughtException();
+ QString errorString = error.toString();
+ TKLog::printf(" Error Message: %s", errorString.toLocal8Bit().data());
+ mEngine->clearExceptions();
+ }
+}
+
+bool DNQSBasicCell::doTick(float time)
+{
+ if (!mCellCodeInstance) return false;
+
+ prepareValueForScript();
+
+ if (mCellCodeInstance->doTick(time))
+ {
+ reflectValueFromScript();
return true;
}
else
{
+ handleScriptException("doTick()");
return false;
}
}
bool DNQSBasicCell::doInit()
{
- if (mCellCodeInstance) return false;
- return mCellCodeInstance->doInit();
+ if (!mCellCodeInstance) return false;
+
+ prepareValueForScript();
+
+ if (mCellCodeInstance->doInit())
+ {
+ reflectValueFromScript();
+ return true;
+ }
+ else
+ {
+ handleScriptException("doInit()");
+ return false;
+ }
}
bool DNQSBasicCell::doDestroy()
{
- if (mCellCodeInstance) return false;
- return mCellCodeInstance->doDestroy();
+ if (!mCellCodeInstance) return false;
+
+ prepareValueForScript();
+
+ if (mCellCodeInstance->doDestroy())
+ {
+ reflectValueFromScript();
+ return true;
+ }
+ else
+ {
+ handleScriptException("doDestroy()");
+ return false;
+ }
}
DNQSBasicCell(DNQSContainer *container, std::string location, std::string name, bool canIntarface = false);
virtual ~DNQSBasicCell();
- virtual bool doTick(float time);
- virtual bool doInit();
- virtual bool doDestroy();
+ virtual bool doTick(float time);
+ virtual bool doInit();
+ virtual bool doDestroy();
+
private:
- QScriptValue mQSAxon;
- QScriptValue mQSReceptors;
+ void prepareValueForScript();
+ void reflectValueFromScript();
+ void handleScriptException(const char *funcName);
+
+ QScriptEngine *mEngine;
+ QScriptValue mQSReceptors;
+ QScriptString mAxonValueHandle;
};
#endif // DNQSBASICCELL_H
QScriptValueList args;
args << time;
mQSDoTick.call(mQSCellCodeInstance, args);
- return true;
+ return !mScriptEngine->hasUncaughtException();
}
else
{
- return false;
+ return true;
}
}
if (mQSDoInit.isFunction())
{
mQSDoInit.call(mQSCellCodeInstance);
- return true;
+ return !mScriptEngine->hasUncaughtException();
}
else
{
- return false;
+ return true;
}
}
if (mQSDoDestroy.isFunction())
{
mQSDoDestroy.call(mQSCellCodeInstance);
- return true;
+ return !mScriptEngine->hasUncaughtException();
}
else
{
- return false;
+ return true;
}
}
#include "DNUtils.h"
#include "versioninfo.h"
#include "dnqsbasiccell.h"
+#include "dnqsinputcell.h"
+#include "dnqsoutputcell.h"
#include "TKUICell.h"
#include "dnqscellcode.h"
#include "DNGlobal.h"
const std::string DNQSContainer::CELLTYPE_JSBASIC = "B";
-const std::string DNQSContainer::CELLTYPE_UIBASIC = "UB";
+const std::string DNQSContainer::CELLTYPE_OUT = "O";
+const std::string DNQSContainer::CELLTYPE_IN = "I";
static QScriptValue scriptPrint(QScriptContext *context, QScriptEngine *engine)
{
mQSCellContainer = mQSEngine->newObject();
mQSGlobalObject.setProperty("__private_DNCellContainer__",mQSCellContainer);
- std::string pname = "_";
- pname.append(CELLTYPE_JSBASIC);
- mEmptyCellClassForB = createCellCode(pname,CELLTYPE_JSBASIC,"");
- pname = "_";
- pname.append(CELLTYPE_UIBASIC);
- mEmptyCellClassForUB = createCellCode(pname,CELLTYPE_UIBASIC,"");
+ mEmptyCellClass = createCellCode("_DNEMPTY",CELLTYPE_JSBASIC,"");
}
DNQSContainer::~DNQSContainer()
TKCell* DNQSContainer::createCellWithoutCellCodeClass(std::string theLocation, std::string theName, std::string type, std::string customScript)
{
TKCell *cell = NULL;
- TKCellCode *cellCode = NULL;
+ bool noScript = false;
+
if (type == CELLTYPE_JSBASIC || type.length() == 0)
{
cell = new DNQSBasicCell(this, theLocation, theName, false);
- cellCode = mEmptyCellClassForB;
}
- else if (type == CELLTYPE_UIBASIC)
+ else if (type == CELLTYPE_IN)
+ {
+ cell = new DNQSInputCell(this, theLocation, theName, true);
+ noScript = true;
+ }
+ else if (type == CELLTYPE_OUT)
{
- cell = new DNQSBasicCell(this, theLocation, theName, true);
- cellCode = mEmptyCellClassForUB;
+ cell = new DNQSOutputCell(this, theLocation, theName, true);
+ noScript = true;
}
else
{
}
}
-
if (cell)
{
std::string fqnName = getFQNString(theLocation.c_str(), theName.c_str());
mCells.insert(TKCellMap::value_type(fqnName, cell));
- cell->setCellCode(cellCode,(const void*)customScript.c_str());
-
if (cell->isInterface())
{
mInterfaceCells.insert(TKCellMap::value_type(fqnName, cell));
}
+ if (!noScript)
+ {
+ cell->setCellCode(mEmptyCellClass,(const void*)customScript.c_str());
+ }
+ else
+ {
+ if (customScript.length()>0)
+ {
+ std::string message = std::string("Failed to construct cell '").append(theLocation).append("#").append(theName);
+ message.append("'\nThe cellcode is type '").append(type).append("'. This type doesn't support custom script.");
+ TKLog::printf("%s", message.c_str());
+ if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
+ {
+ dnGlobal()->setMessage1("Initialization failed");
+ dnGlobal()->setMessage2(message);
+ }
+ }
+ }
}
else
{
{
cell = new DNQSBasicCell(this, theLocation, theName, false);
}
- else if (type == CELLTYPE_UIBASIC)
+ else if (type == CELLTYPE_OUT)
+ {
+ std::string message = std::string("Failed to construct cell '").append(theLocation).append("#").append(theName);
+ message.append("'\nThe cellcode type '").append(type).append("' doesn't support to have a CellCode class.");
+ TKLog::printf("%s", message.c_str());
+ if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
+ {
+ dnGlobal()->setMessage1("Initialization failed");
+ dnGlobal()->setMessage2(message);
+ }
+ }
+ else if (type == CELLTYPE_IN)
{
- cell = new DNQSBasicCell(this, theLocation, theName, true);
+ std::string message = std::string("Failed to construct cell '").append(theLocation).append("#").append(theName);
+ message.append("'\nThe cellcode requires type '").append(type).append("' doesn't support to have a CellCode class.");
+ TKLog::printf("%s", message.c_str());
+ if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
+ {
+ dnGlobal()->setMessage1("Initialization failed");
+ dnGlobal()->setMessage2(message);
+ }
}
else
{
inline QScriptValue getQSCellContainer() { return mQSCellContainer; }
static const std::string CELLTYPE_JSBASIC;
- static const std::string CELLTYPE_UIBASIC;
+ static const std::string CELLTYPE_OUT;
+ static const std::string CELLTYPE_IN;
private:
QScriptEngine *mQSEngine;
QScriptValue mQSGlobalObject;
QScriptValue mQSCellContainer;
- TKCellCode *mEmptyCellClassForB;
- TKCellCode *mEmptyCellClassForUB;
+ TKCellCode *mEmptyCellClass;
};
#endif // DNQSCONTAINER_H
--- /dev/null
+// Copyright (c) 2012 Dennco Project
+//
+// This program 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.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+//
+// Created by tkawata on 3/14/2012.
+//
+#include "dnqsinputcell.h"
+
+#include "TKcontainer.h"
+#include "TKAxon.h"
+
+DNQSInputCell::DNQSInputCell(TKContainer *container, std::string location, std::string name, bool canInterface):
+ TKCell(container,location,name,canInterface)
+{
+}
+
+DNQSInputCell::~DNQSInputCell()
+{
+}
+
+bool DNQSInputCell::doTick(float time)
+{
+ return true;
+}
+
+bool DNQSInputCell::doInit()
+{
+ return true;
+}
+
+bool DNQSInputCell::doDestroy()
+{
+ return true;
+}
--- /dev/null
+// Copyright (c) 2012 Dennco Project
+//
+// This program 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.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+//
+// Created by tkawata on 3/14/2012.
+//
+#ifndef DNQSINPUTCELL_H
+#define DNQSINPUTCELL_H
+
+#include "TKCell.h"
+
+class TKContainer;
+
+class DNQSInputCell : public TKCell
+{
+public:
+ DNQSInputCell(TKContainer *container, std::string location, std::string name, bool canIntarface = false);
+ virtual ~DNQSInputCell();
+
+ virtual bool doTick(float time);
+ virtual bool doInit();
+ virtual bool doDestroy();
+};
+
+#endif // DNQSINPUTCELL_H
--- /dev/null
+// Copyright (c) 2012 Dennco Project
+//
+// This program 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.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+//
+// Created by tkawata on 3/14/2012.
+//
+#include "dnqsoutputcell.h"
+
+#include "TKContainer.h"
+#include "TKAxon.h"
+#include "TKReceptor.h"
+
+DNQSOutputCell::DNQSOutputCell(TKContainer *container, std::string location, std::string name, bool canInterface):
+ TKCell(container,location,name,canInterface)
+{
+}
+
+DNQSOutputCell::~DNQSOutputCell()
+{
+}
+
+bool DNQSOutputCell::doTick(float time)
+{
+ float value = 0.0;
+
+ for ( TKReceptorMap::iterator it = mReceptors.begin(); it != mReceptors.end(); ++it ) {
+ value += it->second->getValue();
+ }
+
+ mAxon->setValue(value);
+
+ return true;
+}
+
+bool DNQSOutputCell::doInit()
+{
+ return true;
+}
+
+bool DNQSOutputCell::doDestroy()
+{
+ return true;
+}
--- /dev/null
+// Copyright (c) 2012 Dennco Project
+//
+// This program 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.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+//
+// Created by tkawata on 3/14/2012.
+//
+#ifndef DNQSOUTPUTCELL_H
+#define DNQSOUTPUTCELL_H
+
+#include "TKCell.h"
+
+class TKContainer;
+
+class DNQSOutputCell : public TKCell
+{
+public:
+ DNQSOutputCell(TKContainer *container, std::string location, std::string name, bool canIntarface = false);
+ virtual ~DNQSOutputCell();
+
+ virtual bool doTick(float time);
+ virtual bool doInit();
+ virtual bool doDestroy();
+};
+
+#endif // DNQSOUTPUTCELL_H
//
#include "TKAxon.h"
#include "TKAxonTerminal.h"
+#include "TKLock.h"
+#include "DNUtils.h"
-TKAxon::TKAxon(TKCell *theOwner) : mOwner(theOwner)
+TKAxon::TKAxon(TKCell *theOwner) : mValue(0.0), mOwner(theOwner)
{
}
mTerminals.clear();
}
+float TKAxon::getValue()
+{
+ DNLocker locker(&mLock);
+
+ return mValue;
+}
+
+void TKAxon::setValue(float value)
+{
+ DNLocker locker(&mLock);
+
+ mValue = value;
+}
+
TKAxonTerminal* TKAxon::addTerminal()
{
TKAxonTerminal *terminal = new TKAxonTerminal(this);
#include <string>
#include <vector>
+#include "TKLock.h"
+
class TKCell;
class TKAxonTerminal;
-
class TKAxon
{
public:
TKAxon(TKCell *theOwner);
~TKAxon();
TKAxonTerminal* addTerminal();
- TKCell* getOwner() { return mOwner; }
-
- float value;
-
+ TKCell* getOwner() { return mOwner; }
+ float getValue();
+ void setValue(float value);
+
private:
- TKCell *mOwner;
+ float mValue;
+ TKCell *mOwner;
std::vector<TKAxonTerminal*> mTerminals;
+ TKLock mLock;
};
-#endif
\ No newline at end of file
+#endif
float TKAxonTerminal::getValue()
{
TKASSERT(mOwner);
- return mOwner->value;
+ return mOwner->getValue();
}
{
if (mCellCodeInstance)
{
- mCellCodeInstance->doDestroy();
delete mCellCodeInstance;
mCellCodeInstance = NULL;
}
{
if (!mAxon)
return 0.0;
- return mAxon->value;
+ return mAxon->getValue();
}
void TKCell::setAxonValue(float value)
{
if (!mAxon)
return;
- mAxon->value = value;
+ mAxon->setValue(value);
}
bool TKCell::setCellCode(TKCellCode *code, const void *data)
{
mCellCodeInstance = code->createCellCodeInstance(this, data);
if (mCellCodeInstance)
- return mCellCodeInstance->doInit();
+ return doInit();
else
return false;
}
TKContainer::~TKContainer()
{
for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it ) {
+ (it->second)->doDestroy();
+ }
+ for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it ) {
delete it->second;
}
mCells.clear();
mIsInput = true;
TKReceptor *receptor = it->second;
float v = receptor->getValue();
- mAxon->value = v;
+ mAxon->setValue(v);
}
return true;
void TKUICell::setValue(float value)
{
- mAxon->value = value;
+ mAxon->setValue(value);
}
float TKUICell::getValue()
{
- return mAxon->value;
+ return mAxon->getValue();
}
//
#include "qtdndirectoryimpl.h"
-#include <QDir>
+#include <QDirIterator>
DNDirectoryImpl *DNDirectoryImpl::create(const char *dir)
{
{
cleanFileList();
}
-
const DNFileList* QtDNDirectoryImpl::getFileList(const char *filter)
{
cleanFileList();
- QDir dir(mRootDir);
QStringList filters;
QString filterString = QString::fromLocal8Bit(filter);
if (filterString.length()>0)
}
QString pre("*.");
filters << pre.append(filterString);
- dir.setNameFilters (filters);
}
- QStringList list = dir.entryList(QDir::Files);
+
+ QDir rootDir(mRootDir);
+ QDirIterator dirIterator(mRootDir, filters, QDir::Files, QDirIterator::Subdirectories);
+
mFileList = 0;
DNFileList *prev = 0;
- for (int i = 0; i < list.size() ; i++)
+ while(dirIterator.hasNext())
{
- DNFileList *dnfile = new DNFileList(list.at(i).toStdString());
+ dirIterator.next();
+ std::string filePath = "/";
+ filePath.append(rootDir.relativeFilePath(dirIterator.filePath()).toStdString());
+ DNFileList *dnfile = new DNFileList(filePath);
if (prev)
{
prev->next = dnfile;
}
}
- return mFileList;
+ return mFileList;
}
void QtDNDirectoryImpl::cleanFileList()
{
Source/DNGlobal.cpp \
Source/DNThread.cpp \
Source/platform/qt/qtdnthreadimpl.cpp \
- Source/QtDennco/dnwebinterface.cpp
+ Source/QtDennco/dnwebinterface.cpp \
+ Source/QtScript/dnqsinputcell.cpp \
+ Source/QtScript/dnqsoutputcell.cpp
HEADERS += Source/QtDennco/mainwindow.h \
Source/TKUICell.h \
Source/DNThread.h \
Source/DNThreadImpl.h \
Source/platform/qt/qtdnthreadimpl.h \
- Source/QtDennco/dnwebinterface.h
+ Source/QtDennco/dnwebinterface.h \
+ Source/QtScript/dnqsinputcell.h \
+ Source/QtScript/dnqsoutputcell.h
FORMS += Source/QtDennco/mainwindow.ui
Debug:DEFINES+=DEBUG