From ef85e2b88d7529e3801856357263d46a87a1d30d Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Mon, 11 Dec 2017 18:17:24 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=81=9A=E4=BA=86EString=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/main.cpp | 146 +++++++----- Demo/test.png | Bin 21833 -> 18230 bytes Demo/test2.png | Bin 0 -> 21833 bytes Easy2D/Action/EActionMoveBy.cpp | 10 +- Easy2D/Action/EActionMoveTo.cpp | 2 +- Easy2D/Base/EApp.cpp | 6 +- Easy2D/Base/EScene.cpp | 2 +- Easy2D/Common/EFont.cpp | 6 +- Easy2D/Common/EString.cpp | 350 +++++++++++++++++++++++++++++ Easy2D/Common/ETexture.cpp | 21 +- Easy2D/Easy2D.vcxproj | 2 +- Easy2D/Easy2D.vcxproj.filters | 4 +- Easy2D/Manager/EActionManager.cpp | 2 +- Easy2D/Manager/EMsgManager.cpp | 12 +- Easy2D/Manager/EObjectManager.cpp | 4 +- Easy2D/Manager/EPhysicsManager.cpp | 8 +- Easy2D/Manager/ETimerManager.cpp | 4 +- Easy2D/Node/ENode.cpp | 19 +- Easy2D/Node/EText.cpp | 8 +- Easy2D/Tool/EFileUtils.cpp | 53 +++-- Easy2D/Tool/EMusicUtils.cpp | 20 +- Easy2D/Win/MciPlayer.cpp | 12 +- Easy2D/eactions.h | 4 +- Easy2D/easy2d.h | 6 +- Easy2D/ebase.h | 2 +- Easy2D/ecommon.h | 276 ++++++++++++++++++++++- Easy2D/emacros.h | 2 - Easy2D/enodes.h | 6 +- Easy2D/etypedef.h | 169 -------------- 29 files changed, 814 insertions(+), 342 deletions(-) create mode 100644 Demo/test2.png create mode 100644 Easy2D/Common/EString.cpp delete mode 100644 Easy2D/etypedef.h diff --git a/Demo/main.cpp b/Demo/main.cpp index e88e2fdf..05e86578 100644 --- a/Demo/main.cpp +++ b/Demo/main.cpp @@ -1,5 +1,5 @@ #include "..\Easy2D\easy2d.h" - +#include int WINAPI WinMain( HINSTANCE hInstance, @@ -8,69 +8,109 @@ int WINAPI WinMain( int nCmdShow ) { - if (!EApp::init(L"Easy2D Demo", 640, 480)) + if (!EApp::init(L"Demo", 250, 150)) return -1; + EString str; + str += L"123"; + str += L"4"; + UINT h1 = str.hash(); + + EString s = L"abcdea"; + EString ss = s.sub(0); + EString sss = s.sub(0, 5); + EString ssss = s.sub(0, 9); + EString ssssss = s.sub(1, 4); + EString sssss = s.sub(-1, 3); + int i = s.findFirstOf(L'a'); + int j = s.findLastOf(L'a'); + + EString string = L"Hello"; + string = string + 2017 + L"!"; + + EString str2; + str2 += 1; + str2 += 2L; + str2 += 2.3; + str2 += 4.6f; + UINT h2 = str2.hash(); + + str2 += std::wstring(L"sdf"); + EString str3; + str3 += str2 + str; + UINT h3 = str3.hash(); + auto scene = new EScene(); - scene->retain(); + EApp::enterScene(scene); - auto text = new EText(L"中文测试中文测试中文测试中文测试中文测试中文测试中文测试", L"楷体"); - text->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); - //text->setWordWrapping(true); - //text->setWordWrappingWidth(130); - text->setRotation(40); - text->runAction(new EActionLoop(new EActionTwo(new EActionFadeOut(1), new EActionFadeIn(1)))); - scene->add(text); + for (int i = 0; i < 25; i++) + { + auto sprite = new ESprite(L"test.png"); + sprite->setScale(0.5f); + sprite->setPos(ERandom::between(0, EApp::getWidth()), ERandom::between(0, EApp::getHeight())); + scene->add(sprite); + } - auto listener = new EListenerKeyboardPress([=]() { - if (EKeyboardMsg::getKeyValue() == EKeyboardMsg::KEY::SPACE) - { - EApp::backScene(new ETransitionMove(0.5f, ETransitionMove::DOWN)); - } - }); - listener->bindWith(scene); + //auto scene = new EScene(); + //scene->retain(); - auto scene2 = new EScene(); + //auto text = new EText(L"中文测试中文测试中文测试中文测试中文测试中文测试中文测试", L"楷体"); + //text->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); + ////text->setWordWrapping(true); + ////text->setWordWrappingWidth(130); + //text->setRotation(40); + //text->runAction(new EActionLoop(new EActionTwo(new EActionFadeOut(1), new EActionFadeIn(1)))); + //scene->add(text); - auto bird = new ESprite(L"atlas.png", 5, 982, 34, 24); - auto animation = new EAnimation(); - animation->addFrame(new ESpriteFrame(L"atlas.png", 5, 982, 34, 24)); - animation->addFrame(new ESpriteFrame(L"atlas.png", 61, 982, 34, 24)); - animation->addFrame(new ESpriteFrame(L"atlas.png", 117, 982, 34, 24)); - animation->addFrame(new ESpriteFrame(L"atlas.png", 61, 982, 34, 24)); - bird->runAction(new EActionLoop(animation)); - bird->setPivot(0.5f, 0.5f); - bird->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); - scene2->add(bird); + //auto listener = new EListenerKeyboardPress([=]() { + // if (EKeyboardMsg::getKeyValue() == EKeyboardMsg::KEY::SPACE) + // { + // EApp::backScene(new ETransitionMove(0.5f, ETransitionMove::DOWN)); + // } + //}); + //listener->bindWith(scene); - auto btnStart = new ESprite(L"atlas.png", 702, 234, 116, 70); - auto btnStartSelected = new ESprite(L"atlas.png", 702, 234, 116, 70); - btnStartSelected->setPosY(5); - auto button = new EButton(btnStart, btnStartSelected, [=] { - /*if (EApp::isPaused()) - { - EApp::resume(); - } - else - { - EApp::pause(); - }*/ - EApp::enterScene(scene, new ETransitionMove(1, ETransitionMove::RIGHT)); - }); - button->setPivot(0.5f, 0.5f); - button->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2 + 100); - scene2->add(button); + //auto scene2 = new EScene(); - EMusicUtils::playMusic(L"music.wav", -1); + //auto bird = new ESprite(L"atlas.png", 5, 982, 34, 24); + //auto animation = new EAnimation(); + //animation->addFrame(new ESpriteFrame(L"atlas.png", 5, 982, 34, 24)); + //animation->addFrame(new ESpriteFrame(L"atlas.png", 61, 982, 34, 24)); + //animation->addFrame(new ESpriteFrame(L"atlas.png", 117, 982, 34, 24)); + //animation->addFrame(new ESpriteFrame(L"atlas.png", 61, 982, 34, 24)); + //bird->runAction(new EActionLoop(animation)); + //bird->setPivot(0.5f, 0.5f); + //bird->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); + //scene2->add(bird); - /*scene2->runAction(new EActionSequence(5, - new EActionCallback([]() { EMusicUtils::playMusic(L"music.wav", -1); }), - new EActionDelay(3), - new EActionCallback([]() { EMusicUtils::pauseMusic(L"music.wav"); }), - new EActionDelay(10), - new EActionCallback([]() { EMusicUtils::resumeMusic(L"music.wav"); })));*/ + //auto btnStart = new ESprite(L"atlas.png", 702, 234, 116, 70); + //auto btnStartSelected = new ESprite(L"atlas.png", 702, 234, 116, 70); + //btnStartSelected->setPosY(5); + //auto button = new EButton(btnStart, btnStartSelected, [=] { + // /*if (EApp::isPaused()) + // { + // EApp::resume(); + // } + // else + // { + // EApp::pause(); + // }*/ + // EApp::enterScene(scene, new ETransitionMove(1, ETransitionMove::RIGHT)); + //}); + //button->setPivot(0.5f, 0.5f); + //button->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2 + 100); + //scene2->add(button); - EApp::enterScene(scene2, new ETransitionMove(1, ETransitionMove::UP)); + //EMusicUtils::playMusic(L"music.wav", -1); + + ///*scene2->runAction(new EActionSequence(5, + // new EActionCallback([]() { EMusicUtils::playMusic(L"music.wav", -1); }), + // new EActionDelay(3), + // new EActionCallback([]() { EMusicUtils::pauseMusic(L"music.wav"); }), + // new EActionDelay(10), + // new EActionCallback([]() { EMusicUtils::resumeMusic(L"music.wav"); })));*/ + + //EApp::enterScene(scene2, new ETransitionMove(1, ETransitionMove::UP)); return EApp::run(); } diff --git a/Demo/test.png b/Demo/test.png index 23b604623cfa24166dd9310929b57ee6de3aafba..a9ddbade12c13a7c5e999a0f9bff574fd029a0a7 100644 GIT binary patch literal 18230 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 diff --git a/Demo/test2.png b/Demo/test2.png new file mode 100644 index 0000000000000000000000000000000000000000..23b604623cfa24166dd9310929b57ee6de3aafba GIT binary patch literal 21833 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 literal 0 HcmV?d00001 diff --git a/Easy2D/Action/EActionMoveBy.cpp b/Easy2D/Action/EActionMoveBy.cpp index 1c4dfc27..75847083 100644 --- a/Easy2D/Action/EActionMoveBy.cpp +++ b/Easy2D/Action/EActionMoveBy.cpp @@ -4,7 +4,7 @@ e2d::EActionMoveBy::EActionMoveBy(float duration, EVec vector) : EActionGradual(duration) { - m_MoveVector = vector; + m_MoveVec = vector; } void e2d::EActionMoveBy::_init() @@ -30,8 +30,8 @@ void e2d::EActionMoveBy::_update() { // 移动节点 m_pTarget->setPos( - m_BeginPos.x + m_MoveVector.x * m_fRateOfProgress, - m_BeginPos.y + m_MoveVector.y * m_fRateOfProgress + m_BeginPos.x + m_MoveVec.x * m_fRateOfProgress, + m_BeginPos.y + m_MoveVec.y * m_fRateOfProgress ); // 判断动作是否结束 if (_isEnd()) @@ -49,10 +49,10 @@ void e2d::EActionMoveBy::_reset() e2d::EActionMoveBy * e2d::EActionMoveBy::clone() const { - return new EActionMoveBy(m_fTotalDuration / 1000, m_MoveVector); + return new EActionMoveBy(m_fTotalDuration / 1000, m_MoveVec); } e2d::EActionMoveBy * e2d::EActionMoveBy::reverse() const { - return new EActionMoveBy(m_fTotalDuration / 1000, EVec(-m_MoveVector.x, -m_MoveVector.y)); + return new EActionMoveBy(m_fTotalDuration / 1000, EVec(-m_MoveVec.x, -m_MoveVec.y)); } \ No newline at end of file diff --git a/Easy2D/Action/EActionMoveTo.cpp b/Easy2D/Action/EActionMoveTo.cpp index 08a025e8..d9d1a723 100644 --- a/Easy2D/Action/EActionMoveTo.cpp +++ b/Easy2D/Action/EActionMoveTo.cpp @@ -14,7 +14,7 @@ e2d::EActionMoveTo * e2d::EActionMoveTo::clone() const void e2d::EActionMoveTo::_init() { EActionMoveBy::_init(); - m_MoveVector = m_EndPos - m_BeginPos; + m_MoveVec = m_EndPos - m_BeginPos; } void e2d::EActionMoveTo::_reset() diff --git a/Easy2D/Base/EApp.cpp b/Easy2D/Base/EApp.cpp index ef2d431e..3c64439b 100644 --- a/Easy2D/Base/EApp.cpp +++ b/Easy2D/Base/EApp.cpp @@ -121,7 +121,7 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, const EW // 创建窗口 GetHWnd() = CreateWindow( L"Easy2DApp", - title.c_str(), + title, dwStyle, 0, 0, width, height, NULL, @@ -420,7 +420,7 @@ void e2d::EApp::setWindowSize(UINT32 width, UINT32 height) void e2d::EApp::setWindowTitle(const EString &title) { // 设置窗口标题 - SetWindowText(GetHWnd(), title.c_str()); + SetWindowText(GetHWnd(), title); // 保存当前标题,用于修改窗口大小时恢复标题 getInstance()->m_sTitle = title; } @@ -525,7 +525,7 @@ void e2d::EApp::setAppName(const EString &appname) e2d::EString e2d::EApp::getAppName() { - if (getInstance()->m_sAppName.empty()) + if (getInstance()->m_sAppName.isEmpty()) getInstance()->m_sAppName = getInstance()->m_sTitle; return getInstance()->m_sAppName; } diff --git a/Easy2D/Base/EScene.cpp b/Easy2D/Base/EScene.cpp index 052e20d5..c32c5dca 100644 --- a/Easy2D/Base/EScene.cpp +++ b/Easy2D/Base/EScene.cpp @@ -77,7 +77,7 @@ void e2d::EScene::remove(const EString &childName) return m_pRoot->removeChild(childName); } -e2d::EVector& e2d::EScene::getChildren() +std::vector& e2d::EScene::getChildren() { return m_pRoot->m_vChildren; } diff --git a/Easy2D/Common/EFont.cpp b/Easy2D/Common/EFont.cpp index 1e85bac7..21775b3f 100644 --- a/Easy2D/Common/EFont.cpp +++ b/Easy2D/Common/EFont.cpp @@ -80,13 +80,13 @@ void e2d::EFont::_initTextFormat() SafeReleaseInterface(&m_pTextFormat); HRESULT hr = GetDirectWriteFactory()->CreateTextFormat( - m_sFontFamily.c_str(), - NULL, // Font collection(NULL sets it to the system font collection) + m_sFontFamily, + NULL, DWRITE_FONT_WEIGHT(m_FontWeight), m_bItalic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, m_fFontSize, - L"en-us", // Local + L"en-us", &m_pTextFormat ); diff --git a/Easy2D/Common/EString.cpp b/Easy2D/Common/EString.cpp new file mode 100644 index 00000000..01292904 --- /dev/null +++ b/Easy2D/Common/EString.cpp @@ -0,0 +1,350 @@ +#include "..\ecommon.h" +#include +using namespace e2d; + + +EString::EString() +{ + _size = 0; + _string = nullptr; +} + +EString::EString(const wchar_t *str) +{ + if (str) + { + _size = wcslen(str); + _string = new wchar_t[_size + 1]; + wcscpy_s(_string, _size + 1, str); + } + else + { + _string = nullptr; + _size = 0; + } +} + +EString::EString(EString && str) +{ + _size = str._size; + _string = str._string; + str._string = nullptr; +} + +EString::EString(const EString &str) +{ + if (str._size) + { + _size = str._size; + _string = new wchar_t[_size + 1]; + wcscpy_s(_string, _size + 1, str._string); + } + else + { + _string = nullptr; + _size = 0; + } +} + +e2d::EString::EString(const std::wstring &str) +{ + if (!str.empty()) + { + _size = static_cast(str.length()); + _string = new wchar_t[_size + 1]; + wcscpy_s(_string, _size + 1, str.c_str()); + } + else + { + _string = nullptr; + _size = 0; + } +} + +EString::~EString() +{ + delete[] _string; +} + +EString &EString::operator=(const wchar_t *str) +{ + if (_string == str) + return *this; + + if (str) + { + delete[] _string; + _size = wcslen(str); + _string = new wchar_t[_size + 1]; + wcscpy_s(_string, _size + 1, str); + } + else + { + _string = nullptr; + _size = 0; + } + return *this; +} + +EString &EString::operator=(const EString &str) +{ + if (_string == str._string) + return *this; + + if (str._size) + { + delete[] _string; + _size = str._size; + _string = new wchar_t[_size + 1]; + wcscpy_s(_string, _size + 1, str._string); + } + else + { + _string = nullptr; + _size = 0; + } + return *this; +} + +EString & e2d::EString::operator=(const std::wstring &str) +{ + if (!str.empty()) + { + delete[] _string; + _size = static_cast(str.length()); + _string = new wchar_t[_size + 1]; + wcscpy_s(_string, _size + 1, str.c_str()); + } + else + { + _string = nullptr; + _size = 0; + } + return *this; +} + +bool EString::operator==(const wchar_t *str) +{ + return (wcscmp(str, _string) == 0); +} + +bool EString::operator ==(const EString &str) +{ + return (wcscmp(str._string, _string) == 0); +} + +bool e2d::EString::operator==(const std::wstring &str) +{ + return (str.compare(_string) == 0); +} + +bool e2d::EString::operator!=(const wchar_t *str) +{ + return (wcscmp(str, _string) != 0); +} + +bool e2d::EString::operator!=(const EString &str) +{ + return (wcscmp(str._string, _string) != 0); +} + +bool e2d::EString::operator!=(const std::wstring &str) +{ + return (str.compare(_string) != 0); +} + +wchar_t &EString::operator[](int index) +{ + ASSERT(index >= 0 && index < _size, "EString subscript out of range"); + return _string[index]; +} + +EString EString::operator+(const wchar_t *str) +{ + EString str_temp(*this); + + str_temp += str; + return std::move(str_temp); +} + +EString EString::operator+(const wchar_t x) +{ + EString str_temp(*this); + + str_temp += x; + return std::move(str_temp); +} + +EString EString::operator+(const EString &str) +{ + EString str_temp(*this); + + str_temp += str; + return std::move(str_temp); +} + +EString e2d::EString::operator+(const std::wstring &str) +{ + EString str_temp(*this); + + str_temp += str; + return std::move(str_temp); +} + +EString &EString::operator+=(const wchar_t x) +{ + wchar_t *str_temp = new wchar_t[_size + 2]; + if (_string) wcscpy_s(str_temp, _size + 2, _string); + str_temp[_size] = x; + str_temp[_size + 1] = 0; + + delete[] _string; + _string = str_temp; + _size++; + return *this; +} + +EString &EString::operator+=(const wchar_t *str) +{ + if (!str) return *this; + + int d_size = wcslen(str); + if (d_size == 0) return *this; + + wchar_t *str_temp = new wchar_t[_size + d_size + 1]; + if (_string) wcscpy_s(str_temp, _size + d_size + 1, _string); + wcscpy_s(str_temp + _size, d_size + 1, str); + + delete[] _string; + _string = str_temp; + _size += d_size; + return *this; +} + +EString &EString::operator+=(const EString &str) +{ + if (str._size == 0) return *this; + + wchar_t *str_temp = new wchar_t[_size + str._size + 1]; + if (_string) wcscpy_s(str_temp, _size + str._size + 1, _string); + wcscpy_s(str_temp + _size, str._size + 1, str._string); + + delete[] _string; + _string = str_temp; + _size += str._size; + return *this; +} + +EString & e2d::EString::operator+=(const std::wstring &str) +{ + if (str.length() == 0) return *this; + + wchar_t *str_temp = new wchar_t[_size + str.length() + 1]; + if (_string) wcscpy_s(str_temp, _size + str.length() + 1, _string); + wcscpy_s(str_temp + _size, str.length() + 1, str.c_str()); + + delete[] _string; + _string = str_temp; + _size += static_cast(str.length()); + return *this; +} + +unsigned int e2d::EString::hash() const +{ + unsigned int hash = 0; + + for (int i = 0; i < _size; i++) + { + hash *= 16777619; + hash ^= (unsigned int)towupper(_string[i]); + } + return (hash); +} + +std::wistream & e2d::operator>>(std::wistream &cin, EString &str) +{ + const int limit_string_size = 4096; + + str._string = new wchar_t[limit_string_size]; + + cin >> std::setw(limit_string_size) >> str._string; + str._size = wcslen(str._string); + return cin; +} + + +EString e2d::EString::upper() const +{ + EString str(*this); + + for (int i = 0; i < str._size; i++) + if (str._string[i] >= L'a' && str._string[i] <= L'z') + str._string[i] -= (L'a' - L'A'); + + return std::move(str); +} + +EString e2d::EString::lower() const +{ + EString str(*this); + + for (int i = 0; i < str._size; i++) + str._string[i] = towlower(str._string[i]); + + return std::move(str); +} + +EString e2d::EString::sub(int offset, int count) const +{ + if (_size == 0 || offset >= _size) + return std::move(EString()); + + offset = offset >= 0 ? offset : 0; + + if (count < 0 || (offset + count) > _size) + count = _size - offset; + + EString str_temp; + str_temp._string = new wchar_t[count + 1]; + + for (int i = 0; i < count; i++) + str_temp._string[i] = (_string + offset)[i]; + str_temp._string[count] = 0; + + return std::move(str_temp); +} + +int e2d::EString::findFirstOf(wchar_t ch) const +{ + for (int i = 0; i < _size; i++) + if (_string[i] == ch) + return i; + + return -1; +} + +int e2d::EString::findLastOf(wchar_t ch) const +{ + int index = -1; + + for (int i = 0; i < _size; i++) + if (_string[i] == ch) + index = i; + + return index; +} + +EString & e2d::EString::append(wchar_t ch) +{ + return (*this) += ch; +} + +EString & e2d::EString::append(wchar_t * str) +{ + return (*this) += str; +} + +EString & e2d::EString::append(EString & str) +{ + return (*this) += str; +} diff --git a/Easy2D/Common/ETexture.cpp b/Easy2D/Common/ETexture.cpp index 89bf9a6c..c064f90c 100644 --- a/Easy2D/Common/ETexture.cpp +++ b/Easy2D/Common/ETexture.cpp @@ -46,9 +46,9 @@ e2d::ETexture::~ETexture() void e2d::ETexture::loadFromFile(const EString & fileName) { - WARN_IF(fileName.empty(), "ETexture cannot load bitmap from NULL file name."); + WARN_IF(fileName.isEmpty(), "ETexture cannot load bitmap from NULL file name."); - if (fileName.empty()) + if (fileName.isEmpty()) return; if (!e2d::ETexture::preload(fileName)) @@ -57,10 +57,7 @@ void e2d::ETexture::loadFromFile(const EString & fileName) return; } - std::hash h; - size_t hash = h(fileName); - - m_pBitmap = s_mBitmapsFromFile.at(hash); + m_pBitmap = s_mBitmapsFromFile.at(fileName.hash()); } void e2d::ETexture::loadFromResource(LPCTSTR resourceName, LPCTSTR resourceType) @@ -122,10 +119,7 @@ e2d::ESize e2d::ETexture::getSourceSize() const bool e2d::ETexture::preload(const EString & fileName) { - std::hash h; - size_t hash = h(fileName); - - if (s_mBitmapsFromFile.find(hash) != s_mBitmapsFromFile.end()) + if (s_mBitmapsFromFile.find(fileName.hash()) != s_mBitmapsFromFile.end()) { return true; } @@ -140,7 +134,7 @@ bool e2d::ETexture::preload(const EString & fileName) // 创建解码器 hr = GetImagingFactory()->CreateDecoderFromFilename( - fileName.c_str(), + fileName, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, @@ -183,12 +177,9 @@ bool e2d::ETexture::preload(const EString & fileName) if (SUCCEEDED(hr)) { // 保存图片指针和图片的 Hash 名 - std::hash h; - size_t hash = h(fileName); - s_mBitmapsFromFile.insert( std::map::value_type( - hash, + fileName.hash(), pBitmap) ); } diff --git a/Easy2D/Easy2D.vcxproj b/Easy2D/Easy2D.vcxproj index eeec2dec..fc40508c 100644 --- a/Easy2D/Easy2D.vcxproj +++ b/Easy2D/Easy2D.vcxproj @@ -212,6 +212,7 @@ + @@ -264,7 +265,6 @@ - diff --git a/Easy2D/Easy2D.vcxproj.filters b/Easy2D/Easy2D.vcxproj.filters index a603ca5d..e793408e 100644 --- a/Easy2D/Easy2D.vcxproj.filters +++ b/Easy2D/Easy2D.vcxproj.filters @@ -219,6 +219,9 @@ Msg + + Common + @@ -235,7 +238,6 @@ - Win diff --git a/Easy2D/Manager/EActionManager.cpp b/Easy2D/Manager/EActionManager.cpp index e171a3df..f0e5e0f6 100644 --- a/Easy2D/Manager/EActionManager.cpp +++ b/Easy2D/Manager/EActionManager.cpp @@ -2,7 +2,7 @@ #include "..\eactions.h" #include "..\Win\winbase.h" -static e2d::EVector s_vActions; +static std::vector s_vActions; void e2d::EActionManager::addAction(EAction * action) diff --git a/Easy2D/Manager/EMsgManager.cpp b/Easy2D/Manager/EMsgManager.cpp index f020c054..ca0f10d9 100644 --- a/Easy2D/Manager/EMsgManager.cpp +++ b/Easy2D/Manager/EMsgManager.cpp @@ -5,9 +5,9 @@ // 鼠标消息监听器 -e2d::EVector s_vMouseListeners; +std::vector s_vMouseListeners; // 按键消息监听器 -e2d::EVector s_vKeyboardListeners; +std::vector s_vKeyboardListeners; void e2d::EMsgManager::MouseProc(UINT message, WPARAM wParam, LPARAM lParam) @@ -20,7 +20,7 @@ void e2d::EMsgManager::MouseProc(UINT message, WPARAM wParam, LPARAM lParam) if (s_vMouseListeners.empty()) return; // 执行鼠标消息监听函数 - EVector::size_type i = s_vMouseListeners.size(); + std::vector::size_type i = s_vMouseListeners.size(); do { @@ -45,7 +45,7 @@ void e2d::EMsgManager::KeyboardProc(UINT message, WPARAM wParam, LPARAM lParam) if (s_vKeyboardListeners.empty()) return; // 执行按键消息监听函数 - EVector::size_type i = s_vKeyboardListeners.size(); + std::vector::size_type i = s_vKeyboardListeners.size(); do { @@ -133,7 +133,7 @@ void e2d::EMsgManager::stopMouseListeners(const EString & name) void e2d::EMsgManager::delMouseListeners(const EString & name) { // 删除鼠标消息监听器 - EVector::iterator mIter; + std::vector::iterator mIter; for (mIter = s_vMouseListeners.begin(); mIter != s_vMouseListeners.end();) { if ((*mIter)->getName() == name) @@ -175,7 +175,7 @@ void e2d::EMsgManager::stopKeyboardListeners(const EString & name) void e2d::EMsgManager::delKeyboardListeners(const EString & name) { // 删除按键消息监听器 - EVector::iterator kIter; + std::vector::iterator kIter; for (kIter = s_vKeyboardListeners.begin(); kIter != s_vKeyboardListeners.end();) { if ((*kIter)->getName() == name) diff --git a/Easy2D/Manager/EObjectManager.cpp b/Easy2D/Manager/EObjectManager.cpp index 7c6e3e15..16bd3892 100644 --- a/Easy2D/Manager/EObjectManager.cpp +++ b/Easy2D/Manager/EObjectManager.cpp @@ -9,7 +9,7 @@ // 让其自动释放 // 释放池容器 -static e2d::EVector s_vPool; +static std::vector s_vPool; // 标志释放池执行状态 static bool s_bNotifyed = false; @@ -19,7 +19,7 @@ void e2d::EObjectManager::__flush() s_bNotifyed = false; // 创建迭代器 - static EVector::iterator iter; + static std::vector::iterator iter; // 循环遍历容器中的所有对象 for (iter = s_vPool.begin(); iter != s_vPool.end();) { diff --git a/Easy2D/Manager/EPhysicsManager.cpp b/Easy2D/Manager/EPhysicsManager.cpp index 871cec83..70091872 100644 --- a/Easy2D/Manager/EPhysicsManager.cpp +++ b/Easy2D/Manager/EPhysicsManager.cpp @@ -4,9 +4,9 @@ #include "..\egeometry.h" // 监听器集合 -e2d::EVector s_vListeners; +std::vector s_vListeners; // 形状集合 -e2d::EVector s_vGeometries; +std::vector s_vGeometries; void e2d::EPhysicsManager::PhysicsGeometryProc(EGeometry * pActiveGeometry) @@ -48,7 +48,7 @@ void e2d::EPhysicsManager::PhysicsGeometryProc(EGeometry * pActiveGeometry) void e2d::EPhysicsManager::PhysicsListenerProc() { // 执行鼠标消息监听函数 - EVector::size_type i = s_vListeners.size(); + std::vector::size_type i = s_vListeners.size(); do { @@ -136,7 +136,7 @@ void e2d::EPhysicsManager::stopListeners(const EString & name) void e2d::EPhysicsManager::delListeners(const EString & name) { - EVector::iterator iter; + std::vector::iterator iter; for (iter = s_vListeners.begin(); iter != s_vListeners.end();) { if ((*iter)->getName() == name) diff --git a/Easy2D/Manager/ETimerManager.cpp b/Easy2D/Manager/ETimerManager.cpp index 18827b25..d4192aa1 100644 --- a/Easy2D/Manager/ETimerManager.cpp +++ b/Easy2D/Manager/ETimerManager.cpp @@ -3,7 +3,7 @@ #include "..\enodes.h" #include "..\Win\winbase.h" -static e2d::EVector s_vTimers; +static std::vector s_vTimers; void e2d::ETimerManager::TimerProc() @@ -69,7 +69,7 @@ void e2d::ETimerManager::stopTimers(const EString & name) void e2d::ETimerManager::delTimers(const EString & name) { - EVector::iterator mIter; + std::vector::iterator mIter; for (mIter = s_vTimers.begin(); mIter != s_vTimers.end();) { if ((*mIter)->getName() == name) diff --git a/Easy2D/Node/ENode.cpp b/Easy2D/Node/ENode.cpp index 40d24c54..192e337d 100644 --- a/Easy2D/Node/ENode.cpp +++ b/Easy2D/Node/ENode.cpp @@ -573,7 +573,7 @@ e2d::EScene * e2d::ENode::getParentScene() const return m_pParentScene; } -e2d::EVector& e2d::ENode::getChildren() +std::vector& e2d::ENode::getChildren() { return m_vChildren; } @@ -585,10 +585,9 @@ size_t e2d::ENode::getChildrenCount() const e2d::ENode * e2d::ENode::getChild(const EString & name) { - WARN_IF(name.empty(), "Invalid ENode name."); + WARN_IF(name.isEmpty(), "Invalid ENode name."); - std::hash h; - size_t hash = h(name); + unsigned int hash = name.hash(); for (const auto& child : m_vChildren) { @@ -640,7 +639,7 @@ bool e2d::ENode::removeChild(ENode * child) void e2d::ENode::removeChild(const EString & childName) { - WARN_IF(childName.empty(), "Invalid ENode name."); + WARN_IF(childName.isEmpty(), "Invalid ENode name."); if (m_vChildren.empty()) { @@ -648,8 +647,7 @@ void e2d::ENode::removeChild(const EString & childName) } // 计算名称 Hash 值 - std::hash h; - size_t hash = h(childName); + unsigned int hash = childName.hash(); size_t size = m_vChildren.size(); for (size_t i = 0; i < size; i++) @@ -782,15 +780,14 @@ void e2d::ENode::setVisiable(bool value) void e2d::ENode::setName(const EString & name) { - WARN_IF(name.empty(), "Invalid ENode name."); + WARN_IF(name.isEmpty(), "Invalid ENode name."); - if (!name.empty()) + if (!name.isEmpty()) { // 保存节点名 m_sName = name; // 保存节点 Hash 名 - std::hash h; - m_nHashName = h(name); + m_nHashName = name.hash(); } } diff --git a/Easy2D/Node/EText.cpp b/Easy2D/Node/EText.cpp index b13f567b..6f002daf 100644 --- a/Easy2D/Node/EText.cpp +++ b/Easy2D/Node/EText.cpp @@ -94,7 +94,7 @@ void e2d::EText::_render() { GetSolidColorBrush()->SetColor(D2D1::ColorF(m_pFont->m_Color, m_fDisplayOpacity)); GetRenderTarget()->DrawTextW( - m_sText.c_str(), + m_sText, UINT32(m_sText.length()), m_pFont->_getTextFormat(), D2D1::RectF( @@ -110,7 +110,7 @@ void e2d::EText::_render() void e2d::EText::_initTextLayout() { // 未设置字体或空字符串时,文本宽高为 0 - if (!m_pFont || m_sText.empty()) + if (!m_pFont || m_sText.isEmpty()) { this->_setHeight(0); m_fWordWrappingWidth = 0; @@ -131,8 +131,8 @@ void e2d::EText::_initTextLayout() IDWriteTextLayout * pDWriteTextLayout = nullptr; HRESULT hr = GetDirectWriteFactory()->CreateTextLayout( - m_sText.c_str(), - UINT32(m_sText.size()), + m_sText, + UINT32(m_sText.length()), m_pFont->_getTextFormat(), m_bWordWrapping ? m_fWordWrappingWidth : 0, 0, diff --git a/Easy2D/Tool/EFileUtils.cpp b/Easy2D/Tool/EFileUtils.cpp index 3d6aee6e..0e18e061 100644 --- a/Easy2D/Tool/EFileUtils.cpp +++ b/Easy2D/Tool/EFileUtils.cpp @@ -35,14 +35,14 @@ e2d::EString e2d::EFileUtils::getLocalAppDataPath() e2d::EString e2d::EFileUtils::getTempPath() { // 获取临时文件目录 - TCHAR path[_MAX_PATH]; + wchar_t path[_MAX_PATH]; ::GetTempPath(_MAX_PATH, path); // 创建临时文件目录 e2d::EString tempFilePath = path + e2d::EApp::getAppName(); - if (_waccess(tempFilePath.c_str(), 0) == -1) + if (_waccess(tempFilePath, 0) == -1) { - _wmkdir(tempFilePath.c_str()); + _wmkdir(tempFilePath); } return tempFilePath; } @@ -50,67 +50,66 @@ e2d::EString e2d::EFileUtils::getTempPath() e2d::EString e2d::EFileUtils::getDefaultSavePath() { EString path = EFileUtils::getLocalAppDataPath(); - WARN_IF(path.empty(), "Cannot get local AppData path!"); + WARN_IF(path.isEmpty(), "Cannot get local AppData path!"); - path.append(L"\\"); - path.append(EApp::getAppName()); + path += L"\\" + EApp::getAppName(); - if (_waccess(path.c_str(), 0) == -1) + if (_waccess(path, 0) == -1) { - _wmkdir(path.c_str()); + _wmkdir(path); } - path.append(L"\\DefaultData.ini"); + path += L"\\DefaultData.ini"; return path; } void e2d::EFileUtils::saveInt(const EString & key, int value) { - ::WritePrivateProfileString(L"Default", key.c_str(), std::to_wstring(value).c_str(), getDefaultSavePath().c_str()); + ::WritePrivateProfileString(L"Default", key, EString::parse(value), getDefaultSavePath()); } void e2d::EFileUtils::saveFloat(const EString & key, float value) { - ::WritePrivateProfileString(L"Default", key.c_str(), std::to_wstring(value).c_str(), getDefaultSavePath().c_str()); + ::WritePrivateProfileString(L"Default", key, EString::parse(value), getDefaultSavePath()); } void e2d::EFileUtils::saveString(const EString & key, const EString & value) { - ::WritePrivateProfileString(L"Default", key.c_str(), value.c_str(), getDefaultSavePath().c_str()); + ::WritePrivateProfileString(L"Default", key, value, getDefaultSavePath()); } int e2d::EFileUtils::getInt(const EString & key, int default) { - return ::GetPrivateProfileInt(L"Default", key.c_str(), default, getDefaultSavePath().c_str()); + return ::GetPrivateProfileInt(L"Default", key, default, getDefaultSavePath()); } float e2d::EFileUtils::getFloat(const EString & key, float default) { - TCHAR temp[32] = { 0 }; - ::GetPrivateProfileString(L"Default", key.c_str(), std::to_wstring(default).c_str(), temp, 31, getDefaultSavePath().c_str()); + wchar_t temp[32] = { 0 }; + ::GetPrivateProfileString(L"Default", key, EString::parse(default), temp, 31, getDefaultSavePath()); return std::stof(temp); } e2d::EString e2d::EFileUtils::getString(const EString & key, const EString & default) { - TCHAR temp[256] = { 0 }; - ::GetPrivateProfileString(L"Default", key.c_str(), default.c_str(), temp, 255, getDefaultSavePath().c_str()); - return EString(temp); + wchar_t temp[256] = { 0 }; + ::GetPrivateProfileString(L"Default", key, default, temp, 255, getDefaultSavePath()); + return temp; } e2d::EString e2d::EFileUtils::getFileExtension(const EString & filePath) { EString fileExtension; // 找到文件名中的最后一个 '.' 的位置 - size_t pos = filePath.find_last_of('.'); + size_t pos = filePath.findLastOf(L'.'); // 判断 pos 是否是个有效位置 - if (pos != EString::npos) + if (pos != -1) { // 截取扩展名 - fileExtension = filePath.substr(pos, filePath.length()); + fileExtension = filePath.sub(pos, filePath.length()); // 转换为小写字母 - std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::tolower); + fileExtension = fileExtension.lower(); } return fileExtension; @@ -122,15 +121,15 @@ e2d::EString e2d::EFileUtils::getSaveFilePath(const EString & title, const EStri OPENFILENAME ofn = { 0 }; TCHAR strFilename[MAX_PATH] = { 0 }; // 用于接收文件名 ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小 - ofn.hwndOwner = GetHWnd(); // 拥有着窗口句柄,NULL 表示对话框是非模态的 - ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤 + ofn.hwndOwner = GetHWnd(); // 窗口句柄 + ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤 ofn.nFilterIndex = 1; // 过滤器索引 ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名 ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度 ofn.lpstrInitialDir = NULL; // 初始目录为默认 - ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;// 目录必须存在,覆盖文件前发出警告 - ofn.lpstrTitle = title.c_str(); // 使用系统默认标题留空即可 - ofn.lpstrDefExt = defExt.c_str(); // 默认追加的扩展名 + ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + ofn.lpstrTitle = title; // 标题 + ofn.lpstrDefExt = defExt; // 默认追加的扩展名 if (GetSaveFileName(&ofn)) { diff --git a/Easy2D/Tool/EMusicUtils.cpp b/Easy2D/Tool/EMusicUtils.cpp index 889063d2..0381dddc 100644 --- a/Easy2D/Tool/EMusicUtils.cpp +++ b/Easy2D/Tool/EMusicUtils.cpp @@ -6,12 +6,6 @@ typedef std::pair Music; typedef std::map MusicList; -static UINT Hash(const e2d::EString & key) -{ - static std::hash h; - return h(key); -} - static MusicList& getMciPlayerList() { static MusicList s_List; @@ -43,10 +37,10 @@ UINT e2d::EMusicUtils::playMusic(const EString & musicResourceName, const EStrin UINT e2d::EMusicUtils::preloadMusic(const EString & musicFilePath) { - if (musicFilePath.empty()) + if (musicFilePath.isEmpty()) return 0; - UINT nRet = ::Hash(musicFilePath); + UINT nRet = musicFilePath.hash(); if (getMciPlayerList().end() != getMciPlayerList().find(nRet)) return nRet; @@ -64,10 +58,10 @@ UINT e2d::EMusicUtils::preloadMusic(const EString & musicFilePath) UINT e2d::EMusicUtils::preloadMusic(const EString & musicResourceName, const EString & musicResourceType, const EString & musicExtension) { - if (musicResourceName.empty() || musicResourceType.empty()) + if (musicResourceName.isEmpty() || musicResourceType.isEmpty()) return 0; - UINT nRet = ::Hash(musicResourceName); + UINT nRet = musicResourceName.hash(); if (getMciPlayerList().end() != getMciPlayerList().find(nRet)) return nRet; @@ -96,7 +90,7 @@ bool e2d::EMusicUtils::resumeMusic(UINT musicId) bool e2d::EMusicUtils::resumeMusic(const EString & musicName) { - return resumeMusic(Hash(musicName));; + return resumeMusic(musicName.hash());; } bool e2d::EMusicUtils::pauseMusic(UINT musicId) @@ -112,7 +106,7 @@ bool e2d::EMusicUtils::pauseMusic(UINT musicId) bool e2d::EMusicUtils::pauseMusic(const EString & musicName) { - return pauseMusic(Hash(musicName)); + return pauseMusic(musicName.hash()); } bool e2d::EMusicUtils::stopMusic(UINT musicId) @@ -128,7 +122,7 @@ bool e2d::EMusicUtils::stopMusic(UINT musicId) bool e2d::EMusicUtils::stopMusic(const EString & musicName) { - return stopMusic(Hash(musicName));; + return stopMusic(musicName.hash());; } void e2d::EMusicUtils::pauseAllMusics() diff --git a/Easy2D/Win/MciPlayer.cpp b/Easy2D/Win/MciPlayer.cpp index 41c4c67e..59beac71 100644 --- a/Easy2D/Win/MciPlayer.cpp +++ b/Easy2D/Win/MciPlayer.cpp @@ -66,14 +66,14 @@ MciPlayer::~MciPlayer() bool MciPlayer::open(const e2d::EString & pFileName, UINT uId) { - if (pFileName.empty()) + if (pFileName.isEmpty()) return false; close(); MCI_OPEN_PARMS mciOpen = { 0 }; mciOpen.lpstrDeviceType = (LPCTSTR)MCI_ALL_DEVICE_ID; - mciOpen.lpstrElementName = pFileName.c_str(); + mciOpen.lpstrElementName = pFileName; MCIERROR mciError; mciError = mciSendCommand( @@ -96,18 +96,16 @@ bool MciPlayer::open(const e2d::EString & pFileName, UINT uId) bool MciPlayer::open(const e2d::EString & pResouceName, const e2d::EString & pResouceType, const e2d::EString & musicExtension, UINT uId) { // 忽略不存在的文件 - if (pResouceName.empty() || pResouceType.empty() || musicExtension.empty()) return false; + if (pResouceName.isEmpty() || pResouceType.isEmpty() || musicExtension.isEmpty()) return false; // 获取临时文件目录 e2d::EString tempFileName = e2d::EFileUtils::getTempPath(); // 产生临时文件的文件名 - tempFileName.append(L"\\"); - tempFileName.append(std::to_wstring(uId)); - tempFileName.append(L"." + musicExtension); + tempFileName = tempFileName + L"\\" + uId + L"." + musicExtension; // 导出资源为临时文件 - if (ExtractResource(tempFileName.c_str(), pResouceType.c_str(), pResouceName.c_str())) + if (ExtractResource(tempFileName, pResouceType, pResouceName)) { return open(tempFileName, uId); } diff --git a/Easy2D/eactions.h b/Easy2D/eactions.h index 490dafba..52e73da0 100644 --- a/Easy2D/eactions.h +++ b/Easy2D/eactions.h @@ -144,7 +144,7 @@ protected: protected: EPoint m_BeginPos; - EVec m_MoveVector; + EVec m_MoveVec; }; @@ -605,7 +605,7 @@ protected: protected: UINT m_nFrameIndex; - EVector m_vFrames; + std::vector m_vFrames; }; diff --git a/Easy2D/easy2d.h b/Easy2D/easy2d.h index 2d4a73f2..3d51d77c 100644 --- a/Easy2D/easy2d.h +++ b/Easy2D/easy2d.h @@ -1,10 +1,11 @@ /****************************************************** -* Easy2D Game Engine +* Easy2D Game Framework * * Website: http://www.easy2d.cn -* Source Code: https://gitee.com/werelone/Easy2D +* Source Code: https://github.com/Nomango/Easy2D ******************************************************/ + #pragma once #ifndef __cplusplus @@ -17,7 +18,6 @@ #include "emacros.h" -#include "etypedef.h" #include "ecommon.h" #include "ebase.h" #include "emanagers.h" diff --git a/Easy2D/ebase.h b/Easy2D/ebase.h index a9bc132c..773ca7ce 100644 --- a/Easy2D/ebase.h +++ b/Easy2D/ebase.h @@ -225,7 +225,7 @@ public: ); // 获取所有子节点 - EVector &getChildren(); + std::vector &getChildren(); // 获取子节点数量 size_t getChildrenCount() const; diff --git a/Easy2D/ecommon.h b/Easy2D/ecommon.h index 3c873f2e..83d4d81a 100644 --- a/Easy2D/ecommon.h +++ b/Easy2D/ecommon.h @@ -1,11 +1,251 @@ #pragma once #include "emacros.h" -#include "etypedef.h" +#include +#include +#include namespace e2d { +// 表示坐标的结构体 +struct EPoint +{ + float x; + float y; + + EPoint() + { + x = 0; + y = 0; + } + + EPoint(float x, float y) + { + this->x = x; + this->y = y; + } + + EPoint operator + (EPoint const & p) + { + return EPoint(x + p.x, y + p.y); + } + + EPoint operator - (EPoint const & p) + { + return EPoint(x - p.x, y - p.y); + } + + EPoint operator * (float const & value) + { + return EPoint(x * value, y * value); + } + + EPoint operator / (float const & value) + { + return EPoint(x / value, y / value); + } +}; + +// 表示二维向量的结构体 +typedef EPoint EVec; + +// 表示大小的结构体 +struct ESize +{ + float width; + float height; + + ESize() + { + width = 0; + height = 0; + } + + ESize(float width, float height) + { + this->width = width; + this->height = height; + } + + ESize operator + (ESize const & size) + { + return ESize(width + size.width, height + size.height); + } + + ESize operator - (ESize const & size) + { + return ESize(width - size.width, height - size.height); + } + + ESize operator * (float const & value) + { + return ESize(width * value, height * value); + } + + ESize operator / (float const & value) + { + return ESize(width / value, height / value); + } +}; + +// 表示窗口样式的结构体 +struct EWindowStyle +{ + LPCTSTR m_pIconID; /* 程序图标 ID */ + bool m_bNoClose; /* 禁用关闭按钮 */ + bool m_bNoMiniSize; /* 禁用最小化按钮 */ + bool m_bTopMost; /* 窗口置顶 */ + + EWindowStyle() + { + m_pIconID = 0; + m_bNoClose = false; + m_bNoMiniSize = false; + m_bTopMost = false; + } + + EWindowStyle( + LPCTSTR pIconID + ) + { + m_pIconID = pIconID; + m_bNoClose = false; + m_bNoMiniSize = false; + m_bTopMost = false; + } + + EWindowStyle( + LPCTSTR pIconID, + bool bNoClose, + bool bNoMiniSize, + bool bTopMost + ) + { + m_pIconID = pIconID; + m_bNoClose = bNoClose; + m_bNoMiniSize = bNoMiniSize; + m_bTopMost = bTopMost; + } +}; + +// 字符串 +class EString +{ +public: + EString(); + EString(const wchar_t *); + EString(const EString &); + EString(const std::wstring &); + EString(EString &&); + + ~EString(); + + EString& operator=(const wchar_t *); + EString& operator=(const EString &); + EString& operator=(const std::wstring &); + + bool operator==(const wchar_t *); + bool operator==(const EString &); + bool operator==(const std::wstring &); + + bool operator!=(const wchar_t *); + bool operator!=(const EString &); + bool operator!=(const std::wstring &); + + wchar_t &operator[](int); + + EString operator+(const wchar_t); + EString operator+(const wchar_t *); + EString operator+(const EString &); + EString operator+(const std::wstring &); + + template + EString &operator+(const T value) + { + EString str_temp(*this); + + str_temp += value; + return std::move(str_temp); + } + + EString &operator +=(const wchar_t); + EString &operator +=(const wchar_t *); + EString &operator +=(const EString &); + EString &operator +=(const std::wstring &); + + template + EString &operator +=(const T value) + { + std::wostringstream ss; + ss << value; + return (*this) += ss.str(); + } + + friend std::wistream &operator>>(std::wistream &, EString &); + + operator const wchar_t*() const { return _string; } + operator bool() const { return _size != 0; } + + // 判断字符串是否为空 + bool isEmpty() const { return _size == 0; } + + // 获取字符串长度 + int length() const { return _size; } + + // 获取大写字符串 + EString upper() const; + + // 获取小写字符串 + EString lower() const; + + // 获取裁剪字符串 + EString sub(int offset, int count = -1) const; + + // 获取字符串中第一个特定字符的下标 + int findFirstOf(wchar_t ch) const; + + // 获取字符串中最后一个特定字符的下标 + int findLastOf(wchar_t ch) const; + + // 后接字符 + EString &append(wchar_t ch); + + // 后接字符串 + EString &append(wchar_t *str); + + // 后接字符串 + EString &append(EString &str); + + // 后接字符串 + template + EString &append(T &value) + { + return (*this) += value; + } + + // 获取该字符串的散列值 + unsigned int hash() const; + + // 将模板类型转化为字符串 + template + static EString parse(const T value) + { + EString str; + + std::wostringstream ss; + ss << value; + str += ss.str(); + + return std::move(str); + } + +private: + wchar_t *_string; + int _size; +}; + +// 颜色 class EColor { public: @@ -154,7 +394,7 @@ public: }; }; - +// 字体粗细值 class EFontWeight { public: @@ -588,4 +828,36 @@ protected: ETexture * m_pTexture; }; +class ENode; + +// 定时器回调函数(参数为该定时器被调用的次数,从 0 开始) +typedef std::function TIMER_CALLBACK; + +// 按钮点击回调函数 +typedef std::function BUTTON_CLICK_CALLBACK; + +// 按键消息监听回调函数 +typedef std::function KEY_LISTENER_CALLBACK; + +// 鼠标消息监听回调函数 +typedef std::function MOUSE_LISTENER_CALLBACK; + +// 鼠标点击消息监听回调函数(参数为点击位置) +typedef std::function MOUSE_CLICK_LISTENER_CALLBACK; + +// 鼠标按下消息监听回调函数(参数为按下位置) +typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_PRESS_LISTENER_CALLBACK; + +// 鼠标双击消息监听回调函数(参数为双击位置) +typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_DBLCLK_LISTENER_CALLBACK; + +// 鼠标拖动消息监听回调函数(参数为拖动前位置和拖动后位置) +typedef std::function MOUSE_DRAG_LISTENER_CALLBACK; + +// 物理世界消息监听器回调函数 +typedef std::function PHYSICS_LISTENER_CALLBACK; + +// 碰撞消息监听器回调函数 +typedef PHYSICS_LISTENER_CALLBACK COLLISION_LISTENER_CALLBACK; + } \ No newline at end of file diff --git a/Easy2D/emacros.h b/Easy2D/emacros.h index 9d5a5075..79934a1a 100644 --- a/Easy2D/emacros.h +++ b/Easy2D/emacros.h @@ -30,8 +30,6 @@ // C RunTime Header Files #include -#include -#include #include #include #include diff --git a/Easy2D/enodes.h b/Easy2D/enodes.h index b031dcd5..c1493952 100644 --- a/Easy2D/enodes.h +++ b/Easy2D/enodes.h @@ -104,7 +104,7 @@ public: virtual EScene * getParentScene() const; // 获取所有子节点 - virtual EVector &getChildren(); + virtual std::vector &getChildren(); // 获取子节点数量 virtual size_t getChildrenCount() const; @@ -398,7 +398,7 @@ protected: ENode * m_pParent; D2D1::Matrix3x2F m_MatriInitial; D2D1::Matrix3x2F m_MatriFinal; - EVector m_vChildren; + std::vector m_vChildren; }; @@ -855,7 +855,7 @@ public: protected: bool m_bEnable; - EVector m_vButtons; + std::vector m_vButtons; }; } \ No newline at end of file diff --git a/Easy2D/etypedef.h b/Easy2D/etypedef.h deleted file mode 100644 index 1728a854..00000000 --- a/Easy2D/etypedef.h +++ /dev/null @@ -1,169 +0,0 @@ -#pragma once -#include -#include -#include -#include - -namespace e2d -{ - -struct EPoint -{ - float x; - float y; - - EPoint() - { - x = 0; - y = 0; - } - - EPoint(float x, float y) - { - this->x = x; - this->y = y; - } - - EPoint operator + (EPoint const & p) - { - return EPoint(x + p.x, y + p.y); - } - - EPoint operator - (EPoint const & p) - { - return EPoint(x - p.x, y - p.y); - } - - EPoint operator * (float const & value) - { - return EPoint(x * value, y * value); - } - - EPoint operator / (float const & value) - { - return EPoint(x / value, y / value); - } -}; - -struct ESize -{ - float width; - float height; - - ESize() - { - width = 0; - height = 0; - } - - ESize(float width, float height) - { - this->width = width; - this->height = height; - } - - ESize operator + (ESize const & size) - { - return ESize(width + size.width, height + size.height); - } - - ESize operator - (ESize const & size) - { - return ESize(width - size.width, height - size.height); - } - - ESize operator * (float const & value) - { - return ESize(width * value, height * value); - } - - ESize operator / (float const & value) - { - return ESize(width / value, height / value); - } -}; - - -struct EWindowStyle -{ - LPCTSTR m_pIconID; /* 程序图标 ID */ - bool m_bNoClose; /* 禁用关闭按钮 */ - bool m_bNoMiniSize; /* 禁用最小化按钮 */ - bool m_bTopMost; /* 窗口置顶 */ - - EWindowStyle() - { - m_pIconID = 0; - m_bNoClose = false; - m_bNoMiniSize = false; - m_bTopMost = false; - } - - EWindowStyle( - LPCTSTR pIconID - ) - { - m_pIconID = pIconID; - m_bNoClose = false; - m_bNoMiniSize = false; - m_bTopMost = false; - } - - EWindowStyle( - LPCTSTR pIconID, - bool bNoClose, - bool bNoMiniSize, - bool bTopMost - ) - { - m_pIconID = pIconID; - m_bNoClose = bNoClose; - m_bNoMiniSize = bNoMiniSize; - m_bTopMost = bTopMost; - } -}; - -// 二维向量 -typedef EPoint EVec; - -// 字符串 -typedef std::wstring EString; - -// Vector 容器 -template -using EVector = std::vector; - - -class ENode; - -// 定时器回调函数(参数为该定时器被调用的次数,从 0 开始) -typedef std::function TIMER_CALLBACK; - -// 按钮点击回调函数 -typedef std::function BUTTON_CLICK_CALLBACK; - -// 按键消息监听回调函数 -typedef std::function KEY_LISTENER_CALLBACK; - -// 鼠标消息监听回调函数 -typedef std::function MOUSE_LISTENER_CALLBACK; - -// 鼠标点击消息监听回调函数(参数为点击位置) -typedef std::function MOUSE_CLICK_LISTENER_CALLBACK; - -// 鼠标按下消息监听回调函数(参数为按下位置) -typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_PRESS_LISTENER_CALLBACK; - -// 鼠标双击消息监听回调函数(参数为双击位置) -typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_DBLCLK_LISTENER_CALLBACK; - -// 鼠标拖动消息监听回调函数(参数为拖动前位置和拖动后位置) -typedef std::function MOUSE_DRAG_LISTENER_CALLBACK; - -// 物理世界消息监听器回调函数 -typedef std::function PHYSICS_LISTENER_CALLBACK; - -// 碰撞消息监听器回调函数 -typedef PHYSICS_LISTENER_CALLBACK COLLISION_LISTENER_CALLBACK; - -} \ No newline at end of file