From 41c2a3bad60c38746cfcc13b411cc8501e241dd4 Mon Sep 17 00:00:00 2001 From: Jerboa <84378622+Jerboa-app@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:48:00 +0100 Subject: [PATCH] Adds AssetStore, TextureAssetStore (#188) * Adds AssetStore, TextureAssetStore Adds ctest verbose output --- .github/workflows/release.yml | 15 ++- include/Util/assetStore.h | 88 ++++++++++++++++++ tests/regression/CMakeLists.txt | 3 +- tests/regression/assets/CMakeLists.txt | 33 +++++++ tests/regression/assets/main.cpp | 22 +++++ tests/regression/assets/main.h | 10 ++ .../assets/resource/texture/HEART.png | Bin 0 -> 6158 bytes .../regression/assets/resource/texture/Pi.png | Bin 0 -> 2664 bytes .../assets/resource/texture/random.png | Bin 0 -> 2587 bytes 9 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 include/Util/assetStore.h create mode 100644 tests/regression/assets/CMakeLists.txt create mode 100644 tests/regression/assets/main.cpp create mode 100644 tests/regression/assets/main.h create mode 100644 tests/regression/assets/resource/texture/HEART.png create mode 100644 tests/regression/assets/resource/texture/Pi.png create mode 100644 tests/regression/assets/resource/texture/random.png diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8fec609b..95f2d53a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -109,7 +109,11 @@ jobs: working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest + run: | + export DISPLAY=:99 + sudo Xvfb :99 -screen 0 800x600x24 & + sleep 5 + MESA_GL_VERSION_OVERRIDE=3.3 ctest --output-on-failure --verbose - name: buildArtifact uses: actions/upload-artifact@v4 @@ -154,7 +158,12 @@ jobs: working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: MESA_GL_VERSION_OVERRIDE=3.3 ctest --exclude-regex Vulkan + run: | + cp *.dll TestAssetStore/ + export DISPLAY=:99 + sudo Xvfb :99 -screen 0 800x600x24 & + sleep 5 + MESA_GL_VERSION_OVERRIDE=3.3 ctest --output-on-failure --verbose --exclude-regex Vulkan - name: buildArtifact uses: actions/upload-artifact@v4 @@ -204,7 +213,7 @@ jobs: working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: MESA_GL_VERSION_OVERRIDE=3.3 ctest --exclude-regex Vulkan + run: MESA_GL_VERSION_OVERRIDE=3.3 ctest --output-on-failure --verbose --exclude-regex Vulkan --exclude-regex assetStore - name: buildArtifact uses: actions/upload-artifact@v4 diff --git a/include/Util/assetStore.h b/include/Util/assetStore.h new file mode 100644 index 00000000..3da7c380 --- /dev/null +++ b/include/Util/assetStore.h @@ -0,0 +1,88 @@ +#ifndef ASSETSTORE_H +#define ASSETSTORE_H + +#include +#include + +#include +#include +#include +#include + +namespace Hop::Util::Assets +{ + template + class AssetStore + { + public: + + AssetStore(std::filesystem::path root) + : root(root) + {} + + void scan() + { + if (std::filesystem::is_directory(root)) + { + scanDirectory(root); + } + }; + + virtual void load(std::filesystem::path assetPath) = 0; + + std::shared_ptr get(std::filesystem::path relative_path) { return assets[relative_path]; } + + typename std::map>::const_iterator begin() { return assets.cbegin(); } + typename std::map>::const_iterator end() { return assets.cend(); } + + protected: + std::filesystem::path root; + std::map> assets; + + virtual bool matchesAssetType(std::filesystem::path file) = 0; + + void scanDirectory(std::filesystem::path dir) + { + for (auto const & entry : std::filesystem::directory_iterator{dir}) + { + if (entry.is_regular_file()) + { + if (matchesAssetType(entry)) { load(entry); } + } + else + { + scanDirectory(entry); + } + } + } + }; + + class TextureAssetStore : public AssetStore + { + public: + + TextureAssetStore(std::filesystem::path root, std::unique_ptr & instance) + : AssetStore(root), instance(instance) + {} + + void load(std::filesystem::path assetPath) + { + std::filesystem::path relative = std::filesystem::relative(assetPath, root); + assets[relative] = instance->createTexture + ( + assetPath.generic_string(), + jGL::Texture::Type::RGBA + ); + }; + + protected: + std::unique_ptr & instance; + + bool matchesAssetType(std::filesystem::path file) + { + static std::vector extensions = {".png"}; + return std::find(extensions.begin(), extensions.end(), file.extension().generic_string()) != extensions.end(); + } + }; +} +#endif /* ASSETSTORE_H */ diff --git a/tests/regression/CMakeLists.txt b/tests/regression/CMakeLists.txt index 31222f4e..995c939a 100644 --- a/tests/regression/CMakeLists.txt +++ b/tests/regression/CMakeLists.txt @@ -1 +1,2 @@ -add_subdirectory(scriptPack) \ No newline at end of file +add_subdirectory(scriptPack) +add_subdirectory(assets) \ No newline at end of file diff --git a/tests/regression/assets/CMakeLists.txt b/tests/regression/assets/CMakeLists.txt new file mode 100644 index 00000000..5d809ddf --- /dev/null +++ b/tests/regression/assets/CMakeLists.txt @@ -0,0 +1,33 @@ +set(OUTPUT_NAME TestAssetStore) + +include_directories(.) + +if (WINDOWS) + if (RELEASE) + # launch as windows, not console app - so cmd does not open as well + add_link_options(-mwindows) + endif () +else() + # so nautilus etc recognise target as executable rather than .so + add_link_options(-no-pie) +endif() + +add_executable(${OUTPUT_NAME} "main.cpp") + +target_link_libraries(${OUTPUT_NAME} Hop) + +set_target_properties(${OUTPUT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${OUTPUT_NAME}") + +file(COPY "resource" DESTINATION "${CMAKE_BINARY_DIR}/${OUTPUT_NAME}/") + +if (TEST_SUITE) + if(WINDOWS) + add_test(NAME assetStore COMMAND "${CMAKE_CROSSCOMPILING_EMULATOR}" "${CMAKE_BINARY_DIR}/${OUTPUT_NAME}/${OUTPUT_NAME}.exe") + else() + add_test(NAME assetStore COMMAND "/${CMAKE_BINARY_DIR}/${OUTPUT_NAME}/${OUTPUT_NAME}") + endif() + set_tests_properties(assetStore PROPERTIES + PASS_REGULAR_EXPRESSION "HEART\.png.*Pi\.png.*random\.png" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/${OUTPUT_NAME}/" + ) +endif() \ No newline at end of file diff --git a/tests/regression/assets/main.cpp b/tests/regression/assets/main.cpp new file mode 100644 index 00000000..afe44d1c --- /dev/null +++ b/tests/regression/assets/main.cpp @@ -0,0 +1,22 @@ +#include "main.h" +#include + +int main(int argc, char ** argv) +{ + + jGL::DesktopDisplay::Config conf; + conf.VULKAN = false; + conf.COCOA_RETINA = false; + + jGL::DesktopDisplay display(glm::ivec2(1,1),"Test TextureAssetStore", conf); + glewInit(); + std::unique_ptr jGLInstance = std::move(std::make_unique(display.getRes())); + Hop::Util::Assets::TextureAssetStore textureStore(std::filesystem::path("resource"), jGLInstance); + textureStore.scan(); + for (auto tex : textureStore) + { + std::cout << tex.first << " "; + } + + return 0; +} diff --git a/tests/regression/assets/main.h b/tests/regression/assets/main.h new file mode 100644 index 00000000..f60ea77a --- /dev/null +++ b/tests/regression/assets/main.h @@ -0,0 +1,10 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include + +#include +#include + +#endif /* MAIN_H */ diff --git a/tests/regression/assets/resource/texture/HEART.png b/tests/regression/assets/resource/texture/HEART.png new file mode 100644 index 0000000000000000000000000000000000000000..9d44ab97cfc2cb61acd666ef9bcdfdd1fcbba86e GIT binary patch literal 6158 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 literal 0 HcmV?d00001 diff --git a/tests/regression/assets/resource/texture/Pi.png b/tests/regression/assets/resource/texture/Pi.png new file mode 100644 index 0000000000000000000000000000000000000000..c811289d59dedac843c4dcec639020b566e87b9c GIT binary patch literal 2664 zcmV-u3YYbXP)430THOLwH7Ib`ofwRNerNg#((e;|1pt2 z)EEP5z=XsY6BB|lAQ~hXf(hjzU>mJG+D0g_TSO>OOIxff*!KFz>DBAzclX|zd(N5P z-ri3#p}_8$ncnX`GjnF<+yQKv1FQf}1{MK}fd#5< zebAw6pHR3SchqbKpXQwsiQh8`uM30yrJ`4Y16jMIEj@ zkpH2s08R#e2b^HioDOd`=6|RofTh5_z>?5HJXALE`uw?crJABw!-{4`m+UQ*;l% zZR|&$>qONL4g%XrAFAw%P8kDk0G7~$UdzCXf#tn^IFf$@zXk3F{scS+>;+~b5yc+? z!;1CgYyz%Ff*$(~>=zjZ&I7JG@=psk^S}P=tMT(0^7kCf?dT})5Td-Q;L+!m>MNG( zsb1k&Fax+bqP-7yi2Ah|MQ;xB2PHeD z6d(9#LtEQ`I|F}b1bA=5dW$@!Xe*YB6m4x*wAGWM09H4&bxXwWTm&4`u-+n%DB6l; zt)eY+0pz@y=Ht~F5%u1vP;arEAJGO)mZR5~r#u>*dw_)v?L1Dn`<;QVyUc*CiuPhy zr)X=FqODSL0le7IPK^6s1svb7-Xc!}uPEA!VcH3x$UVfls@=#C63X`?>nkh2ifDr- z!@#TP^~Y*Yp_Ca3`tmAr9M7C$lxZih5?GHc&E_LJ zc9S`by!D%bTanOjC~pN$jrhH(cvRV5D4O$`hk<`7+Uq;6Lig>@NPAyl06A@=)tBqM z8lGay6m+A1Ad|mwWt$z`2U{HsR>ayak{g{mV(Y2e201J$u&xkhcKNLlR49k|8mLRA>v@ zJp$;-chO(|J?Ywm|7Q?*p`=|g_8@gZg>h{32>T$ z-INnRZTD|}0%$Ux0{Ezr-IM~*-2H==kNmticG04xOE+7-Zeu$lcI#wM>o9UiIK#=7MN-{$+0 z@6~IUR3YGn=x0U0&9w&wtcQTb#9bJvLn`-w3HnRVWbWTu02ZP z1)zOWw#Zfr`EDJt=#$$O@LpI6U=UjYqzD1O6Zvj}HtuHtidYHY9Be->kzxg~!NBG} zNqnWmW^vEA3MfBY>6Ij*~?W;P?S0V8qydUmOH25+eYw;1BpGg0RjzXf3c{Vg&FJ^;VSQ zeRj?|S<`Z3`@w_?U_O4)Kk&Z>X6*s2E}29VDu8tnztaToi=Y-M?TdJN&su~&Ot0NP z@IM6%_RF+0u{~@OOo#wxp`RmvDt6+(ZrOUL>^-pW1roN~_D3fzq( zjC>9m_VS@I?-_hTvQ_K^zL~laQ!u7sq)Gs5H7W_DpYG59kUmN1 z*aH^z*nSnYs{Bl=Bc2C5+r+KNVUF=c^^Ya0w__4>fLrkQ03Y+{ zTt|J@BX6b0!+(uFykXQK$H=~cq=B^*K)-KN9rX+WUq?1e_LvQ+yC zvTkqk;3t3|V~~_10000H$*# literal 0 HcmV?d00001 diff --git a/tests/regression/assets/resource/texture/random.png b/tests/regression/assets/resource/texture/random.png new file mode 100644 index 0000000000000000000000000000000000000000..8d5dc5b3c9fed68ad4cfcea36ccaeffbd3326595 GIT binary patch literal 2587 zcmZWrc|6ox8~@FivCJS#md3vClTb~A7|j^VG+bm~OUQB!a+9Sn*2`FurOUMoAvB`w zvLsorC6(+V;@Y#7_s9M7J)h6npL3q`Jm>o?vBqQ~8v=y@0Dw(j4{rkYpcTab^KotAAUOxK~kcj|uE)e~NVTUVcJ=l8-a@djvEkGY zrQXIC=QnWG<3+ijsZVORdI3T9==K>(M~pMqXAIQx$5c*MDe-csHBg}TrT}n*WbCOF zrMm!Exiz9wzKQ_9G~vR64iCKd{f>$^{>`8xnVHtR<9Du%bpqN^4&M=;z0C86N8ciq zLakb?-w8r6&_U%hG6C;ukh&T z=$AG;g62Hh1w+&0)whhxM)^^wgO;hfni>EwFfd5U&Q4fbaudAb3v+UED!1WLH2($fr<#Rz^uFsl4*?-r4fn+DmvMac=c<9SqBTo&?8G zrh&CD4MatwvQcp{F-XqU5b-p*OBpQ2rlwTC#eU8KuRC{eWHS4PZFMUiC>Vev9U4NOulsCyj}fSL}a*ibCT1pKgGpGnpe?MTjN82Kf7yxRv3*+~ zdv|qoRj5XB^*n zbBKB;dna`?A7K>E*xog%HOprl5cv$kwD!M+NW;+UXht?)uQ@gwMKn(r1)PKNi4bXH?<{H6!gZWwK9h$ZC zjHi226(X>iSY~tJZ*p{nOqOlrhTY=o1tY>P!$) zU!Q4b%6~nEPlDFe*3Qm$#+ki1JUsMS9+8v(IHsKh6}%eE&qxike&FOJriNmB8JxyU z4sC10nORtvR^$zT%ZP8N)}}xwnnMI6BqT;wCSLha1KD_)$$!0#M$t&_LwE|b z3Ux-{+_^CGvfCzc(zc;@OyYRMxgGN>9~TEHS%c(hbVzn~cCY)84h0H23)NDIRD+q> z**Ar}*I_c+o}P*+Sl`#S9L4!Y$HaApjg1WuAR{ZDpK4kABq=RTK17vsWC1{~ zNvWf&D^cm;RC5T$�)uccogM=kap$j}ho#Oo3^*`25EF$7BogZoDJUq& zw&9QK#;&YLbHK*NrexF|{3Y&pbUMAg$S}R?W+y`YzA3y7JcCA~ODZet_Mki`qvy}N z(v)nN{V(}*)Bvq@61)HWV*+9@^Jg0kFCM0o*P0?@B%1zS&fm=rb{<$?RShaKiA_u6 zEiscOJJC-VEOvIfjfx3a7sX<+gCipm zlauz_J3CHeE*@A!xI@10V^yloKDpG<@l*U zmK|DwyM0><6fSCH#LUdxoQz3#Q|4cvZewtEc6J=fC&(%)ItR`n(SVb#u5Ojb5|5@WD3A%2-7^D5X-*{p}@A&`AtVPLfOL zu`^JPH*RX;7ccU#v9aMd!B-_^Wax#kCnL3EKzo_x)?Zy+9e?S;H`FTv(&p0X+;BMD z?1hJiN2z^QI8qx(HGntS8z~(R=3V0#5GZ)m2d_%{@$b~!!On`A2Z(Ny24y&3tIqFV z>Iwd5f2!9+{q`E*HLEBL#aRiZyu)jxBOS$B>c5K0Z3k*HGBU<2`a%@( z#lzQEtZf0L)5UoCWIfQ0l27T%VHAJ=B9-rNKwhZ|7AmFOD3pQJ$qnUE_{-jtq|>os znqu|R?&TJ0QI%n{`9e9Go14LanQ_HWy1KWqQDgZYei6!nN2eD&ecCm93{!RO z?}$Y5C8ee5{-;!F6%{Vf4lSDkcM5CIu(05~yp(oK+nU?qxvh=&wCqxkN+~_x1v|cX#ujJwt%OZE0;S%Dk*I>x$p> zw{Nknt=gXBRgkc-F!OK8$W{Q1_Mm5b`^hUF`G5I=rGvxy7^I95QBg=VHKTgX8o0=N zW3I}DJv33vCalGiz|N;VpCQq@-9kuvHOR1cRF>MyIh_Mo%Y0#vzE}jrB%WnraAR