Skip to content

Commit

Permalink
Add code generation options and direct execute script options (#1810)
Browse files Browse the repository at this point in the history
* Add code generation options and direct execute script options

* Format

* Add translations

* Add logging

* Minor fixes and update translations

* Format
  • Loading branch information
MinyazevR authored Nov 11, 2024
1 parent e23982a commit 99ae3c8
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 47 deletions.
47 changes: 36 additions & 11 deletions plugins/robots/checker/twoDModelRunner/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@
* limitations under the License. */

#include <ctime>

#include <QtCore/QDir>
#include <QtCore/QCommandLineParser>
#include <QtCore/QTranslator>
#include <QtCore/QDirIterator>
#include <QtWidgets/QApplication>

#include <qrkernel/logging.h>
#include <qrkernel/platformInfo.h>

#include "runner.h"

const int maxLogSize = 10 * 1024 * 1024; // 10 MB
constexpr int maxLogSize = 10 * 1024 * 1024; // 10 MB
constexpr int TWO_D_MODEL_RUNNER_INTERPRET_ERROR = 2;
constexpr int TWO_D_MODEL_RUNNER_GENERATE_ERROR = 3;
constexpr int TWO_D_MODEL_RUNNER_GENERATE_MODE_NOT_EXIST = 4;

const QString description = QObject::tr(
"Emulates robot`s behaviour on TRIK Studio 2D model separately from programming environment. "\
Expand Down Expand Up @@ -124,6 +124,15 @@ int main(int argc, char *argv[])
, QObject::tr("Close the window and exit after diagram/script"\
" finishes."));
QCommandLineOption showConsoleOption({"c", "console"}, QObject::tr("Shows robot's console."));
QCommandLineOption generatePathOption("generate-path"
, QObject::tr("The complete file path, including the filename"\
", to save the generated JavaScript or Python code.")
, "path-to-save-code", QString());
QCommandLineOption generateModeOption("generate-mode", QObject::tr("Select \"python\" or \"javascript\".")
, "generate-mode", "python");
QCommandLineOption directScriptExecutionPathOption("script-path"
, QObject::tr("The path to the Python or JavaScript file that will be used for interpretation.")
, "script-path", QString());
parser.addOption(backgroundOption);
parser.addOption(reportOption);
parser.addOption(trajectoryOption);
Expand All @@ -133,14 +142,14 @@ int main(int argc, char *argv[])
parser.addOption(closeOnFinishOption);
parser.addOption(closeOnSuccessOption);
parser.addOption(showConsoleOption);

parser.addOption(generatePathOption);
parser.addOption(generateModeOption);
parser.addOption(directScriptExecutionPathOption);
parser.process(*app);

const QStringList positionalArgs = parser.positionalArguments();
if (positionalArgs.size() != 1) {
parser.showHelp();
}

const QString &qrsFile = positionalArgs.first();
const bool backgroundMode = parser.isSet(backgroundOption);
const QString report = parser.isSet(reportOption) ? parser.value(reportOption) : QString();
Expand All @@ -150,12 +159,28 @@ int main(int argc, char *argv[])
const bool closeOnSuccessMode = parser.isSet(closeOnSuccessOption);
const bool closeOnFinishMode = backgroundMode || parser.isSet(closeOnFinishOption);
const bool showConsoleMode = parser.isSet(showConsoleOption);
QScopedPointer<twoDModel::Runner> runner(new twoDModel::Runner(report, trajectory, input, mode));
const QString generatePath = parser.value(generatePathOption);
const QString generateMode = parser.value(generateModeOption);
const QString scriptFilePath = parser.value(directScriptExecutionPathOption);

QScopedPointer<twoDModel::Runner> runner(new twoDModel::Runner(report, trajectory, input, mode, qrsFile));
auto speedFactor = parser.value(speedOption).toInt();
if (!runner->interpret(qrsFile, backgroundMode, speedFactor
, closeOnFinishMode, closeOnSuccessMode, showConsoleMode)) {
return 2;

if (!generatePath.isEmpty()) {
if (generateMode != "python" and generateMode != "javascript") {
parser.showHelp();
QLOG_ERROR() << "Problem with generate code to " << generatePath;
return TWO_D_MODEL_RUNNER_GENERATE_MODE_NOT_EXIST;
}
if (!runner->generate(generatePath, generateMode)) {
QLOG_ERROR() << "Problem with generate code to " << generatePath;
return TWO_D_MODEL_RUNNER_GENERATE_ERROR;
}
}

if (!runner->interpret(backgroundMode, speedFactor, closeOnFinishMode,
closeOnSuccessMode, showConsoleMode, scriptFilePath)) {
return TWO_D_MODEL_RUNNER_INTERPRET_ERROR;
}

const int exitCode = app->exec();
Expand Down
52 changes: 37 additions & 15 deletions plugins/robots/checker/twoDModelRunner/runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
#include <qrutils/widgets/consoleDock.h>
#include <kitBase/robotModel/robotParts/shell.h>
#include <kitBase/robotModel/robotModelUtils.h>

#include <qrkernel/logging.h>
#include <twoDModel/engine/model/model.h>
#include <twoDModel/engine/model/timeline.h>

using namespace twoDModel;

Runner::Runner(const QString &report, const QString &trajectory)
Runner::Runner(const QString &report, const QString &trajectory,
const QString &input, const QString &mode, const QString &qrsFile):
mInputsFile(input)
, mMode(mode)
, mSaveFile(qrsFile)
{
mQRealFacade.reset(new qReal::SystemFacade());
mProjectManager.reset(new qReal::ProjectManager(mQRealFacade->models()));
Expand All @@ -39,7 +43,7 @@ Runner::Runner(const QString &report, const QString &trajectory)

mController.reset(new qReal::Controller());
mSceneCustomizer.reset(new qReal::gui::editor::SceneCustomizer());
mTextManager.reset(new qReal::NullTextManager());
mTextManager.reset(new qReal::text::TextManager(mQRealFacade->events(), *mMainWindow));
mConfigurator.reset(new qReal::PluginConfigurator(mQRealFacade->models().repoControlApi()
, mQRealFacade->models().graphicalModelAssistApi()
, mQRealFacade->models().logicalModelAssistApi()
Expand All @@ -61,14 +65,8 @@ Runner::Runner(const QString &report, const QString &trajectory)
connect(&*mErrorReporter, &qReal::ConsoleErrorReporter::errorAdded, &*mReporter, &Reporter::addError);
connect(&*mErrorReporter, &qReal::ConsoleErrorReporter::criticalAdded, &*mReporter, &Reporter::addError);
connect(&*mErrorReporter, &qReal::ConsoleErrorReporter::logAdded, &*mReporter, &Reporter::addLog);
}

Runner::Runner(const QString &report, const QString &trajectory, const QString &input, const QString &mode)
: Runner(report, trajectory)

{
mInputsFile = input;
mMode = mode;
mProjectManager->open(mSaveFile);
}

Runner::~Runner()
Expand All @@ -87,14 +85,38 @@ Runner::~Runner()
mQRealFacade.reset();
}

bool Runner::interpret(const QString &saveFile, const bool background
, const int customSpeedFactor, bool closeOnFinish
, const bool closeOnSuccess, const bool showConsole)
bool Runner::generate(const QString &generatePath, const QString &generateMode)
{
if (!mProjectManager->open(saveFile)) {
for (auto&& action: mPluginFacade->actionsManager().actions()){
if (generateMode == "python") {
if (action.action()->objectName() == "generatePythonTrikCode") {
emit action.action()->triggered();
}
}
if (generateMode == "javascript") {
if (action.action()->objectName() == "generateTRIKCode") {
emit action.action()->triggered();
}
}
}

auto codes = mTextManager->code(mMainWindow->activeDiagram());
if (codes.empty()) {
// The application has already logged a
// description of the problem that prevented script generation.
return false;
}
auto path = mTextManager->path(codes.first());
if (!QFile::copy(path, generatePath)) {
QLOG_ERROR() << "File with name " << generatePath << " already exist";
return false;
}
return true;
}

bool Runner::interpret(const bool background, const int customSpeedFactor, bool closeOnFinish
, const bool closeOnSuccess, const bool showConsole, const QString &filePath)
{
/// @todo: A bit hacky way to get 2D model window. Actually we must not have need in this.
/// GUI must be separated from logic and not appear here at all.
QList<view::TwoDModelWidget *> twoDModelWindows;
Expand Down Expand Up @@ -143,7 +165,7 @@ bool Runner::interpret(const QString &saveFile, const bool background

mReporter->onInterpretationStart();
if (mMode == "script") {
return mPluginFacade->interpretCode(mInputsFile);
return mPluginFacade->interpretCode(mInputsFile, filePath);
} else if (mMode == "diagram") {
mPluginFacade->actionsManager().runAction().trigger();
}
Expand Down
24 changes: 14 additions & 10 deletions plugins/robots/checker/twoDModelRunner/runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <qrgui/systemFacade/components/consoleErrorReporter.h>
#include <qrgui/systemFacade/components/nullMainWindow.h>
#include <qrgui/systemFacade/components/projectManager.h>
#include <qrgui/systemFacade/components/nullTextManager.h>
#include <textEditor/textManager.h>
#include <qrgui/controller/controller.h>
#include <qrgui/editor/sceneCustomizer.h>
#include <qrgui/plugins/toolPluginInterface/pluginConfigurator.h>
Expand All @@ -46,17 +46,14 @@ class Runner : public QObject
Q_OBJECT

public:
/// Constructor.
/// @param report A path to a file where JSON report about the session will be written after it ends.
/// @param trajectory A path to a file where robot`s trajectory will be written during the session.
Runner(const QString &report, const QString &trajectory);

/// Constructor.
/// @param report A path to a file where JSON report about the session will be written after it ends.
/// @param trajectory A path to a file where robot`s trajectory will be written during the session.
/// @param input A path to a file where JSON with inputs for JavaScript.
/// @param mode Interpret mode.
Runner(const QString &report, const QString &trajectory, const QString &input, const QString &mode);
/// @param qrsFile Path to TRIK Studio project
Runner(const QString &report, const QString &trajectory, const QString &input,
const QString &mode, const QString &qrsFile);

~Runner();

Expand All @@ -67,8 +64,14 @@ class Runner : public QObject
/// @param speedFactor can be used when not in background mode to tune interpretation speed
/// @param closeOnSuccessMode If true then model will be closed if the program finishes without errors.
/// @param showConsole If true then robot's console will be showed.
bool interpret(const QString &saveFile, bool background, int speedFactor
, bool closeOnFinish, bool closeOnSuccess, bool showConsole);
/// @param filePath If not QString() interpret code on this path instead of the code in the TRIK Studio file format.
bool interpret(bool background, int speedFactor
, bool closeOnFinish, bool closeOnSuccess, bool showConsole, const QString &filePath);

/// Generate code from TRIK Studio save file
/// @param generatePath The path to save the generated code
/// @param generateMode "python" or "javascript"
bool generate(const QString &generatePath, const QString &generateMode);

private slots:
void close();
Expand All @@ -85,14 +88,15 @@ private slots:
QScopedPointer<qReal::ConsoleErrorReporter> mErrorReporter;
QScopedPointer<qReal::ProjectManager> mProjectManager;
QScopedPointer<qReal::NullMainWindow> mMainWindow;
QScopedPointer<qReal::NullTextManager> mTextManager;
QScopedPointer<qReal::text::TextManager> mTextManager;
QScopedPointer<qReal::gui::editor::SceneCustomizer> mSceneCustomizer;
QScopedPointer<qReal::PluginConfigurator> mConfigurator;
QScopedPointer<Reporter> mReporter;
QScopedPointer<interpreterCore::RobotsPluginFacade> mPluginFacade;
QList<qReal::ui::ConsoleDock *> mRobotConsoles;
QString mInputsFile;
QString mMode;
QString mSaveFile;
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class RobotsPluginFacade : public QObject
const kitBase::EventsForKitPluginInterface &eventsForKitPlugins() const;

//tempory solution
bool interpretCode(const QString &inputs);
bool interpretCode(const QString &inputs, const QString &filepath);

public slots:
void saveCode(const QString &code, const QString &languageExtension);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,11 +304,27 @@ const kitBase::EventsForKitPluginInterface &RobotsPluginFacade::eventsForKitPlug
return mEventsForKitPlugin;
}

bool RobotsPluginFacade::interpretCode(const QString &inputs)
bool RobotsPluginFacade::interpretCode(const QString &inputs, const QString &filepath)
{
auto logicalRepo = &mLogicalModelApi->logicalRepoApi();
QString code = logicalRepo->metaInformation("activeCode").toString();
QString extension = logicalRepo->metaInformation("activeCodeLanguageExtension").toString();
QString code;
QString extension;
if (filepath.isEmpty()) {
QFile file(filepath);
QFileInfo fileInfo(file);

if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
mMainWindow->errorReporter()->addError(
tr("The specified script file could not be opened for reading ") + filepath);
return false;
}
code = file.readAll();
extension = fileInfo.suffix().toLower();
}
else {
auto logicalRepo = &mLogicalModelApi->logicalRepoApi();
code = logicalRepo->metaInformation("activeCode").toString();
extension = logicalRepo->metaInformation("activeCodeLanguageExtension").toString();
}
if (code.isEmpty()) {
mMainWindow->errorReporter()->addError(tr("No saved code found in the qrs file"));
return false;
Expand Down
7 changes: 6 additions & 1 deletion qrtranslations/fr/plugins/robots/interpreterCore_fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,12 @@
<translation type="unfinished"></translation>
</message>
<message>
<location line="+111"/>
<location line="+115"/>
<source>The specified script file could not be opened for reading </source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+12"/>
<source>No saved code found in the qrs file</source>
<translation type="unfinished"></translation>
</message>
Expand Down
19 changes: 17 additions & 2 deletions qrtranslations/fr/plugins/robots/twoDModelRunner_fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ In background mode the session will be terminated just after the execution ended
<source>Speed factor, try from 5 to 20, or even 1000 (at your own risk!).</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+10"/>
<source>The complete file path, including the filename, to save the generated JavaScript or Python code.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+6"/>
<source>The path to the Python or JavaScript file that will be used for interpretation.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="-3"/>
<source>Select &quot;python&quot; or &quot;javascript&quot;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Use this option set to &quot;minimal&quot; to disable connection to X server</source>
<translation type="vanished">Mettez &quot;minimal&quot; dans cette option pour désactiver la connexion au serveur X</translation>
Expand All @@ -49,7 +64,7 @@ In background mode the session will be terminated just after the execution ended
<translation type="vanished">Le chemin au fichier de sauvegarde des resultats (JSON)</translation>
</message>
<message>
<location line="-10"/>
<location line="-23"/>
<source>A path to file where robot`s trajectory will be written. The writing will not be performed not immediately, each trajectory point will be written just when obtained by checker, so FIFOs are recommended to be targets for this option.</source>
<translation>Le chemin au ficher ou la trajectoire du robot sera enregistrée. L&apos;enregistrement ne sera pas fait immediatement, chaque point de trajectoire sera écrit dès lors qu&apos;il est obteneur par le checker, donc FIFO sont récommandés pour cette option.</translation>
</message>
Expand All @@ -72,7 +87,7 @@ In background mode the session will be terminated just after the execution ended
<context>
<name>twoDModel::Runner</name>
<message>
<location filename="../../../../plugins/robots/checker/twoDModelRunner/runner.cpp" line="+203"/>
<location filename="../../../../plugins/robots/checker/twoDModelRunner/runner.cpp" line="+225"/>
<source>Robot console</source>
<translation type="unfinished"></translation>
</message>
Expand Down
7 changes: 6 additions & 1 deletion qrtranslations/ru/plugins/robots/interpreterCore_ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,12 @@
<translation>Экспорт упражнения по заданному пути не удался (попробуйте другой путь)</translation>
</message>
<message>
<location line="+111"/>
<location line="+115"/>
<source>The specified script file could not be opened for reading </source>
<translation>Не удалось открыть указанный файл для чтения скрипта</translation>
</message>
<message>
<location line="+12"/>
<source>No saved code found in the qrs file</source>
<translation>В qrs не найден сохраннёный код</translation>
</message>
Expand Down
19 changes: 17 additions & 2 deletions qrtranslations/ru/plugins/robots/twoDModelRunner_ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,22 @@ In background mode the session will be terminated just after the execution ended
<translation>Ускорение, попробуйте от 5 до 20, но можно пробовать и 1000.</translation>
</message>
<message>
<location line="-10"/>
<location line="+10"/>
<source>The complete file path, including the filename, to save the generated JavaScript or Python code.</source>
<translation>Полный путь, включающий имя файла, для сохранения сгенерированного Javascript или Python кода.</translation>
</message>
<message>
<location line="+6"/>
<source>The path to the Python or JavaScript file that will be used for interpretation.</source>
<translation>Путь к Python или Javascript файлу, который будет использоваться для интерпретации.</translation>
</message>
<message>
<location line="-3"/>
<source>Select &quot;python&quot; or &quot;javascript&quot;.</source>
<translation>Выберите &quot;python&quot; или &quot;javascript&quot;.</translation>
</message>
<message>
<location line="-23"/>
<source>A path to file where robot`s trajectory will be written. The writing will not be performed not immediately, each trajectory point will be written just when obtained by checker, so FIFOs are recommended to be targets for this option.</source>
<translation>Путь к файлу, куда будет выводиться траектори робота. Запись не будет осуществлена единомоментно, каждый узел траектории будет записан по факту его просчета проверяющей системой. Поэтому разумно использования FIFO-файлов в качестве значения этого параметра.</translation>
</message>
Expand All @@ -74,7 +89,7 @@ In background mode the session will be terminated just after the execution ended
<context>
<name>twoDModel::Runner</name>
<message>
<location filename="../../../../plugins/robots/checker/twoDModelRunner/runner.cpp" line="+203"/>
<location filename="../../../../plugins/robots/checker/twoDModelRunner/runner.cpp" line="+225"/>
<source>Robot console</source>
<translation>Консоль робота</translation>
</message>
Expand Down

0 comments on commit 99ae3c8

Please sign in to comment.