Arcane  v3.14.10.0
Documentation utilisateur
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/*---------------------------------------------------------------------------*/
41/*!
42 * \brief Classe de base d'une instance de service en C#.
43 */
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/*---------------------------------------------------------------------------*/
73/*!
74 * \internal
75 * \brief Instance d'un service.
76 */
77template<typename InterfaceType>
79: public IServiceInstanceT<InterfaceType>
80{
81 public:
82 ServiceInstanceT(Ref<InterfaceType> i,IServiceInfo* si)
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/*---------------------------------------------------------------------------*/
109/*!
110 * \internal
111 * \brief Infos sur la fabrication d'un service ou d'un module.
112 */
113class ARCANE_CORE_EXPORT ServiceFactoryInfo
114: public IServiceFactoryInfo
115{
116 public:
117
118 explicit ServiceFactoryInfo(IServiceInfo* si)
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/*---------------------------------------------------------------------------*/
155/*!
156 * \internal
157 * \brief Interface d'un fonctor de création d'une instance de service
158 * correspondant à l'interface \a InterfaceType.
159 */
160template<typename InterfaceType>
162{
163 public:
164 virtual ~IServiceInterfaceFactory() = default;
165 public:
166 //! Créé une instance du service .
167 virtual Ref<InterfaceType> createReference(const ServiceBuildInfo& sbi) =0;
168};
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172/*!
173 * \internal
174 * \brief Fabrique de service.
175 *
176 * Cette classe implémente IServiceFactory2 et IServiceFactory2T pour
177 * l'interface \a InterfaceType.
178 */
179
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/*---------------------------------------------------------------------------*/
241/*!
242 * \internal
243 * \brief Fabrique pour le service \a ServiceType pour l'interface \a InterfaceType.
244 */
245template<typename ServiceType,typename InterfaceType>
247: public IServiceInterfaceFactory<InterfaceType>
248{
249 public:
250
251 Ref<InterfaceType> createReference(const ServiceBuildInfo& sbi) override
252 {
253 ServiceType* st = new ServiceType(sbi);
254 st->build();
255 return makeRef<InterfaceType>(st);
256 }
257};
258
259/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
261/*!
262 * \internal
263 */
264class ARCANE_CORE_EXPORT IServiceInstanceAdder
265{
266 public:
267 virtual ~IServiceInstanceAdder() = default;
268 virtual void addInstance(ServiceInstanceRef instance) =0;
269};
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
273/*!
274 * \internal
275 * \brief Classe de base des fabriques pour les services singleton.
276 *
277 * Il faut dériver de cette classe et implémenter _createInstance().
278 */
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
288 //! Créé un service singleton
289 Ref<ISingletonServiceInstance> createSingletonServiceInstance(const ServiceBuildInfoBase& sbib) override;
290
291 //! Retourne le IServiceInfo associé à cette fabrique.
292 IServiceInfo* serviceInfo() const override { return m_service_info; }
293 protected:
294 virtual ServiceInstanceRef _createInstance(const ServiceBuildInfoBase& sbi,IServiceInstanceAdder* instance_adder) =0;
295 private:
296 IServiceInfo* m_service_info;
297};
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301/*!
302 * \internal
303 * \brief Fabrique pour le service singleton de type \a ServiceType implémentant
304 * les interfaces \a Interfaces.
305 */
306template<typename ServiceType,typename ... Interfaces>
309{
310 /*!
311 * \brief Classe utilitaire permettant de créér une instance
312 * de IServiceInstance pour chaque interface de \a Interfaces.
313 */
314 class Helper
315 {
316 public:
317 Helper(ServiceType* service,IServiceInfo* si,IServiceInstanceAdder* adder)
318 : m_service(service), m_service_info(si), m_adder(adder) {}
319 private:
320 //! Surcharge pour 1 interface
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().
327 auto x_ref = Ref<InterfaceType>::_createNoDestroy(x);
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 }
333 //! Surcharge pour 2 interfaces ou plus
334 template<typename I1,typename I2,typename ... OtherInterfaces>
335 void _create()
336 {
337 _create<I1>();
338 // Applique la récursivité sur les types restants
339 _create<I2,OtherInterfaces...>();
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:
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();
363 return ServiceInstanceRef::createRef(si);
364 }
365};
366
367/*---------------------------------------------------------------------------*/
368/*---------------------------------------------------------------------------*/
369/*!
370 * \internal
371 * \brief Classe permettant d'enregistrer une fabrique pour un service
372 * implémentant l'interface \a InterfaceType.
373 */
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
393 //! Enregistre dans \a si une fabrique pour créer une instance du service \a ServiceType
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/*---------------------------------------------------------------------------*/
413/*!
414 * \internal
415 * \brief Classe permettant de créer et d'enregistrer les fabriques pour un service.
416 */
417template<typename ServiceType>
419{
420 private:
421
422 //! Surcharge pour 1 interface
423 template<typename InterfaceType> static void
424 _create(ServiceInfo* si,const InterfaceType& i1)
425 {
426 i1.template registerToServiceInfo<ServiceType>(si);
427 }
428 //! Surcharge pour 2 interfaces ou plus
429 template<typename I1,typename I2,typename ... OtherInterfaces>
430 static void _create(ServiceInfo* si,const I1& i1,const I2& i2,const OtherInterfaces& ... args)
431 {
432 _create<I1>(si,i1);
433 // Applique la récursivité sur les types restants
434 _create<I2,OtherInterfaces...>(si,i2,args...);
435 }
436
437 public:
438
439 //! Enregistre dans le service les fabriques pour les interfacs \a Interfaces
440 template<typename ... Interfaces> static void
441 registerToServiceInfo(ServiceInfo* si, const Interfaces& ... args)
442 {
444 _create(si,args...);
445 }
446};
447
448/*---------------------------------------------------------------------------*/
449/*---------------------------------------------------------------------------*/
450
451} // End namespace Arcane::Internal
452
453/*---------------------------------------------------------------------------*/
454/*---------------------------------------------------------------------------*/
455/*!
456 * \brief Macro pour déclarer une interface lors de l'enregistrement d'un service.
457 *
458 * Cette macro s'utilise dans la macro ARCANE_REGISTER_SERVICE.
459 *
460 * L'appel est comme suit:
461 *
462 \code
463 * ARCANE_SERVICE_INTERFACE(ainterface)
464 \endcode
465 *
466 * \a ainterface est le nom de l'interface (sans les guillemets). Il
467 * peut contenir un namespace.
468 * Par exemple:
469 *
470 \code
471 * ARCANE_SERVICE_INTERFACE(Arcane::IUnitTest);
472 \endcode
473 *
474 */
475#define ARCANE_SERVICE_INTERFACE(ainterface)\
476 Arcane::Internal::ServiceInterfaceRegisterer< ainterface >(#ainterface)
477
478//! Enregistre une interface avec un nom de namespace.
479#define ARCANE_SERVICE_INTERFACE_NS(ainterface_ns,ainterface) \
480 Arcane::Internal::ServiceInterfaceRegisterer<ainterface_ns :: ainterface>(#ainterface_ns,#ainterface)
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
484/*!
485 * \ingroup Service
486 * \brief Macro pour enregistrer un service.
487 *
488 * L'appel est comme suit:
489 *
490 \code
491 * ARCANE_REGISTER_SERVICE(ClassName,
492 * ServiceProperty("ServiceName",where),
493 * ARCANE_SERVICE_INTERFACE(InterfaceName1),);
494 * ARCANE_SERVICE_INTERFACE(InterfaceName2),...);
495 \endcode
496
497 * Avec les paramètres suivants:
498 * - \a ClassName est le nom de la classe du service,
499 * - \a "ServiceName" est le nom du service.
500 * - \a where est de type eServiceType et indique où le service peut être créé.
501 * - \a InterfaceName est le nom de l'interface implémentée par le service. Il
502 * est possible de spécifier plusieurs interfaces pour un même service.
503 *
504 * Par exemple, on peut avoir une utilisation comme suit:
505 *
506 \code
507 * ARCANE_REGISTER_SERVICE(ThreadParallelSuperMng,
508 * ServiceProperty("ThreadParallelSuperMng",ST_Application),
509 * ARCANE_SERVICE_INTERFACE(IParallelSuperMng));
510 \endcode
511 *
512 * \note Cette macro utilise un objet global pour enregistrer le service et
513 * ne doit donc pas être utilisée dans un fichier qui peut appartenir à plusieurs
514 * unités de compilation (par exemple il ne doit pas se trouve dans un fichier d'en-tête).
515 */
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/*---------------------------------------------------------------------------*/
532/*!
533 * \internal
534 * \brief Macro pour enregistrer un service issu d'un fichier AXL.
535 *
536 * Cette macro est interne à Arcane et ne doit pas être utilisée directement
537 */
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/*---------------------------------------------------------------------------*/
564/*!
565 * \brief Enregistre un service de fabrique pour la classe \a aclass
566 *
567 * Le service est enregistré sous le nom \a aname et implémente
568 * l'interface \a ainterface.
569 *
570 * \deprecated Utiliser ARCANE_REGISTER_SERVICE() à la place.
571 */
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/*---------------------------------------------------------------------------*/
578/*!
579 * \brief Enregistre un service de fabrique pour la classe \a aclass
580 *
581 * Le service est enregistré sous le nom \a aname et implémente
582 * l'interface \a ainterface.
583 *
584 * \deprecated Utiliser ARCANE_REGISTER_SERVICE() à la place.
585 */
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/*---------------------------------------------------------------------------*/
592/*!
593 * \brief Enregistre un service de fabrique pour la classe \a aclass
594 *
595 * Le service est enregistré sous le nom \a aname et implémente
596 * l'interface \a ainterface du namespace \a ainterface_ns.
597 *
598 * \deprecated Utiliser ARCANE_REGISTER_SERVICE() à la place.
599 */
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/*---------------------------------------------------------------------------*/
606/*!
607 * \brief Enregistre un service de fabrique pour la classe \a aclass
608 *
609 * Le service est enregistré sous le nom \a aname et implémente
610 * l'interface \a ainterface.
611 *
612 * \deprecated Utiliser ARCANE_REGISTER_SERVICE() à la place.
613 */
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/*---------------------------------------------------------------------------*/
620/*!
621 * \brief Enregistre un service de fabrique pour la classe \a aclass
622 *
623 * Le service est enregistré sous le nom \a aname et implémente
624 * l'interface \a ainterface.
625 *
626 * \deprecated Utiliser ARCANE_REGISTER_SERVICE() à la place.
627 */
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.
virtual int usageType() const =0
Indique où peut être utilisé le service.
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#.
void removeReference() override
Supprime une référence.
void addReference() override
Ajoute une référence.
virtual Ref< InterfaceType > createReference(const ServiceBuildInfo &sbi)=0
Créé une instance du service .
static void registerToServiceInfo(ServiceInfo *si, const Interfaces &... args)
Enregistre dans le service les fabriques pour les interfacs Interfaces.
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.
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
void addImplementedInterface(const String &name) override
Ajoute l'interface de nom name aux interfaces implémentées par ce service.
void removeReference() override
Supprime une référence.
void addReference() override
Ajoute une référence.
Ref< InterfaceType > createReference(const ServiceBuildInfo &sbi) override
Créé une instance du service .
void registerToServiceInfo(ServiceInfo *si) const
Enregistre dans si une fabrique pour créer une instance du service ServiceType.
IServiceInfo * serviceInfo() const override
Retourne le IServiceInfo associé à cette fabrique.
Informations pour créer un service.
eServiceType creationType() const
Type du service pouvant être créé par cette instance.
Structure contenant les informations pour créer un service.
Référence sur une instance de service.
Chaîne de caractères unicode.
Types interne à Arcane.
Definition ArcaneTypes.h:88