www.digitalmars.com         C & C++   DMDScript  

D - Announce: DUI 00.06 for dmd 0.74

reply Ant <Ant_member pathlink.com> writes:
Announce: DUI 00.06 for dmd 0.74

Another alpha version with:

- corrected GC bug
- linux support for dmd 0.74 (well, it compiles with .74 ;)
- windows package (tested for dmd 0.73, should work with dmd 0.74)

(no visible changes from DUI 00.05 but the bug correction is important,
no improvements on the windows installation process.)

DUI Home:
http://ca.geocities.com/duitoolkit/index.html

DUI linux version download page:
http://ca.geocities.com/duitoolkit/downloadPage.html

DUI windows version download page:
http://ca.geocities.com/duitoolkit/duiWindows.html

Ant
Oct 17 2003
parent reply Andy Friesen <andy ikagames.com> writes:
Why did you use listener interfaces instead of delegates?  The way SWING 
does it feels like a dirty hack around the lack of a genuine delegate 
type in Java.

Also, delegates can be declared with function literals in D, which can 
be extremely convenient for quickie callbacks.

Not to imply anything; I'm simply interested in your reasoning. :)

  -- andy

Ant wrote:
 Announce: DUI 00.06 for dmd 0.74
 
 [...]

Oct 17 2003
parent reply Ant <Ant_member pathlink.com> writes:
In article <bmqirq$31q$1 digitaldaemon.com>, Andy Friesen says...
Why did you use listener interfaces instead of delegates?  The way SWING 
does it feels like a dirty hack around the lack of a genuine delegate 
type in Java.

Also, delegates can be declared with function literals in D, which can 
be extremely convenient for quickie callbacks.

Not to imply anything; I'm simply interested in your reasoning. :)

Just spend a long time (hours) trying to answer that and the real reasons were: I like the self documenting aspect of the interface. I was familiar with the listener interfaces and I couldn't see how delegates would be better. But now I think I do. And I want to try it but I don't know how to... So, the answer has changed and now is: because I don't now how to use delegates. I want to pass the delegate to an extern(C) function, get it back on a static D function and then call the delegate. How to do that? (And that's the first problem) Ant
Oct 18 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Ant" <Ant_member pathlink.com> wrote in message
news:bmrvdf$1upd$1 digitaldaemon.com...
 In article <bmqirq$31q$1 digitaldaemon.com>, Andy Friesen says...
Why did you use listener interfaces instead of delegates?  The way SWING
does it feels like a dirty hack around the lack of a genuine delegate
type in Java.

Also, delegates can be declared with function literals in D, which can
be extremely convenient for quickie callbacks.

Not to imply anything; I'm simply interested in your reasoning. :)

Just spend a long time (hours) trying to answer that and the real reasons

 I like the self documenting aspect of the interface.
 I was familiar with the listener interfaces
 and I couldn't see how delegates would be better.

 But now I think I do.
 And I want to try it but I don't know how to...

 So, the answer has changed and now is:
 because I don't now how to use delegates.

 I want to pass the delegate to an extern(C) function,
 get it back on a static D function and then call the delegate.

 How to do that?

C doesn't have the concept of delegates, and you can't call a delegate from within C. But you can just transfer the value around. A delegate is 64 bits wide, so you can use any C 64 bit type to hold the value for transferring, such as long long.
Oct 18 2003
parent reply Ant <Ant_member pathlink.com> writes:
In article <bms3hr$23v2$2 digitaldaemon.com>, Walter says...
"Ant" <Ant_member pathlink.com> wrote in message
news:bmrvdf$1upd$1 digitaldaemon.com...
 In article <bmqirq$31q$1 digitaldaemon.com>, Andy Friesen says...
Why did you use listener interfaces instead of delegates?  The way SWING
does it feels like a dirty hack around the lack of a genuine delegate
type in Java.

Also, delegates can be declared with function literals in D, which can
be extremely convenient for quickie callbacks.

Not to imply anything; I'm simply interested in your reasoning. :)

Just spend a long time (hours) trying to answer that and the real reasons

 I like the self documenting aspect of the interface.
 I was familiar with the listener interfaces
 and I couldn't see how delegates would be better.

 But now I think I do.
 And I want to try it but I don't know how to...

 So, the answer has changed and now is:
 because I don't now how to use delegates.

 I want to pass the delegate to an extern(C) function,
 get it back on a static D function and then call the delegate.

 How to do that?

C doesn't have the concept of delegates, and you can't call a delegate from within C. But you can just transfer the value around. A delegate is 64 bits wide, so you can use any C 64 bit type to hold the value for transferring, such as long long.

I can only pass a pointer to C (it's a GTK connect function) I was trying: static void delegate() static_dlg; void addListener(GObj g, void delegate() dlg) // ok { static_dlg = dlg; the_extern_c_function(g,&callback,&dlg); // ok } static void callback(void* dlgPointer) // ??? { static_dgl(); // ok but not usefull, obviously void delegate() dlg = dlgPointer; // ??? } Any change that will work? What's the proper sintax? also I'm assuming the delegate it's stored with the object it belongs, and so it doesn't get collected, right? Ant
Oct 18 2003
next sibling parent reply Mike Hearn <mike theoretic.com> writes:
On Sat, 18 Oct 2003 21:45:42 +0000, Sir Ant scribed thus:
 I can only pass a pointer to C (it's a GTK connect function)
 I was trying:

Ant, the right way to do this is to implement a D closure marshaller. The GObject system was implemented with these issues in mind - remember before that you found that "writing language bindings for GTK" document? That explains how to implement your own signal connection logic, which will allow you to cleanly map from GTK signals to D delegates.
Oct 19 2003
parent Ant <Ant_member pathlink.com> writes:
In article <pan.2003.10.19.10.40.19.444218 theoretic.com>, Mike Hearn says...
On Sat, 18 Oct 2003 21:45:42 +0000, Sir Ant scribed thus:
 I can only pass a pointer to C (it's a GTK connect function)
 I was trying:

Ant, the right way to do this is to implement a D closure marshaller. The GObject system was implemented with these issues in mind - remember before that you found that "writing language bindings for GTK" document? That explains how to implement your own signal connection logic, which will allow you to cleanly map from GTK signals to D delegates.

Yes, I have to revisit that, I just browse it the other time. IETEFRTM (if every thing else fails read the manual:) Ant
Oct 19 2003
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
"Ant" <Ant_member pathlink.com> wrote in message
news:bmsca5$2er8$1 digitaldaemon.com...
 In article <bms3hr$23v2$2 digitaldaemon.com>, Walter says...
C doesn't have the concept of delegates, and you can't call a delegate


within C. But you can just transfer the value around. A delegate is 64


wide, so you can use any C 64 bit type to hold the value for


such as long long.

I can only pass a pointer to C (it's a GTK connect function)

So you'll need to allocate storage for a delegate, and then pass a pointer to that storage.
Oct 19 2003
parent Ant <Ant_member pathlink.com> writes:
In article <bmuh3h$23ih$1 digitaldaemon.com>, Walter says...
"Ant" <Ant_member pathlink.com> wrote in message
news:bmsca5$2er8$1 digitaldaemon.com...
 In article <bms3hr$23v2$2 digitaldaemon.com>, Walter says...
C doesn't have the concept of delegates, and you can't call a delegate


within C. But you can just transfer the value around. A delegate is 64


wide, so you can use any C 64 bit type to hold the value for


such as long long.

I can only pass a pointer to C (it's a GTK connect function)

So you'll need to allocate storage for a delegate, and then pass a pointer to that storage.

hmmm... I see, thanks. Ant
Oct 19 2003
prev sibling parent reply Andy Friesen <andy ikagames.com> writes:
The approach that Dig takes in windows is to set up an associative array 
that links HWNDs to Control instances.  All the extern(C) end has to do 
is retrieve the instance, and relay the event to the proper place.  This 
could work just as well for GtkWindow*s.

If GTK+ allows a context pointer to be stored in it (like win32's 
GWL_USERDATA) then you could store the instance pointer there instead.

extern (C) void buttonClicked(
	GtkWidget* gtkWidget, ClickEventArgs event)
{
	// getBin() maps a GtkWidget* onto a Bin instance.
	// Then cast to Button before calling the event.
	Button button = cast(Button)getBin(gtkWidget);
	assert(button !== null);

	/*
	 * onClick is a delegate, a wrapped sequence of delegates
	 * or whatever.  It's where the library user puts their
	 * callbacks.
	 */
	button.onClick(event);
}

I do have a relatively nice template class that mimics C# events.  You 
can get it at http://ikagames.com/andy/d/Listener.d if you want to use 
it. (or simply pick it for ideas)

Of course, I'm not very familiar with how GTK+ works at all, so all this 
may be useless. :)

  -- andy

Ant wrote:
 In article <bmqirq$31q$1 digitaldaemon.com>, Andy Friesen says...
 
Why did you use listener interfaces instead of delegates?  The way SWING 
does it feels like a dirty hack around the lack of a genuine delegate 
type in Java.

Also, delegates can be declared with function literals in D, which can 
be extremely convenient for quickie callbacks.

Not to imply anything; I'm simply interested in your reasoning. :)

Just spend a long time (hours) trying to answer that and the real reasons were: I like the self documenting aspect of the interface. I was familiar with the listener interfaces and I couldn't see how delegates would be better. But now I think I do. And I want to try it but I don't know how to... So, the answer has changed and now is: because I don't now how to use delegates. I want to pass the delegate to an extern(C) function, get it back on a static D function and then call the delegate. How to do that? (And that's the first problem) Ant

Oct 18 2003
parent reply Ant <Ant_member pathlink.com> writes:
In article <bmsbvm$2eic$1 digitaldaemon.com>, Andy Friesen says...
The approach that Dig takes in windows is to set up an associative array 
that links HWNDs to Control instances.

I thought of that (and I don't like it) but then I found that GTK objects have a user hash table,
extern (C) void buttonClicked(
	GtkWidget* gtkWidget, ClickEventArgs event)
{
	// getBin() maps a GtkWidget* onto a Bin instance.
	// Then cast to Button before calling the event.
	Button button = cast(Button)getBin(gtkWidget);
	assert(button !== null);

	/*
	 * onClick is a delegate, a wrapped sequence of delegates
	 * or whatever.  It's where the library user puts their
	 * callbacks.
	 */
	button.onClick(event);
}

I don't get it, actually "button.onClick" looks to me like the Button implements a listener interface. I don't think the button should know what to do with the click, just pass it to the object that knows. (unless with can have anonymouns inner classes)
	 * onClick is a delegate
	button.onClick(event);

does the delegate needs the object? if it does I'm completly lost... :((( here is how I see your Button: interface ButtonClickedListener { void onClick(Event event); } class Button : ButtonClickedListener { void onClick(Event event){/* do things */}; } so, to actually "do things" we need to subclass it, and we are back into the anonymouns, inner classes discution. Ant
Oct 18 2003
parent reply Andy Friesen <andy ikagames.com> writes:
Comments embedded.

Ant wrote:
 In article <bmsbvm$2eic$1 digitaldaemon.com>, Andy Friesen says...
 
The approach that Dig takes in windows is to set up an associative array 
that links HWNDs to Control instances.

I thought of that (and I don't like it) but then I found that GTK objects have a user hash table,

It doesn't matter, as long as you can take a GtkWidget* and get a Button instance from that without having to create a new one every time the event is fired. (since the Button object now has its own state that you need to preserve)
extern (C) void buttonClicked(
	GtkWidget* gtkWidget, ClickEventArgs event)
{
	// getBin() maps a GtkWidget* onto a Bin instance.
	// Then cast to Button before calling the event.
	Button button = cast(Button)getBin(gtkWidget);
	assert(button !== null);

	/*
	 * onClick is a delegate, a wrapped sequence of delegates
	 * or whatever.  It's where the library user puts their
	 * callbacks.
	 */
	button.onClick(event);
}

I don't get it, actually "button.onClick" looks to me like the Button implements a listener interface.

This is a theoretical rewrite of the buttonClicked method of your Dispatcher class. It relays the click event on to the button's event handler. (which is called onClick in this example) Maybe I should have written that as button.onClick.fire(event) so that it's clear that onClick isn't a member function.
 I don't think the button should know what to do with the click, 
 just pass it to the object that knows.
 (unless with can have anonymouns inner classes)

Right. It doesn't. It just passes the event on to anything that's attached itself to the onClick event.
	 * onClick is a delegate
	button.onClick(event);

does the delegate needs the object? if it does I'm completly lost... :(((

The event object? Not really, but you usually want to pass more information to the event handler. In this case, the event could hold things like the state of modifier keys (ctrl, alt, shift) and the position of the mouse. It's just for convenience.
 here is how I see your Button:
 
 interface ButtonClickedListener
 {
    void onClick(Event event);
 }
 class Button : ButtonClickedListener
 {
    void onClick(Event event){/* do things */};
 }
 
 so, to actually "do things" we need to subclass it,
 and we are back into the anonymouns, inner classes discution.
 

Right, that would suck. :) I was thinking more along the lines of: struct ButtonClickedListener { alias delegate void(ClickEventArgs) Func; // the function type this listener handles Func[] functions; // overloaded call operator. // call each stored delegate void opCall(ClickEventArgs args) { foreach (Func func; functions) func(args); } // other methods for adding, and removing delegates from the list } class Button : Bin { public ButtonClickedListener onClick; // other control things } onClick is a container, not a member function, and so does not need to be overridden polymorphically. You can just append events to onClick, and they will all be called in succession. This means that you could do something like Button exit = new Button("Exit"); exit.onPress += &this.handleExitButton; (this is nearly identical to how it's done in C#, by the way) The handleExitButton delegate would be stored within the onPress event, and later would be caled by the appropriate extern(C) method in Dispatcher.d -- andy
Oct 18 2003
next sibling parent Ant <Ant_member pathlink.com> writes:
In article <bmsg5d$2jom$1 digitaldaemon.com>, Andy Friesen says...
Comments embedded.

Ant wrote:
 In article <bmsbvm$2eic$1 digitaldaemon.com>, Andy Friesen says...
 
The approach that Dig takes in windows is to set up an associative array 
that links HWNDs to Control instances.

I thought of that (and I don't like it) but then I found that GTK objects have a user hash table,

It doesn't matter, as long as you can take a GtkWidget* and get a Button instance from that without having to create a new one every time the event is fired. (since the Button object now has its own state that you need to preserve)
extern (C) void buttonClicked(
	GtkWidget* gtkWidget, ClickEventArgs event)
{
	// getBin() maps a GtkWidget* onto a Bin instance.
	// Then cast to Button before calling the event.
	Button button = cast(Button)getBin(gtkWidget);
	assert(button !== null);

	/*
	 * onClick is a delegate, a wrapped sequence of delegates
	 * or whatever.  It's where the library user puts their
	 * callbacks.
	 */
	button.onClick(event);
}

I don't get it, actually "button.onClick" looks to me like the Button implements a listener interface.

This is a theoretical rewrite of the buttonClicked method of your Dispatcher class. It relays the click event on to the button's event handler. (which is called onClick in this example) Maybe I should have written that as button.onClick.fire(event) so that it's clear that onClick isn't a member function.
 I don't think the button should know what to do with the click, 
 just pass it to the object that knows.
 (unless with can have anonymouns inner classes)

Right. It doesn't. It just passes the event on to anything that's attached itself to the onClick event.
	 * onClick is a delegate
	button.onClick(event);

does the delegate needs the object? if it does I'm completly lost... :(((

The event object? Not really, but you usually want to pass more information to the event handler. In this case, the event could hold things like the state of modifier keys (ctrl, alt, shift) and the position of the mouse. It's just for convenience.
 here is how I see your Button:
 
 interface ButtonClickedListener
 {
    void onClick(Event event);
 }
 class Button : ButtonClickedListener
 {
    void onClick(Event event){/* do things */};
 }
 
 so, to actually "do things" we need to subclass it,
 and we are back into the anonymouns, inner classes discution.
 

Right, that would suck. :) I was thinking more along the lines of: struct ButtonClickedListener { alias delegate void(ClickEventArgs) Func; // the function type this listener handles Func[] functions; // overloaded call operator. // call each stored delegate void opCall(ClickEventArgs args) { foreach (Func func; functions) func(args); } // other methods for adding, and removing delegates from the list } class Button : Bin { public ButtonClickedListener onClick; // other control things } onClick is a container, not a member function, and so does not need to be overridden polymorphically. You can just append events to onClick, and they will all be called in succession. This means that you could do something like Button exit = new Button("Exit"); exit.onPress += &this.handleExitButton; (this is nearly identical to how it's done in C#, by the way) The handleExitButton delegate would be stored within the onPress event, and later would be caled by the appropriate extern(C) method in Dispatcher.d -- andy

I have to go out to dinner (I don't wnat to... please help me );( I'll look at this tomorow
Oct 18 2003
prev sibling parent Ant <Ant_member pathlink.com> writes:
In article <bmsg5d$2jom$1 digitaldaemon.com>, Andy Friesen says...
	 * onClick is a delegate
	button.onClick(event);

does the delegate needs the object? if it does I'm completly lost... :(((

The event object?

no, I mean the button object. I think that once we have the delegate "onClick" we don't need to have the "button." because the delegate already contains it.
Right, that would suck. :)

There is (was) a word war between microsoft and sun about that ;) http://www.javasoft.com/docs/white/delegates.html http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarvj/html/msdn_deltruth.asp who won?
 I was thinking more along the lines of:

struct ButtonClickedListener
{
    alias delegate void(ClickEventArgs) Func; // the function type this 
listener handles

    Func[] functions;

    // overloaded call operator.
    // call each stored delegate
    void opCall(ClickEventArgs args) {
       foreach (Func func; functions)
          func(args);
    }

    // other methods for adding, and removing delegates from the list
}

class Button : Bin
{
    public ButtonClickedListener onClick;

    // other control things
}

onClick is a container, not a member function, and so does not need to 
be overridden polymorphically.  You can just append events to onClick, 
and they will all be called in succession.  This means that you could do 
something like

Button exit = new Button("Exit");
exit.onPress += &this.handleExitButton;

(this is nearly identical to how it's done in C#, by the way)

this is nearly identical to how it's done in java, by the way :) i.e. We have a holding place for all the observers, we have process to add observers, each event is fired to every observer. The difference between delegates and inteface listener is starting dissipating on my mind again... The main difference I'm seeing, and that made rethink how DUI does it, is that with interface listeners (and no anonymouns inner classes) when an object listens to the same even from more then one publischer it has to do the job of identifying the publisher... on DUI I added an user action identifier to each event so tipically we have: switch(action) { case "exit": exit(); break; case "openFile": openFile(); break; } witch I wouldn't mind to getting rid of... wouldn't you ... That means that nothing needs to be changed on DUI except passing a delegate to the dispatcher instead of a listener implementation. The dispatcher still has to translate the messages between DUI and GTK. (maybe the Dispatcher functions could be spread throud the hierarchy of objects(?)) So i think the way I asked Walter is how it should be donne. I'll have to look the best place to store the delegate.
The handleExitButton delegate would be stored within the onPress event, 
and later would be caled by the appropriate extern(C) method in Dispatcher.d

Maybe there (store the delegate) but we corrently don't have it on DUI. Ant
Oct 19 2003