MT Showcase SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
Showcase.hpp
1 #pragma once
2 
3 #include <type_traits>
4 #include <Radiant/Singleton.hpp>
5 
6 #include <QString>
7 
8 #include <MultiWidgets/Widget.hpp>
9 
10 #include "Export.hpp"
11 
12 #include "CachedGraph.hpp"
13 #include "Graph.hpp"
14 #include "GraphGenerators.hpp"
15 #include "ShowcaseTypes.hpp"
16 #include "Configuration.hpp"
17 #include "UserInterface.hpp"
18 #include "UIComponent.hpp"
19 #include "ServiceProvider.hpp"
20 #include "RemoteControl.hpp"
21 #include "Package.hpp"
22 
23 #include <boost/expected/expected.hpp>
24 
25 namespace WebBrowserCef
26 {
27  class BrowserSessionManager;
28 }
29 namespace Luminous
30 {
31  class PDFManager;
32 }
33 
35 namespace Showcase
36 {
37  class ShowcaseLicense;
38  class WidgetInstance;
39  class ScheduleManager;
40  class AppSchedule;
41  INTRUSIVE_PTR_FORWARD_DECL(, ErrorPageWidget);
42 
43  enum class ShowcaseExitCodes
44  {
46  NORMAL_EXIT = 0,
48  NO_LICENSE = 50
49  };
50 
54  class SHOWCASE_API Showcase
55  {
56  DECLARE_SINGLETON(Showcase);
57  public:
58  ~Showcase();
59 
62  void tearDown();
63 
66  GraphPtr graph();
67 
70  UserInterfacePtr ui();
71 
74  ServiceProviderPtr services();
75 
78  RemoteControlPtr remoteControl();
79 
83  std::shared_ptr<ScheduleManager> scheduleManager();
84 
88  void init();
89 
93  PackagePtr packageOfComponent(const QString& componentName);
94 
97  void addCSSFiles(const std::vector<QString>& filePaths);
98 
104  void addCSSFile(const QString& filePath);
105 
108  void removeCSSFiles(const std::vector<QString>& filePaths);
109 
112  void removeCSSFile(const QString& filePath);
113 
117  static void setAssetsPath(const QString & path);
118 
122  void run();
123 
127  bool hasRunConfiguration() const;
128 
132  RunConfigurationPtr runConfiguration();
133 
137  void reloadRunConfiguration(bool showLoadingOverlay = false);
138 
142  void runConfigurationChanged(int id);
143 
145  void reloadSchedule();
148  void scheduleChanged(int id);
149 
153  void updateRemoteConnectionState(bool hasConnection);
154  void updateRunConfigurationState(bool hasRunConf);
155 
156  // Want to add overloads of registering factories to Showcase-class
157  // also, so that we do not need to have multiple implementations
158  // of FactoryRegistrant
159  FactoryKey<GraphGenerator>
160  registerFactory(const QString& name, GraphGenFactoryPtr factory);
161 
162  FactoryKey<PropertyGenerator>
163  registerFactory(const QString& name, PropGenFactoryPtr factory);
164 
165  FactoryKey<UIComponent>
166  registerFactory(const QString &name, UIComponentFactoryPtr factory);
167 
168  FactoryKey<ServiceComponent>
169  registerFactory(const QString &name, ServiceComponentFactoryPtr factory);
170 
171  // Same for unregister-functions
172  bool unregisterFactory(FactoryKey<GraphGenerator> key);
173  bool unregisterFactory(FactoryKey<PropertyGenerator> key);
174  bool unregisterFactory(FactoryKey<UIComponent> key);
175  bool unregisterFactory(FactoryKey<ServiceComponent> key);
177 
181  static std::weak_ptr<Showcase> weakInstance();
182 
185  static const QString& version();
186 
188  static QByteArray showcaseGitHash();
189 
193  void registerWidgetInstance(Valuable::Node::Uuid widgetId, std::weak_ptr<WidgetInstance> instance);
196  void unregisterWidgetInstance(Valuable::Node::Uuid widgetId);
201  std::shared_ptr<WidgetInstance> widgetInstance(Valuable::Node::Uuid widgetId);
202 
206  void showErrorScreen(const QByteArray & css = "", const QString & error = "");
207 
209  void removeErrorScreen();
210 
214  QString editorAddress(bool hideDefaultPort = true) const;
215 
219  static boost::expected<QString, QString> showcaseRoot();
220 
222  void minimize();
223 
225  void resume();
226 
230  static QString localDataDirectory();
231 
235  static QString localCacheDirectory();
236 
239  static QString logDirectory();
240 
244  static void errorMessage(const QString& msg);
245 
250  QString remoteControlServer() const;
251 
254  std::shared_ptr<folly::Executor> graphExecutor() { return m_graphExecutor; }
257  std::shared_ptr<folly::Executor> configExecutor() { return m_configExecutor; }
258 
263  bool verifyGraphExecutorCallingThread() const;
264 
272  void addThemeComponent(const QString & component);
273 
276  const QStringList & themeComponents() const;
277 
281  void setShowExit(bool show);
282 
283  private:
284  void reloadServices();
285  void reloadTheme();
286  void reloadUi();
287  void reloadAppSchedule();
288  void showExpiredLicenseWarning(const ShowcaseLicense& license);
289 
291  void clear(bool removeError = true);
292 
294  bool checkStatus();
295  bool checkRemoteControlConnection();
296  bool checkDatabaseConnection();
297  bool checkAssets();
298  bool checkRunConfiguration();
299 
300  void loadPackagesFrom(const QStringList& paths);
301  void parsePackagesFrom(const QString& path, std::vector<PackagePtr>& packages);
302 
303  Showcase();
304 
305  GraphPtr m_graph;
306  UserInterfacePtr m_ui;
307  ServiceProviderPtr m_services;
308  RemoteControlPtr m_remoteControl;
309  std::shared_ptr<ScheduleManager> m_scheduleManager;
310  std::shared_ptr<AppSchedule> m_appSchedule;
311  std::shared_ptr<WebBrowserCef::BrowserSessionManager> m_browserSessions;
312  std::shared_ptr<Luminous::PDFManager> m_pdfManager;
313 
314  std::map<QString, PackagePtr> m_loadedPackages;
315  QStringList m_themeComponents;
316 
317  std::shared_ptr<RunConfiguration> m_runConf;
318  std::shared_ptr<ScheduleConfig> m_schedule;
319 
320  std::map<QString, size_t> m_loadedCSSFiles;
321 
322  std::mutex m_widgetInstancesMutex;
323  std::map<Valuable::Node::Uuid, std::weak_ptr<WidgetInstance>> m_widgetInstances;
324 
326  std::mutex m_stateMutex;
328  bool m_hasRemoteConnection;
330  bool m_hasRunConf;
331 
332  bool m_showExit;
333 
334  ErrorPageWidgetPtr m_errorScreen;
335 
336  std::shared_ptr<Radiant::BGThread> m_graphThreadPool;
337  std::shared_ptr<folly::Executor> m_graphExecutor;
338 
339  std::shared_ptr<Radiant::BGThread> m_configThreadPool;
340  std::shared_ptr<folly::Executor> m_configExecutor;
341 
342  template <typename Factory> friend class FactoryRegistrant;
343  };
344  typedef std::shared_ptr<Showcase> ShowcasePtr;
345 
346 
347  // -------------------------------------------------------------------
348 
350 
352  template <typename T, typename Predicate = void>
353  struct APIClass;
354 
355  template <typename T>
356  struct APIClass<T, typename std::enable_if<std::is_base_of<GraphGenerator, T>::value>::type>
357  { typedef GraphGenerator type; };
358 
359  template <typename T>
360  struct APIClass<T, typename std::enable_if<std::is_base_of<PropertyGenerator, T>::value>::type>
361  { typedef PropertyGenerator type; };
362 
363  template <typename T>
364  struct APIClass<T, typename std::enable_if<std::is_base_of<UIComponent, T>::value>::type>
365  { typedef UIComponent type; };
366 
367  template <typename T>
368  struct APIClass<T, typename std::enable_if<std::is_base_of<ServiceComponent, T>::value>::type>
369  { typedef ServiceComponent type; };
370 
371  // -------------------------------------------------------------------
372 
373  template <typename ComponentType>
374  class FactoryRegistrant
375  {
376  public:
377  typedef typename APIClass<ComponentType>::type Base;
378  typedef typename ShowcaseFactory<Base>::CreateFunc CreateFunc;
379 
380  FactoryRegistrant(const QString& name, CreateFunc f);
381  ~FactoryRegistrant();
382 
383  private:
384  FactoryKey<Base> m_key;
385  QString m_name;
386  };
387 
388  // ------------------------------------------------------------------
389 
390 
391  template <typename ComponentType>
392  FactoryRegistrant<ComponentType>::FactoryRegistrant(
393  const QString &name, CreateFunc f)
394  : m_name(name)
395  {
398  ShowcaseFactoryPtr<Base> factory =
399  std::make_shared<ShowcaseFactory<Base>>(typeid(ComponentType), f);
400 
401  auto weak = Showcase::weakInstance();
402  auto showcase = weak.lock();
403  if(!showcase)
404  return;
405  auto package = showcase->packageOfComponent(name);
406 
407  if(!package) {
410  Showcase::errorMessage(QString("Couldn't find package for component %1.").arg(name.toUtf8().data()));
411  assert(package);
412  }
413 
414  ComponentDefinitionPtr component = package->component(name);
415  assert(component);
416  component->initComponent();
417 
418  const Schema& schema = component->schema();
419  factory->setSchema(schema);
420 
421  m_key = showcase->registerFactory(name, factory);
422  }
423 
424  template <typename ComponentType>
425  FactoryRegistrant<ComponentType>::~FactoryRegistrant()
426  {
427  std::weak_ptr<Showcase> weak = Showcase::weakInstance();
428  std::shared_ptr<Showcase> s = weak.lock();
429 
430  if(s)
431  s->unregisterFactory(m_key);
432  }
433 
434 }
435 
436 #define _MW_PLUGIN_CONCAT(x,y) x ## y
437 #define MW_PLUGIN_CONCAT(x,y) _MW_PLUGIN_CONCAT(x,y)
438 
439 #define SHOWCASE_COMPONENT(name, type) \
440 namespace {\
441 Showcase::FactoryRegistrant<type> MW_PLUGIN_CONCAT(component, __LINE__) \
442 (name, std::make_shared<type> ); \
443 }