add method

void add(
  1. MusicalElement element
)

Adds a musical element to the measure.

When a time signature is present, validates capacity before adding to ensure the bar's rhythmic value is not exceeded. The check is done against the value already written in the voice the element belongs to (voiceNumberOf), so independent voices may each fill the bar.

Throws MeasureCapacityException if the element would exceed the capacity of its own voice.

Implementation

void add(MusicalElement element) {
  // Check if the element occupies musical time
  final elementDuration = musicalValueOf(element);

  if (elementDuration > 0) {
    // Retrieve the time signature from the measure or use the inherited one
    final ts = timeSignature ?? inheritedTimeSignature;

    if (ts != null) {
      // Only the incoming element's own voice competes for the bar's space.
      final voice = voiceNumberOf(element);
      final currentValue = musicalValueOfVoice(voice);
      final measureCapacity = ts.measureValue;
      final afterAdding = currentValue + elementDuration;

      if (afterAdding > measureCapacity + capacityTolerance) {
        final excess = afterAdding - measureCapacity;
        throw MeasureCapacityException(
          'Cannot add ${element.runtimeType} to voice $voice of the measure!\n'
          'Measure ${ts.numerator}/${ts.denominator} (capacity: $measureCapacity units per voice)\n'
          'Current value of voice $voice: $currentValue units\n'
          'Attempting to add: $elementDuration units\n'
          'Total would be: $afterAdding units\n'
          'EXCESS: ${excess.toStringAsFixed(4)} units\n'
          'OPERATION BLOCKED — Remove elements from voice $voice, move the '
          'element to another voice, or create a new measure!'
        );
      }
    }
  }

  // Add the element
  elements.add(element);
}