Tester Stable
This commit is contained in:
parent
f25d3cc8da
commit
2fba0b1d53
17 changed files with 769 additions and 113 deletions
106
include/Profiling/Timer.hpp
Normal file
106
include/Profiling/Timer.hpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
#pragma once
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <assert.h>
|
||||
|
||||
struct timer_result
|
||||
{
|
||||
double seconds = 0;
|
||||
double difftime = 0;
|
||||
};
|
||||
|
||||
struct Timer {
|
||||
enum State : u8
|
||||
{
|
||||
running = 0,
|
||||
paused = 1
|
||||
};
|
||||
State state = paused;
|
||||
|
||||
std::clock_t begin;
|
||||
std::clock_t elapsed = 0;
|
||||
std::optional<std::ostream*> out;
|
||||
std::optional<timer_result*> result;
|
||||
|
||||
Timer() : begin(std::clock()) {}
|
||||
Timer(std::ostream& o) : begin(std::clock()), out(&o) {}
|
||||
Timer(timer_result& r) : begin(std::clock()), result(&r) {}
|
||||
Timer(std::ostream& o, timer_result& r) : begin(std::clock()), out(&o), result(&r) {}
|
||||
Timer(State initial_state) : state(initial_state), begin(std::clock())
|
||||
{
|
||||
if (state == paused)
|
||||
begin = 0;
|
||||
}
|
||||
|
||||
Timer(std::ostream& o, State initial_state) : state(initial_state), begin(std::clock()), out(&o)
|
||||
{
|
||||
if (state == paused)
|
||||
begin = 0;
|
||||
}
|
||||
Timer(timer_result& r, State initial_state) : state(initial_state), begin(std::clock()), result(&r)
|
||||
{
|
||||
if (state == paused)
|
||||
begin = 0;
|
||||
}
|
||||
|
||||
Timer(std::ostream& o, timer_result& r, State initial_state) : state(initial_state), begin(std::clock()), out(&o), result(&r)
|
||||
{
|
||||
if (state == paused)
|
||||
begin = 0;
|
||||
}
|
||||
|
||||
void reset(State init_state) {
|
||||
if (state == paused)
|
||||
begin = 0;
|
||||
else
|
||||
begin = std::clock();
|
||||
elapsed = 0;
|
||||
state = init_state;
|
||||
lap();
|
||||
}
|
||||
|
||||
void set_state(State new_state)
|
||||
{
|
||||
if (this->state == new_state)
|
||||
return;
|
||||
|
||||
if (new_state == running)
|
||||
{
|
||||
begin = std::clock();
|
||||
}
|
||||
else // pausing
|
||||
{
|
||||
assert(begin != 0);
|
||||
elapsed += std::clock() - begin;
|
||||
begin = 0;
|
||||
}
|
||||
|
||||
lap();
|
||||
this->state = new_state;
|
||||
}
|
||||
|
||||
void lap()
|
||||
{
|
||||
std::clock_t total_time = elapsed;
|
||||
if (state == running)
|
||||
{
|
||||
total_time += std::clock() - begin;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result.value()->seconds = static_cast<double>(total_time) / CLOCKS_PER_SEC;
|
||||
result.value()->difftime = static_cast<double>(total_time) / CLOCKS_PER_SEC;
|
||||
}
|
||||
if (out)
|
||||
{
|
||||
*out.value() << static_cast<double>(total_time) / CLOCKS_PER_SEC << " seconds.\n";
|
||||
*out.value() << "Total time = " << static_cast<double>(total_time) / CLOCKS_PER_SEC << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
~Timer() {
|
||||
lap();
|
||||
}
|
||||
};
|
167
include/list.hpp
Normal file
167
include/list.hpp
Normal file
|
@ -0,0 +1,167 @@
|
|||
#pragma once
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* @brief A thread-safe dynamic array container class
|
||||
*
|
||||
* List provides a fixed-size array container with thread-safe access through mutex protection.
|
||||
* It supports construction with a size or initializer list, as well as copy/move operations.
|
||||
* All operations that access or modify the internal data are protected by a mutex.
|
||||
*
|
||||
* @tparam T The type of elements stored in the list
|
||||
*/
|
||||
template <typename T>
|
||||
class List {
|
||||
public:
|
||||
/**
|
||||
* @brief Type alias for the element type stored in the list
|
||||
*
|
||||
* This type represents the template parameter T that defines
|
||||
* the type of elements contained in the List container.
|
||||
*/
|
||||
using value_type = T;
|
||||
|
||||
/**
|
||||
* @brief Constructs a List with specified size
|
||||
* @param size The number of elements to allocate
|
||||
*/
|
||||
explicit List(std::size_t size)
|
||||
: data_(std::make_unique<T[]>(size))
|
||||
, size_(size) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructs a List from an initializer list
|
||||
* @param init The initializer list containing initial values
|
||||
*/
|
||||
List(std::initializer_list<T> init)
|
||||
: data_(std::make_unique<T[]>(init.size()))
|
||||
, size_(init.size()) {
|
||||
std::lock_guard lock(mutex_);
|
||||
std::copy(init.begin(), init.end(), data_.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
* @param other The List to copy from
|
||||
* @thread_safety Both this and other List's mutexes are locked during copy
|
||||
*/
|
||||
List(const List& other) {
|
||||
std::lock_guard lock(mutex_);
|
||||
std::lock_guard<std::mutex> other_lock(other.mutex_);
|
||||
data_ = std::make_unique<T[]>(other.size_);
|
||||
std::copy(other.data_.get(), other.data_.get() + other.size_, data_.get());
|
||||
size_ = other.size_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move constructor
|
||||
* @param other The List to move from
|
||||
* @thread_safety Both this and other List's mutexes are locked during move
|
||||
*/
|
||||
List(List&& other) noexcept {
|
||||
std::lock_guard lock(mutex_);
|
||||
std::lock_guard<std::mutex> other_lock(other.mutex_);
|
||||
data_ = std::move(other.data_);
|
||||
size_ = other.size_;
|
||||
other.size_ = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment operator
|
||||
* @param other The List to copy from
|
||||
* @return Reference to this List
|
||||
* @thread_safety Both this and other List's mutexes are locked during assignment
|
||||
*/
|
||||
List& operator=(const List& other) {
|
||||
if (this != &other) {
|
||||
std::lock_guard lock(mutex_);
|
||||
std::lock_guard<std::mutex> other_lock(other.mutex_);
|
||||
data_ = std::make_unique<T[]>(other.size_);
|
||||
std::copy(other.data_.get(), other.data_.get() + other.size_, data_.get());
|
||||
size_ = other.size_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move assignment operator
|
||||
* @param other The List to move from
|
||||
* @return Reference to this List
|
||||
* @thread_safety Both this and other List's mutexes are locked during move
|
||||
*/
|
||||
List& operator=(List&& other) noexcept {
|
||||
if (this != &other) {
|
||||
std::lock_guard lock(mutex_);
|
||||
std::lock_guard<std::mutex> other_lock(other.mutex_);
|
||||
data_ = std::move(other.data_);
|
||||
size_ = other.size_;
|
||||
other.size_ = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access element at specified index with bounds wrapping
|
||||
* @param index The index of the element to access
|
||||
* @return Reference to the element at the wrapped index
|
||||
* @thread_safety Protected by mutex
|
||||
*/
|
||||
T& operator[](std::size_t index) {
|
||||
std::lock_guard lock(mutex_);
|
||||
return data_[index % size_];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access const element at specified index with bounds wrapping
|
||||
* @param index The index of the element to access
|
||||
* @return Const reference to the element at the wrapped index
|
||||
* @thread_safety Protected by mutex
|
||||
*/
|
||||
const T& operator[](std::size_t index) const {
|
||||
std::lock_guard lock(mutex_);
|
||||
return data_[index % size_];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get const element at specified index with bounds wrapping
|
||||
* @param index The index of the element to access
|
||||
* @return Const reference to the element at the wrapped index
|
||||
* @thread_safety Protected by mutex
|
||||
*/
|
||||
const T& get(std::size_t index) const
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
return data_[index % size_];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set element at specified index with bounds wrapping
|
||||
* @param index The index of the element to set
|
||||
* @param value The value to set at the specified index
|
||||
* @thread_safety Protected by mutex
|
||||
*/
|
||||
void set(std::size_t index, const T& value) {
|
||||
std::lock_guard lock(mutex_);
|
||||
data_[index % size_] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the size of the List
|
||||
* @return The number of elements in the List
|
||||
* @thread_safety Protected by mutex
|
||||
*/
|
||||
std::size_t size() const {
|
||||
std::lock_guard lock(mutex_);
|
||||
return size_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<T[]> data_; ///< Underlying array storage
|
||||
std::size_t size_; ///< Number of elements in the array
|
||||
mutable std::mutex mutex_; ///< Mutex for thread-safe access
|
||||
};
|
22
include/std.hpp
Normal file
22
include/std.hpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#define SHOW(variable) std::cout << #variable << " = " << (variable) << std::endl;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEBUG
|
||||
#define ASSERT(condition, message) while(!(condition)) { std::cerr << "Assertion failed: " << #condition << "\n\t" << (message); exit(1); }
|
||||
#define FATAL_ASSERT(condition, message) ASSERT(condition, message)
|
||||
#else
|
||||
#define RELEASE
|
||||
#define FATAL_ASSERT(condition, message) ASSERT(condition, message) exit(1);
|
||||
#define ASSERT(condition, message) if(!(condition)) { std::cerr << "Assertion failed: " << #condition << "\nIn File: " << __FILE__ << "\nOn line: " << __LINE__ << "\n\t" << (message); }
|
||||
#endif
|
||||
|
||||
#include "types.hpp"
|
||||
#include "list.hpp"
|
||||
#include "flagman.hpp"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "Profiling/Timer.hpp"
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
@ -84,3 +84,4 @@ typedef TRect<double> rectd;
|
|||
typedef TRect<uintmax_t> rectu;
|
||||
typedef TRect<intmax_t> recti;
|
||||
|
||||
#include "list.hpp"
|
Loading…
Add table
Add a link
Reference in a new issue