farmlands/src/components/basic/Grid.cpp

137 lines
2.5 KiB
C++

/*
* Grid.cpp
*
* Created on: Dec 4, 2016
* Author: tibi
*/
#include <components/basic/Grid.h>
#include <utils/Assert.h>
#include <utils/Exceptions.h>
#include <iostream>
using namespace farmlands::model;
using namespace farmlands::utils;
namespace farmlands {
namespace components {
namespace basic {
Grid::Grid()
: m_bounds(0, 0, 1, 1),
m_grid(nullptr)
{
}
Grid::~Grid()
{
if (m_grid != nullptr)
delete[] m_grid;
}
model::Component* Grid::clone()
{
Grid* clone = new Grid();
clone->m_bounds = m_bounds;
return clone;
}
void Grid::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Grid bounds=[";
std::cout << m_bounds.x << "," << m_bounds.y << ",";
std::cout << m_bounds.w << "," << m_bounds.h << "]\n";
}
void Grid::onInitialize()
{
// Allocate memory
m_grid = new model::GameObject*[m_bounds.w * m_bounds.h];
memset(m_grid, 0, sizeof(model::GameObject*) * m_bounds.w * m_bounds.h);
// Add objects
for (auto it = gameObject->childrenBegin(); it != gameObject->childrenEnd(); it++)
{
GameObject* obj = *it;
// Compute grid position(s)
if (!m_bounds.contains(obj->transform.x, obj->transform.y))
{
std::cerr << "Grid: ignoring object " << obj->name << ": object outside allowed bounds.";
continue;
}
// Set
set(obj, (int)obj->transform.x, (int)obj->transform.y, false);
}
}
void Grid::setBounds(const utils::Rect<int>& bounds)
{
if (m_grid == nullptr)
m_bounds = bounds;
else
{
// Get rid of old grid
delete[] m_grid;
m_grid = nullptr;
m_bounds = bounds;
// Reinitialize
onInitialize();
}
}
utils::Rect<int> Grid::bounds() const
{
return m_bounds;
}
model::GameObject* Grid::get(int x, int y)
{
Assert(m_grid != nullptr, "Grid not initialized!!!");
if (m_bounds.contains(x, y))
{
int gx = x - m_bounds.x;
int gy = y - m_bounds.y;
return m_grid[gy * m_bounds.w + gx];
}
return nullptr;
}
void Grid::set(model::GameObject* obj, int x, int y, bool throwOnOverwrite)
{
int gx = x - m_bounds.x;
int gy = y - m_bounds.y;
int index = gy * m_bounds.w + gx;
if (m_grid[index] != nullptr)
{
if (throwOnOverwrite)
THROW(InvalidArgumentException, "Position already occupied!");
else
{
std::cerr << "Grid: cannot set " << obj->name << " to position " << x << ", " << y;
std::cerr << ": cell already occupied";
}
}
m_grid[index] = obj;
obj->transform.x = x;
obj->transform.y = y;
}
} /* namespace basic */
} /* namespace components */
} /* namespace farmlands */