146 lines
5.0 KiB
C++
146 lines
5.0 KiB
C++
#pragma once
|
|
|
|
#include <state/gamestate.hpp>
|
|
#include <object/entity.hpp>
|
|
#include <utils.hpp>
|
|
#include <thread>
|
|
#include <mutex>
|
|
#include <chrono>
|
|
#include <functional>
|
|
#include <object/camera.hpp>
|
|
#include <game/input.hpp>
|
|
#include <unordered_map>
|
|
#include <memory>
|
|
#include <type_traits>
|
|
|
|
namespace Game {
|
|
using clock = std::chrono::steady_clock;
|
|
|
|
enum class GameStateEnum {
|
|
RUNNING,
|
|
PAUSED,
|
|
STOPPED
|
|
};
|
|
|
|
enum class SharedDataType {
|
|
STRING,
|
|
INT,
|
|
FLOAT,
|
|
BOOL
|
|
};
|
|
|
|
class GameManager {
|
|
public:
|
|
GameManager() { LOG("Created GameManager"); };
|
|
DISABLE_COPY_AND_MOVE(GameManager);
|
|
~GameManager() = default;
|
|
|
|
// Start the game logic slave thread, which will update the gamestate and entities; Run as jthread
|
|
void run(std::stop_token stopToken);
|
|
void setTargetUpdatesPerSecond(int target) { mTargetUpdatesPerSecond = target; }
|
|
int getTargetUpdatesPerSecond() { return mTargetUpdatesPerSecond; }
|
|
float getLastDelta() { return mLastDelta; }
|
|
|
|
template<typename T>
|
|
static void setSharedData(const std::string& key, T data);
|
|
template<typename T>
|
|
static T getSharedData(const std::string& key);
|
|
static void removeSharedData(const std::string& key, SharedDataType type);
|
|
|
|
static GameStateEnum getCurrentGameState() { return mCurrentGameState; }
|
|
static void setCurrentGameState(GameStateEnum newState) { mCurrentGameState = newState; }
|
|
|
|
template<typename T>
|
|
static bool instantiateEntity(std::unique_ptr<T> entity);
|
|
template<typename T>
|
|
static T* getEntityByName(const std::string& name);
|
|
template<typename T>
|
|
static void destroyEntity(T* entity);
|
|
|
|
private:
|
|
int mTargetUpdatesPerSecond = TARGET_UPDATE_RATE;
|
|
clock::time_point mLastUpdate;
|
|
static std::unordered_map<std::string, std::string> mSharedStrings;
|
|
static std::unordered_map<std::string, int> mSharedInts;
|
|
static std::unordered_map<std::string, float> mSharedFloats;
|
|
static std::unordered_map<std::string, bool> mSharedBools;
|
|
static GameStateEnum mCurrentGameState;
|
|
float mLastDelta = 0.f;
|
|
};
|
|
|
|
template<typename T>
|
|
void GameManager::setSharedData(const std::string& key, T data) {
|
|
if constexpr (std::is_same_v<T, std::string>) {
|
|
mSharedStrings[key] = data;
|
|
} else if constexpr (std::is_same_v<T, int>) {
|
|
mSharedInts[key] = data;
|
|
} else if constexpr (std::is_same_v<T, float>) {
|
|
mSharedFloats[key] = data;
|
|
} else if constexpr (std::is_same_v<T, bool>) {
|
|
mSharedBools[key] = data;
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
T GameManager::getSharedData(const std::string& key) {
|
|
if constexpr (std::is_same_v<T, std::string>) {
|
|
auto it = mSharedStrings.find(key);
|
|
if (it != mSharedStrings.end()) {
|
|
return it->second;
|
|
} else {
|
|
return "";
|
|
}
|
|
} else if constexpr (std::is_same_v<T, int>) {
|
|
auto it = mSharedInts.find(key);
|
|
if (it != mSharedInts.end()) {
|
|
return it->second;
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else if constexpr (std::is_same_v<T, float>) {
|
|
auto it = mSharedFloats.find(key);
|
|
if (it != mSharedFloats.end()) {
|
|
return it->second;
|
|
} else {
|
|
return 0.0f;
|
|
}
|
|
} else if constexpr (std::is_same_v<T, bool>) {
|
|
auto it = mSharedBools.find(key);
|
|
if (it != mSharedBools.end()) {
|
|
return it->second;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static_assert(
|
|
std::is_same_v<T, std::string> || std::is_same_v<T, int> ||
|
|
std::is_same_v<T, float> || std::is_same_v<T, bool>,
|
|
"Unsupported type for shared data"
|
|
);
|
|
|
|
return T{};
|
|
}
|
|
|
|
template<typename T>
|
|
bool GameManager::instantiateEntity(std::unique_ptr<T> entity) {
|
|
static_assert(std::is_base_of_v<Object::Entity, T>, "T must derive from Object::Entity");
|
|
State::GameState::getInstance().addEntity(std::move(entity));
|
|
return true;
|
|
}
|
|
|
|
template<typename T>
|
|
T* GameManager::getEntityByName(const std::string& name) {
|
|
static_assert(std::is_base_of_v<Object::Entity, T>, "T must derive from Object::Entity");
|
|
Object::Entity* entity = State::GameState::getInstance().getEntityByName(name);
|
|
return dynamic_cast<T*>(entity);
|
|
}
|
|
|
|
template<typename T>
|
|
void GameManager::destroyEntity(T* entity) {
|
|
static_assert(std::is_base_of_v<Object::Entity, T>, "T must derive from Object::Entity");
|
|
if (entity) {
|
|
State::GameState::getInstance().removeEntity(entity->getName());
|
|
}
|
|
}
|
|
} |