restructure project

This commit is contained in:
2023-08-13 11:59:13 +02:00
parent b4836847f5
commit 50c17e8ed1
210 changed files with 471 additions and 422 deletions

4465
include/td/misc/Backward.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
#include "DataBuffer.h"
namespace td {
namespace utils {
std::uint64_t Inflate(const std::string& source, std::string& dest);
std::uint64_t Deflate(const std::string& source, std::string& dest);
DataBuffer Compress(const DataBuffer& buffer);
DataBuffer Decompress(DataBuffer& buffer);
DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength);
} // namespace utils
} // namespace td

View File

@@ -0,0 +1,177 @@
#pragma once
#include <vector>
#include <algorithm>
#include <cstring>
#include <cassert>
#include <string>
namespace td {
class DataBuffer {
private:
typedef std::vector<std::uint8_t> Data;
Data m_Buffer;
std::size_t m_ReadOffset;
public:
typedef Data::iterator iterator;
typedef Data::const_iterator const_iterator;
typedef Data::reference reference;
typedef Data::const_reference const_reference;
DataBuffer();
DataBuffer(const DataBuffer& other);
DataBuffer(const DataBuffer& other, Data::difference_type offset);
DataBuffer(DataBuffer&& other);
DataBuffer(const std::string& str);
DataBuffer& operator=(const DataBuffer& other);
DataBuffer& operator=(DataBuffer&& other);
template <typename T>
void Append(T data) {
std::size_t size = sizeof(data);
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + size);
memcpy(&m_Buffer[end_pos], &data, size);
}
template <typename T>
DataBuffer& operator<<(T data) {
// Switch to big endian
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
Append(data);
return *this;
}
DataBuffer& operator<<(std::string str) {
m_Buffer.insert(m_Buffer.end(), str.begin(), str.end());
return *this;
}
DataBuffer& operator<<(DataBuffer& data) {
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
return *this;
}
DataBuffer& operator<<(const DataBuffer& data) {
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
return *this;
}
template <typename T>
DataBuffer& operator>>(T& data) {
assert(m_ReadOffset + sizeof(T) <= GetSize());
data = *(reinterpret_cast<T*>(&m_Buffer[m_ReadOffset]));
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
m_ReadOffset += sizeof(T);
return *this;
}
DataBuffer& operator>>(DataBuffer& data) {
data.Resize(GetSize() - m_ReadOffset);
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), m_Buffer.end(), data.begin());
m_ReadOffset = m_Buffer.size();
return *this;
}
DataBuffer& operator>>(std::string& str) {
std::size_t stringSize = strlen(reinterpret_cast<const char*>(m_Buffer.data()) + m_ReadOffset) + 1; // including null character
str.resize(stringSize);
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset),
m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset + stringSize), str.begin());
m_ReadOffset += stringSize;
return *this;
}
void WriteSome(const char* buffer, std::size_t amount) {
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + amount);
memcpy(m_Buffer.data() + end_pos, buffer, amount);
}
void WriteSome(const std::uint8_t* buffer, std::size_t amount) {
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + amount);
memcpy(m_Buffer.data() + end_pos, buffer, amount);
}
void ReadSome(char* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
m_ReadOffset += amount;
}
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
m_ReadOffset += amount;
}
void ReadSome(DataBuffer& buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
buffer.Resize(amount);
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
m_ReadOffset += amount;
}
void ReadSome(std::string& buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
buffer.resize(amount);
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
m_ReadOffset += amount;
}
void Resize(std::size_t size) {
m_Buffer.resize(size);
}
void Reserve(std::size_t amount) {
m_Buffer.reserve(amount);
}
void erase(iterator it) {
m_Buffer.erase(it);
}
void Clear() {
m_Buffer.clear();
m_ReadOffset = 0;
}
bool IsFinished() const {
return m_ReadOffset >= m_Buffer.size();
}
std::uint8_t* data() {
return m_Buffer.data();
}
const std::uint8_t* data() const {
return m_Buffer.data();
}
std::size_t GetReadOffset() const { return m_ReadOffset; }
void SetReadOffset(std::size_t pos);
std::string ToString() const;
std::size_t GetSize() const;
bool IsEmpty() const;
std::size_t GetRemaining() const;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
reference operator[](Data::size_type i) { return m_Buffer[i]; }
const_reference operator[](Data::size_type i) const { return m_Buffer[i]; }
bool ReadFile(const std::string& fileName);
bool WriteFile(const std::string& fileName);
};
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
} // ns td

69
include/td/misc/Easing.h Normal file
View File

@@ -0,0 +1,69 @@
#pragma once
namespace td {
namespace utils {
constexpr float PI = 3.14159274101257324219;
/* Sine functions */
float EaseInSine(float x);
float EaseOutSine(float x);
float EaseInOutSine(float x);
/* Cubic functions */
float EaseInCubic(float x);
float EaseOutCubic(float x);
float EaseInOutCubic(float x);
/* Quint functions */
float EaseInQuint(float x);
float EaseOutQuint(float x);
float EaseInOutQuint(float x);
/* Circ functions */
float EaseInCirc(float x);
float EaseOutCirc(float x);
float EaseInOutCirc(float x);
/* Elastic functions */
float EaseInElastic(float x);
float EaseOutElastic(float x);
float EaseInOutElastic(float x);
/* Quad functions */
float EaseInQuad(float x);
float EaseOutQuad(float x);
float EaseInOutQuad(float x);
/* Quart functions */
float EaseInQuart(float x);
float EaseOutQuart(float x);
float EaseInOutQuart(float x);
/* Expo functions */
float EaseInExpo(float x);
float EaseOutExpo(float x);
float EaseInOutExpo(float x);
/* Back functions */
float EaseInBack(float x);
float EaseOutBack(float x);
float EaseInOutBack(float x);
/* Bounce functions */
float EaseInBounce(float x);
float EaseOutBounce(float x);
float EaseInOutBounce(float x);
} // namespace utils
} // namespace td

23
include/td/misc/Format.h Normal file
View File

@@ -0,0 +1,23 @@
#pragma once
#include <string>
#include <memory>
#include <stdexcept>
namespace td {
namespace utils {
template <typename... Args>
std::string format(const std::string& format, Args... args) {
int size = snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
if (size <= 0) {
throw std::runtime_error("Error during formatting.");
}
std::unique_ptr<char[]> buf(new char[size]);
snprintf(buf.get(), static_cast<std::size_t>(size), format.c_str(), args...);
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
}
} // namespace utils
} // namespace td

13
include/td/misc/Log.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <string>
namespace td {
namespace utils {
void LOG(const std::string& msg);
void LOGD(const std::string& msg);
void LOGE(const std::string& err);
} // namespace utils
} // namespace td

177
include/td/misc/Maths.h Normal file
View File

@@ -0,0 +1,177 @@
#pragma once
#include "td/Defines.h"
#include <cmath>
namespace td {
//////////////////////////////////////////////////////////////////
// Operators //
//////////////////////////////////////////////////////////////////
template<typename T>
Vec2<T> operator+(const Vec2<T>& vect, const Vec2<T>& other) {
return {vect.x + other.x, vect.y + other.y};
}
template<typename T>
Vec2<T> operator- (const Vec2<T>& vect) {
return { -vect.x, -vect.y };
}
template<typename T>
Vec2<T> operator- (const Vec2<T>& vect, const Vec2<T>& other) {
return vect + (-other);
}
template<typename T>
Vec3<T> operator- (const Vec3<T>& vect) {
return { -vect.x, -vect.y, -vect.z };
}
template<typename T>
Vec3<T> operator+ (const Vec3<T>& vect, const Vec3<T>& other) {
return { vect.x + other.x, vect.y + other.y, vect.z + other.y };
}
template<typename T>
Vec3<T> operator- (const Vec3<T>& vect, const Vec3<T>& other) {
return vect + (-other);
}
template<typename T>
Vec4<T> operator- (const Vec4<T>& vect) {
return { -vect.x, -vect.y, -vect.z, -vect.w };
}
template<typename T>
Vec4<T> operator+ (const Vec4<T>& vect, const Vec4<T>& other) {
return { vect.x + other.x, vect.y + other.y, vect.z + other.y, vect.w + other.w };
}
template<typename T>
Vec4<T> operator- (const Vec4<T>& vect, const Vec4<T>& other) {
return vect + (-other);
}
//////////////////////////////////////////////////////////////////
// Vectors //
//////////////////////////////////////////////////////////////////
namespace maths {
template<typename T>
T Length(const Vec3<T>& vect) {
return std::sqrt(vect.x * vect.x + vect.y * vect.y + vect.z * vect.z);
}
template<typename T>
Vec3<T> Normalize(const Vec3<T>& vect) {
T length = Length(vect);
return { vect.x / length, vect.y / length, vect.z / length };
}
template<typename T>
Vec4<T> Normalize(const Vec4<T>& vect) {
T length = std::sqrt(vect.x * vect.x + vect.y * vect.y + vect.z * vect.z + vect.w * vect.w);
return { vect.x / length, vect.y / length, vect.z / length, vect.w / length };
}
template<typename T>
T Dot(const Vec3<T>& vect, const Vec3<T>& other) {
return vect.x * other.x + vect.y * other.y + vect.z * other.z;
}
template<typename T>
Vec3<T> Cross(const Vec3<T>& vect, const Vec3<T>& other) {
return {
vect.y * other.z - vect.z * other.y,
vect.z * other.x - vect.x * other.z,
vect.x * other.y - vect.y * other.x,
};
}
template<typename T>
T Dot(const Vec4<T>& vect, const Vec4<T>& other) {
return vect.x * other.x + vect.y * other.y + vect.z * other.z + vect.w * other.w;
}
template<typename T>
T Distance(const Vec3<T>& vect, const Vec3<T>& other) {
return Length(vect - other);
}
//////////////////////////////////////////////////////////////////
// Matricies //
//////////////////////////////////////////////////////////////////
template<typename T>
Vec4<T> Dot(const Mat4<T>& mat, const Vec4<T>& vect) {
return {
mat.x0 * vect.x + mat.x1 * vect.y + mat.x2 * vect.z + mat.x3 * vect.w,
mat.y0 * vect.x + mat.y1 * vect.y + mat.y2 * vect.z + mat.y3 * vect.w,
mat.z0 * vect.x + mat.z1 * vect.y + mat.z2 * vect.z + mat.z3 * vect.w,
mat.w0 * vect.x + mat.w1 * vect.y + mat.w2 * vect.z + mat.w3 * vect.w
};
}
template<typename T>
Mat4<T> Dot(const Mat4<T>& mat, const Mat4<T>& other) {
Mat4<T> result {};
for (std::size_t i = 0; i < Mat4<T>::MATRIX_SIZE; i++) {
for (std::size_t j = 0; j < Mat4<T>::MATRIX_SIZE; j++) {
for (std::size_t k = 0; k < Mat4<T>::MATRIX_SIZE; k++) {
result.at(i, j) += mat.at(i, k) * other.at(k, j);
}
}
}
return result;
}
template<typename T>
Mat4<T> Identity() {
Mat4<T> result{};
result.x0 = static_cast<T>(1);
result.y1 = static_cast<T>(1);
result.z2 = static_cast<T>(1);
result.w3 = static_cast<T>(1);
return result;
}
template<typename T>
Mat4<T> Transpose(const Mat4<T>& mat) {
Mat4<T> result;
result.x1 = mat.y0;
result.x2 = mat.z0;
result.x3 = mat.w0;
result.y0 = mat.x1;
result.y2 = mat.z1;
result.y3 = mat.w1;
result.z0 = mat.x2;
result.z1 = mat.y2;
result.z3 = mat.w2;
result.w0 = mat.x3;
result.w1 = mat.y3;
result.w2 = mat.z3;
result.x0 = mat.x0;
result.y1 = mat.y1;
result.z2 = mat.z2;
result.w3 = mat.w3;
return result;
}
Mat4f Perspective(float fovY, float aspectRatio, float zNear, float zFar);
Mat4f Look(const Vec3f& eye, const Vec3f& center, const Vec3f& up);
Mat4f Inverse(const Mat4f& mat);
} // namespace maths
} // namespace td

View File

@@ -0,0 +1,36 @@
#pragma once
#include <algorithm>
#include <functional>
#include <vector>
namespace td {
namespace utils {
template <typename Listener>
class ObjectNotifier {
protected:
std::vector<Listener*> m_Listeners;
public:
void BindListener(Listener* listener) {
m_Listeners.push_back(listener);
}
void UnbindListener(Listener* listener) {
auto iter = std::find(m_Listeners.begin(), m_Listeners.end(), listener);
if (iter == m_Listeners.end()) return;
m_Listeners.erase(iter);
}
template <typename Func, typename... Args>
void NotifyListeners(Func function, Args... args) {
for (Listener* listener : m_Listeners)
std::bind(function, listener, args...)();
}
};
} // namespace utils
} // namespace td

View File

@@ -0,0 +1,54 @@
#pragma once
namespace td {
namespace utils {
enum class Os {
Windows = 0,
Linux,
Android,
Unknown,
};
enum class Architecture {
x86_64 = 0,
x86,
Arm64,
Armhf,
Unknown,
};
inline Os GetSystemOs() {
#if defined(_WIN32) || defined(_WIN64)
return Os::Windows;
#elif defined(__ANDROID__)
return Os::Android;
#elif defined(__unix__)
return Os::Linux;
#else
#pragma message ("Target OS unknown or unsupported !")
return Os::Unknown;
#endif
}
inline Architecture GetSystemArchitecture() {
#if defined(_WIN64)
return Architecture::x86_64;
#elif defined(_WIN32)
return Architecture::x86;
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
return Architecture::x86_64;
#elif defined(_M_IX86) || defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
return Architecture::x86;
#elif defined(__aarch64__)
return Architecture::Arm64;
#elif defined(__arm__) || defined(_M_ARM)
return Architecture::Armhf;
#else
#pragma message ("Target CPU architecture unknown or unsupported !")
return Architecture::Unknown;
#endif
}
} // namespace utils
} // namespace td

25
include/td/misc/Random.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#include <random>
namespace td {
namespace utils {
template<typename NumberType>
NumberType GetRandomInt(NumberType min, NumberType max) {
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
std::uniform_int_distribution<NumberType> distrib(min, max);
return distrib(generator);
}
template<typename NumberType>
NumberType GetRandomReal(NumberType min, NumberType max) {
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
std::uniform_real_distribution<NumberType> distrib(min, max);
return distrib(generator);
}
} // namespace utils
} // namespace td

96
include/td/misc/Shapes.h Normal file
View File

@@ -0,0 +1,96 @@
#pragma once
#include <cstdint>
namespace td {
namespace utils {
namespace shape {
class Point {
private:
float m_X, m_Y;
public:
Point() : m_X(0), m_Y(0) {}
Point(float x, float y) : m_X(x), m_Y(y) {}
float GetX() const { return m_X; }
float GetY() const { return m_Y; }
void SetX(float x) { m_X = x; }
void SetY(float y) { m_Y = y; }
float Distance(const Point& point) const;
float DistanceSquared(const Point& point) const;
};
class Circle;
class Rectangle {
private:
Point m_Center;
float m_Width, m_Height;
public:
Rectangle() {}
const Point& GetCenter() const { return m_Center; }
float GetCenterX() const { return m_Center.GetX(); }
float GetCenterY() const { return m_Center.GetY(); }
float GetWidth() const { return m_Width; }
float GetHeight() const { return m_Height; }
Point GetTopLeft() const { return { m_Center.GetX() - (m_Width / 2.0f), m_Center.GetY() - (m_Height / 2.0f) }; }
Point GetBottomRight() const { return { m_Center.GetX() + (m_Width / 2.0f), m_Center.GetY() + (m_Height / 2.0f) }; }
void SetCenter(const Point& center) { m_Center = center; }
void SetCenterX(float x) { m_Center.SetX(x); }
void SetCenterY(float y) { m_Center.SetY(y); }
void SetSize(float width, float height) { SetWidth(width); SetHeight(height); }
void SetSize(Point size) { SetSize(size.GetX(), size.GetY()); }
Point GetSize() { return { m_Width, m_Height }; }
void SetWidth(float width) { m_Width = width; }
void SetHeight(float height) { m_Height = height; }
bool CollidesWith(const Point& point) const;
bool CollidesWith(const Rectangle& rect) const;
bool CollidesWith(const Circle& circle) const;
// distance from the closest side of the rectangle
float Distance(const Circle& circle) const;
float DistanceSquared(const Circle& circle) const;
};
class Circle {
private:
Point m_Center;
float m_Radius;
public:
Circle(float x, float y, float radius) : m_Center(x, y), m_Radius(radius) {}
Circle() : m_Radius(0) {}
const Point& GetCenter() const { return m_Center; }
float GetCenterX() const { return m_Center.GetX(); }
float GetCenterY() const { return m_Center.GetY(); }
float GetRadius() const { return m_Radius; }
void SetCenter(const Point& center) { m_Center = center; }
void SetCenterX(float x) { m_Center.SetX(x); }
void SetCenterY(float y) { m_Center.SetY(y); }
void SetRadius(float radius) { m_Radius = radius; }
bool CollidesWith(const Point& point) const;
bool CollidesWith(const Rectangle& rect) const;
bool CollidesWith(const Circle& circle) const;
// distance from the closest side of the rectangle
float Distance(const Rectangle& rect) const;
float DistanceSquared(const Rectangle& rect) const;
};
} // namespace shape
} // namespace utils
} // namespace td

76
include/td/misc/Time.h Normal file
View File

@@ -0,0 +1,76 @@
#pragma once
#include <cstdint>
#include <functional>
namespace td {
namespace utils {
std::uint64_t GetTime();
typedef std::function<void()> TimerExecFunction;
// utililty class to call function at regular period of time
class AutoTimer {
private:
std::uint64_t m_Interval;
TimerExecFunction m_Function;
std::uint64_t m_LastTime = GetTime();
std::uint64_t m_InternalTime = 0;
public:
AutoTimer() : m_Interval(0), m_Function(nullptr) {}
AutoTimer(std::uint64_t interval) : m_Interval(interval), m_Function(nullptr) {}
AutoTimer(std::uint64_t interval, TimerExecFunction callback) : m_Interval(interval), m_Function(callback) {}
void Update();
void Update(std::uint64_t delta);
void Reset();
void SetInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
std::uint64_t GetInterval() const { return m_Interval; }
void SetCallbackFunction(TimerExecFunction newCallback) { m_Function = newCallback; }
TimerExecFunction GetCallbackFunction() const { return m_Function; }
};
// utililty class to call function at regular period of time
class Timer {
private:
std::uint64_t m_Interval; // in millis
std::uint64_t m_InternalTime = 0;
public:
Timer() : m_Interval(0) {}
Timer(std::uint64_t interval) : m_Interval(interval) {}
bool Update(std::uint64_t delta);
void Reset();
void SetInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
std::uint64_t GetInterval() const { return m_Interval; }
};
// utililty class to call function at regular period of time with a cooldown (used for towers and mobs )
class CooldownTimer {
private:
std::uint64_t m_Cooldown; // in millis
std::uint64_t m_CooldownTime;
public:
CooldownTimer() : m_Cooldown(0), m_CooldownTime(0) {}
CooldownTimer(std::uint64_t cooldown) : m_Cooldown(0), m_CooldownTime(cooldown) {}
bool Update(std::uint64_t delta);
void ApplyCooldown();
void Reset();
void SetCooldown(std::uint64_t newCooldown) { m_CooldownTime = newCooldown; }
std::uint64_t GetCooldown() const { return m_CooldownTime; }
};
} // namespace utils
} // namespace td