Added librarys and test application

This commit is contained in:
Gulum
2017-10-22 14:26:55 +02:00
parent 7e0c0d8a6c
commit ac45f1f944
206 changed files with 68009 additions and 13 deletions

View File

@@ -0,0 +1,20 @@
// Inspired heavily by boost::noncopyable
#pragma once
namespace entityx {
namespace help {
class NonCopyable {
protected:
NonCopyable() = default;
~NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator = (const NonCopyable &) = delete;
};
} // namespace help
} // namespace entityx

View File

@@ -0,0 +1,21 @@
/*
* Copyright (C) 2012-2014 Alec Thomas <alec@swapoff.org>
* All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution.
*
* Author: Alec Thomas <alec@swapoff.org>
*/
#include "entityx/help/Pool.h"
namespace entityx {
BasePool::~BasePool() {
for (char *ptr : blocks_) {
delete[] ptr;
}
}
} // namespace entityx

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2012-2014 Alec Thomas <alec@swapoff.org>
* All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution.
*
* Author: Alec Thomas <alec@swapoff.org>
*/
#pragma once
#include <cstddef>
#include <cassert>
#include <vector>
namespace entityx {
/**
* Provides a resizable, semi-contiguous pool of memory for constructing
* objects in. Pointers into the pool will be invalided only when the pool is
* destroyed.
*
* The semi-contiguous nature aims to provide cache-friendly iteration.
*
* Lookups are O(1).
* Appends are amortized O(1).
*/
class BasePool {
public:
explicit BasePool(std::size_t element_size, std::size_t chunk_size = 8192)
: element_size_(element_size), chunk_size_(chunk_size), capacity_(0) {}
virtual ~BasePool();
std::size_t size() const { return size_; }
std::size_t capacity() const { return capacity_; }
std::size_t chunks() const { return blocks_.size(); }
/// Ensure at least n elements will fit in the pool.
inline void expand(std::size_t n) {
if (n >= size_) {
if (n >= capacity_) reserve(n);
size_ = n;
}
}
inline void reserve(std::size_t n) {
while (capacity_ < n) {
char *chunk = new char[element_size_ * chunk_size_];
blocks_.push_back(chunk);
capacity_ += chunk_size_;
}
}
inline void *get(std::size_t n) {
assert(n < size_);
return blocks_[n / chunk_size_] + (n % chunk_size_) * element_size_;
}
inline const void *get(std::size_t n) const {
assert(n < size_);
return blocks_[n / chunk_size_] + (n % chunk_size_) * element_size_;
}
virtual void destroy(std::size_t n) = 0;
protected:
std::vector<char *> blocks_;
std::size_t element_size_;
std::size_t chunk_size_;
std::size_t size_ = 0;
std::size_t capacity_;
};
/**
* Implementation of BasePool that provides type-"safe" deconstruction of
* elements in the pool.
*/
template <typename T, std::size_t ChunkSize = 8192>
class Pool : public BasePool {
public:
Pool() : BasePool(sizeof(T), ChunkSize) {}
virtual ~Pool() {
// Component destructors *must* be called by owner.
}
virtual void destroy(std::size_t n) override {
assert(n < size_);
T *ptr = static_cast<T*>(get(n));
ptr->~T();
}
};
} // namespace entityx

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2012-2014 Alec Thomas <alec@swapoff.org>
* All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution.
*
* Author: Alec Thomas <alec@swapoff.org>
*/
#define CATCH_CONFIG_MAIN
#include <vector>
#include "entityx/3rdparty/catch.hpp"
#include "entityx/help/Pool.h"
struct Position {
explicit Position(int *ptr = nullptr) : ptr(ptr) {
if (ptr) (*ptr)++;
}
~Position() {
if (ptr) (*ptr)++;
}
float x, y;
int *ptr;
};
TEST_CASE("TestPoolReserve") {
entityx::Pool<Position, 8> pool;
REQUIRE(0 == pool.capacity());
REQUIRE(0 == pool.chunks());
pool.reserve(8);
REQUIRE(0 == pool.size());
REQUIRE(8 == pool.capacity());
REQUIRE(1 == pool.chunks());
pool.reserve(16);
REQUIRE(0 == pool.size());
REQUIRE(16 == pool.capacity());
REQUIRE(2 == pool.chunks());
}
TEST_CASE("TestPoolPointers") {
entityx::Pool<Position, 8> pool;
std::vector<char*> ptrs;
for (int i = 0; i < 4; i++) {
pool.expand(i * 8 + 8);
// NOTE: This is an attempt to ensure non-contiguous allocations from
// arena allocators.
ptrs.push_back(new char[8 * sizeof(Position)]);
}
char *p0 = static_cast<char*>(pool.get(0));
char *p7 = static_cast<char*>(pool.get(7));
char *p8 = static_cast<char*>(pool.get(8));
char *p16 = static_cast<char*>(pool.get(16));
char *p24 = static_cast<char*>(pool.get(24));
void *expected_p7 = p0 + 7 * sizeof(Position);
REQUIRE(expected_p7 == static_cast<void*>(p7));
void *extrapolated_p8 = p0 + 8 * sizeof(Position);
REQUIRE(extrapolated_p8 != static_cast<void*>(p8));
void *extrapolated_p16 = p8 + 8 * sizeof(Position);
REQUIRE(extrapolated_p16 != static_cast<void*>(p16));
void *extrapolated_p24 = p16 + 8 * sizeof(Position);
REQUIRE(extrapolated_p24 != static_cast<void*>(p24));
}
TEST_CASE("TestDeconstruct") {
entityx::Pool<Position, 8> pool;
pool.expand(8);
void *p0 = pool.get(0);
int counter = 0;
new(p0) Position(&counter);
REQUIRE(1 == counter);
pool.destroy(0);
REQUIRE(2 == counter);
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2013 Antony Woods <antony@teamwoods.org>
* All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution.
*
* Author: Antony Woods <antony@teamwoods.org>
*/
#include "entityx/help/Timer.h"
namespace entityx {
namespace help {
Timer::Timer() {
_start = std::chrono::system_clock::now();
}
Timer::~Timer() {
}
void Timer::restart() {
_start = std::chrono::system_clock::now();
}
double Timer::elapsed() {
return std::chrono::duration<double>(std::chrono::system_clock::now() - _start).count();
}
} // namespace help
} // namespace entityx

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2013 Antony Woods <antony@teamwoods.org>
* All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution.
*
* Author: Antony Woods <antony@teamwoods.org>
*/
#pragma once
#include <chrono>
namespace entityx {
namespace help {
class Timer {
public:
Timer();
~Timer();
void restart();
double elapsed();
private:
std::chrono::time_point<std::chrono::system_clock> _start;
};
} // namespace help
} // namespace entityx