Hi there.
I brought this up before as a question - I don't like the lack of error-checking around some c wrapper functions (eg, in sdl2 wrappers); but now I have a very basic implementation.
Have updated the classic platformer.nim so that it delegates all of its SDL2-related error checking over to a new module, safe_sdl2.nim.
My forked and updated version of nim-platformer:
https://github.com/wizzardx/nim-platformer
So instead of eg, code like this:
sdlFailIf(not sdl2.init(INIT_VIDEO or INIT_TIMER or INIT_EVENTS)):
"SDL2 initialization failed"
That can now be written as:
safe_sdl2.safeInit(INIT_VIDEO or INIT_TIMER or INIT_EVENTS)
Inside safe_sdl2 we still do the same checks. We also have a lot of other sanity checks in there too, like eg some parameters must not have nil values, range checks, etc.
Comments?
Would other people find it useful if I made and uploaded a "safe_sdl2" module?
You could go a step further and create a proper high level SDL2 module. For example, use sets and define flags as enums instead of using this bitwise ORing.
That said, it might be better for you to create a high level, graphics-library-agnostic, 2D graphics package. Better yet, update this: https://github.com/nim-lang/graphics
I've started playing with a port of pygame_sdl2 over to Nim. Probably won't go anywhere, but I'm having fun with it :-)
https://github.com/renpy/pygame_sdl2
And occasionally jumping between that and trying to re-implement some really basic parts of Ren'Py into.
Eventually something like cocos2d-nim might be fun to work on :P.
Mainly it's an excuse for me to play with Nim; studying books or tutorials is more boring and makes me sleepy :-/
That said; what's wrong with nim-lang/graphics as it is?
I don't see any open issues on it. Also, no README, so I'm not sure what it's trying to achieve exactly compared to other graphics or game libs that already exist?
Edit: I found this documentation:
https://nim-lang.org/0.11.0/graphics.html
Could you perhaps add some issues against the github repo? eg as feature requests.
In terms of "proper" high level SDL2; I'd probably want to do something like re-implement the rust SDL2 wrapper. What I mainly like about that is not that it's Rust, but that it's entirely safe by default.
Probably wouldn't go as far as making a Result[T] type and returning that; Idiomatic general Nim I think is more about taking advantage of the GC, as well as throwing exceptions. Someone else can wrap things in Result[T] if they like that.
After much gnashing of teeth and wailing, and I guess a few hours of random hacking too.
I'm guessing it's probably just a lot easier to work against Vladar's nimgame2 most of the time for a high level SDL2 wrapper, there's already a huge amount of quality work put into it:
https://vladar4.github.io/nimgame2/
(still, it's fun to hack for the sake of hacking and getting practice, even if what you're working on right now is ultimately useless :P )
Thanks for the idea though.
I'm going through lazyfoo tuts, and making a high level but also really safe wrapper while I'm about it.
The high level wrapper builds on top of the really safe low level wrapper I was working on before.
So eg, my lazyfoo chapter 01 port looks like this:
import ../../my_sdl2_libs/high_level_sdl2
const
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
WHITE = (0xFF, 0xFF, 0xFF)
proc main =
var sdl2_context = initSdl2Context(initvideo=true)
var window = sdl2_context.createWindow(title="SDL Tutorial",
width=SCREEN_WIDTH,
height=SCREEN_HEIGHT,
windowShown=true)
var screenSurface = window.getSurface()
screenSurface.fillRect(color=WHITE)
window.updateSurface()
sdl2Context.delay(2.0)
main()
There's no pointers or references used there, all of those are wrapper objects with built-in Nim destructors, so they also automatically tidy their resources when they go out of scope.
Also not using OR-based flags, but rather bool arguments.
Nim's named and optional arguments are really awesome, you don't need to use builder patterns nearly as much as in some other langs.
I got a bit stuck here.
It's hard to eg, create a RAII-type object in a function, and then pass that to a caller.
Nim wants to destroy the previous object and then make a new object.
Haven't really worked with it, but I think what's missing is some kind of move semantic. I think that's under dev? (have seen something like an =sink operator under github).
Basically; would like to do a Nim library similar to what this C++ library supports in terms of RAII, automated tidy-up, and also flexible passing around of RAII objects without triggering their destructors unnecessarily:
https://github.com/libSDL2pp/libSDL2pp
At the moment I need to eg, set a property called "disableDestructor" to true before returning a RAII-type object from a function, and then setting "disableDestructor" back to false again afterwards.
Comments?