The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
C++ wrapper for libSDL2 (2 years retrospect)
Dmitry Marakasov
Guest

* Dmitry Marakasov wrote:

Quote:
I'm writing a C++ wrapper library for SDL2. Well, not really writing,
as I currently only implement features needed for my other projects,
but still it's usable and already saves much work automatically handing
object destruction and error checking and adding some syntactic sugar.

As said, it has little functionality yet, as there're only wrappers
for SDL itself (SDL_Init/SDL_Quit), and Window, Renderer, Texture,
Point and Rect clases, and wrapper methods are only enough for basic
texture and point/line/rect drawing. However, new stuff is easily
implementable, so feel free to use and/or and submit patches and
requests for covering more SDL2 features.

Replying to my own message from almost two years ago. The development
of libSDL2pp steadily goes on, the library had almost 500 commits and
17 releases in these two years, including 0.9.0 released today, which
finally introduced SDL_mixer support. The library had numerous wrapper
coverage extensions, new features and bug fixes. I'll just briefly
mention key benefits of using this library:

- RAII-style initialization and destruction, automatic resource lifetime
control (you no longer need to care of manually freeing your stuff)
- Total error checking: exceptions are thrown if any SDL function fails.
Exception itself allows retrieval of SDL error string (you no longer
need to manually check return code after each function call)
- Method overloading, default arguments, method chaining allow shorter
and cleaner code
- C++11 move semantics support, which allow you to store SDL objects
in containers and pass/return them by value without noticeable overhead
- Number of additional methods and operator support for Point and Rect

The library currently covers:

- SDL: Point, Rect, window handling, texture and surface management,
2D rendering, audio, rwops
- SDL_image: transparent texture and surface loading from files
- SDL_ttf: everything
- SDL_mixer: everything except for custom effects

There's documentation, tests amd simple demos. Build system uses
CMake and is capable of both systemwide installation and bundling.

The library is already available from some package repos (AUR, FreeBSD
ports, DragonflyBSD DPorts, Yet Another Cygwin Ports).

Code: https://github.com/AMDmi3/libSDL2pp
Doxygen: http://sdl2pp.amdmi3.ru/
Tutorial: https://github.com/AMDmi3/libSDL2pp-tutorial

--
Dmitry Marakasov . 55B5 0596 FF1E 8D84 5F56 9510 D35A 80DD F9D2 F77D
..: jabber: http://amdmi3.ru
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Raymond Jennings
Guest

I definitely wouldn't mind some sort of handle-wise wrapping of the various pointer types.
Especially things like SDL_Texture that can be destroyed without explicit calls to SDL_DestroyTexture.  Make it so that handles are told to go poopy when their objects are destroyed, and make it so that using a handle whose object is destroyed triggers an exception.


Just a few suggestions.


On Mon, Sep 7, 2015 at 9:11 AM, Dmitry Marakasov wrote:
Quote:
* Dmitry Marakasov wrote:

Quote:
I'm writing a C++ wrapper library for SDL2. Well, not really writing,
as I currently only implement features needed for my other projects,
but still it's usable and already saves much work automatically handing
object destruction and error checking and adding some syntactic sugar.

As said, it has little functionality yet, as there're only wrappers
for SDL itself (SDL_Init/SDL_Quit), and Window, Renderer, Texture,
Point and Rect clases, and wrapper methods are only enough for basic
texture and point/line/rect drawing. However, new stuff is easily
implementable, so feel free to use and/or and submit patches and
requests for covering more SDL2 features.

Replying to my own message from almost two years ago. The development
of libSDL2pp steadily goes on, the library had almost 500 commits and
17 releases in these two years, including 0.9.0 released today, which
finally introduced SDL_mixer support. The library had numerous wrapper
coverage extensions, new features and bug fixes. I'll just briefly
mention key benefits of using this library:

- RAII-style initialization and destruction, automatic resource lifetime
  control (you no longer need to care of manually freeing your stuff)
- Total error checking: exceptions are thrown if any SDL function fails.
  Exception itself allows retrieval of SDL error string (you no longer
  need to manually check return code after each function call)
- Method overloading, default arguments, method chaining allow shorter
  and cleaner code
- C++11 move semantics support, which allow you to store SDL objects
  in containers and pass/return them by value without noticeable overhead
- Number of additional methods and operator support for Point and Rect

The library currently covers:

- SDL: Point, Rect, window handling, texture and surface management,
       2D rendering, audio, rwops
- SDL_image: transparent texture and surface loading from files
- SDL_ttf: everything
- SDL_mixer: everything except for custom effects

There's documentation, tests amd simple demos. Build system uses
CMake and is capable of both systemwide installation and bundling.

The library is already available from some package repos (AUR, FreeBSD
ports, DragonflyBSD DPorts, Yet Another Cygwin Ports).

    Code: https://github.com/AMDmi3/libSDL2pp
 Doxygen: http://sdl2pp.amdmi3.ru/
Tutorial: https://github.com/AMDmi3/libSDL2pp-tutorial

--
Dmitry Marakasov   .   55B5 0596 FF1E 8D84 5F56  9510 D35A 80DD F9D2 F77D
  ..:  jabber:      http://amdmi3.ru
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Dmitry Marakasov
Guest

* Raymond Jennings wrote:

Quote:
I definitely wouldn't mind some sort of handle-wise wrapping of the various
pointer types.

Especially things like SDL_Texture that can be destroyed without explicit
calls to SDL_DestroyTexture.

Um, how else can they be destroyed?

Quote:
Make it so that handles are told to go poopy
when their objects are destroyed, and make it so that using a handle whose
object is destroyed triggers an exception.

This is already implemented, though a bit implicitly. Regarding
destroyed objects - they are destroyed along with the handles (that's
what you call wrapper class if I understand correctly), so there's
no need for any special care. Different case is moved-from objects,
e.g.

Texture bar = ...;
Texture foo = std::move(bar); // now bar is empty

Handling these specifically was on my mind (issue #24), but in fact
these are already handled by SDL - SDL functions return errors when
they're passed nullptr instead of expected object, and errors are
converted to expections by the wrapper. It would still be useful to
add explicit asserts though.

--
Dmitry Marakasov . 55B5 0596 FF1E 8D84 5F56 9510 D35A 80DD F9D2 F77D
..: jabber: http://amdmi3.ru
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Ryan C. Gordon
Guest

Quote:
Replying to my own message from almost two years ago. The development
of libSDL2pp steadily goes on, the library had almost 500 commits and
17 releases in these two years,

That's great! It looks like you worked really hard on this. Smile

--ryan.



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Raymond Jennings
Guest

On Tue, Sep 15, 2015 at 6:35 AM, Dmitry Marakasov wrote:
Quote:
* Raymond Jennings wrote:

Quote:
I definitely wouldn't mind some sort of handle-wise wrapping of the various
pointer types.

Especially things like SDL_Texture that can be destroyed without explicit
calls to SDL_DestroyTexture.

Um, how else can they be destroyed?


I found out the hard way that SDL_DestroyRenderer implicitly destroys all textures created using the renderer in question.


Turns out, destroying the same texture twice (either on your own or if another function does it for you) leads to heap corruption.


Quote:
> Make it so that handles are told to go poopy
Quote:
when their objects are destroyed, and make it so that using a handle whose
object is destroyed triggers an exception.

This is already implemented, though a bit implicitly. Regarding
destroyed objects - they are destroyed along with the handles (that's
what you call wrapper class if I understand correctly), so there's
no need for any special care. Different case is moved-from objects,
e.g.

Texture bar = ...;
Texture foo = std::move(bar); // now bar is empty

Handling these specifically was on my mind (issue #24), but in fact
these are already handled by SDL - SDL functions return errors when
they're passed nullptr instead of expected object, and errors are
converted to expections by the wrapper. It would still be useful to
add explicit asserts though.

--
Dmitry Marakasov   .   55B5 0596 FF1E 8D84 5F56  9510 D35A 80DD F9D2 F77D
  ..:  jabber:      http://amdmi3.ru
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


C++ wrapper for libSDL2 (2 years retrospect)
Jared Maddox
Guest

Quote:
Date: Tue, 15 Sep 2015 16:35:09 +0300
From: Dmitry Marakasov
To: SDL Development List
Subject: Re: [SDL] C++ wrapper for libSDL2 (2 years retrospect)
Message-ID:
Content-Type: text/plain; charset=utf-8

* Raymond Jennings wrote:

Quote:
I definitely wouldn't mind some sort of handle-wise wrapping of the various
pointer types.

Especially things like SDL_Texture that can be destroyed without explicit
calls to SDL_DestroyTexture.

Um, how else can they be destroyed?


As I recall, a renderer that's destroyed will also destroy all of the
textures associated with it. Either have your renderer-wrapper keep
track of all of the textures that are associated with it, or allocate
something like this for each renderer-wrapper:
typedef struct
{
SDL_atomic_t refs;
SDL_atomic_t is_alive;
} still_alive;
Then give each texture a pointer to it, and only allow the renderer to
set is_alive to zero. The object that decrements ->refs to zero does
the deallocation. Probably is_alive should be incremented and
decremented (just not to 0, so use CAS) by all code that depends on
the renderer, to keep track of when the renderer can safely be
deallocated (negate when you want to deallocate, and your calling code
can detect this state).

There are upsides to both methods. The texture-tracking method is
memory hungry, but it also allows scripting environments more
flexibility, since you can implement search and iteration.
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Alex Szpakowski
Guest

SDL_Render’s APIs can only be used from the main thread, so atomic counters seem like overkill here. ;)

Quote:
On Sep 16, 2015, at 1:45 AM, Jared Maddox wrote:
typedef struct
{
SDL_atomic_t refs;
SDL_atomic_t is_alive;
} still_alive;

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Dmitry Marakasov
Guest

* Raymond Jennings wrote:

Quote:
Quote:
Quote:
I definitely wouldn't mind some sort of handle-wise wrapping of the
various
Quote:
pointer types.

Especially things like SDL_Texture that can be destroyed without explicit
calls to SDL_DestroyTexture.

Um, how else can they be destroyed?

I found out the hard way that SDL_DestroyRenderer implicitly destroys all
textures created using the renderer in question.

Turns out, destroying the same texture twice (either on your own or if
another function does it for you) leads to heap corruption.

With libSDL2pp it's much harder to do accidentally: you need Renderer
to create Textures, and since everything is destroyed in reverse
order, Textures are then correctly destroyed before Renderer. Unless
you do some magic with moving Renderer into other object and
destroying it first, but I doubt there's a way (also a need) of
handling this gracefully.

--
Dmitry Marakasov . 55B5 0596 FF1E 8D84 5F56 9510 D35A 80DD F9D2 F77D
..: jabber: http://amdmi3.ru
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Dmitry Marakasov
Guest

* Jared Maddox wrote:

Quote:
Quote:
Quote:
I definitely wouldn't mind some sort of handle-wise wrapping of the various
pointer types.

Especially things like SDL_Texture that can be destroyed without explicit
calls to SDL_DestroyTexture.

Um, how else can they be destroyed?

As I recall, a renderer that's destroyed will also destroy all of the
textures associated with it. Either have your renderer-wrapper keep
track of all of the textures that are associated with it, or allocate
something like this for each renderer-wrapper:
typedef struct
{
SDL_atomic_t refs;
SDL_atomic_t is_alive;
} still_alive;
Then give each texture a pointer to it, and only allow the renderer to
set is_alive to zero. The object that decrements ->refs to zero does
the deallocation. Probably is_alive should be incremented and
decremented (just not to 0, so use CAS) by all code that depends on
the renderer, to keep track of when the renderer can safely be
deallocated (negate when you want to deallocate, and your calling code
can detect this state).

There are upsides to both methods. The texture-tracking method is
memory hungry, but it also allows scripting environments more
flexibility, since you can implement search and iteration.

Well, I don't really see it inside the scope of my library. As a
real lifetime management mechanism? Quite complicated (it also need
to be recursive, e.g. while Textures depend on Renderer, Renderer
also depends on Window; not sure what happens if window is destroyed
first), and it produced strange and unexpected bahavior (I destroy
Renderer object, but it isn't actually destroyed. Wut? And what is
the purpose of it if it lives just to hold textures which cannot be
used for anything useful). As a debugging mechanism? Well, probably,
but still quite complicated for its purpose.

I really doubt that if consumer applications's resource management
logic is broken, library can or should do anything about it.

--
Dmitry Marakasov . 55B5 0596 FF1E 8D84 5F56 9510 D35A 80DD F9D2 F77D
..: jabber: http://amdmi3.ru
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Dmitry Marakasov
Guest

* Ryan C. Gordon wrote:

Quote:
Quote:
Replying to my own message from almost two years ago. The development
of libSDL2pp steadily goes on, the library had almost 500 commits and
17 releases in these two years,

That's great! It looks like you worked really hard on this. Smile

Thank you, trying to do my best. I'd be very honored to be listed in
http://libsdl.org/languages.php btw Smile

--
Dmitry Marakasov . 55B5 0596 FF1E 8D84 5F56 9510 D35A 80DD F9D2 F77D
..: jabber: http://amdmi3.ru
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Jared Maddox
Guest

Quote:
Date: Wed, 16 Sep 2015 01:49:42 -0300
From: Alex Szpakowski
To: SDL Development List
Subject: Re: [SDL] C++ wrapper for libSDL2 (2 years retrospect)
Message-ID:
Content-Type: text/plain; charset=utf-8

SDL_Render?s APIs can only be used from the main thread, so atomic counters
seem like overkill here. Wink


Hmm, good point, and yet I expect that someone would indeed cause a
crash in it's absence...




Quote:
Date: Wed, 16 Sep 2015 15:53:44 +0300
From: Dmitry Marakasov
To: SDL Development List
Subject: Re: [SDL] C++ wrapper for libSDL2 (2 years retrospect)
Message-ID:
Content-Type: text/plain; charset=utf-8

* Jared Maddox wrote:

Quote:
Quote:
Quote:
I definitely wouldn't mind some sort of handle-wise wrapping of the various
pointer types.

Especially things like SDL_Texture that can be destroyed without explicit
calls to SDL_DestroyTexture.

Um, how else can they be destroyed?

As I recall, a renderer that's destroyed will also destroy all of the
textures associated with it. Either have your renderer-wrapper keep
track of all of the textures that are associated with it, or allocate
something like this for each renderer-wrapper:
typedef struct
{
SDL_atomic_t refs;
SDL_atomic_t is_alive;
} still_alive;
Then give each texture a pointer to it, and only allow the renderer to
set is_alive to zero. The object that decrements ->refs to zero does
the deallocation. Probably is_alive should be incremented and
decremented (just not to 0, so use CAS) by all code that depends on
the renderer, to keep track of when the renderer can safely be
deallocated (negate when you want to deallocate, and your calling code
can detect this state).

There are upsides to both methods. The texture-tracking method is
memory hungry, but it also allows scripting environments more
flexibility, since you can implement search and iteration.

Well, I don't really see it inside the scope of my library. As a
real lifetime management mechanism? Quite complicated

I guess they'd be lifetime management systems, but the point is a
little different.

The texture-tracking method is so that you can tell the textures that
they aren't valid anymore: I originally explored this technique for
garbage-collection, but it's no good for cyclic structures, so I moved
on. The real reason to use it is if you need to send messages to the
objects being tracked: I played with this for GC instead of a simple
count to deal with someone calling delete on an object being managed
by smart pointers, then I realized it would be useful for paging
really big stuff in and out of a database.

The one I provided actual code for is just a way to provide a common
message location, without having to care about who owns it: it isn't
cyclic, so a reference count is enough.

So, they could be used as lifetime managers... but really they're
intended as a transform/mutate system instead.


Quote:
(it also need
to be recursive, e.g. while Textures depend on Renderer, Renderer
also depends on Window; not sure what happens if window is destroyed
first),

Window deletes Renderer, which deletes all of it's textures, though I
wouldn't actually suggest deleting anything, since you just need to
notify the dependants. If you do it "right", you can even get a stack
crash to go along with your hideous slugishness.


Quote:
and it produced strange and unexpected bahavior (I destroy
Renderer object, but it isn't actually destroyed. Wut? And what is
the purpose of it if it lives just to hold textures which cannot be
used for anything useful).

If you're deleting it, then finish deleting it. The Renderer object
shouldn't be a zombie, but instead the shambling horde of disembowled
Texture objects should be. The Renderer shouldn't try to keep Texture
objects alive: it should just tell them with it's dying breath to seek
vengence for it.

Quote:
As a debugging mechanism? Well, probably,
but still quite complicated for its purpose.


True, but in some cases it can be implemented entirely via exceptions,
no debugger needed.


Quote:
I really doubt that if consumer applications's resource management
logic is broken, library can or should do anything about it.


I might be prone to occasional bouts of excess.
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
C++ wrapper for libSDL2 (2 years retrospect)
Dmitry Marakasov
Guest

* Jared Maddox wrote:

Quote:
Quote:
Well, I don't really see it inside the scope of my library. As a
real lifetime management mechanism? Quite complicated

I guess they'd be lifetime management systems, but the point is a
little different.

The texture-tracking method is so that you can tell the textures that
they aren't valid anymore

I think I got you point. Well this depends on whether we consider a
situation where renderer is destroyed before textures normal. If we do,
then we really need renderer to track its textures to keep the objects
in sync to underlying SDL state. If we don't, all we can do is some
extra error checking, in which case reference counting is quite enough
IMO: it's either we get an assert on using Textures of destroyed
Renderer, or we get an assert on destroying Renderer which still has
Textures. I'd vote for the latter, as it happens early and reliably.

I still lean to `it's not normal situation' and `it's too complicated
for just error checking', however I might reconsider later.

--
Dmitry Marakasov . 55B5 0596 FF1E 8D84 5F56 9510 D35A 80DD F9D2 F77D
..: jabber: http://amdmi3.ru
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org