增加SystemException,移除ASSERT
This commit is contained in:
		
							parent
							
								
									7499e1af7f
								
							
						
					
					
						commit
						6af90623fa
					
				|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  | 	if (animation) | ||||||
|  | 	{ | ||||||
| 		for (auto frame : _frames) | 		for (auto frame : _frames) | ||||||
| 		{ | 		{ | ||||||
| 			animation->add(frame); | 			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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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() | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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() | ||||||
|  |  | ||||||
|  | @ -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(); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ e2d::Scene::Scene() | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		throw Exception(L"场景根节点构造失败!"); | 		throw Exception(L"场景根节点构造失败"); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | #include "..\e2dcustom.h" | ||||||
|  | 
 | ||||||
|  | e2d::SystemException::SystemException() throw() | ||||||
|  | 	: Exception(L"未知的系统异常") | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | e2d::SystemException::SystemException(const String& message) throw() | ||||||
|  | 	: Exception(message) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @ -102,16 +102,24 @@ void e2d::ActionManager::start(Action * action, Node * target, bool paused) | ||||||
| 	WARN_IF(target == nullptr, "Target node NULL pointer exception!"); | 	WARN_IF(target == nullptr, "Target node NULL pointer exception!"); | ||||||
| 
 | 
 | ||||||
| 	if (action && target) | 	if (action && target) | ||||||
|  | 	{ | ||||||
|  | 		if (action->_target == nullptr) | ||||||
| 		{ | 		{ | ||||||
| 			auto iter = std::find(s_vRunningActions.begin(), s_vRunningActions.end(), action); | 			auto iter = std::find(s_vRunningActions.begin(), s_vRunningActions.end(), action); | ||||||
| 		ASSERT(iter == s_vRunningActions.end(), "Action has begun!"); | 			if (iter == s_vRunningActions.end()) | ||||||
| 
 | 			{ | ||||||
| 				action->_startWithTarget(target); | 				action->_startWithTarget(target); | ||||||
| 				action->retain(); | 				action->retain(); | ||||||
| 				action->_running = !paused; | 				action->_running = !paused; | ||||||
| 				s_vRunningActions.push_back(action); | 				s_vRunningActions.push_back(action); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			throw Exception(L"该 Action 已有执行目标"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void e2d::ActionManager::resume(const String& name) | void e2d::ActionManager::resume(const String& name) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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,16 +769,8 @@ void e2d::Node::clearAllChildren() | ||||||
| 
 | 
 | ||||||
| void e2d::Node::runAction(Action * action) | void e2d::Node::runAction(Action * action) | ||||||
| { | { | ||||||
| 	if (this != action->getTarget()) |  | ||||||
| 	{ |  | ||||||
| 		ASSERT(action->getTarget() == nullptr, "The action has already got a target!"); |  | ||||||
| 	ActionManager::start(action, this, false); | 	ActionManager::start(action, this, false); | ||||||
| } | } | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		action->reset(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void e2d::Node::resumeAction(const String& name) | void e2d::Node::resumeAction(const String& name) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -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 }; | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ public: | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	// 启动游戏
 | 	// 启动游戏
 | ||||||
| 	static int start( | 	static void start( | ||||||
| 		bool autoRelease = true			/* 游戏结束时自动回收资源 */ | 		bool autoRelease = true			/* 游戏结束时自动回收资源 */ | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | @ -61,14 +61,15 @@ 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) | ||||||
|  |  | ||||||
|  | @ -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" /> | ||||||
|  |  | ||||||
|  | @ -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" /> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue