Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
CaseOptionService.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* CaseOptionService.h (C) 2000-2025 */
9/* */
10/* Data set options using a service. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_CORE_CASEOPTIONSERVICE_H
13#define ARCANE_CORE_CASEOPTIONSERVICE_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/Functor.h"
19
20#include "arcane/core/CaseOptions.h"
21#include "arcane/core/IServiceMng.h"
22#include "arcane/core/ISubDomain.h"
23#include "arcane/core/ServiceUtils.h"
24#include "arcane/core/ArcaneException.h"
25#include "arcane/core/IFactoryService.h"
26#include "arcane/core/IServiceFactory.h"
27#include "arcane/core/StringDictionary.h"
28#include "arcane/core/CaseOptionServiceImpl.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39class IService;
41template <typename T> class CaseOptionServiceT;
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46/*!
47 * \brief Implementation of the container for a service of type \a InterfaceType.
48 */
49template <typename InterfaceType>
52{
53 public:
54
56 {
58 }
59
60 bool tryCreateService(Integer index, Internal::IServiceFactory2* factory, const ServiceBuildInfoBase& sbi) override
61 {
62 auto true_factory = dynamic_cast<Internal::IServiceFactory2T<InterfaceType>*>(factory);
63 if (true_factory) {
64 Ref<InterfaceType> sr = true_factory->createServiceReference(sbi);
65 InterfaceType* s = sr.get();
66 m_services_reference[index] = sr;
67 m_services[index] = s;
68 return (s != nullptr);
69 }
70 return false;
71 }
72
73 bool hasInterfaceImplemented(Internal::IServiceFactory2* factory) const override
74 {
75 auto true_factory = dynamic_cast<Internal::IServiceFactory2T<InterfaceType>*>(factory);
76 if (true_factory) {
77 return true;
78 }
79 return false;
80 }
81
82 //! Allocates an array for \a size elements
83 void allocate(Integer asize) override
84 {
85 m_services.resize(asize, nullptr);
86 m_services_reference.resize(asize);
87 }
88
89 //! Returns the number of elements in the array.
90 Integer nbElem() const override
91 {
92 return m_services.size();
93 }
94
95 InterfaceType* child(Integer i) const
96 {
97 return m_services[i];
98 }
99
100 Ref<InterfaceType> childRef(Integer i) const
101 {
102 return m_services_reference[i];
103 }
104
105 public:
106
107 //! Removes service instances
109 {
110 m_services_reference.clear();
111 m_services.clear();
112 }
113
114 public:
115
116 ArrayView<InterfaceType*> view() { return m_services; }
117
118 private:
119
120 UniqueArray<InterfaceType*> m_services;
121 UniqueArray<Ref<InterfaceType>> m_services_reference;
122};
123
124/*---------------------------------------------------------------------------*/
125/*---------------------------------------------------------------------------*/
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
130/*!
131 * \ingroup CaseOption
132 * \brief Base class for options using services.
133 *
134 * Instances of this class are not copyable.
135 */
136class ARCANE_CORE_EXPORT CaseOptionService
137{
138 public:
139
140 CaseOptionService(const CaseOptionBuildInfo& cob, bool allow_null, bool is_optional)
141 : m_impl(new CaseOptionServiceImpl(cob, allow_null, is_optional))
142 {
143 }
144
145 virtual ~CaseOptionService() = default;
146
147 public:
148
149 CaseOptionService(const CaseOptionService&) = delete;
150 const CaseOptionService& operator=(const CaseOptionService&) = delete;
151
152 public:
153
154 ARCANE_DEPRECATED_REASON("Y2022: Use toICaseOptions() instead")
155 operator CaseOptions&() { return *_impl(); }
156
157 ARCANE_DEPRECATED_REASON("Y2022: Use toICaseOptions() instead")
158 operator const CaseOptions&() const { return *_impl(); }
159
160 public:
161
162 const ICaseOptions* toICaseOptions() { return _impl(); }
163
164 public:
165
166 String rootTagName() const { return m_impl->rootTagName(); }
167 String name() const { return m_impl->name(); }
168 String serviceName() const { return m_impl->serviceName(); }
169 bool isOptional() const { return m_impl->isOptional(); }
170 bool isPresent() const { return m_impl->isPresent(); }
171 void addAlternativeNodeName(const String& lang, const String& name)
172 {
173 m_impl->addAlternativeNodeName(lang, name);
174 }
175 void getAvailableNames(StringArray& names) const
176 {
177 m_impl->getAvailableNames(names);
178 }
179
180 /*!
181 * \brief Sets the default value for the service name.
182 *
183 * If the option is not present in the data set, its value will be
184 * that specified by the \a def_value argument; otherwise, calling this method
185 * has no effect.
186 *
187 * This method can only be called during phase 1 of reading
188 * the data set because the service is already instantiated afterwards.
189 * A FatalErrorException exception is raised if this method is called and the
190 * service is already instantiated.
191 */
192 void setDefaultValue(const String& def_value)
193 {
194 m_impl->setDefaultValue(def_value);
195 }
196
197 //! Adds the default value \a value to the category \a category
198 void addDefaultValue(const String& category, const String& value)
199 {
200 m_impl->addDefaultValue(category, value);
201 }
202
203 /*!
204 * \brief Sets the mesh name to which the service will be associated.
205 *
206 * If null, the service is associated with the default mesh of the subdomain
207 * (ISubDomain::defaultMeshHandle()). The actual association happens when reading
208 * the options. Calling this method after reading the options will have
209 * no impact.
210 */
211 void setMeshName(const String& mesh_name);
212
213 /*!
214 * \brief Mesh name to which the service is associated.
215 *
216 * This is the name of the mesh as specified in the service descriptor
217 * (the 'axl' file). To get the associated mesh after reading the options
218 * you must use ICaseOptions::meshHandle().
219 */
220 String meshName() const;
221
222 protected:
223
224 CaseOptionServiceImpl* _impl() { return m_impl.get(); }
225 const CaseOptionServiceImpl* _impl() const { return m_impl.get(); }
226
227 private:
228
229 ReferenceCounter<CaseOptionServiceImpl> m_impl;
230};
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
235template <class InterfaceType>
236class CaseOptionServiceT
237: public CaseOptionService
238{
239 public:
240
241 CaseOptionServiceT(const CaseOptionBuildInfo& cob, bool allow_null, bool is_optional)
242 : CaseOptionService(cob, allow_null, is_optional)
243 {
244 _impl()->setContainer(&m_container);
245 }
246 ~CaseOptionServiceT() = default;
247
248 public:
249
250 InterfaceType* operator()() const { return _instance(); }
251 InterfaceType* instance() const { return _instance(); }
252 Ref<InterfaceType> instanceRef() const { return _instanceRef(); }
253
254 private:
255
257
258 private:
259
260 InterfaceType* _instance() const
261 {
262 if (m_container.nbElem() == 1)
263 return m_container.child(0);
264 return nullptr;
265 }
266 Ref<InterfaceType> _instanceRef() const
267 {
268 if (m_container.nbElem() == 1)
269 return m_container.childRef(0);
270 return {};
271 }
272};
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
277/*!
278 * \ingroup CaseOption
279 * \brief Base class for a service option that can appear multiple times.
280 */
281class ARCANE_CORE_EXPORT CaseOptionMultiService
282{
283 public:
284
285 CaseOptionMultiService(const CaseOptionBuildInfo& cob, bool allow_null)
286 : m_impl(new CaseOptionMultiServiceImpl(cob, allow_null))
287 {
288 }
289 virtual ~CaseOptionMultiService() = default;
290 CaseOptionMultiService(const CaseOptionMultiService&) = delete;
291 const CaseOptionMultiService& operator=(const CaseOptionMultiService&) = delete;
292
293 public:
294
295 XmlNode rootElement() const { return m_impl->toCaseOptions()->configList()->rootElement(); }
296 String rootTagName() const { return m_impl->rootTagName(); }
297 String name() const { return m_impl->name(); }
298 //! Returns the valid implementation names for this service in \a names
300 {
301 m_impl->getAvailableNames(names);
302 }
303 //! Name of the n-th service
305 {
306 return m_impl->serviceName(index);
307 }
308 void addAlternativeNodeName(const String& lang, const String& name)
309 {
310 m_impl->addAlternativeNodeName(lang, name);
311 }
312 /*!
313 * \brief Sets the mesh name to which the service will be associated.
314 *
315 * \sa CaseOptionService::setMeshName()
316 */
317 void setMeshName(const String& mesh_name);
318
319 /*!
320 * \brief Mesh name to which the service is associated.
321 *
322 * \sa CaseOptionService::axlMeshName();
323 */
324 String meshName() const;
325
326 protected:
327
328 CaseOptionMultiServiceImpl* _impl() { return m_impl.get(); }
329 const CaseOptionMultiServiceImpl* _impl() const { return m_impl.get(); }
330
331 private:
332
333 ReferenceCounter<CaseOptionMultiServiceImpl> m_impl;
334};
335
336/*---------------------------------------------------------------------------*/
337/*---------------------------------------------------------------------------*/
338
339/*!
340 * \ingroup CaseOption
341 * \brief Data set option of the service list type.
342 */
343template <typename InterfaceType>
344class CaseOptionMultiServiceT
345: public CaseOptionMultiService
346, public ArrayView<InterfaceType*>
347{
348 typedef CaseOptionMultiServiceT<InterfaceType> ThatClass;
349
350 public:
351
352 CaseOptionMultiServiceT(const CaseOptionBuildInfo& cob, bool allow_null)
353 : CaseOptionMultiService(cob, allow_null)
354 , m_notify_functor(this, &ThatClass::_notify)
355 {
356 _impl()->setContainer(&m_container);
357 _impl()->_setNotifyAllocateFunctor(&m_notify_functor);
358 }
359
360 public:
361
362 CaseOptionMultiServiceT<InterfaceType>& operator()()
363 {
364 return *this;
365 }
366 const CaseOptionMultiServiceT<InterfaceType>& operator()() const
367 {
368 return *this;
369 }
370
371 protected:
372
373 // Notification by the implementation
374 void _notify()
375 {
376 this->setArray(m_container.view());
377 }
378
379 private:
380
382 FunctorT<ThatClass> m_notify_functor;
383};
384
385/*---------------------------------------------------------------------------*/
386/*---------------------------------------------------------------------------*/
387
388} // End namespace Arcane
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
393#endif
Modifiable view of an array of type T.
void getAvailableNames(StringArray &names) const
Returns the valid implementation names for this service in names.
String serviceName(Integer index) const
Name of the n-th service.
Implementation of the container for a service of type InterfaceType.
void allocate(Integer asize) override
Allocates an array for size elements.
Integer nbElem() const override
Returns the number of elements in the array.
void removeInstances()
Removes service instances.
void addDefaultValue(const String &category, const String &value)
Adds the default value value to the category category.
void setDefaultValue(const String &def_value)
Sets the default value for the service name.
Interface of a service instance container.
Interface of a service.
Definition IService.h:40
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
Information for creating a service.
Node of a DOM tree.
Definition XmlNode.h:51
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Array< String > StringArray
Dynamic one-dimensional array of strings.
Definition UtilsTypes.h:145
Int32 Integer
Type representing an integer.