Tester Stable

This commit is contained in:
noffie 2024-11-07 01:54:45 +01:00
parent f25d3cc8da
commit 2fba0b1d53
17 changed files with 769 additions and 113 deletions

View file

@ -2,17 +2,15 @@
# CMake Configuration for the Sortiva Project
# ========================================================
# Specify the minimum CMake version required
cmake_minimum_required(VERSION 3.22)
# Project name, languages, and version
project(sortiva
LANGUAGES CXX
VERSION 1.0.0
LANGUAGES CXX
VERSION 1.0.0
)
# ========================================================
# C++ Standard and General Settings
# Global Settings
# ========================================================
set(CMAKE_CXX_STANDARD 20) # Use C++20
@ -22,11 +20,11 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Generate compile commands (useful
set(USE_FOLDERS ON) # Organize targets into folders (for IDEs)
set(BUILD_SHARED_LIBS OFF) # Build static libraries by default
# =======================================================
# ========================================================
# Helper Functions:
# Puts Targets into a Folder
# Finds all files in a dir wich are defined file-types
# =======================================================
# ========================================================
# This function puts targets into a specified folder.
# It checks if the target exists and gets the actual target (if it is aliased).
# It then sets the folder property for the target.
@ -93,6 +91,17 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(sol2)
# --- Add Lua
FetchContent_Declare(
lua
GIT_REPOSITORY "https://github.com/marovira/lua"
GIT_TAG "5.4.4"
)
FetchContent_MakeAvailable(lua)
set(LUA_BUILD_INTERPRETER ON)
# ========================================================
# Helper Function: Set Common Target Properties
# ========================================================
@ -101,8 +110,10 @@ FetchContent_MakeAvailable(sol2)
function(set_common_properties target)
target_link_libraries(${target} PRIVATE sol2::sol2) # Link with Sol2
target_compile_definitions(${target} PRIVATE SOL_ALL_SAFETIES_ON=1)
target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) # Include project headers
target_sources(${target} PRIVATE ${SVA_COMMON_FILES}) # Include common files
target_link_libraries(${target} PRIVATE lua::lua)
endfunction()
# ========================================================
@ -111,11 +122,8 @@ endfunction()
set(GUI_TARGET_NAME "${PROJECT_NAME}")
# --- Create GUI Executable
find_files(SVA_GUI_FILES "./src/gui/" hpp cpp h c hxx cxx)
find_files(SVA_GUI_FILES "./src/" hpp cpp h c hxx cxx)
add_executable(${GUI_TARGET_NAME}
src/main.cpp # Entry point for the GUI application
src/sva.hpp # Header file for the console
${SVA_GUI_FILES}
)
@ -200,21 +208,22 @@ if(${SVA_BUILD_TEST})
enable_testing()
# --- Create Test Executable
set(TEST_TARGET_NAME "${GUI_TARGET_NAME}_test")
add_executable(
sortiva_test
${TEST_TARGET_NAME}
tests/test_main.cpp # Test entry point
tests/test_sorting_functions.cpp
)
target_link_libraries(
sortiva_test
${TEST_TARGET_NAME}
PRIVATE GTest::gtest_main # Link Google Test framework
)
set_common_properties(sortiva_test)
set_common_properties(${TEST_TARGET_NAME})
# --- Enable Google Test's test discovery feature
include(GoogleTest)
gtest_discover_tests(sortiva_test)
gtest_discover_tests(${TEST_TARGET_NAME})
# put google test targets into a folder
put_targets_into_folder(
@ -227,3 +236,28 @@ if(${SVA_BUILD_TEST})
)
endif()
# Option to create an includes target
set(SVA_CREATE_INCLUDES_TARGET ON CACHE BOOL "Create an includes target")
if(${SVA_CREATE_INCLUDES_TARGET})
set(INCLUDES_TARGET_NAME "${GUI_TARGET_NAME}_includes")
set(INCLUDE_FILES)
find_files(
INCLUDE_FILES
"include/"
hpp h hxx
)
message(STATUS "Include files: ${INCLUDE_FILES}")
add_custom_target(${INCLUDES_TARGET_NAME}
SOURCES
${INCLUDE_FILES}
)
set_target_properties(${INCLUDES_TARGET_NAME} PROPERTIES FOLDER "sva")
endif()
put_targets_into_folder(
FOLDER "sva"
TARGETS
${GUI_TARGET_NAME}
${TEST_TARGET_NAME}
)

106
include/Profiling/Timer.hpp Normal file
View 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
View 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
View 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

View file

@ -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"

1
src/Renderer.cpp Normal file
View file

@ -0,0 +1 @@
#include "Renderer.h"

7
src/Renderer.h Normal file
View file

@ -0,0 +1,7 @@
#pragma once
class Renderer
{
public:
};

42
src/SortingTester.cpp Normal file
View file

@ -0,0 +1,42 @@
#include "SortingTester.h"
SortingTester::SortingTester() : list(10)
{
lua.lua.open_libraries(sol::lib::coroutine, sol::lib::table);
lua.lua.new_usertype<SortingTester>("List",
"size", &SortingTester::list_size,
"swap", &SortingTester::list_swap,
"greater", &SortingTester::list_greater,
"less", &SortingTester::list_less,
"equal", &SortingTester::list_equal
);
lua.lua["list"] = this;
}
void SortingTester::load(const std::string& script)
{
if(lua.load(script) != safesol::LuaResultType::SUCCESS)
{
std::cerr << "Error loading file" << std::endl;
std::terminate();
}
}
#include "internal_script.hpp"
void SortingTester::load_internal()
{
if (lua.script(std_intern_sorting_script) != safesol::LuaResultType::SUCCESS)
{
std::cerr << "Error loading internal script" << std::endl;
std::terminate();
}
}
void SortingTester::populate(const populate_function& f)
{
for (size_t i = 0; i < list.size(); i++)
f(i, list[i]);
}

152
src/SortingTester.h Normal file
View file

@ -0,0 +1,152 @@
#pragma once
#define SVA_LIST_CALLBACKS
#include <std.hpp>
#include <functional>
#include "lua/safesol.h"
#include <iostream>
class SortingTester
{
List<u64> list;
safesol lua;
Timer timer = Timer(Timer::State::paused);
using populate_function = std::function<void(size_t, u64&)>;
template<typename ...Args>
sol::protected_function_result run_function(const sol::protected_function& function, Args&&... args)
{
timer.set_state(Timer::State::running);
sol::protected_function_result result = function(std::forward<Args>(args)...);
timer.set_state(Timer::State::paused);
return result;
}
bool list_greater(size_t index1, size_t index2)
{
if (active_result)
++active_result->count_greater;
return list[index1] > list[index2];
}
bool list_less(size_t index1, size_t index2)
{
if (active_result)
++active_result->count_less;
return list[index1] < list[index2];
}
bool list_equal(size_t index1, size_t index2)
{
if (active_result)
++active_result->count_equal;
return list[index1] == list[index2];
}
void list_swap(size_t index1, size_t index2)
{
if (active_result)
++active_result->count_swaps;
// list[index1] ^= list[index2];
// list[index2] ^= list[index1];
// list[index1] ^= list[index2];
auto tmp = list[index1];
list[index1] = list[index2];
list[index2] = tmp;
}
size_t list_size() const
{
return list.size();
}
bool is_sorted()
{
if (list.size() <= 1)
return true;
for (size_t i = 1; i < list.size(); ++i)
{
if (list[i - 1] > list[i])
return false;
}
return true;
}
public:
struct run_result
{
timer_result timer;
// counts
u64 count_swaps = 0;
u64 count_greater = 0;
u64 count_less = 0;
u64 count_equal = 0;
// counts for comparisons
u64 count_comparisons = 0;
};
private:
run_result* active_result = nullptr;
public:
SortingTester();
void load(const std::string& script);
void load_internal();
template<typename ...Args>
run_result run(const std::string& function_name, Args&&... args)
{
run_result result;
timer.result.emplace(&result.timer);
timer.reset(Timer::State::paused);
active_result = &result;
// Create a bound member function using std::bind
auto bound_run_function = std::bind(&SortingTester::run_function<Args...>,
this,
std::placeholders::_1,
std::forward<Args>(args)...);
safesol::LuaResultType runstate = lua.run_on_caller(function_name, bound_run_function);
if (runstate != safesol::LuaResultType::SUCCESS)
{
std::cerr << "Error running function \"" << function_name << "\": " << static_cast<u16>(runstate) << std::endl;
exit(static_cast<int>(runstate));
}
if (!is_sorted())
{
std::cerr << "[ERROR] The algorithm \"" << function_name << "\" did not sort the list" << std::endl;
std::cerr << "[List] [ ";
for (size_t i = 0; i < list.size(); i++)
{
if(i == list.size()-1)
{
std::cerr << list[i] << " ]";
continue;
}
std::cerr << list[i] << ", ";
}
std::flush(std::cerr);
std::terminate();
}
result.count_comparisons = result.count_equal + result.count_greater + result.count_less;
active_result = nullptr;
return result;
}
void populate(const populate_function& f);
};

View file

@ -1,13 +0,0 @@
#include "View.h"
#include <raylibs/raygui.h>
void View::draw()
{
BeginDrawing();
ClearBackground(GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR)));
EndDrawing();
}
void View::update()
{
}

View file

@ -1,43 +0,0 @@
#pragma once
#include "raylib.h"
#include <types.hpp>
class View
{
friend class ViewManager;
public:
View(rectu rect) : m_rect(rect) {}
virtual ~View() = default;
virtual void draw();
virtual void update();
virtual void onMouseDown(vec2d mousePos) {}
virtual void onMouseUp(vec2d mousePos) {}
virtual void onMouseMove(vec2d mousePos) {}
virtual void onKeyDown(int key) {}
virtual void onKeyUp(int key) {}
virtual void onKeyPress(int key) {}
virtual void onFocus() {}
virtual void onBlur() {}
virtual void onResize(vec2d factor)
{
m_rect.width = static_cast<rectu::type>(static_cast<float>(m_rect.width) * factor.x);
m_rect.height = static_cast<rectu::type>(static_cast<float>(m_rect.height) * factor.y);
}
vec2u getPosition() const { return {m_rect.x, m_rect.y}; }
vec2u getSize() const { return {m_rect.width, m_rect.height}; }
const rectu& getRect() const { return m_rect; }
void setPosition(vec2u pos) { m_rect.x = pos.x; m_rect.y = pos.y; }
void setSize(vec2u size) { m_rect.width = size.x; m_rect.height = size.y; }
void setRect(rectu &rect) { m_rect = rect; }
virtual void Resize(float multiplier)
{
m_rect.width = static_cast<rectu::type>(static_cast<float>(m_rect.width) * multiplier);
m_rect.height = static_cast<rectu::type>(static_cast<float>(m_rect.height) * multiplier);
}
private:
rectu m_rect;
};

View file

@ -1,21 +0,0 @@
#include "ViewManager.h"
ViewManager::ViewManager()
{
m_viewportSize = { GetScreenWidth(), GetScreenHeight() };
m_mainView = new View({ 0, 0, m_viewportSize.x, m_viewportSize.y });
}
void ViewManager::update()
{
if (IsWindowResized())
{
m_viewportSize = { GetScreenWidth(), GetScreenHeight() };
m_mainView->onResize({ static_cast<float>(m_viewportSize.x), static_cast<float>(m_viewportSize.y) });
}
m_mainView->update();
}
void ViewManager::draw()
{
}

View file

@ -1,16 +0,0 @@
#pragma once
#include "View.h"
#include <vector>
#include <types.hpp>
class ViewManager
{
vec2u m_viewportSize;
public:
ViewManager();
~ViewManager();
void update();
void draw();
private:
View* m_mainView;
};

27
src/internal_script.hpp Normal file
View file

@ -0,0 +1,27 @@
#pragma once
inline const char* std_intern_sorting_script = R"(
-- bubble sort
function bubble_sort()
isSorted = false
while isSorted == false do
movedElements = 0
for x=1, list:size(), 1 do
if list:greater(x, x+1) then
movedElements = movedElements + 1
list:swap(x, x+1)
end
end
if movedElements == 0 then
isSorted = true
end
end
end
function do_nothing()
end
-- other functions
)";

61
src/lua/safesol.cpp Normal file
View file

@ -0,0 +1,61 @@
#include "safesol.h"
safesol::LuaResultType safesol::script(const std::string& script)
{
sol::load_result result = lua.load(script);
if (!result.valid()) {
sol::error err = result;
std::cout << "Error loading script: " << err.what() << std::endl;
return LuaResultType::LOAD_ERROR;
}
sol::protected_function_result script_result = result();
if (!script_result.valid()) {
sol::error err = script_result;
std::cout << "Error running script: " << err.what() << std::endl;
return LuaResultType::SCRIPT_ERROR;
}
return LuaResultType::SUCCESS;
}
safesol::LuaResultType safesol::script(const char* script)
{
sol::load_result result = lua.load(script);
if (!result.valid()) {
sol::error err = result;
std::cout << "Error loading script: " << err.what() << std::endl;
return LuaResultType::LOAD_ERROR;
}
sol::protected_function_result script_result = result();
if (!script_result.valid()) {
sol::error err = script_result;
std::cout << "Error running script: " << err.what() << std::endl;
return LuaResultType::SCRIPT_ERROR;
}
return LuaResultType::SUCCESS;
}
safesol::LuaResultType safesol::load(const std::string& file)
{
sol::load_result result = lua.load_file(file);
if (!result.valid()) {
sol::error err = result;
std::cout << "Error loading file: " << err.what() << std::endl;
return LuaResultType::LOAD_ERROR;
}
sol::protected_function_result script_result = result();
if (!script_result.valid()) {
sol::error err = script_result;
std::cout << "Error running script: " << err.what() << std::endl;
return LuaResultType::SCRIPT_ERROR;
}
return LuaResultType::SUCCESS;
}

55
src/lua/safesol.h Normal file
View file

@ -0,0 +1,55 @@
#pragma once
#include <std.hpp>
#include <sol/sol.hpp>
class safesol
{
public:
enum class LuaResultType : u8
{
SUCCESS = 0,
LOAD_ERROR = 1,
SCRIPT_ERROR,
RUN_ERROR,
UNKNOWN_ERROR
};
sol::state lua;
LuaResultType script(const std::string& script);
LuaResultType script(const char* script);
LuaResultType load(const std::string& file);
template<typename ...Args>
sol::protected_function_result default_caller(const sol::protected_function& function, Args&&... args)
{
return function(std::forward<Args>(args)...);
}
template<typename ...Args>
LuaResultType run(const std::string& function_name, Args&&... args)
{
return run_on_caller(function_name, default_caller, std::forward<Args>(args)...);
}
template<typename ...Args, typename Caller = std::function<sol::protected_function_result(const sol::protected_function&, Args&&...)>>
LuaResultType run_on_caller(const std::string& function_name, const Caller& caller, Args&&... args)
{
auto function = lua[function_name];
if (!function.valid()) {
std::cout << "Error: function " << function_name << " not found" << std::endl;
return LuaResultType::RUN_ERROR;
}
auto result = caller(function, std::forward<Args>(args)...);
if (!result.valid()) {
sol::error err = result;
std::cout << "Error running function " << function_name << ": " << err.what() << std::endl;
return LuaResultType::RUN_ERROR;
}
return LuaResultType::SUCCESS;
}
};

View file

@ -6,8 +6,14 @@
#include "gui/drawing_helper.hpp"
#define RESOURCES_PATH "G:\\School\\Belegarbeit\\sortiva\\res\\"
#define RESOURCES_PATH "G:/School/Belegarbeit/sortiva/res/"
#define SETTINGS_PATH "./.config.cfg"
#define NO_GUI
#ifndef NO_GUI
int screenWidth = 1280;
int screenHeight = 720;
@ -23,13 +29,77 @@ GAME_STATES gameState = SVA_STATE_TITLE;
void UpdateDrawFrame(); // Update and Draw one frame
#include "gui/themes/dark.h"
#include <filesystem>
#include "gui/Views/ViewManager.h"
#endif
#include <filesystem>
#ifdef NO_GUI
#include "SortingTester.h"
#endif
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<u64> dis(0, 10);
void populate(size_t index, u64& value)
{
value = dis(gen);
}
int main(int argc, char** argv)
{
sva_console_init();
#ifdef NO_GUI
std::cout << "Sortiva - Sorting Algorithm Visualizer" << std::endl;
std::cout << "No GUI mode" << std::endl;
SortingTester tester;
tester.populate( populate );
tester.load_internal();
SortingTester::run_result result = tester.run("bubble_sort");
std::cout << "Time: " << result.timer.seconds << " seconds" << std::endl;
std::cout << "Difftime: " << result.timer.difftime << std::endl;
std::cout << "Count swaps: " << result.count_swaps << std::endl;
std::cout << "Count comparisons: " << result.count_comparisons << std::endl;
std::cout << "\tCount greater: " << result.count_greater << std::endl;
std::cout << "\tCount less: " << result.count_less << std::endl;
std::cout << "\tCount equal: " << result.count_equal << std::endl;
std::cout << "\n\n";
result = tester.run("do_nothing");
std::cout << "Time: " << result.timer.seconds << " seconds" << std::endl;
std::cout << "Difftime: " << result.timer.difftime << std::endl;
std::cout << "Count swaps: " << result.count_swaps << std::endl;
std::cout << "Count comparisons: " << result.count_comparisons << std::endl;
std::cout << "\tCount greater: " << result.count_greater << std::endl;
std::cout << "\tCount less: " << result.count_less << std::endl;
std::cout << "\tCount equal: " << result.count_equal << "\n\n";
std::cout << "\nPress any key to exit..." << std::endl;
getchar();
return 0;
#endif
#ifndef NO_GUI
if(!DirectoryExists(RESOURCES_PATH))
{
std::cerr << "Resources folder not found!" << std::endl;
@ -62,9 +132,11 @@ int main(int argc, char** argv)
UpdateDrawFrame();
}
CloseWindow();
#endif
return 0;
}
#ifndef NO_GUI
//----------------------------------------------------------------------------------
// Render Functions
//----------------------------------------------------------------------------------
@ -150,3 +222,5 @@ void RenderGameplayState()
}
}
#endif