# New Ticket Created by  Geoffrey Broadwell 
# Please include the string:  [perl #53802]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=53802 >


The attached patch mainly cleans up the implementation of GLUT
callbacks, simplifying code both internally and in the PIR-visible API.

It also includes two other small cleanups in the OpenGL code:
  1. a missing libglutcb build dependency that may fix a 'make -j2'
     problem on Mac OS X, as per tetragon
  2. use the 'die string' opcode rather than a manually generated
     string exception in OpenGL.pir, as per pmichaud


-'f

=== config/gen/call_list/opengl.in
==================================================================
--- config/gen/call_list/opengl.in	(revision 5082)
+++ config/gen/call_list/opengl.in	(local)
@@ -1,7 +1,7 @@
 # Used by OpenGL (including GLU and GLUT)
 v    3p
-v    PP
-v    PPi
-v    PPii
+v    JP
+v    JPi
+v    JPii
 v    fff
 v    ffff
=== config/gen/makefiles/root.in
==================================================================
--- config/gen/makefiles/root.in	(revision 5082)
+++ config/gen/makefiles/root.in	(local)
@@ -2185,7 +2185,7 @@
     @[EMAIL PROTECTED]@ $(SRC_DIR)/nci_test$(O) $(C_LIBS)
 
 # for use by runtime/parrot/library/OpenGL.pir
-$(LIBGLUTCB_SO): $(SRC_DIR)/glut_callbacks$(O)
+$(LIBGLUTCB_SO): $(LIBPARROT) $(SRC_DIR)/glut_callbacks$(O)
 	$(LD) $(LD_LOAD_FLAGS) @ncilib_link_extra@ $(LDFLAGS) \
     @[EMAIL PROTECTED]@ $(SRC_DIR)/glut_callbacks$(O) $(C_LIBS)
 
=== config/gen/opengl.pm
==================================================================
--- config/gen/opengl.pm	(revision 5082)
+++ config/gen/opengl.pm	(local)
@@ -251,8 +251,8 @@
 
    foreach (@callbacks) {
         $enums     .= "    $_->{enum},\n";
-        $thunks    .= "           void          $_->{thunk}($_->{proto});\n";
-        $reg_funcs .= "PARROT_API void          $_->{glutcb}(PMC *, PMC *);\n";
+        $thunks    .= "           void $_->{thunk}($_->{proto});\n";
+        $reg_funcs .= "PARROT_API void $_->{glutcb}(Parrot_Interp, PMC *);\n";
    }
 
     my $header = <<HEADER;
@@ -299,49 +299,36 @@
 } GLUT_CALLBACKS;
 
 typedef struct GLUT_CB_data {
-    PMC *sub;
-    PMC *interp_pmc;
+    Parrot_Interp  interp;
+    PMC            *sub;
 } GLUT_CB_data;
 
 GLUT_CB_data callback_data[GLUT_NUM_CALLBACKS];
 
 
-           Parrot_Interp verify_safe(PMC *, PMC *);
-           void          check_notnull_cb(PMC *, PMC *);
+           int  is_safe(Parrot_Interp, PMC *);
 
-           void          glut_timer_func(int);
-PARROT_API void          glutcbTimerFunc(PMC *, PMC *, unsigned int, int);
+           void glut_timer_func(int);
+PARROT_API void glutcbTimerFunc(Parrot_Interp, PMC *, unsigned int, int);
 
 #if GLUT_API_VERSION >= 4
-           void          glut_joystick_func(unsigned int, int, int, int);
-PARROT_API void          glutcbJoystickFunc(PMC *, PMC *, int);
+           void glut_joystick_func(unsigned int, int, int, int);
+PARROT_API void glutcbJoystickFunc(Parrot_Interp, PMC *, int);
 #endif
 
 $thunks
 $reg_funcs
 
-/* Never store a null interp in callback_data */
-void
-check_notnull_cb(PMC *interp_pmc, PMC *sub)
+/* Make sure that interp and sub are sane before running callback sub */
+/* XXXX: Should this do the moral equivalent of PANIC? */
+int
+is_safe(PARROT_INTERP, PMC *sub)
 {
-    if (PMC_IS_NULL(interp_pmc) || (Parrot_Interp) PMC_data(interp_pmc) == NULL)
-        PANIC((Parrot_Interp) PMC_data(interp_pmc),
-              "cannot register callback with null interpreter");
-}
-
-
-/* PANIC before running callback sub if interp or sub are insane;
-   return unwrapped Parrot_Interp if everything OK */
-Parrot_Interp
-verify_safe(PMC *interp_pmc, PMC *sub)
-{
-    Parrot_Interp interp = (Parrot_Interp) PMC_data(interp_pmc);
-
     /* XXXX: Verify that interp still exists */
 
     /* XXXX: Verify that sub exists in interp */
-
-    return PMC_IS_NULL(sub) ? NULL : interp;
+    
+    return PMC_IS_NULL(sub) ? 0 : 1;
 }
 
 
@@ -351,7 +338,7 @@
 # special timer-related arguments that do not follow the template of all
 # of the other GLUT callbacks
 
-=item C<void glutcbTimerFunc(interp_pmc, sub, milliseconds, data)>
+=item C<void glutcbTimerFunc(PARROT_INTERP, sub, milliseconds, data)>
 
 Register a Sub PMC to handle GLUT Timer callbacks.
 
@@ -362,24 +349,20 @@
 void
 glut_timer_func(int data)
 {
-    PMC *sub        = callback_data[GLUT_CB_TIMER].sub;
-    PMC *interp_pmc = callback_data[GLUT_CB_TIMER].interp_pmc;
+    Parrot_Interp interp = callback_data[GLUT_CB_TIMER].interp;
+    PMC           *sub   = callback_data[GLUT_CB_TIMER].sub;
 
-    Parrot_Interp interp = verify_safe(interp_pmc, sub);
-
-    if (interp)
+    if (is_safe(interp, sub))
         Parrot_runops_fromc_args_event(interp, sub, "vi", data);
 }
 
 PARROT_API
 void
-glutcbTimerFunc(PMC *interp_pmc, PMC *sub, unsigned int milliseconds, int data)
+glutcbTimerFunc(PARROT_INTERP, PMC *sub, unsigned int milliseconds, int data)
 {
-    check_notnull_cb(interp_pmc, sub);
+    callback_data[GLUT_CB_TIMER].interp = interp;
+    callback_data[GLUT_CB_TIMER].sub    = sub;
 
-    callback_data[GLUT_CB_TIMER].sub        = sub;
-    callback_data[GLUT_CB_TIMER].interp_pmc = interp_pmc;
-
     if (sub == PMCNULL)
         glutTimerFunc(0, NULL, 0);
     else
@@ -390,7 +373,7 @@
 #if GLUT_API_VERSION >= 4
 /*
 
-=item C<void glutcbJoystickFunc(interp_pmc, sub, pollinterval)>
+=item C<void glutcbJoystickFunc(PARROT_INTERP, sub, pollinterval)>
 
 Register a Sub PMC to handle GLUT Joystick callbacks.
 
@@ -401,31 +384,26 @@
 void
 glut_joystick_func(unsigned int buttons, int xaxis, int yaxis, int zaxis)
 {
-    PMC *sub        = callback_data[GLUT_CB_JOYSTICK].sub;
-    PMC *interp_pmc = callback_data[GLUT_CB_JOYSTICK].interp_pmc;
+    Parrot_Interp interp = callback_data[GLUT_CB_JOYSTICK].interp;
+    PMC           *sub   = callback_data[GLUT_CB_JOYSTICK].sub;
 
-    Parrot_Interp interp = verify_safe(interp_pmc, sub);
-
-    if (interp)
+    if (is_safe(interp, sub))
         Parrot_runops_fromc_args_event(interp, sub, "viiii", buttons, xaxis, yaxis, zaxis);
 }
 
 PARROT_API
 void
-glutcbJoystickFunc(PMC *interp_pmc, PMC *sub, int pollinterval)
+glutcbJoystickFunc(PARROT_INTERP, PMC *sub, int pollinterval)
 {
-    check_notnull_cb(interp_pmc, sub);
+    callback_data[GLUT_CB_JOYSTICK].interp = interp;
+    callback_data[GLUT_CB_JOYSTICK].sub    = sub;
 
-    callback_data[GLUT_CB_JOYSTICK].sub        = sub;
-    callback_data[GLUT_CB_JOYSTICK].interp_pmc = interp_pmc;
-
     if (sub == PMCNULL)
         glutJoystickFunc(NULL, 0);
     else
         glutJoystickFunc(glut_joystick_func, pollinterval);
 }
 #endif
-
 HEADER
 
 
@@ -435,7 +413,7 @@
 
 /*
 
-=item C<void $_->{glutcb}(interp_pmc, sub)>
+=item C<void $_->{glutcb}(PARROT_INTERP, sub)>
 
 Register a Sub PMC to handle GLUT $_->{friendly} callbacks.
 
@@ -446,24 +424,20 @@
 void
 $_->{thunk}($_->{params})
 {
-    PMC *sub        = callback_data[$_->{enum}].sub;
-    PMC *interp_pmc = callback_data[$_->{enum}].interp_pmc;
+    Parrot_Interp interp = callback_data[$_->{enum}].interp;
+    PMC           *sub   = callback_data[$_->{enum}].sub;
 
-    Parrot_Interp interp = verify_safe(interp_pmc, sub);
-
-    if (interp)
+    if (is_safe(interp, sub))
         Parrot_runops_fromc_args_event(interp, sub, "$_->{sig}"$_->{args});
 }
 
 PARROT_API
 void
-$_->{glutcb}(PMC *interp_pmc, PMC *sub)
+$_->{glutcb}(PARROT_INTERP, PMC *sub)
 {
-    check_notnull_cb(interp_pmc, sub);
+    callback_data[$_->{enum}].interp = interp;
+    callback_data[$_->{enum}].sub    = sub;
 
-    callback_data[$_->{enum}].sub        = sub;
-    callback_data[$_->{enum}].interp_pmc = interp_pmc;
-
     if (sub == PMCNULL)
         $_->{glut}(NULL);
     else
=== examples/opengl/triangle.pir
==================================================================
--- examples/opengl/triangle.pir	(revision 5082)
+++ examples/opengl/triangle.pir	(local)
@@ -55,15 +55,12 @@
     window = glutCreateWindow('Test')
     set_global 'glut_window', window
 
-    .local pmc interp
-    interp = getinterp
-
     .const .Sub draw     = 'draw'
     .const .Sub idle     = 'idle'
     .const .Sub keyboard = 'keyboard'
-    glutcbDisplayFunc (interp, draw)
-    glutcbIdleFunc    (interp, idle)
-    glutcbKeyboardFunc(interp, keyboard)
+    glutcbDisplayFunc (draw)
+    glutcbIdleFunc    (idle)
+    glutcbKeyboardFunc(keyboard)
 
     .local pmc rotating
     rotating = new 'Integer'
=== runtime/parrot/library/OpenGL.pir
==================================================================
--- runtime/parrot/library/OpenGL.pir	(revision 5082)
+++ runtime/parrot/library/OpenGL.pir	(local)
@@ -115,11 +115,7 @@
     message  = 'Could not find a suitable '
     message .= friendly_name
     message .= ' shared library!'
-
-    .local pmc    exception
-    exception = new 'Exception'
-    exception['_message'] = message
-    throw exception
+    die message
 .end
 
 
@@ -204,63 +200,63 @@
     .local pmc glutcb_funcs
     glutcb_funcs = new 'ResizableStringArray'
     push glutcb_funcs, 'glutcbCloseFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbDisplayFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbIdleFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbMenuDestroyFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbOverlayDisplayFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbWMCloseFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbEntryFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbMenuStateFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbVisibilityFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbWindowStatusFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbButtonBoxFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbDialsFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbMotionFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbPassiveMotionFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbReshapeFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbSpaceballButtonFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbTabletMotionFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbKeyboardFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbKeyboardUpFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbMenuStatusFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbSpaceballMotionFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbSpaceballRotateFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbSpecialFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbSpecialUpFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbMouseFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbMouseWheelFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbTabletButtonFunc'
-    push glutcb_funcs, 'vPP'
+    push glutcb_funcs, 'vJP'
     push glutcb_funcs, 'glutcbTimerFunc'
-    push glutcb_funcs, 'vPPii'
+    push glutcb_funcs, 'vJPii'
     push glutcb_funcs, 'glutcbJoystickFunc'
-    push glutcb_funcs, 'vPPi'
+    push glutcb_funcs, 'vJPi'
 
     .return (glutcb_funcs)
 .end

Reply via email to