Class: HeadMusic::Content::Score
- Defined in:
- lib/head_music/content/score.rb
Overview
A score is the layout that shows the players together: everyone's music on one system, in the order and the grouping the ensemble conventionally puts them in.
Constant Summary collapse
- KINDS =
%i[score].freeze
Instance Attribute Summary collapse
-
#ensemble_type ⇒ Object
readonly
Returns the value of attribute ensemble_type.
Class Method Summary collapse
Instance Method Summary collapse
- #ensure_known_ensemble_type! ⇒ Object private
-
#initialize(project:, ensemble_type: nil, **layout_kwargs) ⇒ Score
constructor
A new instance of Score.
-
#kept_part_indexes(flow) ⇒ Object
A score reads top to bottom in score order, so its parts are realized in that order rather than in the order they were authored.
-
#ordered_players ⇒ Object
A permutation of this layout's players, never a selection.
-
#player_groups ⇒ Object
The sections a score brackets, in score order, each holding its players.
- #position_of(player) ⇒ Object private
-
#rank_of(part, order) ⇒ Object
private
A part whose chair this score does not place keeps its authored place at the bottom, which is where an unplaced chair sits in #ordered_players too.
- #score_order ⇒ Object
- #section_key_of(player) ⇒ Object private
- #to_h ⇒ Object
Constructor Details
#initialize(project:, ensemble_type: nil, **layout_kwargs) ⇒ Score
Returns a new instance of Score.
17 18 19 20 21 |
# File 'lib/head_music/content/score.rb', line 17 def initialize(project:, ensemble_type: nil, **layout_kwargs) @ensemble_type = ensemble_type&.to_sym ensure_known_ensemble_type! super(project: project, **layout_kwargs, kind: :score) end |
Instance Attribute Details
#ensemble_type ⇒ Object (readonly)
Returns the value of attribute ensemble_type.
10 11 12 |
# File 'lib/head_music/content/score.rb', line 10 def ensemble_type @ensemble_type end |
Class Method Details
.attributes_from_h(hash, project:) ⇒ Object
12 13 14 15 |
# File 'lib/head_music/content/score.rb', line 12 def self.attributes_from_h(hash, project:) hash = hash.transform_keys(&:to_s) super.merge(ensemble_type: hash["ensemble_type"]&.to_sym) end |
Instance Method Details
#ensure_known_ensemble_type! ⇒ Object (private)
79 80 81 82 83 84 |
# File 'lib/head_music/content/score.rb', line 79 def ensure_known_ensemble_type! return if ensemble_type.nil? || HeadMusic::Instruments::ScoreOrder.get(ensemble_type) known = HeadMusic::Instruments::ScoreOrder::SCORE_ORDERS.keys.join(", ") raise ArgumentError, "unknown ensemble type: #{ensemble_type.inspect} (known: #{known})" end |
#kept_part_indexes(flow) ⇒ Object
A score reads top to bottom in score order, so its parts are realized in that order rather than in the order they were authored.
57 58 59 60 |
# File 'lib/head_music/content/score.rb', line 57 def kept_part_indexes(flow) order = ordered_players super.sort_by { |index| [rank_of(flow.parts[index], order), index] } end |
#ordered_players ⇒ Object
A permutation of this layout's players, never a selection. Chairs the order does not place come last in authored order, and ties among equals keep authored order too, so two clarinets stay first and second.
32 33 34 35 36 37 |
# File 'lib/head_music/content/score.rb', line 32 def ordered_players return players if score_order.nil? placed, unplaced = players.each_with_index.partition { |player, _index| position_of(player) } placed.sort_by { |player, index| [position_of(player), index] }.map(&:first) + unplaced.map(&:first) end |
#player_groups ⇒ Object
The sections a score brackets, in score order, each holding its players. Unplaced chairs group under a nil section key.
41 42 43 44 45 46 47 |
# File 'lib/head_music/content/score.rb', line 41 def player_groups # slice_when rather than chunk, which drops the nil-keyed run that the # unplaced chairs belong to. ordered_players .slice_when { |one, other| section_key_of(one) != section_key_of(other) } .map { |members| [section_key_of(members.first), members] } end |
#position_of(player) ⇒ Object (private)
64 65 66 |
# File 'lib/head_music/content/score.rb', line 64 def position_of(player) score_order.position_of(player.primary_instrument) end |
#rank_of(part, order) ⇒ Object (private)
A part whose chair this score does not place keeps its authored place at the bottom, which is where an unplaced chair sits in #ordered_players too.
74 75 76 77 |
# File 'lib/head_music/content/score.rb', line 74 def rank_of(part, order) index = part.player && order.index { |player| player.equal?(part.player) } index || order.length end |
#score_order ⇒ Object
23 24 25 26 27 |
# File 'lib/head_music/content/score.rb', line 23 def score_order return nil if ensemble_type.nil? @score_order ||= HeadMusic::Instruments::ScoreOrder.get(ensemble_type) end |
#section_key_of(player) ⇒ Object (private)
68 69 70 |
# File 'lib/head_music/content/score.rb', line 68 def section_key_of(player) score_order&.section_key_of(player.primary_instrument) end |
#to_h ⇒ Object
49 50 51 |
# File 'lib/head_music/content/score.rb', line 49 def to_h super.merge("ensemble_type" => ensemble_type&.to_s) end |