www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Colors in Raylib

reply Salih Dincer <salihdb hotmail.com> writes:
Hi All,

Is there a namespace I should implement in Raylib? For example, I 
cannot compile without writing Colors at the beginning of the 
colors: ```Colors.GRAY```

SDB 79
Feb 28 2022
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Monday, 28 February 2022 at 11:48:59 UTC, Salih Dincer wrote:
 Hi All,

 Is there a namespace I should implement in Raylib? For example, 
 I cannot compile without writing Colors at the beginning of the 
 colors: ```Colors.GRAY```

 SDB 79
Assuming you mean the raylib-d binding, it implements the values as a named enum, so the `Colors` namespace is required. https://dlang.org/spec/enum.html#named_enums If you have a situation where you need to type it multiple times in consecutive code lines, you can use `with`: ```d with(Colors) { } ``` Then you can drop the namespace and just used the values. Very useful for switches: ```d with(Colors) switch(myColor) { } ``` You can also generate aliases, so that e.g., `LIGHTGRAY` is equivalent to `Colors.LIGHTGRAY`). Just throw this template function in an appropriate module: ```d enum expandEnum(EnumType, string fqnEnumType = EnumType.stringof) = (){ string expandEnum; foreach(m;__traits(allMembers, EnumType)) { expandEnum ~= "alias " ~ m ~ " = " ~ fqnEnumType ~ "." ~ m ~ ";"; } return expandEnum; }(); ``` Then you can mixin aliases for any named enum members you'd like: ```d mixin(expandEnum!Colors); ```
Feb 28 2022
next sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Monday, 28 February 2022 at 12:18:37 UTC, Mike Parker wrote:
 ```d
 enum expandEnum(EnumType, string fqnEnumType = 
 EnumType.stringof) = (){
     string expandEnum;
     foreach(m;__traits(allMembers, EnumType)) {
         expandEnum ~= "alias " ~ m ~ " = " ~ fqnEnumType ~ "." 
 ~ m ~ ";";
     }
     return expandEnum;
 }();
 ```

 Then you can mixin aliases for any named enum members you'd 
 like:

 ```d
 mixin(expandEnum!Colors);
 ```
It definitely works, thank you.
Feb 28 2022
prev sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Monday, 28 February 2022 at 12:18:37 UTC, Mike Parker wrote:
 Then you can mixin aliases for any named enum members you'd 
 like:

 ```d
 mixin(expandEnum!Colors);
 ```
Meanwhile it's very skillful :) It is possible to change all the color palette with a second parameter: ```d import std.stdio; enum Colors { BLACK, GRAY, WHITE } enum Color { WHITE, GRAY, BLACK } mixin(expandEnum!(Colors, "Color")); void main() { with(Colors) writefln("%d%d", GRAY, WHITE);// 12 writefln("%d%d", GRAY, WHITE); // 10 } ```
Mar 01 2022
prev sibling next sibling parent Guillaume Piolat <first.last gmail.com> writes:
On Monday, 28 February 2022 at 11:48:59 UTC, Salih Dincer wrote:
 Is there a namespace I should implement in Raylib? For example, 
 I cannot compile without writing Colors at the beginning of the 
 colors: ```Colors.GRAY```
When writing C bindings, you may refer to this: https://p0nce.github.io/d-idioms/#Porting-from-C-gotchas This keeps example code working.
Feb 28 2022
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 2/28/22 6:48 AM, Salih Dincer wrote:
 Hi All,
 
 Is there a namespace I should implement in Raylib? For example, I cannot 
 compile without writing Colors at the beginning of the colors: 
 ```Colors.GRAY```
 
 SDB 79
If you refer to raylib-d, that's how it was since I've ever used it. The original C code uses #defines for all the colors. It's an interesting incompatibility issue: 1. C doesn't support enums of anything but ints 2. D doesn't support #define constants I think this is the only reason the colors are not an enum in the C code in the first place. One way to fix this would be to just use individual enums to the raylib-d binding. I think it might have been this way originally. I'm hesitant to change it, but I might define both at some point. In general, the raylib enumerations are overly verbose for D, e.g. `KeyboardKey.KEY_X`, instead of just `KeyboardKey.X`. I'd love to provide "better enums". -Steve
Feb 28 2022
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 1 March 2022 at 02:42:52 UTC, Steven Schveighoffer 
wrote:
 On 2/28/22 6:48 AM, Salih Dincer wrote:
 In general, the raylib enumerations are overly verbose for D, 
 e.g. `KeyboardKey.KEY_X`, instead of just `KeyboardKey.X`. I'd 
 love to provide "better enums".
In Derelict, I exclusively used anonymous enums with an alias to the base type like Guillaume noted above. When I did bindbc-sdl, I decided to go with named enums + the template I pasted above---I put the mixin at the bottom of each enum declaration. Though I do use anonymous enums now for any that are intended to be used as bit flags. The mixin approach allows you to keep the stronger typing of named enums and still maintain one-to-one compatibility with the with the C source if both are important to you. I'm ambivalent about it now.
Feb 28 2022
parent reply meta <meta gmail.com> writes:
If the type is ``Color`` I think the compiler should allow 
``GRAY`` if it is a member of ``Color``, isn't how strong 
statically typed language should work? I wonder what is the 
rational against it? How hard would it be to allow it?
Mar 01 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/1/22 7:22 AM, meta wrote:
 If the type is ``Color`` I think the compiler should allow ``GRAY`` if 
 it is a member of ``Color``, isn't how strong statically typed language 
 should work? I wonder what is the rational against it? How hard would it 
 be to allow it?
The problem is how the original source works. The only way to define a manifest constant for a struct instance in C is to #define it. So I'm sure that if raylib could put that inside the `Color` type it would, but it can't. What a D binding should do is exactly what Mike said -- provide a complete binding as expected, and then add machine-generated nicer APIs. I actually have an open issue, in case anyone is interested in working on it: https://github.com/schveiguy/raylib-d/issues/8 -Steve
Mar 01 2022
parent reply meta <meta gmail.com> writes:
On Tuesday, 1 March 2022 at 12:29:56 UTC, Steven Schveighoffer 
wrote:
 On 3/1/22 7:22 AM, meta wrote:
 If the type is ``Color`` I think the compiler should allow 
 ``GRAY`` if it is a member of ``Color``, isn't how strong 
 statically typed language should work? I wonder what is the 
 rational against it? How hard would it be to allow it?
The problem is how the original source works. The only way to define a manifest constant for a struct instance in C is to #define it. So I'm sure that if raylib could put that inside the `Color` type it would, but it can't. What a D binding should do is exactly what Mike said -- provide a complete binding as expected, and then add machine-generated nicer APIs. I actually have an open issue, in case anyone is interested in working on it: https://github.com/schveiguy/raylib-d/issues/8 -Steve
Oh I was talking with regard to D's enum, not about the binding, allowing it via D, would make interfacing with C code easier enum Color { GRAY } void setColor(Color color); setColor(GRAY);
Mar 01 2022
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 1 March 2022 at 13:15:09 UTC, meta wrote:

     enum Color
     { GRAY }

     void setColor(Color color);

     setColor(GRAY);
Then that defeats the purpose of having named enums.
Mar 01 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 3/1/22 07:19, Mike Parker wrote:
 On Tuesday, 1 March 2022 at 13:15:09 UTC, meta wrote:

     enum Color
     { GRAY }

     void setColor(Color color);

     setColor(GRAY);
Then that defeats the purpose of having named enums.
Yes and no. meta is pointing at a difference between the above and the following: writeln(GRAY); In the latter case, the compiler has no clue whether I intended to type GRAM. But in the former case, the type is Color. What remains is whether the compiler should be looking deep into Color and have a list of values to lower GRAY to Color.GRAY. We heard this before for the switch statement: When the variable is Color, the case values can be accepted as Color as well (without the qualifier). (Yes, 'with' works as well, but the idea is the same.) It feels the same for even int because we don't write int(42) when passing an int argument: void foo(int) {} foo(int(42)); // works foo(42); // works as well So the lack of this compiler help does not bother me but still, I think the request is meaningful. Ali
Mar 01 2022
parent meta <meta gmail.com> writes:
On Tuesday, 1 March 2022 at 15:37:55 UTC, Ali Çehreli wrote:
 On 3/1/22 07:19, Mike Parker wrote:
 On Tuesday, 1 March 2022 at 13:15:09 UTC, meta wrote:

     enum Color
     { GRAY }

     void setColor(Color color);

     setColor(GRAY);
Then that defeats the purpose of having named enums.
Yes and no. meta is pointing at a difference between the above and the following: writeln(GRAY); In the latter case, the compiler has no clue whether I intended to type GRAM. But in the former case, the type is Color. What remains is whether the compiler should be looking deep into Color and have a list of values to lower GRAY to Color.GRAY. We heard this before for the switch statement: When the variable is Color, the case values can be accepted as Color as well (without the qualifier). (Yes, 'with' works as well, but the idea is the same.) It feels the same for even int because we don't write int(42) when passing an int argument: void foo(int) {} foo(int(42)); // works foo(42); // works as well So the lack of this compiler help does not bother me but still, I think the request is meaningful. Ali
Yes, that's exactly the point I was trying to make, thanks Ali!
Mar 03 2022