]> code.bitgloo.com Git - clyne/entityx.git/commitdiff
Agh. .gitignore!
authorAlec Thomas <alec@swapoff.org>
Wed, 3 Apr 2013 00:05:53 +0000 (20:05 -0400)
committerAlec Thomas <alec@swapoff.org>
Wed, 3 Apr 2013 00:07:30 +0000 (20:07 -0400)
entityx/tags/TagsComponent.cc [new file with mode: 0644]
entityx/tags/TagsComponent.h [new file with mode: 0644]
entityx/tags/TagsComponent_test.cc [new file with mode: 0644]

diff --git a/entityx/tags/TagsComponent.cc b/entityx/tags/TagsComponent.cc
new file mode 100644 (file)
index 0000000..0906d83
--- /dev/null
@@ -0,0 +1,11 @@
+/**
+ * Copyright (C) 2012 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/tags/TagsComponent.h"
diff --git a/entityx/tags/TagsComponent.h b/entityx/tags/TagsComponent.h
new file mode 100644 (file)
index 0000000..d7151f9
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2012 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 <string>
+#include <boost/unordered_set.hpp>
+#include "entityx/Entity.h"
+
+namespace entityx {
+namespace tags {
+
+/**
+ * Allow entities to be tagged with strings.
+ */
+class TagsComponent : public Component<TagsComponent> {
+  struct TagsPredicate {
+    TagsPredicate(const std::string &tag) : tag(tag) {}
+
+    bool operator () (EntityManager &manager, Entity::Id id) {
+      auto tags = manager.component<TagsComponent>(id);
+      return tags != nullptr && tags->tags.find(tag) != tags->tags.end();
+    }
+
+    std::string tag;
+  };
+
+ public:
+  /**
+   * Construct a new TagsComponent with the given tags.
+   *
+   * eg. TagsComponent tags("a", "b", "c");
+   */
+  template <typename ... Args>
+  TagsComponent(const std::string &tag, const Args & ... tags) {
+    set_tags(tag, tags ...);
+  }
+
+  /**
+   * Filter the provided view to only those entities with the given tag.
+   */
+  static EntityManager::View view(const EntityManager::View &view, const std::string &tag) {
+    return EntityManager::View(view, TagsPredicate(tag));
+  }
+
+  boost::unordered_set<std::string> tags;
+
+ private:
+  template <typename ... Args>
+  void set_tags(const std::string &tag1, const std::string &tag2, const Args & ... tags) {
+    this->tags.insert(tag1);
+    set_tags(tag2, tags ...);
+  }
+
+  void set_tags(const std::string &tag) {
+    tags.insert(tag);
+  }
+};
+
+}
+}
diff --git a/entityx/tags/TagsComponent_test.cc b/entityx/tags/TagsComponent_test.cc
new file mode 100644 (file)
index 0000000..a100812
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2012 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/tags/TagsComponent.h"
+
+using namespace std;
+using namespace boost;
+using namespace entityx;
+using namespace entityx::tags;
+
+
+struct Position : public Component<Position> {};
+
+
+template <typename T>
+int size(const T &t) {
+  int n = 0;
+  for (auto i : t) {
+    ++n;
+    (void)i; // Unused on purpose, suppress warning
+  }
+  return n;
+}
+
+
+TEST(TagsComponentTest, TestVariadicConstruction) {
+  auto tags = TagsComponent("player", "indestructible");
+  unordered_set<string> expected;
+  expected.insert("player");
+  expected.insert("indestructible");
+  ASSERT_TRUE(expected == tags.tags);
+}
+
+TEST(TagsComponentTest, TestEntitiesWithTag) {
+  EventManager ev;
+  EntityManager en(ev);
+  Entity a = en.create();
+  a.assign<Position>();
+  for (int i = 0; i < 99; ++i) {
+    auto e = en.create();
+    e.assign<Position>();
+    e.assign<TagsComponent>("positionable");
+  }
+  a.assign<TagsComponent>("player", "indestructible");
+  auto entities = en.entities_with_components<Position>();
+  ASSERT_EQ(100, size(entities));
+  ASSERT_EQ(1, size(TagsComponent::view(entities, "player")));
+}