Skip to content

Commit

Permalink
- Add capability to OMEdit to link directly against omc (gives a good…
Browse files Browse the repository at this point in the history
… performance increase especially if calling used functions directly without requiring parsing strings)

- Add OMCOutput parser to OMEdit, to parse the most common OMC Values.Value outputs (no records yet; only sequences and values); the output is a QVariant
- Update getClassInformation to use ModelicaBuiltin.mo
- Add a mockup of the OpenModelicaScriptingAPI.mo we should be able to create from ModelicaBuiltin.mo, and OMC_API.{cpp,h} that should be automatically generated Qt/C++ files corresponding to the same API


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@23384 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Nov 16, 2014
1 parent 204c869 commit 282334a
Show file tree
Hide file tree
Showing 13 changed files with 396 additions and 43 deletions.
5 changes: 2 additions & 3 deletions OMEdit/OMEditGUI/Component/Component.cpp
Expand Up @@ -330,9 +330,8 @@ void Component::parseAnnotationString(QString annotation)
{
/* get the class file path */
QString classFileName;
QStringList classInformation = mpOMCProxy->getClassInformation(mClassName);
if (classInformation.size() > 2)
classFileName = classInformation.at(2);
QVariantMap classInformation = mpOMCProxy->getClassInformation(mClassName);
classFileName = classInformation["fileName"].toString();
/* create the bitmap shape */
shape = shape.mid(QString("Bitmap").length());
shape = StringHandler::removeFirstLastBrackets(shape);
Expand Down
34 changes: 17 additions & 17 deletions OMEdit/OMEditGUI/Modeling/LibraryTreeWidget.cpp
Expand Up @@ -255,9 +255,9 @@ void SearchClassWidget::searchClasses()
{
mpMainWindow->getStatusBar()->showMessage(QString(Helper::loading).append(": ").append(searchedClasses[j]));
LibraryTreeNode *pNewLibraryTreeNode;
QStringList info = mpMainWindow->getOMCProxy()->getClassInformation(searchedClasses[j]);
QString fileName = info.size() < 3 ? mpMainWindow->getOMCProxy()->getSourceFile(searchedClasses[j]) : info.at(2);
StringHandler::ModelicaClasses type = info.size() < 3 ? mpMainWindow->getOMCProxy()->getClassRestriction(searchedClasses[j]) : StringHandler::getModelicaClassType(info.at(0));
QVariantMap info = mpMainWindow->getOMCProxy()->getClassInformation(searchedClasses[j]);
QString fileName = info.find("fileName") == info.end() ? mpMainWindow->getOMCProxy()->getSourceFile(searchedClasses[j]) : info["fileName"].toString();
StringHandler::ModelicaClasses type = info.find("restriction") == info.end() ? mpMainWindow->getOMCProxy()->getClassRestriction(searchedClasses[j]) : StringHandler::getModelicaClassType(info["restriction"].toString());
pNewLibraryTreeNode = new LibraryTreeNode(LibraryTreeNode::Modelica, searchedClasses[j], "", searchedClasses[j],
StringHandler::createTooltip(info, StringHandler::getLastWordAfterDot(searchedClasses[j]), searchedClasses[j]),
type, fileName, !mpLibraryTreeWidget->isFileWritAble(fileName), true, false, mpLibraryTreeWidget);
Expand Down Expand Up @@ -613,9 +613,9 @@ void LibraryTreeWidget::addModelicaLibraries(QSplashScreen *pSplashScreen)
systemLibs.sort();
foreach (QString lib, systemLibs)
{
QStringList info = mpMainWindow->getOMCProxy()->getClassInformation(lib);
StringHandler::ModelicaClasses type = info.size() < 3 ? mpMainWindow->getOMCProxy()->getClassRestriction(lib) : StringHandler::getModelicaClassType(info.at(0));
QString fileName = info.size() < 3 ? mpMainWindow->getOMCProxy()->getSourceFile(lib) : info.at(2);
QVariantMap info = mpMainWindow->getOMCProxy()->getClassInformation(lib);
StringHandler::ModelicaClasses type = info.find("restriction") == info.end() ? mpMainWindow->getOMCProxy()->getClassRestriction(lib) : StringHandler::getModelicaClassType(info["restriction"].toString());
QString fileName = info.find("restriction") == info.end() ? mpMainWindow->getOMCProxy()->getSourceFile(lib) : info["fileName"].toString();
LibraryTreeNode *pNewLibraryTreeNode = new LibraryTreeNode(LibraryTreeNode::Modelica, lib, QString(""), lib, StringHandler::createTooltip(info, lib, lib), type,
fileName, true, true, false, this);
pNewLibraryTreeNode->setSystemLibrary(true);
Expand All @@ -634,9 +634,9 @@ void LibraryTreeWidget::addModelicaLibraries(QSplashScreen *pSplashScreen)
{
if (systemLibs.contains(lib))
continue;
QStringList info = mpMainWindow->getOMCProxy()->getClassInformation(lib);
StringHandler::ModelicaClasses type = info.size() < 3 ? mpMainWindow->getOMCProxy()->getClassRestriction(lib) : StringHandler::getModelicaClassType(info.at(0));
QString fileName = info.size() < 3 ? mpMainWindow->getOMCProxy()->getSourceFile(lib) : info.at(2);
QVariantMap info = mpMainWindow->getOMCProxy()->getClassInformation(lib);
StringHandler::ModelicaClasses type = info.find("restriction") == info.end() ? mpMainWindow->getOMCProxy()->getClassRestriction(lib) : StringHandler::getModelicaClassType(info["restriction"].toString());
QString fileName = info.find("fileName") == info.end() ? mpMainWindow->getOMCProxy()->getSourceFile(lib) : info["fileName"].toString();
LibraryTreeNode *pNewLibraryTreeNode = new LibraryTreeNode(LibraryTreeNode::Modelica, lib, QString(""), lib, StringHandler::createTooltip(info, lib, lib), type,
fileName, !isFileWritAble(fileName), true, false, this);
bool isDocumentationClass = mpMainWindow->getOMCProxy()->getDocumentationClassAnnotation(lib);
Expand All @@ -662,9 +662,9 @@ void LibraryTreeWidget::createLibraryTreeNodes(LibraryTreeNode *pLibraryTreeNode
continue;
QString name = StringHandler::getLastWordAfterDot(lib);
QString parentName = StringHandler::removeLastWordAfterDot(lib);
QStringList info = mpMainWindow->getOMCProxy()->getClassInformation(lib);
StringHandler::ModelicaClasses type = info.size() < 3 ? mpMainWindow->getOMCProxy()->getClassRestriction(lib) : StringHandler::getModelicaClassType(info.at(0));
QString fileName = info.size() < 3 ? mpMainWindow->getOMCProxy()->getSourceFile(lib) : info.at(2);
QVariantMap info = mpMainWindow->getOMCProxy()->getClassInformation(lib);
StringHandler::ModelicaClasses type = info.find("restriction") == info.end() ? mpMainWindow->getOMCProxy()->getClassRestriction(lib) : StringHandler::getModelicaClassType(info["restriction"].toString());
QString fileName = info.find("fileName") == info.end() ? mpMainWindow->getOMCProxy()->getSourceFile(lib) : info["fileName"].toString();
LibraryTreeNode *pNewLibraryTreeNode = new LibraryTreeNode(LibraryTreeNode::Modelica, name, parentName, lib, StringHandler::createTooltip(info, lib, lib), type,
fileName, !isFileWritAble(fileName), pLibraryTreeNode->isSaved(), false, this);
pNewLibraryTreeNode->setSystemLibrary(pLibraryTreeNode->isSystemLibrary());
Expand Down Expand Up @@ -704,9 +704,9 @@ void LibraryTreeWidget::loadLibraryTreeNode(LibraryTreeNode *pParentLibraryTreeN
QString parentName = pParentLibraryTreeNode->getNameStructure();
QString name = pLibraryTreeNode->getName();
mpMainWindow->getStatusBar()->showMessage(QString(Helper::loading).append(": ").append(className));
QStringList info = mpMainWindow->getOMCProxy()->getClassInformation(className);
StringHandler::ModelicaClasses type = info.size() < 3 ? mpMainWindow->getOMCProxy()->getClassRestriction(className) : StringHandler::getModelicaClassType(info.at(0));
QString fileName = info.size() < 3 ? mpMainWindow->getOMCProxy()->getSourceFile(className) : info.at(2);
QVariantMap info = mpMainWindow->getOMCProxy()->getClassInformation(className);
StringHandler::ModelicaClasses type = info.find("restriction") == info.end() ? mpMainWindow->getOMCProxy()->getClassRestriction(className) : StringHandler::getModelicaClassType(info["restriction"].toString());
QString fileName = info.find("fileName") == info.end() ? mpMainWindow->getOMCProxy()->getSourceFile(className) : info["fileName"].toString();
bool isProtected = mpMainWindow->getOMCProxy()->isProtectedClass(parentName, name);
// update LibraryTreeNode attributes
pLibraryTreeNode->setModelicaType(type);
Expand Down Expand Up @@ -767,8 +767,8 @@ LibraryTreeNode* LibraryTreeWidget::addLibraryTreeNode(QString name, StringHandl
LibraryTreeNode *pNewLibraryTreeNode;
QString className = parentName.isEmpty() ? name : QString(parentName).append(".").append(name);
mpMainWindow->getStatusBar()->showMessage(QString(Helper::loading).append(": ").append(className));
QStringList info = mpMainWindow->getOMCProxy()->getClassInformation(className);
QString fileName = info.size() < 3 ? mpMainWindow->getOMCProxy()->getSourceFile(className) : info.at(2);
QVariantMap info = mpMainWindow->getOMCProxy()->getClassInformation(className);
QString fileName = info.find("fileName") == info.end() ? mpMainWindow->getOMCProxy()->getSourceFile(className) : info["fileName"].toString();
pNewLibraryTreeNode = new LibraryTreeNode(LibraryTreeNode::Modelica, name, parentName, className,
StringHandler::createTooltip(info, name, className), type, fileName, !isFileWritAble(fileName),
isSaved, false, this);
Expand Down
9 changes: 4 additions & 5 deletions OMEdit/OMEditGUI/Modeling/ModelWidgetContainer.cpp
Expand Up @@ -2367,9 +2367,8 @@ void ModelWidget::getModelIconDiagramShapes(QString className, QString annotatio
{
/* get the class file path */
QString classFileName;
QStringList classInformation = mpModelWidgetContainer->getMainWindow()->getOMCProxy()->getClassInformation(className);
if (classInformation.size() > 2)
classFileName = classInformation.at(2);
QVariantMap classInformation = mpModelWidgetContainer->getMainWindow()->getOMCProxy()->getClassInformation(className);
classFileName = classInformation["fileName"].toString();
/* create the bitmap shape */
shape = shape.mid(QString("Bitmap").length());
shape = StringHandler::removeFirstLastBrackets(shape);
Expand Down Expand Up @@ -2520,8 +2519,8 @@ void ModelWidget::refresh()
pOMCProxy->removeCachedOMCCommand(mpLibraryTreeNode->getNameStructure());
/* set the LibraryTreeNode filename, type & tooltip */
pOMCProxy->setSourceFile(mpLibraryTreeNode->getNameStructure(), mpLibraryTreeNode->getFileName());
QStringList info = pOMCProxy->getClassInformation(mpLibraryTreeNode->getNameStructure());
StringHandler::ModelicaClasses type = info.size() < 3 ? pOMCProxy->getClassRestriction(mpLibraryTreeNode->getNameStructure()) : StringHandler::getModelicaClassType(info.at(0));
QVariantMap info = pOMCProxy->getClassInformation(mpLibraryTreeNode->getNameStructure());
StringHandler::ModelicaClasses type = info.find("restriction") == info.end() ? pOMCProxy->getClassRestriction(mpLibraryTreeNode->getNameStructure()) : StringHandler::getModelicaClassType(info["restriction"].toString());
mpLibraryTreeNode->setModelicaType(type);
mpLibraryTreeNode->setToolTip(0, StringHandler::createTooltip(info, mpLibraryTreeNode->getName(), mpLibraryTreeNode->getNameStructure()));
/* set the LibraryTreeNode icon */
Expand Down
142 changes: 135 additions & 7 deletions OMEdit/OMEditGUI/OMC/OMCProxy.cpp
Expand Up @@ -36,13 +36,58 @@
*
*/

#if USE_OMC_SHARED_OBJECT
#include "meta/meta_modelica.h"

extern "C" {
void (*omc_assert)(threadData_t*,FILE_INFO info,const char *msg,...) __attribute__ ((noreturn)) = omc_assert_function;
void (*omc_assert_warning)(FILE_INFO info,const char *msg,...) = omc_assert_warning_function;
void (*omc_terminate)(FILE_INFO info,const char *msg,...) = omc_terminate_function;
void (*omc_throw)(threadData_t*) __attribute__ ((noreturn)) = omc_throw_function;
int omc_Main_handleCommand(void *threadData, void *imsg, void *ist, void **omsg, void **ost);
void* omc_Main_init(void *threadData, void *args);
void* omc_Main_readSettings(void *threadData, void *args);
}
#endif

#include <OMC/Parser/OMCOutputLexer.h>
#include <OMC/Parser/OMCOutputParser.h>

#if USE_OMC_SHARED_OBJECT
#include "OMC_API.h"
#endif

#include <stdexcept>
#include <stdlib.h>
#include <iostream>

#include "OMCProxy.h"
#include "../../../Compiler/runtime/config.h"


static QVariant parseExpression(QString result)
{
QVariant res;
pANTLR3_INPUT_STREAM input;
pOMCOutputLexer lex;
pANTLR3_COMMON_TOKEN_STREAM tokens;
pOMCOutputParser parser;
QByteArray ba = result.toUtf8();

input = antlr3NewAsciiStringInPlaceStream((pANTLR3_UINT8)ba.data(), ba.size(), (pANTLR3_UINT8)"");
lex = OMCOutputLexerNew(input);
tokens = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lex));
parser = OMCOutputParserNew(tokens);

parser->exp(parser, res);
// Clean up? Check error? For chickens
parser->free(parser);
tokens->free(tokens);
lex->free(lex);
input->close(input);
return res;
}

/*!
\class OMCProxy
\brief It contains the reference of the CORBA object used to communicate with the OpenModelica Compiler.
Expand Down Expand Up @@ -360,6 +405,16 @@ bool OMCProxy::startServer()
mCommandsLogFileTextStream.setCodec(Helper::utf8.toStdString().data());
mCommandsLogFileTextStream.setGenerateByteOrderMark(false);
}
#if USE_OMC_SHARED_OBJECT
mpThreadData = calloc(1, sizeof(threadData_t));
threadData_t *threadData = (threadData_t*) mpThreadData;
MMC_TRY_TOP_INTERNAL()
omc_Main_init(threadData, mmc_mk_nil());
omc_SymbolTable = omc_Main_readSettings(threadData, mmc_mk_nil());
MMC_CATCH_TOP(return false;)

mHasInitialized = true;
#else
try
{
QString msg;
Expand Down Expand Up @@ -452,6 +507,7 @@ bool OMCProxy::startServer()
mHasInitialized = false;
return false;
}
#endif /* USE_OMC_SHARED_OBJECT */
// get OpenModelica version
Helper::OpenModelicaVersion = getVersion();
// set OpenModelicaHome variable
Expand Down Expand Up @@ -485,12 +541,13 @@ void OMCProxy::stopServer()
*/
void OMCProxy::sendCommand(const QString expression, bool cacheCommand, QString className, bool dontUseCachedCommand)
{
if (!mHasInitialized)
if (!mHasInitialized) {
if(!startServer()) // if we are unable to start OMC. Exit the application.
{
mpMainWindow->setExitApplicationStatus(true);
return;
}
}
/* if OMC command is find in the cached OMC commands then use it and return. */
if (!dontUseCachedCommand)
{
Expand All @@ -513,6 +570,37 @@ void OMCProxy::sendCommand(const QString expression, bool cacheCommand, QString
commandTime.start();
writeCommunicationCommandLog(expression, &commandTime);
writeCommandsMosFile(expression);
#if USE_OMC_SHARED_OBJECT
// TODO: Call this in a thread that loops over received messages? Avoid MMC_TRY_TOP all the time, etc
void *reply_str = NULL;
threadData_t *threadData = (threadData_t*) mpThreadData;

MMC_TRY_TOP_INTERNAL()

MMC_TRY_STACK()

if (!omc_Main_handleCommand(threadData, mmc_mk_scon(expression.toStdString().c_str()), omc_SymbolTable, &reply_str, &omc_SymbolTable)) {
if (expression == "quit()") {
return;
}
exitApplication();
}
mResult = MMC_STRINGDATA(reply_str);
// cache the OMC command
if (cacheCommand) {
cacheOMCCommand(className, expression, getResult());
}

MMC_ELSE()
mResult = "";
fprintf(stderr, "Stack overflow detected and was not caught.\nSend us a bug report at https://trac.openmodelica.org/OpenModelica/newticket\n Include the following trace:\n");
printStacktraceMessages();
fflush(NULL);
MMC_CATCH_STACK()

MMC_CATCH_TOP(mResult = "");

#else
// Send command to server
try
{
Expand All @@ -535,9 +623,10 @@ void OMCProxy::sendCommand(const QString expression, bool cacheCommand, QString
future.waitForFinished();
writeCommunicationResponseLog(&commandTime);
logOMCMessages(expression);
// cahce the OMC command
if (cacheCommand)
// cache the OMC command
if (cacheCommand) {
cacheOMCCommand(className, expression, getResult());
}
}
catch (QtConcurrent::Exception&)
{
Expand All @@ -553,8 +642,10 @@ void OMCProxy::sendCommand(const QString expression, bool cacheCommand, QString
return;
exitApplication();
}
#endif /* USE_OMC_SHARED_OBJECT */
}

#if !USE_OMC_SHARED_OBJECT
/*!
Sends the user commands to OMC by using the Qt::concurrent feature.
\see sendCommand(const QString expression)
Expand All @@ -564,6 +655,7 @@ void OMCProxy::sendCommand()
mResult = QString::fromUtf8(mOMC->sendExpression(getExpression().toUtf8()));
emit commandFinished();
}
#endif

/*!
Sets the command result.
Expand Down Expand Up @@ -1020,12 +1112,48 @@ QStringList OMCProxy::searchClassNames(QString searchText, QString findInText)
\param className - is the name of the class whose information is retrieved.
\return the class information list.
*/
QStringList OMCProxy::getClassInformation(QString className)
QVariantMap OMCProxy::getClassInformation(QString className)
{
#if !USE_OMC_SHARED_OBJECT
sendCommand("getClassInformation(" + className + ")", true, className);
QString result = getResult();
QStringList list = StringHandler::unparseStrings(result);
return list;
QString str = getResult();
if (str == "") {
return QVariantMap();
}
QVariantList lst = parseExpression(str).toList();
QVariantMap res;
res["restriction"] = lst[0];
res["comment"] = lst[1];
res["partialPrefix"] = lst[2];
res["finalPrefix"] = lst[3];
res["encapsulatedPrefix"] = lst[4];
res["fileName"] = lst[5];
res["fileReadOnly"] = lst[6];
res["lineNumberStart"] = lst[7];
res["columnNumberStart"] = lst[8];
res["lineNumberEnd"] = lst[9];
res["columnNumberEnd"] = lst[10];
res["dimensions"] = lst[11];
return res;
#else
/* TODO: Let this function return the struct directly; once we skip CORBA */
threadData_t *threadData = (threadData_t*) mpThreadData;
OMC::API::getClassInformation_result r = OMC::API::getClassInformation(threadData, omc_SymbolTable, className);
QVariantMap res;
res["restriction"] = r.restriction;
res["comment"] = r.comment;
res["partialPrefix"] = r.partialPrefix;
res["finalPrefix"] = r.finalPrefix;
res["encapsulatedPrefix"] = r.encapsulatedPrefix;
res["fileName"] = r.fileName;
res["fileReadOnly"] = r.fileReadOnly;
res["lineNumberStart"] = (long long) r.lineNumberStart;
res["columnNumberStart"] = (long long) r.columnNumberStart;
res["lineNumberEnd"] = (long long) r.lineNumberEnd;
res["columnNumberEnd"] = (long long) r.columnNumberEnd;
res["dimensions"] = r.dimensions;
return res;
#endif
}

/*!
Expand Down
8 changes: 7 additions & 1 deletion OMEdit/OMEditGUI/OMC/OMCProxy.h
Expand Up @@ -80,6 +80,10 @@ class OMCProxy : public QObject
MainWindow *mpMainWindow;
int mAnnotationVersion;
QMap<QString, QList<cachedOMCCommand> > mCachedOMCCommandsMap;
#ifdef USE_OMC_SHARED_OBJECT
void *omc_SymbolTable;
void *mpThreadData;
#endif
public:
OMCProxy(MainWindow *pMainWindow);
~OMCProxy();
Expand Down Expand Up @@ -128,7 +132,7 @@ class OMCProxy : public QObject
QStringList getClassNames(QString className = QString(), QString recursive = QString("false"), QString qualified = QString("false"),
QString showProtected = QString("true"));
QStringList searchClassNames(QString searchText, QString findInText = QString("false"));
QStringList getClassInformation(QString className);
QVariantMap getClassInformation(QString className);
bool isPackage(QString className);
bool isBuiltinType(QString typeName);
QString getBuiltinType(QString typeName);
Expand Down Expand Up @@ -227,7 +231,9 @@ class OMCProxy : public QObject
signals:
void commandFinished();
public slots:
#if !USE_OMC_SHARED_OBJECT
void sendCommand();
#endif
void openOMCLoggerWidget();
void sendCustomExpression();
};
Expand Down

0 comments on commit 282334a

Please sign in to comment.