From 9d148c315900c8dbf59cdc851d27774f70145be9 Mon Sep 17 00:00:00 2001 From: Scott Doxey Date: Thu, 22 Aug 2024 17:59:00 -0400 Subject: [PATCH] Switched to a header only library. --- bin/test.sh | 2 +- includes/RhythmGameUtilities/Audio.cpp | 53 ------ includes/RhythmGameUtilities/Audio.h | 18 -- includes/RhythmGameUtilities/Audio.hpp | 61 ++++++ includes/RhythmGameUtilities/Parsers.cpp | 114 ----------- includes/RhythmGameUtilities/Parsers.h | 42 ---- includes/RhythmGameUtilities/Parsers.hpp | 145 ++++++++++++++ .../RhythmGameUtilities.cpp | 6 +- includes/RhythmGameUtilities/Utilities.h | 63 ------ .../{Utilities.cpp => Utilities.hpp} | 180 ++++++++++-------- tests/RhythmGameUtilities/Audio.cpp | 2 +- tests/RhythmGameUtilities/Parsers.cpp | 2 +- tests/RhythmGameUtilities/Utilities.cpp | 2 +- 13 files changed, 310 insertions(+), 380 deletions(-) delete mode 100644 includes/RhythmGameUtilities/Audio.cpp delete mode 100644 includes/RhythmGameUtilities/Audio.h create mode 100644 includes/RhythmGameUtilities/Audio.hpp delete mode 100644 includes/RhythmGameUtilities/Parsers.cpp delete mode 100644 includes/RhythmGameUtilities/Parsers.h create mode 100644 includes/RhythmGameUtilities/Parsers.hpp delete mode 100644 includes/RhythmGameUtilities/Utilities.h rename includes/RhythmGameUtilities/{Utilities.cpp => Utilities.hpp} (63%) diff --git a/bin/test.sh b/bin/test.sh index 35a0737..24d6622 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -18,7 +18,7 @@ COLOROFF=$(tput sgr0) printf " - Running %s " "${FILE}" - if ! g++ -std=c++17 -o test "${FILE}" ./includes/RhythmGameUtilities/RhythmGameUtilities.cpp -Iincludes; then + if ! g++ -std=c++17 -o test "${FILE}" -Iincludes; then printf "%sCOMPILATION FAILED%s\n" "${REDON}" "${COLOROFF}" exit 1 fi diff --git a/includes/RhythmGameUtilities/Audio.cpp b/includes/RhythmGameUtilities/Audio.cpp deleted file mode 100644 index 991626b..0000000 --- a/includes/RhythmGameUtilities/Audio.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include - -#include - -#include "Audio.h" - -namespace RhythmGameUtilities -{ - -int **ConvertSamplesToWaveform(float *samples, int size, int width, int height) -{ - auto waveform = new int *[width]; - - auto step = floor(size / width); - auto amp = height / 2; - - for (auto x = 0; x < width; x += 1) - { - waveform[x] = new int[height]; - - auto min = 1.0f; - auto max = -1.0f; - - for (auto j = 0; j < step; j += 1) - { - auto index = (int)(x * step + j); - - auto datum = samples[index]; - - if (datum < min) - { - min = datum; - } - - if (datum > max) - { - max = datum; - } - } - - auto minY = (int)((1 + min) * amp); - auto maxY = (int)((1 + max) * amp); - - for (auto y = 0; y < height; y += 1) - { - waveform[x][y] = y >= minY && y <= maxY ? 1 : 0; - } - } - - return waveform; -} - -} // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/Audio.h b/includes/RhythmGameUtilities/Audio.h deleted file mode 100644 index 442c482..0000000 --- a/includes/RhythmGameUtilities/Audio.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#ifdef _WIN32 -#define PACKAGE_API __declspec(dllexport) -#else -#define PACKAGE_API -#endif - -namespace RhythmGameUtilities -{ - -extern "C" -{ - PACKAGE_API int **ConvertSamplesToWaveform(float *samples, int size, - int width, int height); -} - -} // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/Audio.hpp b/includes/RhythmGameUtilities/Audio.hpp new file mode 100644 index 0000000..6d789da --- /dev/null +++ b/includes/RhythmGameUtilities/Audio.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include + +#ifdef _WIN32 +#define PACKAGE_API __declspec(dllexport) +#else +#define PACKAGE_API +#endif + +namespace RhythmGameUtilities +{ + +extern "C" +{ + PACKAGE_API int **ConvertSamplesToWaveform(float *samples, int size, + int width, int height) + { + auto waveform = new int *[width]; + + auto step = floor(size / width); + auto amp = height / 2; + + for (auto x = 0; x < width; x += 1) + { + waveform[x] = new int[height]; + + auto min = 1.0f; + auto max = -1.0f; + + for (auto j = 0; j < step; j += 1) + { + auto index = (int)(x * step + j); + + auto datum = samples[index]; + + if (datum < min) + { + min = datum; + } + + if (datum > max) + { + max = datum; + } + } + + auto minY = (int)((1 + min) * amp); + auto maxY = (int)((1 + max) * amp); + + for (auto y = 0; y < height; y += 1) + { + waveform[x][y] = y >= minY && y <= maxY ? 1 : 0; + } + } + + return waveform; + } +} + +} // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/Parsers.cpp b/includes/RhythmGameUtilities/Parsers.cpp deleted file mode 100644 index 61798f8..0000000 --- a/includes/RhythmGameUtilities/Parsers.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include -#include -#include - -#include "Parsers.h" -#include "Utilities.h" -#include - -namespace RhythmGameUtilities -{ - -std::regex CHART_SECTION_PATTERN("\\[([a-z]+)\\]\\s*\\{([^\\}]+)\\}", - std::regex_constants::icase); - -std::regex CHART_SECTION_LINE_PATTERN("([^=]+)\\s*=([^\\r\\n]+)"); - -std::regex JSON_VALUE_PATTERN("(\"[^\"]+\"|\\S+)"); - -std::vector ParseSectionsFromChart(const char *contents) -{ - auto matches = FindAllMatches(contents, CHART_SECTION_PATTERN); - - auto sections = std::vector(); - - for (auto i = 0; i < matches.size(); i += 1) - { - auto parts = FindMatchGroups(matches[i].c_str(), CHART_SECTION_PATTERN); - - if (parts.size() < 3) - { - continue; - } - - ChartSection section; - - section.name = parts[1].c_str(); - - auto lines = - FindAllMatches(parts[2].c_str(), CHART_SECTION_LINE_PATTERN); - - section.lines = - std::vector>>(); - - for (auto j = 0; j < lines.size(); j += 1) - { - auto parts = Split(lines[j].c_str(), '='); - - auto key = Trim(parts[0].c_str()); - auto value = Trim(parts[1].c_str()); - - auto values = FindAllMatches(value.c_str(), JSON_VALUE_PATTERN); - - for (auto k = 0; k < values.size(); k += 1) - { - values[k] = - std::regex_replace(values[k], std::regex("^\"|\"$"), ""); - } - - section.lines.push_back(std::make_pair(key, values)); - } - - sections.push_back(section); - } - - return sections; -} - -ChartSectionInternal *ParseSectionsFromChartInternal(const char *contents, - int *outSize) -{ - auto internalSections = ParseSectionsFromChart(contents); - - *outSize = internalSections.size(); - - auto sections = (ChartSectionInternal *)malloc( - internalSections.size() * sizeof(ChartSectionInternal)); - - for (auto i = 0; i < internalSections.size(); i += 1) - { - sections[i].name = - (char *)malloc(strlen(internalSections[i].name.c_str()) + 1); - strcpy(sections[i].name, internalSections[i].name.c_str()); - - sections[i].lines = (KeyValuePairInternal *)malloc( - internalSections[i].lines.size() * sizeof(KeyValuePairInternal)); - - sections[i].lineCount = internalSections[i].lines.size(); - - for (auto j = 0; j < internalSections[i].lines.size(); j += 1) - { - sections[i].lines[j].key = (char *)malloc( - strlen(internalSections[i].lines[j].first.c_str()) + 1); - strcpy(sections[i].lines[j].key, - internalSections[i].lines[j].first.c_str()); - - auto values = internalSections[i].lines[j].second; - - for (auto k = 0; k < values.size(); k += 1) - { - sections[i].lines[j].values[k] = - (char *)malloc(strlen(values[k].c_str()) + 1); - strcpy(sections[i].lines[j].values[k], values[k].c_str()); - } - - sections[i].lines[j].valueCount = values.size(); - } - } - - return sections; -} - -} // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/Parsers.h b/includes/RhythmGameUtilities/Parsers.h deleted file mode 100644 index 2c0a3cb..0000000 --- a/includes/RhythmGameUtilities/Parsers.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include - -#ifdef _WIN32 -#define PACKAGE_API __declspec(dllexport) -#else -#define PACKAGE_API -#endif - -namespace RhythmGameUtilities -{ - -typedef struct -{ - char *key; - char *values[10]; - int valueCount; -} KeyValuePairInternal; - -typedef struct -{ - char *name; - KeyValuePairInternal *lines; - int lineCount; -} ChartSectionInternal; - -typedef struct -{ - std::string name; - std::vector>> lines; -} ChartSection; - -std::vector ParseSectionsFromChart(const char *contents); - -extern "C" -{ - PACKAGE_API ChartSectionInternal * - ParseSectionsFromChartInternal(const char *contents, int *outSize); -} - -} // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/Parsers.hpp b/includes/RhythmGameUtilities/Parsers.hpp new file mode 100644 index 0000000..17bdd97 --- /dev/null +++ b/includes/RhythmGameUtilities/Parsers.hpp @@ -0,0 +1,145 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "Utilities.hpp" + +#ifdef _WIN32 +#define PACKAGE_API __declspec(dllexport) +#else +#define PACKAGE_API +#endif + +namespace RhythmGameUtilities +{ + +typedef struct +{ + char *key; + char *values[10]; + int valueCount; +} KeyValuePairInternal; + +typedef struct +{ + char *name; + KeyValuePairInternal *lines; + int lineCount; +} ChartSectionInternal; + +typedef struct +{ + std::string name; + std::vector>> lines; +} ChartSection; + +std::regex CHART_SECTION_PATTERN("\\[([a-z]+)\\]\\s*\\{([^\\}]+)\\}", + std::regex_constants::icase); + +std::regex CHART_SECTION_LINE_PATTERN("([^=]+)\\s*=([^\\r\\n]+)"); + +std::regex JSON_VALUE_PATTERN("(\"[^\"]+\"|\\S+)"); + +std::vector ParseSectionsFromChart(const char *contents) +{ + auto matches = FindAllMatches(contents, CHART_SECTION_PATTERN); + + auto sections = std::vector(); + + for (auto i = 0; i < matches.size(); i += 1) + { + auto parts = FindMatchGroups(matches[i].c_str(), CHART_SECTION_PATTERN); + + if (parts.size() < 3) + { + continue; + } + + ChartSection section; + + section.name = parts[1].c_str(); + + auto lines = + FindAllMatches(parts[2].c_str(), CHART_SECTION_LINE_PATTERN); + + section.lines = + std::vector>>(); + + for (auto j = 0; j < lines.size(); j += 1) + { + auto parts = Split(lines[j].c_str(), '='); + + auto key = Trim(parts[0].c_str()); + auto value = Trim(parts[1].c_str()); + + auto values = FindAllMatches(value.c_str(), JSON_VALUE_PATTERN); + + for (auto k = 0; k < values.size(); k += 1) + { + values[k] = + std::regex_replace(values[k], std::regex("^\"|\"$"), ""); + } + + section.lines.push_back(std::make_pair(key, values)); + } + + sections.push_back(section); + } + + return sections; +} + +extern "C" +{ + PACKAGE_API + ChartSectionInternal *ParseSectionsFromChartInternal(const char *contents, + int *outSize) + { + auto internalSections = ParseSectionsFromChart(contents); + + *outSize = internalSections.size(); + + auto sections = (ChartSectionInternal *)malloc( + internalSections.size() * sizeof(ChartSectionInternal)); + + for (auto i = 0; i < internalSections.size(); i += 1) + { + sections[i].name = + (char *)malloc(strlen(internalSections[i].name.c_str()) + 1); + strcpy(sections[i].name, internalSections[i].name.c_str()); + + sections[i].lines = (KeyValuePairInternal *)malloc( + internalSections[i].lines.size() * + sizeof(KeyValuePairInternal)); + + sections[i].lineCount = internalSections[i].lines.size(); + + for (auto j = 0; j < internalSections[i].lines.size(); j += 1) + { + sections[i].lines[j].key = (char *)malloc( + strlen(internalSections[i].lines[j].first.c_str()) + 1); + strcpy(sections[i].lines[j].key, + internalSections[i].lines[j].first.c_str()); + + auto values = internalSections[i].lines[j].second; + + for (auto k = 0; k < values.size(); k += 1) + { + sections[i].lines[j].values[k] = + (char *)malloc(strlen(values[k].c_str()) + 1); + strcpy(sections[i].lines[j].values[k], values[k].c_str()); + } + + sections[i].lines[j].valueCount = values.size(); + } + } + + return sections; + } +} + +} // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/RhythmGameUtilities.cpp b/includes/RhythmGameUtilities/RhythmGameUtilities.cpp index 023e787..361d35f 100644 --- a/includes/RhythmGameUtilities/RhythmGameUtilities.cpp +++ b/includes/RhythmGameUtilities/RhythmGameUtilities.cpp @@ -1,5 +1,5 @@ // RhythmGameUtilities.cpp -#include "Audio.cpp" -#include "Parsers.cpp" -#include "Utilities.cpp" +#include "Audio.hpp" +#include "Parsers.hpp" +#include "Utilities.hpp" diff --git a/includes/RhythmGameUtilities/Utilities.h b/includes/RhythmGameUtilities/Utilities.h deleted file mode 100644 index 6c376f7..0000000 --- a/includes/RhythmGameUtilities/Utilities.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "Structs/BeatBar.h" -#include "Structs/Note.h" - -#ifdef _WIN32 -#define PACKAGE_API __declspec(dllexport) -#else -#define PACKAGE_API -#endif - -namespace RhythmGameUtilities -{ - -extern "C" -{ - PACKAGE_API float ConvertTickToPosition(float tick, int resolution); - - PACKAGE_API int ConvertSecondsToTicksInternal(float seconds, int resolution, - int *bpmChangesKeys, - int *bpmChangesValues, - int bpmChangesSize); - - PACKAGE_API bool IsOnTheBeat(float bpm, float currentTime); - - PACKAGE_API int RoundUpToTheNearestMultiplier(int value, int multiplier); - - PACKAGE_API float Lerp(float a, float b, float t); - - PACKAGE_API float InverseLerp(float a, float b, float v); - - PACKAGE_API BeatBar * - CalculateBeatBarsInternal(int *bpmChangesKeys, int *bpmChangesValues, - int bpmChangesSize, int resolution, int ts, - bool includeHalfNotes, int *outSize); -} - -int ConvertSecondsToTicks(float seconds, int resolution, - std::map bpmChanges); - -std::string Trim(const char *contents); - -std::vector Split(const char *contents, const char delimiter); - -std::vector CalculateBeatBars(std::map bpmChanges, - int resolution, int ts, - bool includeHalfNotes); - -std::vector> -GenerateAdjacentKeyPairs(std::map keyValuePairs); - -std::vector FindAllMatches(const char *contents, - std::regex pattern); - -std::vector FindMatchGroups(const char *contents, - std::regex pattern); - -} // namespace RhythmGameUtilities diff --git a/includes/RhythmGameUtilities/Utilities.cpp b/includes/RhythmGameUtilities/Utilities.hpp similarity index 63% rename from includes/RhythmGameUtilities/Utilities.cpp rename to includes/RhythmGameUtilities/Utilities.hpp index 7549208..e044ab0 100644 --- a/includes/RhythmGameUtilities/Utilities.cpp +++ b/includes/RhythmGameUtilities/Utilities.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -7,21 +9,20 @@ #include #include -#include "Utilities.h" - #include "Structs/BeatBar.h" #include "Structs/Note.h" +#ifdef _WIN32 +#define PACKAGE_API __declspec(dllexport) +#else +#define PACKAGE_API +#endif + namespace RhythmGameUtilities { const float SECONDS_PER_MINUTE = 60.0f; -float ConvertTickToPosition(float tick, int resolution) -{ - return tick / resolution; -} - int ConvertSecondsToTicks(float seconds, int resolution, std::map bpmChanges) { @@ -55,64 +56,27 @@ int ConvertSecondsToTicks(float seconds, int resolution, return totalTicks; } -int ConvertSecondsToTicksInternal(float seconds, int resolution, - int *bpmChangesKeys, int *bpmChangesValues, - int bpmChangesSize) +std::vector> +GenerateAdjacentKeyPairs(std::map keyValuePairs) { - std::map bpmChanges; + auto adjacentKeyPairs = std::vector>(); + + std::vector keys; - for (auto i = 0; i < bpmChangesSize; i += 1) + for (auto item : keyValuePairs) { - bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; + keys.push_back(item.first); } - return ConvertSecondsToTicks(seconds, resolution, bpmChanges); -} - -bool IsOnTheBeat(float bpm, float currentTime) -{ - auto beatInterval = SECONDS_PER_MINUTE / bpm; - - auto beatFraction = currentTime / beatInterval; - - auto difference = std::abs(beatFraction - std::round(beatFraction)); - - auto result = difference < 0.05f; - - return result; -} - -int RoundUpToTheNearestMultiplier(int value, int multiplier) -{ - return (int)ceil((float)value / multiplier) * multiplier; -} - -float Lerp(float a, float b, float t) { return (1 - t) * a + b * t; } - -float InverseLerp(float a, float b, float v) -{ - return std::clamp(((v - a) / (b - a)), 0.0f, 1.0f); -} - -std::string Trim(const char *contents) -{ - return std::regex_replace(contents, std::regex("^\\s+|\\s+$"), ""); -} - -std::vector Split(const char *contents, const char delimiter) -{ - auto parts = std::vector(); - - std::stringstream input(contents); - - std::string str; + std::vector sortedKeys(keys.begin(), keys.end()); - while (std::getline(input, str, delimiter)) + for (auto i = 0; i < size(sortedKeys) - 1; i += 1) { - parts.push_back(str); + adjacentKeyPairs.push_back( + std::make_tuple(sortedKeys[i], sortedKeys[i + 1])); } - return parts; + return adjacentKeyPairs; } std::vector CalculateBeatBars(std::map bpmChanges, @@ -143,54 +107,104 @@ std::vector CalculateBeatBars(std::map bpmChanges, return beatBars; } -BeatBar *CalculateBeatBarsInternal(int *bpmChangesKeys, int *bpmChangesValues, - int bpmChangesSize, int resolution, int ts, - bool includeHalfNotes, int *outSize) +extern "C" { - auto bpmChanges = std::map(); + PACKAGE_API float ConvertTickToPosition(float tick, int resolution) + { + return tick / resolution; + } - for (auto i = 0; i < bpmChangesSize; i += 1) + PACKAGE_API int ConvertSecondsToTicksInternal(float seconds, int resolution, + int *bpmChangesKeys, + int *bpmChangesValues, + int bpmChangesSize) { - bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; + std::map bpmChanges; + + for (auto i = 0; i < bpmChangesSize; i += 1) + { + bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; + } + + return ConvertSecondsToTicks(seconds, resolution, bpmChanges); } - auto internalBeatBars = - CalculateBeatBars(bpmChanges, resolution, ts, includeHalfNotes); + PACKAGE_API bool IsOnTheBeat(float bpm, float currentTime) + { + auto beatInterval = SECONDS_PER_MINUTE / bpm; + + auto beatFraction = currentTime / beatInterval; - *outSize = internalBeatBars.size(); + auto difference = std::abs(beatFraction - std::round(beatFraction)); - auto beatBars = - (BeatBar *)malloc(internalBeatBars.size() * sizeof(BeatBar)); + auto result = difference < 0.05f; - for (auto i = 0; i < internalBeatBars.size(); i += 1) + return result; + } + + PACKAGE_API int RoundUpToTheNearestMultiplier(int value, int multiplier) { - beatBars[i] = internalBeatBars[i]; + return (int)ceil((float)value / multiplier) * multiplier; } - return beatBars; + PACKAGE_API float Lerp(float a, float b, float t) + { + return (1 - t) * a + b * t; + } + + PACKAGE_API float InverseLerp(float a, float b, float v) + { + return std::clamp(((v - a) / (b - a)), 0.0f, 1.0f); + } + + PACKAGE_API BeatBar * + CalculateBeatBarsInternal(int *bpmChangesKeys, int *bpmChangesValues, + int bpmChangesSize, int resolution, int ts, + bool includeHalfNotes, int *outSize) + { + auto bpmChanges = std::map(); + + for (auto i = 0; i < bpmChangesSize; i += 1) + { + bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; + } + + auto internalBeatBars = + CalculateBeatBars(bpmChanges, resolution, ts, includeHalfNotes); + + *outSize = internalBeatBars.size(); + + auto beatBars = + (BeatBar *)malloc(internalBeatBars.size() * sizeof(BeatBar)); + + for (auto i = 0; i < internalBeatBars.size(); i += 1) + { + beatBars[i] = internalBeatBars[i]; + } + + return beatBars; + } } -std::vector> -GenerateAdjacentKeyPairs(std::map keyValuePairs) +std::string Trim(const char *contents) { - auto adjacentKeyPairs = std::vector>(); + return std::regex_replace(contents, std::regex("^\\s+|\\s+$"), ""); +} - std::vector keys; +std::vector Split(const char *contents, const char delimiter) +{ + auto parts = std::vector(); - for (auto item : keyValuePairs) - { - keys.push_back(item.first); - } + std::stringstream input(contents); - std::vector sortedKeys(keys.begin(), keys.end()); + std::string str; - for (auto i = 0; i < size(sortedKeys) - 1; i += 1) + while (std::getline(input, str, delimiter)) { - adjacentKeyPairs.push_back( - std::make_tuple(sortedKeys[i], sortedKeys[i + 1])); + parts.push_back(str); } - return adjacentKeyPairs; + return parts; } std::vector FindAllMatches(const char *contents, diff --git a/tests/RhythmGameUtilities/Audio.cpp b/tests/RhythmGameUtilities/Audio.cpp index 332dbc1..9fdd919 100644 --- a/tests/RhythmGameUtilities/Audio.cpp +++ b/tests/RhythmGameUtilities/Audio.cpp @@ -1,7 +1,7 @@ #include #include -#include "RhythmGameUtilities/Audio.h" +#include "RhythmGameUtilities/Audio.hpp" using namespace RhythmGameUtilities; diff --git a/tests/RhythmGameUtilities/Parsers.cpp b/tests/RhythmGameUtilities/Parsers.cpp index 1586d8f..eb7f8c0 100644 --- a/tests/RhythmGameUtilities/Parsers.cpp +++ b/tests/RhythmGameUtilities/Parsers.cpp @@ -2,7 +2,7 @@ #include #include -#include "RhythmGameUtilities/Parsers.h" +#include "RhythmGameUtilities/Parsers.hpp" using namespace RhythmGameUtilities; diff --git a/tests/RhythmGameUtilities/Utilities.cpp b/tests/RhythmGameUtilities/Utilities.cpp index 6b290dd..0a62f0d 100644 --- a/tests/RhythmGameUtilities/Utilities.cpp +++ b/tests/RhythmGameUtilities/Utilities.cpp @@ -3,7 +3,7 @@ #include #include -#include "RhythmGameUtilities/Utilities.h" +#include "RhythmGameUtilities/Utilities.hpp" using namespace RhythmGameUtilities;