January 23, 2012
On 01/23/12 05:14, Artur Skawina wrote:
> On 01/23/12 03:17, bearophile wrote:
>> This line of code seems an example for people that like named arguments in D:
>> gtk.init(null,null);
> 
> This has nothing to do with named arguments, it's gtk wanting to parse and modify the C argv[], which i didn't want to rebuild in these examples. /* void gtk_init(/*inout*/ int* argc, /*inout*/ char*** argv=null);*/
> 
> A function which handles the argv conversion both ways would be a good idea. On the list. Thanks.

Done.

--- a/example_gtk2.d
+++ b/example_gtk2.d

 int main(string argv[]) {
-   gtk.init(null,null);
+   argv = gtk.init(argv);

Not only looks much better, now you can set the programs class and name/resource, turn off/on the GTK builtin debugging etc.

And even some camelCase got in. :) (for the D-specific additions, not
the 1:1 mapped GTK API)

artur
January 23, 2012
>> The convention for D classes/structs/enums is CamelCase, while functions and methods are the same but start with a lowercase.
>
> There is no such thing as a language mandated identifier naming convention.

It's not mandated, it's standard. http://www.d-programming-language.org/dstyle.html


> A function which handles the argv conversion both ways would be a good
> idea. On the list. Thanks.

I think there was a thread recently which described a way to get ahold of argv.
January 23, 2012
Artur Skawina:

> There is no such thing as a language mandated identifier naming convention. If you think otherwise - make the compiler enforce it. :)

There is a D style guide.


> > This line of code seems an example for people that like named arguments in D:
> > gtk.init(null,null);
> 
> This has nothing to do with named arguments,

It's an example of code where named arguments are useful for the person that reads the code to know what those two arguments are :-)


> Requiring explicit casts for most strings is ugly, but not something that can be fixed both safely and cheaply. For a GUI toolkit the amount of casts needed may be acceptable. [1]

But a string is like a 2-tuple, it's not a pointer. It's not meant to allow a cast to pointer. So it's better to cast the ".ptr" of an array:
cast(char*)"Hello World!".ptr

Bye,
bearophile
January 24, 2012
On 01/24/2012 12:18 AM, bearophile wrote:
> Artur Skawina:
>
>> There is no such thing as a language mandated identifier naming convention.
>> If you think otherwise - make the compiler enforce it. :)
>
> There is a D style guide.
>
>
>>> This line of code seems an example for people that like named arguments in D:
>>> gtk.init(null,null);
>>
>> This has nothing to do with named arguments,
>
> It's an example of code where named arguments are useful for the person that reads the code to know what those two arguments are :-)
>
>
>> Requiring explicit casts for most strings is ugly, but not something
>> that can be fixed both safely and cheaply. For a GUI toolkit the
>> amount of casts needed may be acceptable. [1]
>
> But a string is like a 2-tuple, it's not a pointer. It's not meant to allow a cast to pointer.
> So it's better to cast the ".ptr" of an array:
> cast(char*)"Hello World!".ptr
>
> Bye,
> bearophile

This is wrong. String literals are meant to allow a cast to a pointer. String literals *implicitly* convert to immutable(char)*. They are designed to simultaneously be D style strings and C style strings. There is really no need for that .ptr there. It is just noise.
January 24, 2012
On Sunday, 22 January 2012 at 21:56:24 UTC, Artur Skawina wrote:
>
>
>                  Native GTK2 bindings for D.
>
>
> "Native" for two reasons:
>
> 1. Uses the C API directly. No class wrappers and no function wrappers.
> 2. OO interface, giving a native D look and feel.

Once again. Is it direct C bindings OR OO interface OR both?
January 24, 2012
On 01/24/12 12:15, Kagamin wrote:
> On Sunday, 22 January 2012 at 21:56:24 UTC, Artur Skawina wrote:
>>
>>
>>                  Native GTK2 bindings for D.
>>
>>
>> "Native" for two reasons:
>>
>> 1. Uses the C API directly. No class wrappers and no function wrappers. 2. OO interface, giving a native D look and feel.
> 
> Once again. Is it direct C bindings OR OO interface OR both?

Both.

There are basically three parts:

1) data type definitions - ie structs, aliases (typedefs), and enums (constants)
2) C prototypes; this, plus (1) above, let's you use the C API directly
3) "methods", which are actually disguised GTK functions.

An example:

struct Rectangle {
   int x, y, width, height;

   // Calculates the intersection of two rectangles. It is allowed for
   // do not intersect, @dest's width and height is set to 0 and its x
   // and y values are undefined. If you are only interested in whether
   // the rectangles intersect, but not in the intersecting area itself,
   // pass %NULL for @dest.
   // RETURNS: %TRUE if the rectangles intersect.
   // <src2>: a #GdkRectangle
   // <dest>: return location for the intersection of @src1 and @src2, or %NULL
   int intersect(Rectangle* src2, /*out*/ Rectangle* dest=null) {
      return gdk_rectangle_intersect(&this, src2, dest);
   }

   // Calculates the union of two rectangles.
   // The union of rectangles @src1 and @src2 is the smallest rectangle which
   // includes both @src1 and @src2 within it.
   // It is allowed for @dest to be the same as either @src1 or @src2.
   // <src2>: a #GdkRectangle
   // <dest>: return location for the union of @src1 and @src2
   void union_(Rectangle* src2, /*out*/ Rectangle* dest) {
      gdk_rectangle_union(&this, src2, dest);
   }
}

So instead of:

> gdk_rectangle_union(&dirtyRect, &event.area, &dirtyRect);

you can write:

> dirtyRect.union_(&event.area, &dirtyRect);

and, once i add the (forgotten) overload:

> dirtyRect.union_(&event.area);

and all of these will result in identical code being emitted.


All of the gtk2/*.d files are browsable online: http://repo.or.cz/w/girtod.git/tree/refs/heads/gtk2:/gtk2


And, yes, this is probably suitable for Deimos, iff part #3 is. (I see no advantage in splitting out the trivial "methods")

artur
January 24, 2012
On 2012-01-24 17:09, Artur Skawina wrote:
> On 01/24/12 12:15, Kagamin wrote:
>> On Sunday, 22 January 2012 at 21:56:24 UTC, Artur Skawina wrote:
>>>
>>>
>>>                   Native GTK2 bindings for D.
>>>
>>>
>>> "Native" for two reasons:
>>>
>>> 1. Uses the C API directly. No class wrappers and no function wrappers.
>>> 2. OO interface, giving a native D look and feel.
>>
>> Once again. Is it direct C bindings OR OO interface OR both?
>
> Both.
>
> There are basically three parts:
>
> 1) data type definitions - ie structs, aliases (typedefs), and enums (constants)
> 2) C prototypes; this, plus (1) above, let's you use the C API directly
> 3) "methods", which are actually disguised GTK functions.
>
> An example:
>
> struct Rectangle {
>     int x, y, width, height;
>
>     // Calculates the intersection of two rectangles. It is allowed for
>     // do not intersect, @dest's width and height is set to 0 and its x
>     // and y values are undefined. If you are only interested in whether
>     // the rectangles intersect, but not in the intersecting area itself,
>     // pass %NULL for @dest.
>     // RETURNS: %TRUE if the rectangles intersect.
>     //<src2>: a #GdkRectangle
>     //<dest>: return location for the intersection of @src1 and @src2, or %NULL
>     int intersect(Rectangle* src2, /*out*/ Rectangle* dest=null) {
>        return gdk_rectangle_intersect(&this, src2, dest);
>     }
>
>     // Calculates the union of two rectangles.
>     // The union of rectangles @src1 and @src2 is the smallest rectangle which
>     // includes both @src1 and @src2 within it.
>     // It is allowed for @dest to be the same as either @src1 or @src2.
>     //<src2>: a #GdkRectangle
>     //<dest>: return location for the union of @src1 and @src2
>     void union_(Rectangle* src2, /*out*/ Rectangle* dest) {
>        gdk_rectangle_union(&this, src2, dest);
>     }
> }
>
> So instead of:
>
>> gdk_rectangle_union(&dirtyRect,&event.area,&dirtyRect);
>
> you can write:
>
>> dirtyRect.union_(&event.area,&dirtyRect);
>
> and, once i add the (forgotten) overload:
>
>> dirtyRect.union_(&event.area);
>
> and all of these will result in identical code being emitted.
>
>
> All of the gtk2/*.d files are browsable online:
> http://repo.or.cz/w/girtod.git/tree/refs/heads/gtk2:/gtk2
>
>
> And, yes, this is probably suitable for Deimos, iff part #3 is.
> (I see no advantage in splitting out the trivial "methods")
>
> artur

So what's the difference compared to gtkD:

http://dsource.org/projects/gtkd

-- 
/Jacob Carlborg
January 24, 2012
On Tue, 24 Jan 2012 21:03:22 +0100
Jacob Carlborg <doob@me.com> wrote:

> So what's the difference compared to gtkD:

I believe it was already mentioned: NIH syndrome. ;)


Sincerely,
Gour


-- 
Those persons who execute their duties according to My injunctions and who follow this teaching faithfully, without envy, become free from the bondage of fruitive actions.

http://atmarama.net | Hlapicina (Croatia) | GPG: 52B5C810


January 24, 2012
On 01/24/12 21:03, Jacob Carlborg wrote:
> On 2012-01-24 17:09, Artur Skawina wrote:
>> On 01/24/12 12:15, Kagamin wrote:
>>> On Sunday, 22 January 2012 at 21:56:24 UTC, Artur Skawina wrote:
>>>>
>>>>
>>>>                   Native GTK2 bindings for D.
>>>>
>>>>
>>>> "Native" for two reasons:
>>>>
>>>> 1. Uses the C API directly. No class wrappers and no function wrappers. 2. OO interface, giving a native D look and feel.
>>>
>>> Once again. Is it direct C bindings OR OO interface OR both?
>>
>> Both.
>>
>> There are basically three parts:
>>
>> 1) data type definitions - ie structs, aliases (typedefs), and enums (constants)
>> 2) C prototypes; this, plus (1) above, let's you use the C API directly
>> 3) "methods", which are actually disguised GTK functions.
>>
>> An example:
>>
>> struct Rectangle {
>>     int x, y, width, height;
>>
>>     // Calculates the intersection of two rectangles. It is allowed for
>>     // do not intersect, @dest's width and height is set to 0 and its x
>>     // and y values are undefined. If you are only interested in whether
>>     // the rectangles intersect, but not in the intersecting area itself,
>>     // pass %NULL for @dest.
>>     // RETURNS: %TRUE if the rectangles intersect.
>>     //<src2>: a #GdkRectangle
>>     //<dest>: return location for the intersection of @src1 and @src2, or %NULL
>>     int intersect(Rectangle* src2, /*out*/ Rectangle* dest=null) {
>>        return gdk_rectangle_intersect(&this, src2, dest);
>>     }
>>
>>     // Calculates the union of two rectangles.
>>     // The union of rectangles @src1 and @src2 is the smallest rectangle which
>>     // includes both @src1 and @src2 within it.
>>     // It is allowed for @dest to be the same as either @src1 or @src2.
>>     //<src2>: a #GdkRectangle
>>     //<dest>: return location for the union of @src1 and @src2
>>     void union_(Rectangle* src2, /*out*/ Rectangle* dest) {
>>        gdk_rectangle_union(&this, src2, dest);
>>     }
>> }
>>
>> So instead of:
>>
>>> gdk_rectangle_union(&dirtyRect,&event.area,&dirtyRect);
>>
>> you can write:
>>
>>> dirtyRect.union_(&event.area,&dirtyRect);
>>
>> and, once i add the (forgotten) overload:
>>
>>> dirtyRect.union_(&event.area);
>>
>> and all of these will result in identical code being emitted.
>>
>>
>> All of the gtk2/*.d files are browsable online: http://repo.or.cz/w/girtod.git/tree/refs/heads/gtk2:/gtk2
>>
>>
>> And, yes, this is probably suitable for Deimos, iff part #3 is. (I see no advantage in splitting out the trivial "methods")
>>
>> artur
> 
> So what's the difference compared to gtkD:

The simple struct above maps to this *module* in gtkD:

(i've stripped some comments and whitespace)
-------------------------------------------------------
module gdk.Rectangle;

public  import gtkc.gdktypes;

private import gtkc.gdk;
private import glib.ConstructionException;

public class Rectangle
{
	/** the main Gtk struct */
	protected GdkRectangle* gdkRectangle;

	public GdkRectangle* getRectangleStruct()
	{
		return gdkRectangle;
	}

	/** the main Gtk struct as a void* */
	protected void* getStruct()
	{
		return cast(void*)gdkRectangle;
	}

	/**
	 * Sets our main struct and passes it to the parent class
	 */
	public this (GdkRectangle* gdkRectangle)
	{
		if(gdkRectangle is null)
		{
			this = null;
			return;
		}
		this.gdkRectangle = gdkRectangle;
	}

	/**
	 * Calculates the intersection of two rectangles. It is allowed for
	 * dest to be the same as either src1 or src2. If the rectangles
	 * do not intersect, dest's width and height is set to 0 and its x
	 * and y values are undefined. If you are only interested in whether
	 * the rectangles intersect, but not in the intersecting area itself,
	 * pass NULL for dest.
	 * Params:
	 * src2 = a GdkRectangle
	 * dest = return location for the
	 * intersection of src1 and src2, or NULL. [out caller-allocates][allow-none caller-allocates]
	 * Returns: TRUE if the rectangles intersect.
	 */
	public int intersect(Rectangle src2, Rectangle dest)
	{
		return gdk_rectangle_intersect(gdkRectangle, (src2 is null) ? null : src2.getRectangleStruct(), (dest is null) ? null : dest.getRectangleStruct());
	}

	/**
	 * Calculates the union of two rectangles.
	 * The union of rectangles src1 and src2 is the smallest rectangle which
	 * includes both src1 and src2 within it.
	 * It is allowed for dest to be the same as either src1 or src2.
	 * Params:
	 * src2 = a GdkRectangle
	 * dest = return location for the union of src1 and src2
	 */
	public void unio(Rectangle src2, Rectangle dest)
	{
		gdk_rectangle_union(gdkRectangle, (src2 is null) ? null : src2.getRectangleStruct(), (dest is null) ? null : dest.getRectangleStruct());
	}
}
-------------------------------------------------------------

Now, imagine how eg simple exposure compression code looks like, using both approaches... Where you have one Rectangle storing the area that needs to be repainted, and receive several events, all of them with another embedded Rectangle struct containing newly damaged regions.. Hint: the gtkD approach gives you no way to directly use the gdkRectangle structs passed - you need to allocate a new class instance for every single one of them.

Using my bindings, that same code is just:

> dirtyRect.union_(&event.area);

And this is just a simple example.


gtkD also does some other silly things, like adds another level of indirection, by not linking against the GTK libs, but manually trying to load them, dlopen-style. Failing and/or scaring the user at runtime if it finds a version it didn't expect.

There are probably more issues, but i didn't look at gtkD closely, after being bitten by the latter and realizing the former.

D makes it possible to map most of the API 1:1 completely for free, why would anyone want to use a middle layer that adds almost no value, but a significant cost? (think GC; the code overhead wouldn't really be noticeable in most cases, yes)

artur
January 28, 2012
On Tuesday, 24 January 2012 at 16:09:21 UTC, Artur Skawina wrote:
> So instead of:
>
>> gdk_rectangle_union(&dirtyRect, &event.area, &dirtyRect);
>
> you can write:
>
>> dirtyRect.union_(&event.area, &dirtyRect);

For some reason
gdk_rectangle_union(&dirtyRect, &event.area, &dirtyRect);
looks better.

> and all of these will result in identical code being emitted.

what if
struct Rectangle
{
 GdkRectangle r;
 alias r this;
... methods ...
}

Will a different code be emitted?
Will alias this work with C api?

> And, yes, this is probably suitable for Deimos, iff part #3 is.
> (I see no advantage in splitting out the trivial "methods")

C bindings are a value on their own, this is probably why deimos doesn't like #3: your methods will be a burden to other users(libraries) of the bindings.