From 72b58f6b8b29fb59a91adf9a4ec7a74cd2f777a3 Mon Sep 17 00:00:00 2001 From: kiritow <1362050620@qq.com> Date: Thu, 20 Apr 2017 22:52:42 +0800 Subject: [PATCH] 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. --- MiniEngine.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++----- MiniEngine.h | 24 ++++++++++++++-- 2 files changed, 91 insertions(+), 10 deletions(-) diff --git a/MiniEngine.cpp b/MiniEngine.cpp index a4636f9..050dd8e 100644 --- a/MiniEngine.cpp +++ b/MiniEngine.cpp @@ -401,9 +401,10 @@ namespace MiniEngine return surf; } - void Texture::_set(SDL_Texture* p)//private + void Texture::_set_sp(const std::shared_ptr& 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,[this](std::weak_ptr* 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 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 sp(p,SDL_DestroyTexture); + _lst_texture_sp.push_back(sp); + return sp; + } + + void Window::_deleteTexture_SP(std::shared_ptr 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 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) diff --git a/MiniEngine.h b/MiniEngine.h index e484b00..1df9fe2 100644 --- a/MiniEngine.h +++ b/MiniEngine.h @@ -19,6 +19,7 @@ #include #include #include +#include #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 _text; - void _set(SDL_Texture*); + std::shared_ptr> _text; + void _set_sp(const std::shared_ptr& 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& 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 _newTexture_Raw(SDL_Texture*); + + /// Called by Class Texture + void _deleteTexture_SP(std::shared_ptr); + protected: template void _setRenderer(RendererType Type,Args&&... args) @@ -316,6 +332,8 @@ namespace MiniEngine void _clear(); SDL_Window* _get(); Renderer winrnd; + + std::list> _lst_texture_sp; }; class Font