cascading-configuration-array 1.6.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/cascading-configuration-array/CascadingConfiguration/Array/Interface.rb +16 -16
- data/lib/cascading-configuration-array/CascadingConfiguration/Array.rb +2 -2
- data/lib/cascading-configuration-array/_private_/CascadingConfiguration/Array/CompositingArray.rb +700 -124
- data/lib/cascading-configuration-array/_private_/CascadingConfiguration/Array/Interface/GettersSetters.rb +59 -37
- data/lib/cascading-configuration-array/_private_/CascadingConfiguration/Array/ModuleSupportMethods.rb +18 -15
- data/lib/cascading-configuration-array.rb +5 -5
- data/spec/CascadingConfiguration/Array_spec.rb +22 -18
- data/spec/_private_/CascadingConfiguration/Array/CompositingArray_spec.rb +903 -474
- metadata +6 -8
- data/lib/cascading-configuration-array/_private_/CascadingConfiguration/Array/CompositingArray/LocalConfigurationArray.rb +0 -192
- data/spec/_private_/CascadingConfiguration/Array/CompositingArray/LocalConfigurationArray_spec.rb +0 -155
data/lib/cascading-configuration-array/_private_/CascadingConfiguration/Array/CompositingArray.rb
CHANGED
@@ -1,52 +1,70 @@
|
|
1
1
|
|
2
|
-
class CascadingConfiguration::Array::CompositingArray < ::Array
|
3
|
-
|
4
|
-
attr_accessor :local_cascading_array
|
2
|
+
class ::CascadingConfiguration::Array::CompositingArray < ::Array
|
5
3
|
|
6
4
|
################
|
7
5
|
# initialize #
|
8
6
|
################
|
9
7
|
|
10
8
|
def initialize( configuration_instance, configuration_name )
|
11
|
-
|
9
|
+
|
12
10
|
@configuration_instance = configuration_instance
|
13
|
-
|
14
11
|
@configuration_name = configuration_name
|
15
12
|
|
13
|
+
# hash tracking index in self corresponding to index in parent
|
14
|
+
# this is since objects can be inserted before/between parent objects
|
15
|
+
@local_index_for_parent_index = { }
|
16
|
+
|
17
|
+
# we keep track of how many objects are interpolated between parent objects
|
18
|
+
# plus number of parent objects
|
19
|
+
@parent_and_interpolated_object_count = 0
|
20
|
+
@replaced_parents = {}
|
21
|
+
|
22
|
+
# arrays that inherit from us
|
23
|
+
@sub_composite_arrays = [ ]
|
24
|
+
|
16
25
|
# store self for sub composites
|
17
|
-
::CascadingConfiguration::Variable.set_configuration_variable( configuration_instance,
|
26
|
+
::CascadingConfiguration::Variable.set_configuration_variable( configuration_instance,
|
27
|
+
configuration_name,
|
28
|
+
self )
|
18
29
|
|
19
|
-
# if first ancestor can have a composite array, register self with it
|
20
|
-
|
30
|
+
# if first ancestor can have a composite array, register self with it
|
31
|
+
# in case it gets updated in the future
|
32
|
+
if ancestor = ::CascadingConfiguration::Variable.ancestor( configuration_instance,
|
33
|
+
configuration_name )
|
34
|
+
|
35
|
+
@super_composite_array = ::CascadingConfiguration::Variable.
|
36
|
+
get_configuration_variable( ancestor, configuration_name )
|
21
37
|
|
22
|
-
@super_composite_array = ::CascadingConfiguration::Variable.get_configuration_variable( ancestor,
|
23
|
-
configuration_name )
|
24
38
|
if @super_composite_array.respond_to?( :register_sub_composite_array )
|
25
39
|
@super_composite_array.register_sub_composite_array( self )
|
40
|
+
push( *@super_composite_array )
|
26
41
|
else
|
27
42
|
@super_composite_array = nil
|
28
43
|
end
|
29
|
-
|
44
|
+
|
45
|
+
@super_composite_array.count.times do |this_time|
|
46
|
+
@local_index_for_parent_index[ this_time ] = this_time
|
47
|
+
end
|
48
|
+
|
49
|
+
# since we have a super array we have to note how many objects it has before we insert any
|
50
|
+
@parent_and_interpolated_object_count = @super_composite_array.count
|
51
|
+
|
30
52
|
end
|
31
53
|
|
32
|
-
# instantiate local cascading array
|
33
|
-
@local_cascading_array = ::CascadingConfiguration::Array::CompositingArray::LocalConfigurationArray.new
|
34
|
-
|
35
|
-
# we may later have our own child composites that register with us
|
36
|
-
@sub_composite_arrays = [ ]
|
37
|
-
|
38
|
-
# initialize self status for parent and local
|
39
|
-
update_self_as_cascading_composite
|
40
|
-
|
41
54
|
end
|
42
55
|
|
56
|
+
################################### Sub-Array Management #######################################
|
57
|
+
|
43
58
|
##################################
|
44
59
|
# register_sub_composite_array #
|
45
60
|
##################################
|
46
61
|
|
47
62
|
def register_sub_composite_array( sub_composite_array )
|
63
|
+
|
48
64
|
@sub_composite_arrays.push( sub_composite_array )
|
65
|
+
|
49
66
|
return self
|
67
|
+
|
50
68
|
end
|
51
69
|
|
52
70
|
####################################
|
@@ -54,94 +72,502 @@ class CascadingConfiguration::Array::CompositingArray < ::Array
|
|
54
72
|
####################################
|
55
73
|
|
56
74
|
def unregister_sub_composite_array( sub_composite_array )
|
75
|
+
|
57
76
|
@sub_composite_arrays.delete( sub_composite_array )
|
77
|
+
|
58
78
|
return self
|
79
|
+
|
59
80
|
end
|
60
81
|
|
82
|
+
##################################### Self Management ##########################################
|
83
|
+
|
61
84
|
#########
|
62
85
|
# []= #
|
63
86
|
#########
|
64
87
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
push( element )
|
69
|
-
end
|
70
|
-
|
71
|
-
########
|
72
|
-
# << #
|
73
|
-
########
|
88
|
+
private
|
89
|
+
alias_method :non_cascading_set, :[]=
|
90
|
+
public
|
74
91
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
92
|
+
def []=( index, object )
|
93
|
+
|
94
|
+
# we are either replacing or adding at the end
|
95
|
+
# if we are replacing we are either replacing a parent element or an element in self
|
96
|
+
# * if replacing parent element, track and exclude parent changes
|
97
|
+
|
98
|
+
non_cascading_set( index, object )
|
99
|
+
|
100
|
+
if index_inside_parent_objects?( index )
|
101
|
+
@replaced_parents[ index ] = true
|
102
|
+
end
|
103
|
+
|
104
|
+
@sub_composite_arrays.each do |this_sub_array|
|
105
|
+
this_sub_array.instance_eval do
|
106
|
+
update_as_sub_array_for_parent_set( index, object )
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
return object
|
111
|
+
|
78
112
|
end
|
79
113
|
|
80
|
-
|
81
|
-
#
|
82
|
-
|
114
|
+
############
|
115
|
+
# insert #
|
116
|
+
############
|
117
|
+
|
118
|
+
private
|
119
|
+
alias_method :non_cascading_insert, :insert
|
120
|
+
public
|
121
|
+
|
122
|
+
def insert( index, *objects )
|
123
|
+
|
124
|
+
# if we have less elements in self than the index we are inserting at
|
125
|
+
# we need to make sure the nils inserted cascade
|
126
|
+
if index > count
|
127
|
+
nils_created = index - count
|
128
|
+
index -= nils_created
|
129
|
+
nils = [ ]
|
130
|
+
nils_created.times do |this_time|
|
131
|
+
nils.push( nil )
|
132
|
+
end
|
133
|
+
objects = nils.concat( objects )
|
134
|
+
end
|
135
|
+
|
136
|
+
non_cascading_insert( index, *objects )
|
137
|
+
|
138
|
+
if index_inside_parent_objects?( index )
|
139
|
+
update_corresponding_index_for_local_change( index, objects.count )
|
140
|
+
end
|
83
141
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
142
|
+
@sub_composite_arrays.each do |this_sub_array|
|
143
|
+
this_sub_array.instance_eval do
|
144
|
+
update_as_sub_array_for_parent_insert( index, *objects )
|
145
|
+
end
|
88
146
|
end
|
147
|
+
|
89
148
|
return self
|
149
|
+
|
90
150
|
end
|
91
151
|
|
152
|
+
##########
|
153
|
+
# push #
|
154
|
+
##########
|
155
|
+
|
156
|
+
def push( *objects )
|
157
|
+
|
158
|
+
insert( count, *objects )
|
159
|
+
|
160
|
+
return self
|
161
|
+
|
162
|
+
end
|
163
|
+
alias_method :<<, :push
|
164
|
+
|
92
165
|
############
|
93
166
|
# concat #
|
94
167
|
############
|
95
168
|
|
96
169
|
def concat( *arrays )
|
170
|
+
|
97
171
|
arrays.each do |this_array|
|
98
172
|
push( *this_array )
|
99
173
|
end
|
174
|
+
|
175
|
+
return self
|
176
|
+
|
100
177
|
end
|
178
|
+
alias_method :+, :concat
|
101
179
|
|
102
|
-
|
103
|
-
#
|
104
|
-
|
180
|
+
############
|
181
|
+
# delete #
|
182
|
+
############
|
105
183
|
|
106
|
-
|
107
|
-
def push( *elements )
|
108
|
-
|
109
|
-
# we are a composite array
|
110
|
-
# that means we have to set the value for our class
|
111
|
-
@local_cascading_array.push( *elements )
|
112
|
-
|
113
|
-
update_adding_composite_elements( *elements )
|
184
|
+
def delete( object )
|
114
185
|
|
115
|
-
|
186
|
+
return_value = nil
|
187
|
+
|
188
|
+
if index = index( object )
|
189
|
+
return_value = delete_at( index )
|
190
|
+
end
|
191
|
+
|
192
|
+
return return_value
|
116
193
|
|
117
194
|
end
|
195
|
+
|
196
|
+
####################
|
197
|
+
# delete_objects #
|
198
|
+
####################
|
118
199
|
|
200
|
+
def delete_objects( *objects )
|
201
|
+
|
202
|
+
return_value = nil
|
203
|
+
|
204
|
+
indexes = [ ]
|
205
|
+
objects.each do |this_object|
|
206
|
+
this_index = index( this_object )
|
207
|
+
if this_index
|
208
|
+
indexes.push( this_index )
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
unless indexes.empty?
|
213
|
+
return_value = delete_at_indexes( *indexes )
|
214
|
+
end
|
215
|
+
|
216
|
+
return return_value
|
217
|
+
|
218
|
+
end
|
219
|
+
|
119
220
|
#######
|
120
221
|
# - #
|
121
222
|
#######
|
122
|
-
|
223
|
+
|
123
224
|
def -( *arrays )
|
124
225
|
|
125
226
|
arrays.each do |this_array|
|
126
|
-
|
227
|
+
delete_objects( *this_array )
|
127
228
|
end
|
128
229
|
|
129
230
|
return self
|
130
231
|
|
131
232
|
end
|
132
233
|
|
133
|
-
|
134
|
-
#
|
135
|
-
|
234
|
+
###############
|
235
|
+
# delete_at #
|
236
|
+
###############
|
237
|
+
|
238
|
+
private
|
239
|
+
alias_method :non_cascading_delete_at, :delete_at
|
240
|
+
public
|
136
241
|
|
137
|
-
|
138
|
-
|
242
|
+
def delete_at( index )
|
243
|
+
|
244
|
+
deleted_object = non_cascading_delete_at( index )
|
245
|
+
|
246
|
+
@replaced_parents.delete( index )
|
247
|
+
|
248
|
+
if index_inside_parent_objects?( index )
|
249
|
+
update_corresponding_index_for_local_change( index, -1 )
|
250
|
+
end
|
251
|
+
|
252
|
+
@sub_composite_arrays.each do |this_sub_array|
|
253
|
+
this_sub_array.instance_eval do
|
254
|
+
update_as_sub_array_for_parent_delete( index )
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
return deleted_object
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
#######################
|
263
|
+
# delete_at_indexes #
|
264
|
+
#######################
|
265
|
+
|
266
|
+
def delete_at_indexes( *indexes )
|
267
|
+
|
268
|
+
indexes = indexes.sort.uniq.reverse
|
269
|
+
|
270
|
+
objects = [ ]
|
271
|
+
|
272
|
+
indexes.each do |this_index|
|
273
|
+
objects.push( delete_at( this_index ) )
|
274
|
+
end
|
275
|
+
|
276
|
+
return objects
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
###############
|
281
|
+
# delete_if #
|
282
|
+
###############
|
283
|
+
|
284
|
+
def delete_if
|
285
|
+
|
286
|
+
return to_enum unless block_given?
|
287
|
+
|
288
|
+
indexes = [ ]
|
289
|
+
|
290
|
+
self.each_with_index do |this_object, index|
|
291
|
+
if yield( this_object )
|
292
|
+
indexes.push( index )
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
delete_at_indexes( *indexes )
|
297
|
+
|
298
|
+
return self
|
299
|
+
|
300
|
+
end
|
139
301
|
|
140
|
-
|
302
|
+
#############
|
303
|
+
# keep_if #
|
304
|
+
#############
|
305
|
+
|
306
|
+
def keep_if
|
307
|
+
|
308
|
+
indexes = [ ]
|
309
|
+
|
310
|
+
self.each_with_index do |this_object, index|
|
311
|
+
unless yield( this_object )
|
312
|
+
indexes.push( index )
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
delete_at_indexes( *indexes )
|
317
|
+
|
318
|
+
return self
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
##############
|
323
|
+
# compact! #
|
324
|
+
##############
|
325
|
+
|
326
|
+
def compact!
|
327
|
+
|
328
|
+
return keep_if do |object|
|
329
|
+
object != nil
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
##############
|
335
|
+
# flatten! #
|
336
|
+
##############
|
337
|
+
|
338
|
+
def flatten!
|
339
|
+
|
340
|
+
return_value = nil
|
341
|
+
|
342
|
+
indexes = [ ]
|
343
|
+
|
344
|
+
self.each_with_index do |this_object, index|
|
345
|
+
if this_object.is_a?( Array )
|
346
|
+
indexes.push( index )
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
unless indexes.empty?
|
351
|
+
indexes.sort!.reverse!
|
352
|
+
indexes.each do |this_index|
|
353
|
+
this_array = delete_at( this_index )
|
354
|
+
insert( this_index, *this_array )
|
355
|
+
end
|
356
|
+
return_value = self
|
357
|
+
end
|
358
|
+
|
359
|
+
return return_value
|
360
|
+
|
361
|
+
end
|
362
|
+
|
363
|
+
#############
|
364
|
+
# reject! #
|
365
|
+
#############
|
366
|
+
|
367
|
+
def reject!
|
368
|
+
|
369
|
+
return to_enum unless block_given?
|
370
|
+
|
371
|
+
return_value = nil
|
372
|
+
|
373
|
+
deleted_objects = 0
|
374
|
+
|
375
|
+
iteration_dup = dup
|
376
|
+
iteration_dup.each_with_index do |this_object, index|
|
377
|
+
if yield( this_object )
|
378
|
+
delete_at( index - deleted_objects )
|
379
|
+
deleted_objects += 1
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
if deleted_objects > 0
|
384
|
+
return_value = self
|
385
|
+
end
|
386
|
+
|
387
|
+
return return_value
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
#############
|
392
|
+
# replace #
|
393
|
+
#############
|
394
|
+
|
395
|
+
def replace( other_array )
|
396
|
+
|
397
|
+
clear
|
398
|
+
|
399
|
+
other_array.each_with_index do |this_object, index|
|
400
|
+
unless self[ index ] == this_object
|
401
|
+
self[ index ] = this_object
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
return self
|
406
|
+
|
407
|
+
end
|
141
408
|
|
142
|
-
|
409
|
+
##############
|
410
|
+
# reverse! #
|
411
|
+
##############
|
412
|
+
|
413
|
+
def reverse!
|
414
|
+
|
415
|
+
reversed_array = reverse
|
416
|
+
|
417
|
+
clear
|
418
|
+
|
419
|
+
reversed_array.each_with_index do |this_object, index|
|
420
|
+
self[ index ] = this_object
|
421
|
+
end
|
422
|
+
|
423
|
+
return self
|
424
|
+
|
425
|
+
end
|
426
|
+
|
427
|
+
#############
|
428
|
+
# rotate! #
|
429
|
+
#############
|
430
|
+
|
431
|
+
def rotate!( rotate_count = 1 )
|
432
|
+
|
433
|
+
reversed_array = rotate( rotate_count )
|
434
|
+
|
435
|
+
clear
|
436
|
+
|
437
|
+
reversed_array.each_with_index do |this_object, index|
|
438
|
+
self[ index ] = this_object
|
439
|
+
end
|
440
|
+
|
441
|
+
return self
|
442
|
+
|
443
|
+
end
|
444
|
+
|
445
|
+
#############
|
446
|
+
# select! #
|
447
|
+
#############
|
448
|
+
|
449
|
+
def select!
|
450
|
+
|
451
|
+
return to_enum unless block_given?
|
452
|
+
|
453
|
+
deleted_objects = 0
|
454
|
+
|
455
|
+
iteration_dup = dup
|
456
|
+
iteration_dup.each_with_index do |this_object, index|
|
457
|
+
unless yield( this_object )
|
458
|
+
delete_at( index - deleted_objects )
|
459
|
+
deleted_objects += 1
|
460
|
+
end
|
461
|
+
end
|
143
462
|
|
144
463
|
return self
|
464
|
+
|
465
|
+
end
|
466
|
+
|
467
|
+
##############
|
468
|
+
# shuffle! #
|
469
|
+
##############
|
470
|
+
|
471
|
+
def shuffle!( random_number_generator = nil )
|
472
|
+
|
473
|
+
shuffled_array = shuffle( random: random_number_generator )
|
474
|
+
|
475
|
+
clear
|
476
|
+
|
477
|
+
shuffled_array.each_with_index do |this_object, index|
|
478
|
+
self[ index ] = this_object
|
479
|
+
end
|
480
|
+
|
481
|
+
return self
|
482
|
+
|
483
|
+
end
|
484
|
+
|
485
|
+
##############
|
486
|
+
# collect! #
|
487
|
+
# map! #
|
488
|
+
##############
|
489
|
+
|
490
|
+
def collect!
|
491
|
+
|
492
|
+
return to_enum unless block_given?
|
493
|
+
|
494
|
+
self.each_with_index do |this_object, index|
|
495
|
+
replacement_object = yield( this_object )
|
496
|
+
self[ index ] = replacement_object
|
497
|
+
end
|
498
|
+
|
499
|
+
return self
|
500
|
+
|
501
|
+
end
|
502
|
+
alias_method :map!, :collect!
|
503
|
+
|
504
|
+
###########
|
505
|
+
# sort! #
|
506
|
+
###########
|
507
|
+
|
508
|
+
def sort!( & block )
|
509
|
+
|
510
|
+
sorted_array = sort( & block )
|
511
|
+
|
512
|
+
unless sorted_array == self
|
513
|
+
|
514
|
+
replace( sorted_array )
|
515
|
+
|
516
|
+
end
|
517
|
+
|
518
|
+
return self
|
519
|
+
|
520
|
+
end
|
521
|
+
|
522
|
+
##############
|
523
|
+
# sort_by! #
|
524
|
+
##############
|
525
|
+
|
526
|
+
def sort_by!( & block )
|
527
|
+
|
528
|
+
return to_enum unless block_given?
|
529
|
+
|
530
|
+
sorted_array = sort_by( & block )
|
531
|
+
|
532
|
+
unless sorted_array == self
|
533
|
+
|
534
|
+
replace( sorted_array )
|
535
|
+
|
536
|
+
end
|
537
|
+
|
538
|
+
return self
|
539
|
+
|
540
|
+
end
|
541
|
+
|
542
|
+
###########
|
543
|
+
# uniq! #
|
544
|
+
###########
|
545
|
+
|
546
|
+
def uniq!
|
547
|
+
|
548
|
+
return_value = nil
|
549
|
+
|
550
|
+
uniq_array = uniq
|
551
|
+
|
552
|
+
unless uniq_array == self
|
553
|
+
|
554
|
+
clear
|
555
|
+
|
556
|
+
replace( uniq_array )
|
557
|
+
|
558
|
+
end
|
559
|
+
|
560
|
+
return return_value
|
561
|
+
|
562
|
+
end
|
563
|
+
|
564
|
+
#############
|
565
|
+
# unshift #
|
566
|
+
#############
|
567
|
+
|
568
|
+
def unshift( object )
|
569
|
+
|
570
|
+
insert( 0, object )
|
145
571
|
|
146
572
|
end
|
147
573
|
|
@@ -151,13 +577,9 @@ class CascadingConfiguration::Array::CompositingArray < ::Array
|
|
151
577
|
|
152
578
|
def pop
|
153
579
|
|
154
|
-
|
155
|
-
|
156
|
-
@local_cascading_array.delete( element )
|
157
|
-
|
158
|
-
update_removing_composite_elements( element )
|
580
|
+
object = delete_at( count - 1 )
|
159
581
|
|
160
|
-
return
|
582
|
+
return object
|
161
583
|
|
162
584
|
end
|
163
585
|
|
@@ -167,13 +589,9 @@ class CascadingConfiguration::Array::CompositingArray < ::Array
|
|
167
589
|
|
168
590
|
def shift
|
169
591
|
|
170
|
-
|
171
|
-
|
172
|
-
@local_cascading_array.delete( element )
|
592
|
+
object = delete_at( 0 )
|
173
593
|
|
174
|
-
|
175
|
-
|
176
|
-
return element
|
594
|
+
return object
|
177
595
|
|
178
596
|
end
|
179
597
|
|
@@ -181,15 +599,43 @@ class CascadingConfiguration::Array::CompositingArray < ::Array
|
|
181
599
|
# slice! #
|
182
600
|
############
|
183
601
|
|
184
|
-
def slice!(
|
602
|
+
def slice!( index_start_or_range, length = nil )
|
185
603
|
|
186
|
-
|
604
|
+
slice = nil
|
605
|
+
|
606
|
+
start_index = nil
|
607
|
+
end_index = nil
|
608
|
+
|
609
|
+
if index_start_or_range.is_a?( Range )
|
610
|
+
|
611
|
+
start_index = index_start_or_range.begin
|
612
|
+
end_index = index_start_or_range.end
|
613
|
+
|
614
|
+
elsif length
|
615
|
+
|
616
|
+
start_index = index_start_or_range
|
617
|
+
end_index = index_start_or_range + length
|
618
|
+
|
619
|
+
end
|
187
620
|
|
188
|
-
|
621
|
+
if end_index
|
622
|
+
|
623
|
+
indexes = [ ]
|
624
|
+
|
625
|
+
( end_index - start_index ).times do |this_time|
|
626
|
+
indexes.push( end_index - this_time - 1 )
|
627
|
+
end
|
189
628
|
|
190
|
-
|
191
|
-
|
192
|
-
|
629
|
+
slice = delete_at_indexes( *indexes )
|
630
|
+
|
631
|
+
else
|
632
|
+
|
633
|
+
slice = delete_at( start_index )
|
634
|
+
|
635
|
+
end
|
636
|
+
|
637
|
+
|
638
|
+
return slice
|
193
639
|
|
194
640
|
end
|
195
641
|
|
@@ -197,13 +643,15 @@ class CascadingConfiguration::Array::CompositingArray < ::Array
|
|
197
643
|
# clear #
|
198
644
|
###########
|
199
645
|
|
200
|
-
alias_method :super_clear, :clear
|
201
646
|
def clear
|
202
647
|
|
203
|
-
|
204
|
-
|
648
|
+
indexes = [ ]
|
649
|
+
|
650
|
+
count.times do |this_time|
|
651
|
+
indexes.push( count - this_time - 1 )
|
652
|
+
end
|
205
653
|
|
206
|
-
|
654
|
+
delete_at_indexes( *indexes )
|
207
655
|
|
208
656
|
return self
|
209
657
|
|
@@ -216,69 +664,197 @@ class CascadingConfiguration::Array::CompositingArray < ::Array
|
|
216
664
|
# freezes configuration and prevents ancestors from changing this configuration in the future
|
217
665
|
def freeze!
|
218
666
|
|
219
|
-
# move current configuration into local configuration
|
220
|
-
@local_cascading_array.clear
|
221
|
-
@local_cascading_array.exclude_array.clear
|
222
|
-
@local_cascading_array.push( *self )
|
223
|
-
|
224
667
|
# unregister with parent composite so we don't get future updates from it
|
225
|
-
|
668
|
+
if @super_composite_array
|
669
|
+
@super_composite_array.unregister_sub_composite_array( self )
|
670
|
+
end
|
226
671
|
|
227
672
|
return self
|
228
673
|
|
229
674
|
end
|
230
675
|
|
231
|
-
|
232
|
-
private
|
233
|
-
|
676
|
+
##################################################################################################
|
677
|
+
private ######################################################################################
|
678
|
+
##################################################################################################
|
234
679
|
|
235
|
-
|
236
|
-
# update_self_as_cascading_composite #
|
237
|
-
########################################
|
680
|
+
################ Self Management for Inserts between Parent-Provided Elements ##################
|
238
681
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
682
|
+
###################################
|
683
|
+
# index_inside_parent_objects? #
|
684
|
+
###################################
|
685
|
+
|
686
|
+
def index_inside_parent_objects?( index )
|
687
|
+
|
688
|
+
index_inside_parent_objects = false
|
689
|
+
|
690
|
+
if index < @parent_and_interpolated_object_count
|
691
|
+
|
692
|
+
index_inside_parent_objects = true
|
693
|
+
|
694
|
+
end
|
695
|
+
|
696
|
+
return index_inside_parent_objects
|
697
|
+
|
251
698
|
end
|
252
699
|
|
253
|
-
|
254
|
-
#
|
255
|
-
|
700
|
+
#################################################
|
701
|
+
# update_corresponding_index_for_local_change #
|
702
|
+
#################################################
|
703
|
+
|
704
|
+
def update_corresponding_index_for_local_change( index, step_value )
|
705
|
+
|
706
|
+
# update corresponding indexes for changes in self
|
707
|
+
|
708
|
+
indexes_to_delete = [ ]
|
709
|
+
|
710
|
+
@local_index_for_parent_index.each do |this_parent_index, this_local_index|
|
711
|
+
if this_parent_index >= index
|
712
|
+
existing_corresponding_value = @local_index_for_parent_index[ this_parent_index ]
|
713
|
+
new_corresponding_value = existing_corresponding_value + step_value
|
714
|
+
if new_corresponding_value >= 0
|
715
|
+
@local_index_for_parent_index[ this_parent_index ] = new_corresponding_value
|
716
|
+
else
|
717
|
+
indexes_to_delete.push( this_parent_index )
|
718
|
+
end
|
719
|
+
end
|
720
|
+
end
|
256
721
|
|
257
|
-
|
258
|
-
|
259
|
-
sort!.uniq!
|
260
|
-
update_sub_composite_arrays
|
722
|
+
step_parent_and_interpolated_object_count( step_value )
|
723
|
+
|
261
724
|
end
|
262
725
|
|
726
|
+
######################### Self-as-Sub Management for Parent Updates ############################
|
727
|
+
|
263
728
|
########################################
|
264
|
-
#
|
729
|
+
# update_as_sub_array_for_parent_set #
|
265
730
|
########################################
|
731
|
+
|
732
|
+
def update_as_sub_array_for_parent_set( index, object )
|
733
|
+
|
734
|
+
# if our index is bigger than current parent set we are inserting
|
735
|
+
if index >= @parent_and_interpolated_object_count
|
736
|
+
|
737
|
+
update_as_sub_array_for_parent_insert( index, object )
|
738
|
+
|
739
|
+
# otherwise we are replacing and have a corresponding element defined already
|
740
|
+
else
|
266
741
|
|
267
|
-
|
268
|
-
|
269
|
-
|
742
|
+
unless @replaced_parents[ index ]
|
743
|
+
|
744
|
+
corresponding_index = @local_index_for_parent_index[ index ]
|
745
|
+
non_cascading_set( corresponding_index, object )
|
746
|
+
|
747
|
+
@sub_composite_arrays.each do |this_array|
|
748
|
+
this_array.instance_eval do
|
749
|
+
update_as_sub_array_for_parent_set( corresponding_index, object )
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
end
|
754
|
+
|
270
755
|
end
|
271
|
-
|
756
|
+
|
272
757
|
end
|
273
758
|
|
274
|
-
|
275
|
-
#
|
276
|
-
|
759
|
+
###########################################
|
760
|
+
# update_as_sub_array_for_parent_insert #
|
761
|
+
###########################################
|
762
|
+
|
763
|
+
def update_as_sub_array_for_parent_insert( index, *objects )
|
764
|
+
|
765
|
+
# new parent indexes have been inserted at index in parent
|
766
|
+
|
767
|
+
# we need the corresponding index in self where parallel insert will occur
|
768
|
+
if corresponding_index = @local_index_for_parent_index[ index ]
|
769
|
+
|
770
|
+
if corresponding_index < 0
|
771
|
+
corresponding_index = 0
|
772
|
+
else
|
773
|
+
update_corresponding_index_for_parent_change( index, objects.count )
|
774
|
+
end
|
775
|
+
|
776
|
+
else
|
777
|
+
|
778
|
+
corresponding_index = @parent_and_interpolated_object_count
|
779
|
+
@parent_and_interpolated_object_count += objects.count
|
780
|
+
|
781
|
+
end
|
782
|
+
|
783
|
+
# then we're going to increment existing correspondences
|
784
|
+
# now since we added a space for the new elements we can add their new correspondences
|
785
|
+
objects.count.times do |this_time|
|
786
|
+
new_parent_index = index + this_time
|
787
|
+
new_corresponding_index = corresponding_index + this_time
|
788
|
+
@local_index_for_parent_index[ new_parent_index ] = new_corresponding_index
|
789
|
+
end
|
790
|
+
|
791
|
+
non_cascading_insert( corresponding_index, *objects )
|
792
|
+
|
793
|
+
@sub_composite_arrays.each do |this_array|
|
794
|
+
this_array.instance_eval do
|
795
|
+
update_as_sub_array_for_parent_insert( corresponding_index, *objects )
|
796
|
+
end
|
797
|
+
end
|
798
|
+
|
799
|
+
end
|
277
800
|
|
278
|
-
|
279
|
-
|
280
|
-
|
801
|
+
###########################################
|
802
|
+
# update_as_sub_array_for_parent_delete #
|
803
|
+
###########################################
|
804
|
+
|
805
|
+
def update_as_sub_array_for_parent_delete( index )
|
806
|
+
|
807
|
+
corresponding_index = @local_index_for_parent_index[ index ]
|
808
|
+
|
809
|
+
object = non_cascading_delete_at( corresponding_index )
|
810
|
+
|
811
|
+
@parent_and_interpolated_object_count -= 1
|
812
|
+
|
813
|
+
@sub_composite_arrays.each do |this_array|
|
814
|
+
this_array.instance_eval do
|
815
|
+
update_as_sub_array_for_parent_delete( corresponding_index )
|
816
|
+
end
|
817
|
+
end
|
818
|
+
|
819
|
+
end
|
820
|
+
|
821
|
+
##################################################
|
822
|
+
# update_corresponding_index_for_parent_change #
|
823
|
+
##################################################
|
824
|
+
|
825
|
+
def update_corresponding_index_for_parent_change( parent_index, step_value )
|
826
|
+
|
827
|
+
# update corresponding indexes for changes in parent
|
828
|
+
|
829
|
+
stepped_indices = { }
|
830
|
+
|
831
|
+
# iterate the hash with all indices included and increment/decrement any >= parent_index
|
832
|
+
@local_index_for_parent_index.each do |this_parent_index, this_local_index|
|
833
|
+
if this_parent_index >= parent_index
|
834
|
+
new_index = this_parent_index + step_value
|
835
|
+
stepped_indices[ new_index ] = @local_index_for_parent_index.delete( this_parent_index ) + step_value
|
836
|
+
end
|
281
837
|
end
|
838
|
+
|
839
|
+
# merge stepped indices back in
|
840
|
+
@local_index_for_parent_index.merge!( stepped_indices )
|
841
|
+
|
842
|
+
step_parent_and_interpolated_object_count( step_value )
|
843
|
+
|
282
844
|
end
|
283
845
|
|
846
|
+
###############################################
|
847
|
+
# step_parent_and_interpolated_object_count #
|
848
|
+
###############################################
|
849
|
+
|
850
|
+
def step_parent_and_interpolated_object_count( step_value )
|
851
|
+
|
852
|
+
@parent_and_interpolated_object_count += step_value
|
853
|
+
|
854
|
+
if @parent_and_interpolated_object_count < 0
|
855
|
+
@parent_and_interpolated_object_count = 0
|
856
|
+
end
|
857
|
+
|
858
|
+
end
|
859
|
+
|
284
860
|
end
|