1 /**
2 License:
3 Boost Software License - Version 1.0 - August 17th, 2003
4 5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 27 Authors:
28 aermicioi
29 **/30 moduleaermicioi.aedi.container.gc_registering_container;
31 32 importaermicioi.aedi.container.container;
33 importaermicioi.aedi.storage.object_storage;
34 importaermicioi.aedi.storage.decorator;
35 importaermicioi.aedi.storage.locator : LocatorMixin;
36 importaermicioi.aedi.storage.alias_aware;
37 importaermicioi.aedi.storage.storage;
38 importaermicioi.aedi.factory.factory;
39 importaermicioi.aedi.exception.not_found_exception;
40 importaermicioi.aedi.util.traits;
41 importstd.meta;
42 importstd.traits;
43 44 importstd.range.interfaces;
45 46 /**
47 Decorating container that will decorate all passed factories with gc registering factory.
48 This decorated will inherit following interfaces only and only if the
49 T also implements them:
50 $(OL
51 $(LI Storage!(ObjectFactory, string))
52 $(LI Container)
53 $(LI AliasAware!string)
54 )
55 Decorated container must implement following interfaces:
56 $(OL
57 $(LI Container)
58 $(LI MutableDecorator!T)
59 $(LI Subscribable!ContainerInstantiationEventType)
60 $(LI Decorator!Container)
61 )
62 63 Params:
64 T = The decorated that switchable decorated will decorate.
65 **/66 templateGcRegisteringContainer(T)
67 {
68 69 /**
70 Set which the switchable container will decorate for T. By default
71 Locator!() and Subscribable!ContainerInstantiationEventType is included.
72 **/73 aliasInheritanceSet = NoDuplicates!(Filter!(
74 templateOr!(
75 partialSuffixed!(
76 isDerived,
77 Storage!(ObjectFactory, string)
78 ),
79 partialSuffixed!(
80 isDerived,
81 AliasAware!string82 ),
83 partialSuffixed!(
84 isDerived,
85 FactoryLocator!ObjectFactory86 )
87 ),
88 InterfacesTuple!T),
89 Container,
90 Decorator!Container91 );
92 93 @safeclassGcRegisteringContainer : InheritanceSet94 {
95 96 public97 {
98 99 /**
100 Default constructor for GcRegisteringContainer
101 **/102 this()
103 {
104 }
105 106 mixinMutableDecoratorMixin!(T);
107 mixinLocatorMixin!(typeof(this));
108 mixinContainerMixin!(typeof(this));
109 110 staticif (is(T : Storage!(ObjectFactory, string)))
111 {
112 113 /**
114 Set object factory
115 116 Params:
117 element = factory for a object that is to be managed by prototype container.
118 identity = identity of factory
119 Returns:
120 typeof(this)
121 **/122 GcRegisteringContainer!Tset(ObjectFactoryelement, stringidentity)
123 {
124 decorated.set(newGcRegisteringFactoryDecorator(element), identity);
125 126 returnthis;
127 }
128 129 /**
130 Remove an object factory from container.
131 132 Params:
133 identity = identity of factory to be removed
134 Returns:
135 typeof(this)
136 **/137 GcRegisteringContainer!Tremove(stringidentity)
138 {
139 decorated.remove(identity);
140 141 returnthis;
142 }
143 }
144 145 staticif (is(T : AliasAware!string))
146 {
147 148 mixinAliasAwareMixin!(typeof(this));
149 }
150 151 staticif (is(T : FactoryLocator!ObjectFactory))
152 {
153 154 mixinFactoryLocatorMixin!(typeof(this));
155 }
156 }
157 }
158 }
159 160 private @safeclassGcRegisteringFactoryDecorator : Factory!Object {
161 importaermicioi.aedi.storage.locator_aware : LocatorAwareMixin;
162 importaermicioi.aedi.storage.allocator_aware : AllocatorAwareMixin;
163 164 mixinLocatorAwareMixin!GcRegisteringFactoryDecorator;
165 mixinAllocatorAwareMixin!GcRegisteringFactoryDecorator;
166 mixinMutableDecoratorMixin!(Factory!Object);
167 168 public {
169 this(Factory!Objectdecorated) {
170 this.decorated = decorated;
171 }
172 173 /**
174 Instantiates component of type Object.
175 176 Returns:
177 Object instantiated component.
178 **/179 Objectfactory() @trusted {
180 importcore.memory : GC;
181 182 Objectobject = this.decorated.factory();
183 GC.addRange(cast(void*) object, this.type.initializer.length, object.classinfo);
184 185 returnobject;
186 }
187 188 /**
189 Destructs a component of type T.
190 191 Params:
192 component = component that is to ve destroyed.
193 **/194 voiddestruct(refObjectcomponent) @trusted {
195 importcore.memory : GC;
196 GC.removeRange(cast(void*) component);
197 198 this.decorated.destruct(component);
199 }
200 201 @property {
202 203 /**
204 Get the type info of T that is created.
205 206 Returns:
207 TypeInfo object of created component.
208 **/209 TypeInfotype() @safenothrowconst {
210 returnthis.decorated.type();
211 }
212 }
213 }
214 }