ApplicationComponents.hpp
1 #pragma once
2 #include <score/command/CommandData.hpp>
4 #include <score/plugins/Addon.hpp>
5 #include <score/plugins/Interface.hpp>
6 #include <score/plugins/StringFactoryKey.hpp>
7 #include <score/tools/SafeCast.hpp>
8 #include <score/tools/std/HashMap.hpp>
9 #include <score/tools/std/IndirectContainer.hpp>
10 
11 #include <ossia/detail/hash.hpp>
12 
13 #include <score_lib_base_export.h>
14 
15 #include <utility>
16 #include <vector>
17 
18 namespace score
19 {
20 class DocumentDelegateFactory;
21 class DocumentPluginFactory;
22 class InterfaceListBase;
23 class Plugin_QtInterface;
24 class ApplicationPlugin;
25 class GUIApplicationPlugin;
26 class PanelDelegate;
27 
28 using FindCommandKey = std::pair<CommandGroupKey, CommandKey>;
29 struct CommandKeyHash : std::hash<std::string>
30 {
31  std::size_t operator()(const FindCommandKey& val) const noexcept
32  {
33  std::size_t seed = 0;
34  ossia::hash_combine(seed, val.first.toString());
35  ossia::hash_combine(seed, val.second.toString());
36  return seed;
37  }
38 };
39 struct CommandStore : score::hash_map<FindCommandKey, CommandFactory, CommandKeyHash>
40 {
41 public:
42  using score::hash_map<FindCommandKey, CommandFactory, CommandKeyHash>::hash_map;
43 };
44 
45 struct SCORE_LIB_BASE_EXPORT ApplicationComponentsData
46 {
51  ApplicationComponentsData& operator=(const ApplicationComponentsData&) = delete;
53 
55  findInterfaceList(const UuidKey<score::InterfaceBase>& k) const noexcept;
56 
57  std::vector<score::Addon> addons;
58  std::vector<ApplicationPlugin*> appPlugins;
59  std::vector<GUIApplicationPlugin*> guiAppPlugins;
60 
61  score::hash_map<score::InterfaceKey, std::unique_ptr<InterfaceListBase>> factories;
62 
63  CommandStore commands;
64  std::vector<std::unique_ptr<PanelDelegate>> panels;
65 };
66 
67 class SCORE_LIB_BASE_EXPORT ApplicationComponents
68 {
69 public:
71  : m_data(d)
72  {
73  }
74 
75  // Getters for plugin-registered things
76  const auto& applicationPlugins() const { return m_data.appPlugins; }
77  const auto& guiApplicationPlugins() const { return m_data.guiAppPlugins; }
78  const auto& addons() const { return m_data.addons; }
79 
80  template <typename T>
81  T& applicationPlugin() const
82  {
83  for(auto& elt : m_data.appPlugins)
84  {
85  if(auto c = dynamic_cast<T*>(elt))
86  {
87  return *c;
88  }
89  }
90 
91  SCORE_ABORT;
92  throw;
93  }
94 
95  template <typename T>
96  T& guiApplicationPlugin() const
97  {
98  for(auto& elt : m_data.guiAppPlugins)
99  {
100  if(auto c = dynamic_cast<T*>(elt))
101  {
102  return *c;
103  }
104  }
105 
106  SCORE_ABORT;
107  throw;
108  }
109 
110  template <typename T>
111  T* findApplicationPlugin() const
112  {
113  for(auto& elt : m_data.appPlugins)
114  {
115  if(auto c = dynamic_cast<T*>(elt))
116  {
117  return c;
118  }
119  }
120 
121  return nullptr;
122  }
123 
124  template <typename T>
125  T* findGuiApplicationPlugin() const
126  {
127  for(auto& elt : m_data.guiAppPlugins)
128  {
129  if(auto c = dynamic_cast<T*>(elt))
130  {
131  return c;
132  }
133  }
134 
135  return nullptr;
136  }
137 
138  auto panels() const { return wrap_indirect(m_data.panels); }
139 
140  template <typename T>
141  T& panel() const
142  {
143  for(auto& elt : m_data.panels)
144  {
145  if(auto c = dynamic_cast<T*>(elt.get()))
146  {
147  return *c;
148  }
149  }
150 
151  SCORE_ABORT;
152  throw;
153  }
154 
155  template <typename T>
156  T* findPanel() const
157  {
158  for(auto& elt : m_data.panels)
159  {
160  if(auto c = dynamic_cast<T*>(elt.get()))
161  {
162  return c;
163  }
164  }
165 
166  return nullptr;
167  }
168 
169  template <typename T>
170  const T* findInterfaces() const
171  {
172  static_assert(
173  T::factory_list_tag, "This needs to be called with a factory list class");
174 
175  return static_cast<T*>(m_data.findInterfaceList(T::static_interfaceKey()));
176  }
177 
178  template <typename T>
179  const T& interfaces() const
180  {
181  static_assert(
182  T::factory_list_tag, "This needs to be called with a factory list class");
183 
184  if(auto ptr = m_data.findInterfaceList(T::static_interfaceKey()))
185  return *safe_cast<T*>(ptr);
186 
187  SCORE_ABORT;
188  throw;
189  }
190 
191  score::Command* instantiateUndoCommand(const CommandData& cmd) const;
192 
193 private:
194  const score::ApplicationComponentsData& m_data;
195 };
196 
197 SCORE_LIB_BASE_EXPORT const ApplicationComponents& AppComponents();
198 }
Definition: ConsolePanel.hpp:36
Definition: UuidKey.hpp:343
Definition: ApplicationComponents.hpp:68
The Command class.
Definition: Command.hpp:34
InterfaceListBase Interface to access factories.
Definition: InterfaceList.hpp:29
Base toolkit upon which the software is built.
Definition: Application.cpp:90
Definition: ApplicationComponents.hpp:46
Utility class for the serialization and deserialization of commands.
Definition: CommandData.hpp:14
Definition: ApplicationComponents.hpp:30
Definition: ApplicationComponents.hpp:40