-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Functions added to Rectangle
, and less verbose enums
#50
base: master
Are you sure you want to change the base?
Conversation
…ed a port of an official Raylib C example.
Hi Liam, thanks for the PR. I'm not ignoring you, I just haven't had any time to look at this kind of stuff. I promise I will take a look at some point... |
rayguiexample/source/app.d
Outdated
@@ -103,7 +103,7 @@ int main() { | |||
//---------------------------------------------------------------------------------- | |||
|
|||
// Custom GUI font loading | |||
//Font font = LoadFontEx("fonts/rainyhearts16.ttf", 12, 0, 0); | |||
//Font font = LoadFontEx("fonts/rainyhearts16.ttf".toStringz, 12, 0, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
D string literals are compatible with C strings. This line works as-is in D.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have found that sometimes it works, and sometimes it doesn't. As an experiment, I just tried removing all the .toStringz
uses in my code, and the only errors were for the functions MeasureTextEx
and DrawTextEx
. Having experienced this error before, I had added this use of toStringz
for peace of mind, thinking that it might just suddenly stop working one day without it.
Do you know why using a D string works for some Raylib functions but not for others?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just figured it out. It works without toStringz
when the string is known at compile-time, but fails when a variable is used. I will now keep this in mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, any string literals are implicitly convertible to const char *
and will have proper zero termination. That is a part of the D language specification: https://dlang.org/spec/expression.html#string_literals
So please remove this change.
@schveiguy While the features added in this fork are so far rather small, I plan to make some more commits soon. If you don't merge it very soon, the number of changes are likely to pile up, and there will be more for you to review. Do you need me to put the new changes on another branch with a separate pull request? If you don't have time to review merge requests, perhaps you should add repo permission for an experienced D programmer who you trust with this. |
I have some updates to share on what I have worked on. I haven't committed everything that I have tried, as I didn't want to make any commits that cause Raylib-D to to stop functioning, so much of it has remained on my own computer. However, you can see look in the The new thing I intended to add are overloads of existing Raylib functions which take D strings instead of C strings as arguments. A difficulty with this was that D string literals are already accepted by the existing C functions. This meant that when the functions were called using a string literal, the compiler would complain that the call matches both versions of the function. The solution I found was to change Most of the function overloads I added are generated using a CTFE function, which uses string concatenation to generate the new functions. The RayGUI example currently has I just became aware of the After all this trouble, I decided to make an attempt to simply port some Raylib functions into D. This is in the |
Stopped using the CTFE function to generate the enum.
So sorry for being late on this. I'll take a look tonight to see what you have done here. I know not having feedback is frustrating.
This was requested by a user on the discord. Given that raylib-d is a simple wrapper around a C library, it makes sense that betterC is achievable (and it was with a couple of insignificant changes). If there are things that you are using that are not betterC compatible, you can add them with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I like a lot of the stuff here. The enum changes are not exactly what I was looking for, and I think you should split this into a separate PR which we can discuss separately. The Rectangle functions are awesome, and I have wanted them many many times.
The enum changes might work this way, but you need to make it very simple to generate new bindings, which I don't think this does. Keep in mind, all the binding files that come from raylib are automatically generated using the instructions in generating.md
. If you make any changes to these files by hand, those changes need to be outlined in that document, and "replace all cases of KEY_A with A" is not a good instruction -- I spend about 1-2 hours on generating the bindings when a release occurs, and I depend on the simplicity of the instructions for making sure everything is properly done. I simply don't have the cycles to test that every translation is correct, or hand-adjust all the enums in the file.
What I was looking for when I wrote #8 is something that provides an alternative to the existing enums (imported separately), not replacing the enums in the original file. In other words, the generated enum should be the "better" one.
rayguiexample/source/app.d
Outdated
@@ -103,7 +103,7 @@ int main() { | |||
//---------------------------------------------------------------------------------- | |||
|
|||
// Custom GUI font loading | |||
//Font font = LoadFontEx("fonts/rainyhearts16.ttf", 12, 0, 0); | |||
//Font font = LoadFontEx("fonts/rainyhearts16.ttf".toStringz, 12, 0, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, any string literals are implicitly convertible to const char *
and will have proper zero termination. That is a part of the D language specification: https://dlang.org/spec/expression.html#string_literals
So please remove this change.
result.y -= offset.y; | ||
} | ||
return result; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooh, I like all these! Very Nice.
"license": "Zlib", | ||
"name": "example" | ||
"name": "example", | ||
"mainSourceFile": "source/app.d" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary.
There is one trick to make a function CTFE only -- assign the result of an immediately-called lambda to an enum: string notGoodForBetterC()(string x, string y) {
string result;
result ~= x;
result ~= ", ";
result ~= y;
return result;
}
enum thisDoesntWork = notGoodForBetterC("hello" , "world!");
enum thisDoesWork = (string x, string y) {
string result;
result ~= x;
result ~= ", ";
result ~= y;
return result;
}("hello", "world"); |
Applied most of the suggested changes, but excluded one which appears to be wrong. Co-authored-by: Steven Schveighoffer <[email protected]>
Right. I understood that, but giving them the same name is my preference. My reasoning for putting the better enums directly in the file, and generating the old ones is to encourage use of the better ones, since they can easily be seen by someone reading the file. I found D's restrictions on enum definitions to be a huge pain. It would be so great if additional members of the same enum could be defined in different places, but it's not allowed. Further, mixins can't be placed in enum definitions. This makes things hard. |
Added `Rectangle.centre` function. Deprecated some symbols which are deprecated in mainline Raylib.
I've been thinking of turning raygui into a subpackage, so that both 3.5 and 4.0 will later be available in separate configurations. |
Do you think it's likely that existing enums will change? If not, perhaps all the enums can be placed in a separate file, and the instructions can be to remove them from |
Yes |
Well, that's just the old "menu" button on Android, which modern Android doesn't even use. But I may have a solution that can work even if enum values change. Perhaps we can have a dedicated script to write the enum definitions based on the current Raylib version. I don't know if CtoD can be configured for specialized purposes like this, but I think the easier solution would be to use I can probably write a script on my own that can write automatically generate such enums automatically, with and without the prefixes. The one thing that may be beyond my skill level is if I want it to maintain any alternative names for enum members that were added manually. |
It's just an example. The thing is, raylib changes stuff all the time, adding enum values, removing them, changing them, etc.
Something that is automated is OK, but I am very wary of a fragile tool that needs updating when things break. I'm still confused why we can't just generate the new enums instead of editing the file? They will still be visible to the user. Something like: /// map a new enum `Key` such that `KeyboardKey.KEY_A` => `Key.A`
mixin(GenerateBetterEnum!(KeyboardKey, "Key", "KEY_")); |
Well, I originally wrote that function thinking of just that. But now I think we would be better off using the names of the existing enums. Unfortunately, D requires all enums to be defined in only one place, so we can't do |
Check out this new updater program I wrote and placed in a new branch. Right now it just generates the enums and places them in a separate module, but this approach can potentially be used to generate the rest of the bindings. I'll wait for your feedback before editing |
I am OK adding anything that is not a direct translation of C code in a separate module, as long as the binding modules are generated, and look similar to the existing system. We can't remove existing symbols (unless raylib removes them). We can't change the meaning of them. At its heart, this is a binding with some D niceties added onto it. It should be usable as a binding first. Someone who has code that says import raylib;
KeyboardKey k = KeyboardKey.KEY_A; it should continue to compile. If you can produce a tool that is effective at generating these separate modules, then I'm fine adding it, as long as the core binding isn't affected. raylib-d can grow new features and niceties, but it must retain the existing features and API. But I'd recommend at this point, separating out these ideas into a separate PR, and we can add the Rectangle methods now. |
I would do this, but I don't know how, aside from putting a commit to revert all files except |
So I also am not an expert on git. My usual solution is to just to create new branch and copy in the changes I want. One thing that is unfortunate is that you have made these changes on your master branch. You should always checkout a new branch when proposing changes to an upstream repository. This is my recommendation: # save the original file you want to keep
cp source/raylib/raylib_types.d x.d
# create a branch so this doesn't get lost
git checkout -b savemystuff
# make sure it gets onto github
git push origin savemystuff
# delete your local master branch
git branch -d master
# make sure the upstream remote is present (optional, if you haven't done it yet)
git remote add upstream https://github.com/schveiguy/raylib-d.git
# checkout the upstream master
git checkout upstream/master
# overwrite your master branch on github.
git push origin master --force
# checkout a branch to target with this PR
git checkout -b updaterect
# copy the code you kept
cp x.d source/raylib/raylib_types.d
# commit and push this branch (edit commit message)
git commit -a
# push to your github
git push origin updaterect and now, you can go onto github and change the source branch to this new branch (instead of master) |
Are you against putting anything that's not strictly a binding to a raylib symbol inside Unfortunately, this would really limit us, as D requires that enums are defined in only one place, and all overloads of a function are defined in the same module. I think it would be optimal to have less verbose names for enum members while still giving the enum itself the same name. I also think it would be very helpful to have overloads of Raylib functions using the same names. Perhaps the updater script can be designed in such a way as to leave in anything extra that's added to This can be made to work either in sections, where certain sections of A third option is we split I haven't managed to get comfortable with any of the D parsing libraries, so I would probably just write my own logic in the script to determine what's to be removed and what shouldn't on update, which of course may make it somewhat sensitive to formatting.
I very much agree with this. Perhaps I should write a unittest to make sure all symbols are there, so that we know if the updater script removes anything. Maybe there can even be a test program with visual results to test if it's doing what it should. I can also go over the Raylib-D examples repository to test all the examples.
Alright. Would you rather |
Yes. But I'm not against package.d importing non-binding files (see for example https://github.com/schveiguy/raylib-d/blob/master/source/raylib/package.d#L87). But a module should be the exact translation of What I don't want is to have to run the binding generator and then have to also write complex code in the same file. D has modules, we should use them.
I am not clear on the issue here. What are you trying to do with enums? Overloads of functions can cross module boundaries. In response to your other points, I think we already have package.d split into other modules. package.d imports everything, and you can add more modules to that list if you want. In terms of rewriting raylib functions in D, I am not interested for this project. That is my other project, draylib. Overloading to allow for proper strings is fine, but should be in a separate module, like The goals here are: a simple binding, with basic niceties added on. I'm not looking for a raylib-cpp style API reimagining. At least for this project. For draylib, yes, I want to make everything D-friendly. |
Alright then. I'll try to put new things in other modules. The latest commit I did in my What do you think of the idea of adding default arguments to functions (such as setting the default colour to
Yay! I suppose that means they should just be deleted from |
Fixed two `dub.json` files.
Labelled some original comments in `source/raygui.d` as "D Note" so we know they weren't copied from upstream RayGUI.
`enumAlias` template replaces `enumMixin` CTFE function in `raygui` module. Fixed the newest RayGUI icons, which were previously blank.
Added more functions to `Rectangle`.
Added "raylib" lib requirement to `dub.json`.
Set `raylib_types` modules to `@safe`, and added more rectangle functions.
Resolves #8
I experimented with using CTFE to generate new versions of the enums. Realizing that I can't add aliases to existing enum members this way, I ended up just directly writing shorter identifiers in
package.d
alongside the existing overly-verbose ones. I left the CTFE function in there just in case you want to see.I also added functions to
Rectangle
for convenience. These are to get the corners of the rectangle as aVector2
. There are also operator overloads for offsetting a rectangle by a Vector2.Originally, I was going to include some D ports of the official Raylib examples, before seeing the existing repository for these examples. Perhaps we should consider merging them into here, with a format that can be found in previous commits on my repository in the
examples
directory.If I can figure out a way to generate them, I may later make a commit to add overloads of some functions. (#48)