Texture info stored in Window.

Fix issue #3:
class Texture has a shared_ptr to weak_ptr. The weak_ptr observes a
shared_ptr in a list in class Window.
When Window::setRenderer is called, Textures will be released and the
previous renderer is also release. Then a new renderer is created. User
should reload textures by themselves.
This commit is contained in:
Kirigaya Kazuto 2017-04-20 22:52:42 +08:00
parent 6ed03e3e7d
commit 72b58f6b8b
2 changed files with 91 additions and 10 deletions

View File

@ -401,9 +401,10 @@ namespace MiniEngine
return surf;
}
void Texture::_set(SDL_Texture* p)//private
void Texture::_set_sp(const std::shared_ptr<SDL_Texture>& sp)//private
{
_text.reset(p,SDL_DestroyTexture);
/// Link the weak_ptr (in class Texture) with shared_ptr (in class Window)
*(_text.get())=sp;
updateInfo();
}
@ -415,11 +416,28 @@ namespace MiniEngine
SDL_Texture* Texture::_get()//private
{
return _text.get();
if(_text.get()==nullptr)
{
return nullptr;
}
else return _text.get()->lock().get();
}
void Texture::_setWindow(Window* pwnd)
{
_p_wnd=pwnd;
}
Window* Texture::_getWindow()
{
return _p_wnd;
}
Texture::Texture()
{
_text.reset(new std::weak_ptr<SDL_Texture>,[this](std::weak_ptr<SDL_Texture>* wp){
_getWindow()->_deleteTexture_SP(wp->lock());
});
updateInfo();
}
@ -524,6 +542,16 @@ namespace MiniEngine
return _rnd.lock().get();
}
void Renderer::_setWindow(Window* pWnd)
{
_p_wnd=pWnd;
}
Window* Renderer::_getWindow()
{
return _p_wnd;
}
int Renderer::setColor(RGBA pack)
{
return SDL_SetRenderDrawColor(_get(), pack.r, pack.g, pack.b, pack.a);
@ -700,7 +728,9 @@ namespace MiniEngine
e.fetch();
throw e;
}
t._set(temp);
t._set_sp(_getWindow()->_newTexture_Raw(temp));
t._setWindow(_getWindow());
return t;
}
@ -714,7 +744,9 @@ namespace MiniEngine
e.fetch();
throw e;
}
t._set(temp);
t._set_sp(_getWindow()->_newTexture_Raw(temp));
t._setWindow(_getWindow());
return t;
}
@ -728,7 +760,9 @@ namespace MiniEngine
e.fetch();
throw e;
}
t._set(temp);
t._set_sp(_getWindow()->_newTexture_Raw(temp));
t._setWindow(_getWindow());
return t;
}
@ -742,7 +776,9 @@ namespace MiniEngine
throw e;
}
Texture t;
t._set(temp);
t._set_sp(_getWindow()->_newTexture_Raw(temp));
t._setWindow(_getWindow());
return t;
}
@ -809,6 +845,27 @@ namespace MiniEngine
return _wnd.get();
}
/// Called by class Renderer ONLY.
std::shared_ptr<SDL_Texture> Window::_newTexture_Raw(SDL_Texture* p)
{
// DEBUG:
//printf("Window::_newTexture_Raw: %p\n",p);
/// Create a shared_ptr of SDL_Texture (with special deleter)
std::shared_ptr<SDL_Texture> sp(p,SDL_DestroyTexture);
_lst_texture_sp.push_back(sp);
return sp;
}
void Window::_deleteTexture_SP(std::shared_ptr<SDL_Texture> p)
{
// DEBUG:
//printf("Window::_deleteTexture_SP: %p\n",p.get());
/// Remove shared_ptr of SDL_Texture from list (in class Window)
_lst_texture_sp.remove(p);
}
Window::Window(std::string Title, int Width, int Height, std::initializer_list<RendererType> RendererFlags) throw(ErrorViewer)
{
SDL_Window* temp = SDL_CreateWindow(Title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_WINDOW_SHOWN);
@ -947,6 +1004,9 @@ namespace MiniEngine
void Window::_setRenderer_Real(Uint32 flags)
{
/// Release Previous Textures
_lst_texture_sp.clear();
/// Release Previous Renderer
_rnd.reset();
/// Set New Renderer
@ -954,6 +1014,9 @@ namespace MiniEngine
/// Set Link of class Renderer with _rnd (in class Window)
winrnd._set_sp(_rnd);
/// Associate class Renderer with this (class Window)
winrnd._setWindow(this);
}
int Window::showSimpleMessageBox(MessageBoxType type,std::string Title,std::string Message)

View File

@ -19,6 +19,7 @@
#include <string>
#include <memory>
#include <functional>
#include <list>
#define _DECL_DEPRECATED __declspec(deprecated)
#define _DECL_DEPRECATED_MSG(InfoString) __declspec(deprecated(InfoString))
@ -177,12 +178,16 @@ namespace MiniEngine
/// updateInfo() must be called after Texture is changed.
void updateInfo();
private:
std::shared_ptr<SDL_Texture> _text;
void _set(SDL_Texture*);
std::shared_ptr<std::weak_ptr<SDL_Texture>> _text;
void _set_sp(const std::shared_ptr<SDL_Texture>& sp);
void _clear();
SDL_Texture* _get();
Rect rect;
friend class Renderer;
class Window* _p_wnd;
Window* _getWindow();
void _setWindow(Window*);
};
enum class RendererType { Software, Accelerated, PresentSync, TargetTexture };
@ -239,6 +244,11 @@ namespace MiniEngine
void _set_sp(std::shared_ptr<SDL_Renderer>& p);
void _clear();
SDL_Renderer* _get();
class Window* _getWindow();
void _setWindow(Window*);
Window* _p_wnd;
friend class Window;
};
@ -290,8 +300,14 @@ namespace MiniEngine
void maximize();
void restore();
_DECL_DEPRECATED Surface getSurface();
/// Called by Class Renderer
std::shared_ptr<SDL_Texture> _newTexture_Raw(SDL_Texture*);
/// Called by Class Texture
void _deleteTexture_SP(std::shared_ptr<SDL_Texture>);
protected:
template<typename... Args>
void _setRenderer(RendererType Type,Args&&... args)
@ -316,6 +332,8 @@ namespace MiniEngine
void _clear();
SDL_Window* _get();
Renderer winrnd;
std::list<std::shared_ptr<SDL_Texture>> _lst_texture_sp;
};
class Font