Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
ModuleFactory.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/* ModuleFactory.h (C) 2000-2025 */
9/* */
10/* Module creation. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_CORE_MODULEFACTORY_H
13#define ARCANE_CORE_MODULEFACTORY_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/core/IServiceFactory.h"
18#include "arcane/core/IModuleFactory.h"
19#include "arcane/core/ServiceRegisterer.h"
20#include "arcane/core/ModuleBuildInfo.h"
21#include "arcane/core/IServiceInfo.h"
22#include "arcane/core/ModuleProperty.h"
24
25#include <atomic>
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36/*!
37 * \internal
38 * \brief Module factory.
39 */
40class ARCANE_CORE_EXPORT ModuleFactory
41: public IModuleFactoryInfo
42{
43 public:
44
45 /*!
46 * \brief Constructs a factory for a module.
47 *
48 * This constructor is used by the ARCANE_REGISTER_MODULE
49 * and ARCANE_REGISTER_AXL_MODULE macros.
50 *
51 * This instance becomes the owner of \a factory and will destroy it
52 * in the destructor.
53 */
54 ModuleFactory(Ref<IModuleFactory2> factory, bool is_autoload);
55 ~ModuleFactory() override;
56
57 public:
58
59 void addReference() override;
60 void removeReference() override;
61 Ref<IModule> createModule(ISubDomain* parent, const MeshHandle& mesh_handle) override;
62 bool isAutoload() const override { return m_is_autoload; }
63 void initializeModuleFactory(ISubDomain* sub_domain) override;
64 String moduleName() const override { return m_name; }
65 const IServiceInfo* serviceInfo() const override;
66
67 private:
68
69 Ref<IModuleFactory2> m_factory;
70 bool m_is_autoload;
71 String m_name;
72 std::atomic<Int32> m_nb_ref;
73};
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78/*!
79 * \internal
80 * \brief Class implementing IModuleFactory2.
81 */
82class ARCANE_CORE_EXPORT ModuleFactory2
83: public IModuleFactory2
84{
85 public:
86
87 ModuleFactory2(IServiceInfo* service_info, const String& name)
88 : m_service_info(service_info)
89 , m_name(name)
90 {
91 }
92 ~ModuleFactory2() override;
93
94 String moduleName() const override
95 {
96 return m_name;
97 }
98
99 const IServiceInfo* serviceInfo() const override
100 {
101 return m_service_info;
102 }
103
104 private:
105
106 IServiceInfo* m_service_info;
107 String m_name;
108};
109
110/*---------------------------------------------------------------------------*/
111/*---------------------------------------------------------------------------*/
112
113/*!
114 * \internal
115 * \brief Template class for module factory.
116 *
117 * This class allows creating a module implemented by the class \a ModuleType.
118 */
119template <class ModuleType>
120class ModuleFactory2T
121: public ModuleFactory2
122{
123 public:
124
125 ModuleFactory2T(IServiceInfo* service_info, const String& name)
126 : ModuleFactory2(service_info, name)
127 {
128 }
129
130 Ref<IModule> createModuleInstance(ISubDomain* sd, const MeshHandle& mesh_handle) override
131 {
132 auto x = new ModuleType(ModuleBuildInfo(sd, mesh_handle, moduleName()));
133 return makeRef<IModule>(x);
134 }
135
137 {
138 ModuleType::staticInitialize(sd);
139 }
140};
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145/*!
146 * \ingroup Service
147 * \brief Macro for registering a module.
148 *
149 * The call is as follows:
150 *
151 \code
152 * ARCANE_REGISTER_MODULE(ClassName,
153 * Arcane::ModuleProperty("ModuleName"));
154 \endcode
155
156 * With the following parameters:
157 * - \a ClassName is the name of the module class,
158 * - \a "ModuleName" is the name of the module.
159 *
160 * For example, usage can be as follows:
161 *
162 \code
163 * ARCANE_REGISTER_MODULE(ModuleSimpleHydro,
164 * ModuleProperty("SimpleHydro"));
165 \endcode
166 *
167 * \note This macro is used to register modules that do not have associated files
168 * \c axl files. If that is not the case, you must use the macro
169 * defined in the '.h' file generated from the \c axl file.
170 */
171#define ARCANE_REGISTER_MODULE(class_name, a_module_properties) \
172 extern "C++" ARCANE_EXPORT Arcane::IModuleFactoryInfo* \
173 ARCANE_JOIN_WITH_LINE(arcaneCreateModuleFactory##class_name)(const Arcane::ModuleProperty& properties) \
174 { \
175 const char* module_name = properties.name(); \
176 Arcane::ServiceProperty sp(module_name, 0); \
177 auto* si = Arcane::Internal::ServiceInfo::create(sp, __FILE__, __LINE__); \
178 Arcane::IModuleFactory2* mf = new Arcane::ModuleFactory2T<class_name>(si, module_name); \
179 return new Arcane::ModuleFactory(Arcane::makeRef(mf), properties.isAutoload()); \
180 } \
181 Arcane::ServiceRegisterer ARCANE_EXPORT ARCANE_JOIN_WITH_LINE(globalModuleRegisterer##class_name)(&ARCANE_JOIN_WITH_LINE(arcaneCreateModuleFactory##class_name), a_module_properties)
182
183/*---------------------------------------------------------------------------*/
184/*---------------------------------------------------------------------------*/
185
186/*!
187 * \internal
188 * \brief Macro for registering a module derived from an AXL file.
189 *
190 * This macro is internal to Arcane and should not be used directly.
191 */
192#define ARCANE_REGISTER_AXL_MODULE(class_name, a_module_properties) \
193 extern "C++" ARCANE_EXPORT Arcane::IModuleFactoryInfo* \
194 ARCANE_JOIN_WITH_LINE(arcaneCreateModuleFactory##class_name)(const Arcane::ModuleProperty& properties) \
195 { \
196 const char* module_name = properties.name(); \
197 Arcane::ServiceProperty sp(module_name, 0); \
198 auto* si = Arcane::Internal::ServiceInfo::create(sp, __FILE__, __LINE__); \
199 class_name ::fillServiceInfo(si); \
200 Arcane::IModuleFactory2* mf = new Arcane::ModuleFactory2T<class_name>(si, module_name); \
201 return new Arcane::ModuleFactory(Arcane::makeRef(mf), properties.isAutoload()); \
202 } \
203 Arcane::ServiceRegisterer ARCANE_EXPORT ARCANE_JOIN_WITH_LINE(globalModuleRegisterer##class_name)(&ARCANE_JOIN_WITH_LINE(arcaneCreateModuleFactory##class_name), a_module_properties)
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208/*!
209 * \brief Macro for defining a module in a standard way.
210 *
211 * This macro allows automatically registering a module of
212 * name \a module_name by creating an instance of the class \a class_name.
213 *
214 * \deprecated Use ARCANE_REGISTER_MODULE instead.
215 */
216#define ARCANE_DEFINE_STANDARD_MODULE(class_name, module_name) \
217 ARCANE_REGISTER_MODULE(class_name, Arcane::ModuleProperty(#module_name))
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
222} // End namespace Arcane
223
224/*---------------------------------------------------------------------------*/
225/*---------------------------------------------------------------------------*/
226
227#endif
This file contains the various types and classes for specifying service properties.
Information about a module factory.
Interface for service or module information.
Interface of the subdomain manager.
Definition ISubDomain.h:75
Handle on a mesh.
Definition MeshHandle.h:48
Information for building a module.
Ref< IModule > createModuleInstance(ISubDomain *sd, const MeshHandle &mesh_handle) override
Creates a module instance.
void initializeModuleFactory(ISubDomain *sd) override
Static initialization of the module.
String moduleName() const override
Name of the module created by this factory.
const IServiceInfo * serviceInfo() const override
Information about the module that can be created by this factory.
ModuleFactory(Ref< IModuleFactory2 > factory, bool is_autoload)
Constructs a factory for a module.
Ref< IModule > createModule(ISubDomain *parent, const MeshHandle &mesh_handle) override
Creates a module.
String moduleName() const override
Name of the module created by this factory.
bool isAutoload() const override
Indicates if the module should be loaded automatically.
Reference to an instance.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.