Arcane  v3.14.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ServiceFactory.h
Aller à la documentation de ce fichier.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* ServiceFactory.h (C) 2000-2019 */
9/* */
10/* Manufacture des services. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_SERVICEFACTORY_H
13#define ARCANE_SERVICEFACTORY_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/NotSupportedException.h"
18#include "arcane/utils/TraceInfo.h"
19#include "arcane/utils/ExternalRef.h"
20
21#include "arcane/IApplication.h"
22#include "arcane/ISession.h"
23#include "arcane/ISubDomain.h"
24#include "arcane/ServiceBuildInfo.h"
25
26#include "arcane/IServiceFactory.h"
27#include "arcane/ServiceRegisterer.h"
28#include "arcane/ServiceInfo.h"
29#include "arcane/IService.h"
30#include "arcane/ServiceProperty.h"
31#include "arcane/ServiceInstance.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::Internal
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
45: public IServiceInstance
46{
47 public:
49 : m_service_info(si), m_handle(nullptr){}
50 public:
51 void addReference() override { ++m_nb_ref; }
52 void removeReference() override
53 {
54 Int32 v = std::atomic_fetch_add(&m_nb_ref,-1);
55 if (v==1)
56 delete this;
57 }
58 public:
59 IServiceInfo* serviceInfo() const override
60 {
61 return m_service_info;
62 }
63 void setDotNetHandle(ExternalRef handle) { m_handle = handle; }
64 ExternalRef _internalDotNetHandle() const override { return m_handle; }
65 private:
66 std::atomic<Int32> m_nb_ref = 0;
67 IServiceInfo* m_service_info;
68 ExternalRef m_handle;
69};
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
77template<typename InterfaceType>
79: public IServiceInstanceT<InterfaceType>
80{
81 public:
83 : m_instance(i), m_service_info(si){}
84 public:
85 void addReference() override { ++m_nb_ref; }
86 void removeReference() override
87 {
88 Int32 v = std::atomic_fetch_add(&m_nb_ref,-1);
89 if (v==1)
90 delete this;
91 }
92 public:
93 Ref<InterfaceType> instance() override
94 {
95 return m_instance;
96 }
97 IServiceInfo* serviceInfo() const override
98 {
99 return m_service_info;
100 }
101 private:
102 std::atomic<Int32> m_nb_ref = 0;
103 Ref<InterfaceType> m_instance;
104 IServiceInfo* m_service_info;
105};
106
107/*---------------------------------------------------------------------------*/
108/*---------------------------------------------------------------------------*/
113class ARCANE_CORE_EXPORT ServiceFactoryInfo
114: public IServiceFactoryInfo
115{
116 public:
117
119 : m_service_info(si), m_is_autoload(false), m_is_singleton(false) {}
120 ~ServiceFactoryInfo() override {}
121
122 public:
123
124 IServiceInfo* serviceInfo() const override { return m_service_info; }
125
126 bool isAutoload() const override { return m_is_autoload; }
127 bool isSingleton() const override { return m_is_singleton; }
128
129 virtual bool isModule() const { return false; }
130 virtual void initializeModuleFactory(ISubDomain*) {}
131 virtual IModule* createModule(ISubDomain*,IMesh*) { return nullptr; }
132
133 public:
134
135 void setAutoload(bool v) { m_is_autoload = v; }
136 void setSingleton(bool v) { m_is_singleton = v; }
137 void initProperties(int v)
138 {
139 if (v & SFP_Singleton)
140 setSingleton(v);
141 if (v & SFP_Autoload)
142 setAutoload(v);
143 }
144 void initProperties(){}
145
146 private:
147
148 IServiceInfo* m_service_info;
149 bool m_is_autoload;
150 bool m_is_singleton;
151};
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
160template<typename InterfaceType>
162{
163 public:
164 virtual ~IServiceInterfaceFactory() = default;
165 public:
168};
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
180template<typename InterfaceType>
182: public IServiceFactory2T<InterfaceType>
183{
184 public:
185
187 : m_service_info(si), m_sub_factory(sub_factory), m_type_flags(si->usageType())
188 {
189 }
190
191 ~ServiceFactory2TV2() override
192 {
193 delete m_sub_factory;
194 }
195
197 {
198 return _create(this->createServiceReference(sbi));
199 }
200
201 Ref<InterfaceType> createServiceReference(const ServiceBuildInfoBase& sbi) override
202 {
203 if (!(m_type_flags & sbi.creationType()))
204 return {};
205 return _createReference(sbi);
206 }
207
208 IServiceInfo* serviceInfo() const override
209 {
210 return m_service_info;
211 }
212
213 protected:
214
215 IServiceInfo* m_service_info;
217 int m_type_flags;
218
219 private:
220
221 InterfaceType* _createInstance(const ServiceBuildInfoBase& sbib)
222 {
223 InterfaceType* it = m_sub_factory->createInstance(ServiceBuildInfo(m_service_info,sbib));
224 return it;
225 }
226
227 Ref<InterfaceType> _createReference(const ServiceBuildInfoBase& sbib)
228 {
229 return m_sub_factory->createReference(ServiceBuildInfo(m_service_info,sbib));
230 }
231
232 ServiceInstanceRef _create(Ref<InterfaceType> it)
233 {
234 IServiceInstance* x = (!it) ? nullptr : new ServiceInstanceT<InterfaceType>(it,m_service_info);
235 return ServiceInstanceRef::createRef(x);
236 }
237};
238
239/*---------------------------------------------------------------------------*/
240/*---------------------------------------------------------------------------*/
245template<typename ServiceType,typename InterfaceType>
247: public IServiceInterfaceFactory<InterfaceType>
248{
249 public:
250
252 {
253 ServiceType* st = new ServiceType(sbi);
254 st->build();
255 return makeRef<InterfaceType>(st);
256 }
257};
258
259/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
264class ARCANE_CORE_EXPORT IServiceInstanceAdder
265{
266 public:
267 virtual ~IServiceInstanceAdder() = default;
268 virtual void addInstance(ServiceInstanceRef instance) =0;
269};
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
279class ARCANE_CORE_EXPORT SingletonServiceFactoryBase
281{
282 public:
283 class ServiceInstance;
284 public:
285 explicit SingletonServiceFactoryBase(IServiceInfo* si) : m_service_info(si){}
286 public:
287
289 Ref<ISingletonServiceInstance> createSingletonServiceInstance(const ServiceBuildInfoBase& sbib) override;
290
292 IServiceInfo* serviceInfo() const override { return m_service_info; }
293 protected:
295 private:
296 IServiceInfo* m_service_info;
297};
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
306template<typename ServiceType,typename ... Interfaces>
309{
314 class Helper
315 {
316 public:
318 : m_service(service), m_service_info(si), m_adder(adder) {}
319 private:
321 template<typename InterfaceType> void _create()
322 {
323 InterfaceType* x = m_service;
324 // ATTENTION: la référence suivante ne doit pas détruire 'm_service' car
325 // ce dernier a déjà un ServiceReference qui a été construit lors de
326 // l'appel à _createInstance().
328 auto instance = new ServiceInstanceT<InterfaceType>(x_ref,m_service_info);
329 // TODO: indiquer qu'il ne faut pas détruire la référence.
330 auto instance_ref = ServiceInstanceRef::createRef(instance);
331 m_adder->addInstance(instance_ref);
332 }
334 template<typename I1,typename I2,typename ... OtherInterfaces>
335 void _create()
336 {
337 _create<I1>();
338 // Applique la récursivité sur les types restants
340 }
341 public:
342 void createInterfaceInstances()
343 {
344 _create<Interfaces...>();
345 }
346 private:
347 ServiceType* m_service;
348 IServiceInfo* m_service_info;
349 IServiceInstanceAdder* m_adder;
350 };
351 public:
352 explicit SingletonServiceFactory(IServiceInfo* si) : SingletonServiceFactoryBase(si){}
353 protected:
354 ServiceInstanceRef _createInstance(const ServiceBuildInfoBase& sbib,IServiceInstanceAdder* instance_adder) override
355 {
356 ServiceBuildInfo sbi(serviceInfo(),sbib);
357 ServiceType* st = new ServiceType(sbi);
358 st->build();
359 auto st_ref = makeRef(st);
360 Helper ssf(st,serviceInfo(),instance_adder);
361 ssf.createInterfaceInstances();
362 IServiceInstance* si = new ServiceInstanceT<ServiceType>(st_ref,serviceInfo());
363 return ServiceInstanceRef::createRef(si);
364 }
365};
366
367/*---------------------------------------------------------------------------*/
368/*---------------------------------------------------------------------------*/
374template<typename InterfaceType>
376{
377 public:
378
379 typedef InterfaceType Interface;
380
381 explicit ServiceInterfaceRegisterer(const char* name)
382 : m_name(name), m_namespace_name(nullptr)
383 {
384 }
385
386 ServiceInterfaceRegisterer(const char* namespace_name,const char* name)
387 : m_name(name), m_namespace_name(namespace_name)
388 {
389 }
390
391 public:
392
394 template<typename ServiceType> void
396 {
398 if (m_namespace_name)
399 si->addImplementedInterface(String(m_namespace_name)+String("::")+String(m_name));
400 else
401 si->addImplementedInterface(m_name);
402 si->addFactory(new ServiceFactory2TV2<InterfaceType>(si,factory));
403 }
404
405 private:
406
407 const char* m_name;
408 const char* m_namespace_name;
409};
410
411/*---------------------------------------------------------------------------*/
412/*---------------------------------------------------------------------------*/
417template<typename ServiceType>
419{
420 private:
421
423 template<typename InterfaceType> static void
424 _create(ServiceInfo* si,const InterfaceType& i1)
425 {
427 }
429 template<typename I1,typename I2,typename ... OtherInterfaces>
430 static void _create(ServiceInfo* si,const I1& i1,const I2& i2,const OtherInterfaces& ... args)
431 {
433 // Applique la récursivité sur les types restants
434 _create<I2,OtherInterfaces...>(si,i2,args...);
435 }
436
437 public:
438
440 template<typename ... Interfaces> static void
446};
447
448/*---------------------------------------------------------------------------*/
449/*---------------------------------------------------------------------------*/
450
451} // End namespace Arcane::Internal
452
453/*---------------------------------------------------------------------------*/
454/*---------------------------------------------------------------------------*/
475#define ARCANE_SERVICE_INTERFACE(ainterface)\
476 Arcane::Internal::ServiceInterfaceRegisterer< ainterface >(#ainterface)
477
479#define ARCANE_SERVICE_INTERFACE_NS(ainterface_ns,ainterface) \
480 Arcane::Internal::ServiceInterfaceRegisterer<ainterface_ns :: ainterface>(#ainterface_ns,#ainterface)
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
516#define ARCANE_REGISTER_SERVICE(aclass,a_service_property,...) \
517namespace\
518{\
519 Arcane::IServiceInfo*\
520 ARCANE_JOIN_WITH_LINE(arcaneCreateServiceInfo##aclass) (const Arcane::ServiceProperty& property) \
521 {\
522 auto* si = Arcane::Internal::ServiceInfo::create(property,__FILE__,__LINE__); \
523 Arcane::Internal::ServiceAllInterfaceRegisterer<aclass> :: registerToServiceInfo(si,__VA_ARGS__); \
524 return si;\
525 }\
526}\
527Arcane::ServiceRegisterer ARCANE_EXPORT ARCANE_JOIN_WITH_LINE(globalServiceRegisterer##aclass) \
528 (& ARCANE_JOIN_WITH_LINE(arcaneCreateServiceInfo##aclass),a_service_property)
529
530/*---------------------------------------------------------------------------*/
531/*---------------------------------------------------------------------------*/
538#define ARCANE_REGISTER_AXL_SERVICE(aclass,a_service_properties) \
539namespace\
540{\
541 Arcane::IServiceInfo*\
542 ARCANE_JOIN_WITH_LINE(arcaneCreateServiceInfo##aclass) (const Arcane::ServiceProperty& properties) \
543 {\
544 Arcane::ServiceInfo* si = Arcane::ServiceInfo::create(properties,__FILE__,__LINE__); \
545 aclass :: fillServiceInfo< aclass >(si); \
546 return si;\
547 }\
548}\
549Arcane::ServiceRegisterer ARCANE_EXPORT ARCANE_JOIN_WITH_LINE(globalServiceRegisterer##aclass) \
550 (& ARCANE_JOIN_WITH_LINE(arcaneCreateServiceInfo##aclass),a_service_properties)
551
552/*---------------------------------------------------------------------------*/
553/*---------------------------------------------------------------------------*/
554/*
555 * Les types et macros suivants sont obsolètes.
556 *
557 * A terme, seule la macro ARCANE_REGISTER_SERVICE sera utilisée.
558 */
559/*---------------------------------------------------------------------------*/
560/*---------------------------------------------------------------------------*/
561
562/*---------------------------------------------------------------------------*/
563/*---------------------------------------------------------------------------*/
572#define ARCANE_REGISTER_APPLICATION_FACTORY(aclass,ainterface,aname) \
573ARCANE_REGISTER_SERVICE ( aclass, Arcane::ServiceProperty(#aname,Arcane::ST_Application) ,\
574 ARCANE_SERVICE_INTERFACE(ainterface) )
575
576/*---------------------------------------------------------------------------*/
577/*---------------------------------------------------------------------------*/
586#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass,ainterface,aname) \
587ARCANE_REGISTER_SERVICE ( aclass, Arcane::ServiceProperty(#aname,Arcane::ST_SubDomain) ,\
588 ARCANE_SERVICE_INTERFACE(ainterface) )
589
590/*---------------------------------------------------------------------------*/
591/*---------------------------------------------------------------------------*/
600#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY4(aclass,ainterface_ns,ainterface,aname) \
601ARCANE_REGISTER_SERVICE ( aclass, Arcane::ServiceProperty(#aname,Arcane::ST_SubDomain) ,\
602 ARCANE_SERVICE_INTERFACE_NS(ainterface_ns,ainterface) )
603
604/*---------------------------------------------------------------------------*/
605/*---------------------------------------------------------------------------*/
614#define ARCANE_REGISTER_CASE_OPTIONS_NOAXL_FACTORY(aclass,ainterface,aname) \
615ARCANE_REGISTER_SERVICE ( aclass, Arcane::ServiceProperty(#aname,Arcane::ST_CaseOption) , \
616 ARCANE_SERVICE_INTERFACE(ainterface) )
617
618/*---------------------------------------------------------------------------*/
619/*---------------------------------------------------------------------------*/
628#define ARCANE_REGISTER_CASE_OPTIONS_NOAXL_FACTORY4(aclass,ainterface_ns,ainterface,aname) \
629ARCANE_REGISTER_SERVICE ( aclass, Arcane::ServiceProperty(#aname,Arcane::ST_CaseOption) ,\
630 ARCANE_SERVICE_INTERFACE_NS(ainterface_ns,ainterface) )
631
632/*---------------------------------------------------------------------------*/
633/*---------------------------------------------------------------------------*/
634
635#endif
636
Informations sur la fabrique d'un service.
Interface des informations d'un service ou d'un module.
Interface typée gérant l'instance d'un service.
Definition IService.h:110
Interface d'une instance d'un service.
Definition IService.h:73
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Classe de base d'une instance de service en C#.
ExternalRef _internalDotNetHandle() const override
void removeReference() override
Supprime une référence.
void addReference() override
Ajoute une référence.
Fabrique pour un service implémentant l'interface InterfaceType.
Interface d'un fonctor de création d'une instance de service correspondant à l'interface InterfaceTyp...
virtual Ref< InterfaceType > createReference(const ServiceBuildInfo &sbi)=0
Créé une instance du service .
Classe permettant de créer et d'enregistrer les fabriques pour un service.
static void _create(ServiceInfo *si, const I1 &i1, const I2 &i2, const OtherInterfaces &... args)
Surcharge pour 2 interfaces ou plus.
static void registerToServiceInfo(ServiceInfo *si, const Interfaces &... args)
Enregistre dans le service les fabriques pour les interfacs Interfaces.
static void _create(ServiceInfo *si, const InterfaceType &i1)
Surcharge pour 1 interface.
IServiceInfo * serviceInfo() const override
Retourne le IServiceInfo associé à cette fabrique.
ServiceInstanceRef createServiceInstance(const ServiceBuildInfoBase &sbi) override
Créé une instance du service à partir des infos de sbi.
Infos sur la fabrication d'un service ou d'un module.
IServiceInfo * serviceInfo() const override
Informations sur le service pouvant être créé par cette fabrique.
bool isSingleton() const override
vrai si le service est un service singleton (une seule instance)
bool isAutoload() const override
vrai si le service est un module et doit être chargé automatiquement
Informations d'un service.
Definition ServiceInfo.h:46
void removeReference() override
Supprime une référence.
void addReference() override
Ajoute une référence.
Fabrique pour le service ServiceType pour l'interface InterfaceType.
Ref< InterfaceType > createReference(const ServiceBuildInfo &sbi) override
Créé une instance du service .
Classe permettant d'enregistrer une fabrique pour un service implémentant l'interface InterfaceType.
void registerToServiceInfo(ServiceInfo *si) const
Enregistre dans si une fabrique pour créer une instance du service ServiceType.
Classe de base des fabriques pour les services singleton.
IServiceInfo * serviceInfo() const override
Retourne le IServiceInfo associé à cette fabrique.
Classe utilitaire permettant de créér une instance de IServiceInstance pour chaque interface de Inter...
void _create()
Surcharge pour 2 interfaces ou plus.
void _create()
Surcharge pour 1 interface.
Fabrique pour le service singleton de type ServiceType implémentant les interfaces Interfaces.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Informations pour créer un service.
Structure contenant les informations pour créer un service.
Référence sur une instance de service.
Gestion des références sur un objet externe.
Référence à une instance.
Chaîne de caractères unicode.
Types interne à Arcane.
Definition ArcaneTypes.h:88