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; 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(); updateInfo();
} }
@ -415,11 +416,28 @@ namespace MiniEngine
SDL_Texture* Texture::_get()//private 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() Texture::Texture()
{ {
_text.reset(new std::weak_ptr<SDL_Texture>,[this](std::weak_ptr<SDL_Texture>* wp){
_getWindow()->_deleteTexture_SP(wp->lock());
});
updateInfo(); updateInfo();
} }
@ -524,6 +542,16 @@ namespace MiniEngine
return _rnd.lock().get(); return _rnd.lock().get();
} }
void Renderer::_setWindow(Window* pWnd)
{
_p_wnd=pWnd;
}
Window* Renderer::_getWindow()
{
return _p_wnd;
}
int Renderer::setColor(RGBA pack) int Renderer::setColor(RGBA pack)
{ {
return SDL_SetRenderDrawColor(_get(), pack.r, pack.g, pack.b, pack.a); return SDL_SetRenderDrawColor(_get(), pack.r, pack.g, pack.b, pack.a);
@ -700,7 +728,9 @@ namespace MiniEngine
e.fetch(); e.fetch();
throw e; throw e;
} }
t._set(temp);
t._set_sp(_getWindow()->_newTexture_Raw(temp));
t._setWindow(_getWindow());
return t; return t;
} }
@ -714,7 +744,9 @@ namespace MiniEngine
e.fetch(); e.fetch();
throw e; throw e;
} }
t._set(temp);
t._set_sp(_getWindow()->_newTexture_Raw(temp));
t._setWindow(_getWindow());
return t; return t;
} }
@ -728,7 +760,9 @@ namespace MiniEngine
e.fetch(); e.fetch();
throw e; throw e;
} }
t._set(temp);
t._set_sp(_getWindow()->_newTexture_Raw(temp));
t._setWindow(_getWindow());
return t; return t;
} }
@ -742,7 +776,9 @@ namespace MiniEngine
throw e; throw e;
} }
Texture t; Texture t;
t._set(temp);
t._set_sp(_getWindow()->_newTexture_Raw(temp));
t._setWindow(_getWindow());
return t; return t;
} }
@ -809,6 +845,27 @@ namespace MiniEngine
return _wnd.get(); 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) 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); 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) void Window::_setRenderer_Real(Uint32 flags)
{ {
/// Release Previous Textures
_lst_texture_sp.clear();
/// Release Previous Renderer /// Release Previous Renderer
_rnd.reset(); _rnd.reset();
/// Set New Renderer /// Set New Renderer
@ -954,6 +1014,9 @@ namespace MiniEngine
/// Set Link of class Renderer with _rnd (in class Window) /// Set Link of class Renderer with _rnd (in class Window)
winrnd._set_sp(_rnd); 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) int Window::showSimpleMessageBox(MessageBoxType type,std::string Title,std::string Message)

View File

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