ScenarioListController.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package ArmarXCore::core
19  * @author Cedric Seehausen (usdnr at kit dot edu)
20  * @date 2016
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 
26 #include "ScenarioListController.h"
27 
28 #include <sstream>
29 
30 #include <QApplication>
31 #include <QMessageBox>
32 #include <QSettings>
33 #include <QTimer>
34 
35 #include <SimoxUtility/algorithm/string/string_tools.h>
36 
47 
48 #include "../gui/namelocationview.h"
49 #include "../gui/scenarioitem.h"
50 
51 using namespace ScenarioManager;
52 using namespace Controller;
53 using namespace Data_Structure;
54 using namespace Parser;
55 using namespace Exec;
56 
57 #define UPDATE_TIMER 500 //ms
58 
60  ExecutorPtr executor,
61  QObject* parent) :
62  QObject(parent),
63  treemodel(),
65  packages(packages),
66  executor(executor)
67 {
68  qRegisterMetaType<ApplicationInstanceStatusMap>("ApplicationInstanceStatusMap");
69  qRegisterMetaType<FilterableTreeModelSortFilterProxyModelPtr>(
70  "FilterableTreeModelSortFilterProxyModelPtr");
71 
72  QTimer* timer = new QTimer(this);
73  QObject::connect(timer, SIGNAL(timeout()), this, SLOT(updateStati()));
74  timer->start(UPDATE_TIMER);
75 
76  updateTask = new armarx::SimplePeriodicTask<>(
77  [&] { fetchStati(); }, 100, false, "ScenarioManagerUpdateStatusTask");
78  updateTask->start();
79 
80  model->setDynamicSortFilter(true);
81  model->setSourceModel(&treemodel);
82 
83  QObject::connect(&createScenarioView,
84  SIGNAL(created(std::string, std::string)),
85  this,
86  SLOT(createdScenario(std::string, std::string)));
87 
88  QObject::connect(&treemodel,
89  SIGNAL(applicationsDrop(
90  QList<QPair<QString, ScenarioManager::Data_Structure::Application*>>,
91  int,
92  QModelIndex)),
93  this,
95  QList<QPair<QString, ScenarioManager::Data_Structure::Application*>>,
96  int,
97  QModelIndex)));
98  QObject::connect(this,
100  this,
102 }
103 
105 {
106  updateTask->stop();
107 }
108 
111 {
112  return model;
113 }
114 
115 void
116 ScenarioListController::stop(int row, int column, QModelIndex parent)
117 {
118  ScenarioItem* item =
119  model->data(model->index(row, column, parent), SCENARIOITEMSOURCE).value<ScenarioItem*>();
120  if (item == nullptr)
121  {
122  return;
123  }
124  if (parent.isValid())
125  {
126  if (parent.parent().isValid()) //stop application
127  {
128  if (!item->isEnabled())
129  {
130  return;
131  }
133  executor->stopApplication(instance);
134  }
135  else //stop packageSubpackage
136  {
137  if (!item->isEnabled())
138  {
139  return;
140  }
141  for (const auto& app : *item->getApplicationInstances())
142  {
143  executor->stopApplication(app);
144  }
145  }
146  }
147  else //stop scenario
148  {
149  ScenarioPtr scenario = item->getScenario();
150  executor->stopScenario(scenario);
151  }
152 }
153 
154 void
156 {
157  updateTask->stop();
158 }
159 
160 void
161 ScenarioListController::start(int row, int column, QModelIndex parent)
162 {
163  ScenarioItem* item =
164  model->data(model->index(row, column, parent), SCENARIOITEMSOURCE).value<ScenarioItem*>();
165  if (!item)
166  {
167  return;
168  }
169  if (parent.isValid())
170  {
171  if (parent.parent().isValid()) //start application
172  {
173  if (!item->isEnabled())
174  {
175  return;
176  }
178  instance->updateFound();
179  if (!instance->getFound())
180  {
181  ShowWarningDialog(
182  "The binary `" + QString::fromStdString(instance->getExecutableAbsPath()) +
183  "` for the application " + QString::fromStdString(instance->getName()) +
184  " could not be found");
185  treemodel.update();
186  return;
187  }
188  auto scenario = instance->getScenario();
189  executor->startApplication(instance);
190  }
191  else // start packagesubtree
192  {
193  if (!item->isEnabled())
194  {
195  return;
196  }
198  for (const auto& app : *item->getApplicationInstances())
199  {
200  app->updateFound();
201  if (!app->getFound())
202  {
203  ShowWarningDialog("The Binary for the Application " +
204  QString::fromStdString(app->getName()) +
205  " could not be found");
206  treemodel.update();
207  return;
208  }
209 
210  executor->startApplication(app);
211  }
212  }
213  }
214  else //start scenario
215  {
216  startScenario(item);
217  }
218 }
219 
220 void
221 ScenarioListController::startScenario(ScenarioItem* scenarioItem)
222 {
223  ScenarioPtr scenario = scenarioItem->getScenario();
224  StartScenario(scenario, executor, iceAdmin);
225 }
226 
227 void
228 ScenarioListController::restart(int row, int column, QModelIndex parent)
229 {
230  //hole entsprechende application aus dem package und uebergebe sie dem executor zum restarten & update model entsprechend
231  ScenarioItem* item =
232  model->data(model->index(row, column, parent), SCENARIOITEMSOURCE).value<ScenarioItem*>();
233  if (item == nullptr || !item->isEnabled())
234  {
235  return;
236  }
237  if (parent.isValid())
238  {
239  if (parent.parent().isValid())
240  {
241  //start/stop application
242  executor->restartApplication(item->getApplicationInstance());
243  }
244  else
245  {
246  //start/stop packageSubtree
247  for (const auto& app : *item->getApplicationInstances())
248  {
249  executor->restartApplication(app);
250  }
251  }
252  }
253  else //start/stop scenario
254  {
255  try
256  {
257  executor->restartScenario(item->getScenario());
258  }
259  catch (IceGrid::ServerStartException& ex)
260  {
261  ShowWarningDialog("Ice had an launching error. Please make sure your remote launch "
262  "settings are correct");
263  }
264  }
265 }
266 
267 void
269  QList<QPair<QString, ScenarioManager::Data_Structure::Application*>> applications,
270  int row,
271  const QModelIndex& parent)
272 {
273  ScenarioItem* item; //reinterpret_cast<ScenarioItem*>(model->data(parent, SCENARIOITEM).data());
274  QModelIndex scenarioIndex;
275 
276  if (parent.parent().isValid() && parent.parent().parent().isValid())
277  {
278  item = model->data(parent.parent().parent(), SCENARIOITEMPROXY).value<ScenarioItem*>();
279  scenarioIndex = parent.parent().parent();
280  }
281  else if (parent.parent().isValid())
282  {
283  item = model->data(parent.parent(), SCENARIOITEMPROXY).value<ScenarioItem*>();
284  scenarioIndex = parent.parent();
285  }
286  else
287  {
288  item = model->data(parent, SCENARIOITEMPROXY).value<ScenarioItem*>();
289  scenarioIndex = parent;
290  }
291 
292  if (item == nullptr)
293  {
294  return;
295  }
296 
297  ScenarioPtr scenario = item->getScenario();
298  if (!scenario->isScenarioFileWriteable())
299  {
300  QMessageBox::critical(
301  0,
302  "Adding application failed!",
303  "The scenario '" + QString::fromStdString(scenario->getName()) +
304  "' is read only. You cannot add an application to this scenario!");
305  return;
306  }
308  std::vector<std::string> acceptedApps =
309  generator.getDependencieTree(scenario->getPackage()->getName());
310 
311 
312  for (const auto& pair : applications)
313  {
315  PackagePtr appPackage;
316  for (const auto& package : *packages)
317  {
318  for (const auto& pApp : *package->getApplications())
319  {
320  if (pApp->getName().compare(app->getName()) == 0)
321  {
322  appPackage = package;
323  }
324  }
325  }
326 
327  if (appPackage.get() == nullptr)
328  {
329  return;
330  }
331 
332  if (std::find(acceptedApps.begin(), acceptedApps.end(), appPackage->getName()) ==
333  acceptedApps.end())
334  {
335  const std::string dependenciesStr = simox::alg::join(acceptedApps, ", ");
336 
337  QMessageBox box;
338  QString message("You cannot drop an app from ");
339  message.append(QString::fromStdString(appPackage->getName()));
340  message.append(" into a scenario from ");
341  message.append(QString::fromStdString(scenario->getPackage()->getName()));
342  message.append(QString::fromStdString(". Package `" +
343  scenario->getPackage()->getName() +
344  "` depends on " + dependenciesStr));
345  box.setText(message);
346  box.exec();
347  return;
348  }
349 
350 
351  const std::string appName = app->getName();
352 
353  int instanceCounter = 0;
354  std::string instanceName = pair.first.toStdString();
355  if (instanceName.empty())
356  {
357  for (const ApplicationInstancePtr& instances : *scenario->getApplications())
358  {
359  if (instances->getName().compare(appName) == 0)
360  {
361  instanceCounter++;
362  }
363  }
364  if (instanceCounter == 0)
365  {
366  instanceName = "";
367  }
368  else
369  {
370  instanceName = "instance" + std::to_string(instanceCounter);
371  }
372  }
373  else
374  {
375  for (const ApplicationInstancePtr& instances : *scenario->getApplications())
376  {
377  if (instances->getInstanceName().compare(instanceName) == 0)
378  {
379  instanceCounter++;
380  }
381  }
382  if (instanceCounter > 0)
383  {
384  instanceName += std::to_string(instanceCounter);
385  }
386  }
387 
388 
389  std::string configPath = scenario->getPath();
390  configPath = configPath.substr(0, configPath.find_last_of('/'));
391  configPath.append("/config/");
392 
393 
394  configPath.append(app->getName());
395  if (!instanceName.empty())
396  {
397  configPath.append(".");
398  configPath.append(instanceName);
399  }
400  configPath.append(".cfg");
401 
402  std::ofstream out(configPath);
403  out.close();
404 
406  app->getPathToExecutable(),
407  instanceName,
408  configPath,
409  appPackage->getName(),
410  scenario,
411  "",
412  true));
413 
414  std::string cacheDir = Parser::IceParser::getCacheDir();
415 
416  executor->loadAndSetCachedProperties(appInstance, cacheDir, true);
417  appInstance->load(true);
418 
419  for (const auto& elem : app->getProperties()->getProperties()->getPropertiesForPrefix(""))
420  {
421  appInstance->modifyProperty(elem.first, elem.second);
422  appInstance->setDefaultPropertyEnabled(elem.first, true);
423  }
424 
425  appInstance->save();
426 
427  scenario->addApplication(appInstance);
428 
429  QModelIndex subScenarioIndex =
430  findSubScenarioModelIndexByScenarioIndex(scenarioIndex, appPackage->getName());
431  ;
432 
433  //if this is unvalid than the user dropped an app out of an package that is not currently used inside the scenario
434  //so create subscenario item
435  //this behaviour was kind of buggy be careful while optimising
436  if (!subScenarioIndex.isValid())
437  {
438  std::vector<ApplicationInstancePtr> list;
439 
440  ScenarioItem* subScenarioItem = new ScenarioItem(appPackage->getName(), list);
441 
442  treemodel.insertRow(0, subScenarioItem, scenarioIndex);
443 
444  subScenarioIndex =
445  findSubScenarioModelIndexByScenarioIndex(scenarioIndex, appPackage->getName());
446 
447  treemodel.insertRow(0, new ScenarioItem(appInstance), subScenarioIndex);
448  }
449  else
450  {
451  treemodel.insertRow(0, new ScenarioItem(appInstance), subScenarioIndex);
452  }
453  }
454  scenario->save();
455 }
456 
457 void
459 {
460  ScenarioItem* scenItem;
461  if (item.parent().isValid() && item.parent().parent().isValid())
462  {
463  scenItem = model->data(item.parent().parent(), SCENARIOITEMSOURCE).value<ScenarioItem*>();
464 
465  if (scenItem == nullptr)
466  {
467  return;
468  }
469 
470  ScenarioItem* appItem = model->data(item, SCENARIOITEMSOURCE).value<ScenarioItem*>();
471 
472  ScenarioPtr scenario = scenItem->getScenario();
473  scenario->removeApplication(appItem->getApplicationInstance());
474 
475  scenario->save();
476  treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
477  }
478  else if (item.parent().isValid())
479  {
480  scenItem = model->data(item.parent(), SCENARIOITEMSOURCE).value<ScenarioItem*>();
481 
482  if (scenItem == nullptr)
483  {
484  return;
485  }
486 
487  ScenarioItem* packageItem = model->data(item, SCENARIOITEMSOURCE).value<ScenarioItem*>();
488 
489  ScenarioPtr scenario = scenItem->getScenario();
490 
491  for (const auto& app : *packageItem->getApplicationInstances())
492  {
493  scenario->removeApplication(app);
494  }
495  scenario->save();
496  treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
497  }
498  else
499  {
500  scenItem = model->data(item, SCENARIOITEMSOURCE).value<ScenarioItem*>();
501 
502  if (scenItem == nullptr)
503  {
504  return;
505  }
506 
507  ScenarioPtr scen = scenItem->getScenario();
508 
509  const std::string file =
510  armarx::ArmarXDataPath::GetDefaultUserConfigPath() + "/ScenarioManager.conf";
511  QSettings settings(QString(file.c_str()), QSettings::NativeFormat);
512  QStringList scenarios = settings.value("scenarios").toStringList();
513  scenarios.removeDuplicates();
514  QString toFind(QString::fromStdString(scen->getName()));
515  toFind.append("::Package::");
516  toFind.append(QString::fromStdString(scen->getPackage()->getName()));
517  scenarios.removeAt(scenarios.indexOf(toFind));
518  settings.setValue("scenarios", scenarios);
519 
520  for (const auto& package : *packages)
521  {
522  for (auto it = package->getScenarios()->begin(); it != package->getScenarios()->end();
523  ++it)
524  {
525  if (scen.get() == it->get())
526  {
527  package->getScenarios()->erase(it);
528  break;
529  }
530  }
531  }
532  treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
533  emit updated();
534  }
535 }
536 
537 void
539 {
540  ARMARX_TRACE;
541 
542  if (packages->size() != 0)
543  {
544  QVector<QPair<QString, bool>> packageNames;
545  for (const auto& package : *packages)
546  {
547  packageNames << qMakePair(QString::fromStdString(package->getName()),
548  package->isScenarioPathWritable());
549  }
550  createScenarioView.setPackages(packageNames);
551  createScenarioView.exec();
552  }
553  else
554  {
555  QMessageBox messageBox;
556  messageBox.setText("You have to have at least one Package open to create an Scenario");
557  messageBox.exec();
558  }
559 
560  ARMARX_TRACE;
561 }
562 
563 void
564 ScenarioListController::createdScenario(std::string name, std::string packageStr)
565 {
566  XMLScenarioParser parser;
567 
568  PackagePtr package;
569  for (unsigned int i = 0; i < packages->size(); i++)
570  {
571  if (packages->at(i)->getName().compare(packageStr) == 0)
572  {
573  package = packages->at(i);
574  break;
575  }
576  }
577  if (package.get() == nullptr)
578  {
579  return;
580  }
581 
582  if (parser.isScenarioexistent(name, package))
583  {
584  QMessageBox box;
585  QString message("The Scenario " + QString::fromStdString(name) +
586  " already exists in Package " + QString::fromStdString(packageStr));
587  box.setText(message);
588  box.exec();
589  return;
590  }
591 
592  ScenarioPtr ptr = parser.createNewScenario(name, package);
593  if (ptr.get() == nullptr)
594  {
595  return;
596  }
597 
598  for (const auto& p : *packages)
599  {
600  if (p->getName().compare(packageStr) == 0)
601  {
602  p->addScenario(ptr);
603  treemodel.insertRow(0, new ScenarioItem(ptr));
604  break;
605  }
606  }
607 
608  const std::string file =
609  armarx::ArmarXDataPath::GetDefaultUserConfigPath() + "/ScenarioManager.conf";
610  QSettings settings(QString(file.c_str()), QSettings::NativeFormat);
611  QStringList scenarios = settings.value("scenarios").toStringList();
612  scenarios.removeDuplicates();
613  QString toAdd;
614  toAdd.append(QString::fromStdString(ptr->getName()));
615  toAdd.append("::Package::");
616  toAdd.append(QString::fromStdString(package->getName()));
617  scenarios.append(toAdd);
618  settings.setValue("scenarios", scenarios);
619  emit updated();
620 }
621 
622 void
624 {
625 
626  ScenarioItem* item = model->data(index, SCENARIOITEMSOURCE).value<ScenarioItem*>();
627  if (index.column() > 0 || item == nullptr)
628  {
629  return;
630  }
631 
632  if (index.parent().isValid())
633  {
634  if (index.parent().parent().isValid())
635  {
636  ApplicationInstancePtr appInstance = item->getApplicationInstance();
637  appInstance->updateFound();
638  if (!appInstance->getFound())
639  {
640  QMessageBox message;
641  message.setText("Could not find Application " + item->data(0).toString() + " at " +
642  QString::fromStdString(appInstance->getPathToExecutable()) + ".");
643  message.exec();
644  if (!appInstance->getFound())
645  {
646  updateModel();
647  emit updated();
648  }
649  return;
650  }
651 
652  emit applicationInstanceClicked(appInstance, item);
653  }
654  else
655  {
656  return;
657  }
658  }
659  else
660  {
661  emit scenarioClicked(item->getScenario());
662  }
663 }
664 
665 void
667  updateModel() //Scenarios don't have a setStatus-method, therefore UI should calculate Scenario status based on other
668 {
669  ScenarioItem* rootItem = treemodel.getRootItem();
670 
671  for (const auto& package : *packages)
672  {
673  auto scenarios = package->getScenarios();
674  for (const auto& scenario : *scenarios)
675  {
676  std::map<std::string, std::vector<ApplicationInstancePtr>> packageSubtrees;
677  for (const auto& app : *scenario->getApplications())
678  {
679  std::string packageName = app->getPackageName();
680 
681  if (packageSubtrees.count(packageName) == 0)
682  {
683  packageSubtrees[packageName] = std::vector<ApplicationInstancePtr>();
684  }
685  packageSubtrees[packageName].push_back(app);
686  }
687 
688  ScenarioItem* scenarioItem;
689  int index =
690  findScenario(rootItem, scenario->getName(), scenario->getPackage()->getName());
691  if (index == -1)
692  {
693  scenarioItem = new ScenarioItem(scenario);
694 
695  for (const auto& it : packageSubtrees)
696  {
697  ScenarioItem* currentItem = new ScenarioItem(it.first, it.second);
698  scenarioItem->appendChild(currentItem);
699  }
700  treemodel.insertRow(0, scenarioItem);
701  }
702  else
703  {
704  scenarioItem = static_cast<ScenarioItem*>(rootItem->child(index));
705 
706  for (int i = 0; i < scenarioItem->childCount(); i++)
707  {
708  ScenarioItem* subPackageItem =
709  static_cast<ScenarioItem*>(scenarioItem->child(i));
710  std::string name = subPackageItem->data(0).toString().toStdString();
711 
712  std::vector<ApplicationInstancePtr> currentBuildSubtree = packageSubtrees[name];
713  ApplicationInstanceVectorPtr currentTreeSubtree =
714  subPackageItem->getApplicationInstances();
715  for (size_t k = 0; k < currentTreeSubtree->size(); k++)
716  {
717  bool found = false;
718  for (size_t j = 0; j < currentBuildSubtree.size(); j++)
719  {
720  if (currentTreeSubtree->at(k)->getName() ==
721  currentBuildSubtree[j]->getName() &&
722  currentTreeSubtree->at(k)->getInstanceName() ==
723  currentBuildSubtree[j]->getInstanceName())
724  {
725  found = true;
726  break;
727  }
728  }
729  if (!found)
730  {
731  treemodel.insertRow(
732  0,
733  new ScenarioItem(currentTreeSubtree->at(k)),
734  findSubScenarioModelIndex(scenario->getName(), name));
735  }
736  }
737  }
738  }
739  }
740  }
741 }
742 
743 QModelIndex
744 ScenarioListController::findApplicationModelIndex(
746 {
747  QModelIndex subScenarioModelIndex = findSubScenarioModelIndex(
748  application->getScenario()->getName(), application->getPackageName());
749  if (!subScenarioModelIndex.isValid())
750  {
751  return QModelIndex();
752  }
753  int count = 0;
754  QModelIndex appIndex = subScenarioModelIndex.model()->index(0, 0);
755  while (true)
756  {
757  appIndex = appIndex.sibling(count, 0);
758  if (!appIndex.isValid())
759  {
760  return QModelIndex();
761  }
762  if (application->getInstanceName().empty())
763  {
764  if (application->getName() == appIndex.data().toString().toStdString())
765  {
766  return appIndex;
767  }
768  }
769  else
770  {
771  if (application->getInstanceName() + "." + application->getName() ==
772  appIndex.data().toString().toStdString())
773  {
774  return appIndex;
775  }
776  }
777 
778  count++;
779  }
780 }
781 
782 QModelIndex
783 ScenarioListController::findSubScenarioModelIndex(std::string scenarioName, std::string packageName)
784 {
785  QModelIndex scenarioIndex = treemodel.index(0, 0);
786 
787  bool scenarioFound = false;
788  int count = 0;
789  while (!scenarioFound)
790  {
791  scenarioIndex = scenarioIndex.sibling(count, 0);
792 
793  if (!scenarioIndex.isValid())
794  {
795  return QModelIndex();
796  }
797  if (scenarioName == scenarioIndex.data().toString().toStdString())
798  {
799  scenarioFound = true;
800  break;
801  }
802 
803  count++;
804  }
805 
806  count = 0;
807  while (true)
808  {
809  QModelIndex currentSubPackageIndex = scenarioIndex.model()->index(count, 0);
810  if (!currentSubPackageIndex.isValid())
811  {
812  return QModelIndex();
813  }
814  if (packageName == currentSubPackageIndex.data().toString().toStdString())
815  {
816  return currentSubPackageIndex;
817  }
818  count++;
819  }
820 
821  return QModelIndex();
822 }
823 
824 QModelIndex
825 ScenarioListController::findSubScenarioModelIndexByScenarioIndex(QModelIndex scenarioIndex,
826  std::string packageName)
827 {
828  int count = 0;
829  while (true)
830  {
831  QModelIndex currentSubPackageIndex = scenarioIndex.model()->index(count, 0);
832  if (packageName == currentSubPackageIndex.data().toString().toStdString())
833  {
834  return currentSubPackageIndex;
835  }
836  if (!currentSubPackageIndex.isValid())
837  {
838  return QModelIndex();
839  }
840  count++;
841  }
842 
843  return QModelIndex();
844 }
845 
846 //looks if the current scenario is already added
847 int
848 ScenarioListController::findScenario(ScenarioItem* rootItem,
849  std::string name,
850  std::string packageName)
851 {
852  for (int i = 0; i < rootItem->childCount(); i++)
853  {
854  if (static_cast<ScenarioItem*>(rootItem->child(i))->getScenario()->getName() == name &&
855  static_cast<ScenarioItem*>(rootItem->child(i))
856  ->getScenario()
857  ->getPackage()
858  ->getName() == packageName)
859  {
860  return i;
861  }
862  }
863 
864  return -1;
865 }
866 
867 void
869 {
870  std::vector<ApplicationInstancePtr> apps;
871  {
872  std::unique_lock lock(applicationInstanceMutex);
873  apps.swap(applicationInstances);
874  }
875  if (apps.empty())
876  {
877  return;
878  }
880  IceUtil::Time start = IceUtil::Time ::now();
881  //update all app instances and scenarios
882  for (const ApplicationInstancePtr& appInst : apps)
883  {
884  std::string status = executor->getApplicationStatus(appInst);
885  stati[appInst] = status;
886  }
887  ARMARX_DEBUG << deactivateSpam(5) << "Fetching scenario stati took "
888  << (IceUtil::Time::now() - start).toMilliSecondsDouble() << " ms";
889  emit statusFetched(stati);
890 }
891 
892 bool
894  ExecutorPtr executor,
895  IceGrid::AdminPrx iceAdmin)
896 {
897  // Make sure all required data files are generated when launching scenario
898  const ApplicationInstanceVectorPtr applications = scenario->getApplications();
899  ARMARX_CHECK_NOT_NULL(applications);
900  for (ApplicationInstancePtr applicationInstance : *applications)
901  {
902  executor->loadAndSetCachedProperties(
903  applicationInstance, Parser::IceParser::getCacheDir(), false, false);
904  applicationInstance->load();
905  }
906 
907  executor->setStarter(StarterFactory::getFactory()->getStarter(), scenario);
908  executor->setStopStrategy(executor->getDefaultStopStrategy(), scenario);
909 
910  if (!scenario->allApplicationsFound())
911  {
912  ShowWarningDialog("Not all binaries in the Scenario " +
913  QString::fromStdString(scenario->getName()) + " could be found",
914  true,
915  QString::fromStdString(scenario->getName() + "BinariesMissing"));
916  // return false;
917  }
918  executor->startScenario(scenario);
919  return true;
920 }
921 
922 void
924 {
925  //update all app instances and scenarios
926  // but this needs to be done async -> first get list of applications,
927  // then send these to other thread
928  std::vector<ApplicationInstancePtr> apps;
929  for (ScenarioManager::Data_Structure::PackagePtr& package : *packages)
930  {
931  ScenarioVectorPtr scenarios = package->getScenarios();
932  for (const ScenarioPtr& scenario : *scenarios)
933  {
934  ApplicationInstanceVectorPtr appInsts = scenario->getApplications();
935  for (const ApplicationInstancePtr& appInst : *appInsts)
936  {
937  apps.push_back(appInst);
938  }
939  }
940  }
941 
942  {
943  std::unique_lock lock(applicationInstanceMutex);
944  apps.swap(applicationInstances);
945  }
946 }
947 
948 void
950 {
951  bool changed = false;
952  for (auto& pair : stati)
953  {
954 
955  bool statusChanged = pair.first->setStatus(pair.second);
956  changed |= statusChanged;
957  }
958  // ARMARX_DEBUG << deactivateSpam(5) << "Updating scenarios took " << (IceUtil::Time::now() - start).toMilliSecondsDouble() << " ms";
959  if (changed)
960  {
961  auto start = IceUtil::Time ::now();
962  treemodel.update();
963  ARMARX_DEBUG << deactivateSpam(5) << "Updating scenario Model took "
964  << (IceUtil::Time::now() - start).toMilliSecondsDouble() << " ms";
965  }
966 
967  emit statusUpdated();
968 }
969 
970 void
973 {
974  for (const auto& package : *packages)
975  {
976  for (const auto& scenario : *package->getScenarios())
977  {
978  if (application->getScenario()->getName() == scenario->getName())
979  {
980  std::string cacheDir = Parser::IceParser::getCacheDir();
981  executor->loadAndSetCachedProperties(application, cacheDir, false, false);
982  qApp->processEvents();
983 
984  // only save the scenario itself, don't make each application save it's own config
985  scenario->save(false);
986  return;
987  }
988  }
989  }
990 }
991 
992 void
993 ScenarioListController::setIceAdmin(IceGrid::AdminPrx admin)
994 {
995  iceAdmin = admin;
996 }
997 
998 void
999 ScenarioListController::ShowWarningDialog(QString message, bool showOnce, QString messageId)
1000 {
1001  static std::set<QString> dialogIds;
1002  if (showOnce)
1003  {
1004  ARMARX_CHECK_EXPRESSION(!messageId.isEmpty());
1005  if (dialogIds.count(messageId))
1006  {
1007  return;
1008  }
1009  dialogIds.insert(messageId);
1010  }
1011  QMessageBox box;
1012  box.setText(message);
1013  box.exec();
1014 }
ScenarioItem
TreeItem representing data contained in a Scenario or an Application.
Definition: scenarioitem.h:38
ScenarioManager::Controller::ApplicationInstanceStatusMap
std::map< ApplicationInstancePtr, std::string > ApplicationInstanceStatusMap
Definition: ScenarioListController.h:48
ScenarioManager::Data_Structure::Application::getProperties
armarx::PropertyDefinitionsPtr getProperties()
Definition: Application.cpp:104
ScenarioManager::Data_Structure::ApplicationInstancePtr
std::shared_ptr< ApplicationInstance > ApplicationInstancePtr
Definition: ApplicationInstance.h:33
ScenarioManager::Data_Structure::ScenarioPtr
std::shared_ptr< Scenario > ScenarioPtr
Definition: Scenario.h:36
iceparser.h
ScenarioItem::getPackageName
std::string getPackageName()
Definition: scenarioitem.cpp:180
TreeModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: treemodel.cpp:96
ScenarioManager::Controller::ScenarioListController::StartScenario
static bool StartScenario(ScenarioManager::Data_Structure::ScenarioPtr scenario, Exec::ExecutorPtr executor, IceGrid::AdminPrx iceAdmin)
Definition: ScenarioListController.cpp:893
index
uint8_t index
Definition: EtherCATFrame.h:59
ScenarioManager::Data_Structure::ApplicationInstanceVectorPtr
std::shared_ptr< std::vector< ApplicationInstancePtr > > ApplicationInstanceVectorPtr
Definition: ApplicationInstance.h:35
TreeModel::insertRow
bool insertRow(int position, TreeItem *item, const QModelIndex &parent=QModelIndex())
Definition: treemodel.cpp:192
TreeItem::data
virtual QVariant data(int column) const
Definition: treeitem.cpp:64
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
TreeItem::parent
TreeItem * parent()
Definition: treeitem.cpp:69
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
ScenarioManager::Parser::DependenciesGenerator::getDependencieTree
static DependencyTree getDependencieTree(std::string packageName)
Definition: DependenciesGenerator.cpp:46
StopperFactory.h
ScenarioManager::Controller::ScenarioListController::stop
void stop(int row, int column, QModelIndex parent)
Definition: ScenarioListController.cpp:116
SCENARIOITEMSOURCE
@ SCENARIOITEMSOURCE
Definition: treeitem.h:36
TreeItem::appendChild
void appendChild(TreeItem *child)
Definition: treeitem.cpp:43
ScenarioItem::getApplicationInstances
ScenarioManager::Data_Structure::ApplicationInstanceVectorPtr getApplicationInstances()
Definition: scenarioitem.cpp:195
ScenarioManager::Controller::ScenarioListController::setIceAdmin
void setIceAdmin(IceGrid::AdminPrx iceAdmin)
Set an IceAdmin for the controller.
Definition: ScenarioListController.cpp:993
message
message(STATUS "Boost-Library-Dir: " "${Boost_LIBRARY_DIRS}") message(STATUS "Boost-LIBRARIES
Definition: CMakeLists.txt:8
ScenarioManager::Exec::ExecutorPtr
std::shared_ptr< Executor > ExecutorPtr
Definition: Executor.h:164
ScenarioModel::getRootItem
ScenarioItem * getRootItem()
Definition: scenariomodel.cpp:239
ScenarioManager::Data_Structure::PackageVectorPtr
std::shared_ptr< std::vector< ScenarioManager::Data_Structure::PackagePtr > > PackageVectorPtr
Definition: Package.h:122
ScenarioModel::update
void update()
Updates this model.
Definition: scenariomodel.cpp:208
ScenarioManager::Controller::ScenarioListController::updated
void updated()
Gets emitted after changes have been made to the data structure.
ScenarioManager::Controller::ScenarioListController::scenarioClicked
void scenarioClicked(Data_Structure::ScenarioPtr scenario)
Gets emitted after a Scenario has been clicked.
ApplicationInstancePtr
std::shared_ptr< ScenarioManager::Data_Structure::ApplicationInstance > ApplicationInstancePtr
Definition: StopStrategy.h:7
TreeItem::childCount
int childCount() const
Definition: treeitem.cpp:54
StatusManager.h
TreeItem::child
TreeItem * child(int row)
Definition: treeitem.cpp:49
ScenarioManager::Data_Structure::Application
Class containing data about an application Provides methods to get and set the date contained in the ...
Definition: Application.h:45
CreateScenarioView::setPackages
void setPackages(QVector< QPair< QString, bool >> const &packages)
Sets the packages which are shown in the view.
Definition: createscenarioview.cpp:44
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
armarx::status
status
Definition: FiniteStateMachine.h:259
PackageBuilder.h
ScenarioManager::Controller::ScenarioListController::createdScenario
void createdScenario(std::string name, std::string package)
Creates a new scenario in the package.
Definition: ScenarioListController.cpp:564
ScenarioManager::Controller::ScenarioListController::restart
void restart(int row, int column, QModelIndex parent)
Restarts the object in the specified location.
Definition: ScenarioListController.cpp:228
ScenarioManager::Data_Structure::PackagePtr
std::shared_ptr< Package > PackagePtr
Definition: Package.h:121
TreeItem::isEnabled
bool isEnabled()
Definition: treeitem.cpp:89
ScenarioManager::Parser::DependenciesGenerator
Definition: DependenciesGenerator.h:38
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
ScenarioManager::Controller::ScenarioListController::stopUpdateTask
void stopUpdateTask()
Definition: ScenarioListController.cpp:155
FilterableTreeModelSortFilterProxyModelPtr
std::shared_ptr< FilterableTreeModelSortFilterProxyModel > FilterableTreeModelSortFilterProxyModelPtr
Definition: filterabletreemodelsortfilterproxymodel.h:65
FilterableTreeModelSortFilterProxyModel
Model of the FilterableTreeView.
Definition: filterabletreemodelsortfilterproxymodel.h:41
ScenarioManager::Controller::ScenarioListController::~ScenarioListController
~ScenarioListController() override
Destructor.
Definition: ScenarioListController.cpp:104
DependenciesGenerator.h
UPDATE_TIMER
#define UPDATE_TIMER
Definition: ScenarioListController.cpp:57
XMLScenarioParser.h
ScenarioManager::Controller::ScenarioListController::start
void start(int row, int column, QModelIndex parent)
Starts or stops the object in the specified location.
Definition: ScenarioListController.cpp:161
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
ScenarioManager::Controller::ScenarioListController::showApplication
void showApplication(const QModelIndex &index)
Calculates the object at the given index and signals to show it.
Definition: ScenarioListController.cpp:623
ScenarioManager::Data_Structure::Application::getExecutableName
std::string getExecutableName()
Definition: Application.cpp:168
ScenarioManager::Controller::ScenarioListController::ScenarioListController
ScenarioListController(Data_Structure::PackageVectorPtr packages, Exec::ExecutorPtr executor, QObject *parent=0)
Constructor which sets the data structure, the executor and optionally the parent object.
Definition: ScenarioListController.cpp:59
armarx::ArmarXDataPath::GetDefaultUserConfigPath
static std::string GetDefaultUserConfigPath()
The user config directory of ArmarX.
Definition: ArmarXDataPath.cpp:782
ExpressionException.h
ScenarioManager::Controller::ScenarioListController::addApplicationsToScenario
void addApplicationsToScenario(QList< QPair< QString, ScenarioManager::Data_Structure::Application * > > applications, int row, const QModelIndex &parent)
Adds applications to a scenario.
Definition: ScenarioListController.cpp:268
ScenarioManager::Parser::IceParser::getCacheDir
static std::string getCacheDir()
Definition: iceparser.cpp:304
TreeModel::removeRow
bool removeRow(int position, const QModelIndex &parent=QModelIndex())
Definition: treemodel.cpp:204
ScenarioManager::Controller::ScenarioListController::statusFetched
void statusFetched(ApplicationInstanceStatusMap stati)
ScenarioManager::Controller::ScenarioListController::updateStati
void updateStati()
Updates the statuses of all Applications and Scenarios.
Definition: ScenarioListController.cpp:923
IceStorm::parser
Parser * parser
Definition: Parser.cpp:33
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
ScenarioManager::Controller::ScenarioListController::saveScenario
void saveScenario(ScenarioManager::Data_Structure::ApplicationInstancePtr application)
Definition: ScenarioListController.cpp:971
SCENARIOITEMPROXY
@ SCENARIOITEMPROXY
Definition: treeitem.h:37
ScenarioManager
Definition: Application.cpp:166
ScenarioManager::Data_Structure::Application::getPathToExecutable
std::string getPathToExecutable()
Definition: Application.cpp:94
ApplicationInstance
Interface for classes that handle the starting of applications Classes implementing this interface al...
StopStrategyFactory.h
ScenarioManager::Data_Structure::Application::getName
std::string getName()
Definition: Application.cpp:89
ScenarioManager::Controller::ScenarioListController::applicationInstanceClicked
void applicationInstanceClicked(Data_Structure::ApplicationInstancePtr appInstance, ScenarioItem *item)
Gets emitted after an ApplicationInstance has been clicked.
ScenarioManager::Controller::ScenarioListController::createScenario
void createScenario()
Shows a view that allows the user to create a new Scenario.
Definition: ScenarioListController.cpp:538
ScenarioListController.h
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:92
Logging.h
ScenarioManager::Controller::ScenarioListController::removeItem
void removeItem(QModelIndex item)
Removes an item from the model.
Definition: ScenarioListController.cpp:458
ScenarioItem::getScenario
ScenarioManager::Data_Structure::ScenarioPtr getScenario()
If this item represents a Scenario, it is returned.
Definition: scenarioitem.cpp:185
ScenarioManager::Controller::ScenarioListController::statusUpdated
void statusUpdated()
Gets emitted after changes have been made to the States of the Applications.
StarterFactory.h
ScenarioManager::Controller::ScenarioListController::fetchStati
void fetchStati()
fetches application stati over their designated strategy.
Definition: ScenarioListController.cpp:868
ScenarioItem::getApplicationInstance
ScenarioManager::Data_Structure::ApplicationInstancePtr getApplicationInstance()
If this item represents an Application, it is returned.
Definition: scenarioitem.cpp:190
ScenarioManager::Controller::ScenarioListController::getTreeModel
FilterableTreeModelSortFilterProxyModelPtr getTreeModel()
Returns the model used by the ScenarioListView and managed by this controller.
Definition: ScenarioListController.cpp:110
ScenarioManager::Controller::ScenarioListController::updateModel
void updateModel()
Updates the model by reloading all scenarios and applications.
Definition: ScenarioListController.cpp:667
armarx::SimplePeriodicTask
Usage:
Definition: ApplicationNetworkStats.h:32
ScenarioManager::Data_Structure::ScenarioVectorPtr
std::shared_ptr< std::vector< ScenarioPtr > > ScenarioVectorPtr
Definition: Scenario.h:38