aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--Doxyfile4
-rw-r--r--entityx/deps/Dependencies.cc11
-rw-r--r--entityx/deps/Dependencies.h54
-rw-r--r--entityx/deps/Dependencies_test.cc77
5 files changed, 146 insertions, 3 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 761a031..ba530fa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -102,7 +102,7 @@ set(install_libs entityx)
include(CheckCXX11SharedPtr.cmake)
-set(sources entityx/tags/TagsComponent.cc entityx/System.cc entityx/Event.cc entityx/Entity.cc entityx/Manager.cc)
+set(sources entityx/tags/TagsComponent.cc entityx/deps/Dependencies.cc entityx/System.cc entityx/Event.cc entityx/Entity.cc entityx/Manager.cc)
add_library(entityx STATIC ${sources})
if (ENTITYX_BUILD_SHARED)
@@ -157,6 +157,7 @@ if (ENTITYX_BUILD_TESTING)
create_test(event_test entityx/Event_test.cc)
create_test(system_test entityx/System_test.cc)
create_test(tags_component_test entityx/tags/TagsComponent_test.cc)
+ create_test(dependencies_test entityx/deps/Dependencies_test.cc)
if (Boost_PYTHON_LIBRARY)
add_definitions(-DENTITYX_PYTHON_TEST_DATA=\"${CMAKE_CURRENT_SOURCE_DIR}/entityx/python\")
create_test(python_test entityx/python/PythonSystem_test.cc entityx_python ${Boost_PYTHON_LIBRARY} ${PYTHON_LIBRARIES})
diff --git a/Doxyfile b/Doxyfile
index bcbc897..d115462 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -654,7 +654,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = entityx
+INPUT = entityx README.md entityx/python/README.md
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -672,7 +672,7 @@ INPUT_ENCODING = UTF-8
# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
# *.f90 *.f *.for *.vhd *.vhdl
-FILE_PATTERNS = *.h *.md
+FILE_PATTERNS = *.h
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
diff --git a/entityx/deps/Dependencies.cc b/entityx/deps/Dependencies.cc
new file mode 100644
index 0000000..9271a2f
--- /dev/null
+++ b/entityx/deps/Dependencies.cc
@@ -0,0 +1,11 @@
+/*
+ * Copyright (C) 2013 Alec Thomas <alec@swapoff.org>
+ * All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.
+ *
+ * Author: Alec Thomas <alec@swapoff.org>
+ */
+
+#include "entityx/deps/Dependencies.h"
diff --git a/entityx/deps/Dependencies.h b/entityx/deps/Dependencies.h
new file mode 100644
index 0000000..69e68bb
--- /dev/null
+++ b/entityx/deps/Dependencies.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 Alec Thomas <alec@swapoff.org>
+ * All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.
+ *
+ * Author: Alec Thomas <alec@swapoff.org>
+ */
+#pragma once
+
+#include "entityx/System.h"
+#include "entityx/Event.h"
+#include "entityx/Entity.h"
+
+namespace entityx {
+namespace deps {
+
+/**
+ * An entityx::System for declaring component dependencies.
+ *
+ * eg. To declare that a `Physics` component must always be paired with `Position`
+ * and `Direction` components:
+ *
+ * system_manager->add<Dependency<Physics, Position, Direction>>();
+ */
+template <typename C, typename ... Deps>
+class Dependency : public System<Dependency<C, Deps...>>, public Receiver<Dependency<C, Deps...>> {
+public:
+ void receive(const ComponentAddedEvent<C> &event) {
+ assign<Deps...>(event.entity);
+ }
+
+ virtual void configure(ptr<EventManager> events) override {
+ events->subscribe<ComponentAddedEvent<C>>(*this);
+ }
+
+ virtual void update(ptr<EntityManager> entities, ptr<EventManager> events, double dt) override {}
+
+private:
+ template <typename D>
+ void assign(Entity entity) {
+ if (!entity.component<D>()) entity.assign<D>();
+ }
+
+ template <typename D, typename D1, typename ... Ds>
+ void assign(Entity entity) {
+ assign<D>(entity);
+ assign<D1, Ds...>(entity);
+ }
+};
+
+} // namespace deps
+} // namespace entityx
diff --git a/entityx/deps/Dependencies_test.cc b/entityx/deps/Dependencies_test.cc
new file mode 100644
index 0000000..8a2f17c
--- /dev/null
+++ b/entityx/deps/Dependencies_test.cc
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Alec Thomas <alec@swapoff.org>
+ * All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.
+ *
+ * Author: Alec Thomas <alec@swapoff.org>
+ */
+
+#include <gtest/gtest.h>
+#include "entityx/deps/Dependencies.h"
+
+
+namespace ex = entityx;
+namespace deps = entityx::deps;
+
+
+struct A : public ex::Component<A> {};
+struct B : public ex::Component<B> {
+ explicit B(bool b = false) : b(b) {}
+
+ bool b;
+};
+struct C : public ex::Component<C> {};
+
+
+class DepsTest : public ::testing::Test {
+ protected:
+ DepsTest() : events(ex::EventManager::make()),
+ entities(ex::EntityManager::make(events)),
+ systems(ex::SystemManager::make(entities, events)) {}
+
+ ex::ptr<ex::EventManager> events;
+ ex::ptr<ex::EntityManager> entities;
+ ex::ptr<ex::SystemManager> systems;
+
+ virtual void SetUp() {}
+};
+
+
+TEST_F(DepsTest, TestSingleDependency) {
+ systems->add<deps::Dependency<A, B>>();
+ systems->configure();
+
+ ex::Entity e = entities->create();
+ ASSERT_FALSE(static_cast<bool>(e.component<A>()));
+ ASSERT_FALSE(static_cast<bool>(e.component<B>()));
+ e.assign<A>();
+ ASSERT_TRUE(static_cast<bool>(e.component<A>()));
+ ASSERT_TRUE(static_cast<bool>(e.component<B>()));
+}
+
+TEST_F(DepsTest, TestMultipleDependencies) {
+ systems->add<deps::Dependency<A, B, C>>();
+ systems->configure();
+
+ ex::Entity e = entities->create();
+ ASSERT_FALSE(static_cast<bool>(e.component<A>()));
+ ASSERT_FALSE(static_cast<bool>(e.component<B>()));
+ ASSERT_FALSE(static_cast<bool>(e.component<C>()));
+ e.assign<A>();
+ ASSERT_TRUE(static_cast<bool>(e.component<A>()));
+ ASSERT_TRUE(static_cast<bool>(e.component<B>()));
+ ASSERT_TRUE(static_cast<bool>(e.component<C>()));
+}
+
+TEST_F(DepsTest, TestDependencyDoesNotRecreateComponent) {
+ systems->add<deps::Dependency<A, B>>();
+ systems->configure();
+
+ ex::Entity e = entities->create();
+ e.assign<B>(true);
+ ASSERT_TRUE(e.component<B>()->b);
+ e.assign<A>();
+ ASSERT_TRUE(e.component<B>()->b);
+}