Game初始化失败时自动回收资源;Music类初始化过程修改;节点二维矩阵转换方法修改

This commit is contained in:
Nomango 2018-04-24 10:35:58 +08:00
parent 0614701a30
commit f5185f5630
8 changed files with 178 additions and 211 deletions

View File

@ -21,52 +21,65 @@ bool e2d::Game::init(String sGameName)
return false; return false;
} }
do
{
// 初始化 COM 组件 // 初始化 COM 组件
CoInitializeEx(NULL, COINIT_MULTITHREADED); CoInitialize(NULL);
// 创建设备无关资源 // 创建设备无关资源
if (!Renderer::__createDeviceIndependentResources()) if (!Renderer::__createDeviceIndependentResources())
{ {
WARN_IF(true, "Renderer::__createDeviceIndependentResources Failed!"); WARN_IF(true, "Renderer::__createDeviceIndependentResources Failed!");
break; goto dev_ind_res_fail;
} }
// 初始化窗口 // 初始化窗口
if (!Window::__init()) if (!Window::__init())
{ {
WARN_IF(true, "Window::__init Failed!"); WARN_IF(true, "Window::__init Failed!");
break; goto window_fail;
} }
// 创建设备相关资源 // 创建设备相关资源
if (!Renderer::__createDeviceResources()) if (!Renderer::__createDeviceResources())
{ {
WARN_IF(true, "Renderer::__createDeviceResources Failed!"); WARN_IF(true, "Renderer::__createDeviceResources Failed!");
break; goto dev_res_fail;
} }
// 初始化 DirectInput // 初始化 DirectInput
if (!Input::__init()) if (!Input::__init())
{ {
WARN_IF(true, "Input::__init Failed!"); WARN_IF(true, "Input::__init Failed!");
break; goto input_fail;
} }
// 初始化播放器 // 初始化播放器
if (!MusicManager::__init()) if (!Music::__init())
{ {
WARN_IF(true, "MusicManager::__init Failed!"); WARN_IF(true, "Music::__init Failed!");
break; goto music_fail;
} }
// 保存游戏名称
// 初始化成功
s_sGameName = sGameName; s_sGameName = sGameName;
// 标志初始化成功
s_bInitialized = true; s_bInitialized = true;
goto succeeded;
} while (0); music_fail:
Music::__uninit();
input_fail:
Input::__uninit();
dev_res_fail:
Renderer::__discardDeviceResources();
window_fail:
Window::__init();
dev_ind_res_fail:
Renderer::__discardResources();
succeeded:
return s_bInitialized; return s_bInitialized;
} }
@ -156,17 +169,19 @@ void e2d::Game::destroy()
{ {
// 删除所有场景 // 删除所有场景
SceneManager::__uninit(); SceneManager::__uninit();
// 关闭播放器
MusicManager::__uninit();
// 删除监听器 // 删除监听器
InputManager::__uninit(); InputManager::__uninit();
ColliderManager::__uninit(); ColliderManager::__uninit();
// 删除动画 // 删除动画
ActionManager::__uninit(); ActionManager::__uninit();
// 关闭音乐播放器
MusicManager::__uninit();
// 删除所有对象 // 删除所有对象
ObjectManager::__clear(); ObjectManager::__clear();
// 清空图片缓存 // 清空图片缓存
Image::clearCache(); Image::clearCache();
// 回收音乐相关资源
Music::__uninit();
// 清空定时器 // 清空定时器
Timer::__uninit(); Timer::__uninit();
// 关闭输入 // 关闭输入

View File

@ -2,24 +2,13 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
#include <map> #include <map>
#if HIGHER_THAN_VS2010
static IXAudio2 * s_pXAudio2 = nullptr;
static IXAudio2MasteringVoice * s_pMasteringVoice = nullptr;
#else
static HINSTANCE s_hInstance = nullptr;
#endif
typedef std::pair<UINT, e2d::Music *> MusicPair; typedef std::pair<UINT, e2d::Music *> MusicPair;
typedef std::map<UINT, e2d::Music *> MusicList; typedef std::map<UINT, e2d::Music *> MusicMap;
static MusicList& getMusicList() static MusicMap& GetMusicList()
{ {
static MusicList s_List; static MusicMap s_List;
return s_List; return s_List;
} }
@ -28,7 +17,7 @@ bool e2d::MusicManager::preload(String strFilePath)
{ {
UINT nRet = strFilePath.getHashCode(); UINT nRet = strFilePath.getHashCode();
if (getMusicList().end() != getMusicList().find(nRet)) if (GetMusicList().end() != GetMusicList().find(nRet))
{ {
return true; return true;
} }
@ -38,7 +27,7 @@ bool e2d::MusicManager::preload(String strFilePath)
if (pPlayer->open(strFilePath)) if (pPlayer->open(strFilePath))
{ {
getMusicList().insert(MusicPair(nRet, pPlayer)); GetMusicList().insert(MusicPair(nRet, pPlayer));
pPlayer->retain(); pPlayer->retain();
return true; return true;
} }
@ -56,7 +45,7 @@ bool e2d::MusicManager::play(String strFilePath, int nLoopCount)
if (MusicManager::preload(strFilePath)) if (MusicManager::preload(strFilePath))
{ {
UINT nRet = strFilePath.getHashCode(); UINT nRet = strFilePath.getHashCode();
Music * pMusic = getMusicList()[nRet]; Music * pMusic = GetMusicList()[nRet];
if (pMusic->play(nLoopCount)) if (pMusic->play(nLoopCount))
{ {
return true; return true;
@ -99,15 +88,15 @@ e2d::Music * e2d::MusicManager::get(String strFilePath)
UINT nRet = strFilePath.getHashCode(); UINT nRet = strFilePath.getHashCode();
if (getMusicList().end() != getMusicList().find(nRet)) if (GetMusicList().end() != GetMusicList().find(nRet))
return getMusicList()[nRet]; return GetMusicList()[nRet];
return nullptr; return nullptr;
} }
void e2d::MusicManager::pauseAll() void e2d::MusicManager::pauseAll()
{ {
for (auto iter = getMusicList().begin(); iter != getMusicList().end(); iter++) for (auto iter = GetMusicList().begin(); iter != GetMusicList().end(); iter++)
{ {
(*iter).second->pause(); (*iter).second->pause();
} }
@ -115,7 +104,7 @@ void e2d::MusicManager::pauseAll()
void e2d::MusicManager::resumeAll() void e2d::MusicManager::resumeAll()
{ {
for (auto iter = getMusicList().begin(); iter != getMusicList().end(); iter++) for (auto iter = GetMusicList().begin(); iter != GetMusicList().end(); iter++)
{ {
(*iter).second->resume(); (*iter).second->resume();
} }
@ -123,100 +112,18 @@ void e2d::MusicManager::resumeAll()
void e2d::MusicManager::stopAll() void e2d::MusicManager::stopAll()
{ {
for (auto iter = getMusicList().begin(); iter != getMusicList().end(); iter++) for (auto iter = GetMusicList().begin(); iter != GetMusicList().end(); iter++)
{ {
(*iter).second->stop(); (*iter).second->stop();
} }
} }
#if HIGHER_THAN_VS2010
IXAudio2 * e2d::MusicManager::getIXAudio2()
{
return s_pXAudio2;
}
IXAudio2MasteringVoice * e2d::MusicManager::getIXAudio2MasteringVoice()
{
return s_pMasteringVoice;
}
bool e2d::MusicManager::__init()
{
HRESULT hr;
if (FAILED(hr = XAudio2Create(&s_pXAudio2, 0)))
{
WARN_IF(true, "Failed to init XAudio2 engine");
return false;
}
if (FAILED(hr = s_pXAudio2->CreateMasteringVoice(&s_pMasteringVoice)))
{
WARN_IF(true, "Failed creating mastering voice");
SafeReleaseInterface(&s_pXAudio2);
return false;
}
return true;
}
void e2d::MusicManager::__uninit() void e2d::MusicManager::__uninit()
{ {
for (auto iter : getMusicList()) for (auto iter : GetMusicList())
{ {
iter.second->close(); iter.second->close();
iter.second->release(); iter.second->release();
} }
getMusicList().clear(); GetMusicList().clear();
if (s_pMasteringVoice)
{
s_pMasteringVoice->DestroyVoice();
} }
SafeReleaseInterface(&s_pXAudio2);
}
#else
HINSTANCE e2d::MusicManager::getHInstance()
{
return s_hInstance;
}
bool e2d::MusicManager::__init()
{
s_hInstance = HINST_THISCOMPONENT;
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = Music::MusicProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = s_hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = MUSIC_CLASS_NAME;
if (!RegisterClass(&wc) && 1410 != GetLastError())
{
return false;
}
return true;
}
void e2d::MusicManager::__uninit()
{
for (auto iter = getMusicList().begin(); iter != getMusicList().end(); iter++)
{
(*iter).second->close();
(*iter).second->release();
}
getMusicList().clear();
}
#endif

View File

@ -51,7 +51,7 @@ void e2d::Node::_update()
{ {
if (m_bTransformNeeded) if (m_bTransformNeeded)
{ {
_updateTransform(this); _updateTransform();
} }
if (!m_vChildren.empty()) if (!m_vChildren.empty())
@ -201,7 +201,7 @@ void e2d::Node::_onExit()
} }
} }
void e2d::Node::_updateTransform() void e2d::Node::_updateSelfTransform()
{ {
// 计算中心点坐标 // 计算中心点坐标
D2D1_POINT_2F pivot = { m_fWidth * m_fPivotX, m_fHeight * m_fPivotY }; D2D1_POINT_2F pivot = { m_fWidth * m_fPivotX, m_fHeight * m_fPivotY };
@ -231,46 +231,36 @@ void e2d::Node::_updateTransform()
} }
} }
void e2d::Node::_updateChildrenTransform() void e2d::Node::_updateTransform()
{
FOR_LOOP(child, m_vChildren)
{
_updateTransform(child);
}
}
void e2d::Node::_updateTransform(Node * node)
{ {
// 计算自身的转换矩阵 // 计算自身的转换矩阵
node->_updateTransform(); _updateSelfTransform();
// 绑定于自身的碰撞体也进行相应转换 // 绑定于自身的碰撞体也进行相应转换
if (node->m_pCollider) if (m_pCollider)
{ {
node->m_pCollider->_transform(); m_pCollider->_transform();
} }
// 遍历子节点下的所有节点
node->_updateChildrenTransform();
// 标志已执行过变换 // 标志已执行过变换
node->m_bTransformNeeded = false; m_bTransformNeeded = false;
// 遍历子节点下的所有节点
FOR_LOOP(child, this->m_vChildren)
{
child->_updateTransform();
}
} }
void e2d::Node::_updateChildrenOpacity() void e2d::Node::_updateOpacity()
{ {
if (m_pParent)
{
m_fDisplayOpacity = m_fRealOpacity * m_pParent->m_fDisplayOpacity;
}
FOR_LOOP(child, m_vChildren) FOR_LOOP(child, m_vChildren)
{ {
_updateOpacity(child); child->_updateOpacity();
} }
} }
void e2d::Node::_updateOpacity(Node * node)
{
if (node->m_pParent)
{
node->m_fDisplayOpacity = node->m_fRealOpacity * node->m_pParent->m_fDisplayOpacity;
}
node->_updateChildrenOpacity();
}
bool e2d::Node::isVisiable() const bool e2d::Node::isVisiable() const
{ {
return m_bVisiable; return m_bVisiable;
@ -511,7 +501,7 @@ void e2d::Node::setOpacity(double opacity)
m_fDisplayOpacity = m_fRealOpacity = min(max(static_cast<float>(opacity), 0), 1); m_fDisplayOpacity = m_fRealOpacity = min(max(static_cast<float>(opacity), 0), 1);
// 更新节点透明度 // 更新节点透明度
_updateOpacity(this); _updateOpacity();
} }
void e2d::Node::setPivotX(double pivotX) void e2d::Node::setPivotX(double pivotX)
@ -674,7 +664,7 @@ void e2d::Node::addChild(Node * child, int order /* = 0 */)
} }
// 更新子节点透明度 // 更新子节点透明度
_updateOpacity(child); child->_updateOpacity();
// 更新节点转换 // 更新节点转换
child->m_bTransformNeeded = true; child->m_bTransformNeeded = true;
// 更新子节点排序 // 更新子节点排序

View File

@ -24,6 +24,39 @@ inline bool TraceError(wchar_t* sPrompt, HRESULT hr)
return false; return false;
} }
static IXAudio2 * s_pXAudio2 = nullptr;
static IXAudio2MasteringVoice * s_pMasteringVoice = nullptr;
bool e2d::Music::__init()
{
HRESULT hr;
if (FAILED(hr = XAudio2Create(&s_pXAudio2, 0)))
{
WARN_IF(true, "Failed to init XAudio2 engine");
return false;
}
if (FAILED(hr = s_pXAudio2->CreateMasteringVoice(&s_pMasteringVoice)))
{
WARN_IF(true, "Failed creating mastering voice");
SafeReleaseInterface(&s_pXAudio2);
return false;
}
return true;
}
void e2d::Music::__uninit()
{
if (s_pMasteringVoice)
{
s_pMasteringVoice->DestroyVoice();
}
SafeReleaseInterface(&s_pXAudio2);
}
Music::Music() Music::Music()
: m_bOpened(false) : m_bOpened(false)
@ -69,8 +102,7 @@ bool Music::open(String strFileName)
return false; return false;
} }
IXAudio2 * pXAudio2 = MusicManager::getIXAudio2(); if (!s_pXAudio2)
if (!pXAudio2)
{ {
WARN_IF(true, "IXAudio2 nullptr pointer error!"); WARN_IF(true, "IXAudio2 nullptr pointer error!");
return false; return false;
@ -116,7 +148,7 @@ bool Music::open(String strFileName)
// ´´½¨ÒôÔ´ // ´´½¨ÒôÔ´
HRESULT hr; HRESULT hr;
if (FAILED(hr = pXAudio2->CreateSourceVoice(&m_pSourceVoice, m_pwfx))) if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&m_pSourceVoice, m_pwfx)))
{ {
TraceError(L"Create source voice error", hr); TraceError(L"Create source voice error", hr);
SAFE_DELETE_ARRAY(m_pbWaveData); SAFE_DELETE_ARRAY(m_pbWaveData);
@ -291,6 +323,16 @@ bool Music::setFrequencyRatio(double fFrequencyRatio)
return false; return false;
} }
IXAudio2 * e2d::Music::getIXAudio2()
{
return s_pXAudio2;
}
IXAudio2MasteringVoice * e2d::Music::getIXAudio2MasteringVoice()
{
return s_pMasteringVoice;
}
IXAudio2SourceVoice * Music::getIXAudio2SourceVoice() const IXAudio2SourceVoice * Music::getIXAudio2SourceVoice() const
{ {
return m_pSourceVoice; return m_pSourceVoice;
@ -496,6 +538,33 @@ bool Music::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t *
#else #else
#define MUSIC_CLASS_NAME L"Easy2DMusicCallbackWnd"
static HINSTANCE s_hInstance = nullptr;
bool e2d::Music::__init()
{
s_hInstance = HINST_THISCOMPONENT;
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = Music::MusicProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = s_hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = MUSIC_CLASS_NAME;
if (!RegisterClass(&wc) && 1410 != GetLastError())
{
return false;
}
return true;
}
e2d::Music::Music() e2d::Music::Music()
: m_wnd(NULL) : m_wnd(NULL)
@ -512,7 +581,7 @@ e2d::Music::Music()
0, 0, 0, 0, 0, 0, 0, 0,
NULL, NULL,
NULL, NULL,
MusicManager::getHInstance(), s_hInstance,
NULL); NULL);
if (m_wnd) if (m_wnd)

View File

@ -62,8 +62,6 @@
#if HIGHER_THAN_VS2010 #if HIGHER_THAN_VS2010
#include <xaudio2.h> #include <xaudio2.h>
#pragma comment(lib, "xaudio2.lib") #pragma comment(lib, "xaudio2.lib")
#else
#define MUSIC_CLASS_NAME L"Easy2DMusicCallbackWnd"
#endif #endif

View File

@ -221,26 +221,8 @@ public:
// 停止所有音乐 // 停止所有音乐
static void stopAll(); static void stopAll();
#if HIGHER_THAN_VS2010
// 获取 IXAudio2 对象
static IXAudio2 * getIXAudio2();
// 获取 IXAudio2MasteringVoice 对象
static IXAudio2MasteringVoice * getIXAudio2MasteringVoice();
#else
// 获取 HINSTANCE
static HINSTANCE getHInstance();
#endif
private: private:
// 初始化音乐播放器 // 쀼澗稜있栗都
static bool __init();
// 回收相关资源
static void __uninit(); static void __uninit();
}; };

View File

@ -435,19 +435,13 @@ protected:
); );
// 对自身进行二维矩阵变换 // 对自身进行二维矩阵变换
void _updateTransform(); void _updateSelfTransform();
// 更新所有子节点矩阵
void _updateChildrenTransform();
// 更新所有子节点透明度
void _updateChildrenOpacity();
// 更新节点二维矩阵 // 更新节点二维矩阵
static void _updateTransform(Node * node); void _updateTransform();
// 更新节点透明度 // 更新节点透明度
static void _updateOpacity(Node * node); void _updateOpacity();
protected: protected:
String m_sName; String m_sName;

View File

@ -56,7 +56,7 @@ private:
class Music : class Music :
public Object public Object
{ {
friend MusicManager; friend Game;
public: public:
Music(); Music();
@ -108,8 +108,20 @@ public:
double fFrequencyRatio /* 频率比范围为 1/1024.0f ~ 1024.0f,其中 1.0 为正常声调 */ double fFrequencyRatio /* 频率比范围为 1/1024.0f ~ 1024.0f,其中 1.0 为正常声调 */
); );
private:
static bool __init();
static void __uninit();
#if HIGHER_THAN_VS2010 #if HIGHER_THAN_VS2010
public:
// 获取 IXAudio2 对象
static IXAudio2 * getIXAudio2();
// 获取 IXAudio2MasteringVoice 对象
static IXAudio2MasteringVoice * getIXAudio2MasteringVoice();
// 获取 IXAudio2SourceVoice 对象 // 获取 IXAudio2SourceVoice 对象
IXAudio2SourceVoice* getIXAudio2SourceVoice() const; IXAudio2SourceVoice* getIXAudio2SourceVoice() const;