cascading-configuration-array 1.6.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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, configuration_name, self )
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 in case it gets updated in the future
20
- if ancestor = ::CascadingConfiguration::Variable.ancestor( configuration_instance, configuration_name )
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
- def []=( index, element )
66
- # we sort internally, so index is irrelevant
67
- # no reason to differentiate from push
68
- push( element )
69
- end
70
-
71
- ########
72
- # << #
73
- ########
88
+ private
89
+ alias_method :non_cascading_set, :[]=
90
+ public
74
91
 
75
- def <<( *elements )
76
- # no reason to differentiate from push
77
- push( *elements )
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
- def +( *arrays )
85
- # no reason to differentiate from push
86
- arrays.each do |this_array|
87
- push( *this_array )
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
- # push #
104
- ##########
180
+ ############
181
+ # delete #
182
+ ############
105
183
 
106
- alias_method :super_push, :push
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
- return self
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
- delete( *this_array )
227
+ delete_objects( *this_array )
127
228
  end
128
229
 
129
230
  return self
130
231
 
131
232
  end
132
233
 
133
- ############
134
- # delete #
135
- ############
234
+ ###############
235
+ # delete_at #
236
+ ###############
237
+
238
+ private
239
+ alias_method :non_cascading_delete_at, :delete_at
240
+ public
136
241
 
137
- alias_method :super_delete, :delete
138
- def delete( *elements )
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
- @local_cascading_array.delete( *elements )
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
- update_removing_composite_elements( *elements )
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
- element = super
155
-
156
- @local_cascading_array.delete( element )
157
-
158
- update_removing_composite_elements( element )
580
+ object = delete_at( count - 1 )
159
581
 
160
- return element
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
- element = super
171
-
172
- @local_cascading_array.delete( element )
592
+ object = delete_at( 0 )
173
593
 
174
- update_removing_composite_elements( element )
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!( *args )
602
+ def slice!( index_start_or_range, length = nil )
185
603
 
186
- elements = super
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
- @local_cascading_array.delete( *elements )
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
- update_removing_composite_elements( *elements )
191
-
192
- return elements
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
- # add all existing values to exclude array
204
- @local_cascading_array.delete( *self )
648
+ indexes = [ ]
649
+
650
+ count.times do |this_time|
651
+ indexes.push( count - this_time - 1 )
652
+ end
205
653
 
206
- update_removing_composite_elements( *self )
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
- @super_composite_array.unregister_sub_composite_array( self ) if @super_composite_array
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
- def update_self_as_cascading_composite
240
- # start fresh
241
- super_clear
242
- # add parent config
243
- super_push( *@super_composite_array ) if @super_composite_array
244
- # add additional local config
245
- super_push( *@local_cascading_array )
246
- # remove local exclude
247
- super_delete( *@local_cascading_array.exclude_array ) unless @local_cascading_array.exclude_array.empty?
248
- # notify children to update their composite status
249
- update_sub_composite_arrays
250
- return self
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
- # update_adding_composite_elements #
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
- def update_adding_composite_elements( *elements_to_cascade )
258
- super_push( *elements_to_cascade )
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
- # update_removing_composite_elements #
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
- def update_removing_composite_elements( *elements_to_exclude )
268
- elements_to_exclude.each do |this_excluded_element|
269
- super_delete( this_excluded_element )
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
- update_sub_composite_arrays
756
+
272
757
  end
273
758
 
274
- ###################################
275
- # update_sub_composite_arrays #
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
- def update_sub_composite_arrays
279
- @sub_composite_arrays.each do |this_composite_array|
280
- this_composite_array.instance_eval { update_self_as_cascading_composite }
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