88// of patent rights can be found in the PATENTS file in the same directory.
99//
1010
11- #import " ASLayoutSpec+Private .h"
11+ #import " ASLayoutSpec.h"
1212
1313#import " ASAssert.h"
1414#import " ASEnvironmentInternal.h"
1717#import " ASThread.h"
1818#import " ASTraitCollection.h"
1919
20+ #import < objc/runtime.h>
21+ #import < map>
2022#import < vector>
2123
24+ typedef std::map<unsigned long , id <ASLayoutable>, std::less<unsigned long >> ASChildMap;
25+
2226@interface ASLayoutSpec () {
2327 ASEnvironmentState _environmentState;
2428 ASDN::RecursiveMutex __instanceLock__;
25- ASChildrenMap _childrenMap;
26- unsigned long _mutations;
29+ ASChildMap _children;
2730}
2831@end
2932
@@ -32,7 +35,6 @@ @implementation ASLayoutSpec
3235// these dynamic properties all defined in ASLayoutOptionsPrivate.m
3336@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis,
3437 alignSelf, ascender, descender, sizeRange, layoutPosition, layoutableType;
35- @synthesize parent = _parent;
3638@synthesize isFinalLayoutable = _isFinalLayoutable;
3739
3840- (instancetype )init
@@ -42,7 +44,6 @@ - (instancetype)init
4244 }
4345 _isMutable = YES ;
4446 _environmentState = ASEnvironmentStateMakeDefault ();
45- _mutations = 0 ;
4647 return self;
4748}
4849
@@ -104,8 +105,6 @@ - (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
104105 return child;
105106}
106107
107- #pragma mark - Parent
108-
109108- (void )setParent : (id <ASLayoutable>)parent
110109{
111110 // FIXME: Locking should be evaluated here. _parent is not widely used yet, though.
@@ -116,33 +115,30 @@ - (void)setParent:(id<ASLayoutable>)parent
116115 }
117116}
118117
119- - (id <ASLayoutable>)parent
120- {
121- return _parent;
122- }
123-
124- #pragma mark - Children
125-
126118- (void )setChild : (id <ASLayoutable>)child
127119{
128- [self setChild: child forIndex: 0 ];
120+ ASDisplayNodeAssert (self.isMutable , @" Cannot set properties when layout spec is not mutable" );
121+ if (child) {
122+ id <ASLayoutable> finalLayoutable = [self layoutableToAddFromLayoutable: child];
123+ if (finalLayoutable) {
124+ _children[0 ] = finalLayoutable;
125+ [self propagateUpLayoutable: finalLayoutable];
126+ }
127+ } else {
128+ _children.erase (0 );
129+ }
129130}
130131
131132- (void )setChild : (id <ASLayoutable>)child forIndex : (NSUInteger )index
132133{
133134 ASDisplayNodeAssert (self.isMutable , @" Cannot set properties when layout spec is not mutable" );
134135 if (child) {
135136 id <ASLayoutable> finalLayoutable = [self layoutableToAddFromLayoutable: child];
136- if (finalLayoutable) {
137- _childrenMap[index] = finalLayoutable;
138- [self propagateUpLayoutable: finalLayoutable];
139- }
137+ _children[index] = finalLayoutable;
140138 } else {
141- _childrenMap .erase (index);
139+ _children .erase (index);
142140 }
143- _mutations++;
144-
145- // TODO: Should we propagate up the layoutable as it could happen that multiple children will propagated up their
141+ // TODO: Should we propagate up the layoutable at it could happen that multiple children will propagated up their
146142 // layout options and one child will overwrite values from another child
147143 // [self propagateUpLayoutable:finalLayoutable];
148144}
@@ -151,71 +147,35 @@ - (void)setChildren:(NSArray<id<ASLayoutable>> *)children
151147{
152148 ASDisplayNodeAssert (self.isMutable , @" Cannot set properties when layout spec is not mutable" );
153149
154- _childrenMap .clear ();
150+ _children .clear ();
155151 NSUInteger i = 0 ;
156152 for (id <ASLayoutable> child in children) {
157- _childrenMap [i] = [self layoutableToAddFromLayoutable: child];
153+ _children [i] = [self layoutableToAddFromLayoutable: child];
158154 i += 1 ;
159-
160- _mutations++;
161155 }
162156}
163157
164158- (id <ASLayoutable>)childForIndex : (NSUInteger )index
165159{
166- if (index < _childrenMap .size ()) {
167- return _childrenMap [index];
160+ if (index < _children .size ()) {
161+ return _children [index];
168162 }
169163 return nil ;
170164}
171165
172166- (id <ASLayoutable>)child
173167{
174- return _childrenMap [0 ];
168+ return _children [0 ];
175169}
176170
177171- (NSArray *)children
178172{
179- // If used inside ASDK, the childrenMap property should be preferred over the children array to prevent
180- // unecessary boxing
181173 std::vector<ASLayout *> children;
182- for (auto const &entry : _childrenMap ) {
183- children.push_back (entry. second );
174+ for (ASChildMap::iterator it = _children. begin (); it != _children. end (); ++it ) {
175+ children.push_back (it-> second );
184176 }
185-
186- return [NSArray arrayWithObjects: &children[0 ] count: children.size ()];
187- }
188-
189- #pragma mark - NSFastEnumeration
190-
191- - (NSUInteger )countByEnumeratingWithState : (NSFastEnumerationState *)state
192- objects : (id __unsafe_unretained [])stackbuf
193- count : (NSUInteger )stackbufLength
194- {
195- NSUInteger count = 0 ;
196- unsigned long countOfItemsAlreadyEnumerated = state->state ;
197177
198- if (countOfItemsAlreadyEnumerated == 0 ) {
199- state->mutationsPtr = &_mutations;
200- }
201-
202- if (countOfItemsAlreadyEnumerated < _childrenMap.size ()) {
203- state->itemsPtr = stackbuf;
204-
205- while ((countOfItemsAlreadyEnumerated < _childrenMap.size ()) && (count < stackbufLength)) {
206- // Hold on for the object while enumerating
207- __autoreleasing id child = _childrenMap[countOfItemsAlreadyEnumerated];
208- stackbuf[count] = child;
209- countOfItemsAlreadyEnumerated++;
210- count++;
211- }
212- } else {
213- count = 0 ;
214- }
215-
216- state->state = countOfItemsAlreadyEnumerated;
217-
218- return count;
178+ return [NSArray arrayWithObjects: &children[0 ] count: children.size ()];
219179}
220180
221181#pragma mark - ASEnvironment
@@ -273,15 +233,6 @@ - (ASTraitCollection *)asyncTraitCollection
273233
274234@end
275235
276- @implementation ASLayoutSpec (Private)
277-
278- - (ASChildrenMap)childrenMap
279- {
280- return _childrenMap;
281- }
282-
283- @end
284-
285236@implementation ASLayoutSpec (Debugging)
286237
287238#pragma mark - ASLayoutableAsciiArtProtocol
0 commit comments