ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
plugins.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_lang of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib::lang {
9
10//==================================================================================================
11/// This class usually is used as a base class for types that need to manage simple plug-ins.
12/// Within \alib itself, for example, classes \alib{variables;Configuration} and
13/// \alib{expressions;Compiler} inherit from this class.
14///
15/// Plug-ins are organized with a prioritization. This means, that plug-ins which are inserted with
16/// a higher priority are 'asked' first, and those with a lower value become 'asked' only if higher
17/// prioritized plug-ins did not answer.<br>
18/// However, a derived class can deviate from this behavior. Using the typical \alib class design,
19/// all internal fields are \c protected, hence freely accessible by derived classes.
20///
21/// @tparam TPlugin The plug-in type that this class manages. This type is publicly exposed as
22/// #PluginType
23/// This type is publicly exposed as #PrioritiesType.
24//==================================================================================================
25template<typename TPlugin, typename TPriorities>
26class Plugin
27{
28 public:
29 /// This exposes the template parameter \p{TPlugin} to the outer world.
30 using PluginType= TPlugin;
31
32 /// This exposes the template parameter \p{pTPlugin} to the outer world.
33 using PrioritiesType= TPriorities;
34
35 protected:
36 /// The priority of this plug-in.
38
39 /// Constructor which is protected, as this is a bace class.
40 /// @param pPriority The priority that this plug-in uses.
42 : priority (pPriority) {}
43
44 public:
45 /// Returns the priority of this plug-in which is set during construction.
46 /// @return The priority of this plugin.
48
49}; //class Plugin
50
51//==================================================================================================
52/// This class usually is used as a base class for types that need to manage simple plug-ins.
53/// Within \alib itself, for example, classes \alib{variables;Configuration} and
54/// \alib{expressions;Compiler} inherit from this class.
55///
56/// Plug-ins are organized with a prioritization. This means, that plug-ins which are inserted with
57/// a higher priority are 'asked' first, and those with a lower value become 'asked' only if higher
58/// prioritized plug-ins did not answer.<br>
59/// However, a derived class can deviate from this behavior. Using the typical \alib class design,
60/// all internal fields are \c protected, hence freely accessible by derived classes.
61///
62/// @tparam TPlugin The type of the plug-ins managed. This type is publicly exposed as
63/// #PluginType.
64/// @tparam TPriorities The enumeration type providing the default "plug-in slots" and priorities
65/// of the plug-ins managed. This type is publicly exposed as #PrioritiesType.
66//==================================================================================================
67template<typename TPlugin, typename TPriorities>
69{
70 //################################################################################################
71 // public fields and types
72 //################################################################################################
73 public:
74 /// This exposes the template parameter \p{pTPlugin} to the outer world.
75 using PluginType= TPlugin;
76
77 /// This exposes the template parameter \p{pTPlugin} to the outer world.
78 using PrioritiesType= TPriorities;
79
80 /// Type definition for elements of the list of plug-ins with their priority.
81 struct Slot
82 {
83 TPlugin* plugin; ///< The plug-in.
84 bool owned; ///< If \c true, this container is responsible for deleting
85 ///< the plug-in object.
86 };
87
88 /// The list that stores the plugins.
89 using PluginList= std::vector<Slot>;
90
91 //################################################################################################
92 // internal fields
93 //################################################################################################
94 protected:
95
96 /// The plug-ins we have attached in descending priority order.
98
99 //################################################################################################
100 // Constructor/destructor
101 //################################################################################################
102 public:
103 /// Destructor. All plug-ins that were inserted with parameter \p{responsibility} set to
104 /// \alib{lang;Responsibility::Transfer} will be deleted.
106 for( auto& slot : plugins )
107 if( slot.owned )
108 delete slot.plugin;
109 }
110
111
112
113 //################################################################################################
114 // interface
115 //################################################################################################
116 public:
117 /// Adds the given plug-in to the list of plug-ins.
118 ///
119 /// @param plugin The plug-in to insert.
120 /// @param responsibility If \c Responsibility::Transfer, the given plugin will be deleted
121 /// with destruction of this object.
122 /// Defaults to \c Responsibility::KeepWithSender which denotes that
123 /// the life-cycle of the given external buffer is managed elsewhere.
124 void InsertPlugin( TPlugin* plugin, lang::Responsibility responsibility
126 ALIB_ASSERT_ERROR( plugin != nullptr, "FSPLUGINS", "Nullptr provided for plugin." )
127
128 ALIB_STATIC_ASSERT( Plugin_type_not_virtual,
129 std::has_virtual_destructor<TPlugin>::value
130 || responsibility == lang::Responsibility::KeepWithSender,
131 "Can't take responsibility for plug-in destruction. TPlugin has no virtual destructor.")
132
133 // gcc needs this captured, clang warns.
134 // Its about the ALIB_CALLER inside ALIB_ASSERT_ERROR
136 plugins.insert( std::find_if( plugins.begin(), plugins.end(),
137 [plugin,this]( Slot& ppp)
138 {
139 ALIB_ASSERT_ERROR( ppp.plugin->GetPriority() != plugin->GetPriority(), "FSPLUGINS",
140 "PluginContainer::InsertPlugin(): Plug-in with same priority {} exists",
141 ppp.plugin->GetPriority() )
142
143 return ppp.plugin->GetPriority() < plugin->GetPriority();
144 } ),
145 Slot { plugin, responsibility == lang::Responsibility::Transfer } );
147 }
148
149
150 /// Removes the given plug-in from the list of plug-ins.
151 ///
152 /// Responsibility for deletion of removed plug-ins is passed to the remover in case the
153 /// plug-in was inserted with parameter \p{responsibility} set to
154 /// \alib{lang;Responsibility::Transfer}.
155 ///
156 /// @param plugIn The plug-in to be removed.
157 /// @return \c true if the plug-in was removed, else \c false, which indicates that the
158 /// given plug-in was not found.
159 bool RemovePlugin( TPlugin* plugIn ) {
160 auto it= std::find_if( plugins.begin(), plugins.end(), [plugIn](Slot& pair)
161 {
162 return pair.plugin == plugIn;
163 } );
164 if( it != plugins.end() ) {
165 plugins.erase( it );
166 return true;
167 }
168
169 ALIB_WARNING("LANG", "PluginContainer::RemovePlugin(): Plug-in not found for removal.")
170 return false;
171 }
172
173 /// Remove the plug-in at the given \p{idx} from the list of plug-ins.
174 ///
175 /// Responsibility for deletion of removed plug-ins is passed to the remover in case the
176 /// plug-in was inserted with parameter \p{responsibility} set to
177 /// \alib{lang;Responsibility::Transfer}.
178 ///
179 /// @param idx The index of the plug-in to remove.
180 void RemovePlugin( integer idx ) {
181 ALIB_ASSERT_WARNING( idx < CountPlugins(), "FSPLUGINS",
182 "PluginContainer::RemovePlugin(): Index out of bounds: {} >= {}", idx, CountPlugins() )
183 plugins.erase( plugins.begin() + idx );
184 }
185
186
187 /// Remove the plug-in with the given priority.
188 ///
189 /// Responsibility for deletion of removed plug-ins is passed to the remover in case the
190 /// plug-in was inserted with parameter \p{responsibility} set to
191 /// \alib{lang;Responsibility::Transfer}.
192 ///
193 /// @param priority The priority of the plug-in to remove.
194 /// @return \c true if the plug-in was removed, else \c false, which indicates that no
195 /// plug-in with the given priority was found.
196 TPlugin* RemovePlugin( TPriorities priority ) {
197 TPlugin* plugin= nullptr;
198 plugins.erase( std::remove_if( plugins.begin(), plugins.end(),
199 [priority, &plugin](Slot& entry)
200 {
201 if( entry.priority == priority) {
202 plugin= entry.plugin;
203 return true;
204 }
205 return false;
206 } ),
207 plugins.end() );
208
209 ALIB_ASSERT_WARNING( plugin, "FSPLUGINS", "No Plug-in was removed." )
210
211 return plugin;
212 }
213
214
215 /// Checks if any plug-in is attached. This is useful if optional configuration objects
216 /// are used. In case no plug-in was attached (by a third party), the effort to declare and
217 /// search a variable can be omitted.
218 /// @return \c true if this object has any plugin set, \c false otherwise.
219 bool HasPlugins() { return CountPlugins() > 0; }
220
221 /// Returns the number of plug-ins attached.
222 /// @return The quantity of attached plug-ins.
223 integer CountPlugins() { return integer(plugins.size()); }
224
225 /// Returns the plug-in with the given internal number. Valid numbers are
226 /// 0..[#CountPlugins]. No internal checks for valid plug-in numbers are made.
227 ///
228 /// @param number The number of the plug-in requested.
229 /// @return The plug-in requested.
230 TPlugin* GetPlugin( integer number ) { return plugins[size_t(number)].plugin; }
231
232 /// Returns the priority of the plug-in with the given internal number. Valid numbers are
233 /// 0..[#CountPlugins]. No internal checks for valid plug-in numbers are made.
234 ///
235 /// @param number The number of the plug-in requested.
236 /// @return The priortiy of the plug-in.
237 TPriorities GetPriority( integer number ) { return plugins[size_t(number)].priority; }
238
239
240 /// Returns the plug-in with the given priority. If the plug-in does not exist, \c nullptr
241 /// is returned.
242 ///
243 /// @param priority The priority of the plug-in to return.
244 /// @return The plug-in requested or \c nullptr if not available.
245 TPlugin* GetPlugin( TPriorities priority ) {
246 auto it = std::find_if( plugins.begin(), plugins.end(),
247 [priority](Slot& pair) { return pair.priority == priority; } );
248 if( it != plugins.end() )
249 return it->plugin;
250 return nullptr;
251 }
252
253 /// Same as #GetPlugin, but converts the plug-in found to the template type, which has
254 /// to be explicitly provided with the invocation of this method.
255 ///
256 /// A type-check is performed using standard C++ \c dynamic_cast mechanics.
257 /// If the plugin has a different type, \c nullptr is returned.
258 ///
259 /// @tparam TPluginType The type of the plugin to search.
260 /// @param priority The priority of the plug-in to return.
261 /// @return The plug-in of requested type and priority. \c nullptr if not available.
262 template<typename TPluginType>
263 TPluginType* GetPluginTypeSafe( TPriorities priority )
264 { return dynamic_cast<TPluginType*>( GetPlugin( priority ) ); }
265
266 /// Searches the list of plug-ins for the first found with type \p{TPluginType}.
267 ///
268 /// @tparam TPluginType The type of the plugin to search.
269 /// @return The plug-in of requested type. \c nullptr if not available.
270 template<typename TPluginType>
271 TPluginType* GetPluginTypeSafe() {
272 TPluginType* cast= nullptr;
273 for( auto& ppp : plugins )
274 if( (cast= dynamic_cast<TPluginType*>( ppp.plugin )) != nullptr )
275 break;
276
277 return cast;
278 }
279
280}; // class PluginContainer
281
282} // namespace [alib::lang]
TPlugin * GetPlugin(TPriorities priority)
Definition plugins.inl:245
TPlugin * RemovePlugin(TPriorities priority)
Definition plugins.inl:196
TPriorities PrioritiesType
This exposes the template parameter pTPlugin to the outer world.
Definition plugins.inl:78
void RemovePlugin(integer idx)
Definition plugins.inl:180
TPriorities GetPriority(integer number)
Definition plugins.inl:237
bool RemovePlugin(TPlugin *plugIn)
Definition plugins.inl:159
TPlugin * GetPlugin(integer number)
Definition plugins.inl:230
TPlugin PluginType
This exposes the template parameter pTPlugin to the outer world.
Definition plugins.inl:75
PluginList plugins
The plug-ins we have attached in descending priority order.
Definition plugins.inl:97
void InsertPlugin(TPlugin *plugin, lang::Responsibility responsibility=lang::Responsibility::KeepWithSender)
Definition plugins.inl:124
TPluginType * GetPluginTypeSafe(TPriorities priority)
Definition plugins.inl:263
TPluginType * GetPluginTypeSafe()
Definition plugins.inl:271
std::vector< Slot > PluginList
The list that stores the plugins.
Definition plugins.inl:89
TPriorities PrioritiesType
This exposes the template parameter pTPlugin to the outer world.
Definition plugins.inl:33
PrioritiesType priority
The priority of this plug-in.
Definition plugins.inl:37
TPlugin PluginType
This exposes the template parameter TPlugin to the outer world.
Definition plugins.inl:30
PrioritiesType GetPriority() const
Definition plugins.inl:47
Plugin(PrioritiesType pPriority)
Definition plugins.inl:41
#define ALIB_WARNINGS_IGNORE_UNUSED_LAMBDA_CAPTURE
Definition alib.inl:683
#define ALIB_WARNINGS_RESTORE
Definition alib.inl:719
#define ALIB_WARNING(domain,...)
Definition alib.inl:1063
#define ALIB_STATIC_ASSERT(CondVariable, Cond, Message)
Definition alib.inl:971
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1067
#define ALIB_EXPORT
Definition alib.inl:497
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1066
platform_specific integer
Definition integers.inl:32
@ KeepWithSender
Keeps responsibility, e.g., when passing an object.
Type definition for elements of the list of plug-ins with their priority.
Definition plugins.inl:82
TPlugin * plugin
The plug-in.
Definition plugins.inl:83