![]() |
C++ wrapper for libSDL2 (2 years retrospect) | ![]() |
Dmitry Marakasov
Guest
![]() |
![]() |
* Dmitry Marakasov wrote:
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:
|
||||||||||||||
|
![]() |
C++ wrapper for libSDL2 (2 years retrospect) | ![]() |
Dmitry Marakasov
Guest
![]() |
![]() |
* Raymond Jennings wrote:
Um, how else can they be destroyed?
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
![]() |
![]() |
That's great! It looks like you worked really hard on this. :) --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:
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.
|
||||||||||||||||||
|
![]() |
C++ wrapper for libSDL2 (2 years retrospect) | ![]() |
Jared Maddox
Guest
![]() |
![]() |
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. ;)
_______________________________________________ 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:
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:
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:
Thank you, trying to do my best. I'd be very honored to be listed in http://libsdl.org/languages.php btw :) -- 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
![]() |
![]() |
Hmm, good point, and yet I expect that someone would indeed cause a crash in it's absence...
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.
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.
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.
True, but in some cases it can be implemented entirely via exceptions, no debugger needed.
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:
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 |
||||||||||||||
|