optimize: intrusive list supported
This commit is contained in:
parent
298f686729
commit
eb59f7b245
|
|
@ -21,6 +21,7 @@
|
|||
#pragma once
|
||||
#include "base.h"
|
||||
#include "time.h"
|
||||
#include "IntrusiveList.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -28,6 +29,7 @@ namespace easy2d
|
|||
|
||||
class Action
|
||||
: public RefCounter
|
||||
, public IntrusiveItem<spAction>
|
||||
{
|
||||
E2D_DISABLE_COPY(Action);
|
||||
|
||||
|
|
@ -42,18 +44,18 @@ namespace easy2d
|
|||
virtual ~Action() {}
|
||||
|
||||
// 获取动作运行状态
|
||||
inline bool IsRunning() { return running_; }
|
||||
virtual bool IsRunning() { return running_; }
|
||||
|
||||
// 继续动作
|
||||
inline void Resume() { running_ = true; }
|
||||
virtual void Resume() { running_ = true; }
|
||||
|
||||
// 暂停动作
|
||||
inline void Pause() { running_ = false; }
|
||||
virtual void Pause() { running_ = false; }
|
||||
|
||||
// 停止动作
|
||||
inline void Stop() { done_ = true; }
|
||||
virtual void Stop() { done_ = true; }
|
||||
|
||||
inline bool IsDone() const { return done_; }
|
||||
virtual bool IsDone() const { return done_; }
|
||||
|
||||
// 获取动作的拷贝
|
||||
virtual spAction Clone() const = 0;
|
||||
|
|
|
|||
|
|
@ -80,12 +80,6 @@ namespace easy2d
|
|||
{
|
||||
Action::Update(target, dt);
|
||||
|
||||
if (times_ == total_times_)
|
||||
{
|
||||
this->Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (action_)
|
||||
{
|
||||
action_->Update(target, dt);
|
||||
|
|
@ -97,6 +91,11 @@ namespace easy2d
|
|||
Action::Reset();
|
||||
action_->Reset();
|
||||
}
|
||||
|
||||
if (times_ == total_times_)
|
||||
{
|
||||
this->Stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -112,6 +111,11 @@ namespace easy2d
|
|||
times_ = 0;
|
||||
}
|
||||
|
||||
bool Loop::IsRunning()
|
||||
{
|
||||
return Action::IsRunning() && times_ != total_times_;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Sequence
|
||||
|
|
@ -142,7 +146,7 @@ namespace easy2d
|
|||
{
|
||||
Action::Update(target, dt);
|
||||
|
||||
auto &action = actions_[action_index_];
|
||||
auto& action = actions_[action_index_];
|
||||
action->Update(target, dt);
|
||||
|
||||
if (action->IsDone())
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ namespace easy2d
|
|||
// 重置动作
|
||||
virtual void Reset() override;
|
||||
|
||||
virtual bool IsRunning() override;
|
||||
|
||||
protected:
|
||||
// 初始化动作
|
||||
virtual void Init(Node* target) override;
|
||||
|
|
@ -66,11 +68,13 @@ namespace easy2d
|
|||
{
|
||||
E2D_DISABLE_COPY(Sequence);
|
||||
|
||||
using Actions = std::vector<spAction>;
|
||||
|
||||
public:
|
||||
Sequence();
|
||||
|
||||
explicit Sequence(
|
||||
const Actions& actions /* 动作列表 */
|
||||
Actions const& actions /* 动作列表 */
|
||||
);
|
||||
|
||||
virtual ~Sequence();
|
||||
|
|
@ -113,6 +117,8 @@ namespace easy2d
|
|||
{
|
||||
E2D_DISABLE_COPY(Spawn);
|
||||
|
||||
using Actions = std::vector<spAction>;
|
||||
|
||||
public:
|
||||
Spawn();
|
||||
|
||||
|
|
|
|||
|
|
@ -25,58 +25,40 @@ namespace easy2d
|
|||
{
|
||||
void ActionManager::UpdateActions(Node* target, Duration const& dt)
|
||||
{
|
||||
if (actions_.empty())
|
||||
if (actions_.IsEmpty())
|
||||
return;
|
||||
|
||||
std::vector<spAction> currActions;
|
||||
currActions.reserve(actions_.size());
|
||||
std::copy_if(
|
||||
actions_.begin(),
|
||||
actions_.end(),
|
||||
std::back_inserter(currActions),
|
||||
[](spAction action) { return action->IsRunning() && !action->IsDone(); }
|
||||
);
|
||||
|
||||
// 遍历所有正在运行的动作
|
||||
for (const auto& action : currActions)
|
||||
action->Update(target, dt);
|
||||
|
||||
// 清除完成的动作
|
||||
for (auto iter = actions_.begin(); iter != actions_.end();)
|
||||
spAction next;
|
||||
for (auto action = actions_.First(); action; action = next)
|
||||
{
|
||||
if ((*iter)->IsDone())
|
||||
{
|
||||
iter = actions_.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
next = action->Next();
|
||||
|
||||
if (action->IsRunning())
|
||||
action->Update(target, dt);
|
||||
|
||||
if (action->IsDone())
|
||||
actions_.Remove(action);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionManager::RunAction(spAction const& action)
|
||||
void ActionManager::AddAction(spAction const& action)
|
||||
{
|
||||
if (!action)
|
||||
logs::Warningln("Node::RunAction failed, action is nullptr");
|
||||
|
||||
if (action)
|
||||
{
|
||||
auto iter = std::find(actions_.begin(), actions_.end(), action);
|
||||
if (iter == actions_.end())
|
||||
{
|
||||
action->Start();
|
||||
actions_.push_back(action);
|
||||
}
|
||||
action->Start();
|
||||
actions_.Append(action);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionManager::ResumeAllActions()
|
||||
{
|
||||
if (actions_.empty())
|
||||
if (actions_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (const auto& action : actions_)
|
||||
for (auto& action = actions_.First(); action; action = action->Next())
|
||||
{
|
||||
action->Resume();
|
||||
}
|
||||
|
|
@ -84,10 +66,10 @@ namespace easy2d
|
|||
|
||||
void ActionManager::PauseAllActions()
|
||||
{
|
||||
if (actions_.empty())
|
||||
if (actions_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (const auto& action : actions_)
|
||||
for (auto& action = actions_.First(); action; action = action->Next())
|
||||
{
|
||||
action->Pause();
|
||||
}
|
||||
|
|
@ -95,16 +77,16 @@ namespace easy2d
|
|||
|
||||
void ActionManager::StopAllActions()
|
||||
{
|
||||
if (actions_.empty())
|
||||
if (actions_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (const auto& action : actions_)
|
||||
for (auto& action = actions_.First(); action; action = action->Next())
|
||||
{
|
||||
action->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
const Actions& ActionManager::GetAllActions() const
|
||||
const ActionManager::Actions& ActionManager::GetAllActions() const
|
||||
{
|
||||
return actions_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@ namespace easy2d
|
|||
{
|
||||
class ActionManager
|
||||
{
|
||||
using Actions = IntrusiveList<spAction>;
|
||||
|
||||
public:
|
||||
// 执行动作
|
||||
void RunAction(
|
||||
void AddAction(
|
||||
spAction const& action
|
||||
);
|
||||
|
||||
|
|
@ -41,7 +43,7 @@ namespace easy2d
|
|||
void StopAllActions();
|
||||
|
||||
// 获取所有动作
|
||||
const Actions& GetAllActions() const;
|
||||
Actions const& GetAllActions() const;
|
||||
|
||||
protected:
|
||||
void UpdateActions(Node* target, Duration const& dt);
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ namespace easy2d
|
|||
return interval_;
|
||||
}
|
||||
|
||||
const Images& Animation::GetFrames() const
|
||||
Animation::Images const& Animation::GetFrames() const
|
||||
{
|
||||
return frames_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ namespace easy2d
|
|||
{
|
||||
E2D_DISABLE_COPY(Animation);
|
||||
|
||||
using Images = std::vector< spImage >;
|
||||
|
||||
public:
|
||||
Animation();
|
||||
|
||||
|
|
@ -61,7 +63,7 @@ namespace easy2d
|
|||
Duration const& GetInterval() const;
|
||||
|
||||
// 获取关键帧
|
||||
const Images& GetFrames() const;
|
||||
Images const& GetFrames() const;
|
||||
|
||||
// 设置每一帧的时间间隔
|
||||
void SetInterval(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,231 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "macros.h"
|
||||
#include <functional>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
template <typename T>
|
||||
class IntrusiveList
|
||||
{
|
||||
T first_;
|
||||
T last_;
|
||||
int size_;
|
||||
|
||||
public:
|
||||
IntrusiveList() : first_(), last_(), size_(0) {}
|
||||
|
||||
~IntrusiveList() { Clear(); }
|
||||
|
||||
T const& First() const { return first_; }
|
||||
|
||||
T& First() { return first_; }
|
||||
|
||||
T const& Last() const { return last_; }
|
||||
|
||||
T& Last() { return last_; }
|
||||
|
||||
bool IsEmpty() const { return size_ == 0; }
|
||||
|
||||
int Size() const { return size_; }
|
||||
|
||||
void Append(T child)
|
||||
{
|
||||
child->prev_ = last_;
|
||||
child->next_ = nullptr;
|
||||
|
||||
if (first_)
|
||||
{
|
||||
last_->next_ = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_ = child;
|
||||
}
|
||||
|
||||
last_ = child;
|
||||
++size_;
|
||||
|
||||
#ifdef E2D_DEBUG
|
||||
Check();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Prepend(T child)
|
||||
{
|
||||
child->prev_ = nullptr;
|
||||
child->next_ = first_;
|
||||
|
||||
if (first_)
|
||||
{
|
||||
first_->prev_ = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_ = child;
|
||||
}
|
||||
|
||||
first_ = child;
|
||||
++size_;
|
||||
|
||||
#ifdef E2D_DEBUG
|
||||
Check();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Remove(T child)
|
||||
{
|
||||
#ifdef E2D_DEBUG
|
||||
T tmp = first_;
|
||||
while (tmp != child)
|
||||
{
|
||||
if (tmp == last_)
|
||||
throw std::logic_error("The node to be removed is not in this list");
|
||||
tmp = tmp->next_;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (child->next_)
|
||||
{
|
||||
child->next_->prev_ = child->prev_;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_ = child->prev_;
|
||||
}
|
||||
|
||||
if (child->prev_)
|
||||
{
|
||||
child->prev_->next_ = child->next_;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_ = child->next_;
|
||||
}
|
||||
|
||||
child->prev_ = nullptr;
|
||||
child->next_ = nullptr;
|
||||
--size_;
|
||||
|
||||
#ifdef E2D_DEBUG
|
||||
Check();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Insert(T child, T before)
|
||||
{
|
||||
if (before->prev_)
|
||||
before->prev_->next_ = child;
|
||||
else
|
||||
first_ = child;
|
||||
|
||||
child->prev_ = before->prev_;
|
||||
child->next_ = before;
|
||||
before->prev_ = child;
|
||||
++size_;
|
||||
|
||||
#ifdef E2D_DEBUG
|
||||
Check();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
T p = first_;
|
||||
while (p)
|
||||
{
|
||||
T tmp = p;
|
||||
p = p->next_;
|
||||
if (tmp)
|
||||
{
|
||||
tmp->next_ = nullptr;
|
||||
tmp->prev_ = nullptr;
|
||||
}
|
||||
}
|
||||
first_ = nullptr;
|
||||
last_ = nullptr;
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
void Sort(std::function<bool(T const&, T const&)> func)
|
||||
{
|
||||
#ifdef E2D_DEBUG
|
||||
Check();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef E2D_DEBUG
|
||||
|
||||
void Check()
|
||||
{
|
||||
if (!first_)
|
||||
return;
|
||||
|
||||
int pos = 0;
|
||||
T p = first_;
|
||||
T tmp = p;
|
||||
do
|
||||
{
|
||||
tmp = p;
|
||||
p = p->next_;
|
||||
++pos;
|
||||
|
||||
if (p)
|
||||
{
|
||||
if (p->prev_ != tmp)
|
||||
throw std::logic_error("Check list failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmp != last_)
|
||||
throw std::logic_error("Check list failed");
|
||||
}
|
||||
} while (p);
|
||||
|
||||
if (pos != size_)
|
||||
throw std::logic_error("Check list failed");
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class IntrusiveItem
|
||||
{
|
||||
T prev_;
|
||||
T next_;
|
||||
|
||||
template <typename U>
|
||||
friend class IntrusiveList;
|
||||
|
||||
public:
|
||||
IntrusiveItem() : prev_(), next_() {}
|
||||
|
||||
T const& Prev() const { return prev_; }
|
||||
|
||||
T& Prev() { return prev_; }
|
||||
|
||||
T const& Next() const { return next_; }
|
||||
|
||||
T& Next() { return next_; }
|
||||
};
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ namespace easy2d
|
|||
graphics->PushClip(final_matrix_, transform_.size);
|
||||
}
|
||||
|
||||
if (children_.empty())
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
graphics->SetTransform(final_matrix_);
|
||||
OnDraw();
|
||||
|
|
@ -87,20 +87,17 @@ namespace easy2d
|
|||
// ×Ó½ÚµãÅÅÐò
|
||||
if (dirty_sort_)
|
||||
{
|
||||
std::sort(
|
||||
children_.begin(),
|
||||
children_.end(),
|
||||
children_.Sort(
|
||||
[](spNode const& n1, spNode const& n2) { return n1->GetOrder() < n2->GetOrder(); }
|
||||
);
|
||||
|
||||
dirty_sort_ = false;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < children_.size(); ++i)
|
||||
spNode child = children_.First();
|
||||
for (spNode next; child; child = next)
|
||||
{
|
||||
auto child = children_[i];
|
||||
// 访问 Order 小于零的节点
|
||||
next = child->Next();
|
||||
if (child->GetOrder() < 0)
|
||||
{
|
||||
child->Visit();
|
||||
|
|
@ -114,9 +111,11 @@ namespace easy2d
|
|||
graphics->SetTransform(final_matrix_);
|
||||
OnDraw();
|
||||
|
||||
// 访问剩余节点
|
||||
for (; i < children_.size(); ++i)
|
||||
children_[i]->Visit();
|
||||
for (spNode next; child; child = next)
|
||||
{
|
||||
next = child->Next();
|
||||
child->Visit();
|
||||
}
|
||||
}
|
||||
|
||||
if (clip_enabled_)
|
||||
|
|
@ -127,7 +126,7 @@ namespace easy2d
|
|||
|
||||
void Node::Update(Duration const& dt)
|
||||
{
|
||||
if (children_.empty())
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
OnUpdate(dt);
|
||||
UpdateActions(this, dt);
|
||||
|
|
@ -136,13 +135,13 @@ namespace easy2d
|
|||
}
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < children_.size(); ++i)
|
||||
// ·ÃÎÊ Order СÓÚÁãµÄ½Úµã
|
||||
spNode child = children_.First();
|
||||
for (spNode next; child; child = next)
|
||||
{
|
||||
auto child = children_[i];
|
||||
// 访问 Order 小于零的节点
|
||||
if (child->GetOrder() < 0)
|
||||
{
|
||||
next = child->Next();
|
||||
child->Update(dt);
|
||||
}
|
||||
else
|
||||
|
|
@ -156,9 +155,11 @@ namespace easy2d
|
|||
UpdateTasks(dt);
|
||||
UpdateTransform();
|
||||
|
||||
// 访问剩余节点
|
||||
for (; i < children_.size(); ++i)
|
||||
children_[i]->Update(dt);
|
||||
for (spNode next; child; child = next)
|
||||
{
|
||||
next = child->Next();
|
||||
child->Update(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +172,7 @@ namespace easy2d
|
|||
devices::Graphics::Instance()->DrawGeometry(border_, border_color_, 1.f, 1.5f);
|
||||
}
|
||||
|
||||
for (const auto& child : children_)
|
||||
for (auto& child = children_.First(); child; child = child->Next())
|
||||
{
|
||||
child->DrawBorder();
|
||||
}
|
||||
|
|
@ -202,7 +203,7 @@ namespace easy2d
|
|||
devices::Graphics::Instance()->CreateRectGeometry(final_matrix_, transform_.size, &border_)
|
||||
);
|
||||
|
||||
for (auto& child : children_)
|
||||
for (auto& child = children_.First(); child; child = child->Next())
|
||||
{
|
||||
child->dirty_transform_ = true;
|
||||
}
|
||||
|
|
@ -212,8 +213,12 @@ namespace easy2d
|
|||
{
|
||||
if (visible_)
|
||||
{
|
||||
for (auto riter = children_.crbegin(); riter != children_.crend(); ++riter)
|
||||
handled = (*riter)->Dispatch(e, handled);
|
||||
spNode prev;
|
||||
for (auto& child = children_.Last(); child; child = prev)
|
||||
{
|
||||
prev = child->Prev();
|
||||
handled = child->Dispatch(e, handled);
|
||||
}
|
||||
|
||||
auto handler = dynamic_cast<MouseEventHandler*>(this);
|
||||
if (handler)
|
||||
|
|
@ -227,8 +232,12 @@ namespace easy2d
|
|||
{
|
||||
if (visible_)
|
||||
{
|
||||
for (auto riter = children_.crbegin(); riter != children_.crend(); ++riter)
|
||||
handled = (*riter)->Dispatch(e, handled);
|
||||
spNode prev;
|
||||
for (auto& child = children_.Last(); child; child = prev)
|
||||
{
|
||||
prev = child->Prev();
|
||||
handled = child->Dispatch(e, handled);
|
||||
}
|
||||
|
||||
auto handler = dynamic_cast<KeyEventHandler*>(this);
|
||||
if (handler)
|
||||
|
|
@ -244,7 +253,7 @@ namespace easy2d
|
|||
{
|
||||
display_opacity_ = real_opacity_ * parent_->display_opacity_;
|
||||
}
|
||||
for (const auto& child : children_)
|
||||
for (auto& child = children_.First(); child; child = child->Next())
|
||||
{
|
||||
child->UpdateOpacity();
|
||||
}
|
||||
|
|
@ -547,7 +556,7 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
children_.push_back(child);
|
||||
children_.Append(child);
|
||||
child->SetOrder(order);
|
||||
child->parent_ = this;
|
||||
|
||||
|
|
@ -573,14 +582,13 @@ namespace easy2d
|
|||
return parent_;
|
||||
}
|
||||
|
||||
Nodes Node::GetChildren(const String& name) const
|
||||
Node::Nodes Node::GetChildren(const String& name) const
|
||||
{
|
||||
Nodes children;
|
||||
size_t hash_code = std::hash<String>{}(name);
|
||||
|
||||
for (const auto& child : children_)
|
||||
for (auto child = children_.First(); child != children_.Last(); child = child->Next())
|
||||
{
|
||||
// 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度
|
||||
if (child->hash_name_ == hash_code && child->name_ == name)
|
||||
{
|
||||
children.push_back(child);
|
||||
|
|
@ -593,9 +601,8 @@ namespace easy2d
|
|||
{
|
||||
size_t hash_code = std::hash<String>{}(name);
|
||||
|
||||
for (const auto& child : children_)
|
||||
for (auto child = children_.First(); child != children_.Last(); child = child->Next())
|
||||
{
|
||||
// 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度
|
||||
if (child->hash_name_ == hash_code && child->name_ == name)
|
||||
{
|
||||
return child;
|
||||
|
|
@ -604,14 +611,14 @@ namespace easy2d
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const std::vector<spNode>& Node::GetAllChildren() const
|
||||
Node::Children const & Node::GetChildren() const
|
||||
{
|
||||
return children_;
|
||||
}
|
||||
|
||||
int Node::GetChildrenCount() const
|
||||
{
|
||||
return static_cast<int>(children_.size());
|
||||
return children_.Size();
|
||||
}
|
||||
|
||||
void Node::RemoveFromParent()
|
||||
|
|
@ -627,49 +634,40 @@ namespace easy2d
|
|||
if (!child)
|
||||
logs::Warningln("Node::RemoveChild failed, child is nullptr");
|
||||
|
||||
if (children_.empty())
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (child)
|
||||
{
|
||||
auto iter = std::find(children_.begin(), children_.end(), child);
|
||||
if (iter != children_.end())
|
||||
{
|
||||
children_.erase(iter);
|
||||
child->parent_ = nullptr;
|
||||
return true;
|
||||
}
|
||||
children_.Remove(child);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Node::RemoveChildren(const String& child_name)
|
||||
{
|
||||
if (children_.empty())
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
size_t hash_code = std::hash<String>{}(child_name);
|
||||
for (auto iter = children_.begin(); iter != children_.end();)
|
||||
spNode next;
|
||||
for (auto& child = children_.First(); child; child = next)
|
||||
{
|
||||
if ((*iter)->hash_name_ == hash_code && (*iter)->name_ == child_name)
|
||||
{
|
||||
(*iter)->parent_ = nullptr;
|
||||
iter = children_.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
next = child->Next();
|
||||
|
||||
if (child->hash_name_ == hash_code && child->name_ == child_name)
|
||||
children_.Remove(child);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::RemoveAllChildren()
|
||||
{
|
||||
children_.clear();
|
||||
children_.Clear();
|
||||
}
|
||||
|
||||
bool Node::ContainsPoint(const Point& point)
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@
|
|||
#pragma once
|
||||
#include "base.h"
|
||||
#include "time.h"
|
||||
#include "ActionManager.h"
|
||||
#include "TaskManager.h"
|
||||
#include "KeyEvent.h"
|
||||
#include "MouseEvent.h"
|
||||
#include "ActionManager.h"
|
||||
#include "TaskManager.h"
|
||||
#include "IntrusiveList.hpp"
|
||||
#include "../math/Transform.hpp"
|
||||
#include "../math/Matrix.hpp"
|
||||
|
||||
|
|
@ -37,6 +38,7 @@ namespace easy2d
|
|||
: public RefCounter
|
||||
, public ActionManager
|
||||
, public TaskManager
|
||||
, public IntrusiveItem<spNode>
|
||||
{
|
||||
friend class Game;
|
||||
friend class Scene;
|
||||
|
|
@ -44,6 +46,9 @@ namespace easy2d
|
|||
|
||||
E2D_DISABLE_COPY(Node);
|
||||
|
||||
using Nodes = std::vector< spNode >;
|
||||
using Children = IntrusiveList<spNode>;
|
||||
|
||||
public:
|
||||
Node();
|
||||
|
||||
|
|
@ -310,8 +315,8 @@ namespace easy2d
|
|||
const String& name
|
||||
) const;
|
||||
|
||||
// 获取所有子节点
|
||||
const Nodes& GetAllChildren() const;
|
||||
// 获取全部子节点
|
||||
Children const& GetChildren() const;
|
||||
|
||||
// »ñÈ¡×Ó½ÚµãÊýÁ¿
|
||||
int GetChildrenCount() const;
|
||||
|
|
@ -372,7 +377,7 @@ namespace easy2d
|
|||
bool dirty_transform_;
|
||||
Node* parent_;
|
||||
Color border_color_;
|
||||
Nodes children_;
|
||||
Children children_;
|
||||
ID2D1Geometry* border_;
|
||||
math::Transform transform_;
|
||||
math::Matrix initial_matrix_;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#pragma once
|
||||
#include "base.h"
|
||||
#include "time.h"
|
||||
#include "IntrusiveList.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace easy2d
|
||||
|
|
@ -30,6 +31,7 @@ namespace easy2d
|
|||
// 定时任务
|
||||
class Task
|
||||
: public RefCounter
|
||||
, public IntrusiveItem<spTask>
|
||||
{
|
||||
friend class TaskManager;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,25 +19,42 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include "TaskManager.h"
|
||||
#include "logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
void TaskManager::UpdateTasks(Duration const& dt)
|
||||
{
|
||||
if (tasks_.IsEmpty())
|
||||
return;
|
||||
|
||||
spTask next;
|
||||
for (auto task = tasks_.First(); task; task = next)
|
||||
{
|
||||
next = task->Next();
|
||||
|
||||
task->Update(dt);
|
||||
|
||||
if (task->stopped_)
|
||||
tasks_.Remove(task);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskManager::AddTask(spTask const& task)
|
||||
{
|
||||
if (!task)
|
||||
logs::Warningln("Node::AddTask failed, action is nullptr");
|
||||
|
||||
if (task)
|
||||
{
|
||||
auto iter = std::find(tasks_.begin(), tasks_.end(), task);
|
||||
if (iter == tasks_.end())
|
||||
{
|
||||
task->Reset();
|
||||
tasks_.push_back(task);
|
||||
}
|
||||
task->Reset();
|
||||
tasks_.Append(task);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskManager::StopTasks(const String& name)
|
||||
{
|
||||
for (const auto& task : tasks_)
|
||||
for (auto& task = tasks_.First(); task; task = task->Next())
|
||||
{
|
||||
if (task->GetName() == name)
|
||||
{
|
||||
|
|
@ -48,7 +65,7 @@ namespace easy2d
|
|||
|
||||
void TaskManager::StartTasks(const String& name)
|
||||
{
|
||||
for (const auto& task : tasks_)
|
||||
for (auto& task = tasks_.First(); task; task = task->Next())
|
||||
{
|
||||
if (task->GetName() == name)
|
||||
{
|
||||
|
|
@ -59,7 +76,7 @@ namespace easy2d
|
|||
|
||||
void TaskManager::RemoveTasks(const String& name)
|
||||
{
|
||||
for (const auto& task : tasks_)
|
||||
for (auto& task = tasks_.First(); task; task = task->Next())
|
||||
{
|
||||
if (task->GetName() == name)
|
||||
{
|
||||
|
|
@ -70,7 +87,7 @@ namespace easy2d
|
|||
|
||||
void TaskManager::StopAllTasks()
|
||||
{
|
||||
for (const auto& task : tasks_)
|
||||
for (auto& task = tasks_.First(); task; task = task->Next())
|
||||
{
|
||||
task->Stop();
|
||||
}
|
||||
|
|
@ -78,7 +95,7 @@ namespace easy2d
|
|||
|
||||
void TaskManager::StartAllTasks()
|
||||
{
|
||||
for (const auto& task : tasks_)
|
||||
for (auto& task = tasks_.First(); task; task = task->Next())
|
||||
{
|
||||
task->Start();
|
||||
}
|
||||
|
|
@ -86,46 +103,14 @@ namespace easy2d
|
|||
|
||||
void TaskManager::RemoveAllTasks()
|
||||
{
|
||||
for (const auto& task : tasks_)
|
||||
for (auto& task = tasks_.First(); task; task = task->Next())
|
||||
{
|
||||
task->stopped_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
const Tasks & TaskManager::GetAllTasks() const
|
||||
const TaskManager::Tasks & TaskManager::GetAllTasks() const
|
||||
{
|
||||
return tasks_;
|
||||
}
|
||||
|
||||
void TaskManager::UpdateTasks(Duration const& dt)
|
||||
{
|
||||
if (tasks_.empty())
|
||||
return;
|
||||
|
||||
std::vector<spTask> currTasks;
|
||||
currTasks.reserve(tasks_.size());
|
||||
std::copy_if(
|
||||
tasks_.begin(),
|
||||
tasks_.end(),
|
||||
std::back_inserter(currTasks),
|
||||
[](spTask const& task) { return !task->stopped_; }
|
||||
);
|
||||
|
||||
// 遍历就绪的任务
|
||||
for (const auto& task : currTasks)
|
||||
task->Update(dt);
|
||||
|
||||
// 清除结束的任务
|
||||
for (auto iter = tasks_.begin(); iter != tasks_.end();)
|
||||
{
|
||||
if ((*iter)->stopped_)
|
||||
{
|
||||
iter = tasks_.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ namespace easy2d
|
|||
{
|
||||
class TaskManager
|
||||
{
|
||||
using Tasks = IntrusiveList<spTask>;
|
||||
|
||||
public:
|
||||
// Ìí¼ÓÈÎÎñ
|
||||
void AddTask(
|
||||
|
|
|
|||
|
|
@ -81,12 +81,6 @@ namespace easy2d
|
|||
E2D_DECLARE_NS_SMART_PTR(ui, Button);
|
||||
E2D_DECLARE_NS_SMART_PTR(ui, Menu);
|
||||
|
||||
using Images = ::std::vector< spImage >;
|
||||
using Nodes = ::std::vector< spNode >;
|
||||
using Actions = ::std::vector< spAction >;
|
||||
using Tasks = ::std::vector< spTask >;
|
||||
|
||||
|
||||
template<class Interface>
|
||||
inline void SafeRelease(Interface*& p)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include <stdexcept>
|
||||
|
||||
#ifndef E2D_LOG
|
||||
# if defined(DEBUG) || defined(_DEBUG)
|
||||
# ifdef E2D_DEBUG
|
||||
# define E2D_LOG(format, ...) easy2d::logs::Println(format, ##__VA_ARGS__)
|
||||
# else
|
||||
# define E2D_LOG ((void)0)
|
||||
|
|
|
|||
|
|
@ -68,6 +68,14 @@
|
|||
# define INITGUID
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
# ifndef E2D_DEBUG
|
||||
# define E2D_DEBUG
|
||||
# endif
|
||||
#else
|
||||
# undef E2D_DEBUG
|
||||
#endif
|
||||
|
||||
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
<ClInclude Include="..\..\core\base\Game.h" />
|
||||
<ClInclude Include="..\..\core\base\Image.h" />
|
||||
<ClInclude Include="..\..\core\base\Input.h" />
|
||||
<ClInclude Include="..\..\core\base\IntrusiveList.hpp" />
|
||||
<ClInclude Include="..\..\core\base\IntrusivePtr.hpp" />
|
||||
<ClInclude Include="..\..\core\base\KeyEvent.h" />
|
||||
<ClInclude Include="..\..\core\base\logs.h" />
|
||||
|
|
|
|||
|
|
@ -155,6 +155,9 @@
|
|||
<ClInclude Include="..\..\core\base\Font.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\IntrusiveList.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="base">
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
<ClInclude Include="..\..\core\base\Game.h" />
|
||||
<ClInclude Include="..\..\core\base\Image.h" />
|
||||
<ClInclude Include="..\..\core\base\Input.h" />
|
||||
<ClInclude Include="..\..\core\base\IntrusiveList.hpp" />
|
||||
<ClInclude Include="..\..\core\base\IntrusivePtr.hpp" />
|
||||
<ClInclude Include="..\..\core\base\KeyEvent.h" />
|
||||
<ClInclude Include="..\..\core\base\logs.h" />
|
||||
|
|
|
|||
|
|
@ -155,6 +155,9 @@
|
|||
<ClInclude Include="..\..\core\base\Font.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\IntrusiveList.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="base">
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
<ClInclude Include="..\..\core\base\Game.h" />
|
||||
<ClInclude Include="..\..\core\base\Image.h" />
|
||||
<ClInclude Include="..\..\core\base\Input.h" />
|
||||
<ClInclude Include="..\..\core\base\IntrusiveList.hpp" />
|
||||
<ClInclude Include="..\..\core\base\IntrusivePtr.hpp" />
|
||||
<ClInclude Include="..\..\core\base\KeyEvent.h" />
|
||||
<ClInclude Include="..\..\core\base\logs.h" />
|
||||
|
|
|
|||
|
|
@ -155,6 +155,9 @@
|
|||
<ClInclude Include="..\..\core\base\Font.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\IntrusiveList.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="base">
|
||||
|
|
|
|||
Loading…
Reference in New Issue