update ComponentManager & remove Actor::GetPhysicBody

This commit is contained in:
Nomango 2020-06-21 18:02:33 +08:00
parent e981457370
commit 0f3b5ca473
9 changed files with 120 additions and 92 deletions

View File

@ -21,6 +21,8 @@
#include <kiwano-physics/PhysicBody.h> #include <kiwano-physics/PhysicBody.h>
#include <kiwano-physics/PhysicWorld.h> #include <kiwano-physics/PhysicWorld.h>
#define KGE_PHYSIC_COMP_NAME "__KGE_PHYSIC_BODY__"
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
@ -48,6 +50,25 @@ PhysicBodyPtr PhysicBody::Create(PhysicWorld* world, Type type)
return nullptr; return nullptr;
} }
PhysicBody* PhysicBody::Get(Actor* actor)
{
if (actor)
{
static size_t physic_comp_name_hash = 0;
if (physic_comp_name_hash == 0)
{
physic_comp_name_hash = std::hash<String>{}(KGE_PHYSIC_COMP_NAME);
}
return (PhysicBody*)actor->GetComponent(physic_comp_name_hash);
}
return nullptr;
}
PhysicBody* PhysicBody::Get(ActorPtr actor)
{
return PhysicBody::Get(actor.Get());
}
PhysicBody::PhysicBody() PhysicBody::PhysicBody()
: body_(nullptr) : body_(nullptr)
, world_(nullptr) , world_(nullptr)
@ -56,7 +77,7 @@ PhysicBody::PhysicBody()
, mask_bits_(0xFFFF) , mask_bits_(0xFFFF)
, group_index_(0) , group_index_(0)
{ {
SetName("KGE_PHYSIC_BODY"); SetName(KGE_PHYSIC_COMP_NAME);
} }
PhysicBody::~PhysicBody() {} PhysicBody::~PhysicBody() {}
@ -65,8 +86,6 @@ void PhysicBody::InitComponent(Actor* actor)
{ {
Component::InitComponent(actor); Component::InitComponent(actor);
actor->SetPhysicBody(this);
UpdateFromActor(actor); UpdateFromActor(actor);
} }

View File

@ -62,6 +62,16 @@ public:
/// @param type ÎïÌåÀàÐÍ /// @param type ÎïÌåÀàÐÍ
static PhysicBodyPtr Create(PhysicWorld* world, Type type); static PhysicBodyPtr Create(PhysicWorld* world, Type type);
/// \~chinese
/// @brief 获取角色的物理身体
/// @param actor 角色
static PhysicBody* Get(Actor* actor);
/// \~chinese
/// @brief 获取角色的物理身体
/// @param actor 角色
static PhysicBody* Get(ActorPtr actor);
PhysicBody(); PhysicBody();
virtual ~PhysicBody(); virtual ~PhysicBody();

View File

@ -413,7 +413,7 @@ void PhysicWorld::BeforeSimulation(Actor* parent, const Matrix3x2& parent_to_wor
{ {
Matrix3x2 child_to_world = child->GetTransformMatrixToParent() * parent_to_world; Matrix3x2 child_to_world = child->GetTransformMatrixToParent() * parent_to_world;
PhysicBody* body = child->GetPhysicBody(); PhysicBody* body = PhysicBody::Get(child);
if (body) if (body)
{ {
body->BeforeSimulation(child.Get(), parent_to_world, child_to_world, parent_rotation); body->BeforeSimulation(child.Get(), parent_to_world, child_to_world, parent_rotation);
@ -428,7 +428,7 @@ void PhysicWorld::AfterSimulation(Actor* parent, const Matrix3x2& parent_to_worl
{ {
for (auto child : parent->GetAllChildren()) for (auto child : parent->GetAllChildren())
{ {
PhysicBody* body = child->GetPhysicBody(); PhysicBody* body = PhysicBody::Get(child);
if (body) if (body)
{ {
body->AfterSimulation(child.Get(), parent_to_world, parent_rotation); body->AfterSimulation(child.Get(), parent_to_world, parent_rotation);

View File

@ -66,7 +66,6 @@ Actor::Actor()
, opacity_(1.f) , opacity_(1.f)
, displayed_opacity_(1.f) , displayed_opacity_(1.f)
, anchor_(default_anchor_x, default_anchor_y) , anchor_(default_anchor_x, default_anchor_y)
, physic_body_(nullptr)
{ {
} }

View File

@ -33,11 +33,6 @@ class Stage;
class Director; class Director;
class RenderContext; class RenderContext;
namespace physics
{
class PhysicBody;
}
KGE_DECLARE_SMART_PTR(Actor); KGE_DECLARE_SMART_PTR(Actor);
/// \~chinese /// \~chinese
@ -391,14 +386,6 @@ public:
/// @brief 获取更新时的回调函数 /// @brief 获取更新时的回调函数
UpdateCallback GetCallbackOnUpdate() const; UpdateCallback GetCallbackOnUpdate() const;
/// \~chinese
/// @brief 获取物理身体仅当kiwano-physics包启用时生效
physics::PhysicBody* GetPhysicBody() const;
/// \~chinese
/// @brief 设置物理身体仅当kiwano-physics包启用时生效
void SetPhysicBody(physics::PhysicBody* body);
/// \~chinese /// \~chinese
/// @brief 判断点是否在角色内 /// @brief 判断点是否在角色内
virtual bool ContainsPoint(const Point& point) const; virtual bool ContainsPoint(const Point& point) const;
@ -502,8 +489,6 @@ private:
mutable Matrix3x2 transform_matrix_; mutable Matrix3x2 transform_matrix_;
mutable Matrix3x2 transform_matrix_inverse_; mutable Matrix3x2 transform_matrix_inverse_;
mutable Matrix3x2 transform_matrix_to_parent_; mutable Matrix3x2 transform_matrix_to_parent_;
physics::PhysicBody* physic_body_;
}; };
/** @} */ /** @} */
@ -688,16 +673,6 @@ inline Actor::UpdateCallback Actor::GetCallbackOnUpdate() const
return cb_update_; return cb_update_;
} }
inline physics::PhysicBody* Actor::GetPhysicBody() const
{
return physic_body_;
}
inline void Actor::SetPhysicBody(physics::PhysicBody* body)
{
physic_body_ = body;
}
inline void Actor::ShowBorder(bool show) inline void Actor::ShowBorder(bool show)
{ {
show_border_ = show; show_border_ = show;

View File

@ -47,7 +47,7 @@ ButtonPtr Button::Create(const Callback& click, const Callback& pressed, const C
Button::Button() Button::Button()
: status_(Status::Normal) : status_(Status::Normal)
{ {
SetName("KGE_BUTTON"); SetName("__KGE_BUTTON__");
} }
Button::~Button() Button::~Button()

View File

@ -21,7 +21,6 @@
#pragma once #pragma once
#include <kiwano/core/Time.h> #include <kiwano/core/Time.h>
#include <kiwano/base/ObjectBase.h> #include <kiwano/base/ObjectBase.h>
#include <kiwano/core/IntrusiveList.h>
#include <kiwano/render/RenderContext.h> #include <kiwano/render/RenderContext.h>
namespace kiwano namespace kiwano
@ -49,10 +48,8 @@ KGE_DECLARE_SMART_PTR(Component);
*/ */
class KGE_API Component class KGE_API Component
: public ObjectBase : public ObjectBase
, protected IntrusiveListValue<ComponentPtr>
{ {
friend class ComponentManager; friend class ComponentManager;
friend IntrusiveList<ComponentPtr>;
public: public:
/// \~chinese /// \~chinese

View File

@ -19,6 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/base/component/ComponentManager.h> #include <kiwano/base/component/ComponentManager.h>
#include <functional>
namespace kiwano namespace kiwano
{ {
@ -35,45 +36,62 @@ Component* ComponentManager::AddComponent(ComponentPtr component)
if (component) if (component)
{ {
component->InitComponent(target_); component->InitComponent(target_);
components_.PushBack(component);
size_t hash = std::hash<String>{}(component->GetName());
components_.insert(std::make_pair(hash, component));
} }
return component.Get(); return component.Get();
} }
ComponentList& ComponentManager::GetAllComponents() Component* ComponentManager::GetComponent(const String& name)
{
size_t hash = std::hash<String>{}(name);
return GetComponent(hash);
}
Component* ComponentManager::GetComponent(size_t name_hash)
{
if (!components_.empty())
{
auto iter = components_.find(name_hash);
if (iter != components_.end())
{
return iter->second.Get();
}
}
return nullptr;
}
ComponentMap& ComponentManager::GetAllComponents()
{ {
return components_; return components_;
} }
const ComponentList& ComponentManager::GetAllComponents() const const ComponentMap& ComponentManager::GetAllComponents() const
{ {
return components_; return components_;
} }
void ComponentManager::RemoveComponent(ComponentPtr component) void ComponentManager::RemoveComponent(ComponentPtr component)
{ {
auto iter = std::find(components_.begin(), components_.end(), component); RemoveComponent(component->GetName());
if (iter != components_.end())
{
component->DestroyComponent();
components_.Remove(component);
}
} }
void ComponentManager::RemoveComponents(const String& name) void ComponentManager::RemoveComponent(const String& name)
{ {
if (!components_.IsEmpty()) size_t hash = std::hash<String>{}(name);
{ RemoveComponent(hash);
ComponentPtr next; }
for (auto component = components_.GetFirst(); component; component = next)
{
next = component->GetNext();
if (component->IsName(name)) void ComponentManager::RemoveComponent(size_t name_hash)
{
if (!components_.empty())
{ {
component->DestroyComponent(); auto iter = components_.find(name_hash);
components_.Remove(component); if (iter != components_.end())
} {
iter->second->DestroyComponent();
components_.erase(iter);
} }
} }
} }
@ -81,31 +99,28 @@ void ComponentManager::RemoveComponents(const String& name)
void ComponentManager::RemoveAllComponents() void ComponentManager::RemoveAllComponents()
{ {
// Destroy all components // Destroy all components
if (!components_.IsEmpty()) if (!components_.empty())
{ {
ComponentPtr next; for (auto& p : components_)
for (auto component = components_.GetFirst(); component; component = next)
{ {
next = component->GetNext(); p.second->DestroyComponent();
component->DestroyComponent();
} }
} }
components_.Clear(); components_.clear();
} }
void ComponentManager::Update(Duration dt) void ComponentManager::Update(Duration dt)
{ {
if (!components_.IsEmpty()) if (!components_.empty())
{ {
ComponentPtr next; if (!components_.empty())
for (auto component = components_.GetFirst(); component; component = next)
{ {
next = component->GetNext(); for (auto& p : components_)
if (component->IsEnable())
{ {
component->OnUpdate(dt); if (p.second->IsEnable())
{
p.second->OnUpdate(dt);
}
} }
} }
} }
@ -113,16 +128,16 @@ void ComponentManager::Update(Duration dt)
void ComponentManager::Render(RenderContext& ctx) void ComponentManager::Render(RenderContext& ctx)
{ {
if (!components_.IsEmpty()) if (!components_.empty())
{ {
ComponentPtr next; if (!components_.empty())
for (auto component = components_.GetFirst(); component; component = next)
{ {
next = component->GetNext(); for (auto& p : components_)
if (component->IsEnable())
{ {
component->OnRender(ctx); if (p.second->IsEnable())
{
p.second->OnRender(ctx);
}
} }
} }
} }
@ -130,16 +145,16 @@ void ComponentManager::Render(RenderContext& ctx)
void ComponentManager::DispatchToComponents(Event* evt) void ComponentManager::DispatchToComponents(Event* evt)
{ {
if (!components_.IsEmpty()) if (!components_.empty())
{ {
ComponentPtr next; if (!components_.empty())
for (auto component = components_.GetFirst(); component; component = next)
{ {
next = component->GetNext(); for (auto& p : components_)
if (component->IsEnable())
{ {
component->HandleEvent(evt); if (p.second->IsEnable())
{
p.second->HandleEvent(evt);
}
} }
} }
} }

View File

@ -31,8 +31,8 @@ namespace kiwano
*/ */
/// \~chinese /// \~chinese
/// @brief 组件列表 /// @brief 组件映射
typedef IntrusiveList<ComponentPtr> ComponentList; typedef UnorderedMap<size_t, ComponentPtr> ComponentMap;
/** /**
* \~chinese * \~chinese
@ -47,12 +47,20 @@ public:
Component* AddComponent(ComponentPtr component); Component* AddComponent(ComponentPtr component);
/// \~chinese /// \~chinese
/// @brief 获取所有组件 /// @brief 获取组件
ComponentList& GetAllComponents(); Component* GetComponent(const String& name);
/// \~chinese
/// @brief 获取组件
Component* GetComponent(size_t name_hash);
/// \~chinese /// \~chinese
/// @brief 获取所有组件 /// @brief 获取所有组件
const ComponentList& GetAllComponents() const; ComponentMap& GetAllComponents();
/// \~chinese
/// @brief 获取所有组件
const ComponentMap& GetAllComponents() const;
/// \~chinese /// \~chinese
/// @brief 移除组件 /// @brief 移除组件
@ -61,7 +69,12 @@ public:
/// \~chinese /// \~chinese
/// @brief 移除组件 /// @brief 移除组件
/// @param name 组件名称 /// @param name 组件名称
void RemoveComponents(const String& name); void RemoveComponent(const String& name);
/// \~chinese
/// @brief 移除组件
/// @param name_hash 组件名称hash值
void RemoveComponent(size_t name_hash);
/// \~chinese /// \~chinese
/// @brief 移除所有组件 /// @brief 移除所有组件
@ -84,7 +97,7 @@ protected:
private: private:
Actor* target_; Actor* target_;
ComponentList components_; ComponentMap components_;
}; };
/** @} */ /** @} */