X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fdispatcher.cc;h=b1b076759f83b8a7e1a655d84054957b84afb4c5;hb=a6a51abfd0195a3cf7d6ea095cf69808852f21ce;hp=b268218f4719905b3f882e788bad22bcc4ef4f5f;hpb=47db9a3883d726ca53e2133a3b2298f78dd6a32e;p=lilypond.git diff --git a/lily/dispatcher.cc b/lily/dispatcher.cc index b268218f47..b1b076759f 100644 --- a/lily/dispatcher.cc +++ b/lily/dispatcher.cc @@ -21,8 +21,9 @@ #include "input.hh" #include "international.hh" #include "warn.hh" +#include "lily-imports.hh" -const char Dispatcher::type_p_name_[] = "ly:dispatcher?"; +const char * const Dispatcher::type_p_name_ = "ly:dispatcher?"; Dispatcher::~Dispatcher () { @@ -41,7 +42,7 @@ Dispatcher::Dispatcher () } SCM -Dispatcher::mark_smob () +Dispatcher::mark_smob () const { scm_gc_mark (dispatchers_); scm_gc_mark (listen_classes_); @@ -49,11 +50,10 @@ Dispatcher::mark_smob () } int -Dispatcher::print_smob (SCM p, scm_print_state *) +Dispatcher::print_smob (SCM p, scm_print_state *) const { scm_puts ("#alist"), - listeners_), p); + scm_write (Lily::hash_table_to_alist (listeners_), p); scm_puts (">", p); return 1; } @@ -72,11 +72,10 @@ Event dispatching: combination of dispatchers, even if it matches more than one event type. */ -IMPLEMENT_LISTENER (Dispatcher, dispatch); void Dispatcher::dispatch (SCM sev) { - Stream_event *ev = Stream_event::unsmob (sev); + Stream_event *ev = unsmob (sev); SCM class_list = ev->get_property ("class"); if (!scm_is_pair (class_list)) { @@ -143,8 +142,8 @@ Dispatcher::dispatch (SCM sev) assert (lists[0].prio > last_priority); last_priority = lists[0].prio; - Listener *l = Listener::unsmob (scm_cdar (lists[0].list)); - l->listen (ev->self_scm ()); + SCM l = scm_cdar (lists[0].list); + scm_call_1 (l, ev->self_scm ()); #if 0 sent = true; #endif @@ -207,13 +206,20 @@ Dispatcher::broadcast (Stream_event *ev) void Dispatcher::add_listener (Listener l, SCM ev_class) { - internal_add_listener (l, ev_class, ++priority_count_); + add_listener (l.smobbed_copy (), ev_class); +} + +void +Dispatcher::add_listener (SCM callback, SCM ev_class) +{ + internal_add_listener (callback, ev_class, ++priority_count_); } inline void -Dispatcher::internal_add_listener (Listener l, SCM ev_class, int priority) +Dispatcher::internal_add_listener (SCM callback, SCM ev_class, int priority) { - SCM list = scm_hashq_ref (listeners_, ev_class, SCM_EOL); + SCM handle = scm_hashq_create_handle_x (listeners_, ev_class, SCM_EOL); + SCM list = scm_cdr (handle); // if ev_class is not yet listened to, we go through our list of // source dispatchers and register ourselves there with the priority // we have reserved for this dispatcher. The priority system @@ -229,34 +235,36 @@ Dispatcher::internal_add_listener (Listener l, SCM ev_class, int priority) for (SCM disp = dispatchers_; scm_is_pair (disp); disp = scm_cdr (disp)) { int priority = scm_to_int (scm_cdar (disp)); - Dispatcher *d = Dispatcher::unsmob (scm_caar (disp)); - d->internal_add_listener (GET_LISTENER (dispatch), ev_class, priority); + Dispatcher *d = unsmob (scm_caar (disp)); + d->internal_add_listener (GET_LISTENER (Dispatcher, dispatch).smobbed_copy (), + ev_class, priority); } listen_classes_ = scm_cons (ev_class, listen_classes_); } - SCM entry = scm_cons (scm_from_int (priority), l.smobbed_copy ()); - list = scm_merge (list, scm_list_1 (entry), ly_lily_module_constant ("car<")); - scm_hashq_set_x (listeners_, ev_class, list); + SCM entry = scm_cons (scm_from_int (priority), callback); + list = scm_merge (list, scm_list_1 (entry), Lily::car_less); + scm_set_cdr_x (handle, list); } void Dispatcher::remove_listener (Listener l, SCM ev_class) { - SCM list = scm_hashq_ref (listeners_, ev_class, SCM_EOL); + SCM handle = scm_hashq_get_handle (listeners_, ev_class); - if (list == SCM_EOL) + if (scm_is_false (handle)) { programming_error ("remove_listener called with incorrect class."); return; } + SCM list = scm_cdr (handle); // We just remove the listener once. bool first = true; SCM dummy = scm_cons (SCM_EOL, list); SCM e = dummy; while (scm_is_pair (scm_cdr (e))) - if (*Listener::unsmob (scm_cdadr (e)) == l && first) + if (*unsmob (scm_cdadr (e)) == l && first) { scm_set_cdr_x (e, scm_cddr (e)); first = false; @@ -265,7 +273,7 @@ Dispatcher::remove_listener (Listener l, SCM ev_class) else e = scm_cdr (e); list = scm_cdr (dummy); - scm_hashq_set_x (listeners_, ev_class, list); + scm_set_cdr_x (handle, list); if (first) warning (_ ("Attempting to remove nonexisting listener.")); @@ -274,8 +282,8 @@ Dispatcher::remove_listener (Listener l, SCM ev_class) /* Unregister with all dispatchers. */ for (SCM disp = dispatchers_; scm_is_pair (disp); disp = scm_cdr (disp)) { - Dispatcher *d = Dispatcher::unsmob (scm_caar (disp)); - d->remove_listener (GET_LISTENER (dispatch), ev_class); + Dispatcher *d = unsmob (scm_caar (disp)); + d->remove_listener (GET_LISTENER (Dispatcher, dispatch), ev_class); } listen_classes_ = scm_delq_x (ev_class, listen_classes_); } @@ -292,7 +300,7 @@ Dispatcher::register_as_listener (Dispatcher *disp) int priority = ++disp->priority_count_; // Don't register twice to the same dispatcher. - if (scm_assq (disp->self_scm (), dispatchers_) != SCM_BOOL_F) + if (scm_is_true (scm_assq (disp->self_scm (), dispatchers_))) { warning (_ ("Already listening to dispatcher, ignoring request")); return; @@ -300,7 +308,7 @@ Dispatcher::register_as_listener (Dispatcher *disp) dispatchers_ = scm_acons (disp->self_scm (), scm_from_int (priority), dispatchers_); - Listener list = GET_LISTENER (dispatch); + SCM list = GET_LISTENER (Dispatcher, dispatch).smobbed_copy (); for (SCM cl = listen_classes_; scm_is_pair (cl); cl = scm_cdr (cl)) { disp->internal_add_listener (list, scm_car (cl), priority); @@ -313,7 +321,7 @@ Dispatcher::unregister_as_listener (Dispatcher *disp) { dispatchers_ = scm_assq_remove_x (dispatchers_, disp->self_scm ()); - Listener listener = GET_LISTENER (dispatch); + Listener listener = GET_LISTENER (Dispatcher, dispatch); for (SCM cl = listen_classes_; scm_is_pair (cl); cl = scm_cdr (cl)) { disp->remove_listener (listener, scm_car (cl));