Merge remote-tracking branch 'origin/master' into RendererDecoupling

# Conflicts:
#	src/Game/Game.cpp
This commit is contained in:
Tleety
2015-12-14 13:16:56 +01:00
16 changed files with 260 additions and 130 deletions
+67 -67
View File
@@ -17,119 +17,119 @@ class EventBroker;
class BaseEventRelay
{
friend class EventBroker;
friend class EventBroker;
protected:
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName)
, m_Broker(nullptr)
{ }
~BaseEventRelay();
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName)
, m_Broker(nullptr)
{ }
~BaseEventRelay();
public:
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
protected:
std::string m_ContextTypeName;
std::string m_EventTypeName;
EventBroker* m_Broker;
std::string m_ContextTypeName;
std::string m_EventTypeName;
EventBroker* m_Broker;
};
template <typename ContextType, typename EventType>
class EventRelay : public BaseEventRelay
{
public:
typedef std::function<bool(const EventType&)> CallbackType;
typedef std::function<bool(const EventType&)> CallbackType;
EventRelay()
: m_Callback(nullptr)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay(CallbackType callback)
: m_Callback(callback)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay()
: m_Callback(nullptr)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay(CallbackType callback)
: m_Callback(callback)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
protected:
bool Receive(const std::shared_ptr<Event> event) override;
bool Receive(const std::shared_ptr<Event> event) override;
private:
CallbackType m_Callback;
CallbackType m_Callback;
};
template <typename ContextType, typename EventType>
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
{
if (m_Callback != nullptr) {
return m_Callback(*static_cast<const EventType*>(event.get()));
} else {
return false;
}
if (m_Callback != nullptr) {
return m_Callback(*static_cast<const EventType*>(event.get()));
} else {
return false;
}
}
class EventBroker
{
template <typename ContextType, typename EventType> friend class EventRelay;
template <typename ContextType, typename EventType> friend class EventRelay;
public:
EventBroker()
{
m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>();
}
EventBroker()
{
m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>();
}
void Subscribe(BaseEventRelay &relay);
template <typename EventType>
void Publish(const EventType &event);
/*
Process all events in a given context.
Returns: Number of events processed
*/
template <typename ContextType>
int Process();
int Process(std::string contextTypeName);
void Swap();
void Clear();
void Unsubscribe(BaseEventRelay &relay);
void Subscribe(BaseEventRelay &relay);
template <typename EventType>
void Publish(const EventType &event);
/*
Process all events in a given context.
Returns: Number of events processed
*/
template <typename ContextType>
int Process();
int Process(std::string contextTypeName);
void Swap();
void Clear();
void Unsubscribe(BaseEventRelay &relay);
private:
bool m_IsProcessing = false;
bool m_IsProcessing = false;
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
typedef std::string EventTypeName_t; // typeid(EventType).name()
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
typedef std::string EventTypeName_t; // typeid(EventType).name()
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
ContextRelays_t m_ContextRelays;
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
ContextRelays_t m_ContextRelays;
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
std::shared_ptr<EventQueue_t> m_EventQueueRead;
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
std::shared_ptr<EventQueue_t> m_EventQueueRead;
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
void subscribeImmediate(BaseEventRelay& relay);
void unsubscribeImmediate(BaseEventRelay& relay);
void subscribeImmediate(BaseEventRelay& relay);
void unsubscribeImmediate(BaseEventRelay& relay);
};
template <typename EventType>
void EventBroker::Publish(const EventType &event)
{
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
for (auto it = itpair.first; it != itpair.second; ++it)
{
it->second->Receive(event);
}*/
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
for (auto it = itpair.first; it != itpair.second; ++it)
{
it->second->Receive(event);
}*/
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
}
template <typename ContextType>
int EventBroker::Process()
{
const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName);
const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName);
}
#endif
+3 -3
View File
@@ -10,16 +10,16 @@ class System
friend class SystemPipeline;
public:
System(const EventBroker* eventBroker, std::string componentType)
System(EventBroker* eventBroker, std::string componentType)
: m_EventBroker(eventBroker)
, m_ComponentType(componentType)
{ }
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
private:
const EventBroker* m_EventBroker;
protected:
std::string m_ComponentType;
EventBroker* m_EventBroker;
};
#endif
+2 -2
View File
@@ -9,7 +9,7 @@
class SystemPipeline
{
public:
SystemPipeline(const EventBroker* eventBroker)
SystemPipeline(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
~SystemPipeline()
@@ -51,7 +51,7 @@ public:
}
private:
const EventBroker* m_EventBroker;
EventBroker* m_EventBroker;
std::unordered_map<std::string, std::vector<System*>> m_Systems;
};
+1
View File
@@ -13,6 +13,7 @@
#include "Core/EntityXMLFile.h"
#include "Core/SystemPipeline.h"
#include "RaptorCopterSystem.h"
#include "PlayerSystem.h"
class Game
{
+44
View File
@@ -0,0 +1,44 @@
#ifndef PlayerSystem_h__
#define PlayerSystem_h__
#include <GLFW/glfw3.h>
#include <glm/common.hpp>
#include "Common.h"
#include "Core/System.h"
#include "Core/EventBroker.h"
#include "Core/EKeyDown.h"
#include "Core/EKeyUp.h"
struct KeyInput
{
bool Forward = false;
bool Left = false;
bool Back = false;
bool Right = false;
};
class PlayerSystem : public System
{
public:
PlayerSystem(EventBroker* eventBroker)
: System(eventBroker, "Player")
{
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp);
}
virtual void Update(World* world, ComponentWrapper& player, double dt) override;
private:
float m_Speed = 5;
glm::vec3 m_Direction;
KeyInput input;
EventRelay<PlayerSystem, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown &event);
EventRelay<PlayerSystem, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp &event);
};
#endif
+3 -1
View File
@@ -4,10 +4,12 @@
class RaptorCopterSystem : public System
{
public:
RaptorCopterSystem(const EventBroker* eventBroker)
RaptorCopterSystem(EventBroker* eventBroker)
: System(eventBroker, "RaptorCopter")
{ }
virtual void Initialize() { }
virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override
{
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
+2 -1
View File
@@ -6,4 +6,5 @@ LoadMap=
Fullscreen=false
VSYNC=false
Width=1280
Height=720
Height=720
FOV=45
+1
View File
@@ -5,4 +5,5 @@
<xs:include schemaLocation="Components/Model.xsd"/>
<xs:include schemaLocation="Components/Test.xsd"/>
<xs:include schemaLocation="Components/RaptorCopter.xsd"/>
<xs:include schemaLocation="Components/Player.xsd"/>
</xs:schema>
+3
View File
@@ -0,0 +1,3 @@
<c:Player>
<Velocity X="0" Y="0" Z="0"/>
</c:Player>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="Player">
<xs:complexType>
<xs:all>
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+18 -17
View File
@@ -31,6 +31,19 @@
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Player>
<Velocity X="0" Y="0" Z="0"/>
</c:Player>
<c:Transform>
<Position X="2.5"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
@@ -48,7 +61,7 @@
<Components>
<c:Transform>
<Position X="0" Y="0"/>
<Orientation X="0.0" Y="0" Z="0.0"/>
<Orientation X="0.0" Y="0" Z="1.0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitRaptor.obj</Resource>
@@ -59,8 +72,8 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0"/>
<Orientation X="0" Y="0" Z="0"/>
<Position X="-0.01" Y="0.55"/>
<Orientation X="0" Y="0" Z="-1"/>
</c:Transform>
<c:RaptorCopter>
<Speed>20</Speed>
@@ -71,19 +84,7 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.4"/>
<Scale X="0.1" Y="0.4" Z="0.1"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCylinder.obj</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.6"/>
<Position X="0" Y="0"/>
<Scale X="1.7" Y="0.03" Z="0.1"/>
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
@@ -96,7 +97,7 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.6"/>
<Position X="0" Y="0"/>
<Scale X="1.7" Y="0.03" Z="0.1"/>
<Orientation X="0" Y="1.57" Z="0"/>
</c:Transform>
+1
View File
@@ -14,6 +14,7 @@
<xs:element ref="c:Model" minOccurs="0"/>
<xs:element ref="c:Test" minOccurs="0"/>
<xs:element ref="c:RaptorCopter" minOccurs="0"/>
<xs:element ref="c:Player" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
+1 -1
View File
@@ -30,7 +30,7 @@ glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity)
do {
ComponentWrapper transform = world->GetComponent(entity, "Transform");
position += AbsoluteOrientation(world, entity) * (glm::vec3)transform["Position"];
position += (glm::vec3)transform["Position"];
entity = world->GetParent(entity);
} while (entity != 0);
+1
View File
@@ -19,6 +19,7 @@ file(GLOB SOURCE_FILES
set(SOURCE_FILES
${SOURCE_FILES}
"Game.cpp"
"PlayerSystem.cpp"
)
set(LIBRARIES
+42 -38
View File
@@ -2,39 +2,40 @@
Game::Game(int argc, char* argv[])
{
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<Model>("Model");
ResourceManager::RegisterType<Texture>("Texture");
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<Model>("Model");
ResourceManager::RegisterType<Texture>("Texture");
ResourceManager::RegisterType<EntityXMLFile>("EntityXMLFile");
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
// Create the core event broker
m_EventBroker = new EventBroker();
// Create the core event broker
m_EventBroker = new EventBroker();
m_RenderQueueFactory = new RenderQueueFactory();
// Create the renderer
m_Renderer = new Renderer(m_EventBroker);
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
m_Renderer->SetResolution(Rectangle(
0,
0,
m_Config->Get<int>("Video.Width", 1280),
m_Config->Get<int>("Video.Height", 720)
));
m_Renderer->Initialize();
// Create the renderer
m_Renderer = new Renderer(m_EventBroker);
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
m_Renderer->SetResolution(Rectangle(
0,
0,
m_Config->Get<int>("Video.Width", 1280),
m_Config->Get<int>("Video.Height", 720)
));
m_Renderer->Initialize();
m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get<float>("Video.FOV", 90.f)));
// Create input manager
m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker);
// Create input manager
m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker);
// Create the root level GUI frame
m_FrameStack = new GUI::Frame(m_EventBroker);
m_FrameStack->Width = m_Renderer->Resolution().Width;
m_FrameStack->Height = m_Renderer->Resolution().Height;
// Create the root level GUI frame
m_FrameStack = new GUI::Frame(m_EventBroker);
m_FrameStack->Width = m_Renderer->Resolution().Width;
m_FrameStack->Height = m_Renderer->Resolution().Height;
// Create a world
m_World = new World();
@@ -42,31 +43,34 @@ Game::Game(int argc, char* argv[])
if (!mapToLoad.empty()) {
ResourceManager::Load<EntityXMLFile>(mapToLoad)->PopulateWorld(m_World);
}
// Create system pipeline
m_SystemPipeline = new SystemPipeline(m_EventBroker);
m_SystemPipeline->AddSystem<RaptorCopterSystem>();
m_SystemPipeline->AddSystem<PlayerSystem>();
m_LastTime = glfwGetTime();
m_LastTime = glfwGetTime();
testIntialize();
}
Game::~Game()
{
delete m_FrameStack;
delete m_EventBroker;
delete m_FrameStack;
delete m_EventBroker;
}
void Game::Tick()
{
double currentTime = glfwGetTime();
double dt = currentTime - m_LastTime;
m_LastTime = currentTime;
double currentTime = glfwGetTime();
double dt = currentTime - m_LastTime;
m_LastTime = currentTime;
m_EventBroker->Swap();
m_InputManager->Update(dt);
m_EventBroker->Swap();
m_EventBroker->Swap();
m_InputManager->Update(dt);
m_EventBroker->Swap();
// Iterate through systems and update world!
m_SystemPipeline->Update(m_World, dt);
@@ -75,12 +79,12 @@ void Game::Tick()
m_RenderQueueFactory->Update(m_World);
GLERROR("Game::Tick m_RenderQueueFactory->Update");
m_Renderer->Draw(m_RenderQueueFactory->RenderQueues());
m_Renderer->Draw(m_RenderQueueFactory->RenderQueues());
GLERROR("Game::Tick m_Renderer->Draw");
m_EventBroker->Swap();
m_EventBroker->Clear();
m_EventBroker->Swap();
m_EventBroker->Clear();
glfwPollEvents();
glfwPollEvents();
}
+58
View File
@@ -0,0 +1,58 @@
#include "PlayerSystem.h"
void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt)
{
if (input.Forward) {
m_Direction.z = -1;
} else if (input.Back) {
m_Direction.z = 1;
} else {
m_Direction.z = 0;
}
if (input.Left) {
m_Direction.x = -1;
} else if (input.Right) {
m_Direction.x = 1;
} else {
m_Direction.x = 0;
}
m_EventBroker->Process<PlayerSystem>();
ComponentWrapper& transform = world->GetComponent(player.EntityID, "Transform");
(glm::vec3&)player["Velocity"] = m_Speed * float(dt) * m_Direction;
(glm::vec3&)transform["Position"] += (glm::vec3)player["Velocity"];
}
bool PlayerSystem::OnKeyDown(const Events::KeyDown & event)
{
if (event.KeyCode == GLFW_KEY_W) {
input.Forward = true;
}
if (event.KeyCode == GLFW_KEY_A) {
input.Left = true;
}
if (event.KeyCode == GLFW_KEY_S) {
input.Back = true;
}
if (event.KeyCode == GLFW_KEY_D) {
input.Right = true;
}
return true;
}
bool PlayerSystem::OnKeyUp(const Events::KeyUp & event)
{
if (event.KeyCode == GLFW_KEY_W) {
input.Forward = false;
}
if (event.KeyCode == GLFW_KEY_A) {
input.Left = false;
}
if (event.KeyCode == GLFW_KEY_S) {
input.Back = false;
}
if (event.KeyCode == GLFW_KEY_D) {
input.Right = false;
}
return false;
}