From 58e21af84d7f82f0153c946275ceb607097e3c5c Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Fri, 4 Oct 2013 10:41:04 -0400 Subject: Add `Dependency` System for automatic component dependencies. --- CMakeLists.txt | 3 +- Doxyfile | 4 +- entityx/deps/Dependencies.cc | 11 ++++++ entityx/deps/Dependencies.h | 54 +++++++++++++++++++++++++++ entityx/deps/Dependencies_test.cc | 77 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 entityx/deps/Dependencies.cc create mode 100644 entityx/deps/Dependencies.h create mode 100644 entityx/deps/Dependencies_test.cc 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 + * 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 + */ + +#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 + * 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 + */ +#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>(); + */ +template +class Dependency : public System>, public Receiver> { +public: + void receive(const ComponentAddedEvent &event) { + assign(event.entity); + } + + virtual void configure(ptr events) override { + events->subscribe>(*this); + } + + virtual void update(ptr entities, ptr events, double dt) override {} + +private: + template + void assign(Entity entity) { + if (!entity.component()) entity.assign(); + } + + template + void assign(Entity entity) { + assign(entity); + assign(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 + * 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 + */ + +#include +#include "entityx/deps/Dependencies.h" + + +namespace ex = entityx; +namespace deps = entityx::deps; + + +struct A : public ex::Component {}; +struct B : public ex::Component { + explicit B(bool b = false) : b(b) {} + + bool b; +}; +struct C : public ex::Component {}; + + +class DepsTest : public ::testing::Test { + protected: + DepsTest() : events(ex::EventManager::make()), + entities(ex::EntityManager::make(events)), + systems(ex::SystemManager::make(entities, events)) {} + + ex::ptr events; + ex::ptr entities; + ex::ptr systems; + + virtual void SetUp() {} +}; + + +TEST_F(DepsTest, TestSingleDependency) { + systems->add>(); + systems->configure(); + + ex::Entity e = entities->create(); + ASSERT_FALSE(static_cast(e.component())); + ASSERT_FALSE(static_cast(e.component())); + e.assign(); + ASSERT_TRUE(static_cast(e.component())); + ASSERT_TRUE(static_cast(e.component())); +} + +TEST_F(DepsTest, TestMultipleDependencies) { + systems->add>(); + systems->configure(); + + ex::Entity e = entities->create(); + ASSERT_FALSE(static_cast(e.component())); + ASSERT_FALSE(static_cast(e.component())); + ASSERT_FALSE(static_cast(e.component())); + e.assign(); + ASSERT_TRUE(static_cast(e.component())); + ASSERT_TRUE(static_cast(e.component())); + ASSERT_TRUE(static_cast(e.component())); +} + +TEST_F(DepsTest, TestDependencyDoesNotRecreateComponent) { + systems->add>(); + systems->configure(); + + ex::Entity e = entities->create(); + e.assign(true); + ASSERT_TRUE(e.component()->b); + e.assign(); + ASSERT_TRUE(e.component()->b); +} -- cgit v1.2.3