更新ENode
This commit is contained in:
parent
7f402c7593
commit
489fa780ca
|
|
@ -23,7 +23,7 @@
|
||||||
<ProjectGuid>{9D85A92F-BCCE-4EF0-BAD3-601C0086661C}</ProjectGuid>
|
<ProjectGuid>{9D85A92F-BCCE-4EF0-BAD3-601C0086661C}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>Demo</RootNamespace>
|
<RootNamespace>Demo</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
|
|
||||||
|
|
@ -10,37 +10,26 @@ int WINAPI WinMain(
|
||||||
{
|
{
|
||||||
EApp app;
|
EApp app;
|
||||||
|
|
||||||
if (app.init(L"Easy2D Demo", 640, 480, true))
|
if (app.init(L"Easy2D Demo", 640, 480))
|
||||||
{
|
{
|
||||||
auto scene = new EScene();
|
auto scene = new EScene();
|
||||||
|
|
||||||
auto node = new ENode();
|
auto node = new ENode(L"node1");
|
||||||
node->setPos(50, 80);
|
node->setPos(50, 80);
|
||||||
node->setSize(30, 180);
|
node->setSize(30, 30);
|
||||||
scene->add(node);
|
scene->add(node);
|
||||||
|
|
||||||
auto mlistener = new EMouseClickListener([=](EPoint) {
|
auto node2 = new ENode(L"node2");
|
||||||
node->setPos(EMouseMsg::getPos());
|
node2->setPos(20, 20);
|
||||||
});
|
node2->setSize(40, 40);
|
||||||
|
node->addChild(node2);
|
||||||
|
|
||||||
auto klistener = new EKeyPressListener([=] {
|
auto mlistener = new EMouseClickListener([](EPoint) {
|
||||||
if (EKeyMsg::isCapitalLockOn())
|
EApp::getCurrentScene()->getChild(L"node1")->setPos(EMouseMsg::getPos());
|
||||||
{
|
|
||||||
if (EKeyMsg::getVal() == EKeyMsg::KEY::LEFT)
|
|
||||||
{
|
|
||||||
node->move(-3, 0);
|
|
||||||
}
|
|
||||||
if (EKeyMsg::getVal() == EKeyMsg::KEY::RIGHT)
|
|
||||||
{
|
|
||||||
node->move(3, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mlistener->bindWith(node);
|
mlistener->bindWith(node);
|
||||||
|
|
||||||
scene->bindListener(klistener);
|
|
||||||
|
|
||||||
app.enterScene(scene);
|
app.enterScene(scene);
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ std::stack<e2d::EScene*> s_SceneStack;
|
||||||
e2d::EApp::EApp()
|
e2d::EApp::EApp()
|
||||||
: m_bRunning(false)
|
: m_bRunning(false)
|
||||||
, m_ClearColor(EColor::Black)
|
, m_ClearColor(EColor::Black)
|
||||||
, m_bSaveScene(true)
|
|
||||||
, m_pCurrentScene(nullptr)
|
, m_pCurrentScene(nullptr)
|
||||||
, m_pNextScene(nullptr)
|
, m_pNextScene(nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -340,15 +339,22 @@ void e2d::EApp::enterScene(EScene * scene, bool save /* = true */)
|
||||||
// 保存下一场景的指针
|
// 保存下一场景的指针
|
||||||
get()->m_pNextScene = scene;
|
get()->m_pNextScene = scene;
|
||||||
// 切换场景时,是否保存当前场景
|
// 切换场景时,是否保存当前场景
|
||||||
get()->m_bSaveScene = save;
|
if (get()->m_pCurrentScene)
|
||||||
|
{
|
||||||
|
get()->m_pCurrentScene->m_bWillSave = save;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::EApp::backScene()
|
void e2d::EApp::backScene()
|
||||||
{
|
{
|
||||||
// 从栈顶取出场景指针,作为下一场景
|
// 从栈顶取出场景指针,作为下一场景
|
||||||
get()->m_pNextScene = s_SceneStack.top();
|
get()->m_pNextScene = s_SceneStack.top();
|
||||||
|
s_SceneStack.pop();
|
||||||
// 不保存当前场景
|
// 不保存当前场景
|
||||||
get()->m_bSaveScene = false;
|
if (get()->m_pCurrentScene)
|
||||||
|
{
|
||||||
|
get()->m_pCurrentScene->m_bWillSave = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::EApp::clearScene()
|
void e2d::EApp::clearScene()
|
||||||
|
|
@ -404,7 +410,7 @@ void e2d::EApp::free()
|
||||||
SafeDelete(&temp);
|
SafeDelete(&temp);
|
||||||
s_SceneStack.pop();
|
s_SceneStack.pop();
|
||||||
}
|
}
|
||||||
// 删除所有定时器、监听器
|
// 删除所有定时器、监听器和动画
|
||||||
//Timer::clearAllTimers();
|
//Timer::clearAllTimers();
|
||||||
EMsgManager::clearAllKeyboardListeners();
|
EMsgManager::clearAllKeyboardListeners();
|
||||||
EMsgManager::clearAllMouseListeners();
|
EMsgManager::clearAllMouseListeners();
|
||||||
|
|
@ -425,36 +431,18 @@ void e2d::EApp::end()
|
||||||
|
|
||||||
void e2d::EApp::_enterNextScene()
|
void e2d::EApp::_enterNextScene()
|
||||||
{
|
{
|
||||||
// 若下一场景处于栈顶,说明正在返回上一场景
|
|
||||||
if (s_SceneStack.size() && m_pNextScene == s_SceneStack.top())
|
|
||||||
{
|
|
||||||
// 返回上一场景时,恢复场景上的定时器
|
|
||||||
//Timer::notifyAllSceneTimers(m_pNextScene);
|
|
||||||
EMsgManager::notifyAllListenersBindWithScene(m_pNextScene);
|
|
||||||
//ActionManager::notifyAllSceneActions(m_pNextScene);
|
|
||||||
// 删除栈顶场景
|
|
||||||
s_SceneStack.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行当前场景的 onExit 函数
|
// 执行当前场景的 onExit 函数
|
||||||
if (m_pCurrentScene)
|
if (m_pCurrentScene)
|
||||||
{
|
{
|
||||||
m_pCurrentScene->onExit();
|
m_pCurrentScene->onExit();
|
||||||
if (m_bSaveScene)
|
|
||||||
|
if (m_pCurrentScene->m_bWillSave)
|
||||||
{
|
{
|
||||||
// 若要保存当前场景,把它放入栈中
|
// 若要保存当前场景,把它放入栈中
|
||||||
s_SceneStack.push(m_pCurrentScene);
|
s_SceneStack.push(m_pCurrentScene);
|
||||||
// 暂停当前场景上运行的所有定时器
|
|
||||||
//Timer::waitAllSceneTimers(m_pCurrentScene);
|
|
||||||
EMsgManager::waitAllListenersBindWithScene(m_pCurrentScene);
|
|
||||||
//ActionManager::waitAllSceneActions(m_pCurrentScene);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 不保存场景时,停止当前场景上运行的所有定时器,并删除当前场景
|
|
||||||
//Timer::clearAllSceneTimers(m_pCurrentScene);
|
|
||||||
EMsgManager::clearAllListenersBindWithScene(m_pCurrentScene);
|
|
||||||
//ActionManager::stopAllSceneActions(m_pCurrentScene);
|
|
||||||
SafeDelete(&m_pCurrentScene);
|
SafeDelete(&m_pCurrentScene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,79 +1,91 @@
|
||||||
#include "..\ebase.h"
|
#include "..\ebase.h"
|
||||||
#include "..\enodes.h"
|
#include "..\enodes.h"
|
||||||
#include "..\emsg.h"
|
#include "..\emsg.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
e2d::EScene::EScene()
|
||||||
|
: m_bWillSave(true)
|
||||||
|
, m_bSortNeeded(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
e2d::EScene::~EScene()
|
e2d::EScene::~EScene()
|
||||||
{
|
{
|
||||||
clearAllChildren();
|
clearAllChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void e2d::EScene::_exec()
|
|
||||||
{
|
|
||||||
// active 标志画面是否取得焦点
|
|
||||||
bool active = true;
|
|
||||||
// 逆序执行,最后绘制的节点(即位于画面最上方)最先被访问
|
|
||||||
for (int i = int(m_vChildren.size()) - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (m_vChildren[i]->_exec(active)) // 执行节点程序
|
|
||||||
{
|
|
||||||
active = false; // 若子节点取得焦点,将标志置 false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void e2d::EScene::_onRender()
|
void e2d::EScene::_onRender()
|
||||||
{
|
{
|
||||||
// 绘制所有节点
|
this->_sortChildren();
|
||||||
|
|
||||||
|
// 访问所有节点
|
||||||
for (auto child : m_vChildren)
|
for (auto child : m_vChildren)
|
||||||
{
|
{
|
||||||
child->_onRender();
|
child->callOn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EScene::_sortChildren()
|
||||||
|
{
|
||||||
|
if (m_bSortNeeded)
|
||||||
|
{
|
||||||
|
m_bSortNeeded = false;
|
||||||
|
|
||||||
|
// 子节点排序
|
||||||
|
std::sort(
|
||||||
|
std::begin(m_vChildren),
|
||||||
|
std::end(m_vChildren),
|
||||||
|
[](ENode * n1, ENode * n2) {
|
||||||
|
return n1->getOrder() < n2->getOrder();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::EScene::onEnter()
|
void e2d::EScene::onEnter()
|
||||||
{
|
{
|
||||||
|
// 启用场景上的所有定时器、监听器和动画
|
||||||
|
//Timer::notifyAllSceneTimers(m_pNextScene);
|
||||||
|
EMsgManager::notifyAllListenersBindWithScene(this);
|
||||||
|
//ActionManager::notifyAllSceneActions(m_pNextScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::EScene::onExit()
|
void e2d::EScene::onExit()
|
||||||
{
|
{
|
||||||
}
|
if (m_bWillSave)
|
||||||
|
|
||||||
void e2d::EScene::add(ENode * child, int zOrder /* = 0 */)
|
|
||||||
{
|
{
|
||||||
// 断言添加的节点非空
|
//Timer::waitAllSceneTimers(m_pCurrentScene);
|
||||||
ASSERT(child != nullptr, "Scene::add NULL pointer exception.");
|
EMsgManager::waitAllListenersBindWithScene(this);
|
||||||
// 忽略空指针
|
//ActionManager::waitAllSceneActions(m_pCurrentScene);
|
||||||
if (child == nullptr) return;
|
|
||||||
// 设置节点的父场景
|
|
||||||
child->setParentScene(this);
|
|
||||||
// 设置 z 轴顺序
|
|
||||||
child->setZOrder(zOrder);
|
|
||||||
// 对象的引用计数加一
|
|
||||||
child->retain();
|
|
||||||
|
|
||||||
// 按 z 轴顺序插入节点
|
|
||||||
size_t size = m_vChildren.size();
|
|
||||||
for (unsigned i = 0; i <= size; i++)
|
|
||||||
{
|
|
||||||
if (i == size)
|
|
||||||
{
|
|
||||||
m_vChildren.push_back(child);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto temp = m_vChildren.at(i);
|
//Timer::clearAllSceneTimers(m_pCurrentScene);
|
||||||
if (temp->getZOrder() > zOrder)
|
EMsgManager::clearAllListenersBindWithScene(this);
|
||||||
{
|
//ActionManager::stopAllSceneActions(m_pCurrentScene);
|
||||||
m_vChildren.insert(m_vChildren.begin() + i, child);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::EScene::del(ENode * child, bool autoRelease /* = true */)
|
void e2d::EScene::add(ENode * child, int order /* = 0 */)
|
||||||
|
{
|
||||||
|
ASSERT(child != nullptr, "Scene::add NULL pointer exception.");
|
||||||
|
ASSERT(child->getParentScene() == nullptr, "Child already added. It can't be added again!");
|
||||||
|
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
child->setParentScene(this);
|
||||||
|
|
||||||
|
child->setOrder(order);
|
||||||
|
|
||||||
|
child->retain();
|
||||||
|
|
||||||
|
m_vChildren.push_back(child);
|
||||||
|
|
||||||
|
m_bSortNeeded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::EScene::remove(ENode * child, bool autoRelease /* = true */)
|
||||||
{
|
{
|
||||||
if (child == nullptr) return false;
|
if (child == nullptr) return false;
|
||||||
|
|
||||||
|
|
@ -84,7 +96,8 @@ bool e2d::EScene::del(ENode * child, bool autoRelease /* = true */)
|
||||||
// 找到相同节点
|
// 找到相同节点
|
||||||
if (*iter == child)
|
if (*iter == child)
|
||||||
{
|
{
|
||||||
if (autoRelease) (*iter)->autoRelease();
|
if (autoRelease)
|
||||||
|
(*iter)->autoRelease();
|
||||||
// 对象的引用计数减一
|
// 对象的引用计数减一
|
||||||
(*iter)->release();
|
(*iter)->release();
|
||||||
// 去掉该节点
|
// 去掉该节点
|
||||||
|
|
@ -101,6 +114,16 @@ std::vector<e2d::ENode*>& e2d::EScene::getChildren()
|
||||||
return m_vChildren;
|
return m_vChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t e2d::EScene::getChildrenCount() const
|
||||||
|
{
|
||||||
|
return m_vChildren.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::ENode * e2d::EScene::getChild(EString childName) const
|
||||||
|
{
|
||||||
|
return ENode::getChild(childName, m_vChildren);
|
||||||
|
}
|
||||||
|
|
||||||
void e2d::EScene::clearAllChildren()
|
void e2d::EScene::clearAllChildren()
|
||||||
{
|
{
|
||||||
// 所有节点的引用计数减一
|
// 所有节点的引用计数减一
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<ProjectGuid>{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}</ProjectGuid>
|
<ProjectGuid>{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>Easy2D</RootNamespace>
|
<RootNamespace>Easy2D</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
|
@ -203,6 +203,7 @@
|
||||||
<ClCompile Include="Msg\Listener\EMouseDraggedListener.cpp" />
|
<ClCompile Include="Msg\Listener\EMouseDraggedListener.cpp" />
|
||||||
<ClCompile Include="Msg\Listener\EMouseListener.cpp" />
|
<ClCompile Include="Msg\Listener\EMouseListener.cpp" />
|
||||||
<ClCompile Include="Node\ENode.cpp" />
|
<ClCompile Include="Node\ENode.cpp" />
|
||||||
|
<ClCompile Include="Node\ERectangle.cpp" />
|
||||||
<ClCompile Include="Tool\EObjectManager.cpp" />
|
<ClCompile Include="Tool\EObjectManager.cpp" />
|
||||||
<ClCompile Include="Tool\ETimerManager.cpp" />
|
<ClCompile Include="Tool\ETimerManager.cpp" />
|
||||||
<ClCompile Include="Win\winbase.cpp" />
|
<ClCompile Include="Win\winbase.cpp" />
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,9 @@
|
||||||
<ClCompile Include="Msg\Listener\EKeyPressListener.cpp">
|
<ClCompile Include="Msg\Listener\EKeyPressListener.cpp">
|
||||||
<Filter>Msg\Listener</Filter>
|
<Filter>Msg\Listener</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Node\ERectangle.cpp">
|
||||||
|
<Filter>Node</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Win\winbase.h">
|
<ClInclude Include="Win\winbase.h">
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
#include "..\enodes.h"
|
#include "..\enodes.h"
|
||||||
#include "..\Win\winbase.h"
|
#include "..\Win\winbase.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
e2d::ENode::ENode()
|
e2d::ENode::ENode()
|
||||||
: m_nZOrder(0)
|
: m_nOrder(0)
|
||||||
, m_bVisiable(true)
|
, m_bVisiable(true)
|
||||||
, m_pParent(nullptr)
|
, m_pParent(nullptr)
|
||||||
, m_pParentScene(nullptr)
|
, m_pParentScene(nullptr)
|
||||||
, m_nHashName(0)
|
, m_nHashName(0)
|
||||||
|
, m_bSortNeeded(false)
|
||||||
|
, m_bTransformNeeded(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -20,46 +23,114 @@ e2d::ENode::~ENode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void e2d::ENode::callOn()
|
||||||
|
{
|
||||||
|
if (!m_bVisiable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_transfrom();
|
||||||
|
|
||||||
|
if (!m_vChildren.empty())
|
||||||
|
{
|
||||||
|
this->_sortChildren();
|
||||||
|
|
||||||
|
size_t size = m_vChildren.size();
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
auto child = m_vChildren[i];
|
||||||
|
// 访问 Order 小于零的节点
|
||||||
|
if (child->getOrder() < 0)
|
||||||
|
{
|
||||||
|
child->callOn();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染自身
|
||||||
|
this->_onRender();
|
||||||
|
|
||||||
|
// 访问剩余节点
|
||||||
|
for (; i < size; i++)
|
||||||
|
m_vChildren[i]->callOn();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 渲染自身
|
||||||
|
this->_onRender();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void e2d::ENode::_onRender()
|
void e2d::ENode::_onRender()
|
||||||
{
|
{
|
||||||
D2D1_RECT_F rectangle = D2D1::RectF(
|
}
|
||||||
m_Rect.left,
|
|
||||||
m_Rect.top,
|
void e2d::ENode::_onTransfrom()
|
||||||
m_Rect.right,
|
{
|
||||||
m_Rect.bottom
|
}
|
||||||
|
|
||||||
|
void e2d::ENode::_sortChildren()
|
||||||
|
{
|
||||||
|
if (m_bSortNeeded)
|
||||||
|
{
|
||||||
|
// 子节点排序
|
||||||
|
std::sort(
|
||||||
|
std::begin(m_vChildren),
|
||||||
|
std::end(m_vChildren),
|
||||||
|
[](ENode * n1, ENode * n2) {
|
||||||
|
return n1->getOrder() < n2->getOrder();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
|
|
||||||
GetRenderTarget()->CreateSolidColorBrush(
|
m_bSortNeeded = false;
|
||||||
D2D1::ColorF(D2D1::ColorF::LightSlateGray),
|
}
|
||||||
&m_pLightSlateGrayBrush
|
}
|
||||||
);
|
|
||||||
GetRenderTarget()->FillRectangle(&rectangle, m_pLightSlateGrayBrush);
|
void e2d::ENode::_transfrom()
|
||||||
|
{
|
||||||
|
if (m_bTransformNeeded)
|
||||||
|
{
|
||||||
|
// 更新自身属性
|
||||||
|
if (m_pParent)
|
||||||
|
{
|
||||||
|
this->setPos(m_pParent->getX() + m_Pos.x, m_pParent->getY() + m_Pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据子节点特殊性进行更新
|
||||||
|
_onTransfrom();
|
||||||
|
|
||||||
|
// 提示子节点更新属性
|
||||||
|
for (const auto &child : m_vChildren)
|
||||||
|
{
|
||||||
|
child->m_bTransformNeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bTransformNeeded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::ENode::isVisiable() const
|
||||||
|
{
|
||||||
|
return m_bVisiable;
|
||||||
}
|
}
|
||||||
|
|
||||||
int e2d::ENode::getX() const
|
int e2d::ENode::getX() const
|
||||||
{
|
{
|
||||||
if (m_pParent)
|
|
||||||
{
|
|
||||||
return m_pParent->getX() + m_Rect.TopLeft().x;
|
|
||||||
}
|
|
||||||
return m_Rect.TopLeft().x;
|
return m_Rect.TopLeft().x;
|
||||||
}
|
}
|
||||||
|
|
||||||
int e2d::ENode::getY() const
|
int e2d::ENode::getY() const
|
||||||
{
|
{
|
||||||
if (m_pParent)
|
|
||||||
{
|
|
||||||
return m_pParent->getY() + m_Rect.TopLeft().y;
|
|
||||||
}
|
|
||||||
return m_Rect.TopLeft().y;
|
return m_Rect.TopLeft().y;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPoint e2d::ENode::getPos() const
|
CPoint e2d::ENode::getPos() const
|
||||||
{
|
{
|
||||||
if (m_pParent)
|
|
||||||
{
|
|
||||||
return m_pParent->getPos() + m_Rect.TopLeft();
|
|
||||||
}
|
|
||||||
return m_Rect.TopLeft();
|
return m_Rect.TopLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,22 +156,31 @@ e2d::ERect e2d::ENode::getRect() const
|
||||||
|
|
||||||
void e2d::ENode::setX(int x)
|
void e2d::ENode::setX(int x)
|
||||||
{
|
{
|
||||||
m_Rect.MoveToX(x);
|
this->setPos(x, m_Rect.TopLeft().y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::setY(int y)
|
void e2d::ENode::setY(int y)
|
||||||
{
|
{
|
||||||
m_Rect.MoveToY(y);
|
this->setPos(m_Rect.TopLeft().x, y);
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setPos(int x, int y)
|
|
||||||
{
|
|
||||||
m_Rect.MoveToXY(x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::setPos(EPoint p)
|
void e2d::ENode::setPos(EPoint p)
|
||||||
{
|
{
|
||||||
m_Rect.MoveToXY(p.x, p.y);
|
this->setPos(p.x, p.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::ENode::setPos(int x, int y)
|
||||||
|
{
|
||||||
|
if (getX() == x && getY() == y)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!m_bTransformNeeded)
|
||||||
|
{
|
||||||
|
m_Pos.x = x;
|
||||||
|
m_Pos.y = y;
|
||||||
|
m_bTransformNeeded = true;
|
||||||
|
}
|
||||||
|
m_Rect.MoveToXY(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::move(int x, int y)
|
void e2d::ENode::move(int x, int y)
|
||||||
|
|
@ -125,13 +205,13 @@ void e2d::ENode::setHeight(UINT32 height)
|
||||||
|
|
||||||
void e2d::ENode::setSize(UINT32 width, UINT32 height)
|
void e2d::ENode::setSize(UINT32 width, UINT32 height)
|
||||||
{
|
{
|
||||||
setWidth(width);
|
m_Rect.BottomRight().x = m_Rect.TopLeft().x + width;
|
||||||
setHeight(height);
|
m_Rect.BottomRight().y = m_Rect.TopLeft().y + height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::setSize(ESize size)
|
void e2d::ENode::setSize(ESize size)
|
||||||
{
|
{
|
||||||
setSize(size.cx, size.cy);
|
this->setSize(size.cx, size.cy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::setRect(int x1, int y1, int x2, int y2)
|
void e2d::ENode::setRect(int x1, int y1, int x2, int y2)
|
||||||
|
|
@ -150,40 +230,58 @@ void e2d::ENode::setRect(ERect rect)
|
||||||
m_Rect = rect;
|
m_Rect = rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
int e2d::ENode::getZOrder() const
|
int e2d::ENode::getOrder() const
|
||||||
{
|
{
|
||||||
return m_nZOrder;
|
return m_nOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::setZOrder(int z)
|
void e2d::ENode::setOrder(int order)
|
||||||
{
|
{
|
||||||
m_nZOrder = z;
|
m_nOrder = order;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::setParent(ENode * parent)
|
void e2d::ENode::setParent(ENode * parent)
|
||||||
{
|
{
|
||||||
m_pParent = parent;
|
if (m_pParent)
|
||||||
|
{
|
||||||
|
m_pParent->addChild(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeFromParent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::addChild(ENode * child)
|
void e2d::ENode::addChild(ENode * child, int order /* = 0 */)
|
||||||
{
|
{
|
||||||
WARN_IF(child == nullptr, "NULL ENode pointer exception.");
|
WARN_IF(child == nullptr, "ENode::addChild NULL pointer exception.");
|
||||||
|
ASSERT(child->m_pParent == nullptr, "Child already added. It can't be added again!");
|
||||||
|
|
||||||
if (child)
|
if (child)
|
||||||
{
|
{
|
||||||
for (ENode * parent = this; parent != nullptr; parent = parent->getParent())
|
for (ENode * parent = this; parent != nullptr; parent = parent->getParent())
|
||||||
{
|
{
|
||||||
ASSERT(child != parent, "A ENode cannot be the child of his own children");
|
ASSERT(child != parent, "A ENode cannot be the child of his own children!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_vChildren.push_back(child);
|
||||||
|
|
||||||
|
child->m_pParent = this;
|
||||||
|
|
||||||
|
child->setOrder(order);
|
||||||
|
|
||||||
|
child->retain();
|
||||||
|
|
||||||
|
m_bSortNeeded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::ENode *& e2d::ENode::getParent()
|
e2d::ENode * e2d::ENode::getParent() const
|
||||||
{
|
{
|
||||||
return m_pParent;
|
return m_pParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::EScene * &e2d::ENode::getParentScene()
|
e2d::EScene * e2d::ENode::getParentScene() const
|
||||||
{
|
{
|
||||||
return m_pParentScene;
|
return m_pParentScene;
|
||||||
}
|
}
|
||||||
|
|
@ -193,19 +291,24 @@ std::vector<e2d::ENode*>& e2d::ENode::getChildren()
|
||||||
return m_vChildren;
|
return m_vChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
int e2d::ENode::getChildrenCount() const
|
size_t e2d::ENode::getChildrenCount() const
|
||||||
{
|
{
|
||||||
return m_vChildren.size();
|
return m_vChildren.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::ENode * e2d::ENode::getChild(EString name)
|
e2d::ENode * e2d::ENode::getChild(EString name) const
|
||||||
|
{
|
||||||
|
return ENode::getChild(name, this->m_vChildren);
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::ENode * e2d::ENode::getChild(EString name, const std::vector<ENode*> &children)
|
||||||
{
|
{
|
||||||
WARN_IF(name.empty(), "Invalid ENode name.");
|
WARN_IF(name.empty(), "Invalid ENode name.");
|
||||||
|
|
||||||
std::hash<EString> h;
|
std::hash<EString> h;
|
||||||
size_t hash = h(name);
|
size_t hash = h(name);
|
||||||
|
|
||||||
for (const auto& child : m_vChildren)
|
for (const auto& child : children)
|
||||||
{
|
{
|
||||||
// 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度
|
// 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度
|
||||||
if (child->m_nHashName == hash && child->m_sName == name)
|
if (child->m_nHashName == hash && child->m_sName == name)
|
||||||
|
|
@ -215,20 +318,73 @@ e2d::ENode * e2d::ENode::getChild(EString name)
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::setParentScene(EScene * scene)
|
void e2d::ENode::setParentScene(EScene * scene)
|
||||||
|
{
|
||||||
|
if (m_pParentScene)
|
||||||
{
|
{
|
||||||
m_pParentScene = scene;
|
m_pParentScene = scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::removeFromParent(bool release)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::removeChild(ENode * child, bool release)
|
void e2d::ENode::removeFromParent(bool release /* = false */)
|
||||||
{
|
{
|
||||||
|
if (m_pParent)
|
||||||
|
{
|
||||||
|
m_pParent->removeChild(this, release);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::removeChild(EString childName, bool release)
|
void e2d::ENode::removeChild(ENode * child, bool release /* = false */)
|
||||||
{
|
{
|
||||||
|
WARN_IF(child == nullptr, "ENode::removeChild NULL pointer exception.");
|
||||||
|
|
||||||
|
if (m_vChildren.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
size_t size = m_vChildren.size();
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (m_vChildren[i] == child)
|
||||||
|
{
|
||||||
|
m_vChildren.erase(m_vChildren.begin() + i);
|
||||||
|
child->m_pParent = nullptr;
|
||||||
|
child->release();
|
||||||
|
if (release)
|
||||||
|
child->autoRelease();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::ENode::removeChild(EString childName, bool release /* = false */)
|
||||||
|
{
|
||||||
|
WARN_IF(childName.empty(), "Invalid ENode name.");
|
||||||
|
|
||||||
|
if (m_vChildren.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::hash<EString> h;
|
||||||
|
size_t hash = h(childName);
|
||||||
|
size_t size = m_vChildren.size();
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
auto child = m_vChildren[i];
|
||||||
|
if (child->m_nHashName == hash && child->m_sName == childName)
|
||||||
|
{
|
||||||
|
m_vChildren.erase(m_vChildren.begin() + i);
|
||||||
|
child->m_pParent = nullptr;
|
||||||
|
child->release();
|
||||||
|
if (release)
|
||||||
|
child->autoRelease();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::ENode::setVisiable(bool value)
|
void e2d::ENode::setVisiable(bool value)
|
||||||
|
|
@ -249,8 +405,3 @@ void e2d::ENode::setName(EString name)
|
||||||
m_nHashName = h(name);
|
m_nHashName = h(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::ENode::isVisiable() const
|
|
||||||
{
|
|
||||||
return m_bVisiable;
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "..\enodes.h"
|
||||||
|
#include "..\Win\winbase.h"
|
||||||
|
|
||||||
|
|
||||||
|
void e2d::ERectangle::_onRender()
|
||||||
|
{
|
||||||
|
static D2D1_RECT_F rectangle = D2D1::RectF(
|
||||||
|
m_Rect.left,
|
||||||
|
m_Rect.top,
|
||||||
|
m_Rect.right,
|
||||||
|
m_Rect.bottom
|
||||||
|
);
|
||||||
|
GetRenderTarget()->FillRectangle(&rectangle, GetSolidColorBrush(D2D1::ColorF(D2D1::ColorF::LightSlateGray)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::ERectangle::_onTransfrom()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
HWND hwnd = nullptr;
|
HWND hwnd = nullptr;
|
||||||
ID2D1Factory * pDirect2dFactory = nullptr;
|
ID2D1Factory * pDirect2dFactory = nullptr;
|
||||||
ID2D1HwndRenderTarget * pRenderTarget = nullptr;
|
ID2D1HwndRenderTarget * pRenderTarget = nullptr;
|
||||||
|
ID2D1SolidColorBrush * m_pSolidBrush = nullptr;
|
||||||
|
|
||||||
|
|
||||||
HWND &GetHWnd()
|
HWND &GetHWnd()
|
||||||
|
|
@ -21,3 +22,9 @@ ID2D1HwndRenderTarget * &GetRenderTarget()
|
||||||
return pRenderTarget;
|
return pRenderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ID2D1SolidColorBrush *& GetSolidColorBrush(D2D1_COLOR_F & color)
|
||||||
|
{
|
||||||
|
pRenderTarget->CreateSolidColorBrush(color, &m_pSolidBrush);
|
||||||
|
return m_pSolidBrush;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ ID2D1Factory * &GetFactory();
|
||||||
|
|
||||||
ID2D1HwndRenderTarget * &GetRenderTarget();
|
ID2D1HwndRenderTarget * &GetRenderTarget();
|
||||||
|
|
||||||
|
ID2D1SolidColorBrush * &GetSolidColorBrush(D2D1_COLOR_F &color);
|
||||||
|
|
||||||
|
|
||||||
template<class Interface>
|
template<class Interface>
|
||||||
inline void SafeReleaseInterface(
|
inline void SafeReleaseInterface(
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,6 @@ protected:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool m_bRunning;
|
bool m_bRunning;
|
||||||
bool m_bSaveScene;
|
|
||||||
EString m_sTitle;
|
EString m_sTitle;
|
||||||
EString m_sAppName;
|
EString m_sAppName;
|
||||||
EColor::Enum m_ClearColor;
|
EColor::Enum m_ClearColor;
|
||||||
|
|
@ -164,7 +163,7 @@ class EScene
|
||||||
friend EApp;
|
friend EApp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EScene() = default;
|
EScene();
|
||||||
|
|
||||||
~EScene();
|
~EScene();
|
||||||
|
|
||||||
|
|
@ -181,7 +180,7 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// 删除子成员
|
// 删除子成员
|
||||||
bool del(
|
bool remove(
|
||||||
e2d::ENode * child,
|
e2d::ENode * child,
|
||||||
bool autoRelease = true
|
bool autoRelease = true
|
||||||
);
|
);
|
||||||
|
|
@ -189,6 +188,14 @@ public:
|
||||||
// 获取所有子节点
|
// 获取所有子节点
|
||||||
std::vector<e2d::ENode*> &getChildren();
|
std::vector<e2d::ENode*> &getChildren();
|
||||||
|
|
||||||
|
// 获取子节点数量
|
||||||
|
size_t getChildrenCount() const;
|
||||||
|
|
||||||
|
// 根据名称获取子节点
|
||||||
|
ENode * getChild(
|
||||||
|
EString childName
|
||||||
|
) const;
|
||||||
|
|
||||||
// 清空所有子成员
|
// 清空所有子成员
|
||||||
void clearAllChildren();
|
void clearAllChildren();
|
||||||
|
|
||||||
|
|
@ -202,7 +209,12 @@ protected:
|
||||||
// 渲染场景画面
|
// 渲染场景画面
|
||||||
void _onRender();
|
void _onRender();
|
||||||
|
|
||||||
|
// 子节点排序
|
||||||
|
void _sortChildren();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool m_bSortNeeded;
|
||||||
|
bool m_bWillSave;
|
||||||
std::vector<e2d::ENode*> m_vChildren;
|
std::vector<e2d::ENode*> m_vChildren;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ namespace e2d
|
||||||
class ENode :
|
class ENode :
|
||||||
public EObject
|
public EObject
|
||||||
{
|
{
|
||||||
friend EScene;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ENode();
|
ENode();
|
||||||
|
|
||||||
|
|
@ -22,7 +20,7 @@ public:
|
||||||
virtual bool isVisiable() const;
|
virtual bool isVisiable() const;
|
||||||
|
|
||||||
// 获取节点绘图顺序
|
// 获取节点绘图顺序
|
||||||
virtual int getZOrder() const;
|
virtual int getOrder() const;
|
||||||
|
|
||||||
// 获取节点横坐标
|
// 获取节点横坐标
|
||||||
virtual int getX() const;
|
virtual int getX() const;
|
||||||
|
|
@ -46,19 +44,27 @@ public:
|
||||||
virtual ERect getRect() const;
|
virtual ERect getRect() const;
|
||||||
|
|
||||||
// 获取父节点
|
// 获取父节点
|
||||||
virtual ENode * &getParent();
|
virtual ENode * getParent() const;
|
||||||
|
|
||||||
// 获取节点所在场景
|
// 获取节点所在场景
|
||||||
virtual EScene * &getParentScene();
|
virtual EScene * getParentScene() const;
|
||||||
|
|
||||||
// 获取所有子节点
|
// 获取所有子节点
|
||||||
virtual std::vector<ENode*> &getChildren();
|
virtual std::vector<ENode*> &getChildren();
|
||||||
|
|
||||||
// 获取子节点数量
|
// 获取子节点数量
|
||||||
virtual int getChildrenCount() const;
|
virtual size_t getChildrenCount() const;
|
||||||
|
|
||||||
// 根据名字获取子节点
|
// 根据名字获取子节点
|
||||||
virtual ENode * getChild(EString name);
|
virtual ENode * getChild(
|
||||||
|
EString name
|
||||||
|
) const;
|
||||||
|
|
||||||
|
// 根据名字获取子节点
|
||||||
|
static ENode * getChild(
|
||||||
|
EString name,
|
||||||
|
const std::vector<ENode*> &children
|
||||||
|
);
|
||||||
|
|
||||||
// 设置节点是否显示
|
// 设置节点是否显示
|
||||||
virtual void setVisiable(
|
virtual void setVisiable(
|
||||||
|
|
@ -66,7 +72,9 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// 设置节点名称
|
// 设置节点名称
|
||||||
virtual void setName(EString name);
|
virtual void setName(
|
||||||
|
EString name
|
||||||
|
);
|
||||||
|
|
||||||
// 设置节点横坐标
|
// 设置节点横坐标
|
||||||
virtual void setX(
|
virtual void setX(
|
||||||
|
|
@ -140,9 +148,9 @@ public:
|
||||||
ERect rect
|
ERect rect
|
||||||
);
|
);
|
||||||
|
|
||||||
// 设置节点绘图顺序(0为最先绘制,显示在最底层)
|
// 设置节点绘图顺序
|
||||||
virtual void setZOrder(
|
virtual void setOrder(
|
||||||
int z
|
int order
|
||||||
);
|
);
|
||||||
|
|
||||||
// 设置节点所在场景
|
// 设置节点所在场景
|
||||||
|
|
@ -156,30 +164,66 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// 添加子节点
|
// 添加子节点
|
||||||
virtual void addChild(ENode * child);
|
virtual void addChild(
|
||||||
|
ENode * child,
|
||||||
|
int order = 0
|
||||||
|
);
|
||||||
|
|
||||||
// 从父节点移除
|
// 从父节点移除
|
||||||
virtual void removeFromParent(bool release = false);
|
virtual void removeFromParent(
|
||||||
|
bool release = false
|
||||||
|
);
|
||||||
|
|
||||||
// 移除子节点
|
// 移除子节点
|
||||||
virtual void removeChild(ENode * child, bool release = false);
|
virtual void removeChild(
|
||||||
|
ENode * child,
|
||||||
|
bool release = false
|
||||||
|
);
|
||||||
|
|
||||||
// 移除子节点
|
// 移除子节点
|
||||||
virtual void removeChild(EString childName, bool release = false);
|
virtual void removeChild(
|
||||||
|
EString childName,
|
||||||
|
bool release = false
|
||||||
|
);
|
||||||
|
|
||||||
|
// 访问节点
|
||||||
|
virtual void callOn();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// 渲染节点
|
// 渲染节点
|
||||||
virtual void _onRender();
|
virtual void _onRender();
|
||||||
|
|
||||||
|
// 节点状态转换
|
||||||
|
virtual void _onTransfrom();
|
||||||
|
|
||||||
|
// 子节点排序
|
||||||
|
void _sortChildren();
|
||||||
|
|
||||||
|
// 节点状态转换
|
||||||
|
void _transfrom();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EString m_sName;
|
EString m_sName;
|
||||||
size_t m_nHashName;
|
size_t m_nHashName;
|
||||||
int m_nZOrder;
|
int m_nOrder;
|
||||||
bool m_bVisiable;
|
bool m_bVisiable;
|
||||||
|
bool m_bSortNeeded;
|
||||||
|
bool m_bTransformNeeded;
|
||||||
ERect m_Rect;
|
ERect m_Rect;
|
||||||
|
EPoint m_Pos;
|
||||||
EScene * m_pParentScene;
|
EScene * m_pParentScene;
|
||||||
ENode * m_pParent;
|
ENode * m_pParent;
|
||||||
std::vector<ENode*> m_vChildren;
|
std::vector<ENode*> m_vChildren;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ERectangle :
|
||||||
|
public ENode
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual void _onRender() override;
|
||||||
|
|
||||||
|
virtual void _onTransfrom() override;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -27,6 +27,14 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 定时器
|
||||||
|
class ETimer :
|
||||||
|
public EObject
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// 定时器管理器
|
// 定时器管理器
|
||||||
class ETimerManager
|
class ETimerManager
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue