Merge remote-tracking branch 'origin/master' into AndersTest
# Conflicts: # include/Engine/Core/InputController.h # include/Game/Game.h
This commit is contained in:
@@ -54,6 +54,8 @@ public:
|
||||
ComponentWrapper Allocate(EntityID entity);
|
||||
// Get the component belonging to a specific entity
|
||||
ComponentWrapper GetByEntity(EntityID ent);
|
||||
// Returns true if the pool contains a component for the specified entity
|
||||
bool KnowsEntity(EntityID ent);
|
||||
// Delete a component and free its memory
|
||||
void Delete(ComponentWrapper& wrapper);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/ini_parser.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../Common.h"
|
||||
#include "ResourceManager.h"
|
||||
@@ -19,12 +20,14 @@ private:
|
||||
public:
|
||||
template <typename T>
|
||||
T Get(std::string key, T defaultValue);
|
||||
template <typename T>
|
||||
std::vector<std::pair<std::string, T>> GetAll(std::string key);
|
||||
template <typename T>
|
||||
void Set(std::string key, T value);
|
||||
|
||||
void SaveToDisk();
|
||||
|
||||
private:
|
||||
private:
|
||||
boost::filesystem::path m_Path;
|
||||
boost::property_tree::ptree m_PTreeDefaults;
|
||||
boost::property_tree::ptree m_PTreeOverrides;
|
||||
@@ -37,6 +40,21 @@ T ConfigFile::Get(std::string key, T defaultValue)
|
||||
return m_PTreeMerged.get<T>(key, defaultValue);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<std::pair<std::string, T>> ConfigFile::GetAll(std::string key)
|
||||
{
|
||||
std::vector<std::pair<std::string, T>> out;
|
||||
auto parent = m_PTreeMerged.find(key);
|
||||
if (parent == m_PTreeMerged.not_found()) {
|
||||
return out;
|
||||
}
|
||||
for (auto& child : parent->second) {
|
||||
T value = boost::lexical_cast<T>(child.second.data());
|
||||
out.push_back(std::make_pair(child.first, value));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ConfigFile::Set(std::string key, T value)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef Events_KeyboardChar_h__
|
||||
#define Events_KeyboardChar_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
struct KeyboardChar : Event
|
||||
{
|
||||
double Timestamp = 0.f;
|
||||
unsigned int Char = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef Events_MouseScroll_h__
|
||||
#define Events_MouseScroll_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
struct MouseScroll : Event
|
||||
{
|
||||
double DeltaX;
|
||||
double DeltaY;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
|
||||
@@ -11,26 +11,23 @@ template <typename EventContext>
|
||||
class InputController
|
||||
{
|
||||
public:
|
||||
InputController(std::shared_ptr<dd::EventBroker> eventBroker)
|
||||
: EventBroker(eventBroker)
|
||||
InputController(EventBroker* eventBroker)
|
||||
: m_EventBroker(eventBroker)
|
||||
{ Initialize(); }
|
||||
|
||||
virtual void Initialize()
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(
|
||||
_EInputCommand, &InputController::OnCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &InputController::OnMouseMove);
|
||||
}
|
||||
|
||||
virtual bool OnCommand(const Events::InputCommand &event) { return false; }
|
||||
virtual bool OnMouseMove(const Events::MouseMove &event) { return false; }
|
||||
virtual bool OnCommand(const Events::InputCommand& e) { return false; }
|
||||
|
||||
protected:
|
||||
std::shared_ptr<dd::EventBroker> EventBroker;
|
||||
EventBroker* m_EventBroker;
|
||||
|
||||
private:
|
||||
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
|
||||
EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
#include "EventBroker.h"
|
||||
#include "EKeyDown.h"
|
||||
#include "EKeyUp.h"
|
||||
#include "EKeyboardChar.h"
|
||||
#include "EMousePress.h"
|
||||
#include "EMouseRelease.h"
|
||||
#include "EMouseMove.h"
|
||||
#include "EMouseScroll.h"
|
||||
#include "ELockMouse.h"
|
||||
#include "EGamepadAxis.h"
|
||||
#include "EGamepadButton.h"
|
||||
@@ -64,6 +66,11 @@ private:
|
||||
|
||||
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
|
||||
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
|
||||
|
||||
static std::vector<unsigned int> GLFWCharCallbackQueue;
|
||||
static void GLFWCharCallback(GLFWwindow* window, unsigned int c);
|
||||
static std::vector<std::pair<double, double>> GLFWScrollCallbackQueue;
|
||||
static void GLFWScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,20 +6,40 @@
|
||||
#include "ComponentWrapper.h"
|
||||
|
||||
class System
|
||||
{
|
||||
protected:
|
||||
System(EventBroker* eventBroker)
|
||||
: m_EventBroker(eventBroker)
|
||||
{ }
|
||||
|
||||
EventBroker* m_EventBroker;
|
||||
};
|
||||
|
||||
class PureSystem : public System
|
||||
{
|
||||
friend class SystemPipeline;
|
||||
|
||||
public:
|
||||
System(const EventBroker* eventBroker, std::string componentType)
|
||||
: m_EventBroker(eventBroker)
|
||||
protected:
|
||||
PureSystem(EventBroker* eventBroker, std::string componentType)
|
||||
: System(eventBroker)
|
||||
, m_ComponentType(componentType)
|
||||
{ }
|
||||
|
||||
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
|
||||
const std::string m_ComponentType;
|
||||
|
||||
private:
|
||||
const EventBroker* m_EventBroker;
|
||||
std::string m_ComponentType;
|
||||
virtual void UpdateComponent(World* world, ComponentWrapper& component, double dt) = 0;
|
||||
};
|
||||
|
||||
class ImpureSystem : public System
|
||||
{
|
||||
friend class SystemPipeline;
|
||||
|
||||
protected:
|
||||
ImpureSystem(EventBroker* eventBroker)
|
||||
: System(eventBroker)
|
||||
{ }
|
||||
|
||||
virtual void Update(World* world, double dt) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -9,12 +9,12 @@
|
||||
class SystemPipeline
|
||||
{
|
||||
public:
|
||||
SystemPipeline(const EventBroker* eventBroker)
|
||||
SystemPipeline(EventBroker* eventBroker)
|
||||
: m_EventBroker(eventBroker)
|
||||
{ }
|
||||
~SystemPipeline()
|
||||
{
|
||||
for (auto& pair : m_Systems) {
|
||||
for (auto& pair : m_PureSystems) {
|
||||
for (auto& system : pair.second) {
|
||||
delete system;
|
||||
}
|
||||
@@ -25,17 +25,32 @@ public:
|
||||
void AddSystem(Arguments... args)
|
||||
{
|
||||
System* system = new T(m_EventBroker, args...);
|
||||
if (!system->m_ComponentType.empty()) {
|
||||
m_Systems[system->m_ComponentType].push_back(system);
|
||||
} else {
|
||||
LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name());
|
||||
delete system;
|
||||
m_Systems[typeid(T).name()] = system;
|
||||
|
||||
if (std::is_base_of<PureSystem, T>::value) {
|
||||
PureSystem* pureSystem = static_cast<PureSystem*>(system);
|
||||
if (!pureSystem->m_ComponentType.empty()) {
|
||||
m_PureSystems[pureSystem->m_ComponentType].push_back(pureSystem);
|
||||
} else {
|
||||
LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name());
|
||||
}
|
||||
}
|
||||
|
||||
if (std::is_base_of<ImpureSystem, T>::value) {
|
||||
ImpureSystem* impureSystem = static_cast<ImpureSystem*>(system);
|
||||
m_ImpureSystems.push_back(impureSystem);
|
||||
}
|
||||
}
|
||||
|
||||
void Update(World* world, double dt)
|
||||
{
|
||||
// Process events
|
||||
for (auto& pair : m_Systems) {
|
||||
m_EventBroker->Process(pair.first);
|
||||
}
|
||||
|
||||
// Update
|
||||
for (auto& pair : m_PureSystems) {
|
||||
const std::string& componentName = pair.first;
|
||||
auto& systems = pair.second;
|
||||
const ComponentPool* pool = world->GetComponents(componentName);
|
||||
@@ -44,15 +59,20 @@ public:
|
||||
}
|
||||
for (auto& component : *pool) {
|
||||
for (auto& system : systems) {
|
||||
system->Update(world, component, dt);
|
||||
system->UpdateComponent(world, component, dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& system : m_ImpureSystems) {
|
||||
system->Update(world, dt);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const EventBroker* m_EventBroker;
|
||||
std::unordered_map<std::string, std::vector<System*>> m_Systems;
|
||||
EventBroker* m_EventBroker;
|
||||
std::map<std::string, System*> m_Systems;
|
||||
std::map<std::string, std::vector<PureSystem*>> m_PureSystems;
|
||||
std::vector<ImpureSystem*> m_ImpureSystems;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -14,17 +14,27 @@ public:
|
||||
|
||||
// Create empty entity
|
||||
EntityID CreateEntity(EntityID parent = 0);
|
||||
// Delete entity and all components within
|
||||
void DeleteEntity(EntityID entity);
|
||||
|
||||
// Register a component type and allocate space for it
|
||||
void RegisterComponent(ComponentInfo& ci);
|
||||
// Attach a component to an entity and fill it with default values
|
||||
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
|
||||
// Check if an entity has a component
|
||||
bool HasComponent(EntityID entity, std::string componentType);
|
||||
// Get a component of an entity
|
||||
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
||||
// Delete a component off an entity
|
||||
void DeleteComponent(EntityID entity, std::string componentType);
|
||||
// Get all components of the specified type
|
||||
const ComponentPool* GetComponents(std::string componentType);
|
||||
// Get entity parent
|
||||
EntityID GetParent(EntityID entity);
|
||||
// Get all component pools
|
||||
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
|
||||
// Get the entity children map
|
||||
const std::unordered_multimap<EntityID, EntityID>& GetEntityChildren() const { return m_EntityChildren; }
|
||||
|
||||
private:
|
||||
EntityID m_CurrentEntityID = 1;
|
||||
|
||||
Reference in New Issue
Block a user