Well, a char * could mean many things, but in the vast majority of the cases, it points to a null-terminated string, so SWIG takes liberty in assuming it as such. Besides a char * is all you need to properly access a null-terminated string. For a char ** though, is it a null-terminated list of null-terminated strings? Is it the address of a pointer to a single null-terminated string? Or is it what it is in this case? So, SWIG doesn't attempt anything fancy when it sees a char ** by default. You can make it wrap a char ** however you wish with some SWIG-fu(you can define typemaps which tell how to map types), but in this case, i didn't think it was worth it for a single function.
To me, the only valid assumption would be a pointer to a null-terminated string. Which works fine in any of the actual cases.
The potential extra entries in an array, if any, would be the responsibility of the programmer.
If it were declared as a char*[n], that would be different, of course.
So as long as it's assuming null-terminated string by default for char*, it should also assume pointer to null-terminated string by default for a char**, not saying that those can't be overridden by the programmer, but at least it'd be consistent, me think.
As for the "reserve", I agree, it's such an easy and harmless optimization that there's no excuse not to do it here, aside from that, this code is going to talk to Python , besides, we're constructing an extra vector<string> in the first place, and I don't think it's at all possible to avoid that, since most of the target languages keep their strings as unicode, and worse, they're not even null-terminated.
I guess it depends on which kind of unicode encoding they're using. If it's Go, for example, it'd be UTF-8, which is also what orx is using internally. I do not know what other languages use.
You could avoid the internal heap allocation altogether by using a stack-allocation for storing the pointers before sending the list to orx.
In general, I really ignore most performance considerations while writing language bindings, since the activity is excessively wasteful to begin with.
It's probably the best option, yes, but who knows, sometimes a "death by thousand paper cuts" can be alleviated a bit. In this case though, I agree it doesn't really matter. However the heap allocation could have been worth removing were this function used more often.
Well, I'm probably not as comfortable with the orx codebase as you are, so whenever I see a platform-specific #define I'm afraid that it'll cause SWIG to emit different wrappers on each platform. Besides, I'd prefer to have complete control over how SWIG wraps, say, orxFLOAT, so that the wrappers work correctly and similarly on each platform.
I understand and it's totally fine with me to do a cherry-picking approach, I was just trying to learn more about SWIG and its limitations, it's really a brand new world to me.
I see, I guess Windows.i would be essential in a codebase that has declspecs and such all around the codebase, but thanks to your consistent use of macros, we should be able to avoid that problem without it. As I said, I'd prefer to stay away from anything that implies a platform dependency, so a "#define orxFASTCALL // empty" feels much more innocent since we know it'll work the same way on all platforms.
Sounds good to me!
Ah, case in point, if those are private functions, what's the officially recommended way of using the config module in isolation? I've discovered that you need to call the following first:
The exhaustive sequence can be found in tools/orxCrypt/src/orxCrypt.c. In this case, I'd recommend not using the embedded version as you won't need any of the plugins, like display, for example. This way the library remains pretty light and should initialize very quickly as well.
I definitely agree, I hate it when I unnecessarily complicate things . As Einstein said “A clever person solves a problem. A wise person avoids it.”(Conclusion: I'm definitely not wise). We could even manually upload the cross-platform binding packages for chosen releases, no need to complicate the build setup.
Excellent, let's start with this approach then. We can always iterate and improve it over time, of course.
I guess it depends on which kind of unicode encoding they're using. If it's Go, for example, it'd be UTF-8, which is also what orx is using internally. I do not know what other languages use.
You could avoid the internal heap allocation altogether by using a stack-allocation for storing the pointers before sending the list to orx.
You're right, that would be a worthy optimisation indeed, especially for relatively fast target languages such as Java or Go. Probably not worth it for Python though. Maybe, in time, we could specialise the wrappers for those functions for languages that need it.
"death by thousand paper cuts"
I fell in love with that phrase
I understand and it's totally fine with me to do a cherry-picking approach, I was just trying to learn more about SWIG and its limitations, it's really a brand new world to me.
I hope you like SWIG. As a C/C++ lover, SWIG has enabled me to use C++ under circumstances that would make it impossible to use C++ otherwise. In today's IT world, I think SWIG gives superpowers to a C++ programmer. In my experience, the best way to approach SWIG is to focus on what it can do, rather than what it can't. It almost always does the most dangerous and ugly bits automagically, while you can find clever solutions to fill in the gaps.
Excellent, let's start with this approach then. We can always iterate and improve it over time, of course.
How would you like to proceed? I can create a pull request for an initial version that only wraps the config module (as that's what the current potential users, me included, need.). We could try to get the build setup going with that. We can wrap the rest of the orx headers over time. CAUTION, AMBITIOUS DREAM AHEAD: One day, we could even package orx with a Python interpreter, along with the wrappers and build a cross-platform python environment to develop mobile games! That would be very much appreciated in the Python community. end of AMBITIOUS DREAM.
How would like the code to be organised? I can put all the SWIG stuff under code/build/bindings. I can create a cross-platform CMake build setup to generate and compile the bindings, CMake + SWIG works well.
What branch would you like to keep these in?
About the build slave; I've tried to set it up as a system service, so it should be up as long as my dev machine is on (and that would be the case on most week days), but as a Mac noob, there's a good chance that I didn't set it up correctly, so could you confirm that it's working?
I hope you like SWIG. As a C/C++ lover, SWIG has enabled me to use C++ under circumstances that would make it impossible to use C++ otherwise. In today's IT world, I think SWIG gives superpowers to a C++ programmer. In my experience, the best way to approach SWIG is to focus on what it can do, rather than what it can't. It almost always does the most dangerous and ugly bits automagically, while you can find clever solutions to fill in the gaps.
I've heard very good things on SWIG for quite some time now, I just never got into it as my favourite high-level scripting language isn't supported: Rebol.
How would you like to proceed? I can create a pull request for an initial version that only wraps the config module (as that's what the current potential users, me included, need.). We could try to get the build setup going with that. We can wrap the rest of the orx headers over time. CAUTION, AMBITIOUS DREAM AHEAD: One day, we could even package orx with a Python interpreter, along with the wrappers and build a cross-platform python environment to develop mobile games! That would be very much appreciated in the Python community. end of AMBITIOUS DREAM.
How would like the code to be organised? I can put all the SWIG stuff under code/build/bindings. I can create a cross-platform CMake build setup to generate and compile the bindings, CMake + SWIG works well.
What branch would you like to keep these in?
A pull request on a new branch, named, say, SWIG, sounds good to me. /code/build/bindings sounds like a good place as well. We'll merge everything back in the default branch when it's stable.
Do we really need CMake? What tasks will it run precisely? If it's the SWIG command line invocation, I believe that can be handled directly in buildbot or through a python script (I'm just trying to avoid adding new dependencies on the slaves unless they're mandatory ).
About the build slave; I've tried to set it up as a system service, so it should be up as long as my dev machine is on (and that would be the case on most week days), but as a Mac noob, there's a good chance that I didn't set it up correctly, so could you confirm that it's working?
Your slave is up and running, you can see its status here:
It did compile two mac versions fine (not the iOS ones, but I'm sure it's another format change as your mac is running 10.10 with a newer XCode than mine). However, it has since had other problems: apparently on the latest builds, it doesn't find hg in the path anymore. Here's the log of the last failed attempt:
I've heard very good things on SWIG for quite some time now, I just never got into it as my favourite high-level scripting language isn't supported: Rebol.
I had never heard about Rebol before, I've checked it a bit and it definitely seems interesting. However, it also seems very similar to LISP, why do you prefer it over LISP? Is it because Rebol has an interpreter more suitable for embedding?
A pull request on a new branch, named, say, SWIG, sounds good to me. /code/build/bindings sounds like a good place as well. We'll merge everything back in the default branch when it's stable.
Great!
Do we really need CMake? What tasks will it run precisely? If it's the SWIG command line invocation, I believe that can be handled directly in buildbot or through a python script (I'm just trying to avoid adding new dependencies on the slaves unless they're mandatory ).
I'm a bit confused at this point, I think this paragraph is in conflict with our previous agreement of including the SWIG generated wrappers in the repository. In that case, the slaves wouldn't need to call SWIG anyway, so the slaves wouldn't even depend on SWIG. In any case, I can easily drop cmake for this setup. It would probably create more problems than it solves.
Your slave is up and running, you can see its status here:
...
I'll try to update to 10.10 locally and see if I can get the newer version of xcode to run on my old macbook in the coming days.
I think I've fixed my slave. As I said, I'm a noob at mac, and I wasn't very successful at setting the slave up as a system service running as an isolated user. Now I've fixed it, so the slave should be up whenever my computer is on.
By the way, fixing the slave was harder since I had to wait for the build to be triggered by some means. Is there any way I can trigger a build the next time I need to fix anything? If so, I could attempt to fix the iOS build myself.
I had never heard about Rebol before, I've checked it a bit and it definitely seems interesting. However, it also seems very similar to LISP, why do you prefer it over LISP? Is it because Rebol has an interpreter more suitable for embedding?
It's actually much higher level and simpler than LISP. For example, the source of the "read" function can be a file as well as an URL or even a block/object. It makes writing scripts very easy and fast, no matter which resources one is handling.
It supports file path, URLs, dates, etc... as first citizens.
But it does have some strong similarities with LISP, such as the homoiconicity property (ie. data and code are stored in the same way).
There's now some work done by the Rebol community on Red, a Rebol-based language suited for both low and high level development. The language is still in its infancy:http://www.red-lang.org/p/about.html
I'm a bit confused at this point, I think this paragraph is in conflict with our previous agreement of including the SWIG generated wrappers in the repository. In that case, the slaves wouldn't need to call SWIG anyway, so the slaves wouldn't even depend on SWIG. In any case, I can easily drop cmake for this setup. It would probably create more problems than it solves.
Mmh, I guess that's probably because we don't share exactly the same vision for the process. Here's in details how I thought we could do it (very similar to how the Doxygen doc is maintained):
- When a .h file is modified and/or the .i files are
- Buildbot will trigger a "SWIG" build on one of the capable slaves
- This build would create the new wrappers by calling SWIG
- And it would then commit/push the wrapper changes to the repository
Does it sound reasonable? How would you see the whole process?
I think I've fixed my slave. As I said, I'm a noob at mac, and I wasn't very successful at setting the slave up as a system service running as an isolated user. Now I've fixed it, so the slave should be up whenever my computer is on.
By the way, fixing the slave was harder since I had to wait for the build to be triggered by some means. Is there any way I can trigger a build the next time I need to fix anything? If so, I could attempt to fix the iOS build myself.
Ah, thanks! Regaarding the build triggering, yes, there's a way to do it, I'll send you the credentials by PM. Once logged with them on the master, you can request new builds.
It's actually much higher level and simpler than LISP. For example, the source of the "read" function can be a file as well as an URL or even a block/object. It makes writing scripts very easy and fast, no matter which resources one is handling.
It supports file path, URLs, dates, etc... as first citizens.
But it does have some strong similarities with LISP, such as the homoiconicity property (ie. data and code are stored in the same way).
There's now some work done by the Rebol community on Red, a Rebol-based language suited for both low and high level development. The language is still in its infancy:http://www.red-lang.org/p/about.html
You've definitely put Rebol and Red on my radar, though I have my sights set on Haskell these days. Incidentally, Haskell also suffers from a lack of SWIG support, though that's probably because object-oriented imperative programming is so alien to Haskell.
I've a feeling that the SWIG CLISP back-end could be a very good starting point to write a Rebol back-end, since they're so similar topologically. That would probably still be a significant undertaking though.
- When a .h file is modified and/or the .i files are
- Buildbot will trigger a "SWIG" build on one of the capable slaves
- This build would create the new wrappers by calling SWIG
- And it would then commit/push the wrapper changes to the repository
Does it sound reasonable? How would you see the whole process?
That's great, I initially thought we'd manually commit the wrappers, but that's better. For now, I'll focus on generating complete bindings and writing some tests/examples for them.
Ah, thanks! Regaarding the build triggering, yes, there's a way to do it, I'll send you the credentials by PM. Once logged with them on the master, you can request new builds.
You've definitely put Rebol and Red on my radar, though I have my sights set on Haskell these days. Incidentally, Haskell also suffers from a lack of SWIG support, though that's probably because object-oriented imperative programming is so alien to Haskell.
I never had the courage to look deeply into Haskell. One day that might change maybe. Right now, I'm interested in Go, as an evolution from C. I do not like C++ and, even if they solved quite a few shortcomings of C++ with D, I find the language needlessly complicated. Go, on the contrary, tried to both add meaningful features and to simplify C as well. For example, they added support for concurrency in a very elegant way without making the language itself much more complicated. They also added duck-typing, which works much better than the rigid C++ OO approach, if you ask me.
Lastly, fetching programs or dependent applications is integrated in the language/compiler itself. Imagine that orx were written in Go (or wrapped using SWIG, as it is), if one were to type, in their game.go file:
import (
"bitbucket.org/orx/orx"
)
When compiling their game, Go would sync the hg repository by itself and compile it for the target platform, unless it's already been compiled in the past, in which case it simply uses it.
That's great, I initially thought we'd manually commit the wrappers, but that's better. For now, I'll focus on generating complete bindings and writing some tests/examples for them.
Excellent, I'll take care of the buildbot scripting part when you're done!
I find Go to be quite nice as well, although I'm mainly watching both Rust and Jai (the language Jonathan Blow is working on) and hoping for the future Until then I will continue my love of C!
Comments
To me, the only valid assumption would be a pointer to a null-terminated string. Which works fine in any of the actual cases.
The potential extra entries in an array, if any, would be the responsibility of the programmer.
If it were declared as a char*[n], that would be different, of course.
So as long as it's assuming null-terminated string by default for char*, it should also assume pointer to null-terminated string by default for a char**, not saying that those can't be overridden by the programmer, but at least it'd be consistent, me think.
I guess it depends on which kind of unicode encoding they're using. If it's Go, for example, it'd be UTF-8, which is also what orx is using internally. I do not know what other languages use.
You could avoid the internal heap allocation altogether by using a stack-allocation for storing the pointers before sending the list to orx.
It's probably the best option, yes, but who knows, sometimes a "death by thousand paper cuts" can be alleviated a bit. In this case though, I agree it doesn't really matter.
I understand and it's totally fine with me to do a cherry-picking approach, I was just trying to learn more about SWIG and its limitations, it's really a brand new world to me.
Sounds good to me!
The exhaustive sequence can be found in tools/orxCrypt/src/orxCrypt.c. In this case, I'd recommend not using the embedded version as you won't need any of the plugins, like display, for example. This way the library remains pretty light and should initialize very quickly as well.
Excellent, let's start with this approach then. We can always iterate and improve it over time, of course.
Thanks a lot, that'll definitely be helpful!
You're right, that would be a worthy optimisation indeed, especially for relatively fast target languages such as Java or Go. Probably not worth it for Python though. Maybe, in time, we could specialise the wrappers for those functions for languages that need it.
I fell in love with that phrase
I hope you like SWIG. As a C/C++ lover, SWIG has enabled me to use C++ under circumstances that would make it impossible to use C++ otherwise. In today's IT world, I think SWIG gives superpowers to a C++ programmer. In my experience, the best way to approach SWIG is to focus on what it can do, rather than what it can't. It almost always does the most dangerous and ugly bits automagically, while you can find clever solutions to fill in the gaps.
How would you like to proceed? I can create a pull request for an initial version that only wraps the config module (as that's what the current potential users, me included, need.). We could try to get the build setup going with that. We can wrap the rest of the orx headers over time. CAUTION, AMBITIOUS DREAM AHEAD: One day, we could even package orx with a Python interpreter, along with the wrappers and build a cross-platform python environment to develop mobile games! That would be very much appreciated in the Python community. end of AMBITIOUS DREAM.
How would like the code to be organised? I can put all the SWIG stuff under code/build/bindings. I can create a cross-platform CMake build setup to generate and compile the bindings, CMake + SWIG works well.
What branch would you like to keep these in?
About the build slave; I've tried to set it up as a system service, so it should be up as long as my dev machine is on (and that would be the case on most week days), but as a Mac noob, there's a good chance that I didn't set it up correctly, so could you confirm that it's working?
I've heard very good things on SWIG for quite some time now, I just never got into it as my favourite high-level scripting language isn't supported: Rebol.
A pull request on a new branch, named, say, SWIG, sounds good to me. /code/build/bindings sounds like a good place as well. We'll merge everything back in the default branch when it's stable.
Do we really need CMake? What tasks will it run precisely? If it's the SWIG command line invocation, I believe that can be handled directly in buildbot or through a python script (I'm just trying to avoid adding new dependencies on the slaves unless they're mandatory
Your slave is up and running, you can see its status here:
http://buildbot.orx-project.org:8010/buildslaves/orx-mac-slave-enobayram
It did compile two mac versions fine (not the iOS ones, but I'm sure it's another format change as your mac is running 10.10 with a newer XCode than mine). However, it has since had other problems: apparently on the latest builds, it doesn't find hg in the path anymore. Here's the log of the last failed attempt:
http://buildbot.orx-project.org:8010/builders/mac/builds/8/steps/hg/logs/stdio
Maybe hg isn't in the PATH (PATH=/usr/bin:/bin:/usr/sbin:/sbin) ?
I'll try to update to 10.10 locally and see if I can get the newer version of xcode to run on my old macbook in the coming days.
I had never heard about Rebol before, I've checked it a bit and it definitely seems interesting. However, it also seems very similar to LISP, why do you prefer it over LISP? Is it because Rebol has an interpreter more suitable for embedding?
Great!
I'm a bit confused at this point, I think this paragraph is in conflict with our previous agreement of including the SWIG generated wrappers in the repository. In that case, the slaves wouldn't need to call SWIG anyway, so the slaves wouldn't even depend on SWIG. In any case, I can easily drop cmake for this setup. It would probably create more problems than it solves.
I think I've fixed my slave. As I said, I'm a noob at mac, and I wasn't very successful at setting the slave up as a system service running as an isolated user. Now I've fixed it, so the slave should be up whenever my computer is on.
By the way, fixing the slave was harder since I had to wait for the build to be triggered by some means. Is there any way I can trigger a build the next time I need to fix anything? If so, I could attempt to fix the iOS build myself.
It's actually much higher level and simpler than LISP. For example, the source of the "read" function can be a file as well as an URL or even a block/object. It makes writing scripts very easy and fast, no matter which resources one is handling.
It supports file path, URLs, dates, etc... as first citizens.
But it does have some strong similarities with LISP, such as the homoiconicity property (ie. data and code are stored in the same way).
There's now some work done by the Rebol community on Red, a Rebol-based language suited for both low and high level development. The language is still in its infancy:http://www.red-lang.org/p/about.html
Mmh, I guess that's probably because we don't share exactly the same vision for the process. Here's in details how I thought we could do it (very similar to how the Doxygen doc is maintained):
- When a .h file is modified and/or the .i files are
- Buildbot will trigger a "SWIG" build on one of the capable slaves
- This build would create the new wrappers by calling SWIG
- And it would then commit/push the wrapper changes to the repository
Does it sound reasonable? How would you see the whole process?
Ah, thanks! Regaarding the build triggering, yes, there's a way to do it, I'll send you the credentials by PM. Once logged with them on the master, you can request new builds.
You've definitely put Rebol and Red on my radar, though I have my sights set on Haskell these days. Incidentally, Haskell also suffers from a lack of SWIG support, though that's probably because object-oriented imperative programming is so alien to Haskell.
I've a feeling that the SWIG CLISP back-end could be a very good starting point to write a Rebol back-end, since they're so similar topologically. That would probably still be a significant undertaking though.
That's great, I initially thought we'd manually commit the wrappers, but that's better. For now, I'll focus on generating complete bindings and writing some tests/examples for them.
Thanks
I never had the courage to look deeply into Haskell. One day that might change maybe.
Lastly, fetching programs or dependent applications is integrated in the language/compiler itself. Imagine that orx were written in Go (or wrapped using SWIG, as it is), if one were to type, in their game.go file:
When compiling their game, Go would sync the hg repository by itself and compile it for the target platform, unless it's already been compiled in the past, in which case it simply uses it.
Excellent, I'll take care of the buildbot scripting part when you're done!