diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj
index 3946e0bf..06fa487e 100644
--- a/projects/kiwano/kiwano.vcxproj
+++ b/projects/kiwano/kiwano.vcxproj
@@ -9,9 +9,11 @@
-
-
+
+
+
+
@@ -44,7 +46,6 @@
-
@@ -115,18 +116,19 @@
-
+
-
-
+
+
+
diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters
index 06293856..9a950f94 100644
--- a/projects/kiwano/kiwano.vcxproj.filters
+++ b/projects/kiwano/kiwano.vcxproj.filters
@@ -34,6 +34,9 @@
{b0d28d20-bfaf-4816-8415-28c20ecf9fac}
+
+ {d15f4de1-7c2c-40d6-a3ce-68860b95a61e}
+
@@ -69,9 +72,6 @@
2d
-
- 2d
-
2d
@@ -132,9 +132,6 @@
platform\win32
-
- 2d
-
core
@@ -261,9 +258,6 @@
render
-
- 2d
-
core
@@ -345,6 +339,18 @@
event
+
+ 2d
+
+
+ base\component
+
+
+ base\component
+
+
+ base\component
+
@@ -365,9 +371,6 @@
2d
-
- 2d
-
2d
@@ -422,9 +425,6 @@
platform\win32
-
- 2d
-
platform\win32
@@ -503,9 +503,6 @@
render
-
- 2d
-
core
@@ -566,6 +563,18 @@
event
+
+ 2d
+
+
+ base\component
+
+
+ base\component
+
+
+ base\component
+
diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp
index f94ae3fa..5f54647c 100644
--- a/src/kiwano/2d/Actor.cpp
+++ b/src/kiwano/2d/Actor.cpp
@@ -46,7 +46,8 @@ ActorPtr Actor::Create()
}
Actor::Actor()
- : visible_(true)
+ : ComponentManager(this)
+ , visible_(true)
, visible_in_rt_(true)
, update_pausing_(false)
, hover_(false)
@@ -79,7 +80,7 @@ void Actor::Update(Duration dt)
{
ActionScheduler::Update(this, dt);
TaskScheduler::Update(dt);
- UpdateComponents(dt);
+ ComponentManager::Update(dt);
if (!update_pausing_)
{
@@ -112,7 +113,7 @@ void Actor::Render(RenderContext& ctx)
if (CheckVisibility(ctx))
{
PrepareToRender(ctx);
- RenderComponents(ctx);
+ ComponentManager::Render(ctx);
OnRender(ctx);
}
}
@@ -132,7 +133,7 @@ void Actor::Render(RenderContext& ctx)
if (CheckVisibility(ctx))
{
PrepareToRender(ctx);
- RenderComponents(ctx);
+ ComponentManager::Render(ctx);
OnRender(ctx);
}
@@ -242,19 +243,7 @@ void Actor::DoDeserialize(Deserializer* deserializer)
bool Actor::HandleEvent(Event* evt)
{
- if (!components_.IsEmpty())
- {
- ComponentPtr next;
- for (auto component = components_.GetFirst(); component; component = next)
- {
- next = component->GetNext();
-
- if (component->IsEnable())
- {
- component->HandleEvent(evt);
- }
- }
- }
+ ComponentManager::DispatchToComponents(evt);
if (!EventDispatcher::DispatchEvent(evt))
return false;
@@ -304,40 +293,6 @@ bool Actor::HandleEvent(Event* evt)
return true;
}
-void Actor::UpdateComponents(Duration dt)
-{
- if (!components_.IsEmpty())
- {
- ComponentPtr next;
- for (auto component = components_.GetFirst(); component; component = next)
- {
- next = component->GetNext();
-
- if (component->IsEnable())
- {
- component->OnUpdate(dt);
- }
- }
- }
-}
-
-void Actor::RenderComponents(RenderContext& ctx)
-{
- if (!components_.IsEmpty())
- {
- ComponentPtr next;
- for (auto component = components_.GetFirst(); component; component = next)
- {
- next = component->GetNext();
-
- if (component->IsEnable())
- {
- component->OnRender(ctx);
- }
- }
- }
-}
-
const Matrix3x2& Actor::GetTransformMatrix() const
{
UpdateTransform();
@@ -657,72 +612,6 @@ void Actor::RemoveFromParent()
}
}
-Component* Actor::AddComponent(ComponentPtr component)
-{
- KGE_ASSERT(component && "AddComponent failed, NULL pointer exception");
-
- if (component)
- {
- component->InitComponent(this);
- components_.PushBack(component);
- }
- return component.Get();
-}
-
-ComponentList& Actor::GetAllComponents()
-{
- return components_;
-}
-
-const ComponentList& Actor::GetAllComponents() const
-{
- return components_;
-}
-
-void Actor::RemoveComponent(ComponentPtr component)
-{
- auto iter = std::find(components_.begin(), components_.end(), component);
- if (iter != components_.end())
- {
- component->DestroyComponent();
- components_.Remove(component);
- }
-}
-
-void Actor::RemoveComponents(const String& name)
-{
- if (!components_.IsEmpty())
- {
- ComponentPtr next;
- for (auto component = components_.GetFirst(); component; component = next)
- {
- next = component->GetNext();
-
- if (component->IsName(name))
- {
- component->DestroyComponent();
- components_.Remove(component);
- }
- }
- }
-}
-
-void Actor::RemoveAllComponents()
-{
- // Destroy all components
- if (!components_.IsEmpty())
- {
- ComponentPtr next;
- for (auto component = components_.GetFirst(); component; component = next)
- {
- next = component->GetNext();
-
- component->DestroyComponent();
- }
- }
- components_.Clear();
-}
-
void Actor::RemoveChild(ActorPtr child)
{
KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception");
diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h
index 802a70ed..f0e258a0 100644
--- a/src/kiwano/2d/Actor.h
+++ b/src/kiwano/2d/Actor.h
@@ -20,12 +20,12 @@
#pragma once
#include
-#include
#include
+#include
+#include
#include
#include
#include
-#include
namespace kiwano
{
@@ -65,6 +65,7 @@ class KGE_API Actor
, public TaskScheduler
, public ActionScheduler
, public EventDispatcher
+ , public ComponentManager
, protected IntrusiveListValue
{
friend class Director;
@@ -370,32 +371,6 @@ public:
/// @brief 从父角色移除
void RemoveFromParent();
- /// \~chinese
- /// @brief 添加组件
- /// @param component 组件
- Component* AddComponent(ComponentPtr component);
-
- /// \~chinese
- /// @brief 获取所有组件
- ComponentList& GetAllComponents();
-
- /// \~chinese
- /// @brief 获取所有组件
- const ComponentList& GetAllComponents() const;
-
- /// \~chinese
- /// @brief 移除组件
- void RemoveComponent(ComponentPtr component);
-
- /// \~chinese
- /// @brief 移除组件
- /// @param name 组件名称
- void RemoveComponents(const String& name);
-
- /// \~chinese
- /// @brief 移除所有组件
- void RemoveAllComponents();
-
/// \~chinese
/// @brief 暂停角色更新
void PauseUpdating();
@@ -499,14 +474,6 @@ protected:
/// @brief 处理事件
bool HandleEvent(Event* evt);
- /// \~chinese
- /// @brief 更新组件
- void UpdateComponents(Duration dt);
-
- /// \~chinese
- /// @brief 渲染组件
- void RenderComponents(RenderContext& ctx);
-
private:
bool visible_;
bool update_pausing_;
@@ -524,7 +491,6 @@ private:
Point anchor_;
Size size_;
ActorList children_;
- ComponentList components_;
UpdateCallback cb_update_;
Transform transform_;
diff --git a/src/kiwano/2d/action/Action.h b/src/kiwano/2d/action/Action.h
index 0df4595a..0de9a0a4 100644
--- a/src/kiwano/2d/action/Action.h
+++ b/src/kiwano/2d/action/Action.h
@@ -34,10 +34,6 @@ class ActionScheduler;
KGE_DECLARE_SMART_PTR(Action);
-/// \~chinese
-/// @brief 动画列表
-typedef IntrusiveList ActionList;
-
/**
* \~chinese
* \defgroup Actions 动画
diff --git a/src/kiwano/2d/action/ActionScheduler.h b/src/kiwano/2d/action/ActionScheduler.h
index 34d37421..ccbf4172 100644
--- a/src/kiwano/2d/action/ActionScheduler.h
+++ b/src/kiwano/2d/action/ActionScheduler.h
@@ -28,6 +28,10 @@ namespace kiwano
* @{
*/
+/// \~chinese
+/// @brief 动画列表
+typedef IntrusiveList ActionList;
+
/**
* \~chinese
* @brief 动画调度器
diff --git a/src/kiwano/2d/Button.cpp b/src/kiwano/base/component/Button.cpp
similarity index 98%
rename from src/kiwano/2d/Button.cpp
rename to src/kiwano/base/component/Button.cpp
index 061c87fb..c37e207b 100644
--- a/src/kiwano/2d/Button.cpp
+++ b/src/kiwano/base/component/Button.cpp
@@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include
+#include
#include
#include
diff --git a/src/kiwano/2d/Button.h b/src/kiwano/base/component/Button.h
similarity index 100%
rename from src/kiwano/2d/Button.h
rename to src/kiwano/base/component/Button.h
diff --git a/src/kiwano/2d/Component.cpp b/src/kiwano/base/component/Component.cpp
similarity index 97%
rename from src/kiwano/2d/Component.cpp
rename to src/kiwano/base/component/Component.cpp
index a22a9c22..7fbdb59e 100644
--- a/src/kiwano/2d/Component.cpp
+++ b/src/kiwano/base/component/Component.cpp
@@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include
+#include
#include
namespace kiwano
diff --git a/src/kiwano/2d/Component.h b/src/kiwano/base/component/Component.h
similarity index 96%
rename from src/kiwano/2d/Component.h
rename to src/kiwano/base/component/Component.h
index 9d486cc6..c48a168a 100644
--- a/src/kiwano/2d/Component.h
+++ b/src/kiwano/base/component/Component.h
@@ -29,6 +29,7 @@ namespace kiwano
class Actor;
class Event;
+class ComponentManager;
KGE_DECLARE_SMART_PTR(Component);
@@ -42,10 +43,6 @@ KGE_DECLARE_SMART_PTR(Component);
* @{
*/
-/// \~chinese
-/// @brief 组件列表
-typedef IntrusiveList ComponentList;
-
/**
* \~chinese
* @brief 组件
@@ -54,7 +51,7 @@ class KGE_API Component
: public ObjectBase
, protected IntrusiveListValue
{
- friend class Actor;
+ friend class ComponentManager;
friend IntrusiveList;
public:
diff --git a/src/kiwano/base/component/ComponentManager.cpp b/src/kiwano/base/component/ComponentManager.cpp
new file mode 100644
index 00000000..8f99ce75
--- /dev/null
+++ b/src/kiwano/base/component/ComponentManager.cpp
@@ -0,0 +1,148 @@
+// Copyright (c) 2016-2018 Kiwano - 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.
+
+#include
+
+namespace kiwano
+{
+
+ComponentManager::ComponentManager(Actor* target)
+ : target_(target)
+{
+}
+
+Component* ComponentManager::AddComponent(ComponentPtr component)
+{
+ KGE_ASSERT(component && "AddComponent failed, NULL pointer exception");
+
+ if (component)
+ {
+ component->InitComponent(target_);
+ components_.PushBack(component);
+ }
+ return component.Get();
+}
+
+ComponentList& ComponentManager::GetAllComponents()
+{
+ return components_;
+}
+
+const ComponentList& ComponentManager::GetAllComponents() const
+{
+ return components_;
+}
+
+void ComponentManager::RemoveComponent(ComponentPtr component)
+{
+ auto iter = std::find(components_.begin(), components_.end(), component);
+ if (iter != components_.end())
+ {
+ component->DestroyComponent();
+ components_.Remove(component);
+ }
+}
+
+void ComponentManager::RemoveComponents(const String& name)
+{
+ if (!components_.IsEmpty())
+ {
+ ComponentPtr next;
+ for (auto component = components_.GetFirst(); component; component = next)
+ {
+ next = component->GetNext();
+
+ if (component->IsName(name))
+ {
+ component->DestroyComponent();
+ components_.Remove(component);
+ }
+ }
+ }
+}
+
+void ComponentManager::RemoveAllComponents()
+{
+ // Destroy all components
+ if (!components_.IsEmpty())
+ {
+ ComponentPtr next;
+ for (auto component = components_.GetFirst(); component; component = next)
+ {
+ next = component->GetNext();
+
+ component->DestroyComponent();
+ }
+ }
+ components_.Clear();
+}
+
+void ComponentManager::Update(Duration dt)
+{
+ if (!components_.IsEmpty())
+ {
+ ComponentPtr next;
+ for (auto component = components_.GetFirst(); component; component = next)
+ {
+ next = component->GetNext();
+
+ if (component->IsEnable())
+ {
+ component->OnUpdate(dt);
+ }
+ }
+ }
+}
+
+void ComponentManager::Render(RenderContext& ctx)
+{
+ if (!components_.IsEmpty())
+ {
+ ComponentPtr next;
+ for (auto component = components_.GetFirst(); component; component = next)
+ {
+ next = component->GetNext();
+
+ if (component->IsEnable())
+ {
+ component->OnRender(ctx);
+ }
+ }
+ }
+}
+
+void ComponentManager::DispatchToComponents(Event* evt)
+{
+ if (!components_.IsEmpty())
+ {
+ ComponentPtr next;
+ for (auto component = components_.GetFirst(); component; component = next)
+ {
+ next = component->GetNext();
+
+ if (component->IsEnable())
+ {
+ component->HandleEvent(evt);
+ }
+ }
+ }
+}
+
+} // namespace kiwano
diff --git a/src/kiwano/base/component/ComponentManager.h b/src/kiwano/base/component/ComponentManager.h
new file mode 100644
index 00000000..469e7eaa
--- /dev/null
+++ b/src/kiwano/base/component/ComponentManager.h
@@ -0,0 +1,92 @@
+// Copyright (c) 2016-2018 Kiwano - 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
+#include
+
+namespace kiwano
+{
+
+/**
+ * \addtogroup Component
+ * @{
+ */
+
+/// \~chinese
+/// @brief 组件列表
+typedef IntrusiveList ComponentList;
+
+/**
+ * \~chinese
+ * @brief 组件管理器
+ */
+class KGE_API ComponentManager
+{
+public:
+ /// \~chinese
+ /// @brief 添加组件
+ /// @param component 组件
+ Component* AddComponent(ComponentPtr component);
+
+ /// \~chinese
+ /// @brief 获取所有组件
+ ComponentList& GetAllComponents();
+
+ /// \~chinese
+ /// @brief 获取所有组件
+ const ComponentList& GetAllComponents() const;
+
+ /// \~chinese
+ /// @brief 移除组件
+ void RemoveComponent(ComponentPtr component);
+
+ /// \~chinese
+ /// @brief 移除组件
+ /// @param name 组件名称
+ void RemoveComponents(const String& name);
+
+ /// \~chinese
+ /// @brief 移除所有组件
+ void RemoveAllComponents();
+
+ /// \~chinese
+ /// @brief 更新组件
+ void Update(Duration dt);
+
+ /// \~chinese
+ /// @brief 渲染组件
+ void Render(RenderContext& ctx);
+
+ /// \~chinese
+ /// @brief 分发事件
+ void DispatchToComponents(Event* evt);
+
+protected:
+ ComponentManager(Actor* target);
+
+private:
+ Actor* target_;
+ ComponentList components_;
+};
+
+/** @} */
+
+} // namespace kiwano
diff --git a/src/kiwano/event/EventDispatcher.h b/src/kiwano/event/EventDispatcher.h
index 3f53cd81..35c286d2 100644
--- a/src/kiwano/event/EventDispatcher.h
+++ b/src/kiwano/event/EventDispatcher.h
@@ -23,6 +23,11 @@
namespace kiwano
{
+
+/// \~chinese
+/// @brief 监听器列表
+typedef IntrusiveList ListenerList;
+
/**
* \~chinese
* @brief 事件分发系统
diff --git a/src/kiwano/event/EventListener.h b/src/kiwano/event/EventListener.h
index 59d9a10d..d179ba11 100644
--- a/src/kiwano/event/EventListener.h
+++ b/src/kiwano/event/EventListener.h
@@ -31,10 +31,6 @@ class EventDispatcher;
KGE_DECLARE_SMART_PTR(EventListener);
-/// \~chinese
-/// @brief 监听器列表
-typedef IntrusiveList ListenerList;
-
/**
* \~chinese
* @brief 事件监听器
diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h
index 8062e660..50ef674e 100644
--- a/src/kiwano/kiwano.h
+++ b/src/kiwano/kiwano.h
@@ -56,6 +56,9 @@
#include
#include
#include
+#include
+#include
+#include
//
@@ -91,7 +94,6 @@
//
#include
-#include
#include
#include
#include
diff --git a/src/kiwano/utils/Task.h b/src/kiwano/utils/Task.h
index 30e4b652..09b27dba 100644
--- a/src/kiwano/utils/Task.h
+++ b/src/kiwano/utils/Task.h
@@ -28,10 +28,6 @@ class TaskScheduler;
KGE_DECLARE_SMART_PTR(Task);
-/// \~chinese
-/// @brief 任务列表
-typedef IntrusiveList TaskList;
-
/// \~chinese
/// @brief 任务
/// @details 任务用于每隔一段时间执行一次回调函数,且可以指定执行总次数
diff --git a/src/kiwano/utils/TaskScheduler.h b/src/kiwano/utils/TaskScheduler.h
index 32ae2c33..65ee6b5a 100644
--- a/src/kiwano/utils/TaskScheduler.h
+++ b/src/kiwano/utils/TaskScheduler.h
@@ -23,6 +23,11 @@
namespace kiwano
{
+
+/// \~chinese
+/// @brief 任务列表
+typedef IntrusiveList TaskList;
+
/**
* \~chinese
* @brief 任务调度器