diff --git a/CMakeLists.txt b/CMakeLists.txt index c01e65d..8a017a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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,14 +122,11 @@ 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} ) - + # --------------- # RAYLIB # --------------- @@ -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} +) diff --git a/include/Profiling/Timer.hpp b/include/Profiling/Timer.hpp new file mode 100644 index 0000000..30094e9 --- /dev/null +++ b/include/Profiling/Timer.hpp @@ -0,0 +1,106 @@ +#pragma once +#include +#include +#include +#include + +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 out; + std::optional 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(total_time) / CLOCKS_PER_SEC; + result.value()->difftime = static_cast(total_time) / CLOCKS_PER_SEC; + } + if (out) + { + *out.value() << static_cast(total_time) / CLOCKS_PER_SEC << " seconds.\n"; + *out.value() << "Total time = " << static_cast(total_time) / CLOCKS_PER_SEC << std::endl; + } + } + + ~Timer() { + lap(); + } +}; \ No newline at end of file diff --git a/include/list.hpp b/include/list.hpp new file mode 100644 index 0000000..a580939 --- /dev/null +++ b/include/list.hpp @@ -0,0 +1,167 @@ +#pragma once +#include +#include +#include +#include +#include + +/** + * @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 +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(size)) + , size_(size) { + } + + /** + * @brief Constructs a List from an initializer list + * @param init The initializer list containing initial values + */ + List(std::initializer_list init) + : data_(std::make_unique(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 other_lock(other.mutex_); + data_ = std::make_unique(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 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 other_lock(other.mutex_); + data_ = std::make_unique(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 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 data_; ///< Underlying array storage + std::size_t size_; ///< Number of elements in the array + mutable std::mutex mutex_; ///< Mutex for thread-safe access +}; \ No newline at end of file diff --git a/include/std.hpp b/include/std.hpp new file mode 100644 index 0000000..7e44003 --- /dev/null +++ b/include/std.hpp @@ -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 diff --git a/include/types.hpp b/include/types.hpp index 79cdd54..58d29b7 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include @@ -84,3 +84,4 @@ typedef TRect rectd; typedef TRect rectu; typedef TRect recti; +#include "list.hpp" \ No newline at end of file diff --git a/src/Renderer.cpp b/src/Renderer.cpp new file mode 100644 index 0000000..ca38bab --- /dev/null +++ b/src/Renderer.cpp @@ -0,0 +1 @@ +#include "Renderer.h" diff --git a/src/Renderer.h b/src/Renderer.h new file mode 100644 index 0000000..fa8c6d8 --- /dev/null +++ b/src/Renderer.h @@ -0,0 +1,7 @@ +#pragma once + +class Renderer +{ +public: + +}; diff --git a/src/SortingTester.cpp b/src/SortingTester.cpp new file mode 100644 index 0000000..65ec7a5 --- /dev/null +++ b/src/SortingTester.cpp @@ -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("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]); +} diff --git a/src/SortingTester.h b/src/SortingTester.h new file mode 100644 index 0000000..d2dff5f --- /dev/null +++ b/src/SortingTester.h @@ -0,0 +1,152 @@ +#pragma once +#define SVA_LIST_CALLBACKS +#include + +#include +#include "lua/safesol.h" +#include + + +class SortingTester +{ + List list; + + safesol lua; + + Timer timer = Timer(Timer::State::paused); + + using populate_function = std::function; + + template + 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)...); + 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 + 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, + this, + std::placeholders::_1, + std::forward(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(runstate) << std::endl; + exit(static_cast(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); +}; diff --git a/src/gui/Views/View.cpp b/src/gui/Views/View.cpp deleted file mode 100644 index 6755117..0000000 --- a/src/gui/Views/View.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "View.h" -#include - -void View::draw() -{ - BeginDrawing(); - ClearBackground(GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); - EndDrawing(); -} - -void View::update() -{ -} diff --git a/src/gui/Views/View.h b/src/gui/Views/View.h deleted file mode 100644 index 033b907..0000000 --- a/src/gui/Views/View.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "raylib.h" -#include - -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(static_cast(m_rect.width) * factor.x); - m_rect.height = static_cast(static_cast(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(static_cast(m_rect.width) * multiplier); - m_rect.height = static_cast(static_cast(m_rect.height) * multiplier); - } -private: - rectu m_rect; -}; diff --git a/src/gui/Views/ViewManager.cpp b/src/gui/Views/ViewManager.cpp deleted file mode 100644 index 8feb8f3..0000000 --- a/src/gui/Views/ViewManager.cpp +++ /dev/null @@ -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(m_viewportSize.x), static_cast(m_viewportSize.y) }); - } - m_mainView->update(); -} - -void ViewManager::draw() -{ -} diff --git a/src/gui/Views/ViewManager.h b/src/gui/Views/ViewManager.h deleted file mode 100644 index 7ba2b71..0000000 --- a/src/gui/Views/ViewManager.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include "View.h" -#include -#include - -class ViewManager -{ - vec2u m_viewportSize; -public: - ViewManager(); - ~ViewManager(); - void update(); - void draw(); -private: - View* m_mainView; -}; diff --git a/src/internal_script.hpp b/src/internal_script.hpp new file mode 100644 index 0000000..3814851 --- /dev/null +++ b/src/internal_script.hpp @@ -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 + + +)"; \ No newline at end of file diff --git a/src/lua/safesol.cpp b/src/lua/safesol.cpp new file mode 100644 index 0000000..fa9849b --- /dev/null +++ b/src/lua/safesol.cpp @@ -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; +} diff --git a/src/lua/safesol.h b/src/lua/safesol.h new file mode 100644 index 0000000..cfc23d3 --- /dev/null +++ b/src/lua/safesol.h @@ -0,0 +1,55 @@ +#pragma once +#include +#include + +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 + sol::protected_function_result default_caller(const sol::protected_function& function, Args&&... args) + { + return function(std::forward(args)...); + } + + template + LuaResultType run(const std::string& function_name, Args&&... args) + { + return run_on_caller(function_name, default_caller, std::forward(args)...); + } + + template> + 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)...); + 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; + } +}; diff --git a/src/main.cpp b/src/main.cpp index a993f92..18caba6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 #include "gui/Views/ViewManager.h" +#endif +#include + + +#ifdef NO_GUI +#include "SortingTester.h" +#endif + + +#include + +std::random_device rd; +std::mt19937 gen(rd()); +std::uniform_int_distribution 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 //---------------------------------------------------------------------------------- @@ -149,4 +221,6 @@ void RenderGameplayState() ); } -} \ No newline at end of file +} + +#endif \ No newline at end of file