#include "protected-scm.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
+#include "stream-event.hh"
#include "tie-column.hh"
#include "tie.hh"
#include "warn.hh"
+#include "translator.icc"
+
/**
Manufacture ties. Acknowledge noteheads, and put them into a
priority queue. If we have a TieEvent, connect the notes that finish
struct Head_event_tuple
{
Grob *head_;
+ Moment end_moment_;
SCM tie_definition_;
- Music *event_;
+ Stream_event *event_;
+
Head_event_tuple ()
{
- }
- Head_event_tuple (Grob *h, Music *m, SCM def)
- {
- head_ = h;
- event_ = m;
- tie_definition_ = def;
+ event_ = 0;
+ head_ = 0;
+ tie_definition_ = SCM_EOL;
}
};
class Tie_engraver : public Engraver
{
- Music *event_;
- Link_array<Grob> now_heads_;
- Array<Head_event_tuple> heads_to_tie_;
- Link_array<Grob> ties_;
+ Stream_event *event_;
+ vector<Grob*> now_heads_;
+ vector<Head_event_tuple> heads_to_tie_;
+ vector<Grob*> ties_;
Spanner *tie_column_;
virtual void derived_mark () const;
void start_translation_timestep ();
DECLARE_ACKNOWLEDGER (note_head);
- virtual bool try_music (Music *);
+ DECLARE_TRANSLATOR_LISTENER (tie);
void process_music ();
void typeset_tie (Grob *);
public:
Tie_engraver::derived_mark () const
{
Engraver::derived_mark ();
- for (int i = 0; i < heads_to_tie_.size (); i++)
+ for (vsize i = 0; i < heads_to_tie_.size (); i++)
scm_gc_mark (heads_to_tie_[i].tie_definition_);
}
tie_column_ = 0;
}
-bool
-Tie_engraver::try_music (Music *mus)
+IMPLEMENT_TRANSLATOR_LISTENER (Tie_engraver, tie);
+void
+Tie_engraver::listen_tie (Stream_event *ev)
{
- if (mus->is_mus_type ("tie-event"))
- event_ = mus;
-
- return true;
+ event_ = ev;
}
void
Tie_engraver::acknowledge_note_head (Grob_info i)
{
Grob *h = i.grob ();
- now_heads_.push (h);
- for (int i = heads_to_tie_.size (); i--;)
+ now_heads_.push_back (h);
+ for (vsize i = heads_to_tie_.size (); i--;)
{
Grob *th = heads_to_tie_[i].head_;
- Music *right_mus = unsmob_music (h->get_property ("cause"));
- Music *left_mus = unsmob_music (th->get_property ("cause"));
+ Stream_event *right_ev = unsmob_stream_event (h->get_property ("cause"));
+ Stream_event *left_ev = unsmob_stream_event (th->get_property ("cause"));
/*
maybe should check positions too.
*/
- if (right_mus && left_mus
- && ly_is_equal (right_mus->get_property ("pitch"),
- left_mus->get_property ("pitch")))
+ if (right_ev && left_ev
+ && !to_boolean (left_ev->get_property ("untied"))
+ && ly_is_equal (right_ev->get_property ("pitch"),
+ left_ev->get_property ("pitch")))
{
Grob *p = new Spanner (heads_to_tie_[i].tie_definition_,
context ()->get_grob_key ("Tie"));
Tie::set_head (p, LEFT, th);
Tie::set_head (p, RIGHT, h);
- ties_.push (p);
- heads_to_tie_.del (i);
+ ties_.push_back (p);
+ heads_to_tie_.erase (heads_to_tie_.begin () + i);
}
}
tie_column_ = make_spanner ("TieColumn", ties_[0]->self_scm ());
if (tie_column_)
- for (int i = ties_.size (); i--;)
+ for (vsize i = ties_.size (); i--;)
Tie_column::add_tie (tie_column_, ties_[i]);
}
{
context ()->set_property ("tieMelismaBusy",
ly_bool2scm (heads_to_tie_.size ()));
+
+
+ if (!to_boolean (get_property ("tieWaitForNote")))
+ {
+ Moment now = now_mom ();
+ for (vsize i = heads_to_tie_.size (); i--; )
+ {
+ if (now > heads_to_tie_[i].end_moment_)
+ heads_to_tie_.erase (heads_to_tie_.begin () + i);
+ }
+ }
}
void
if (!to_boolean (get_property ("tieWaitForNote")))
heads_to_tie_.clear ();
- for (int i = 0; i < ties_.size (); i++)
+ for (vsize i = 0; i < ties_.size (); i++)
typeset_tie (ties_[i]);
ties_.clear ();
if (!to_boolean (get_property ("tieWaitForNote")))
heads_to_tie_.clear ();
- for (int i = 0; i < now_heads_.size (); i++)
+ for (vsize i = 0; i < now_heads_.size (); i++)
{
- heads_to_tie_.push (Head_event_tuple (now_heads_[i], event_,
- start_definition));
+ Grob *head = now_heads_[i];
+ Stream_event *left_ev = unsmob_stream_event (head->get_property ("cause"));
+ if (left_ev)
+ {
+ Head_event_tuple event_tup;
+
+ event_tup.head_ = head;
+ event_tup.tie_definition_ = start_definition;
+ event_tup.event_ = event_;
+
+ Moment end = now_mom ();
+ if (end.grace_part_)
+ {
+ end.grace_part_ += get_event_length (left_ev).main_part_;
+ }
+ else
+ {
+ end += get_event_length (left_ev);
+ }
+ event_tup.end_moment_ = end;
+
+ heads_to_tie_.push_back (event_tup);
+ }
}
}
sp->set_bound (RIGHT, new_head_drul[RIGHT]);
}
-#include "translator.icc"
-
ADD_ACKNOWLEDGER (Tie_engraver, note_head);
ADD_TRANSLATOR (Tie_engraver,
/* doc */ "Generate ties between noteheads of equal pitch.",