Delegate managing SDL_RWops to SDL_mixer when possible
SDL_mixer 2 offers the option to have the library free the SDL_RWops. Add macros to use this feature when available. References: <https://github.com/dxx-rebirth/dxx-rebirth/issues/82>
This commit is contained in:
parent
d97afc2ad5
commit
9ea09107d1
|
@ -29,8 +29,23 @@ namespace dcx {
|
|||
|
||||
namespace {
|
||||
|
||||
#if SDL_MIXER_MAJOR_VERSION == 2
|
||||
#define DXX_SDL_MIXER_MANAGES_RWOPS 1
|
||||
#else
|
||||
#define DXX_SDL_MIXER_MANAGES_RWOPS 0
|
||||
#endif
|
||||
|
||||
#if DXX_SDL_MIXER_MANAGES_RWOPS
|
||||
#define DXX_SDL_MIXER_Mix_LoadMUS_MANAGE_RWOPS , SDL_TRUE
|
||||
#define DXX_SDL_MIXER_Mix_LoadMUS_PASS_RWOPS(rw)
|
||||
#else
|
||||
#define DXX_SDL_MIXER_Mix_LoadMUS_MANAGE_RWOPS
|
||||
#define DXX_SDL_MIXER_Mix_LoadMUS_PASS_RWOPS(rw) , rw
|
||||
#endif
|
||||
|
||||
class current_music_t
|
||||
{
|
||||
#if !DXX_SDL_MIXER_MANAGES_RWOPS
|
||||
struct RWops_delete
|
||||
{
|
||||
void operator()(SDL_RWops *o)
|
||||
|
@ -38,30 +53,38 @@ class current_music_t
|
|||
SDL_RWclose(o);
|
||||
}
|
||||
};
|
||||
using rwops_pointer = std::unique_ptr<SDL_RWops, RWops_delete>;
|
||||
rwops_pointer m_ops;
|
||||
#endif
|
||||
struct Music_delete
|
||||
{
|
||||
void operator()(Mix_Music *m) { Mix_FreeMusic(m); }
|
||||
};
|
||||
typedef SDL_RWops *rpointer;
|
||||
typedef Mix_Music *mpointer;
|
||||
std::unique_ptr<SDL_RWops, RWops_delete> m_ops;
|
||||
std::unique_ptr<Mix_Music, Music_delete> m_music;
|
||||
using music_pointer = std::unique_ptr<Mix_Music, Music_delete>;
|
||||
music_pointer m_music;
|
||||
public:
|
||||
void reset(mpointer m = mpointer(), rpointer r = rpointer()) noexcept(noexcept(m_music.reset(m)) && noexcept(m_ops.reset(r)))
|
||||
void reset(
|
||||
Mix_Music *const music = nullptr
|
||||
#if !DXX_SDL_MIXER_MANAGES_RWOPS
|
||||
, SDL_RWops *const rwops = nullptr
|
||||
#endif
|
||||
) noexcept
|
||||
{
|
||||
/* Clear music first in case it needs the old ops
|
||||
* Clear old ops
|
||||
* If no new music, clear new ops immediately. This only
|
||||
* happens if the new music fails to load.
|
||||
*/
|
||||
m_music.reset(m);
|
||||
m_ops.reset(r);
|
||||
if (!m)
|
||||
m_music.reset(music);
|
||||
#if !DXX_SDL_MIXER_MANAGES_RWOPS
|
||||
m_ops.reset(rwops);
|
||||
if (!music)
|
||||
m_ops.reset();
|
||||
#endif
|
||||
}
|
||||
bool operator!() const { return !m_music; }
|
||||
explicit operator bool() const { return static_cast<bool>(m_music); }
|
||||
mpointer get() { return m_music.get(); }
|
||||
typename music_pointer::pointer get() { return m_music.get(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -92,7 +115,7 @@ int mix_play_file(const char *filename, int loop, void (*hook_finished_track)())
|
|||
{
|
||||
hmp2mid(filename, current_music_hndlbuf);
|
||||
rw = SDL_RWFromConstMem(¤t_music_hndlbuf[0], current_music_hndlbuf.size()*sizeof(char));
|
||||
current_music.reset(Mix_LoadMUS_RW(rw), rw);
|
||||
current_music.reset(Mix_LoadMUS_RW(rw DXX_SDL_MIXER_Mix_LoadMUS_MANAGE_RWOPS) DXX_SDL_MIXER_Mix_LoadMUS_PASS_RWOPS(rw));
|
||||
}
|
||||
|
||||
// try loading music via given filename
|
||||
|
@ -133,7 +156,7 @@ int mix_play_file(const char *filename, int loop, void (*hook_finished_track)())
|
|||
current_music_hndlbuf.resize(len);
|
||||
bufsize = PHYSFS_read(filehandle, ¤t_music_hndlbuf[0], sizeof(char), len);
|
||||
rw = SDL_RWFromConstMem(¤t_music_hndlbuf[0], bufsize*sizeof(char));
|
||||
current_music.reset(Mix_LoadMUS_RW(rw), rw);
|
||||
current_music.reset(Mix_LoadMUS_RW(rw DXX_SDL_MIXER_Mix_LoadMUS_MANAGE_RWOPS) DXX_SDL_MIXER_Mix_LoadMUS_PASS_RWOPS(rw));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue