Application.h
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 Nils Adermann (naderman at naderman dot de)
20 * @author Kai Welke (welke at kit dot edu)
21 * @author Jan Issac (jan dot issac at gmail dot com)
22 * @date 2010
23 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
24 * GNU General Public License
25 */
26 
27 #pragma once
28 
29 #include "../ArmarXManager.h"
30 #include "../Component.h" // for Component
31 #include "../logging/Logging.h"
32 #include "../system/ArmarXDataPath.h"
33 #include "../system/ImportExport.h" // for ARMARXCORE_IMPORT_EXPORT
34 #include "../system/cmake/CMakePackageFinder.h"
35 #include "ApplicationOptions.h"
36 #include "ApplicationNetworkStats.h" // for ApplicationNetworkStatsPtr
37 #include "ArmarXCore/core/ArmarXFwd.h" // for ArmarXManagerPtr
40 #include "ArmarXCore/core/exceptions/Exception.h" // for LocalException
41 #include "properties/PropertyUser.h" // for PropertyDefinitionsPtr, etc
42 
43 #include <Ice/Application.h> // for Application
44 #include <Ice/BuiltinSequences.h> // for StringSeq
45 #include <Ice/PropertiesF.h> // for PropertiesPtr
46 #include <IceUtil/Handle.h> // for Handle, HandleBase
47 
48 #include <string> // for string
49 #include <vector> // for vector
50 #include <mutex>
51 
52 
53 namespace Ice
54 {
55  struct InitializationData;
56 } // namespace Ice
57 
58 #define xstr(s) stringify(s)
59 #define stringify(s) #s
60 
66 namespace std
67 {
68  class thread;
69 }
70 
71 namespace armarx
72 {
73  // forward declarations
74  class ManagedIceObjectRegistryInterface;
75  class ThreadPool;
76  using ThreadPoolPtr = std::shared_ptr<ThreadPool>;
79 
84 
88  class Application;
89 
94 
103  {
104  public:
108  ApplicationPropertyDefinitions(std::string prefix);
109  };
110 
194  public Ice::Application,
195  public PropertyUser
196  {
197  public:
201  Application();
209  template <class T, typename ...Args>
210  static ApplicationPtr createInstance(Args&&... args)
211  {
212  std::unique_lock lock(instanceMutex);
213 
214  if (instance)
215  {
216  throw LocalException("Application instance already created");
217  }
218 
219  instance = ApplicationPtr(new T(std::forward<Args>(args)...));
220 
221  return instance;
222  }
223 
230  static ApplicationPtr getInstance();
231 
232  static void setInstance(ApplicationPtr const& inst);
233 
234  static std::string GetVersion()
235  {
236 #ifdef ARMARX_VERSION
237  return xstr(ARMARX_VERSION);
238 #else
239  return "undefined";
240 #endif
241  }
242 
246  int run(int argc, char* argv[]) override;
247 
254  void setName(const std::string& name);
255 
261  std::string getName() const;
262 
268  void interruptCallback(int signal) override;
269 
270  void registerDataPathsFromDependencies(std::string dependencies);
271 
277  std::vector<std::string> getArmarXPackageNames();
278 
279  bool isPackageAutoDiscoveryEnabled();
280 
281  static std::string GetArmarXConfigDefaultPath(bool envVarExpanded = true);
282  static Ice::StringSeq GetDefaultsPaths();
283  static void LoadDefaultConfig(Ice::PropertiesPtr properties);
284  static const std::string& GetProjectName();
285  static const Ice::StringSeq& GetProjectDependencies();
286 
291  void setIceProperties(Ice::PropertiesPtr properties) override;
292 
293  void updateIceProperties(const Ice::PropertyDict& properties) override;
294 
295  void icePropertiesUpdated(const std::set<std::string>& changedProperties) override;
296  static const std::string ArmarXUserConfigDirEnvVar;
297 
298  const ThreadPoolPtr& getThreadPool() const;
299  bool getForbidThreadCreation() const;
300  void setForbidThreadCreation(bool value);
301  void enableLibLoading(bool enable = true);
302 
303  void storeCommandLineArguments(int argc, char* argv[]);
304  const std::vector<std::string>& getCommandLineArguments() const;
305  protected:
309  PropertyDefinitionsPtr createPropertyDefinitions() override;
310 
317  virtual void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) = 0;
318 
332  virtual int exec(const ArmarXManagerPtr& armarXManager);
333 
341  int doMain(int argc, char* argv[], const Ice::InitializationData& initData, Ice::Int i) override;
342 
343  void loadDefaultConfig(int argc, char* argv[], const Ice::InitializationData& initData);
344 
345  void loadDependentProjectDatapaths();
346 
354  virtual std::string getDomainName();
355 
359  ArmarXManagerPtr getArmarXManager();
360 
361 
362 
366  void showHelp(ApplicationOptions::Options& options);
367 
371  Ice::PropertiesPtr parseOptionsMergeProperties(int argc, char* argv[]);
372 
373 
378  static void HandlerInterrupt(int sig);
379 
380 
385  static void HandlerFault(int sig);
386 
387  private:
388 
389  void loadLibrariesFromProperties();
390 
394  static ApplicationPtr instance;
395 
399  static std::mutex instanceMutex;
400 
404  std::string applicationName;
405 
409  ArmarXManagerPtr armarXManager;
410 
411  ApplicationNetworkStatsPtr applicationNetworkStats;
412 
413  std::shared_ptr<std::thread> shutdownThread;
414 
415  static std::string ProjectName;
416  static Ice::StringSeq ProjectDependendencies;
417 
418  ThreadPoolPtr threadPool;
419  bool forbidThreadCreation = false;
420  bool libLoadingEnabled = false;
421 
422  std::vector<std::string> commandLineArguments;
423  };
424 
426  {
427  // Application interface
428  protected:
429  void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) override
430  {
431  }
432  };
433 }
434 
436 {
437  template<class ComponentT, class AppT>
443  class SimpleSingleComponentApp : virtual public AppT
444  {
445  void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) override
446  {
447  registry->addObject(Component::create<ComponentT>(properties, "", appConfigDomain));
448  }
449 
450  public:
451  std::string appConfigName;
452  std::string appConfigDomain;
453  };
454 }
455 
456 namespace armarx
457 {
484  template<class ComponentT, class AppT = armarx::Application>
485  int runSimpleComponentApp(int argc, char* argv[], std::string appName, const std::string& configName = "", const std::string& configDomain = "ArmarX", bool enableLibLoading = false)
486  {
487  armarx::ApplicationPtr app = AppT::template createInstance<internal::SimpleSingleComponentApp<ComponentT, AppT> >();
488 
490  sApp->appConfigDomain = configDomain;
491  sApp->appConfigName = configName;
492  app->enableLibLoading(enableLibLoading);
493  app->setName(appName);
494  app->storeCommandLineArguments(argc, argv);
495  return app->main(argc, argv);
496  }
497 
502  {
503  public:
504  MultipleComponentsApplication(std::vector<ComponentPtr> components) :
505  components(components) {}
506 
507  private:
508  std::vector<ComponentPtr> components;
509 
510  // Application interface
511  protected:
512  void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) override
513  {
514  for (ComponentPtr comp : components)
515  {
516  registry->addObject(comp);
517  }
518  }
519  };
520 
521  template<class ComponentType>
522  std::vector<ComponentPtr> createComponents(ComponentType comp)
523  {
524  return {comp};
525  }
526 
527  template<class ComponentType, class... ComponentTypes >
528  std::vector<ComponentPtr> createComponents(ComponentType comp, ComponentTypes... components)
529  {
530  std::vector<ComponentPtr> result {comp};
531  std::vector<ComponentPtr> tempResult = createComponents(components...);
532  result.insert(result.end(), tempResult.begin(), tempResult.end());
533  return result;
534  }
535 
536  template<class... ComponentTypes >
537  std::vector<ComponentPtr> createComponentsUtil(ComponentTypes&& ... components)
538  {
539  std::vector<ComponentPtr> result;
540  std::vector<ComponentPtr> tempResult = createComponents(components...);
541  result.insert(result.end(), tempResult.begin(), tempResult.end());
542  return result;
543  }
544 
561  template<class... ComponentTypes >
562  std::tuple<armarx::ApplicationPtr, std::vector<ComponentPtr> > runMultipleComponentsApp(int argc, char* argv[], std::string appName, const std::string& configDomain = "ArmarX")
563  {
564  Ice::PropertiesPtr props = Ice::createProperties(argc, argv);
565  std::vector<ComponentPtr> comps = createComponentsUtil(Component::create<ComponentTypes>(props, "", configDomain)...);
567 
568  app->setName(appName);
569  return std::make_tuple(app, comps);
570  }
571 
572 }
armarx::internal::SimpleSingleComponentApp::appConfigName
std::string appConfigName
Definition: Application.h:451
armarx::internal
Definition: Application.h:435
armarx::runMultipleComponentsApp
std::tuple< armarx::ApplicationPtr, std::vector< ComponentPtr > > runMultipleComponentsApp(int argc, char *argv[], std::string appName, const std::string &configDomain="ArmarX")
Convenience function to create an app with multiple components easily.
Definition: Application.h:562
ApplicationOptions.h
armarx::ThreadPoolPtr
std::shared_ptr< ThreadPool > ThreadPoolPtr
Definition: Application.h:76
xstr
#define xstr(s)
Definition: Application.h:58
IceInternal::Handle< ::Ice::Properties >
armarx::ApplicationNetworkStats
The ApplicationNetworkStats class implements the Ice::Instrumentation::CommunicatorObserver interface...
Definition: ApplicationNetworkStats.h:51
armarx::createComponentsUtil
std::vector< ComponentPtr > createComponentsUtil(ComponentTypes &&... components)
Definition: Application.h:537
armarx::createComponents
std::vector< ComponentPtr > createComponents(ComponentType comp)
Definition: Application.h:522
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::MultipleComponentsApplication::setup
void setup(const ManagedIceObjectRegistryInterfacePtr &registry, Ice::PropertiesPtr properties) override
Setup method to be implemented by user applications.
Definition: Application.h:512
Ice::createProperties
Ice::PropertiesPtr createProperties()
PropertyUser.h
armarx::DummyApplication
Definition: Application.h:425
armarx::ApplicationOptions::Options
Stucture containing the parsed options of the application.
Definition: ApplicationOptions.h:76
ApplicationNetworkStats.h
armarx::runSimpleComponentApp
int runSimpleComponentApp(int argc, char *argv[], std::string appName, const std::string &configName="", const std::string &configDomain="ArmarX", bool enableLibLoading=false)
Creates and runs an application (of AppT) for the given component (ComponentT).
Definition: Application.h:485
armarx::ApplicationPtr
IceUtil::Handle< Application > ApplicationPtr
Definition: Application.h:93
armarx::PropertyDefinitionContainer
PropertyDefinitionContainer.
Definition: PropertyDefinitionContainer.h:53
armarx::Application
Baseclass for all ArmarX applications.
Definition: Application.h:193
armarx::ApplicationPropertyDefinitions
Application property definition container.
Definition: Application.h:101
armarx::internal::SimpleSingleComponentApp::appConfigDomain
std::string appConfigDomain
Definition: Application.h:452
armarx::internal::SimpleSingleComponentApp
Used by runSimpleComponentApp<ComponentT, AppT>. This class can't be defined in function,...
Definition: Application.h:443
ArmarXFwd.h
Ice
Definition: DBTypes.cpp:64
armarx::DummyApplication::setup
void setup(const ManagedIceObjectRegistryInterfacePtr &registry, Ice::PropertiesPtr properties) override
Setup method to be implemented by user applications.
Definition: Application.h:429
PropertyDefinitionContainer.h
std
Definition: Application.h:66
IceUtil::Handle< ApplicationNetworkStats >
armarx::Application::createInstance
static ApplicationPtr createInstance(Args &&... args)
Creates the one application instance of type T.
Definition: Application.h:210
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
ManagedIceObjectRegistryInterface.h
armarx::Application::GetVersion
static std::string GetVersion()
Definition: Application.h:234
armarx::MultipleComponentsApplication::MultipleComponentsApplication
MultipleComponentsApplication(std::vector< ComponentPtr > components)
Definition: Application.h:504
ARMARXCORE_IMPORT_EXPORT
#define ARMARXCORE_IMPORT_EXPORT
Definition: ImportExport.h:38
armarx::MultipleComponentsApplication
Do not use! Use armarx::runMultipleComponentsApp()
Definition: Application.h:501
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
armarx::ApplicationOptions::showHelp
void showHelp(ApplicationPtr application, ArmarXDummyManagerPtr dummyManager, Options options, Ice::PropertiesPtr properties, std::ostream &out=std::cout)
Prints help according to the format selection in options.
Definition: ApplicationOptions.cpp:169
armarx::PropertyUser
Abstract PropertyUser class.
Definition: PropertyUser.h:62
armarx::Application::ArmarXUserConfigDirEnvVar
static const std::string ArmarXUserConfigDirEnvVar
Definition: Application.h:296
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
Exception.h