X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fdispatcher.cc;h=b1b076759f83b8a7e1a655d84054957b84afb4c5;hb=a6a51abfd0195a3cf7d6ea095cf69808852f21ce;hp=49536a0a8a36d7485bb1211522d22e34813591a8;hpb=5bbfc22fce036b9b69df5e420de93e11da23c05e;p=lilypond.git diff --git a/lily/dispatcher.cc b/lily/dispatcher.cc index 49536a0a8a..b1b076759f 100644 --- a/lily/dispatcher.cc +++ b/lily/dispatcher.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 2005--2014 Erik Sandberg + Copyright (C) 2005--2015 Erik Sandberg LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,12 +20,10 @@ #include "dispatcher.hh" #include "input.hh" #include "international.hh" -#include "ly-smobs.icc" #include "warn.hh" +#include "lily-imports.hh" -IMPLEMENT_SMOBS (Dispatcher); -IMPLEMENT_TYPE_P (Dispatcher, "ly:dispatcher?"); -IMPLEMENT_DEFAULT_EQUAL_P (Dispatcher); +const char * const Dispatcher::type_p_name_ = "ly:dispatcher?"; Dispatcher::~Dispatcher () { @@ -33,7 +31,6 @@ Dispatcher::~Dispatcher () Dispatcher::Dispatcher () { - self_scm_ = SCM_EOL; listeners_ = SCM_EOL; dispatchers_ = SCM_EOL; listen_classes_ = SCM_EOL; @@ -45,21 +42,18 @@ Dispatcher::Dispatcher () } SCM -Dispatcher::mark_smob (SCM sm) +Dispatcher::mark_smob () const { - Dispatcher *me = (Dispatcher *) SCM_CELL_WORD_1 (sm); - scm_gc_mark (me->dispatchers_); - scm_gc_mark (me->listen_classes_); - return me->listeners_; + scm_gc_mark (dispatchers_); + scm_gc_mark (listen_classes_); + return listeners_; } int -Dispatcher::print_smob (SCM s, SCM p, scm_print_state *) +Dispatcher::print_smob (SCM p, scm_print_state *) const { - Dispatcher *me = (Dispatcher *) SCM_CELL_WORD_1 (s); scm_puts ("#alist"), - me->listeners_), p); + scm_write (Lily::hash_table_to_alist (listeners_), p); scm_puts (">", p); return 1; } @@ -78,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 = unsmob_stream_event (sev); + Stream_event *ev = unsmob (sev); SCM class_list = ev->get_property ("class"); if (!scm_is_pair (class_list)) { @@ -149,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 @@ -213,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 @@ -235,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; @@ -271,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.")); @@ -280,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_); } @@ -298,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; @@ -306,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); @@ -319,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));