Fix for a crash occurring when the window is resized.

Temporary Platform objects were registering themselves.
The move ctor would then initialize the final object in
the circular buffer (see PlatformSystem), but it would
leave the address of the temporary object registered in
the ObserversManager.
This commit is contained in:
King_DuckZ 2014-07-06 02:21:25 +02:00
parent 0c8e9b2d7c
commit b4ddfa8f4f
5 changed files with 27 additions and 5 deletions

View file

@ -96,6 +96,7 @@ namespace cloonel {
TicketType Add ( T parObserver );
void Remove ( TicketType parTicket ) noexcept;
void Update ( TicketType parTicket, T parObserver );
std::size_t size ( void ) const { return m_usedCount; }
iterator begin ( void ) { return iterator(m_occupied, m_list, false); }
iterator end ( void ) { return iterator(m_occupied, m_list, true); }
@ -148,6 +149,18 @@ namespace cloonel {
m_list.resize(newSize);
}
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
void ObserversManager<T>::Update (TicketType parTicket, T parObserver) {
assert(static_cast<std::size_t>(parTicket) <= m_list.size());
assert(m_occupied[parTicket - 1]);
assert(m_usedCount > 0);
assert(m_list.size() == m_occupied.size());
std::swap(m_list[parTicket - 1], parObserver);
}
} //namespace cloonel
#endif

View file

@ -140,6 +140,12 @@ namespace cloonel {
m_localData->resChangeNotifList.Remove(parID);
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
void SDLMain::SwapRegisteredForResChange (size_t parID, SizeNotifiableBase* parNotif) {
m_localData->resChangeNotifList.Update(parID, parNotif);
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
ushort2 SDLMain::WidthHeight() const noexcept {

View file

@ -41,6 +41,7 @@ namespace cloonel {
void SetResolution ( ushort2 parRes );
size_t RegisterForResChange ( SizeNotifiableBase* parNotif );
void UnregisterForResChange ( size_t parID ) noexcept;
void SwapRegisteredForResChange ( size_t parID, SizeNotifiableBase* parNotif );
private:
struct LocalData;

View file

@ -34,7 +34,7 @@ namespace cloonel {
///----------------------------------------------------------------------
///----------------------------------------------------------------------
AutoRegister::AutoRegister (AutoRegister&& parOther) :
AutoRegister::AutoRegister (AutoRegister&& parOther, SizeNotifiableBase* parSwapTo) :
m_sdlmain(nullptr),
m_id(0)
#if !defined(NDEBUG)
@ -46,6 +46,8 @@ namespace cloonel {
#if !defined(NDEBUG)
std::swap(m_registered, parOther.m_registered);
#endif
assert(m_sdlmain);
m_sdlmain->SwapRegisteredForResChange(m_id, parSwapTo);
}
} //namespace regbehaviours

View file

@ -35,7 +35,7 @@ namespace cloonel {
enum { SDLMAIN_NEEDED = false };
DontRegister ( void ) = default;
DontRegister ( DontRegister&& ) { }
DontRegister ( DontRegister&&, SizeNotifiableBase* ) { }
~DontRegister ( void ) noexcept = default;
void Register ( SizeNotifiableBase* ) const noexcept { return; }
@ -46,7 +46,7 @@ namespace cloonel {
public:
enum { SDLMAIN_NEEDED = true };
AutoRegister ( AutoRegister&& parOther );
AutoRegister ( AutoRegister&& parOther, SizeNotifiableBase* parSwapTo );
explicit AutoRegister ( SDLMain* parMain ) :
m_sdlmain(parMain)
#if !defined(NDEBUG)
@ -92,7 +92,7 @@ namespace cloonel {
public:
SizeNotifiable ( const SizeNotifiable& ) = delete;
SizeNotifiable ( SizeNotifiable&& parOther ) :
RegisterBehaviour(parOther),
RegisterBehaviour(std::move(parOther), this),
SizeNotifiableBase(parOther)
{
}
@ -110,7 +110,7 @@ namespace cloonel {
public:
SizeNotifiable ( const SizeNotifiable& ) = delete;
SizeNotifiable ( SizeNotifiable&& parOther ) :
RegisterBehaviour(std::move(parOther)),
RegisterBehaviour(std::move(parOther), this),
SizeNotifiableBase(parOther)
{
}