Skip to content

Commit

Permalink
Merge pull request Revolutionary-Games#19 from Nimbal/ogre
Browse files Browse the repository at this point in the history
Reworked the Ogre components and systems
bkloster committed May 15, 2013
2 parents 56d96fd + fe48c90 commit e446c8f
Showing 21 changed files with 582 additions and 343 deletions.
7 changes: 3 additions & 4 deletions res/dist/scripts/test.lua
Original file line number Diff line number Diff line change
@@ -15,10 +15,9 @@ end
player = Entity("player")
playerTransform = TransformComponent()
player:addComponent(playerTransform)
playerMesh = MeshComponent()
player:addComponent(playerMesh)
playerMesh.workingCopy.meshName = "Sinbad.mesh"
playerMesh:touch()
playerSceneNode = OgreSceneNodeComponent()
player:addComponent(playerSceneNode)
player:addComponent(OgreEntityComponent("Sinbad.mesh"))

playerTransform.position = Vector3(0, 0, 0)
playerTransform:touch()
2 changes: 1 addition & 1 deletion src/common/movement.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "common/movement.h"

#include "common/transform.h"
#include "engine/component_factory.h"
#include "engine/component_registry.h"
#include "engine/entity_filter.h"
#include "scripting/luabind.h"

2 changes: 1 addition & 1 deletion src/common/transform.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "common/transform.h"

#include "engine/component_factory.h"
#include "engine/component_registry.h"
#include "scripting/luabind.h"


5 changes: 2 additions & 3 deletions src/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@ add_sources(
${CMAKE_CURRENT_SOURCE_DIR}/component.h
${CMAKE_CURRENT_SOURCE_DIR}/component_collection.cpp
${CMAKE_CURRENT_SOURCE_DIR}/component_collection.h
${CMAKE_CURRENT_SOURCE_DIR}/component_factory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/component_factory.h
${CMAKE_CURRENT_SOURCE_DIR}/component_registry.cpp
${CMAKE_CURRENT_SOURCE_DIR}/component_registry.h
${CMAKE_CURRENT_SOURCE_DIR}/engine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/engine.h
${CMAKE_CURRENT_SOURCE_DIR}/entity.cpp
@@ -20,7 +20,6 @@ add_sources(
)

add_test_sources(
${CMAKE_CURRENT_SOURCE_DIR}/tests/component_factory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/engine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/entity.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/entity_filter.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "engine/component_factory.h"
#include "engine/component_registry.h"

#include <assert.h>
#include <boost/lexical_cast.hpp>
@@ -10,9 +10,7 @@
using namespace thrive;


struct ComponentFactory::Implementation {

std::unordered_map<Component::TypeId, ComponentConstructor> m_constructors;
struct ComponentRegistry::Implementation {

std::unordered_map<Component::TypeId, std::string> m_typeIdToName;

@@ -21,50 +19,27 @@ struct ComponentFactory::Implementation {
};


ComponentFactory&
ComponentFactory::instance() {
static ComponentFactory instance;
ComponentRegistry&
ComponentRegistry::instance() {
static ComponentRegistry instance;
return instance;
}


ComponentFactory::ComponentFactory()
ComponentRegistry::ComponentRegistry()
: m_impl(new Implementation())
{
}


ComponentFactory::~ComponentFactory() {}


std::shared_ptr<Component>
ComponentFactory::create(
const std::string& name
) {
Component::TypeId typeId = this->typeNameToId(name);
return this->create(typeId);
}


std::shared_ptr<Component>
ComponentFactory::create(
Component::TypeId typeId
) {
auto iter = m_impl->m_constructors.find(typeId);
if (iter == m_impl->m_constructors.end()) {
throw std::invalid_argument("Component not found: " + boost::lexical_cast<std::string>(typeId));
}
return iter->second();
}
ComponentRegistry::~ComponentRegistry() {}


bool
ComponentFactory::registerComponent(
ComponentRegistry::registerComponent(
Component::TypeId typeId,
const std::string& name,
ComponentConstructor constructor
const std::string& name
) {
std::cout << "Registering " << name << std::endl;
// Insert name
auto nameInsertionResult = m_impl->m_typeNameToId.insert(
std::make_pair(name, typeId)
@@ -82,17 +57,13 @@ ComponentFactory::registerComponent(
std::cout << "Duplicate component id: " << name << std::endl;
return false;
}
// Insert constructor
auto constructorInsertionResult = m_impl->m_constructors.insert(
std::make_pair(typeId, constructor)
);
assert(constructorInsertionResult.second && "Name and type id are unique, but constructor is not?!");
// Success
return true;
}


Component::TypeId
ComponentFactory::typeNameToId(
ComponentRegistry::typeNameToId(
const std::string& name
) {
auto iter = m_impl->m_typeNameToId.find(name);
@@ -104,7 +75,7 @@ ComponentFactory::typeNameToId(


std::string
ComponentFactory::typeIdToName(
ComponentRegistry::typeIdToName(
Component::TypeId typeId
) {
auto iter = m_impl->m_typeIdToName.find(typeId);
@@ -115,5 +86,3 @@ ComponentFactory::typeIdToName(
}




66 changes: 10 additions & 56 deletions src/engine/component_factory.h → src/engine/component_registry.h
Original file line number Diff line number Diff line change
@@ -3,62 +3,23 @@
#include "engine/component.h"

#include <memory>
#include <stdexcept>

namespace thrive {

/**
* @brief Produces components by name
* @brief Central registry for component classes
*/
class ComponentFactory {
class ComponentRegistry {

public:

/**
* @brief Produces shared pointers of components
*
* shared_ptr was selected over unique_ptr here because the EntityManager
* and the ComponentCollection instances will need shared pointers.
* Constructing a shared pointer from the start will allow us to use
* std::make_shared, improving cache coherency.
*/
using ComponentConstructor = std::function<std::shared_ptr<Component>(void)>;

/**
* @brief Returns the singleton instance
*/
static ComponentFactory&
static ComponentRegistry&
instance();

/**
* @brief Creates a component by name
*
* @param name The component's type name
*
* @return A new component
*
* @throws std::invalid_argument if the name is unknown
*
* @note The type id overload should be preferred for performance reasons
*/
std::shared_ptr<Component>
create(
const std::string& name
);

/**
* @brief Creates a component by type id
*
* @param typeId The component's type id
*
* @return A new component
*
* @throws std::invalid_argument if the id is unknown
*/
std::shared_ptr<Component>
create(
Component::TypeId typeId
);

/**
* @brief Registers a component by class
*
@@ -73,10 +34,7 @@ class ComponentFactory {
registerClass() {
return this->registerComponent(
C::TYPE_ID(),
C::TYPE_NAME(),
[]() -> std::shared_ptr<Component> {
return std::make_shared<C>();
}
C::TYPE_NAME()
);
}

@@ -87,9 +45,6 @@ class ComponentFactory {
* The component's type id
* @param name
* The component's name (e.g. for scripts)
* @param constructor
* An \c std::function taking \c void and returning a shared
* pointer to a new component.
*
* @return \c true if the registration was successful, false otherwise
*
@@ -99,8 +54,7 @@ class ComponentFactory {
bool
registerComponent(
Component::TypeId typeId,
const std::string& name,
ComponentConstructor constructor
const std::string& name
);

/**
@@ -139,20 +93,20 @@ class ComponentFactory {

private:

ComponentFactory();
ComponentRegistry();

~ComponentFactory();
~ComponentRegistry();

struct Implementation;
std::unique_ptr<Implementation> m_impl;
};

/**
* @brief Registers a component class with the ComponentFactory
* @brief Registers a component class with the ComponentRegistry
*
* Use this in the component's source file.
*/
#define REGISTER_COMPONENT(cls) \
static const bool cls ## _REGISTERED = thrive::ComponentFactory::instance().registerClass<cls>();
static const bool cls ## _REGISTERED = thrive::ComponentRegistry::instance().registerClass<cls>();

}
8 changes: 4 additions & 4 deletions src/engine/entity.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "engine/entity.h"

#include "engine/component_factory.h"
#include "engine/component_registry.h"
#include "engine/entity_manager.h"
#include "game.h"
#include "scripting/luabind.h"
@@ -165,7 +165,7 @@ Entity::getComponent(
const std::string& typeName
) {
return this->getComponent(
ComponentFactory::instance().typeNameToId(typeName)
ComponentRegistry::instance().typeNameToId(typeName)
);
}

@@ -187,7 +187,7 @@ Entity::hasComponent(
const std::string& typeName
) {
return this->hasComponent(
ComponentFactory::instance().typeNameToId(typeName)
ComponentRegistry::instance().typeNameToId(typeName)
);
}

@@ -208,6 +208,6 @@ Entity::removeComponent(
const std::string& typeName
) {
this->removeComponent(
ComponentFactory::instance().typeNameToId(typeName)
ComponentRegistry::instance().typeNameToId(typeName)
);
}
15 changes: 12 additions & 3 deletions src/engine/entity_filter.cpp
Original file line number Diff line number Diff line change
@@ -120,8 +120,9 @@ struct EntityFilter<ComponentTypes...>::Implementation {
);
if (isComplete) {
m_entities[id] = group;
m_entities.insert(std::make_pair(id, group));
if (m_recordChanges) {
m_addedEntities.insert(id);
m_addedEntities[id] = group;
}
}
}
@@ -205,7 +206,7 @@ struct EntityFilter<ComponentTypes...>::Implementation {
m_registeredCallbacks.clear();
}

std::unordered_set<EntityId> m_addedEntities;
EntityMap m_addedEntities;

Engine* m_engine = nullptr;

@@ -231,7 +232,7 @@ EntityFilter<ComponentTypes...>::EntityFilter(


template<typename... ComponentTypes>
std::unordered_set<EntityId>&
typename EntityFilter<ComponentTypes...>::EntityMap&
EntityFilter<ComponentTypes...>::addedEntities() {
assert(m_impl->m_recordChanges && "Added entities are not recorded by this filter");
return m_impl->m_addedEntities;
@@ -245,6 +246,14 @@ EntityFilter<ComponentTypes...>::begin() const {
}


template<typename... ComponentTypes>
void
EntityFilter<ComponentTypes...>::clearChanges() {
m_impl->m_addedEntities.clear();
m_impl->m_removedEntities.clear();
}


template<typename... ComponentTypes>
typename EntityFilter<ComponentTypes...>::EntityMap::const_iterator
EntityFilter<ComponentTypes...>::end() const {
8 changes: 7 additions & 1 deletion src/engine/entity_filter.h
Original file line number Diff line number Diff line change
@@ -141,7 +141,7 @@ class EntityFilter {
* it.
*
*/
std::unordered_set<EntityId>&
EntityMap&
addedEntities();

/**
@@ -157,6 +157,12 @@ class EntityFilter {
typename EntityMap::const_iterator
begin() const;

/**
* @brief Clears the lists for added and removed entities
*/
void
clearChanges();

/**
* @brief Iterator
*
Loading

0 comments on commit e446c8f

Please sign in to comment.