acme
Loading...
Searching...
No Matches
factory.h
1#pragma once
2
3
5#include "acme/parallelization/critical_section.h"
6#include "acme/prototype/collection/atom_map.h"
7
8#include "acme/prototype/prototype/type.h"
9#include "acme/prototype/collection/list_iterator.h"
11//#include "acme/platform/library.h"
12
13
14CLASS_DECL_ACME ::string demangle(const char * pszMangledName);
15
16
17//CLASS_DECL_ACME ::critical_section * factory_critical_section();
18//
19//template < typename TYPE >
20//inline void __defer_construct(::particle* pparticle, ::pointer<TYPE>& p, ::factory::factory * pfactory = nullptr);
21
22namespace factory
23{
24
25
26 class CLASS_DECL_ACME factory_item_interface :
27 virtual public ::particle
28 {
29 public:
30
31
32 factory_item_interface();
33 ~factory_item_interface() override;
34
35
36 virtual string base_type_name() const;
37
38 virtual string __type_name() const;
39
40 virtual ::pointer < ::subparticle > __call__create_particle();
41
42 virtual void return_back(::subparticle * pelement);
43
44
45 };
46
47
48 template < typename ORIGIN_TYPE >
49 class factory_item_base :
50 public factory_item_interface
51 {
52 public:
53
54
55 factory_item_base()
56 {
57
58
59 }
60
61 ~factory_item_base() override
62 {
63
64
65 }
66
67
68 string base_type_name() const override { return ::demangle(::type < ORIGIN_TYPE>().name()); }
69
70 virtual ::pointer<ORIGIN_TYPE> __call__create() = 0;
71
72
74 virtual ::pointer < ::subparticle > __call__create_particle() override
75 {
76
77 return __call__create();
78
79 }
80
81
82 virtual void return_back(::subparticle * pelement) override
83 {
84
85 delete pelement;
86
87 }
88
89
90 };
91
92
93 template < typename TYPE, typename ORIGIN_TYPE >
94 class factory_item :
95 public factory_item_base < ORIGIN_TYPE >
96 {
97 public:
98
99
100 factory_item()
101 {
102
103
104 }
105
106 ~factory_item() override
107 {
108
109
110 }
111
112
113 string __type_name() const override { return ::demangle(typeid(TYPE).name()); }
114
115
118 {
119
120 return { place_t{}, __new_refdbg_continuation TYPE() };
121
122 }
123
124
125 };
126
127
128 template < typename TYPE, typename ORIGIN_TYPE >
130 public factory_item < TYPE, ORIGIN_TYPE >
131 {
132 public:
133
134 critical_section m_criticalsection;
135
136 ORIGIN_TYPE * m_pfree;
137
139 {
140
141 free_all();
142
143 }
144
146
147 void return_back(ORIGIN_TYPE * p);
148
149 void free_all()
150 {
151
152 while (m_pfree)
153 {
154
155 auto p = m_pfree;
156
157 m_pfree = m_pfree->m_pnext;
158
159 try
160 {
161
162 delete p;
163
164 }
165 catch (...)
166 {
167
168 }
169
170 }
171
172 }
173
174 };
175
176
177 using factory_base = atom_map < ::pointer<factory_item_interface > >;
178
179
180 class CLASS_DECL_ACME factory :
181 virtual public factory_base
182 {
183 public:
184
185
186 ::atom m_atomSource;
188 ::critical_section m_criticalsection;
189 ::string m_strArgument;
190
191
192 factory();
193 ~factory();
194
195
196 ::pointer<::factory::factory_item_interface>& get_factory_item(const ::atom & atom);
197
198 //inline ::pointer<::factory::factory_item_interface>& get_factory_item_from(const ::atom& atom, const ::atom & atomSource);
199
200 inline ::factory::factory_item_interface * get_factory_item(const ::atom& atom) const;
201 bool has_factory_item(const ::atom& atom) const;
202
203 //inline ::factory::factory_item_interface * get_factory_item_from(const ::atom& atom, const ::atom & atomSource) const;
204
205 template < typename ORIGIN_TYPE >
206 inline ::pointer<::factory::factory_item_interface>& get_factory_item();
207
208 template < typename ORIGIN_TYPE >
209 inline ::pointer<::factory::factory_item_interface>& get_factory_item(const ::atom& atom);
210 //inline ::pointer<factory_item_interface>& get_factory_item(const ::atom& atom)
211
212 template < typename BASE_TYPE >
213 inline bool __call__defer_construct(::particle * pparticle, ::pointer<BASE_TYPE> & ptype);
214 template < typename TYPE, typename ORIGIN_TYPE>
215 inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > _add_factory_item_from(const ::atom& atomSource);
216
217
218#if REFERENCING_DEBUGGING
219
220
221 factory * __call__add_referer2(const ::reference_referer & referer) const;
222
223#endif
224
225 //template < typename ORIGIN_TYPE >
226 //inline ::pointer<::factory::factory_item_interface>& get_factory_item_from(const ::atom & atomSource);
227
228 template < typename TYPE, typename ORIGIN_TYPE = TYPE >
230
231 template < typename ORIGIN_TYPE >
232 inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > add_factory_item(const ::atom& atom);
233 //template < typename TYPE, typename ORIGIN_TYPE >
234 //inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > add_factory_item_from(const ::atom& atomSource);
235
236 template < typename TYPE, typename ORIGIN_TYPE>
237 inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > create_reusable_factory_item();
238
239 template < typename ORIGIN_TYPE >
240 inline ::pointer<ORIGIN_TYPE>__call__create(::particle * pparticle);
241
242 void merge(const ::factory::factory* pfactory);
243
244 void merge_to_global_factory() const;
245
246 void set_currently_loading_library();
247
248
249 template < typename ORIGIN_TYPE >
250 inline void __defer_raw_construct( ::pointer<ORIGIN_TYPE> & p)
251 {
252
253 if (::is_null(p))
254 {
255
256 this->__raw_construct(p);
257
258 }
259
260 }
261
262
263 template < typename ORIGIN_TYPE >
264 inline void __call__construct(::particle * pparticleInitializer, ::pointer<ORIGIN_TYPE> & p);
265
266
267 template < typename ORIGIN_TYPE >
268 inline void __call__raw_construct(::pointer<ORIGIN_TYPE> & p);
269
270
271 virtual ::particle_pointer __call__create(const ::string & strType, ::particle * pparticle);
272
273
274 virtual bool has(const ::atom & atom) const;
275
276 template < typename TYPE >
277 bool has() const
278 {
279
280 return this->has(::demangle(typeid(TYPE).name()));
281
282 }
283
284
285 };
286
287
288
289 using factory_array = pointer_array < factory_item_interface >;
290
291 //CLASS_DECL_ACME factory * get_factory();
292
294
295
296 ::pointer<factory_item_interface>& get_factory_item(const ::atom & atom);
297
298
299 ::pointer<factory_item_interface>& get_existing_factory_item(const ::atom & atom);
300
301
302 ::pointer<factory_item_interface>& get_factory_item(const ::atom & atom, const ::atom & atomSource);
303
304
305 bool has(const ::atom& atom);
306
307
308
309 void set_factory(const ::atom & atom, const ::pointer<factory_item_interface>& pfactory);
310
311 template < typename ORIGIN_TYPE >
312 inline ::atom get_atom();
313// {
314//
315// auto pszTypename = typeid(ORIGIN_TYPE).name();
316//
317//#ifdef WINDOWS
318//
319// pszTypename = c_demangle(pszTypename);
320//
321// return pszTypename;
322//
323//#else
324//
325// auto strTypename = ::transfer(demangle(pszTypename));
326//
327// return strTypename;
328//
329//
330//#endif
331//
332// }
333
334
335 //template < typename ORIGIN_TYPE >
336 //inline ::pointer<factory_item_interface>& get_factory_item();
337// {
338//
339// //static auto atom = get_atom<ORIGIN_TYPE>();
340//
341// //return get_factory_item(atom);
342//
343// return get_factory_item(get_atom<ORIGIN_TYPE>());
344//
345// }
346
347
348 template < typename ORIGIN_TYPE >
349 inline ::pointer<factory_item_interface> get_factory_item(const ::atom & atomSource);
350// {
351//
352// //static auto atom = get_atom<ORIGIN_TYPE>();
353//
354// //return get_factory_item(atom, atomSource);
355//
356// ///static auto atom = get_atom<ORIGIN_TYPE>();
357//
358// return get_factory_item(atomSource, get_atom<ORIGIN_TYPE>());
359//
360// }
361
362
363} // namespace factory
364
365
366// using factory_pointer = ::pointer<::factory::factory>;
367
368
369// namespace factory
370// {
371
372
373// template < typename TYPE, typename ORIGIN_TYPE = TYPE >
374// inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > add_factory_item();
375
376
377// template < typename TYPE, typename ORIGIN_TYPE = TYPE >
378// inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > add_factory_item(const ::atom& atom);
379
380
381// template < typename TYPE, typename ORIGIN_TYPE = TYPE >
382// inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > add_factory_item_from(const ::atom& atomSource);
383
384
385// template < typename TYPE, typename ORIGIN_TYPE = TYPE >
386// inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > create_reusable_factory();
387
388
389// template < typename TYPE >
390// ::pointer<TYPE>__call__create();
391
392
393// } // namespace factory
394
395
396
397
398
399
400namespace factory
401{
402
403
404 //CLASS_DECL_ACME critical_section * &m_criticalsection;
405
406
407 template < typename ORIGIN_TYPE>
408 inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > factory::add_factory_item(const ::atom & atom)
409 {
410
411 critical_section_lock lock(&m_criticalsection);
412
413 auto pfactoryitem = __allocate ::factory::factory_item< ORIGIN_TYPE, ORIGIN_TYPE > ();
414
415 set_at(atom, pfactoryitem);
416
417 //factory()->set_at(atom, pfactory);
418
419 return pfactoryitem;
420
421 }
422
423
424 CLASS_DECL_ACME::factory::factory * loading_library_factory();
425
426//
427// template < typename TYPE, typename ORIGIN_TYPE>
428// inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > factory::_add_factory_item_from(const ::atom & atomSource)
429// {
430//
432//
433// auto pfactory = ::factory::loading_library_factory();
434//
435// if (::is_set(pfactory))
436// {
437//
438// return pfactory->add_factory_item < TYPE, ORIGIN_TYPE >();
439//
440// }
441//
442// critical_section_lock lock(&m_criticalsection);
443//
444// auto pfactoryitem = __allocate ::factory::factory_item< TYPE, ORIGIN_TYPE > ();
445//
446// get_factory_item < ORIGIN_TYPE >(atomSource) = pfactoryitem;
447//
448// return pfactoryitem;
449//
450// }
451//
452
453 //template < typename TYPE, typename ORIGIN_TYPE>
454 //inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > add_factory_item()
455 //{
456
457 // critical_section_lock lock(&m_criticalsection);
458
459 // auto pfactory = __allocate ::factory::factory_item< TYPE, ORIGIN_TYPE > ();
460
461 // factory_item < ORIGIN_TYPE >() = pfactory;
462
463 // return pfactory;
464
465 //}
466
467
468// template < typename TYPE, typename ORIGIN_TYPE>
469// inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > factory::create_reusable_factory_item()
470// {
471//
472// critical_section_lock lock(&m_criticalsection);
473//
474// auto pfactory = __allocate ::factory::reusable_factory_item< TYPE, ORIGIN_TYPE > ();
475//
476// factory_item < TYPE, ORIGIN_TYPE >() = pfactory;
477//
478// return pfactory;
479//
480// }
481
482
483} // namespace factory
484
485
486
487
488namespace factory
489{
490
491//
492// template < typename TYPE, typename ORIGIN_TYPE >
493// inline ::pointer<ORIGIN_TYPE>reusable_factory_item < TYPE, ORIGIN_TYPE >::__call__create()
494// {
495//
496// {
497//
498// critical_section_lock lock(&m_criticalsection);
499//
500// if (m_pfree)
501// {
502//
503// auto pNew = m_pfree;
504//
505// m_pfree = pNew->m_pnext;
506//
507// pNew->reuse();
508//
509// return pNew;
510//
511// }
512//
513// }
514//
515// return factory_item < TYPE, ORIGIN_TYPE >::_call_new();
516//
517// }
518
519//
520// template < typename TYPE, typename ORIGIN_TYPE >
521// inline void reusable_factory_item < TYPE, ORIGIN_TYPE >::return_back(ORIGIN_TYPE * p)
522// {
523//
524// critical_section_lock lock(&m_criticalsection);
525//
526// p->m_pnext = m_pfree;
527//
528// m_pfree = p;
529//
530// }
531
532
533// template < typename ORIGIN_TYPE >
534// inline ::pointer<ORIGIN_TYPE>factory::__call__create()
535// {
536//
537// auto pfactoryinterface = get_factory_item < ORIGIN_TYPE >();
538//
539// if (!pfactoryinterface)
540// {
541//
542// throw_exception(error_no_factory);
543//
544// }
545//
546// return pfactoryinterface->__call__create_particle();
547//
548// }
549
550//
551// template < typename TYPE, typename ORIGIN_TYPE>
552// inline pointer< ::factory::factory_item_base < ORIGIN_TYPE > > factory::add_factory_item()
553// {
554//
555// critical_section_lock lock(&m_criticalsection);
556//
557// auto pfactory = __allocate ::factory::factory_item< TYPE, ORIGIN_TYPE > ();
558//
559// this->get_factory_item < ORIGIN_TYPE >() = pfactory;
560//
561// return pfactory;
562//
563// }
564
565//
566// template < typename ORIGIN_TYPE >
567// inline void factory::__øconstruct(::particle * pparticleInitializer, ::pointer < ORIGIN_TYPE > & p)
568// {
569//
570// __raw_construct(p);
571//
572// p->initialize(pparticleInitializer);
573//
574// }
575//
576
577// template < typename ORIGIN_TYPE >
578// inline void factory::__raw_construct(::pointer<ORIGIN_TYPE> & p)
579// {
580//
581// auto & pfactoryitem = get_factory_item < ORIGIN_TYPE >();
582//
583// if (!pfactoryitem)
584// {
585//
586// throw_exception(error_no_factory, "Factory hasn't creator for type \"" + __type_name<ORIGIN_TYPE>() + "\"");
587//
588// }
589//
590// auto pparticle = ::transfer(pfactoryitem->__call__create_particle());
591//
592// if (!pparticle)
593// {
594//
595// throw_exception(error_no_memory, "Couldn't __call__create_particle for type \"" + __type_name<ORIGIN_TYPE>() + "\"");
596//
597// }
598//
599// p = pparticle;
600//
601// if (!p)
602// {
603//
604// throw_exception(error_wrong_type, "Created element is not of the base type \"" + __type_name<ORIGIN_TYPE>() + "\"");
605//
606// }
607//
608// }
609//
610
611
612// inline ::factory::factory_item_interface * factory::get_factory_item(const ::atom & atom) const
613// {
614//
615// critical_section_lock cs(&((factory*)this)->m_criticalsection);
616//
617// auto iterator = this->plookup(atom);
618//
619// if (iterator.is_null())
620// {
621//
622// return nullptr;
623//
624// }
625//
626// return iterator->m_element2;
627//
628// }
629
630
631// template < typename ORIGIN_TYPE >
632// inline ::pointer<::factory::factory_item_interface> & factory::get_factory_item()
633// {
634//
635// string strTypename(typeid(ORIGIN_TYPE).name());
636//
637// strTypename = ::demangle(strTypename);
638//
639// return get_factory_item(strTypename);
640//
641// }
642
643
644 //inline ::pointer<::factory::factory_item_interface> & factory::get_factory_item(const ::atom & atom);
645// {
646//
647// critical_section_lock cs(&m_criticalsection);
648//
649//
650// return this->operator[](atom);
651//
652// }
653
654
655 //inline ::pointer<factory_item_interface> & factory::get_factory_item(const ::atom & atom)
656 //{
657
658 // critical_section_lock cs(&m_criticalsection);
659
660 // return (*get_factory())[atom];
661
662 //}
663
664
665 inline ::pointer<factory_item_interface> & get_existing_factory_item(const ::atom & atom);
666// {
667//
668// auto & pfactoryitem = get_factory_item(atom);
669//
670// if (!pfactoryitem)
671// {
672//
673// throw_exception(error_no_factory, "No factory for \"" + atom + "\"");
674//
675// }
676//
677// return pfactoryitem;
678//
679// }
680//
681
682
683
684 //template < typename TYPE >
685 //inline stream & load_object(stream & stream, ::pointer<TYPE>& p)
686 //{
687
688 // string strText;
689
690 // stream >> strText;
691
692 // if (strText.is_empty() || strText.case_insensitive_begins_eat("factoryless://"))
693 // {
694
695 // if (p && ::type(p).name()) == strText
696 // {
697
698 // informationf("loading into existing matter of same class type (1)");
699
700 // }
701 // else
702 // {
703
704 // p.defer_create_new();
705
706 // if (!p)
707 // {
708
709 // informationf("defer_new failed (1.1)");
710
711 // stream.set_fail_bit();
712
713 // }
714 // else if (::type(p).name()) != strText
715 // {
716
717 // informationf("allocated matter type is different from streamed matter type (1.2)");
718
719 // stream.set_fail_bit();
720
721 // }
722
723 // }
724
725 // }
726 // else
727 // {
728
729 // auto atom = stream.text_to_factory_id(strText);
730
731 // if (p && atom == ::type(p).name())
732 // {
733
734 // informationf("loading into existing matter of same class type (2)");
735
736 // }
737 // else
738 // {
739
740 // p = stream.create_object_from_text(strText);
741
742 // if (!p)
743 // {
744
745 // informationf("stream::alloc_object_from_text failed (2.1)");
746
747 // }
748 // else if (::type(p).name()) != atom.to_string()
749 // {
750
751 // informationf("allocated matter type is different from streamed matter type (2.2)");
752
753 // stream.set_fail_bit();
754
755 // }
756
757 // }
758
759 // }
760
761 // if (!stream.fail())
762 // {
763
764 // if (p->has(e_object_factory))
765 // {
766
767 // p->read(stream);
768
769 // }
770 // else
771 // {
772
773 // stream >> *p;
774
775 // }
776
777 // }
778
779 // return stream;
780
781 //}
782
783
784} // namespace factory
785
786
787//#include "_factory.h"
788//
789//
790//namespace factory
791//{
792//
793//
794// template < typename BASE_TYPE >
795// inline void factory::__defer_construct(::particle * pparticle, ::pointer<BASE_TYPE> & ptype)
796// {
797//
798// ::__defer_construct(pparticle, ptype, this);
799//
800// }
801//
802//
803//} // namespace factory
804//
805//
806//template < typename TYPE >
807//inline void __raw_construct(::pointer<TYPE>& p, ::factory::factory * pfactory = nullptr);
808//{
809//
810// auto& pfactoryitem = pfactory->get_factory_item< TYPE >();
811//
812// if (!pfactoryitem)
813// {
814//
815// string strMessage;
816//
817// strMessage.formatf("matter::__øconstruct has failed to find factory_item for type \"%s\"", __type_name < TYPE >().c_str());
818//
819// throw_exception(::error_not_implemented, strMessage);
820//
821// }
822//
823// auto pparticleNew = pfactoryitem->__call__create_particle();
824//
825// if (!pparticleNew)
826// {
827//
828// string strMessage;
829//
830// strMessage.formatf("matter::__øconstruct no memory to allocate implementation of type \"%ss\"", __type_name < TYPE >().c_str());
831//
832// throw_exception(::error_no_memory, strMessage);
833//
834// }
835//
836// p.release();
837//
838// p = pparticleNew;
839//
840// if (!p)
841// {
842//
843// string strMessage;
844//
845// strMessage.formatf("matter::__øconstruct object(%s) is not of type \"%s\"", ::type(pparticleNew).name().c_str(), __type_name < TYPE >().c_str());
846//
847// throw_exception(::error_wrong_type, strMessage);
848//
849// }
850//
851//}
852
853
854template < typename BASE_TYPE >
855inline ::pointer<BASE_TYPE> __raw_create(::factory::factory* pfactory);
856//{
857//
858// ::pointer<BASE_TYPE> p;
859//
860// __raw_construct(p, pfactory);
861//
862// return ::transfer(p);
863//
864//}
865
866
867//template < typename TYPE >
868//inline void __øconstruct(::particle* pparticle, ::pointer<TYPE>& p, ::factory::factory * pfactory = nullptr);
869//{
870//
871// __raw_construct(p, pfactory);
872//
873// p->initialize(pparticle);
874//
875//}
876//
877
878//template < typename BASE_TYPE >
879//inline ::pointer < BASE_TYPE > __øcreate(::particle* pparticle, ::factory::factory * pfactory = nullptr);
880//{
881//
882// ::pointer < BASE_TYPE > p;
883//
884// __øconstruct(pparticle, p, pfactory);
885//
886// return p;
887//
888//}
889
890
891//template < typename TYPE >
892//inline void __call__defer_construct(::particle* pparticle, ::pointer<TYPE>& p, ::factory::factory* pfactory);
893//{
894//
895// if (!p)
896// {
897//
898// __øconstruct(pparticle, p, pfactory);
899//
900// }
901//
902//
903//}
904
905
906
907
908
909//template < typename TYPE >
910//inline void __id_construct(particle* pparticle, ::pointer<TYPE>& p, const ::atom& atom, ::factory::factory * pfactory = nullptr);
911//{
912//
913// auto& pfactoryitem = pfactory->get_factory_item(atom);
914//
915// auto pparticleNew = pfactoryitem->__call__create_particle();
916//
917// //if (!pparticleNew)
918// //{
919//
920// // return error_no_memory;
921//
922// //}
923//
924// p = pparticleNew;
925//
926// if (!p)
927// {
928//
929// throw_exception(error_wrong_type);
930//
931// }
932//
933// p->set_flag(e_flag_factory);
934//
935// //auto estatus =
936//
937// p->initialize(pparticle);
938//
939// //if (!estatus)
940// //{
941//
942// // return estatus;
943//
944// //}
945//
946// //return estatus;
947//
948//}
949
950
951//template < typename TYPE >
952//inline ::pointer < TYPE > __id_create(particle* pparticle, const ::atom& atom, ::factory::factory * pfactory = nullptr);
953//{
954//
955// auto& pfactoryitem = pfactory->get_factory_item(atom);
956//
957// auto pparticleNew = pfactoryitem->__call__create_particle();
958//
959// //if (!pparticleNew)
960// //{
961//
962// // return error_no_memory;
963//
964// //}
965//
966//
967//
968// ::pointer < TYPE > p = pparticleNew;
969//
970// if (!p)
971// {
972//
973// throw_exception(error_wrong_type);
974//
975// }
976//
977// p->set_flag(e_flag_factory);
978//
979// //auto estatus =
980//
981// p->initialize(pparticle);
982//
983// //if (!estatus)
984// //{
985//
986// // return estatus;
987//
988// //}
989//
990// //return estatus;
991//
992// return p;
993//
994//}
995
996//
997//template < class T >
998//template < typename PARTICLE >
999//inline pointer < T >& pointer < T >::__call__create(PARTICLE* pparticle, ::factory::factory* pfactory)
1000//{
1001//
1002// auto p = ::__øcreate < T >(pparticle);
1003//
1004// return operator =(p);
1005//
1006//}
1007
1008
1009
Definition atom.h:233
Definition critical_section.h:29
Definition critical_section.h:9
virtual ::pointer< ::subparticle > __call__create_particle() override
consumes a referer
Definition factory.h:74
::pointer< ORIGIN_TYPE > __call__create() override
consumes a referer
Definition factory.h:117
Definition factory.h:182
Definition factory.h:131
::pointer< ORIGIN_TYPE > __call__create() override
consumes a referer
Definition _impl_factory.h:12
Definition pointer.h:46
Definition subparticle.h:26
Definition pointer.h:9