Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 21, 2006 Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
So I have decided to roll my own GUI library, one dedicated to computer games. But I've run into a bit of an unpleasant design problem - for handling callbacks, how should my library expose function pointers and delegates? I suppose I could choose one or the other, but I think it desirable to allow use of both since I don't want to force the user of the library into a particular style or make them use ugly workarounds. I am currently thinking of a few possible solutions, none of which look very pleasing to me: #1: Force them to use delegates and work around it to do module-level programming. Example - import std.stdio; int delegate(int) increment; void main() { Dummy d = new Dummy(); increment = &d.classIncr; writefln( increment(1) ); } int incr( int a ) { return a + 1; } class Dummy { this() {} int classIncr( int a ) { return incr(a); } } #2: Provide a templated struct kind of thing that can double as a function pointer or a delegate, but is kinda clumsy to deal with. EX: import std.stdio; alias CallBack!(int function(int,Object)) IncCallBack; IncCallBack increment; void main() { increment.functionPointer = &incr; writefln( increment.functionPointer(1,null) ); } int incr( int a ) { return a + 1; } struct CallBack( fpType ) { Object object = null; fpType functionPointer; static CallBack!(fpType) opCall( fpType fp ) { CallBack!(fpType) result; result.functionPointer = fp; return result; } } #3: Expose both function pointers and delegates, with some kind of naming convention. I suppose there could be a better naming convention here, but it seems hackish as well. EX: void delegate(int,int,ubyte) mouseButtonUp_dg; void function(int,int,ubyte) mouseButtonUp_fp; Maybe I'm missing something obvious. I'd appreciate it if someone has a better solution than any of these. Otherwise I'll settle for some wise advice from those who have already been here :) |
June 21, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chad J | On Wed, 21 Jun 2006 00:40:15 -0400, Chad J wrote: > So I have decided to roll my own GUI library, one dedicated to computer games. But I've run into a bit of an unpleasant design problem - for handling callbacks, how should my library expose function pointers and delegates? > > I suppose I could choose one or the other, but I think it desirable to allow use of both since I don't want to force the user of the library into a particular style or make them use ugly workarounds. I am currently thinking of a few possible solutions, none of which look very pleasing to me: > > #1: Force them to use delegates and work around it to do module-level programming. Example - It doesn't have to be as complex as that. All you need to do to turn module-level functions into delegates is to place them inside the module's constructor or any other function for that matter, including main(). For example .. import std.stdio; int delegate(int) increment; static this() { int incr( int a ) { return a + 1; } increment = &incr; } void main() { writefln( increment(1) ); } Or if you prefer the new function literal syntax (and not use the module constructor) ... import std.stdio; int delegate(int) increment; int delegate(int) decrement; void Init_Delegates() { increment = delegate int ( int a ) { return a + 1; }; decrement = delegate int ( int a ) { return a - 1; }; } void main() { Init_Delegates(); writefln( increment(1) ); writefln( decrement(1) ); } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 21/06/2006 3:18:11 PM |
June 21, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
>
> It doesn't have to be as complex as that. All you need to do to turn
> module-level functions into delegates is to place them inside the module's
> constructor or any other function for that matter, including main(). For
> example ..
>
> import std.stdio;
> int delegate(int) increment;
> static this()
> {
> int incr( int a )
> {
> return a + 1;
> }
> increment = &incr;
> }
>
> void main()
> {
> writefln( increment(1) );
> }
>
Pretty nice, but then I can't do something like this:
import std.stdio;
int delegate(int) increment;
void main()
{
writefln( increment(1) );
writefln( incr(2) );
}
static this()
{
int incr( int a )
{
return a + 1;
}
increment = &incr;
}
I'm thinking incase someone wanted to say, have a mouse handling function be triggered by the GUI's delegate and also have it artificially triggered by some other code via a direct function call (maybe a tutorial, debug routine, or something like that).
I suppose they should just call the delegate though. I like it. Thanks.
|
June 21, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chad J | On Wed, 21 Jun 2006 02:12:54 -0400, Chad J wrote: > Pretty nice, but then I can't do something like this: ... > writefln( increment(1) ); > writefln( incr(2) ); ... > I'm thinking incase someone wanted to say, have a mouse handling function be triggered by the GUI's delegate and also have it artificially triggered by some other code via a direct function call (maybe a tutorial, debug routine, or something like that). Sure you can! How about this ... import std.stdio; int delegate(int) increment; void main() { writefln( increment(1) ); writefln( incr(2) ); } int incr( int a ) { return a + 1; } static this() { increment = delegate int ( int a ) {return incr(a); }; } Would that do? > I suppose they should just call the delegate though. I like it. Thanks. Yeah, I guess you could do that as well. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 21/06/2006 4:20:09 PM |
June 21, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
>
>>I'm thinking incase someone wanted to say, have a mouse handling function be triggered by the GUI's delegate and also have it artificially triggered by some other code via a direct function call (maybe a tutorial, debug routine, or something like that).
>
>
> Sure you can! How about this ...
>
>
> import std.stdio;
>
> int delegate(int) increment;
>
> void main()
> {
> writefln( increment(1) );
> writefln( incr(2) );
> }
>
> int incr( int a )
> {
> return a + 1;
> }
>
> static this()
> {
> increment = delegate int ( int a ) {return incr(a); };
> }
>
> Would that do?
>
Indeed. That kicks ass.
I still have to completely wrap my head around that function literal syntax. All of the sudden it is very useful to me. :)
|
June 21, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chad J | Chad J wrote: > So I have decided to roll my own GUI library, one dedicated to computer games. But I've run into a bit of an unpleasant design problem - for handling callbacks, how should my library expose function pointers and delegates? > > I suppose I could choose one or the other, but I think it desirable to allow use of both since I don't want to force the user of the library into a particular style or make them use ugly workarounds. I am currently thinking of a few possible solutions, none of which look very pleasing to me: I'd pick delegates. > #1: Force them to use delegates and work around it to do module-level programming. Example - At the moment, a function can't be cast to a delegate, but I think this will change in the future (since it's theoretically possible). In the mean time you can use the new lambda/literal syntax: int module_level_func() { return 1; } void somefunc( int delegate() callback ) { callback(); } void main() { // somefunc( &module_level_func );// not (yet) possible somefunc( { return module_level_func();} ); //wrap it } L. |
June 21, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chad J | Chad J wrote:
> So I have decided to roll my own GUI library, one dedicated to computer games. But I've run into a bit of an unpleasant design problem - for handling callbacks, how should my library expose function pointers and delegates?
>
[...]
a while back someone found out that you can take a delegate and replace the internal function pointer with a regular function pointer and it still works just fine. Given this, you could wright a little function*-to-delegate function and let people do this
UseThisCallback(int delegate(int));
int delegate(int) f2d(int function(int) fnp){...}
int fn(int);
void main()
{
UseThisCallback(f2d(&fn));
}
I known this is an *ugly* hack, OTOH maybe Walter can be convinced to add a function-pointer to delegate cast that does this in a consistent manner.
cast(int delegate(int))&fn
|
June 21, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell escribió: > On Wed, 21 Jun 2006 02:12:54 -0400, Chad J wrote: > >> Pretty nice, but then I can't do something like this: > .... > >> writefln( increment(1) ); >> writefln( incr(2) ); > > .... > >> I'm thinking incase someone wanted to say, have a mouse handling function be triggered by the GUI's delegate and also have it artificially triggered by some other code via a direct function call (maybe a tutorial, debug routine, or something like that). > > Sure you can! How about this ... > > > import std.stdio; > > int delegate(int) increment; > > void main() > { > writefln( increment(1) ); > writefln( incr(2) ); > } > > int incr( int a ) > { > return a + 1; > } > > static this() > { > increment = delegate int ( int a ) {return incr(a); }; > } > > Would that do? > I thought the frame pointer would get lost and cause a segfault later on (see DFL events handling for an example.) Did that change with 0.161? >> I suppose they should just call the delegate though. I like it. Thanks. > > Yeah, I guess you could do that as well. > -- Carlos Santander Bernal |
July 18, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander | Carlos Santander wrote: > Derek Parnell escribió: >> Sure you can! How about this ... >> >> >> import std.stdio; >> >> int delegate(int) increment; >> >> void main() >> { >> writefln( increment(1) ); >> writefln( incr(2) ); >> } >> >> int incr( int a ) >> { >> return a + 1; >> } >> >> static this() >> { >> increment = delegate int ( int a ) {return incr(a); }; >> } >> >> Would that do? >> > > I thought the frame pointer would get lost and cause a segfault later on (see DFL events handling for an example.) Did that change with 0.161? > The frame pointer becomes invalid, but that is no problem since the delegate is function-like and does not access the frame context (i.e., it's not a closure). -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
July 18, 2006 Re: Library writing - delegates or fp's? | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | BCS wrote: > Chad J wrote: > > So I have decided to roll my own GUI library, one dedicated to computer games. But I've run into a bit of an unpleasant design problem - for handling callbacks, how should my library expose function pointers and delegates? > > > [...] > > a while back someone found out that you can take a delegate and replace the internal function pointer with a regular function pointer and it still works just fine. Given this, you could wright a little function*-to-delegate function and let people do this > > > UseThisCallback(int delegate(int)); > > int delegate(int) f2d(int function(int) fnp){...} > > > int fn(int); > > void main() > { > UseThisCallback(f2d(&fn)); > } > > > I known this is an ugly hack, OTOH maybe Walter can be convinced to add a function-pointer to delegate cast that does this in a consistent manner. > > cast(int delegate(int))&fn maybe just "cast(delegate)&fn" in the spirit of inferred typing? -- |
Copyright © 1999-2021 by the D Language Foundation