FactorySetup.hpp
1 #pragma once
2 #include <score/plugins/InterfaceList.hpp>
3 
4 #include <core/application/ApplicationSettings.hpp>
5 
6 #include <ossia/detail/for_each.hpp>
7 
8 #include <type_traits>
9 
10 namespace score
11 {
12 struct GUIApplicationContext;
13 struct ApplicationContext;
14 }
15 SCORE_LIB_BASE_EXPORT bool
16 appcontext_has_ui(const score::GUIApplicationContext&) noexcept;
17 SCORE_LIB_BASE_EXPORT bool appcontext_has_ui(const score::ApplicationContext&) noexcept;
18 
23 template <typename Base_T, typename... Args>
24 auto make_ptr_vector() noexcept
25 {
26  std::vector<std::unique_ptr<Base_T>> vec;
27 
28  vec.reserve(sizeof...(Args));
29  (vec.push_back(std::unique_ptr<Base_T>((Base_T*)new Args)), ...);
30 
31  return vec;
32 }
33 
41 template <
42  typename Context_T,
43  typename Factory_T>
44 struct FactoryBuilder // sorry padre for I have sinned
45 {
46  static score::InterfaceBase* make(const Context_T& ctx)
47  {
48  if constexpr(std::is_constructible_v<Factory_T, const Context_T&>)
49  return new Factory_T(ctx);
50  else
51  return new Factory_T();
52  }
53 };
54 
58 template <typename Context_T, typename... Args>
59 void fill_ptr_vector(
60  const Context_T& context, std::vector<score::InterfaceBase*>& vec) noexcept
61 {
62  vec.reserve(sizeof...(Args));
63  (vec.push_back(FactoryBuilder<Context_T, Args>::make(context)), ...);
64 }
65 
66 template <typename T>
67 struct has_ui : public std::false_type
68 {
69 };
70 template <typename T>
71  requires(T::ui_interface)
72 struct has_ui<T>
73 {
74  static const constexpr bool value = T::ui_interface;
75 };
76 
82 template <typename Factory_T, typename... Types_T>
83 struct FW_T
84 {
85 #if !defined(_MSC_VER)
86  static_assert(
87  (std::is_base_of<Factory_T, Types_T>::value && ...),
88  "A type is not child of the parent.");
89 #endif
90  template <typename Context_T>
91  bool operator()(
92  const Context_T& ctx, const score::InterfaceKey& fact,
93  std::vector<score::InterfaceBase*>& vec) noexcept
94  {
95  if constexpr(has_ui<Factory_T>::value)
96  {
97  if(!appcontext_has_ui(ctx))
98  {
99  return false;
100  }
101  }
102 
103  if(fact == Factory_T::static_interfaceKey())
104  {
105  vec.reserve(sizeof...(Types_T));
106  (vec.push_back(FactoryBuilder<Context_T, Types_T>::make(ctx)), ...);
107  return true;
108  }
109 
110  return false;
111  }
112 };
113 
114 template <typename Factory_T, typename... Args>
115 using FW = FW_T<Factory_T, Args...>;
116 
135 template <typename Context_T, typename... Args>
136 auto instantiate_factories(const Context_T& ctx, const score::InterfaceKey& key) noexcept
137 {
138  std::vector<score::InterfaceBase*> vec;
139 
140  ossia::for_each_type_if_tagged<Args...>([&](auto t) {
141  using fw_t = typename decltype(t)::type;
142  return fw_t{}(ctx, key, vec);
143  });
144 
145  return vec;
146 }
Definition: UuidKey.hpp:343
Base class for plug-in interfaces.
Definition: Interface.hpp:52
Base toolkit upon which the software is built.
Definition: Application.cpp:90
Used to group base classes and concrete classes in a single argument list.
Definition: FactorySetup.hpp:84
Definition: FactorySetup.hpp:45
Definition: FactorySetup.hpp:68
Used to access all the application-wide state and structures.
Definition: ApplicationContext.hpp:24
Specializes ApplicationContext with the QMainWindow.
Definition: GUIApplicationContext.hpp:15