增加SystemException,移除ASSERT

This commit is contained in:
Nomango 2018-05-24 12:24:39 +08:00
parent 7499e1af7f
commit 6af90623fa
25 changed files with 228 additions and 141 deletions

View File

@ -107,22 +107,7 @@ e2d::Animate * e2d::Animate::reverse() const
{ {
if (_animation) if (_animation)
{ {
auto& oldFrames = _animation->getFrames(); auto animation = _animation->reverse();
std::vector<Image*> frames(oldFrames.size());
if (!oldFrames.empty())
{
for (auto iter = oldFrames.crbegin(), iterCrend = oldFrames.crend(); iter != iterCrend; ++iter)
{
Image* frame = *iter;
if (frame)
{
frames.push_back(frame);
}
}
}
auto animation = GC::create<Animation>(_animation->getInterval(), frames);
if (animation) if (animation)
{ {
return GC::create<Animate>(animation); return GC::create<Animate>(animation);

View File

@ -69,9 +69,35 @@ const std::vector<e2d::Image*>& e2d::Animation::getFrames() const
e2d::Animation * e2d::Animation::clone() const e2d::Animation * e2d::Animation::clone() const
{ {
auto animation = GC::create<Animation>(_interval); auto animation = GC::create<Animation>(_interval);
for (auto frame : _frames) if (animation)
{ {
animation->add(frame); for (auto frame : _frames)
{
animation->add(frame);
}
} }
return animation; return animation;
} }
e2d::Animation * e2d::Animation::reverse() const
{
auto& oldFrames = this->getFrames();
std::vector<Image*> frames(oldFrames.size());
if (!oldFrames.empty())
{
for (auto iter = oldFrames.crbegin(),
iterCrend = oldFrames.crend();
iter != iterCrend;
++iter)
{
Image* frame = *iter;
if (frame)
{
frames.push_back(frame);
}
}
}
return GC::create<Animation>(this->getInterval(), frames);
}

View File

@ -6,7 +6,7 @@ e2d::Loop::Loop(Action * action, int times /* = -1 */)
, _times(0) , _times(0)
, _totalTimes(times) , _totalTimes(times)
{ {
ASSERT(action, "Loop NULL pointer exception!"); WARN_IF(action == nullptr, "Loop NULL pointer exception!");
if (action) if (action)
{ {
@ -33,7 +33,14 @@ e2d::Loop * e2d::Loop::clone() const
e2d::Loop * e2d::Loop::reverse() const e2d::Loop * e2d::Loop::reverse() const
{ {
return GC::create<Loop>(_action); if (_action)
{
return GC::create<Loop>(_action->clone());
}
else
{
return nullptr;
}
} }
void e2d::Loop::_init() void e2d::Loop::_init()

View File

@ -111,7 +111,7 @@ e2d::Sequence * e2d::Sequence::clone() const
e2d::Sequence * e2d::Sequence::reverse() const e2d::Sequence * e2d::Sequence::reverse() const
{ {
auto sequence = GC::create<Sequence>(); auto sequence = GC::create<Sequence>();
if (!_actions.empty()) if (sequence && !_actions.empty())
{ {
std::vector<Action*> newActions(_actions.size()); std::vector<Action*> newActions(_actions.size());
for (auto iter = _actions.crbegin(), iterCrend = _actions.crend(); iter != iterCrend; ++iter) for (auto iter = _actions.crbegin(), iterCrend = _actions.crend(); iter != iterCrend; ++iter)

View File

@ -109,7 +109,7 @@ e2d::Spawn * e2d::Spawn::clone() const
e2d::Spawn * e2d::Spawn::reverse() const e2d::Spawn * e2d::Spawn::reverse() const
{ {
auto spawn = GC::create<Spawn>(); auto spawn = GC::create<Spawn>();
if (!_actions.empty()) if (spawn && !_actions.empty())
{ {
std::vector<Action*> newActions(_actions.size()); std::vector<Action*> newActions(_actions.size());
for (auto iter = _actions.crbegin(), iterCrend = _actions.crend(); iter != iterCrend; ++iter) for (auto iter = _actions.crbegin(), iterCrend = _actions.crend(); iter != iterCrend; ++iter)

View File

@ -18,7 +18,7 @@ bool e2d::Game::init(const String& name, const String& mutexName)
{ {
if (s_bInitialized) if (s_bInitialized)
{ {
WARN_IF(true, "The game has been initialized!"); WARN("The game has been initialized!");
return false; return false;
} }
@ -29,7 +29,7 @@ bool e2d::Game::init(const String& name, const String& mutexName)
if (hMutex == nullptr) if (hMutex == nullptr)
{ {
WARN_IF(true, "CreateMutex Failed!"); WARN("CreateMutex Failed!");
} }
else if (::GetLastError() == ERROR_ALREADY_EXISTS) else if (::GetLastError() == ERROR_ALREADY_EXISTS)
{ {
@ -44,39 +44,74 @@ bool e2d::Game::init(const String& name, const String& mutexName)
// 初始化 COM 组件 // 初始化 COM 组件
CoInitialize(nullptr); CoInitialize(nullptr);
// ´´½¨É豸ÎÞ¹Ø×ÊÔ´ bool bRendererDevIndResInit = false,
if (!Renderer::__createDeviceIndependentResources()) bWindowInit = false,
bRendererDevResInit = false,
bInputInit = false,
bMusicInit = false;
auto DestroyResources = [&]()
{ {
WARN_IF(true, "Renderer::__createDeviceIndependentResources Failed!"); if (bRendererDevIndResInit) Renderer::__discardResources();
goto dev_ind_res_fail; if (bWindowInit) Window::__init();
if (bRendererDevResInit) Renderer::__discardDeviceResources();
if (bInputInit) Input::__uninit();
if (bMusicInit) Music::__uninit();
};
// 创建设备无关资源
if (Renderer::__createDeviceIndependentResources())
{
bRendererDevIndResInit = true;
}
else
{
DestroyResources();
throw SystemException(L"渲染器设备无关资源创建失败");
} }
// 初始化窗口 // 初始化窗口
if (!Window::__init()) if (Window::__init())
{ {
WARN_IF(true, "Window::__init Failed!"); bWindowInit = true;
goto window_fail; }
else
{
DestroyResources();
throw SystemException(L"初始化窗口失败");
} }
// 创建设备相关资源 // 创建设备相关资源
if (!Renderer::__createDeviceResources()) if (Renderer::__createDeviceResources())
{ {
WARN_IF(true, "Renderer::__createDeviceResources Failed!"); bRendererDevResInit = true;
goto dev_res_fail; }
else
{
DestroyResources();
throw SystemException(L"渲染器设备相关资源创建失败");
} }
// 初始化 DirectInput // 初始化 DirectInput
if (!Input::__init()) if (Input::__init())
{ {
WARN_IF(true, "Input::__init Failed!"); bInputInit = true;
goto input_fail; }
else
{
DestroyResources();
throw SystemException(L"初始化 DirectInput 失败");
} }
// 初始化播放器 // 初始化播放器
if (!Music::__init()) if (Music::__init())
{ {
WARN_IF(true, "Music::__init Failed!"); bMusicInit = true;
Music::__uninit(); }
else
{
DestroyResources();
throw SystemException(L"初始化 XAudio2 失败");
} }
// 保存游戏名称 // 保存游戏名称
@ -85,35 +120,20 @@ bool e2d::Game::init(const String& name, const String& mutexName)
// 初始化路径 // 初始化路径
if (!Path::__init()) if (!Path::__init())
{ {
WARN_IF(true, "Path::__init Failed!"); WARN("Path::__init failed!");
} }
// 初始化成功 // 初始化成功
s_bInitialized = true; s_bInitialized = true;
goto succeeded;
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;
} }
int e2d::Game::start(bool autoRelease/* true */) void e2d::Game::start(bool autoRelease/* true */)
{ {
if (!s_bInitialized) if (!s_bInitialized)
{ {
ASSERT(false, "You must initialize Game first!"); throw Exception(L"开始游戏前未进行初始化");
return -1;
} }
// 初始化场景管理器 // 初始化场景管理器
@ -162,8 +182,6 @@ int e2d::Game::start(bool autoRelease/* true */)
{ {
Game::destroy(); Game::destroy();
} }
return 0;
} }
void e2d::Game::pause() void e2d::Game::pause()

View File

@ -23,9 +23,11 @@ bool e2d::Renderer::__createDeviceIndependentResources()
&s_pDirect2dFactory &s_pDirect2dFactory
); );
ASSERT(SUCCEEDED(hr), "Create ID2D1Factory Failed!"); if (FAILED(hr))
{
if (SUCCEEDED(hr)) throw SystemException(L"Create ID2D1Factory failed");
}
else
{ {
// 创建 WIC 绘图工厂,用于统一处理各种格式的图片 // 创建 WIC 绘图工厂,用于统一处理各种格式的图片
hr = CoCreateInstance( hr = CoCreateInstance(
@ -35,10 +37,13 @@ bool e2d::Renderer::__createDeviceIndependentResources()
IID_IWICImagingFactory, IID_IWICImagingFactory,
reinterpret_cast<void**>(&s_pIWICFactory) reinterpret_cast<void**>(&s_pIWICFactory)
); );
ASSERT(SUCCEEDED(hr), "Create IWICImagingFactory Failed!");
} }
if (SUCCEEDED(hr)) if (FAILED(hr))
{
throw SystemException(L"Create IWICImagingFactory failed");
}
else
{ {
// 创建 DirectWrite 工厂 // 创建 DirectWrite 工厂
hr = DWriteCreateFactory( hr = DWriteCreateFactory(
@ -46,17 +51,17 @@ bool e2d::Renderer::__createDeviceIndependentResources()
__uuidof(IDWriteFactory), __uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&s_pDWriteFactory) reinterpret_cast<IUnknown**>(&s_pDWriteFactory)
); );
ASSERT(SUCCEEDED(hr), "Create IDWriteFactory Failed!");
} }
if (SUCCEEDED(hr)) if (FAILED(hr))
{
throw SystemException(L"Create IDWriteFactory failed");
}
else
{ {
// 工厂将返回当前的系统 DPI这个值也将用来创建窗口 // 工厂将返回当前的系统 DPI这个值也将用来创建窗口
Renderer::getID2D1Factory()->GetDesktopDpi(&s_fDpiScaleX, &s_fDpiScaleY); Renderer::getID2D1Factory()->GetDesktopDpi(&s_fDpiScaleX, &s_fDpiScaleY);
}
if (SUCCEEDED(hr))
{
// 创建文本格式化对象 // 创建文本格式化对象
hr = s_pDWriteFactory->CreateTextFormat( hr = s_pDWriteFactory->CreateTextFormat(
L"", L"",
@ -105,19 +110,24 @@ bool e2d::Renderer::__createDeviceResources()
&s_pRenderTarget &s_pRenderTarget
); );
ASSERT(SUCCEEDED(hr), "Create ID2D1HwndRenderTarget Failed!"); if (FAILED(hr))
{
if (SUCCEEDED(hr)) throw SystemException(L"Create ID2D1HwndRenderTarget failed");
}
else
{ {
// 创建画刷 // 创建画刷
hr = s_pRenderTarget->CreateSolidColorBrush( hr = s_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White), D2D1::ColorF(D2D1::ColorF::White),
&s_pSolidBrush &s_pSolidBrush
); );
ASSERT(SUCCEEDED(hr), "Create ID2D1SolidColorBrush Failed!");
} }
if (SUCCEEDED(hr)) if (FAILED(hr))
{
throw SystemException(L"Create ID2D1SolidColorBrush failed");
}
else
{ {
// 创建自定义的文字渲染器 // 创建自定义的文字渲染器
s_pTextRenderer = new (std::nothrow) TextRenderer( s_pTextRenderer = new (std::nothrow) TextRenderer(
@ -165,7 +175,7 @@ void e2d::Renderer::__render()
SceneManager::__render(); SceneManager::__render();
// 渲染 FPS // 渲染 FPS
if (s_bShowFps) if (s_bShowFps && s_pTextFormat)
{ {
static int s_nRenderTimes = 0; static int s_nRenderTimes = 0;
static double s_fLastRenderTime = 0; static double s_fLastRenderTime = 0;
@ -223,8 +233,7 @@ void e2d::Renderer::__render()
if (FAILED(hr)) if (FAILED(hr))
{ {
Window::error(L"Device loss recovery failed. Exiting game."); throw SystemException(L"Device loss recovery failed");
Game::quit();
} }
} }

View File

@ -56,7 +56,7 @@ bool e2d::Image::open(const String& filePath)
if (!Image::preload(filePath)) if (!Image::preload(filePath))
{ {
WARN_IF(true, "Load Image from file failed!"); WARN("Load Image from file failed!");
return false; return false;
} }
@ -68,7 +68,7 @@ bool e2d::Image::open(int resNameId, const String& resType)
{ {
if (!Image::preload(resNameId, resType)) if (!Image::preload(resNameId, resType))
{ {
WARN_IF(true, "Load Image from file failed!"); WARN("Load Image from file failed!");
return false; return false;
} }

View File

@ -15,7 +15,7 @@ e2d::Scene::Scene()
} }
else else
{ {
throw Exception(L"场景根节点构造失败"); throw Exception(L"场景根节点构造失败");
} }
} }

View File

@ -1,22 +1,22 @@
#include "..\e2dcustom.h" #include "..\e2dcustom.h"
e2d::Exception::Exception() e2d::Exception::Exception() throw()
: _message() : _message()
{ {
} }
e2d::Exception::Exception(String message) e2d::Exception::Exception(const String& message) throw()
: _message(message) : _message(message)
{ {
} }
e2d::Exception::Exception(Exception const& other) e2d::Exception::Exception(Exception const& other) throw()
: _message(other._message) : _message(other._message)
{ {
} }
e2d::Exception& e2d::Exception::operator=(Exception const& other) e2d::Exception& e2d::Exception::operator=(Exception const& other) throw()
{ {
if (this == &other) if (this == &other)
{ {
@ -27,7 +27,7 @@ e2d::Exception& e2d::Exception::operator=(Exception const& other)
return *this; return *this;
} }
e2d::Exception::~Exception() e2d::Exception::~Exception() throw()
{ {
} }

View File

@ -0,0 +1,12 @@
#include "..\e2dcustom.h"
e2d::SystemException::SystemException() throw()
: Exception(L"未知的系统异常")
{
}
e2d::SystemException::SystemException(const String& message) throw()
: Exception(message)
{
}

View File

@ -103,13 +103,21 @@ void e2d::ActionManager::start(Action * action, Node * target, bool paused)
if (action && target) if (action && target)
{ {
auto iter = std::find(s_vRunningActions.begin(), s_vRunningActions.end(), action); if (action->_target == nullptr)
ASSERT(iter == s_vRunningActions.end(), "Action has begun!"); {
auto iter = std::find(s_vRunningActions.begin(), s_vRunningActions.end(), action);
action->_startWithTarget(target); if (iter == s_vRunningActions.end())
action->retain(); {
action->_running = !paused; action->_startWithTarget(target);
s_vRunningActions.push_back(action); action->retain();
action->_running = !paused;
s_vRunningActions.push_back(action);
}
}
else
{
throw Exception(L"该 Action 已有执行目标");
}
} }
} }

View File

@ -56,7 +56,7 @@ void e2d::ColliderManager::__addCollider(Collider * pCollider)
{ {
if (pCollider->_parentNode) if (pCollider->_parentNode)
{ {
WARN_IF(true, "ColliderManager::__add Failed! The shape is already added."); WARN("ColliderManager::__add Failed! The shape is already added.");
return; return;
} }
pCollider->retain(); pCollider->retain();

View File

@ -10,11 +10,14 @@ static std::stack<e2d::Scene*> s_SceneStack;
void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullptr */, bool saveCurrentScene /* = true */) void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullptr */, bool saveCurrentScene /* = true */)
{ {
ASSERT(scene, "Next scene NULL pointer exception!"); if (scene == nullptr)
scene->retain(); {
throw Exception(L"³¡¾°¿ÕÖ¸ÕëÒì³£");
}
// 保存下一场景的指针 // 保存下一场景的指针
s_pNextScene = scene; s_pNextScene = scene;
s_pNextScene->retain();
// 设置切换场景动作 // 设置切换场景动作
if (transition) if (transition)

View File

@ -598,14 +598,14 @@ void e2d::Node::addChild(Node * child, int order /* = 0 */)
{ {
if (child->_parent != nullptr) if (child->_parent != nullptr)
{ {
throw Exception(L"节点已有父节点, 不能再添加到其他节点"); throw Exception(L"节点已有父节点, 不能再添加到其他节点");
} }
for (Node * parent = this; parent != nullptr; parent = parent->getParent()) for (Node * parent = this; parent != nullptr; parent = parent->getParent())
{ {
if (child == parent) if (child == parent)
{ {
throw Exception(L"一个节点不能同时是另一个节点的父节点和子节点"); throw Exception(L"一个节点不能同时是另一个节点的父节点和子节点");
} }
} }
@ -769,15 +769,7 @@ void e2d::Node::clearAllChildren()
void e2d::Node::runAction(Action * action) void e2d::Node::runAction(Action * action)
{ {
if (this != action->getTarget()) ActionManager::start(action, this, false);
{
ASSERT(action->getTarget() == nullptr, "The action has already got a target!");
ActionManager::start(action, this, false);
}
else
{
action->reset();
}
} }
void e2d::Node::resumeAction(const String& name) void e2d::Node::resumeAction(const String& name)

View File

@ -331,9 +331,13 @@ void e2d::Text::_createFormat()
&_textFormat &_textFormat
); );
ASSERT(SUCCEEDED(hr), "Create IDWriteTextFormat Failed!"); if (FAILED(hr))
{
if (_textFormat) WARN("Text::_createFormat error : Create IDWriteTextFormat failed!");
_textFormat = nullptr;
return;
}
else
{ {
// 设置文字对齐方式 // 设置文字对齐方式
_textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(_style.alignment)); _textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(_style.alignment));
@ -375,7 +379,7 @@ void e2d::Text::_createLayout()
if (_textFormat == nullptr) if (_textFormat == nullptr)
{ {
WARN_IF(true, "Text::_createLayout failed! _textFormat NULL pointer exception."); WARN("Text::_createLayout failed! _textFormat NULL pointer exception.");
return; return;
} }
@ -420,7 +424,12 @@ void e2d::Text::_createLayout()
} }
} }
ASSERT(SUCCEEDED(hr), "Create IDWriteTextFormat Failed!"); if (FAILED(hr))
{
WARN("Text::_createLayout error : Create IDWriteTextLayout failed!");
_textLayout = nullptr;
return;
}
// 添加下划线和删除线 // 添加下划线和删除线
DWRITE_TEXT_RANGE range = { 0, length }; DWRITE_TEXT_RANGE range = { 0, length };

View File

@ -10,13 +10,13 @@
inline bool TraceError(wchar_t* sPrompt) inline bool TraceError(wchar_t* sPrompt)
{ {
WARN_IF(true, "MusicInfo error: %s failed!", sPrompt); WARN("MusicInfo error: %s failed!", sPrompt);
return false; return false;
} }
inline bool TraceError(wchar_t* sPrompt, HRESULT hr) inline bool TraceError(wchar_t* sPrompt, HRESULT hr)
{ {
WARN_IF(true, "MusicInfo error: %s (%#X)", sPrompt, hr); WARN("MusicInfo error: %s (%#X)", sPrompt, hr);
return false; return false;
} }
@ -75,19 +75,19 @@ bool e2d::Music::open(const e2d::String& filePath)
{ {
if (_opened) if (_opened)
{ {
WARN_IF(true, "MusicInfo can be opened only once!"); WARN("MusicInfo can be opened only once!");
return false; return false;
} }
if (filePath.isEmpty()) if (filePath.isEmpty())
{ {
WARN_IF(true, "MusicInfo::open Invalid file name."); WARN("MusicInfo::open Invalid file name.");
return false; return false;
} }
if (!s_pXAudio2) if (!s_pXAudio2)
{ {
WARN_IF(true, "IXAudio2 nullptr pointer error!"); WARN("IXAudio2 nullptr pointer error!");
return false; return false;
} }
@ -95,7 +95,7 @@ bool e2d::Music::open(const e2d::String& filePath)
wchar_t pFilePath[MAX_PATH]; wchar_t pFilePath[MAX_PATH];
if (!_findMediaFileCch(pFilePath, MAX_PATH, filePath)) if (!_findMediaFileCch(pFilePath, MAX_PATH, filePath))
{ {
WARN_IF(true, "Failed to find media file: %s", pFilePath); WARN("Failed to find media file: %s", pFilePath);
return false; return false;
} }
@ -152,13 +152,13 @@ bool e2d::Music::open(int resNameId, const e2d::String& resType)
if (_opened) if (_opened)
{ {
WARN_IF(true, "MusicInfo can be opened only once!"); WARN("MusicInfo can be opened only once!");
return false; return false;
} }
if (!s_pXAudio2) if (!s_pXAudio2)
{ {
WARN_IF(true, "IXAudio2 nullptr pointer error!"); WARN("IXAudio2 nullptr pointer error!");
return false; return false;
} }
@ -226,13 +226,13 @@ bool e2d::Music::play(int nLoopCount)
{ {
if (!_opened) if (!_opened)
{ {
WARN_IF(true, "MusicInfo::play Failed: MusicInfo must be opened first!"); WARN("MusicInfo::play Failed: MusicInfo must be opened first!");
return false; return false;
} }
if (_voice == nullptr) if (_voice == nullptr)
{ {
WARN_IF(true, "MusicInfo::play Failed: IXAudio2SourceVoice Null pointer exception!"); WARN("MusicInfo::play Failed: IXAudio2SourceVoice Null pointer exception!");
return false; return false;
} }
@ -584,13 +584,13 @@ bool e2d::Music::__init()
if (FAILED(hr = XAudio2Create(&s_pXAudio2, 0))) if (FAILED(hr = XAudio2Create(&s_pXAudio2, 0)))
{ {
WARN_IF(true, "Failed to init XAudio2 engine"); WARN("Failed to init XAudio2 engine");
return false; return false;
} }
if (FAILED(hr = s_pXAudio2->CreateMasteringVoice(&s_pMasteringVoice))) if (FAILED(hr = s_pXAudio2->CreateMasteringVoice(&s_pMasteringVoice)))
{ {
WARN_IF(true, "Failed creating mastering voice"); WARN("Failed creating mastering voice");
e2d::SafeRelease(s_pXAudio2); e2d::SafeRelease(s_pXAudio2);
return false; return false;
} }

View File

@ -30,7 +30,7 @@ bool e2d::Path::__init()
} }
else else
{ {
WARN_IF(true, "Cannot get local AppData path!"); WARN("Cannot get local AppData path!");
} }
// »ñÈ¡ÓÎÏ·Ãû³Æ // »ñÈ¡ÓÎÏ·Ãû³Æ
@ -173,7 +173,7 @@ bool e2d::Path::createFolder(const String& dirPath)
{ {
if (dirPath.isEmpty()) if (dirPath.isEmpty())
{ {
WARN_IF(true, "Path::createFolder Failed: Invalid directory path!"); WARN("Path::createFolder Failed: Invalid directory path!");
return false; return false;
} }

View File

@ -45,7 +45,7 @@ void e2d::Transition::_init(Scene * prev, Scene * next)
if (FAILED(hr)) if (FAILED(hr))
{ {
ASSERT(false, "Create layer failed!"); throw SystemException(L"场景过渡动画图层创建失败");
} }
_last = Time::getTotalTime(); _last = Time::getTotalTime();

View File

@ -164,7 +164,7 @@ public:
// 获取该动作的倒转 // 获取该动作的倒转
virtual MoveTo * reverse() const override virtual MoveTo * reverse() const override
{ {
ASSERT(false, "reverse() not supported in MoveTo"); WARN("reverse() not supported in MoveTo");
return nullptr; return nullptr;
} }
@ -229,7 +229,7 @@ public:
// 获取该动作的倒转 // 获取该动作的倒转
virtual JumpTo * reverse() const override virtual JumpTo * reverse() const override
{ {
ASSERT(false, "reverse() not supported in JumpTo"); WARN("reverse() not supported in JumpTo");
return nullptr; return nullptr;
} }
@ -301,7 +301,7 @@ public:
// 获取该动作的倒转 // 获取该动作的倒转
virtual ScaleTo * reverse() const override virtual ScaleTo * reverse() const override
{ {
ASSERT(false, "reverse() not supported in ScaleTo"); WARN("reverse() not supported in ScaleTo");
return nullptr; return nullptr;
} }
@ -360,7 +360,7 @@ public:
// 获取该动作的倒转 // 获取该动作的倒转
virtual OpacityTo * reverse() const override virtual OpacityTo * reverse() const override
{ {
ASSERT(false, "reverse() not supported in OpacityTo"); WARN("reverse() not supported in OpacityTo");
return nullptr; return nullptr;
} }
@ -448,7 +448,7 @@ public:
// 获取该动作的倒转 // 获取该动作的倒转
virtual RotateTo * reverse() const override virtual RotateTo * reverse() const override
{ {
ASSERT(false, "reverse() not supported in RotateTo"); WARN("reverse() not supported in RotateTo");
return nullptr; return nullptr;
} }
@ -707,8 +707,11 @@ public:
double interval /* 帧间隔(秒) */ double interval /* 帧间隔(秒) */
); );
// 获取动画的拷贝对象 // 获取帧动画的拷贝对象
virtual Animation * clone() const; Animation * clone() const;
// 获取帧动画的倒转
Animation * reverse() const;
// 销毁对象 // 销毁对象
virtual void onDestroy() override; virtual void onDestroy() override;

View File

@ -21,7 +21,7 @@ public:
); );
// 启动游戏 // 启动游戏
static int start( static void start(
bool autoRelease = true /* 游戏结束时自动回收资源 */ bool autoRelease = true /* 游戏结束时自动回收资源 */
); );

View File

@ -164,10 +164,9 @@ private:
class Exception class Exception
{ {
public: public:
Exception() throw(); Exception() throw();
explicit Exception(String message) throw(); explicit Exception(const String& message) throw();
Exception(Exception const& other) throw(); Exception(Exception const& other) throw();
@ -182,4 +181,15 @@ private:
String _message; String _message;
}; };
// 系统异常
class SystemException
: public Exception
{
public:
SystemException() throw();
explicit SystemException(const String& message) throw();
};
} }

View File

@ -61,17 +61,18 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#endif #endif
#ifndef ASSERT #ifndef WARN
#if defined( DEBUG ) || defined( _DEBUG ) #if defined( DEBUG ) || defined( _DEBUG )
#define ASSERT(expression, message, ...) do {if (!(expression)) { fwprintf(stderr, L"Assert: " _CRT_WIDE(#message) L"\n", __VA_ARGS__); abort(); }} while(0) #define WARN(message, ...) do { fwprintf(stderr, L"Warning: " _CRT_WIDE(#message) L"\n", __VA_ARGS__); } while(0)
#else #else
#define ASSERT(expression, message, ...) ((void)0) #define WARN(message, ...) ((void)0)
#endif #endif
#endif #endif
#ifndef WARN_IF #ifndef WARN_IF
#if defined( DEBUG ) || defined( _DEBUG ) #if defined( DEBUG ) || defined( _DEBUG )
#define WARN_IF(expression, message, ...) do {if (expression) { fwprintf(stderr, L"Warning: " _CRT_WIDE(#message) L"\n", __VA_ARGS__); }} while(0) #define WARN_IF(expression, message, ...) do { if (expression) { fwprintf(stderr, L"Warning: " _CRT_WIDE(#message) L"\n", __VA_ARGS__); } } while(0)
#else #else
#define WARN_IF(expression, message, ...) ((void)0) #define WARN_IF(expression, message, ...) ((void)0)
#endif #endif

View File

@ -237,6 +237,7 @@
<ClCompile Include="..\..\core\Common\String.cpp" /> <ClCompile Include="..\..\core\Common\String.cpp" />
<ClCompile Include="..\..\core\Common\Image.cpp" /> <ClCompile Include="..\..\core\Common\Image.cpp" />
<ClCompile Include="..\..\core\Custom\Exception.cpp" /> <ClCompile Include="..\..\core\Custom\Exception.cpp" />
<ClCompile Include="..\..\core\Custom\SystemException.cpp" />
<ClCompile Include="..\..\core\Custom\TextRenderer.cpp" /> <ClCompile Include="..\..\core\Custom\TextRenderer.cpp" />
<ClCompile Include="..\..\core\Custom\VoiceCallback.cpp" /> <ClCompile Include="..\..\core\Custom\VoiceCallback.cpp" />
<ClCompile Include="..\..\core\Manager\ActionManager.cpp" /> <ClCompile Include="..\..\core\Manager\ActionManager.cpp" />

View File

@ -240,6 +240,9 @@
<ClCompile Include="..\..\core\Custom\Exception.cpp"> <ClCompile Include="..\..\core\Custom\Exception.cpp">
<Filter>Custom</Filter> <Filter>Custom</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Custom\SystemException.cpp">
<Filter>Custom</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\core\easy2d.h" /> <ClInclude Include="..\..\core\easy2d.h" />