Added librarys and test application
This commit is contained in:
179
include/entityx/System.h
Normal file
179
include/entityx/System.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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 <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
#include "entityx/config.h"
|
||||
#include "entityx/Entity.h"
|
||||
#include "entityx/Event.h"
|
||||
#include "entityx/help/NonCopyable.h"
|
||||
|
||||
|
||||
namespace entityx {
|
||||
|
||||
|
||||
class SystemManager;
|
||||
|
||||
|
||||
/**
|
||||
* Base System class. Generally should not be directly used, instead see System<Derived>.
|
||||
*/
|
||||
class BaseSystem : entityx::help::NonCopyable {
|
||||
public:
|
||||
typedef size_t Family;
|
||||
|
||||
virtual ~BaseSystem();
|
||||
|
||||
/**
|
||||
* Called once all Systems have been added to the SystemManager.
|
||||
*
|
||||
* Typically used to set up event handlers.
|
||||
*/
|
||||
virtual void configure(EntityManager &entities, EventManager &events) {
|
||||
configure(events);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy configure(). Called by default implementation of configure(EntityManager&, EventManager&).
|
||||
*/
|
||||
virtual void configure(EventManager &events) {}
|
||||
|
||||
/**
|
||||
* Apply System behavior.
|
||||
*
|
||||
* Called every game step.
|
||||
*/
|
||||
virtual void update(EntityManager &entities, EventManager &events, TimeDelta dt) = 0;
|
||||
|
||||
static Family family_counter_;
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Use this class when implementing Systems.
|
||||
*
|
||||
* struct MovementSystem : public System<MovementSystem> {
|
||||
* void update(EntityManager &entities, EventManager &events, TimeDelta dt) {
|
||||
* // Do stuff to/with entities...
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
template <typename Derived>
|
||||
class System : public BaseSystem {
|
||||
public:
|
||||
virtual ~System() {}
|
||||
|
||||
private:
|
||||
friend class SystemManager;
|
||||
|
||||
static Family family() {
|
||||
static Family family = family_counter_++;
|
||||
return family;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class SystemManager : entityx::help::NonCopyable {
|
||||
public:
|
||||
SystemManager(EntityManager &entity_manager,
|
||||
EventManager &event_manager) :
|
||||
entity_manager_(entity_manager),
|
||||
event_manager_(event_manager) {}
|
||||
|
||||
/**
|
||||
* Add a System to the SystemManager.
|
||||
*
|
||||
* Must be called before Systems can be used.
|
||||
*
|
||||
* eg.
|
||||
* std::shared_ptr<MovementSystem> movement = entityx::make_shared<MovementSystem>();
|
||||
* system.add(movement);
|
||||
*/
|
||||
template <typename S>
|
||||
void add(std::shared_ptr<S> system) {
|
||||
systems_.insert(std::make_pair(S::family(), system));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a System to the SystemManager.
|
||||
*
|
||||
* Must be called before Systems can be used.
|
||||
*
|
||||
* eg.
|
||||
* auto movement = system.add<MovementSystem>();
|
||||
*/
|
||||
template <typename S, typename ... Args>
|
||||
std::shared_ptr<S> add(Args && ... args) {
|
||||
std::shared_ptr<S> s(new S(std::forward<Args>(args) ...));
|
||||
add(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the registered System instance, if any.
|
||||
*
|
||||
* std::shared_ptr<CollisionSystem> collisions = systems.system<CollisionSystem>();
|
||||
*
|
||||
* @return System instance or empty shared_std::shared_ptr<S>.
|
||||
*/
|
||||
template <typename S>
|
||||
std::shared_ptr<S> system() {
|
||||
auto it = systems_.find(S::family());
|
||||
assert(it != systems_.end());
|
||||
return it == systems_.end()
|
||||
? std::shared_ptr<S>()
|
||||
: std::shared_ptr<S>(std::static_pointer_cast<S>(it->second));
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the System::update() method for a registered system.
|
||||
*/
|
||||
template <typename S>
|
||||
void update(TimeDelta dt) {
|
||||
assert(initialized_ && "SystemManager::configure() not called");
|
||||
std::shared_ptr<S> s = system<S>();
|
||||
s->update(entity_manager_, event_manager_, dt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call System::update() on all registered systems.
|
||||
*
|
||||
* The order which the registered systems are updated is arbitrary but consistent,
|
||||
* meaning the order which they will be updated cannot be specified, but that order
|
||||
* will stay the same as long no systems are added or removed.
|
||||
*
|
||||
* If the order in which systems update is important, use SystemManager::update()
|
||||
* to manually specify the update order. EntityX does not yet support a way of
|
||||
* specifying priority for update_all().
|
||||
*/
|
||||
void update_all(TimeDelta dt);
|
||||
|
||||
/**
|
||||
* Configure the system. Call after adding all Systems.
|
||||
*
|
||||
* This is typically used to set up event handlers.
|
||||
*/
|
||||
void configure();
|
||||
|
||||
private:
|
||||
bool initialized_ = false;
|
||||
EntityManager &entity_manager_;
|
||||
EventManager &event_manager_;
|
||||
std::unordered_map<BaseSystem::Family, std::shared_ptr<BaseSystem>> systems_;
|
||||
};
|
||||
|
||||
} // namespace entityx
|
||||
Reference in New Issue
Block a user