changeset 3250:43f084bfce99 dispatcher

Added dispatcher to screen
author unexist
date Thu, 27 Aug 2015 09:20:10 +0200
parents 31e0a9716e58
children
files src/subtlext/screen.c src/subtlext/subtlext.c src/subtlext/subtlext.h
diffstat 3 files changed, 63 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/subtlext/screen.c	Tue Jan 06 16:47:32 2015 +0100
+++ b/src/subtlext/screen.c	Thu Aug 27 09:20:10 2015 +0200
@@ -230,6 +230,64 @@
   return screen;
 } /* }}} */
 
+VALUE
+subextScreenSingDispatcher(int argc,
+  VALUE *argv,
+  VALUE self)
+{
+  VALUE missing = Qnil, args = Qnil, ret = Qnil;
+
+  VALUE list  = ScreenList();
+  VALUE first = rb_ary_entry(list, 0);
+
+  rb_scan_args(argc, argv, "1*", &missing, &args);
+
+  /* Check whether first elements knows this method */
+  if(rb_respond_to(first, rb_to_id(missing)))
+    {
+      int i, size = RARRAY_LEN(list);
+
+      printf("Element responds to '%s'; type=%d\n", SYM2CHAR(missing), rb_type(argv[1]));
+
+      switch(rb_type(argv[1]))
+        {
+          case T_ARRAY:
+
+            /* Check whether both arrays have same number of elements */
+            if(RARRAY_LEN(argv[1]) == size)
+              {
+                for(i = 0; i < size; i++)
+                  {
+                    VALUE entry = rb_ary_entry(list, i);
+                    VALUE value = rb_ary_entry(argv[1], i);
+
+                    rb_funcall(entry, rb_to_id(missing), 1, value);
+                  }
+
+                break;
+              }
+            /** Fall-through */
+
+          case T_OBJECT:
+          case T_HASH:
+            /* Just pass everything else to the method */
+            for(i = 0; i < size; i++)
+              {
+                VALUE entry = rb_ary_entry(list, i);
+
+                rb_funcall(entry, missing, 1, ++argv);
+              }
+            break;
+        }
+    }
+  else if(rb_respond_to(list, rb_to_id(missing)))
+    {
+      printf("Array responds to %s; type=%d\n", SYM2CHAR(missing), rb_type(argv[1]));
+    }
+
+  return ret;
+}
+
 /* Helper */
 
 /* subextScreenInstantiate {{{ */
--- a/src/subtlext/subtlext.c	Tue Jan 06 16:47:32 2015 +0100
+++ b/src/subtlext/subtlext.c	Thu Aug 27 09:20:10 2015 +0200
@@ -2074,9 +2074,10 @@
   rb_define_attr(screen, "geometry", 1, 0);
 
   /* Singleton methods */
-  rb_define_singleton_method(screen, "find",    subextScreenSingFind,    1);
-  rb_define_singleton_method(screen, "list",    subextScreenSingList,    0);
-  rb_define_singleton_method(screen, "current", subextScreenSingCurrent, 0);
+  rb_define_singleton_method(screen, "find",           subextScreenSingFind,        1);
+  rb_define_singleton_method(screen, "list",           subextScreenSingList,        0);
+  rb_define_singleton_method(screen, "current",        subextScreenSingCurrent,     0);
+  rb_define_singleton_method(screen, "method_missing", subextScreenSingDispatcher, -1); 
 
   /* General methods */
   rb_define_method(screen, "<=>",  SubtlextEqualSpaceId, 1);
--- a/src/subtlext/subtlext.h	Tue Jan 06 16:47:32 2015 +0100
+++ b/src/subtlext/subtlext.h	Thu Aug 27 09:20:10 2015 +0200
@@ -161,6 +161,7 @@
 VALUE subextScreenSingFind(VALUE self, VALUE id);                    ///< Find screen
 VALUE subextScreenSingList(VALUE self);                              ///< Get all screens
 VALUE subextScreenSingCurrent(VALUE self);                           ///< Get current screen
+VALUE subextScreenSingDispatcher(int argc, VALUE *argv, VALUE self); ///< Method dispatcher
 
 /* Class */
 VALUE subextScreenInstantiate(int id);                               ///< Instantiate screen