WIP World changes

This commit is contained in:
2014-03-03 20:08:08 +01:00
parent 68f4be5822
commit 444be4f502
12 changed files with 249 additions and 52 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ struct Component;
#define REGISTER_COMPONENT(NAME, TYPE) \
static ComponentRegistrar<TYPE> registrar(NAME);
template<class T>
template <typename T>
class ComponentRegistrar
{
public:
+4
View File
@@ -90,6 +90,8 @@
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="Renderer.cpp" />
<ClCompile Include="Systems\CollisionSystem.cpp" />
<ClCompile Include="World.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Component.h" />
@@ -99,6 +101,8 @@
<ClInclude Include="logging.h" />
<ClInclude Include="glerror.h" />
<ClInclude Include="Renderer.h" />
<ClInclude Include="System.h" />
<ClInclude Include="Systems\CollisionSystem.h" />
<ClInclude Include="World.h" />
</ItemGroup>
<ItemGroup>
@@ -18,6 +18,8 @@
</Filter>
<Filter Include="Source Files\Renderer">
<UniqueIdentifier>{7abbf0e9-8bda-475e-bf00-a347f396b892}</UniqueIdentifier>
<Filter Include="Header Files\Systems">
<UniqueIdentifier>{aca68cba-a16a-4975-8ff3-4d56b88373a1}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Renderer">
<UniqueIdentifier>{091f6f01-79ab-4a49-9639-c7185e89c84e}</UniqueIdentifier>
@@ -32,6 +34,11 @@
</ClCompile>
<ClCompile Include="Renderer.cpp">
<Filter>Source Files\Renderer</Filter>
<ClCompile Include="World.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Systems\CollisionSystem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
@@ -56,6 +63,12 @@
<ClInclude Include="ComponentFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="System.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Systems\CollisionSystem.h">
<Filter>Header Files\Systems</Filter>
</ClInclude>
<ClInclude Include="Renderer.h">
<Filter>Header Files\Renderer</Filter>
</ClInclude>
+20
View File
@@ -0,0 +1,20 @@
#ifndef System_h__
#define System_h__
#include "Entity.h"
class World;
class System
{
public:
System(World* world) : m_World(world) { }
virtual ~System() { }
virtual void Update(double dt, EntityID entity, EntityID parent) = 0;
protected:
World* m_World;
};
#endif // System_h__
@@ -0,0 +1,16 @@
#include "CollisionSystem.h"
#include "World.h"
void Systems::Collision::Update(double dt, EntityID entity, EntityID parent)
{
if (parent != 0)
{
auto transform = m_World->GetComponent<Components::Transform>(entity, "Transform");
auto parentTransform = m_World->GetComponent<Components::Transform>(parent, "Transform");
transform->Position[0] += parentTransform->Position[0];
transform->Position[1] += parentTransform->Position[1];
transform->Position[2] += parentTransform->Position[2];
}
LOG_INFO("Updating entity %i with parent %i", entity, parent);
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef CollisionSystem_h__
#define CollisionSystem_h__
#include "System.h"
#include "logging.h"
#include "Components/Transform.h"
namespace Systems
{
class Collision : public System
{
public:
Collision(World* world) : System(world) { }
void Update(double dt, EntityID entity, EntityID parent) override;
};
}
#endif // CollisionSystem_h__
+87
View File
@@ -0,0 +1,87 @@
#include "World.h"
void World::RecycleEntityID(EntityID id)
{
m_RecycledEntityIDs.push(id);
}
EntityID World::GenerateEntityID()
{
if (!m_RecycledEntityIDs.empty()) {
EntityID id = m_RecycledEntityIDs.top();
m_RecycledEntityIDs.pop();
return id;
} else {
return ++m_LastEntityID;
}
}
void World::RecursiveUpdate(std::shared_ptr<System> system, double dt, EntityID parentEntity)
{
for (auto pair : m_EntityParents) {
EntityID child = pair.first;
EntityID parent = pair.second;
if (parent == parentEntity) {
system->Update(dt, child, parent);
RecursiveUpdate(system, dt, child);
}
}
}
void World::Update(double dt)
{
for (auto system : m_Systems) {
RecursiveUpdate(system, dt, 0);
}
}
void World::AddSystem(System* system)
{
}
//std::vector<EntityID> GetEntityChildren(EntityID entity);
//{
// std::vector<EntityID> children;
// auto range = m_SceneGraph.equal_range(entity);
// for (auto it = range.first; it != range.second; ++it)
// children.push_back(it->second);
// return children;
//}
EntityID World::GetEntityParent(EntityID entity)
{
auto it = m_EntityParents.find(entity);
return it == m_EntityParents.end() ? 0 : it->second;
}
bool World::ValidEntity(EntityID entity)
{
return m_EntityParents.find(entity) != m_EntityParents.end();
}
void World::RemoveEntity(EntityID entity)
{
m_EntityParents.erase(entity);
RecycleEntityID(entity);
}
EntityID World::CreateEntity(EntityID parent /*= 0*/)
{
EntityID newEntity = GenerateEntityID();
m_EntityParents.insert(std::pair<EntityID, EntityID>(newEntity, parent));
return newEntity;
}
World::~World()
{
}
World::World()
{
m_LastEntityID = 0;
m_Systems.push_back(std::make_shared<Systems::Collision>(this));
}
+31 -50
View File
@@ -9,79 +9,60 @@
#include "Entity.h"
#include "Component.h"
#include "ComponentFactory.h"
//#include "Components/Transform.h"
#include "System.h"
#include "Systems/CollisionSystem.h"
class World
{
public:
World()
{
m_LastEntityID = 0;
}
World();
~World();
EntityID CreateEntity(EntityID parent = 0)
{
EntityID newEntity = GenerateEntityID();
m_SceneGraph.insert(std::pair<EntityID, EntityID>(newEntity, parent));
return newEntity;
}
EntityID CreateEntity(EntityID parent = 0);
void RemoveEntity(EntityID entity)
{
m_SceneGraph.erase(entity);
RecycleEntityID(entity);
}
void RemoveEntity(EntityID entity);
bool ValidEntity(EntityID entity)
{
return m_SceneGraph.find(entity) != m_SceneGraph.end();
}
bool ValidEntity(EntityID entity);
EntityID GetEntityParent(EntityID entity)
{
auto it = m_SceneGraph.find(entity);
return it == m_SceneGraph.end() ? 0 : it->second;
}
EntityID GetEntityParent(EntityID entity);
std::shared_ptr<Component> AddComponent(EntityID entity, std::string componentType)
template <class T>
std::shared_ptr<T> AddComponent(EntityID entity, std::string componentType)
{
std::shared_ptr<Component> component = ComponentFactory::Instance()->Create(componentType);
std::shared_ptr<T> component = std::static_pointer_cast<T>(ComponentFactory::Instance()->Create(componentType));
m_ComponentsOfType[componentType].push_back(component);
m_EntityComponents[entity][componentType] = component;
return component;
}
/*std::vector<EntityID> GetEntityChildren(EntityID entity)
template <class T>
std::shared_ptr<T> GetComponent(EntityID entity, std::string componentType)
{
std::vector<EntityID> children;
auto range = m_SceneGraph.equal_range(entity);
for (auto it = range.first; it != range.second; ++it)
children.push_back(it->second);
return children;
}*/
return std::static_pointer_cast<T>(m_EntityComponents[entity][componentType]);
}
/*std::vector<EntityID> GetEntityChildren(EntityID entity);*/
void AddSystem(System* system);
// Recursively update through the scene graph
void Update(double dt);
void RecursiveUpdate(std::shared_ptr<System> system, double dt, EntityID parentEntity);
private:
EntityID m_LastEntityID;
std::stack<EntityID> m_RecycledEntityIDs;
// A map of child entities to parent entities
std::unordered_map<EntityID, EntityID> m_SceneGraph;
// A bottom to top tree. A map of child entities to parent entities.
std::unordered_map<EntityID, EntityID> m_EntityParents;
std::unordered_map<std::string, std::vector<std::shared_ptr<Component>>> m_ComponentsOfType;
std::unordered_map<EntityID, std::map<std::string, std::shared_ptr<Component>>> m_EntityComponents;
std::vector<std::shared_ptr<System>> m_Systems;
EntityID GenerateEntityID()
{
if (!m_RecycledEntityIDs.empty()) {
EntityID id = m_RecycledEntityIDs.top();
m_RecycledEntityIDs.pop();
return id;
} else {
return ++m_LastEntityID;
}
}
EntityID GenerateEntityID();
void RecycleEntityID(EntityID id)
{
m_RecycledEntityIDs.push(id);
}
void RecycleEntityID(EntityID id);
};
#endif // World_h__
+1 -1
View File
@@ -49,7 +49,7 @@ static void _LOG(_LOG_LEVEL logLevel, char* file, char* func, unsigned int line,
char message[512];
va_list args;
va_start(args, format);
vsnprintf(message, 512, format, args);
vsnprintf_s(message, 512, format, args);
va_end(args);
if (logLevel == LOG_LEVEL_ERROR)
+22
View File
@@ -9,12 +9,34 @@
#include "logging.h"
#include "glerror.h"
#include "World.h"
GLFWwindow* window;
GLint glVersion[2];
GLchar* glVendor;
int main(int argc, char* argv[])
{
World world;
EntityID ent1 = world.CreateEntity();
auto t1 = world.AddComponent<Components::Transform>(ent1, "Transform");
t1->Position[0] = 1.0f;
t1->Position[1] = 1.0f;
t1->Position[2] = 1.0f;
EntityID ent2 = world.CreateEntity(ent1);
auto t2 = world.AddComponent<Components::Transform>(ent2, "Transform");
t2->Position[0] = 1.0f;
t2->Position[1] = 1.0f;
t2->Position[2] = 1.0f;
world.Update(0.0);
LOG_INFO("ent1: %f %f %f", t1->Position[0], t1->Position[1], t1->Position[2]);
LOG_INFO("ent2: %f %f %f", t2->Position[0], t2->Position[1], t2->Position[2]);
return 0;
// Initialize GLFW
if (!glfwInit())
{
+10
View File
@@ -80,6 +80,16 @@
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Escape-the-Dawn\Escape-the-Dawn.vcxproj">
<Project>{fe405cfa-8fce-4867-92cf-797e73b36482}</Project>
<Private>true</Private>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
+21
View File
@@ -20,6 +20,27 @@ BOOST_AUTO_TEST_CASE(Parenting)
BOOST_CHECK(world.GetEntityParent(ent2) == ent1);
}
BOOST_AUTO_TEST_CASE(SceneGraphTraversal)
{
World world;
EntityID ent1 = world.CreateEntity();
auto t1 = world.AddComponent<Components::Transform>(ent1, "Transform");
t1->Position[0] = 1.0f;
t1->Position[1] = 1.0f;
t1->Position[2] = 1.0f;
EntityID ent2 = world.CreateEntity(ent1);
auto t2 = world.AddComponent<Components::Transform>(ent2, "Transform");
t2->Position[0] = 1.0f;
t2->Position[1] = 1.0f;
t2->Position[2] = 1.0f;
world.Update(0.0);
LOG_INFO("ent1: %f %f %f", t1->Position[0], t1->Position[1], t1->Position[2]);
LOG_INFO("ent2: %f %f %f", t2->Position[0], t2->Position[1], t2->Position[2]);
}
BOOST_AUTO_TEST_CASE(Recycling)
{
World world;