]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/context.cc, lily/music.cc, lily/context-scheme.cc: Add
authorErik Sandberg <mandolaerik@gmail.com>
Tue, 16 May 2006 11:30:55 +0000 (11:30 +0000)
committerErik Sandberg <mandolaerik@gmail.com>
Tue, 16 May 2006 11:30:55 +0000 (11:30 +0000)
dispatchers event-source and events-below to Context

12 files changed:
lily/context-def.cc
lily/context-scheme.cc
lily/context.cc
lily/dispatcher.cc
lily/include/context.hh
lily/include/music.hh
lily/include/stream-event.hh
lily/listener.cc
lily/music-iterator.cc
lily/music.cc
scm/define-event-classes.scm
scm/lily.scm

index d77b075322ed0433ac17a367f4ffcde327a8f5e1..05363e498c32279b0be00529d1d19fa643e12471 100644 (file)
@@ -298,6 +298,7 @@ Context_def::instantiate (SCM ops, Object_key const *key)
     context = new Context (key);
 
   context->definition_ = self_scm ();
+  context->definition_mods_ = ops;
 
   SCM trans_names = get_translator_names (ops);
 
index 51b49b7d8fe606d5107af20fd5850331fa98e2af..92240a9b1d8dc1636d4cce9e89538eeda7a6ce95 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "context.hh"
 #include "context-def.hh"
+#include "dispatcher.hh"
 
 LY_DEFINE (ly_context_id, "ly:context-id",
           1, 0, 0, (SCM context),
@@ -159,3 +160,22 @@ LY_DEFINE (ly_context_now, "ly:context-now",
   SCM_ASSERT_TYPE (ctx, context, SCM_ARG1, __FUNCTION__, "Context");
   return ctx->now_mom ().smobbed_copy ();
 }
+
+LY_DEFINE (ly_context_event_source, "ly:context-event-source",
+           1, 0, 0, (SCM context),
+           "Return event-source of context CONTEXT")
+{
+  Context *ctx = unsmob_context (context);
+  SCM_ASSERT_TYPE (ctx, context, SCM_ARG1, __FUNCTION__, "Context");
+  return ctx->event_source ()->self_scm ();
+}
+
+LY_DEFINE (ly_context_events_below, "ly:context-events-below",
+           1, 0, 0, (SCM context),
+           "Return a stream-distributor that distributes all events\n"
+           " from @var{context} and all its subcontexts.")
+{
+  Context *ctx = unsmob_context (context);
+  SCM_ASSERT_TYPE (ctx, context, SCM_ARG1, __FUNCTION__, "Context");
+  return ctx->events_below ()->self_scm ();
+}
index 9ebdb106957217cb584f721024ead451d0117113..7ab871b15ec9b033e4e55b40216666ffa671af7b 100644 (file)
@@ -9,6 +9,7 @@
 #include "context.hh"
 
 #include "context-def.hh"
+#include "dispatcher.hh"
 #include "international.hh"
 #include "ly-smobs.icc"
 #include "main.hh"
@@ -24,7 +25,7 @@ bool
 Context::is_removable () const
 {
   return context_list_ == SCM_EOL && ! iterator_count_
-    && !dynamic_cast<Score_context const *> (this);
+    && !dynamic_cast<Global_context const *> (daddy_context_);
 }
 
 void
@@ -96,12 +97,19 @@ Context::Context (Object_key const *key)
   accepts_list_ = SCM_EOL;
   context_list_ = SCM_EOL;
   definition_ = SCM_EOL;
+  definition_mods_ = SCM_EOL;
   unique_ = -1;
+  event_source_ = 0;
+  events_below_ = 0;
 
   smobify_self ();
 
   Scheme_hash_table *tab = new Scheme_hash_table;
   properties_scm_ = tab->unprotect ();
+  event_source_ = new Dispatcher ();
+  event_source_->unprotect ();
+  events_below_ = new Dispatcher ();
+  events_below_->unprotect ();
 
   /*
     UGH UGH
@@ -117,9 +125,9 @@ Context::create_unique_context (SCM name, string id, SCM operations)
   /*
     Don't create multiple score contexts.
   */
-  if (dynamic_cast<Global_context *> (this)
-      && dynamic_cast<Global_context *> (this)->get_score_context ())
-    return get_score_context ()->create_unique_context (name, id, operations);
+  Global_context *gthis = dynamic_cast<Global_context *> (this);
+  if (gthis && gthis->get_score_context ())
+    return gthis->get_score_context ()->create_unique_context (name, id, operations);
 
   /*
     TODO: use accepts_list_.
@@ -171,9 +179,9 @@ Context::find_create_context (SCM n, string id, SCM operations)
   /*
     Don't create multiple score contexts.
   */
-  if (dynamic_cast<Global_context *> (this)
-      && dynamic_cast<Global_context *> (this)->get_score_context ())
-    return get_score_context ()->find_create_context (n, id, operations);
+  Global_context *gthis = dynamic_cast<Global_context *> (this);
+  if (gthis && gthis->get_score_context ())
+    return gthis->get_score_context ()->find_create_context (n, id, operations);
 
   if (Context *existing = find_context_below (this, n, id))
     return existing;
@@ -232,15 +240,29 @@ Context::create_context (Context_def *cdef,
                         string id,
                         SCM ops)
 {
+  int unique = get_global_context()->new_unique();
+
+  // TODO: The following should be carried out by a listener.
   string type = ly_symbol2string (cdef->get_context_name ());
   Object_key const *key = key_manager_.get_context_key (now_mom(), type, id);
   Context *new_context
     = cdef->instantiate (ops, key);
 
-  new_context->unique_ = get_global_context()->new_unique();
   new_context->id_string_ = id;
+  new_context->unique_ = unique;
+  
+  new_context->events_below_->register_as_listener (new_context->event_source_);
+  
   add_context (new_context);
   apply_property_operations (new_context, ops);
+  events_below_->register_as_listener (new_context->events_below_);
+
+  // TODO: The above operations should be performed by a listener to the following event.
+  send_stream_event (this, "CreateContext",
+                     ly_symbol2scm ("unique"), scm_int2num (unique),
+                     ly_symbol2scm ("ops"), ops,
+                     ly_symbol2scm ("type"), cdef->get_context_name (),
+                     ly_symbol2scm ("id"), scm_makfrom0str (id.c_str ()));
 
   return new_context;
 }
@@ -280,10 +302,7 @@ Context::get_default_interpreter ()
        }
 
       Context *tg = create_context (t, "", SCM_EOL);
-      if (!tg->is_bottom_context ())
-       return tg->get_default_interpreter ();
-      else
-       return tg;
+      return tg->get_default_interpreter ();
     }
   return this;
 }
@@ -326,6 +345,19 @@ Context::internal_get_property (SCM sym) const
   return val;
 }
 
+void
+Context::internal_send_stream_event (SCM type, SCM props[])
+{
+  Stream_event *e = new Stream_event (this, type);
+  for (int i = 0; props[i]; i++)
+  {
+    assert(props[i+1]);
+    e->internal_set_property (props[i], props[i+1]);
+  }
+  event_source_->broadcast (e);
+  e->unprotect ();
+}
+
 bool
 Context::is_alias (SCM sym) const
 {
@@ -377,6 +409,7 @@ Context::remove_context (Context *trans)
   return trans;
 }
 
+
 /*
   ID == "" means accept any ID.
 */
@@ -402,6 +435,25 @@ find_context_below (Context *where,
   return found;
 }
 
+Context *
+find_context_below (Context *where,
+                    int unique)
+{
+  if (where->get_unique () == unique)
+    return where;
+
+  Context *found = 0;
+  for (SCM s = where->children_contexts ();
+       !found && scm_is_pair (s); s = scm_cdr (s))
+    {
+      Context *tr = unsmob_context (scm_car (s));
+
+      found = find_context_below (tr, unique);
+    }
+
+  return found;
+}
+
 SCM
 Context::properties_as_alist () const
 {
@@ -500,10 +552,13 @@ Context::mark_smob (SCM sm)
   scm_gc_mark (me->context_list_);
   scm_gc_mark (me->aliases_);
   scm_gc_mark (me->definition_);
+  scm_gc_mark (me->definition_mods_);
   scm_gc_mark (me->properties_scm_);
   scm_gc_mark (me->accepts_list_);
   if (me->implementation_)
     scm_gc_mark (me->implementation_->self_scm ());
+  if (me->event_source_) scm_gc_mark (me->event_source_->self_scm ());
+  if (me->events_below_) scm_gc_mark (me->events_below_->self_scm ());
 
   return me->properties_scm_;
 }
index c6fedb23741f6b050dd4dffe2768e6bc3fc62727..e66f0952cb69456cbf2e61b328cc8e474cf6fcb3 100644 (file)
@@ -31,7 +31,9 @@ Dispatcher::Dispatcher ()
   dispatchers_ = SCM_EOL;
   listen_classes_ = SCM_EOL;
   smobify_self ();
-  listeners_ = scm_c_make_hash_table (0);
+// TODO: use resizable hash (guile 1.8)
+//  listeners_ = scm_c_make_hash_table (0);
+  listeners_ = scm_c_make_hash_table (17);
   priority_count_ = 0;
 }
 
@@ -147,8 +149,10 @@ Dispatcher::dispatch (SCM sev)
       lists[i].list = next;
     }
 
+/* TODO: Uncomment.
   if (!sent)
     warning (_f ("Junking event: %s", ly_symbol2string (class_symbol).c_str ()));
+*/
 }
 
 void
index 4b85bd31cdc5136d973a2dbec5eef15843e9715b..5a7eb92687a522dd0f1f7043f0edf6cabd223341 100644 (file)
@@ -33,7 +33,10 @@ private:
 protected:
   int unique_;
   Context *daddy_context_;
+  /* The used Context_def */
   SCM definition_;
+  /* Additions to the Context_def, given by \with */
+  SCM definition_mods_;
   Context_key_manager key_manager_;
   
   SCM properties_scm_;
@@ -42,6 +45,13 @@ protected:
   SCM aliases_;
   Translator_group *implementation_;
   string id_string_;
+  
+  /* Events reported in the context is sent to this dispatcher. */
+  Dispatcher *event_source_;
+
+  /* Events reported to this context or recursively in any of its
+     children, are sent to this dispatcher. */
+  Dispatcher *events_below_;
 
   friend class Context_def;
   void clear_key_disambiguations ();
@@ -57,6 +67,13 @@ public:
   SCM default_child_context_name () const;
   int get_unique() { return unique_; }
 
+  Dispatcher *event_source () const { return event_source_; }
+  Dispatcher *events_below () const { return events_below_; }
+  void internal_send_stream_event (SCM type, SCM props[]);
+
+  SCM get_definition () const { return definition_; }
+  SCM get_definition_mods () const { return definition_mods_; }
+
   Translator_group *implementation () const { return implementation_; }
   Context *get_parent_context () const;
   Context (Object_key const *);
@@ -116,5 +133,12 @@ Moment measure_position (Context const *context);
 Rational measure_length (Context const *context);
 void set_context_property_on_children (Context *trans, SCM sym, SCM val);
 
+/* Shorthand for creating and broadcasting stream events. */
+#define send_stream_event(ctx, type, ...)                              \
+{                                                                      \
+  SCM props[] = { __VA_ARGS__, 0 };                                    \
+  ctx->internal_send_stream_event (ly_symbol2scm (type), props);       \
+}
+
 #endif /* CONTEXT_HH */
 
index f278786847033f827f1413e4108a3b0f2e8b8d33..3c43209b47307e256f8b8607ca9938b7f40617fa 100644 (file)
@@ -41,6 +41,9 @@ public:
 
   /// Scale the music in time by #factor#.
   void compress (Moment factor);
+  
+  // Broadcast the event in a context's event-source.
+  void send_to_context (Context *c);
 
   DECLARE_SCHEME_CALLBACK (duration_length_callback, (SCM));
   
index 9966a35eb96dc5a3abe6245d57f7ff7a74c265ff..13535c73f6ecd1826db46bf0e23eb2b4b5ed9569 100644 (file)
@@ -42,15 +42,4 @@ protected:
 DECLARE_UNSMOB (Stream_event, stream_event);
 DECLARE_TYPE_P (Stream_event);
 
-#define SEND_EVENT_TO_CONTEXT(ctx, cl, ...)                            \
-  {                                                                    \
-    Stream_event *_e_ = new Stream_event (ctx, ly_symbol2scm (cl));    \
-    __VA_ARGS__;                                                       \
-    ctx->event_source ()->distribute (_e_);                            \
-    scm_gc_unprotect_object (_e_->self_scm ());                                \
-  }
-  
-#define EVENT_PROPERTY(prop, val)      \
-  (_e_->set_property (prop, val))
-
 #endif /* STREAM_EVENT_HH */
index 8b9f3ad9ac30047aca16d773344ae1ddfc4dc007..edc96bdf1c84aed5a51c69b87ae4914a125ebe77 100644 (file)
 #include "ly-smobs.icc"
 #include "warn.hh"
 
-/*
-Listener_target::~Listener_target ()
-{
-}
-*/
-
 Listener::Listener (const void *target, Listener_function_table *type)
 {
   target_ = (void *)target;
index 326b97502886559ab3140f6e07f1c2573ecbcd77..528fffb682817b2e6bb74dcbb669ff7324eb49e0 100644 (file)
@@ -157,6 +157,12 @@ Music_iterator::try_music (Music *m) const
   Music_iterator *it = b ? (Music_iterator *) this : 0;        // ugh
   if (!it)
     it = try_music_in_children (m);
+  else
+    /* TODO: try_music should only do the following:
+     - descend iterator to bottom context
+     - send music to a bottom context.
+     The function should also be renamed, and it should not return a value. */
+    m->send_to_context (get_outlet ());
   return it;
 }
 
index 191f42a1b725d82e00a3ba84470749f18efe2730..5bd573dab00519ee22f18a12a549890761a66ffa 100644 (file)
@@ -8,6 +8,8 @@
 
 #include "music.hh"
 
+#include "context.hh"
+#include "dispatcher.hh"
 #include "duration.hh"
 #include "input-smob.hh"
 #include "international.hh"
@@ -234,6 +236,13 @@ Music::origin () const
   return ip ? ip : &dummy_input_global;
 }
 
+void
+Music::send_to_context (Context *c)
+{
+  send_stream_event (c, "MusicEvent",
+                    ly_symbol2scm("music"), self_scm ());
+}
+
 Music *
 make_music_by_name (SCM sym)
 {
index 80bf8a4fa87439558075f1bed85fb9294a0e2225..84d6ef57d4001d978b463b946f5ebf763ff0b573 100644 (file)
       MusicEvent CreateContext Prepare OneTimeStep Finish) . StreamEvent)
     ))
 
+;; Maps event-class to a list of ancestors (inclusive)
+;; TODO: use resizable hash
+(define ancestor-lookup (make-hash-table 1))
+
 ;; Each class will be defined as
 ;; (class parent grandparent .. )
 ;; so that (eq? (cdr class) parent) holds.
  (lambda (rel)
    (for-each
     (lambda (type)
-      (primitive-eval `(define ,type (cons ',type ,(cdr rel)))))
+      (hashq-set! ancestor-lookup type (cons type (hashq-ref ancestor-lookup (cdr rel) '())))) ;; `(define ,type (cons ',type ,(cdr rel)))))
     (car rel)))
  event-classes)
 
 ;; TODO: Allow entering more complex classes, by taking unions.
 (define-public (ly:make-event-class leaf)
- (primitive-eval leaf))
+ (hashq-ref ancestor-lookup leaf))
+;; (primitive-eval leaf))
 
 (defmacro-public make-stream-event (expr)
   (Stream_event::undump (primitive-eval (list 'quasiquote expr))))
index 701c70ea6aee17c9ea9db9bf41d2cce5ed906503..f0cda6749e63f53e632f927604607a8955e0aef5 100644 (file)
@@ -228,7 +228,7 @@ The syntax is the same as `define*-public'."
          ;; load-from-path
          '("lily-library.scm"
            "file-cache.scm"
-;          "define-event-classes.scm"
+           "define-event-classes.scm"
            "define-music-types.scm"
            "output-lib.scm"
            "c++.scm"