]> code.bitgloo.com Git - clyne/entityx.git/commitdiff
Allow shared_ptr implementation to be selected.
authorAlec Thomas <alec@swapoff.org>
Mon, 1 Apr 2013 15:51:29 +0000 (11:51 -0400)
committerAlec Thomas <alec@swapoff.org>
Tue, 2 Apr 2013 21:50:58 +0000 (17:50 -0400)
Fixes #6.

.gitignore
.travis.yml
CMakeLists.txt
README.md
entityx/Benchmarks_test.cc
entityx/Components.h
entityx/Entity.h
entityx/Event.h
entityx/System.h
entityx/config.h.in [new file with mode: 0644]
scripts/travis.sh [new file with mode: 0755]

index f08d8e3310072361568b28eb2f563543d1089305..4f2a96241fe2cbfef2570d7c887abd64c5f1e181 100644 (file)
@@ -3,3 +3,4 @@
 *.so
 *.o
 build/*
+entityx/config.h
index e7ac9b837e27ac9e809f9e9cb1cb0107c97ae773..1f5acba0dd9ba0227a97b7c207935eee89ff0005 100644 (file)
@@ -2,6 +2,9 @@ language: cpp
 compiler:
   - clang
   - gcc
+env:
+  - USE_STD_SHARED_PTR=1
+  - USE_STD_SHARED_PTR=0
 before_install:
   - sudo apt-add-repository -y ppa:jkeiren/ppa
   - if test $CC = gcc; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
@@ -14,4 +17,4 @@ before_install:
   - if test $CC = gcc; then sudo update-alternatives --config gcc; fi
   - if test $CC = gcc; then sudo update-alternatives --config g++; fi
 
-script: cmake -DBUILD_TESTING=1 && make && make test
+script: ./scripts/travis.sh
index 9200f8c374afef81494a1f9e21771dcdc6bd0863..013c96e88ed6cff1b1d0ffd932cef8648b7d216c 100644 (file)
@@ -5,10 +5,82 @@ include_directories(${CMAKE_CURRENT_LIST_DIR})
 set(RUN_BENCHMARKS false CACHE BOOL "Run benchmarks")
 
 include(${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake)
+include(CheckCXXSourceCompiles)
+
+# Default compiler args
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Werror -Wall -Wextra -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=sign-compare -std=c++11")
+set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
+set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
+
 # C++11 feature checks
 include(CheckCXX11Features.cmake)
+
 # Misc features
-CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H)
+check_include_file("stdint.h" HAVE_STDINT_H)
+
+set(USE_CPP11_STDLIB false CACHE BOOL "Use the C++11 stdlib (-stdlib=libc++).")
+
+if (USE_CPP11_STDLIB)
+    set(OLD_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+    check_cxx_source_compiles(
+    "
+    #include <memory>
+
+    int main() {
+        std::shared_ptr<int>();
+    }
+    "
+    HAVE_CXX11_STDLIB
+    )
+
+    if (NOT HAVE_CXX11_STDLIB)
+        message("-- Not using -stdlib=libc++ (test failed to build)")
+        set(CMAKE_CXX_FLAGS "${OLD_CMAKE_CXX_FLAGS}")
+    else ()
+        message("-- Using -stdlib=libc++")
+    endif ()
+else ()
+    message("-- Using default stdlib (try -DUSE_CPP11_STDLIB=1 to use -stdlib=libc++)")
+endif ()
+
+# Check for which shared_ptr implementation to use.
+set(USE_STD_SHARED_PTR false CACHE BOOL "Use std::shared_ptr<T> rather than boost::shared_ptr<T>?")
+
+check_cxx_source_compiles(
+"
+#include <memory>
+
+int main() { std::shared_ptr<int>(); }
+"
+HAVE_STD_SHARED_PTR
+)
+
+check_cxx_source_compiles(
+"
+#include <boost/shared_ptr.hpp>
+
+int main() { boost::shared_ptr<int>(); }
+"
+HAVE_BOOST_SHARED_PTR
+)
+
+if (HAVE_STD_SHARED_PTR AND USE_STD_SHARED_PTR)
+    message("-- Using std::shared_ptr<T>")
+else()
+    if (USE_STD_SHARED_PTR)
+        message("-- Using boost::shared_ptr<T> (std::shared_ptr<T> could not be used)")
+    else()
+        message("-- Using boost::shared_ptr<T> (try -DUSE_STD_SHARED_PTR=1 to use std::shared_ptr<T>)")
+    endif()
+endif()
+
+configure_file(
+    ${CMAKE_CURRENT_SOURCE_DIR}/entityx/config.h.in
+    ${CMAKE_CURRENT_SOURCE_DIR}/entityx/config.h
+)
 
 macro(require FEATURE_NAME MESSAGE_STRING)
     if (NOT ${${FEATURE_NAME}})
@@ -55,12 +127,6 @@ set(Boost_USE_MULTITHREADED ON)
 set(Boost_USE_STATIC_RUNTIME OFF)
 find_package(Boost 1.48.0 REQUIRED COMPONENTS signals)
 
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Werror -Wall -Wextra -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=sign-compare -std=c++11")
-set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
-set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
-set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
-set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
-
 set(sources entityx/Components.cc entityx/System.cc entityx/Event.cc entityx/Entity.cc entityx/Manager.cc)
 add_library(entityx STATIC ${sources})
 add_library(entityx_shared SHARED ${sources})
index 36f93fa799d898a48aba89bff11d253db0f3d5f1..bc7248d20d23497786676984a0da5e5f23ea56ae 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
 # EntityX - A fast, type-safe C++ Entity-Component system
 
+[![Build Status](https://travis-ci.org/alecthomas/entityx.png)](https://travis-ci.org/alecthomas/entityx)
+
 Entity-Component (EC) systems are a form of decomposition that completely decouples entity logic and data from the entity "objects" themselves. The [Evolve your Hierarchy](http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/) article provides a solid overview of EC systems and why you should use them.
 
 EntityX is an EC system that uses C++11 features to provide type-safe component management, event delivery, etc. It was built during the creation of a 2D space shooter.
@@ -76,7 +78,7 @@ entity.assign<Position>(1.0f, 2.0f);
 You can also assign existing instances of components:
 
 ```c++
-boost::shared_ptr<Position> position = boost::make_shared<Position>(1.0f, 2.0f);
+entityx::shared_ptr<Position> position = entityx::make_shared<Position>(1.0f, 2.0f);
 entity.assign(position);
 ```
 
@@ -86,8 +88,8 @@ To query all entities with a set of components assigned, use ``EntityManager::en
 
 ```c++
 for (auto entity : entities.entities_with_components<Position, Direction>()) {
-  boost::shared_ptr<Position> position = entity.component<Position>();
-  boost::shared_ptr<Direction> direction = entity.component<Direction>();
+  entityx::shared_ptr<Position> position = entity.component<Position>();
+  entityx::shared_ptr<Direction> direction = entity.component<Direction>();
 
   // Do things with entity, position and direction.
 }
@@ -96,7 +98,7 @@ for (auto entity : entities.entities_with_components<Position, Direction>()) {
 To retrieve a component associated with an entity use ``Entity::component<C>()``:
 
 ```c++
-boost::shared_ptr<Position> position = entity.component<Position>();
+entityx::shared_ptr<Position> position = entity.component<Position>();
 if (position) {
   // Do stuff with position
 }
@@ -117,8 +119,8 @@ A basic movement system might be implemented with something like the following:
 struct MovementSystem : public System<MovementSystem> {
   void update(EntityManager &es, EventManager &events, double dt) override {
     for (auto entity : es.entities_with_components<Position, Direction>()) {
-      boost::shared_ptr<Position> position = entity.component<Position>();
-      boost::shared_ptr<Direction> direction = entity.component<Direction>();
+      entityx::shared_ptr<Position> position = entity.component<Position>();
+      entityx::shared_ptr<Direction> direction = entity.component<Direction>();
 
       position->x += direction->x * dt;
       position->y += direction->y * dt;
@@ -154,7 +156,7 @@ Next we implement our collision system, which emits ``Collision`` objects via an
 class CollisionSystem : public System<CollisionSystem> {
  public:
   void update(EntityManager &es, EventManager &events, double dt) override {
-    boost::shared_ptr<Position> left_position, right_position;
+    entityx::shared_ptr<Position> left_position, right_position;
     for (auto left_entity : es.entities_with_components<Position>()) {
       for (auto right_entity : es.entities_with_components<Position>()) {
         if (collide(left_position, right_position)) {
@@ -192,7 +194,7 @@ Several events are emitted by EntityX itself:
   - `Entity entity` - Entity about to be destroyed.
 - `ComponentAddedEvent<T>` - emitted when a new component is added to an entity.
   - `Entity entity` - Entity that component was added to.
-  - `boost::shared_ptr<T> component` - The component added.
+  - `entityx::shared_ptr<T> component` - The component added.
 
 #### Implementation notes
 
index bee7d15f70db084c7405d0eaa175f933a0b6f677..a2ed3631ba3ff81bd3c48a8ecf7f475420926bfd 100644 (file)
@@ -98,7 +98,7 @@ TEST_F(BenchmarksTest, TestEntityIteration) {
 
   for (int i = 0; i < 10; ++i) {
     for (auto e : em.entities_with_components<Position>()) {
-      boost::shared_ptr<Position> position = e.component<Position>();
+      entityx::shared_ptr<Position> position = e.component<Position>();
     }
   }
 }
index c963302a7f55b5a20d6150ccdc0feb7a201f2b94..9168cc586b3b49079bf078a2d3d219357e731531 100644 (file)
@@ -1,10 +1,10 @@
 /**
  * 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>
  */
 
index 65900b902393f2c9d396935ee33a7d74b81480ca..c2d4af1cd614c06a3c4f388ce748612e7288cb6e 100644 (file)
@@ -23,7 +23,7 @@
 #include <utility>
 #include <vector>
 
-#include <boost/shared_ptr.hpp>
+#include "entityx/config.h"
 #include "entityx/Event.h"
 
 namespace entityx {
@@ -88,17 +88,17 @@ class Entity {
   EntityManager &manager() { return *manager_; }
 
   template <typename C>
-  boost::shared_ptr<C> assign(boost::shared_ptr<C> component);
+  entityx::shared_ptr<C> assign(entityx::shared_ptr<C> component);
   template <typename C, typename ... Args>
-  boost::shared_ptr<C> assign(Args && ... args);
+  entityx::shared_ptr<C> assign(Args && ... args);
 
   template <typename C>
-  boost::shared_ptr<C> component();
+  entityx::shared_ptr<C> component();
 
   template <typename A>
-  void unpack(boost::shared_ptr<A> &a);
+  void unpack(entityx::shared_ptr<A> &a);
   template <typename A, typename B, typename ... Args>
-  void unpack(boost::shared_ptr<A> &a, boost::shared_ptr<B> &b, Args && ... args);
+  void unpack(entityx::shared_ptr<A> &a, entityx::shared_ptr<B> &b, Args && ... args);
 
   /**
    * Destroy and invalidate this Entity.
@@ -183,11 +183,11 @@ struct EntityDestroyedEvent : public Event<EntityDestroyedEvent> {
  */
 template <typename T>
 struct ComponentAddedEvent : public Event<ComponentAddedEvent<T>> {
-  ComponentAddedEvent(Entity entity, boost::shared_ptr<T> component) :
+  ComponentAddedEvent(Entity entity, entityx::shared_ptr<T> component) :
       entity(entity), component(component) {}
 
   Entity entity;
-  boost::shared_ptr<T> component;
+  entityx::shared_ptr<T> component;
 };
 
 
@@ -291,7 +291,7 @@ class EntityManager : boost::noncopyable {
     const Iterator end() const { return Iterator(manager_, predicates_, unpackers_, manager_->size()); }
 
     template <typename A>
-    View &unpack_to(boost::shared_ptr<A> &a) {
+    View &unpack_to(entityx::shared_ptr<A> &a) {
       unpackers_.push_back(Unpacker<A>(manager_, a));
       // This resulted in a segfault under clang 4.1 on OSX. No idea why.
       /*unpackers_.push_back([&a, this](Entity::Id id) {
@@ -301,7 +301,7 @@ class EntityManager : boost::noncopyable {
     }
 
     template <typename A, typename B, typename ... Args>
-    View &unpack_to(boost::shared_ptr<A> &a, boost::shared_ptr<B> &b, Args && ... args) {
+    View &unpack_to(entityx::shared_ptr<A> &a, entityx::shared_ptr<B> &b, Args && ... args) {
       unpack_to<A>(a);
       return unpack_to<B, Args ...>(b, args ...);
     }
@@ -310,7 +310,7 @@ class EntityManager : boost::noncopyable {
 
     template <typename T>
     struct Unpacker {
-      Unpacker(EntityManager *manager, boost::shared_ptr<T> &c) : manager_(manager), c(c) {}
+      Unpacker(EntityManager *manager, entityx::shared_ptr<T> &c) : manager_(manager), c(c) {}
 
       void operator () (Entity::Id id) {
         c = manager_->component<T>(id);
@@ -318,7 +318,7 @@ class EntityManager : boost::noncopyable {
 
      private:
       EntityManager *manager_;
-      boost::shared_ptr<T> &c;
+      entityx::shared_ptr<T> &c;
     };
 
     View(EntityManager *manager, Predicate predicate) : manager_(manager) {
@@ -378,8 +378,8 @@ class EntityManager : boost::noncopyable {
    * @returns component
    */
   template <typename C>
-  boost::shared_ptr<C> assign(Entity::Id entity, boost::shared_ptr<C> component) {
-    boost::shared_ptr<BaseComponent> base = boost::static_pointer_cast<BaseComponent>(component);
+  entityx::shared_ptr<C> assign(Entity::Id entity, entityx::shared_ptr<C> component) {
+    entityx::shared_ptr<BaseComponent> base = entityx::static_pointer_cast<BaseComponent>(component);
     accomodate_component(C::family());
     entity_components_.at(C::family()).at(entity) = base;
     entity_component_mask_.at(entity) |= uint64_t(1) << C::family();
@@ -396,8 +396,8 @@ class EntityManager : boost::noncopyable {
    * @returns Newly created component.
    */
   template <typename C, typename ... Args>
-  boost::shared_ptr<C> assign(Entity::Id entity, Args && ... args) {
-    return assign<C>(entity, boost::make_shared<C>(args ...));
+  entityx::shared_ptr<C> assign(Entity::Id entity, Args && ... args) {
+    return assign<C>(entity, entityx::make_shared<C>(args ...));
   }
 
   /**
@@ -406,13 +406,13 @@ class EntityManager : boost::noncopyable {
    * @returns Component instance, or empty shared_ptr<> if the Entity::Id does not have that Component.
    */
   template <typename C>
-  boost::shared_ptr<C> component(Entity::Id id) {
+  entityx::shared_ptr<C> component(Entity::Id id) {
     // We don't bother checking the component mask, as we return a nullptr anyway.
     if (C::family() >= entity_components_.size()) {
-      return boost::shared_ptr<C>();
+      return entityx::shared_ptr<C>();
     }
-    boost::shared_ptr<BaseComponent> c = entity_components_.at(C::family()).at(id);
-    return boost::static_pointer_cast<C>(c);
+    entityx::shared_ptr<BaseComponent> c = entity_components_.at(C::family()).at(id);
+    return entityx::static_pointer_cast<C>(c);
   }
 
   /**
@@ -428,7 +428,7 @@ class EntityManager : boost::noncopyable {
    * Find Entities that have all of the specified Components.
    */
   template <typename C, typename ... Components>
-  View entities_with_components(boost::shared_ptr<C> &c, Components && ... args) {
+  View entities_with_components(entityx::shared_ptr<C> &c, Components && ... args) {
     auto mask = component_mask(c, args ...);
     return
         View(this, View::ComponentMaskPredicate(entity_component_mask_, mask))
@@ -442,12 +442,12 @@ class EntityManager : boost::noncopyable {
    *
    * Useful for fast bulk iterations.
    *
-   * boost::shared_ptr<Position> p;
-   * boost::shared_ptr<Direction> d;
+   * entityx::shared_ptr<Position> p;
+   * entityx::shared_ptr<Direction> d;
    * unpack<Position, Direction>(e, p, d);
    */
   template <typename A>
-  void unpack(Entity::Id id, boost::shared_ptr<A> &a) {
+  void unpack(Entity::Id id, entityx::shared_ptr<A> &a) {
     a = component<A>(id);
   }
 
@@ -458,12 +458,12 @@ class EntityManager : boost::noncopyable {
    *
    * Useful for fast bulk iterations.
    *
-   * boost::shared_ptr<Position> p;
-   * boost::shared_ptr<Direction> d;
+   * entityx::shared_ptr<Position> p;
+   * entityx::shared_ptr<Direction> d;
    * unpack<Position, Direction>(e, p, d);
    */
   template <typename A, typename B, typename ... Args>
-  void unpack(Entity::Id id, boost::shared_ptr<A> &a, boost::shared_ptr<B> &b, Args && ... args) {
+  void unpack(Entity::Id id, entityx::shared_ptr<A> &a, entityx::shared_ptr<B> &b, Args && ... args) {
     unpack<A>(id, a);
     unpack<B, Args ...>(id, b, args ...);
   }
@@ -482,12 +482,12 @@ class EntityManager : boost::noncopyable {
   }
 
   template <typename C>
-  ComponentMask component_mask(const boost::shared_ptr<C> &c) {
+  ComponentMask component_mask(const entityx::shared_ptr<C> &c) {
     return component_mask<C>();
   }
 
   template <typename C1, typename C2, typename ... Components>
-  ComponentMask component_mask(const boost::shared_ptr<C1> &c1, const boost::shared_ptr<C2> &c2, Components && ... args) {
+  ComponentMask component_mask(const entityx::shared_ptr<C1> &c1, const entityx::shared_ptr<C2> &c2, Components && ... args) {
     return component_mask<C1>(c1) | component_mask<C2, Components ...>(c2, args...);
   }
 
@@ -513,7 +513,7 @@ class EntityManager : boost::noncopyable {
 
   EventManager &event_manager_;
   // A nested array of: components = entity_components_[family][entity]
-  std::vector<std::vector<boost::shared_ptr<BaseComponent>>> entity_components_;
+  std::vector<std::vector<entityx::shared_ptr<BaseComponent>>> entity_components_;
   // Bitmask of components associated with each entity. Index into the vector is the Entity::Id.
   std::vector<ComponentMask> entity_component_mask_;
   // List of available Entity::Id IDs.
@@ -528,27 +528,27 @@ BaseComponent::Family Component<C>::family() {
 }
 
 template <typename C>
-boost::shared_ptr<C> Entity::assign(boost::shared_ptr<C> component) {
+entityx::shared_ptr<C> Entity::assign(entityx::shared_ptr<C> component) {
   return manager_->assign<C>(id_, component);
 }
 
 template <typename C, typename ... Args>
-boost::shared_ptr<C> Entity::assign(Args && ... args) {
+entityx::shared_ptr<C> Entity::assign(Args && ... args) {
   return manager_->assign<C>(id_, args ...);
 }
 
 template <typename C>
-boost::shared_ptr<C> Entity::component() {
+entityx::shared_ptr<C> Entity::component() {
   return manager_->component<C>(id_);
 }
 
 template <typename A>
-void Entity::unpack(boost::shared_ptr<A> &a) {
+void Entity::unpack(entityx::shared_ptr<A> &a) {
   manager_->unpack(id_, a);
 }
 
 template <typename A, typename B, typename ... Args>
-void Entity::unpack(boost::shared_ptr<A> &a, boost::shared_ptr<B> &b, Args && ... args) {
+void Entity::unpack(entityx::shared_ptr<A> &a, entityx::shared_ptr<B> &b, Args && ... args) {
   manager_->unpack(id_, a, b, args ...);
 }
 
index a599b9052c12af77a5871839259ea959fac25af8..fcec247f7bed9df05450c956ab35c2517bb06641 100644 (file)
@@ -1,22 +1,22 @@
 /**
  * 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 <stdint.h>
-#include <boost/shared_ptr.hpp>
 #include <boost/bind.hpp>
 #include <boost/function.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/signal.hpp>
 #include <boost/unordered_map.hpp>
+#include "entityx/config.h"
 
 
 namespace entityx {
@@ -25,7 +25,7 @@ namespace entityx {
 /// Used internally by the EventManager.
 class BaseEvent {
  public:
-  typedef boost::shared_ptr<BaseEvent> Ptr;
+  typedef entityx::shared_ptr<BaseEvent> Ptr;
   typedef uint64_t Family;
 
   virtual ~BaseEvent() {}
@@ -46,7 +46,7 @@ class BaseEvent {
 template <typename Derived>
 class Event : public BaseEvent {
  public:
-  typedef boost::shared_ptr<Event<Derived>> Ptr;
+  typedef entityx::shared_ptr<Event<Derived>> Ptr;
 
   /// Used internally for registration.
   static Family family() {
@@ -127,17 +127,17 @@ class EventManager : boost::noncopyable {
 
  private:
   typedef boost::signal<void (const BaseEvent*)> EventSignal;
-  typedef boost::shared_ptr<EventSignal> EventSignalPtr;
+  typedef entityx::shared_ptr<EventSignal> EventSignalPtr;
 
    EventSignalPtr signal_for(int id) {
     auto it = handlers_.find(id);
     if (it == handlers_.end()) {
-      EventSignalPtr sig(boost::make_shared<EventSignal>());
+      EventSignalPtr sig(entityx::make_shared<EventSignal>());
       handlers_.insert(make_pair(id, sig));
       return sig;
     }
     return it->second;
-  } 
+  }
 
   // Functor used as an event signal callback that casts to E.
   template <typename E>
index 962fd290755ed0cc69a6d82139ab89e1d5e06f1b..b0077d7a4b992ad85b33737094a869f2a59bd58c 100644 (file)
@@ -14,8 +14,8 @@
 #include <stdint.h>
 #include <cassert>
 #include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
 #include <boost/unordered_map.hpp>
+#include "entityx/config.h"
 #include "entityx/Entity.h"
 #include "entityx/Event.h"
 
@@ -82,11 +82,11 @@ class SystemManager : boost::noncopyable {
    * Must be called before Systems can be used.
    *
    * eg.
-   * boost::shared_ptr<MovementSystem> movement = boost::make_shared<MovementSystem>();
+   * entityx::shared_ptr<MovementSystem> movement = entityx::make_shared<MovementSystem>();
    * system.add(movement);
    */
   template <typename S>
-  void add(boost::shared_ptr<S> system) {
+  void add(entityx::shared_ptr<S> system) {
     systems_.insert(std::make_pair(S::family(), system));
   }
 
@@ -99,8 +99,8 @@ class SystemManager : boost::noncopyable {
    * auto movement = system.add<MovementSystem>();
    */
   template <typename S, typename ... Args>
-  boost::shared_ptr<S> add(Args && ... args) {
-    boost::shared_ptr<S> s = boost::make_shared<S>(args ...);
+  entityx::shared_ptr<S> add(Args && ... args) {
+    entityx::shared_ptr<S> s = entityx::make_shared<S>(args ...);
     add(s);
     return s;
   }
@@ -108,17 +108,17 @@ class SystemManager : boost::noncopyable {
   /**
    * Retrieve the registered System instance, if any.
    *
-   *   boost::shared_ptr<CollisionSystem> collisions = systems.system<CollisionSystem>();
+   *   entityx::shared_ptr<CollisionSystem> collisions = systems.system<CollisionSystem>();
    *
    * @return System instance or empty shared_ptr<S>.
    */
   template <typename S>
-  boost::shared_ptr<S> system() {
+  entityx::shared_ptr<S> system() {
     auto it = systems_.find(S::family());
     assert(it != systems_.end());
     return it == systems_.end()
-        ? boost::shared_ptr<S>()
-        : boost::static_pointer_cast<S>(it->second);
+        ? entityx::shared_ptr<S>()
+        : entityx::static_pointer_cast<S>(it->second);
   }
 
   /**
@@ -127,7 +127,7 @@ class SystemManager : boost::noncopyable {
   template <typename S>
   void update(double dt) {
     assert(initialized_ && "SystemManager::configure() not called");
-    boost::shared_ptr<S> s = system<S>();
+    entityx::shared_ptr<S> s = system<S>();
     s->update(entities_, events_, dt);
   }
 
@@ -142,7 +142,7 @@ class SystemManager : boost::noncopyable {
   bool initialized_ = false;
   EntityManager &entities_;
   EventManager &events_;
-  boost::unordered_map<BaseSystem::Family, boost::shared_ptr<BaseSystem>> systems_;
+  boost::unordered_map<BaseSystem::Family, entityx::shared_ptr<BaseSystem>> systems_;
 };
 
 }
diff --git a/entityx/config.h.in b/entityx/config.h.in
new file mode 100644 (file)
index 0000000..f5d1689
--- /dev/null
@@ -0,0 +1,23 @@
+#pragma once
+
+#cmakedefine HAVE_BOOST_SHARED_PTR 1
+#cmakedefine HAVE_STD_SHARED_PTR 1
+#cmakedefine USE_STD_SHARED_PTR 0
+
+// Which shared_ptr implementation should we use?
+#if (HAVE_STD_SHARED_PTR && USE_STD_SHARED_PTR)
+#include <memory>
+namespace entityx {
+using std::make_shared;
+using std::shared_ptr;
+using std::static_pointer_cast;
+}
+#elif HAVE_BOOST_SHARED_PTR
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+namespace entityx {
+using boost::shared_ptr;
+using boost::make_shared;
+using boost::static_pointer_cast;
+}
+#endif
diff --git a/scripts/travis.sh b/scripts/travis.sh
new file mode 100755 (executable)
index 0000000..9d06fa6
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/bash -e
+
+CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=1"
+
+if [ "$USE_STD_SHARED_PTR" = "1" ]; then
+  CMAKE_ARGS="${CMAKE_ARGS} -DUSE_STD_SHARED_PTR=1"
+  # This fails on OSX
+  if [ "$CXX" = "clang++" ]; then
+    CMAKE_ARGS="${CMAKE_ARGS} -DUSE_CPP11_STDLIB=1"
+  fi
+fi
+
+cmake ${CMAKE_ARGS}
+make
+make test