Solved TODOs
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace array { // TODO rename to container or something
|
namespace array {
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
concept Deletable = requires(U u) {
|
concept Deletable = requires(U u) {
|
||||||
@@ -148,7 +148,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
pair_t *m_Pool = nullptr;
|
pair_t *m_Pool = nullptr;
|
||||||
// TODO use unique_ptr
|
|
||||||
std::stack<size_t> m_FreeIdx;
|
std::stack<size_t> m_FreeIdx;
|
||||||
|
|
||||||
size_t m_Capacity = 0;
|
size_t m_Capacity = 0;
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// TODO this should be replaced with a matrix
|
|
||||||
float m_Zoom = 1.0f;
|
float m_Zoom = 1.0f;
|
||||||
WorldPos m_Pan;
|
WorldPos m_Pan;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,16 +63,12 @@ void GameLoop::Draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rethink coupling and dependencies in the game loop class
|
|
||||||
|
|
||||||
void GameLoop::Run() {
|
void GameLoop::Run() {
|
||||||
LOG_INFO("Running the game");
|
LOG_INFO("Running the game");
|
||||||
while (!m_Game->IsExitRequested()) {
|
while (!m_Game->IsExitRequested()) {
|
||||||
m_Game->HandleActions(m_UserInput->GetActions());
|
m_Game->HandleActions(m_UserInput->GetActions());
|
||||||
m_Game->UpdateWorld();
|
m_Game->UpdateWorld();
|
||||||
|
|
||||||
// TODO measure fps, draw only if delay for target fps was reached
|
|
||||||
// or create a separate thread for drawing
|
|
||||||
m_Window->ClearWindow();
|
m_Window->ClearWindow();
|
||||||
Draw();
|
Draw();
|
||||||
m_Window->Flush();
|
m_Window->Flush();
|
||||||
|
|||||||
@@ -7,16 +7,11 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <numbers>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <numbers>
|
|
||||||
#define M_PI std::numbers::pi
|
|
||||||
// TODO use std::numbers::pi instead of M_PI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::floating_point<T>
|
requires std::floating_point<T>
|
||||||
static inline bool equalEpsilon(const T &a, const T &b) {
|
static inline bool equalEpsilon(const T &a, const T &b) {
|
||||||
@@ -174,8 +169,6 @@ public:
|
|||||||
vec &a = *this;
|
vec &a = *this;
|
||||||
auto b = std::views::repeat(scalar);
|
auto b = std::views::repeat(scalar);
|
||||||
std::ranges::transform(a.m_Array, b, a.m_Array.begin(), std::divides{});
|
std::ranges::transform(a.m_Array, b, a.m_Array.begin(), std::divides{});
|
||||||
// TODO check all of this, could be done better with views instead of
|
|
||||||
// ranges?
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ PathFindingDemo::PathFindingDemo(int width, int height) : m_Map(width, height) {
|
|||||||
PathFindingDemo::~PathFindingDemo() { LOG_DEBUG("."); }
|
PathFindingDemo::~PathFindingDemo() { LOG_DEBUG("."); }
|
||||||
|
|
||||||
void PathFindingDemo::AddEntity(std::shared_ptr<Entity> e) {
|
void PathFindingDemo::AddEntity(std::shared_ptr<Entity> e) {
|
||||||
// TODO emplace_back
|
|
||||||
m_Entities.push_back(e);
|
m_Entities.push_back(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,11 +70,6 @@ void PathFindingDemo::CreateMap() {
|
|||||||
AddEntity(p);
|
AddEntity(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// select everything - TODO this is just temporary for testing
|
|
||||||
for (const auto &entity : m_Entities) {
|
|
||||||
m_SelectedEntities.push_back(entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldPos PathFindingDemo::GetRandomPosition() const {
|
WorldPos PathFindingDemo::GetRandomPosition() const {
|
||||||
@@ -121,8 +115,6 @@ void PathFindingDemo::UpdateWorld() {
|
|||||||
entity->SetActualVelocity(velocity * tile_velocity_coeff);
|
entity->SetActualVelocity(velocity * tile_velocity_coeff);
|
||||||
|
|
||||||
for (const auto &collision : GetEntityCollisions()) {
|
for (const auto &collision : GetEntityCollisions()) {
|
||||||
// TODO this loop is quite "hot", is it good idea to use weak_ptr and
|
|
||||||
// promote it?
|
|
||||||
auto weak_A = std::get<0>(collision);
|
auto weak_A = std::get<0>(collision);
|
||||||
auto weak_B = std::get<1>(collision);
|
auto weak_B = std::get<1>(collision);
|
||||||
auto A = weak_A.lock();
|
auto A = weak_A.lock();
|
||||||
@@ -136,8 +128,6 @@ void PathFindingDemo::UpdateWorld() {
|
|||||||
// LOG_DEBUG("Collision: A is ", A, ", B is ", B);
|
// LOG_DEBUG("Collision: A is ", A, ", B is ", B);
|
||||||
auto AB = B->GetPosition() - A->GetPosition();
|
auto AB = B->GetPosition() - A->GetPosition();
|
||||||
A->ZeroActualVelocityInDirection(AB);
|
A->ZeroActualVelocityInDirection(AB);
|
||||||
// handle logic
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the position
|
// update the position
|
||||||
@@ -211,7 +201,6 @@ void PathFindingDemo::DeselectEntities() {
|
|||||||
|
|
||||||
void PathFindingDemo::SelectEntitiesInRectangle(WorldPos A, WorldPos B) {
|
void PathFindingDemo::SelectEntitiesInRectangle(WorldPos A, WorldPos B) {
|
||||||
DeselectEntities();
|
DeselectEntities();
|
||||||
// TODO use colliders for this
|
|
||||||
auto [x_min, x_max] = std::minmax(A.x(), B.x());
|
auto [x_min, x_max] = std::minmax(A.x(), B.x());
|
||||||
auto [y_min, y_max] = std::minmax(A.y(), B.y());
|
auto [y_min, y_max] = std::minmax(A.y(), B.y());
|
||||||
for (const auto &entity : m_Entities) {
|
for (const auto &entity : m_Entities) {
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cmath>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "math.hpp"
|
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
|
#include "math.hpp"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept HasPosition = requires(T t, WorldPos pos) {
|
concept HasPosition = requires(T t, WorldPos pos) {
|
||||||
@@ -17,48 +17,36 @@ concept HasPosition = requires(T t, WorldPos pos) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept HasCollisions = requires(T t) {
|
requires HasPosition<T>
|
||||||
t.Dummy(); // TODO
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
class IPositionalContainer {
|
||||||
requires HasPosition<T>
|
|
||||||
|
|
||||||
class IPositionalContainer
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
virtual ~IPositionalContainer() = default;
|
virtual ~IPositionalContainer() = default;
|
||||||
virtual bool Add(std::shared_ptr<T> t) = 0;
|
virtual bool Add(std::shared_ptr<T> t) = 0;
|
||||||
virtual std::vector<std::weak_ptr<T>> Get(const WorldPos& p, float radius) = 0;
|
virtual std::vector<std::weak_ptr<T>> Get(const WorldPos &p,
|
||||||
|
float radius) = 0;
|
||||||
virtual void UpdateAll() = 0;
|
virtual void UpdateAll() = 0;
|
||||||
virtual void Update(std::shared_ptr<T> item) = 0;
|
virtual void Update(std::shared_ptr<T> item) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class IColliderContainer : public IPositionalContainer<T>
|
class IColliderContainer : public IPositionalContainer<T> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
virtual std::vector<std::weak_ptr<T>> GetCollisions() = 0;
|
virtual std::vector<std::weak_ptr<T>> GetCollisions() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> class SimpleContainer : IPositionalContainer<T> {
|
||||||
class SimpleContainer : IPositionalContainer<T>
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
bool Add(std::shared_ptr<T> t) override
|
bool Add(std::shared_ptr<T> t) override {
|
||||||
{
|
|
||||||
m_Items.push_back(t);
|
m_Items.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::weak_ptr<T>> Get(const WorldPos& center, float radius) override
|
std::vector<std::weak_ptr<T>> Get(const WorldPos ¢er,
|
||||||
{
|
float radius) override {
|
||||||
std::vector<std::weak_ptr<T>> matched_items;
|
std::vector<std::weak_ptr<T>> matched_items;
|
||||||
for (const auto& item : m_Items)
|
for (const auto &item : m_Items) {
|
||||||
{
|
if (center.DistanceTo(item->GetPosition()) < radius) {
|
||||||
if (center.DistanceTo(item->GetPosition()) < radius)
|
|
||||||
{
|
|
||||||
matched_items.push_back(item);
|
matched_items.push_back(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,48 +61,35 @@ private:
|
|||||||
std::vector<std::shared_ptr<T>> m_Items;
|
std::vector<std::shared_ptr<T>> m_Items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T> class PositionalContainer : IPositionalContainer<T> {
|
||||||
template <class T>
|
|
||||||
class PositionalContainer : IPositionalContainer<T>
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
PositionalContainer(const WorldSize &size, size_t chunks)
|
||||||
PositionalContainer(const WorldSize& size, size_t chunks) :
|
: m_GridSize{size}, m_GridStep{size / chunks}, m_ChunksPerAxis{chunks} {
|
||||||
m_GridSize{size},
|
|
||||||
m_GridStep{size / chunks},
|
|
||||||
m_ChunksPerAxis{chunks}
|
|
||||||
{
|
|
||||||
LOG_INFO("Size: ", m_GridSize, " step: ", m_GridStep);
|
LOG_INFO("Size: ", m_GridSize, " step: ", m_GridStep);
|
||||||
m_Grid.reserve(chunks);
|
m_Grid.reserve(chunks);
|
||||||
for (size_t i = 0; i < chunks; i++)
|
for (size_t i = 0; i < chunks; i++) {
|
||||||
{
|
|
||||||
m_Grid.emplace_back(chunks);
|
m_Grid.emplace_back(chunks);
|
||||||
for (size_t j = 0; j < chunks; j++)
|
for (size_t j = 0; j < chunks; j++) {
|
||||||
{
|
|
||||||
m_Grid[i][j].reserve(16);
|
m_Grid[i][j].reserve(16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// calling Add on object that is already in the container is UB
|
// calling Add on object that is already in the container is UB
|
||||||
bool Add(std::shared_ptr<T> item) override
|
bool Add(std::shared_ptr<T> item) override {
|
||||||
{
|
const auto &world_pos = item->GetPosition();
|
||||||
const auto& world_pos = item->GetPosition();
|
if (!CheckBounds(world_pos)) {
|
||||||
if (!CheckBounds(world_pos))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_Items.push_back(item);
|
m_Items.push_back(item);
|
||||||
auto coords = GetCoords(world_pos);
|
auto coords = GetCoords(world_pos);
|
||||||
m_Grid[coords.x()][coords.y()].push_back(item);
|
m_Grid[coords.x()][coords.y()].push_back(item);
|
||||||
m_ReverseGridLookup[item] = coords;
|
m_ReverseGridLookup[item] = coords;
|
||||||
// TODO should we call Update instead?
|
|
||||||
//Update(item);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::weak_ptr<T>> Get(const WorldPos& center, float radius) override
|
std::vector<std::weak_ptr<T>> Get(const WorldPos ¢er,
|
||||||
{
|
float radius) override {
|
||||||
vector_wptr output_vec{};
|
vector_wptr output_vec{};
|
||||||
|
|
||||||
Get(output_vec, center, radius);
|
Get(output_vec, center, radius);
|
||||||
@@ -122,18 +97,16 @@ public:
|
|||||||
return output_vec;
|
return output_vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get(std::vector<std::weak_ptr<T>>& output_vec, const WorldPos& corner, const WorldSize& size)
|
void Get(std::vector<std::weak_ptr<T>> &output_vec, const WorldPos &corner,
|
||||||
{
|
const WorldSize &size) {
|
||||||
const WorldSize half_size = size / 2.0f;
|
const WorldSize half_size = size / 2.0f;
|
||||||
const WorldPos center = corner + half_size.ChangeTag<WorldPos>();
|
const WorldPos center = corner + half_size.ChangeTag<WorldPos>();
|
||||||
float radius = half_size.x();
|
float radius = half_size.x();
|
||||||
Get(output_vec, center, radius);
|
Get(output_vec, center, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO add those Get methods to the interface
|
void Get(std::vector<std::weak_ptr<T>> &output_vec, const WorldPos ¢er,
|
||||||
|
float radius) {
|
||||||
void Get(std::vector<std::weak_ptr<T>>& output_vec, const WorldPos& center, float radius)
|
|
||||||
{
|
|
||||||
output_vec.clear();
|
output_vec.clear();
|
||||||
const WorldPos corner_1 = center + radius;
|
const WorldPos corner_1 = center + radius;
|
||||||
const WorldPos corner_2 = center - radius;
|
const WorldPos corner_2 = center - radius;
|
||||||
@@ -149,89 +122,64 @@ public:
|
|||||||
size_t y_min = static_cast<size_t>(std::floor(y_min_f));
|
size_t y_min = static_cast<size_t>(std::floor(y_min_f));
|
||||||
size_t y_max = static_cast<size_t>(std::ceil(y_max_f));
|
size_t y_max = static_cast<size_t>(std::ceil(y_max_f));
|
||||||
|
|
||||||
for (size_t x = x_min; x <= x_max; x++)
|
for (size_t x = x_min; x <= x_max; x++) {
|
||||||
{
|
for (size_t y = y_min; y <= y_max; y++) {
|
||||||
for (size_t y = y_min; y <= y_max; y++)
|
if (!CheckBounds(x, y)) {
|
||||||
{
|
|
||||||
if (!CheckBounds(x, y))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#if 0
|
for (auto item_wptr : m_Grid[x][y]) {
|
||||||
// TODO this is approx 2x faster, but inserts items outside of radius;
|
if (auto shared = item_wptr.lock()) {
|
||||||
// We can use this is a Get(rectangle) function
|
if (center.DistanceTo(shared->GetPosition()) < radius) {
|
||||||
std::ranges::copy(m_Grid[x][y], std::back_inserter(output_vec));
|
|
||||||
#else
|
|
||||||
for (auto item_wptr : m_Grid[x][y])
|
|
||||||
{
|
|
||||||
if (auto shared = item_wptr.lock())
|
|
||||||
{
|
|
||||||
if (center.DistanceTo(shared->GetPosition()) < radius)
|
|
||||||
{
|
|
||||||
output_vec.push_back(item_wptr);
|
output_vec.push_back(item_wptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAll() override
|
void UpdateAll() override {
|
||||||
{
|
for (auto ptr : m_Items) {
|
||||||
for (auto ptr : m_Items)
|
|
||||||
{
|
|
||||||
// TODO is this efficient? Maybe use const ref?
|
|
||||||
|
|
||||||
|
|
||||||
Update(ptr);
|
Update(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Update(std::shared_ptr<T> item) override
|
void Update(std::shared_ptr<T> item) override {
|
||||||
{
|
|
||||||
coord_type current_coords = GetCoords(item->GetPosition());
|
coord_type current_coords = GetCoords(item->GetPosition());
|
||||||
coord_type last_known_coords = m_ReverseGridLookup[item];
|
coord_type last_known_coords = m_ReverseGridLookup[item];
|
||||||
if (current_coords == last_known_coords)
|
if (current_coords == last_known_coords) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vector_wptr& vec = m_Grid[last_known_coords.x()][last_known_coords.y()];
|
vector_wptr &vec = m_Grid[last_known_coords.x()][last_known_coords.y()];
|
||||||
// remove the old weak ptr from the map
|
// remove the old weak ptr from the map
|
||||||
vec.erase(std::remove_if(vec.begin(), vec.end(),
|
vec.erase(std::remove_if(vec.begin(), vec.end(),
|
||||||
[&](const std::weak_ptr<T>& w)
|
[&](const std::weak_ptr<T> &w) {
|
||||||
{
|
return !w.owner_before(item) &&
|
||||||
return !w.owner_before(item) && !item.owner_before(w);
|
!item.owner_before(w);
|
||||||
}),
|
}),
|
||||||
vec.end());
|
vec.end());
|
||||||
// add new weak ptr to the map
|
// add new weak ptr to the map
|
||||||
m_Grid[current_coords.x()][current_coords.y()].push_back(item);
|
m_Grid[current_coords.x()][current_coords.y()].push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
using coord_type = vec<size_t, 2>;
|
using coord_type = vec<size_t, 2>;
|
||||||
using vector_wptr = std::vector<std::weak_ptr<T>>;
|
using vector_wptr = std::vector<std::weak_ptr<T>>;
|
||||||
using grid_type = std::vector<std::vector<vector_wptr>>;
|
using grid_type = std::vector<std::vector<vector_wptr>>;
|
||||||
|
|
||||||
coord_type GetCoords(const WorldPos &wp)
|
coord_type GetCoords(const WorldPos &wp) {
|
||||||
{
|
|
||||||
auto coord_float = wp / m_GridStep.ChangeTag<WorldPos>();
|
auto coord_float = wp / m_GridStep.ChangeTag<WorldPos>();
|
||||||
return coord_type{
|
return coord_type{static_cast<size_t>(coord_float.x()),
|
||||||
static_cast<size_t>(coord_float.x()),
|
static_cast<size_t>(coord_float.y())};
|
||||||
static_cast<size_t>(coord_float.y())
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckBounds(size_t x, size_t y) const
|
bool CheckBounds(size_t x, size_t y) const {
|
||||||
{
|
|
||||||
bool x_in_bounds = x < m_Grid.size();
|
bool x_in_bounds = x < m_Grid.size();
|
||||||
bool y_in_bounds = y < m_Grid.size();
|
bool y_in_bounds = y < m_Grid.size();
|
||||||
return x_in_bounds && y_in_bounds;
|
return x_in_bounds && y_in_bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckBounds(const WorldPos& pos) const
|
bool CheckBounds(const WorldPos &pos) const {
|
||||||
{
|
auto [x, y] = pos;
|
||||||
auto [x,y] = pos;
|
|
||||||
bool x_in_bounds = 0.0f < x && x < m_GridSize.x();
|
bool x_in_bounds = 0.0f < x && x < m_GridSize.x();
|
||||||
bool y_in_bounds = 0.0f < y && y < m_GridSize.y();
|
bool y_in_bounds = 0.0f < y && y < m_GridSize.y();
|
||||||
return x_in_bounds && y_in_bounds;
|
return x_in_bounds && y_in_bounds;
|
||||||
@@ -240,17 +188,16 @@ private:
|
|||||||
WorldSize m_GridSize;
|
WorldSize m_GridSize;
|
||||||
WorldSize m_GridStep;
|
WorldSize m_GridStep;
|
||||||
size_t m_ChunksPerAxis;
|
size_t m_ChunksPerAxis;
|
||||||
// TODO it would be better to have vector<T> - contiguous memory, more cache-friendly?
|
|
||||||
std::vector<std::shared_ptr<T>> m_Items;
|
std::vector<std::shared_ptr<T>> m_Items;
|
||||||
grid_type m_Grid;
|
grid_type m_Grid;
|
||||||
|
|
||||||
// normal lookup: WorldPos -> coord_type -> vector_wptr -> std::shared_ptr<T>
|
// normal lookup: WorldPos -> coord_type -> vector_wptr -> std::shared_ptr<T>
|
||||||
// reverse lookup: std::shared_ptr<T> -> vector_wptr -> coord_type
|
// reverse lookup: std::shared_ptr<T> -> vector_wptr -> coord_type
|
||||||
// we need the reverse lookup because T.GetPosition() may change and we need to delete
|
// we need the reverse lookup because T.GetPosition() may change and we need
|
||||||
// the old weak_ptr from vector_wptr (without iterating through all of them).
|
// to delete the old weak_ptr from vector_wptr (without iterating through all
|
||||||
// Also it might be useful to have T -> location lookup
|
// of them). Also it might be useful to have T -> location lookup Note: hash
|
||||||
// Note: hash of std::shared_ptr<T> may give us trouble if we free the memory and new one points
|
// of std::shared_ptr<T> may give us trouble if we free the memory and new one
|
||||||
// to the same location, maybe it would be better to hash the object itself?
|
// points to the same location, maybe it would be better to hash the object
|
||||||
// TODO how about using counting bloom filter for this?
|
// itself? NOTE how about using counting bloom filter for this?
|
||||||
std::unordered_map<std::shared_ptr<T>, coord_type> m_ReverseGridLookup;
|
std::unordered_map<std::shared_ptr<T>, coord_type> m_ReverseGridLookup;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -117,8 +117,7 @@ const std::vector<UserAction> &UserInput::GetActions() {
|
|||||||
} else if (mouse_events.contains(event.type)) {
|
} else if (mouse_events.contains(event.type)) {
|
||||||
GetActions_mouse(event);
|
GetActions_mouse(event);
|
||||||
} else {
|
} else {
|
||||||
// TODO uncomment, for now too much noise
|
LOG_WARNING("Action not processed");
|
||||||
// LOG_WARNING("Action not processed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m_Actions;
|
return m_Actions;
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ void Window::DrawCircle(const WindowPos &position, float radius, uint8_t R,
|
|||||||
int cy = static_cast<int>(position.y());
|
int cy = static_cast<int>(position.y());
|
||||||
SDL_SetRenderDrawColor(m_Renderer.get(), R, G, B, 255);
|
SDL_SetRenderDrawColor(m_Renderer.get(), R, G, B, 255);
|
||||||
for (int i = 0; i < 360; ++i) {
|
for (int i = 0; i < 360; ++i) {
|
||||||
double a = i * M_PI / 180.0;
|
double a = i * std::numbers::pi / 180.0;
|
||||||
SDL_RenderPoint(m_Renderer.get(),
|
SDL_RenderPoint(m_Renderer.get(),
|
||||||
cx + static_cast<int>(std::round(radius * std::cos(a))),
|
cx + static_cast<int>(std::round(radius * std::cos(a))),
|
||||||
cy + static_cast<int>(std::round(radius * std::sin(a))));
|
cy + static_cast<int>(std::round(radius * std::sin(a))));
|
||||||
|
|||||||
Reference in New Issue
Block a user