Created
April 29, 2018 19:40
-
-
Save tylerreisinger/63717311972a8eeb7dc0feb69e9c4fb3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/entityx/Entity.h b/entityx/Entity.h | |
index 7c69e0a..7a205c7 100644 | |
--- a/entityx/Entity.h | |
+++ b/entityx/Entity.h | |
@@ -34,6 +34,11 @@ | |
#include "entityx/Event.h" | |
#include "entityx/help/NonCopyable.h" | |
+//Included on g++ and clang to demangle type_info::name(). | |
+#if defined(__GNUG__) || defined(__clang__) | |
+#include <cxxabi.h> | |
+#endif | |
+ | |
namespace entityx { | |
typedef std::uint32_t uint32_t; | |
@@ -170,6 +175,7 @@ public: | |
Entity::Id id_ = INVALID; | |
}; | |
+std::ostream &operator << (std::ostream &out, const Entity::Id &id); | |
/** | |
* A ComponentHandle<C> is a wrapper around an instance of a component. | |
@@ -342,9 +348,11 @@ public: | |
virtual void remove_component(Entity e) = 0; | |
virtual void copy_component_to(Entity source, Entity target) = 0; | |
}; | |
+template <typename C, typename = void> | |
+class ComponentHelper; | |
template <typename C> | |
-class ComponentHelper : public BaseComponentHelper { | |
+class ComponentHelper<C, std::enable_if_t<std::is_copy_constructible_v<C>>>: public BaseComponentHelper { | |
public: | |
void remove_component(Entity e) override { | |
e.remove<C>(); | |
@@ -354,6 +362,33 @@ public: | |
} | |
}; | |
+//If C has no copy constructor, we need to not call `assign_from_copy` or it is an error, even if | |
+//the component is never copied. | |
+//If copy_component_to is called on C, then we print a helpful error and abort. | |
+template <typename C> | |
+class ComponentHelper<C, std::enable_if_t<!std::is_copy_constructible_v<C>>>: public BaseComponentHelper { | |
+public: | |
+ void remove_component(Entity e) override { | |
+ e.remove<C>(); | |
+ } | |
+ void copy_component_to(Entity source, Entity target) override { | |
+ int status = 0; | |
+//G++ and clang return mangled symbols in name. VC++ always returns the unmangled symbol directly. | |
+#if defined(__GNUG__) || defined(__clang__) | |
+ auto component_name = abi::__cxa_demangle(typeid(C).name(), 0, 0, &status); | |
+#else | |
+ auto component_name = typeid(C).name(); | |
+#endif | |
+ std::cerr << "Error trying to copy a component of type '" << component_name | |
+ << "' from entity " << source.id() << " to entity " << target.id() << "." | |
+ << "'" << component_name << "' is not copy constructable.\n"; | |
+ std::abort(); | |
+#if defined(__GNUG__) || defined(__clang__) | |
+ free(component_name); | |
+#endif | |
+ } | |
+}; | |
+ | |
/** | |
* Manages Entity::Id creation and component assignment. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment