resolve #18, 简化 Player

This commit is contained in:
Nomango 2018-08-12 12:06:06 +08:00
parent 250332aa2e
commit 4ef4715ea6
9 changed files with 109 additions and 192 deletions

View File

@ -3,7 +3,6 @@
e2d::Config::Config() e2d::Config::Config()
: _gameName() : _gameName()
, _soundEnabled(true)
, _showFps(false) , _showFps(false)
, _outlineVisible(false) , _outlineVisible(false)
, _collisionEnabled(false) , _collisionEnabled(false)
@ -30,11 +29,6 @@ void e2d::Config::setOutlineVisible(bool visible)
_outlineVisible = visible; _outlineVisible = visible;
} }
void e2d::Config::setSoundEnabled(bool enabled)
{
_soundEnabled = enabled;
}
void e2d::Config::setCollisionEnabled(bool enabled) void e2d::Config::setCollisionEnabled(bool enabled)
{ {
_collisionEnabled = enabled; _collisionEnabled = enabled;
@ -50,11 +44,6 @@ e2d::String e2d::Config::getGameName() const
return _gameName; return _gameName;
} }
bool e2d::Config::isSoundEnabled() const
{
return _soundEnabled;
}
bool e2d::Config::isFpsShow() const bool e2d::Config::isFpsShow() const
{ {
return _showFps; return _showFps;

View File

@ -36,15 +36,16 @@ e2d::GC::~GC()
{ {
// 删除所有对象 // 删除所有对象
this->clear(); this->clear();
// 清除图片缓存 // 清除图片缓存
Image::clearCache(); Image::clearCache();
// 删除所有单例 // 删除所有单例
Game::destroyInstance(); Game::destroyInstance();
Renderer::destroyInstance(); Renderer::destroyInstance();
Input::destroyInstance(); Input::destroyInstance();
Window::destroyInstance(); Window::destroyInstance();
Timer::destroyInstance(); Timer::destroyInstance();
Player::destroyInstance();
SceneManager::destroyInstance(); SceneManager::destroyInstance();
ActionManager::destroyInstance(); ActionManager::destroyInstance();
CollisionManager::destroyInstance(); CollisionManager::destroyInstance();

View File

@ -100,14 +100,6 @@ bool e2d::Game::isPaused()
void e2d::Game::setConfig(const Config& config) void e2d::Game::setConfig(const Config& config)
{ {
if (_config.isSoundEnabled() != config.isSoundEnabled())
{
if (config.isSoundEnabled())
Player::getInstance()->getXAudio2()->StartEngine();
else
Player::getInstance()->getXAudio2()->StopEngine();
}
_config = config; _config = config;
} }
@ -125,5 +117,4 @@ void e2d::Game::cleanup()
{ {
GC::getInstance()->clear(); GC::getInstance()->clear();
Image::clearCache(); Image::clearCache();
Player::getInstance()->clearCache();
} }

View File

@ -32,21 +32,10 @@ e2d::Music::Music()
, _dwSize(0) , _dwSize(0)
, _voice(nullptr) , _voice(nullptr)
, _voiceCallback(this) , _voiceCallback(this)
, _xAudio2(nullptr)
, _masteringVoice(nullptr)
{ {
} CoInitialize(nullptr);
e2d::Music::Music(const e2d::String & filePath)
: _opened(false)
, _playing(false)
, _wfx(nullptr)
, _hmmio(nullptr)
, _resBuffer(nullptr)
, _waveData(nullptr)
, _dwSize(0)
, _voice(nullptr)
, _voiceCallback(this)
{
this->open(filePath);
} }
e2d::Music::Music(const Resource& res) e2d::Music::Music(const Resource& res)
@ -59,28 +48,72 @@ e2d::Music::Music(const Resource& res)
, _dwSize(0) , _dwSize(0)
, _voice(nullptr) , _voice(nullptr)
, _voiceCallback(this) , _voiceCallback(this)
, _xAudio2(nullptr)
, _masteringVoice(nullptr)
{ {
CoInitialize(nullptr);
this->open(res); this->open(res);
} }
e2d::Music::Music(IXAudio2 * xAudio2)
: _opened(false)
, _playing(false)
, _wfx(nullptr)
, _hmmio(nullptr)
, _resBuffer(nullptr)
, _waveData(nullptr)
, _dwSize(0)
, _voice(nullptr)
, _voiceCallback(this)
, _xAudio2(xAudio2)
, _masteringVoice(nullptr)
{
CoInitialize(nullptr);
if (_xAudio2)
{
_xAudio2->AddRef();
}
}
e2d::Music::~Music() e2d::Music::~Music()
{ {
close(); close();
if (_masteringVoice)
{
_masteringVoice->DestroyVoice();
_masteringVoice = nullptr;
} }
bool e2d::Music::open(const e2d::String& filePath) SafeRelease(_xAudio2);
{
return open(Resource(filePath)); CoUninitialize();
} }
bool e2d::Music::open(const Resource& res) bool e2d::Music::open(const Resource& res)
{ {
if (_opened) if (_opened)
{ {
WARN("MusicInfo can be opened only once!"); close();
}
if (!_xAudio2)
{
if (FAILED(XAudio2Create(&_xAudio2, 0)))
{
TraceError(L"Create IXAudio2 error");
return false; return false;
} }
if (FAILED(_xAudio2->CreateMasteringVoice(&_masteringVoice)))
{
TraceError(L"Create IXAudio2MasteringVoice error");
return false;
}
}
if (!res.isFile()) if (!res.isFile())
{ {
HRSRC hResInfo; HRSRC hResInfo;
@ -167,13 +200,7 @@ bool e2d::Music::open(const Resource& res)
} }
// ´´½¨ÒôÔ´ // ´´½¨ÒôÔ´
HRESULT hr = Player::getInstance()->getXAudio2()->CreateSourceVoice( HRESULT hr = _xAudio2->CreateSourceVoice(&_voice, _wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO, &_voiceCallback);
&_voice,
_wfx,
0,
XAUDIO2_DEFAULT_FREQ_RATIO,
&this->_voiceCallback
);
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -191,13 +218,13 @@ bool e2d::Music::play(int nLoopCount)
{ {
if (!_opened) if (!_opened)
{ {
WARN("MusicInfo::play Failed: MusicInfo must be opened first!"); WARN("Music::play Failed: Music must be opened first!");
return false; return false;
} }
if (_voice == nullptr) if (_voice == nullptr)
{ {
WARN("MusicInfo::play Failed: IXAudio2SourceVoice Null pointer exception!"); WARN("Music::play Failed: IXAudio2SourceVoice Null pointer exception!");
return false; return false;
} }

View File

@ -1,14 +1,23 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
e2d::Player * e2d::Player::_instance = nullptr;
e2d::Player::Player() e2d::Player::Player()
: _volume(1.f) : _volume(1.f)
, _enabled(true)
, _xAudio2(nullptr) , _xAudio2(nullptr)
, _masteringVoice(nullptr) , _masteringVoice(nullptr)
{ {
CoInitialize(nullptr); CoInitialize(nullptr);
if (FAILED(XAudio2Create(&_xAudio2, 0)))
{
WARN("初始化 XAudio2 组件失败");
}
if (FAILED(_xAudio2->CreateMasteringVoice(&_masteringVoice)))
{
WARN("初始化 MasteringVoice 组件失败");
}
} }
e2d::Player::~Player() e2d::Player::~Player()
@ -22,48 +31,24 @@ e2d::Player::~Player()
} }
if (_masteringVoice) if (_masteringVoice)
{
_masteringVoice->DestroyVoice(); _masteringVoice->DestroyVoice();
_masteringVoice = nullptr;
}
SafeRelease(_xAudio2); SafeRelease(_xAudio2);
CoUninitialize(); CoUninitialize();
} }
e2d::Player * e2d::Player::getInstance()
{
if (!_instance)
{
_instance = new (std::nothrow) Player;
if (FAILED(XAudio2Create(&_instance->_xAudio2, 0)) ||
FAILED(_instance->_xAudio2->CreateMasteringVoice(&_instance->_masteringVoice)))
{
throw SystemException(L"³õʼ»¯ XAudio2 ×é¼þʧ°Ü");
}
}
return _instance;
}
void e2d::Player::destroyInstance()
{
if (_instance)
{
delete _instance;
_instance = nullptr;
}
}
IXAudio2 * e2d::Player::getXAudio2() IXAudio2 * e2d::Player::getXAudio2()
{ {
return _xAudio2; return _xAudio2;
} }
bool e2d::Player::preload(const String& filePath) IXAudio2MasteringVoice * e2d::Player::getMasteringVoice()
{ {
if (filePath.isEmpty()) return _masteringVoice;
return false;
return preload(Resource(filePath));
} }
bool e2d::Player::preload(const Resource& res) bool e2d::Player::preload(const Resource& res)
@ -71,9 +56,9 @@ bool e2d::Player::preload(const Resource& res)
if (_musicList.end() != _musicList.find(res)) if (_musicList.end() != _musicList.find(res))
return true; return true;
Music * music = new Music(); Music * music = new (std::nothrow) Music();
if (music->open(res)) if (music && music->open(res))
{ {
music->setVolume(_volume); music->setVolume(_volume);
_musicList.insert(std::make_pair(res, music)); _musicList.insert(std::make_pair(res, music));
@ -82,14 +67,6 @@ bool e2d::Player::preload(const Resource& res)
return false; return false;
} }
bool e2d::Player::play(const String& filePath, int nLoopCount)
{
if (filePath.isEmpty())
return false;
return play(Resource(filePath), nLoopCount);
}
bool e2d::Player::play(const Resource& res, int nLoopCount) bool e2d::Player::play(const Resource& res, int nLoopCount)
{ {
if (Player::preload(res)) if (Player::preload(res))
@ -103,56 +80,24 @@ bool e2d::Player::play(const Resource& res, int nLoopCount)
return false; return false;
} }
void e2d::Player::pause(const String& filePath)
{
if (filePath.isEmpty())
return;
pause(Resource(filePath));
}
void e2d::Player::pause(const Resource& res) void e2d::Player::pause(const Resource& res)
{ {
if (_musicList.end() != _musicList.find(res)) if (_musicList.end() != _musicList.find(res))
_musicList[res]->pause(); _musicList[res]->pause();
} }
void e2d::Player::resume(const String& filePath)
{
if (filePath.isEmpty())
return;
resume(Resource(filePath));
}
void e2d::Player::resume(const Resource& res) void e2d::Player::resume(const Resource& res)
{ {
if (_musicList.end() != _musicList.find(res)) if (_musicList.end() != _musicList.find(res))
_musicList[res]->pause(); _musicList[res]->pause();
} }
void e2d::Player::stop(const String& filePath)
{
if (filePath.isEmpty())
return;
stop(Resource(filePath));
}
void e2d::Player::stop(const Resource& res) void e2d::Player::stop(const Resource& res)
{ {
if (_musicList.end() != _musicList.find(res)) if (_musicList.end() != _musicList.find(res))
_musicList[res]->stop(); _musicList[res]->stop();
} }
bool e2d::Player::isPlaying(const String& filePath)
{
if (filePath.isEmpty())
return false;
return isPlaying(Resource(filePath));
}
bool e2d::Player::isPlaying(const Resource& res) bool e2d::Player::isPlaying(const Resource& res)
{ {
if (_musicList.end() != _musicList.find(res)) if (_musicList.end() != _musicList.find(res))
@ -198,6 +143,15 @@ void e2d::Player::stopAll()
} }
} }
void e2d::Player::setEnabled(bool enabled)
{
if (_enabled == enabled)
return;
_enabled = enabled;
_enabled ? _xAudio2->StartEngine() : _xAudio2->StopEngine();
}
void e2d::Player::clearCache() void e2d::Player::clearCache()
{ {
for (auto pair : _musicList) for (auto pair : _musicList)

View File

@ -36,12 +36,6 @@ public:
bool visible bool visible
); );
// 打开或关闭声音
// 默认:打开
void setSoundEnabled(
bool enabled
);
// 打开或关闭碰撞监听 // 打开或关闭碰撞监听
// 默认:关闭 // 默认:关闭
void setCollisionEnabled( void setCollisionEnabled(
@ -57,9 +51,6 @@ public:
// 获取游戏名称 // 获取游戏名称
String getGameName() const; String getGameName() const;
// 获取声音打开状态
bool isSoundEnabled() const;
// 获取 FPS 显示状态 // 获取 FPS 显示状态
bool isFpsShow() const; bool isFpsShow() const;
@ -74,7 +65,6 @@ public:
protected: protected:
bool _showFps; bool _showFps;
bool _soundEnabled;
bool _outlineVisible; bool _outlineVisible;
bool _collisionEnabled; bool _collisionEnabled;
bool _colliderVisible; bool _colliderVisible;

View File

@ -24,7 +24,10 @@ class VoiceCallback
: public IXAudio2VoiceCallback : public IXAudio2VoiceCallback
{ {
public: public:
VoiceCallback(Music * music); explicit VoiceCallback(
Music * music
);
~VoiceCallback(); ~VoiceCallback();
void __stdcall OnStreamEnd(); void __stdcall OnStreamEnd();

View File

@ -58,20 +58,15 @@ public:
Music(); Music();
explicit Music( explicit Music(
const e2d::String& filePath /* 音乐文件路径 */ const Resource& res /* 音乐资源 */
); );
explicit Music( explicit Music(
const Resource& res IXAudio2* xAudio2
); );
virtual ~Music(); virtual ~Music();
// 打开音乐文件
bool open(
const e2d::String& filePath /* 音乐文件路径 */
);
// 댔역稜있栗都 // 댔역稜있栗都
bool open( bool open(
const Resource& res const Resource& res
@ -142,7 +137,9 @@ protected:
MMCKINFO _ckRiff; MMCKINFO _ckRiff;
WAVEFORMATEX* _wfx; WAVEFORMATEX* _wfx;
VoiceCallback _voiceCallback; VoiceCallback _voiceCallback;
IXAudio2* _xAudio2;
IXAudio2SourceVoice* _voice; IXAudio2SourceVoice* _voice;
IXAudio2MasteringVoice* _masteringVoice;
}; };
@ -150,45 +147,11 @@ protected:
class Player class Player
{ {
friend class Game; friend class Game;
typedef std::map<Resource, Music*> MusicMap;
public: public:
// 获取播放器实例 Player();
static Player * getInstance();
// 销毁实例 ~Player();
static void destroyInstance();
// 预加载音乐资源
bool preload(
const String& filePath /* 音乐文件路径 */
);
// 播放音乐
bool play(
const String& filePath, /* 音乐文件路径 */
int nLoopCount = 0 /* 重复播放次数,设置 -1 为循环播放 */
);
// 暂停音乐
void pause(
const String& filePath /* 音乐文件路径 */
);
// 继续播放音乐
void resume(
const String& filePath /* 音乐文件路径 */
);
// 停止音乐
void stop(
const String& filePath /* 音乐文件路径 */
);
// 获取音乐播放状态
bool isPlaying(
const String& filePath /* 音乐文件路径 */
);
// 渡속潼稜있栗都 // 渡속潼稜있栗都
bool preload( bool preload(
@ -238,26 +201,26 @@ public:
// 界岺杰唐稜있 // 界岺杰唐稜있
void stopAll(); void stopAll();
// 打开或关闭播放器
void setEnabled(
bool enabled
);
// 헌왕稜있뻠닸 // 헌왕稜있뻠닸
void clearCache(); void clearCache();
// 获取 IXAudio2 对象 // 获取 XAudio2 实例对象
IXAudio2 * getXAudio2(); IXAudio2 * getXAudio2();
private: // 获取 MasteringVoice 实例对象
Player(); IXAudio2MasteringVoice* getMasteringVoice();
~Player();
E2D_DISABLE_COPY(Player);
private: private:
bool _enabled;
float _volume; float _volume;
MusicMap _musicList;
IXAudio2* _xAudio2; IXAudio2* _xAudio2;
IXAudio2MasteringVoice* _masteringVoice; IXAudio2MasteringVoice* _masteringVoice;
std::map<Resource, Music*> _musicList;
static Player * _instance;
}; };

View File

@ -22,7 +22,6 @@
#include "e2dbase.h" #include "e2dbase.h"
#include "e2dmanager.h" #include "e2dmanager.h"
#include "e2dnode.h" #include "e2dnode.h"
#include "e2dshape.h"
#include "e2dtool.h" #include "e2dtool.h"
#include "e2daction.h" #include "e2daction.h"
#include "e2dtransition.h" #include "e2dtransition.h"