www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5033] New: Add explicit 'frame context' and 'this' type modifiers for callback functions

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5033

           Summary: Add explicit 'frame context' and 'this' type modifiers
                    for callback functions
           Product: D
           Version: D2
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: ah08010-d yahoo.com


--- Comment #0 from Austin Hastings <ah08010-d yahoo.com> 2010-10-10 12:38:48
PDT ---
When dealing with other languages, it is common to have to pass a function (not
delegate) pointer to a callback. Nearly as common is a "void*" extra parameter
that will be passed to the callback as "user data".

I think it would be very much in the spirit of D to add parameter notations so
that a void* "user data" pointer could be automatically understood to either be
a frame context or 'this'.

Given a callback scenario, there is typically some third-party library function
that accepts either a function pointer as a parameter, or expects that a
callback has been "registered" with the library:

    thirdparty_register_callback( &myfunc );
    // ...
    thirdparty_dosomething( arg1, arg2, userdata );

The library will then invoke the callback function with some set of arguments,
including the "userdata" extra argument.

    static ReturnT myfunc( T arg, void * userdata ) { ... }

In many cases, it is desirable to use nested functions or object methods for
these callbacks. The standard approach for object methods would be to create a
wrapper function that converts the userdata into an object reference, and then
hands control to a the desired method.

When the callback is a nested function, either the userdata points to exactly
one item from the enclosing scope, or an aggregate has to be created that
includes all the necessary data. 

** Object Context **

A special parameter type qualifier is used:  this. Because of the expected
usage (in callbacks),  this is an alias for 'void *'. The difference is that
the method is compiled using that parameter as the implicit 'this' pointer.

    class Node {
        string data;

        bool matchesString( immutable(char) * cstring,  this ) {

            string cstr = cstring[ 0 .. data.length ]; // NOTE: use of 'data'
            return cmp( data, cstr ) == 0;
        }
    }

    // ...
    thirdparty_register_callback( &Node.matchesString );

    thirdparty_search_something(  &some_node );

I suppose the  this parameter could have a name, which would be equivalent to
aliasing the name to this. I don't see a lot of value in that, however.

** Frame Context **

A delegate is a "fat pointer" which has two parts. The .funcptr part is the
address of the actual code of the function. The .ptr part is a pointer to some
address that gives the delegate access to the stack frame of the caller.

If a delegate's .funcptr is given as a callback address, the .ptr element can
be passed as the userdata part. A special parameter type qualifier is used:
 outer.  outer appears to be an alias for void *, as above. But it should be
understood by the compiler to be the '.ptr' member. This provides enough info
for the delegate to act like a delegate:

    void outer() {

        string data;

        bool inner( immutable(char) * cstring,  outer ) {

            string cstr = cstring[ 0 .. data.length ]; // NOTE: use of 'data'
            return cmp( data, cstr ) == 0;
        }

        thirdparty_register_callback( (&inner).funcptr );
        // ...

        thirdparty_search_something( ..., (&inner).ptr );
    }

(Frankly, the &inner.ptr could probably use some syntactic sugar, too. But it
works.)

The  outer parameter could have a name, which might be useful for calls to
other sibling functions via the thirdparty mechanism. But that seems less
likely.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 10 2010
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5033


Austin Hastings <ah08010-d yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 10 2010