From 3f965b239328fc58094f3ac858fffc2f3d92faf8 Mon Sep 17 00:00:00 2001 From: legatt Date: Tue, 10 Feb 2026 04:12:04 +0300 Subject: [PATCH] C++20 migration and Client - Migrated to C++20 modules - Worker and ThreadedWorker base classes for interthread systems - Client class for server transport and converting game data models to render data (views) - Update provinces render data from Client - Renderer handles commands now --- .idea/.gitignore | 8 + .../.idea.EtrediaEmpires.dir/.idea/.gitignore | 13 + .../.idea/encodings.xml | 4 + .../.idea/indexLayout.xml | 8 + .idea/.idea.EtrediaEmpires.dir/.idea/vcs.xml | 6 + .idea/EtrediaEmpires.iml | 2 + .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/inspectionProfiles/Project_Default.xml | 11 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + CMakeLists.txt | 19 +- CMakePresets.json | 6 +- assets/map/regions.map | Bin 0 -> 23330 bytes assets/scenarios/empires.save | Bin 70 -> 54 bytes cmake/executable.cmake | 52 +++ cmake/library.cmake | 52 +++ engine-api/CMakeLists.txt | 28 +- .../include/ee_engine_api/AssetData.hpp | 59 --- engine-api/include/ee_engine_api/GameData.hpp | 13 - engine-api/include/ee_engine_api/Map.hpp | 24 - engine-api/modules/AssetData.cppm | 63 +++ .../InputInterface.hpp => modules/Input.cppm} | 7 +- .../Render.cppm} | 76 +++- engine-api/modules/views/MapView.cppm | 28 ++ engine-api/src/AssetData.cpp | 132 +++--- engine-api/src/Render.cpp | 104 +++++ engine-api/src/RenderInterface.cpp | 70 --- engine/.vscode/launch.json | 12 - engine/CMakeLists.txt | 77 ++-- engine/include/Actions.hpp | 14 - engine/include/AssetManager.hpp | 172 ------- engine/include/Engine.hpp | 20 - engine/include/FileSystem.hpp | 69 --- engine/include/GLFWInput.hpp | 10 - engine/include/compile_config.hpp | 17 +- engine/modules/Actions.cppm | 17 + engine/modules/AssetManager.cppm | 425 ++++++++++++++++++ engine/modules/Client.cppm | 51 +++ engine/modules/DataChannel.cppm | 24 + engine/modules/Engine.cppm | 59 +++ engine/modules/FileSystem.cppm | 72 +++ engine/modules/GLFWInput.cppm | 16 + engine/src/Actions.cpp | 7 +- engine/src/AssetManager.cpp | 344 -------------- engine/src/Client.cpp | 93 ++++ engine/src/Engine.cpp | 32 -- engine/src/FileSystem.cpp | 51 ++- engine/src/GLFWInput.cpp | 10 +- engine/src/main.cpp | 170 +++---- p7lib/CMakeLists.txt | 2 +- p7lib/Sources/CMakeLists.txt | 8 +- renderers/magnum-renderer/CMakeLists.txt | 39 +- .../Materials.hpp => modules/Materials.cppm} | 33 +- .../Renderer.hpp => modules/Render.cppm} | 32 +- .../src/{Materials.cpp => Material.cpp} | 24 +- .../src/{Renderer.cpp => Render.cpp} | 63 ++- sdk/assets/CMakeLists.txt | 5 +- sdk/assets/compile_assets.cpp | 16 +- sdk/assets/define/regions.def | 18 +- sdk/assets/saves/empires.save.json | 51 +-- sdk/map/regions.bmp | Bin 0 -> 373086 bytes sdk/map/run.cmd | 2 +- server/.vscode/launch.json | 12 - server/CMakeLists.txt | 17 - server/economy/CMakeLists.txt | 33 -- .../ee_economy/components/container.hpp | 19 - .../ee_economy/components/deliverer.hpp | 24 - .../ee_economy/components/enterprise.hpp | 55 --- .../include/ee_economy/components/miner.hpp | 11 - .../ee_economy/components/producer.hpp | 9 - .../include/ee_economy/components/state.hpp | 9 - .../include/ee_economy/components/tags.hpp | 6 - server/economy/include/ee_economy/defines.hpp | 86 ---- server/economy/include/ee_economy/economy.hpp | 14 - .../ee_economy/enterprise_defaults.hpp | 15 - .../include/ee_economy/resources_exchange.hpp | 27 -- server/economy/include/ee_economy/systems.hpp | 15 - server/economy/src/Economy.cpp | 0 server/economy/src/systems/delivering.cpp | 56 --- .../src/systems/enterprise_routine.cpp | 20 - server/economy/src/systems/mining.cpp | 22 - server/economy/test/CMakeLists.txt | 26 -- server/economy/test/main.cpp | 8 - server/economy/test/systems/delivering.cpp | 214 --------- .../test/systems/enterprise_routine.cpp | 29 -- server/economy/test/systems/mining.cpp | 113 ----- server/economy/test/test_conf.hpp | 45 -- server/ecs/CMakeLists.txt | 27 -- server/ecs/include/ee_ecs/api.hpp | 14 - server/ecs/include/ee_ecs/data.hpp | 24 - server/ecs/include/ee_ecs/ecs.hpp | 4 - server/ecs/include/ee_ecs/world.hpp | 33 -- server/ecs/src/api.cpp | 44 -- server/ecs/src/world.cpp | 87 ---- server/ecs/test/CMakeLists.txt | 25 -- server/ecs/test/benchmark.cpp | 31 -- server/ecs/test/main.cpp | 8 - server/ecs/test/test_conf.hpp | 36 -- server/ecs/test/world.cpp | 80 ---- server/lib/CMakeLists.txt | 5 + server/lib/modules/GameData.cppm | 21 + utils/CMakeLists.txt | 26 +- utils/include/ee_utils/allocator.hpp | 22 - utils/include/ee_utils/buffers.hpp | 10 - utils/include/ee_utils/platform.hpp | 11 + utils/include/ee_utils/utils.hpp | 6 + utils/modules/allocator.cppm | 27 ++ utils/modules/buffers.cppm | 12 + utils/modules/worker.cppm | 151 +++++++ utils/src/buffers.cpp | 11 +- utils/src/utils.cpp | 0 112 files changed, 1859 insertions(+), 2607 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/.idea.EtrediaEmpires.dir/.idea/.gitignore create mode 100644 .idea/.idea.EtrediaEmpires.dir/.idea/encodings.xml create mode 100644 .idea/.idea.EtrediaEmpires.dir/.idea/indexLayout.xml create mode 100644 .idea/.idea.EtrediaEmpires.dir/.idea/vcs.xml create mode 100644 .idea/EtrediaEmpires.iml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 assets/map/regions.map create mode 100644 cmake/executable.cmake create mode 100644 cmake/library.cmake delete mode 100644 engine-api/include/ee_engine_api/AssetData.hpp delete mode 100644 engine-api/include/ee_engine_api/GameData.hpp delete mode 100644 engine-api/include/ee_engine_api/Map.hpp create mode 100644 engine-api/modules/AssetData.cppm rename engine-api/{include/ee_engine_api/InputInterface.hpp => modules/Input.cppm} (87%) rename engine-api/{include/ee_engine_api/RenderInterface.hpp => modules/Render.cppm} (50%) create mode 100644 engine-api/modules/views/MapView.cppm create mode 100644 engine-api/src/Render.cpp delete mode 100644 engine-api/src/RenderInterface.cpp delete mode 100644 engine/.vscode/launch.json delete mode 100644 engine/include/Actions.hpp delete mode 100644 engine/include/AssetManager.hpp delete mode 100644 engine/include/Engine.hpp delete mode 100644 engine/include/FileSystem.hpp delete mode 100644 engine/include/GLFWInput.hpp create mode 100644 engine/modules/Actions.cppm create mode 100644 engine/modules/AssetManager.cppm create mode 100644 engine/modules/Client.cppm create mode 100644 engine/modules/DataChannel.cppm create mode 100644 engine/modules/Engine.cppm create mode 100644 engine/modules/FileSystem.cppm create mode 100644 engine/modules/GLFWInput.cppm delete mode 100644 engine/src/AssetManager.cpp create mode 100644 engine/src/Client.cpp delete mode 100644 engine/src/Engine.cpp rename renderers/magnum-renderer/{include/ee_magnum/Materials.hpp => modules/Materials.cppm} (57%) rename renderers/magnum-renderer/{include/ee_magnum/Renderer.hpp => modules/Render.cppm} (68%) rename renderers/magnum-renderer/src/{Materials.cpp => Material.cpp} (72%) rename renderers/magnum-renderer/src/{Renderer.cpp => Render.cpp} (61%) create mode 100644 sdk/map/regions.bmp delete mode 100644 server/.vscode/launch.json delete mode 100644 server/CMakeLists.txt delete mode 100644 server/economy/CMakeLists.txt delete mode 100644 server/economy/include/ee_economy/components/container.hpp delete mode 100644 server/economy/include/ee_economy/components/deliverer.hpp delete mode 100644 server/economy/include/ee_economy/components/enterprise.hpp delete mode 100644 server/economy/include/ee_economy/components/miner.hpp delete mode 100644 server/economy/include/ee_economy/components/producer.hpp delete mode 100644 server/economy/include/ee_economy/components/state.hpp delete mode 100644 server/economy/include/ee_economy/components/tags.hpp delete mode 100644 server/economy/include/ee_economy/defines.hpp delete mode 100644 server/economy/include/ee_economy/economy.hpp delete mode 100644 server/economy/include/ee_economy/enterprise_defaults.hpp delete mode 100644 server/economy/include/ee_economy/resources_exchange.hpp delete mode 100644 server/economy/include/ee_economy/systems.hpp delete mode 100644 server/economy/src/Economy.cpp delete mode 100644 server/economy/src/systems/delivering.cpp delete mode 100644 server/economy/src/systems/enterprise_routine.cpp delete mode 100644 server/economy/src/systems/mining.cpp delete mode 100644 server/economy/test/CMakeLists.txt delete mode 100644 server/economy/test/main.cpp delete mode 100644 server/economy/test/systems/delivering.cpp delete mode 100644 server/economy/test/systems/enterprise_routine.cpp delete mode 100644 server/economy/test/systems/mining.cpp delete mode 100644 server/economy/test/test_conf.hpp delete mode 100644 server/ecs/CMakeLists.txt delete mode 100644 server/ecs/include/ee_ecs/api.hpp delete mode 100644 server/ecs/include/ee_ecs/data.hpp delete mode 100644 server/ecs/include/ee_ecs/ecs.hpp delete mode 100644 server/ecs/include/ee_ecs/world.hpp delete mode 100644 server/ecs/src/api.cpp delete mode 100644 server/ecs/src/world.cpp delete mode 100644 server/ecs/test/CMakeLists.txt delete mode 100644 server/ecs/test/benchmark.cpp delete mode 100644 server/ecs/test/main.cpp delete mode 100644 server/ecs/test/test_conf.hpp delete mode 100644 server/ecs/test/world.cpp create mode 100644 server/lib/CMakeLists.txt create mode 100644 server/lib/modules/GameData.cppm delete mode 100644 utils/include/ee_utils/allocator.hpp delete mode 100644 utils/include/ee_utils/buffers.hpp create mode 100644 utils/include/ee_utils/platform.hpp create mode 100644 utils/include/ee_utils/utils.hpp create mode 100644 utils/modules/allocator.cppm create mode 100644 utils/modules/buffers.cppm create mode 100644 utils/modules/worker.cppm delete mode 100644 utils/src/utils.cpp diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.EtrediaEmpires.dir/.idea/.gitignore b/.idea/.idea.EtrediaEmpires.dir/.idea/.gitignore new file mode 100644 index 0000000..d505038 --- /dev/null +++ b/.idea/.idea.EtrediaEmpires.dir/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/.idea.EtrediaEmpires.iml +/contentModel.xml +/projectSettingsUpdater.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.EtrediaEmpires.dir/.idea/encodings.xml b/.idea/.idea.EtrediaEmpires.dir/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.EtrediaEmpires.dir/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.EtrediaEmpires.dir/.idea/indexLayout.xml b/.idea/.idea.EtrediaEmpires.dir/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.EtrediaEmpires.dir/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.EtrediaEmpires.dir/.idea/vcs.xml b/.idea/.idea.EtrediaEmpires.dir/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/.idea.EtrediaEmpires.dir/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/EtrediaEmpires.iml b/.idea/EtrediaEmpires.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/EtrediaEmpires.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..bbce9cb --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b76fe5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..a443a4a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 713f9b4..dc80d29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,20 +1,25 @@ -cmake_minimum_required (VERSION 3.8) +cmake_minimum_required (VERSION 4.2.3) + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_SCAN_FOR_MODULES ON) +set(CMAKE_POSITION_INDEPENDENT_CODE OFF) + +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if (POLICY CMP0141) cmake_policy(SET CMP0141 NEW) set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") endif() -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -project (EtrediaEmpires) +project (EtrediaEmpires LANGUAGES CXX) add_subdirectory(sdk/map) add_subdirectory(sdk/assets) -add_subdirectory(utils) add_subdirectory(p7lib) -add_subdirectory(server) +add_subdirectory(utils) +add_subdirectory(server/lib) add_subdirectory(engine-api) add_subdirectory(renderers/magnum-renderer) add_subdirectory(engine) \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json index ba02f36..b38212e 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -8,9 +8,9 @@ "binaryDir": "${sourceDir}/out/build/${presetName}", "installDir": "${sourceDir}/out/install/${presetName}", "cacheVariables": { - "CMAKE_C_COMPILER": "cl.exe", - "CMAKE_CXX_COMPILER": "cl.exe", - "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + "CMAKE_C_COMPILER": "cl.exe", + "CMAKE_CXX_COMPILER": "cl.exe", + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" }, "condition": { "type": "equals", diff --git a/assets/map/regions.map b/assets/map/regions.map new file mode 100644 index 0000000000000000000000000000000000000000..db1df1550ba031746d0035311ccaad1eabf268b8 GIT binary patch literal 23330 zcmbuH4UAURx$n304lu)f@HNZ~!`BQ04BvvHf}+B_sHmu*_|f`B6%{L1+M?2yqpygT zDz(;fT1(Yhj`djU@pyYUybOV@$cf-?P?sUKqSR z=U&LO{`*;b?X}l_zSgtW-tR0Z_;>K&QIxYhEH)1o#n-Dvu_a>-{06*O19yRUfDa57 zwGwy2?}p!%>WgoJ_rQyH)BaoFc6f0sxEr*8dG9B`HuEbpzc{y>llhr-yw^?1d@Fbl zd_g<$qg6$5FZf2rcUBd(yWn4hcYLpcj`vy6@xPz(cc9NVmi|QUSKJ0V9{JVa4sc`O z^&zXHiUzQus1%LGh+-t=$YNA*qo}WNJgR6anmHa7Wpgo_kcYrrnSHzfy6r%VW4^c}2r&?4=k=63I6{0#+#hAksqAEJFQi_AOE4Bp? z4H?q4(AbRQ!JD9N=&KoT0XreZ)&boPd7an}`B?Drm@OHb^Z7PVanLTr!F@tJtr zdaf%JXA@+9o|or*_`%4`b3U#gMZNtVmHEFSX4`*~#s5ddEdTq={{d7T@P+tW(CdGb z>*X~M_;~L3z#HK|%=i&_13dSM`U=PL;`I>Y3-r0YPPyDzy)9&{nv>Txgo+!&`}D+- zoYx1Fn)SWWs9KNH)7mNZvaz70N*x~x9vA8y51*9UNqq;7Fdpin)Z1FX?(n)Ej=S-* zmhicj@Vl1qxt8!d{jC?z)7M(SKE}`zrGD2Gp4U|9eNE6T%2~y1%Gt#L)|8R z>(Ql$e~os}!Rz@4K>K?LG%|=^0rzJ#QhW(s58n*hURQVtyr#}WD?EqlQ+X+LRziU) zt_k(2wvnN_3OJfJDzE~zQmV*GC^MWt1Ddh|^2@4&I3 zp6Co!qH1yGF%tXEU!2kBxH9usfby4t3&6{(TS8`sdz=a!!5L@0dXICiQ+@iJzSlyj+L}Xc^$OD) z$Du|&ur1V<<~V1#PHHAlrdh5H?54)~t}W)fw(z^Q@VhkAInPb!?35_=zBZ_jQjco} z(`?sV^usy#&ElwdGR&eY9&sa&dkK%dDWhur9K7aXy=wnFs99LQJM-cu_&uQ3{vdc= zM%A((UNhPU>Mf#bwI9*zZC3+ToA(npfU0E~s9H2z)v_AY>^y&2_0$;qkb3G95&g?h z*bsiDI`l77kWrK=D4LFxiHIsO1!;@&@I)l3NB^3Lx>SIUhh&zDhjsSSMs0UhMs3@EL}v#>jQ0_}Z#kQI{v(8= zPdnSlJNt<5g9`N>(EGj%UYzSM0)GRqa(|cc&)|jde*)K6&y8ms61Ji(lMK^~LwzB6 zLh=GejvxGYv%aAuqcdisE=p&jj_`$!@CD)m-eB&>zk`LUQ0Lr=VXuXz)!_z?Re|*; z9P)~IJ!Jj)RrOC2z=Kslr&%q^SUn<~o!Z;OY2tpx_mPX8Y4qy%k&shL8twEK@akJs z&M$x(@5^;~HT(g1W0g~g`g{^}Dtinpo##e)ok!;)ISi-MiAv{GZ#t2BwBGyKPNx;s z<1TO=ct7a)_JZeuB%LvS`E#phe=3CGSw@!Iv%R2xG0%VK~EbuNQfc%t+4B2XcVFM`K_ zuYyZJ=XLpCb%vARb&``oonaZMGl+i%PtCX*{1|>s#0Bzy`>G7@tCGw+bVloSPEn_Sr4BWk7vPP6KCjn__OH>X)JHOEj2h)W&~ZJK z`A0#=r*UblPvv@z%;)gBGeC`6{yy+@P^0j9#X->iR%Ko}*?vXlj|080^4j z9GnL_-i6iup~E8wli`_=!DTeQXw**0YzuL^onvEmBWP*NZj5}WF-)y7Osz2t%>dQG zJ<~!`lXIo#+-FE3t-#DQw8@k%Bqv2eTYytJ>vA%swL}!AR?-ZnRwvhf{+q=1ftIGS zeUZxcMJijs&7r*sEp|#Wixfy^=d)m1NV%|BM7gLqn)>;aM;D8WC6r5wVuCZLC;4>^T8}cte8tw5oy&`lmAgQa=Am z=3fKt_l=Bif%f+S=zWy0{U~qiHT~x5fjSdRGruXm)1YNqTANRrNv71MH8RLHO5>4r z?VN3nQX?D{QE5~}rBPvqW+>zHB?oQ=K5{$KcgPgtJ!{Uu74ue>k5xke*pX` zs0sZ;9cpSnfyWeUKL#1=Fyn*Z-PHd8)Z|57_4eh=EYS8<0K5zl&9p4=AF_7!yIo84ZT(pmR&c}21fcysfzBRXpFO*mB;I~5;e>(!}4o%qwDqy*saxqo9g4-7DIF3$G2`8w86Qt}csj>ZDcz5n95(g;CN_Kc1oU2O@EZ`FO3WH z9~Taw3mj=8o*NVK+%WucILczKTFf(?7}D8_va3kwDks#TB+CK8zT5OgsnG(t-E+U z^i9SD?xgK&`PzQDrcIXbs%H}Q27XtxlPR_SjZeDk#dn0oo6+>s zzv<|N2>#ms0LQb!=CyXi{d`J8{hSE)P6i7(ZyGuf0e>LuegKPKLXBzYK!kn6{c!|+ zQ_y20)DM6saMpl75CMOHfIorVMv}PlJ&Gz;z2+36CSo3<3CJ(c{7Jd)MDS=x{#ZyC zuujyhHQCc3OP=S&;REiBnq@BH5WW4$@MY)S%f$=W! zPw;!-O;wyPOg)`nMCYFmY3KYQJ_LRY?gK~gPUAsvBD2du!~mwAyi zspkD!Ad&0iU8UFW=J+V^o`i9pan$aG=f3f7^CR$^@SlJ_hu7Z;aeZI|*YD!k>#Vo^ zPVmFQ&ntsi37C4NO}$ZUz$o?+P;=Djm5rY&Anmm3p{?PQX$3GYe9}^(yBA@p=oS1# zj@^N14S#IKC%eL%Dvu=I z3_b;J&-nFRFIs;acmPq{0ltw%@@wi9(eL0DjjH#&D&GPA1@wB+{;mIV#xH@WJ~jr$ z%@8V!jX+g&1IK>`trxEWRl(I6ugLY6fVTe}=zT8B^`hCc8}> z-vVv-Hu#0iUj@DbzX^OfuE-GMu}hOq-O$_Z5b=ttMkahVrSPucl38%;kHjnL=q& zV`*6LiWH_R0(w_rDDSEZ`8V)g z>b*{*^m*XpIla#3rJvf+nE;9k)4sce;uy&IHHI=})^2f4r$)2X5NA-DM`Hz)X^V>u3k;BH zo4kTt7cR%5Q^=7~3K1jc!Js zZ$K9_VbnnCBTCx-PRQL=qa=LPe;(WkPXvqhS90uiMxI-tYoS{pBhOaIh-0+5I+Mq? zwVl_>Uk-WRDCRlQI{PpZ+E)HX=#uLCc-EnXRGPw)0jT|xqxbADr<^Tr8kDs z8)NcH`0lALNxzEraP8M4oVG=jB| zMqomBb4I63$D?vig=~KkWIy8dkoESz3UUe?gdE2ikmEQDx+rct9yE411 zTD4xSdVLkT4bnPyKw5{PL0(tZihOWUfhZWQ%JU-qhJa244FM-W_Oq&y@0;HXP|~*YH@K5{CMBUMXT5uhDRtl+7PfGCrTdd=Dyd3C9mWOLM&f z^!#!J^j%Ovd0w}XXDw8_AN0Y$1Dy?jU*c=u1{K(zjQ4;FL|%p53mpU5ej()bi>k*u zHq>bh*I9;ttCF^Xk}W8(|2M%Pj1-5G32K`2po<`dK`@VnpuyEaZiE!d7a+BGEmXz^ zgcC8thtoaOzHXq9wm`<5>!5Xzfm`$UdSjdJVO*0pmf8QMkoS}KobKbeJU$=tI$h6t z1#f>^s^v?&{gmPl>>H^lW*+%kO@x3!F>jc>rq^S>7@HpX zgVz1F6N_)WirS+*P%re8gth%(Kh`Nf06hjRfc^nev7QIxyjK5@5aA(k75Gy~A=w^* z#+K%K(EBKOQ6qW;+CaUC0%Ge{1?+>)g?|t{3v?WMkLV=vBM9ZiQkqF7meMOh`?daI z(D8_bli)GDXzzF*f{um%F^Iv&bw_h-`#BjkY}+k_ydM}#^|F38yyI3r-gidzW@S0d z8&jC7{}3sKDT9>Xy9~WARsCZy4Zm)2vKmXN5u_Z#iL0EloUA5tZ40I0ZYZtv4Z~IQKKnL%*HUWNC{;>X{Cu|U#w`-o6-R|6Uo^mlD&~m_Hu*) zT^RF-tM25v6A^-*EPfg4hHl9G&ERxs8`KBc4g-s<0YOGP1*?ZI&h;AFO^^!H16m7Bg7B8`WV|N?p#Zc{yeuqRoCnz-9ua$OctV8dx!`e-g7lntGNi&3 zz5){!p!MEw1*F39zQ8It9>NP_eBP(6$|{V1htE^>6L`H(IF*lPLRYXOpmMWl1V`=E z=p`ek>5bTH$>pHR1yXd@FN2QC*aRx7(U2k;1FeF_WnNJ!I#qZQq$m}s zV^Rf*T2%Dbs|tC?p#6&t&`ij&+0Lix@*SsKHrFoscK48vdGxKT%JBW-27fUO0=guh{yLaeD zklR77y}Kh=c1N)6j!@Yh>u*=zzQ*UXoNuZhOTis?m`$;x|(?4pbpf|}|jpr(0g9V%jz9o1*}dndP3Rad~Ps%t>ix;gVV z)S>lP!;gSO)oQraB(8*1-zG@YvA?O1;j{-bylQHOUro>Zvjr4kS(CMX24s|yKO5?W z&Ve-bHIOcF7GzXA9rC_aNOKZ3CtXFQ>Tj3B{kJWkY;)`q$w^0m6NWc zi;I5%bz$YX6#M`@0d$|#ennl+t*TQpo(igm!Hh;Z&pU3>=d>TA@UOvjfrr1ysyBI! z(WH?rc*?_fAJR)(_aNF>)tM(Wh2b|v6l|)?5}G1Q&~+xzkCV)(F#Iw{7)3NpIYMV- z2>uvnGBp~07g%NqzS5mWO?st!_?A=JZ0ar2%UjLd>|idX`<%1m6_#62^Kq70Q4W2% z&>LSa^oGgz#*3`pc#+i`FS2^$MOJToxzHQ0vwGuoR&Tt{>Wvp!z40Qemls)GxJzUq z7bCc2V!uS({fJwf1HJ&x1E0_Qvzhn2DeZHhW?;SQmv=&Rn_Dw*XH&C!6VyyJYtO$A z9+y$`(tMVHnvLQLqSGHf#ddDE|y$uVxisKO_&sQMFtXp}{kr{P2$0q(3G+a0q z@AX!$e*@HgU#mm!?QX8^Ujpq^-B9?#ASTSelywfh4oNRD4H2V?wBJ?#emkur87b)z<6BW}TOTy}I=KAIk}(q)e0%0s)CPyN2W=qeV;*$(+1=BSkvnn24n#hKKf7Uh}6Ssb5LoK1Olv6gaeaZYhAXn9U?9_4w(I?8p$dj6kZ zT)^>q$|<1b1-wF@0$oUXVQ~@VMacJH5x;8m6+)V0p20X)VH^iQ=NgU1IqzxkBv3~& z6E`>+q%=B%*9)NOr^e;nWiT^%{Sx##`*SY)1?ct9491Ttv+-$8pS9$1Mk;p`-OgxX zj?(Nj)0C3AU^(c5WmP=J{d7Nvw=Lhz_yD*V{yT|J8)ppTd+^ILUc&jk@SEVp&ADFQ z>$idSyEXR%AN|#G`}=dd?`QrI&U@WHc*pT5==G0NFDmAYu@Uzq{I{tGYkN|=*m$%3 zJ@EFo8?>Kq<@4VJAEW-RbUt2k$nS*T58eSj0oD>9zr*5uApONo=!4)boOk>;gL}a3 z;N7`?C-^1!UEo%52e=LNxot1+^~&d~;FgS=a{Wf|Yt+l%23`j4%Dm%-kFNr(zYm`4 zLmspbIjp1J=U)TfoiLtv1-$YAm z2bw*grO~P%f`&zszth%C)$ymj*TdeJ!TbFKt^ zF4qjo$@@G8dVhJxV_de~e$a7>XMoE2tjzly@)v>+fj+5WDG=5)Ez82U<@)R34?62}UI)a}!xB5h`wTC~S{!_8^8sM9MG5+9r}eKI$E zb2_=*XC)OWr7*QP^!0X1Fi4SbNfIO+k~BD+QTLk}?x$-GP~RV=$%bo>LqDBk^1&5# zM8B`_Tj}(x4S%s=im?Qz^GoTalqMI8Kugn%Md5gh!ts*BEyD3mJjC%9h2t&4@p$=_ z=DjqP8c!c3{$-4>t5A2uN7e7V;d$dE7(DYs%rnjt#$VmZd5LMd_V*xeRr>*mTg6w* zPTxO-cY6O3_+m!Q?qT>>z@LDaX>4u(KJ$Npe~9{zK(B+3enk8K1l*g^`R@<3bAJ0H z_0AU`WYk@D!oLCD4l=HoUwlsIIi54-J?Bx|`P^Rr_~5mOt3KBqiE;Y*zFU67-3;c9{3?|)7nPvsQ=p09lTjgojCw)8S-j7@4?)Z?8GZ$!(<*tvLtL0Z? z^|>yYddv|TqjQC&bHvmzNVD92j{E6rUV1GS?+9ZVpqIJ>B2I<$)-jpy1uus@FM3|@ zwf-t-IsulFv;GRG9lE$W^p3C+f*79RrKLuCYn*;F zkvQ zR^vAo<*$P$!cF3=E6s_}WDLm{Rc>KfIz=>vCpLu_vgd#=A{{0NCx~83y|R9qa8fW1 zo42vQ!gPVOKbqF@Q7Q^nkvDCWjwF_*~#uTO^V z9Fz=aGlr<4fMGaW;58uYzYp%nxC=DU?xvjq7(VbG@L~7|GVTK(fp^~j2?!tWWSuzn z!y8zw7k>;IfFA{)%h!Vu=wAlCPl-$vF@e}_AN5W!P9)}Sj!WL>aGj}vJMlOX8Q7hO zs1L(;96Ad5NVJ#tc^Plie?Rm0(~sBJGHwICZu{U(Av+fa$?!C`M(Wbiz$HOiai+hr z;V(;%^s7?WpkrvM$vKUfpZHG5%;eCQ=gAP$_J8^Y%Z%mFiJ)8{q)&(4|MZuomYUq8 zFuCEs=yI#1Kg@0xr6%W3S=by*pN|~RVN#Z}y2=xO3M%Bs!CxY*ClbcDiwgbc@Xqr8 z1eUx?eF~o0J-(5A75r!T*E7CJ`+tFd5B_=Z&+z{N8YTY?Y$DqHJJ<%j01++X+fAdw zOOVk~G`jpJM3jr`;cK=Z5B+b*s3a2o;#*ImQuJdq^uA78&p}45e}!!KKOp*x=i>T! zUi*I%ay&ji_m2+^oVJvcyiQRfl>NH?vN$4T?1A`B#v)B|#TO!FQQ+|>@4K$^8)oRQm&QjLDr!tW~bVn{tneNM# z#+hE~r@!js-}IRn(XW#-AMTm65+9 zG&xn>wsUe5H9y;HE}q9+BBt8TnB?Sb?9q&kWz@%c%|zZLz*sl3y4W$*sWrWLRDH&d z!()zhu7=Wk=(G|_lb*`-hjW%jp3xC)Mn}ZCD?NU%cZ!heV>k@a;bYw~JotDlysB0{ zX8G7!zwIA`Oy-Oh;y*%O_cKthk=H9dKY@CYWHF|Q$sBwAw9L=oSZkjGFZN^}?+tH| zSIl~`Q-=LHZoTzEkajU{ygQ}>+DFK@-YLVVpgL5O*j63-g-8Wi80OO=R8gnjiRf2N z;Yo-3kG~l4V_St@|Cy}{D}Sk&mZ0e`Riv->{O#hQzuT(7`)hGCj|w!2(rlv=zEp_} zBW3y(d@1b)Rf?yR3d35$auk6g@evh~qSd10vnWG_rD&(;`aV#V&w^|}pMJc)#5wSK z02r3O5VZXw$bOH8yf1w8za)?2*j#@+Xn)J8_qvlZe@f<0&F$sA{~&0;RmcE&CZvkj zK&tpG$ad#J_IEDi{nurFedaghelO1bg5iN)@9e&cdQHM{$ur*I9l!PSz`fvHP*ds8 zh+Mi$H*GW?O{e_Z6U}gbpWPhg&~nj)wA@NGF#DRMTrSS!*u=B~&WcQ7 zfMb99=N`sfj{QJC{Zb^Qr)mEp?OvFwru4K@yq!#Rfk7rj>Kv;mdom)@LQxY9LN$mw zRzRBAeb53#d=GdGcrUmN{1&(p+5?>de>b=qyerr5%6KQZg8Dl^OfHb?#e=*ti$85@OM9~+UFNbG3aZY#7Dx&c}Y-3U2u>t{nZK|a?uXa;l(q^o@` zV-1`MiMo{I)6^XA0O<4Z+_54npWpM}rq1@?h58^(c5241>TSw6CXEVMMzNtZwTxVD zptTU$G(NvgX`|HijCPh9UrJO>Q_GL~Msk!)PqTA%RBwDE!}!cNx`}*;n_x0J&G1Mm zs()@^21cs!Is4Dz*z|N#7+xbdn?B708pHe=!vq_{{EV~n;w65i_*vTFFvUpXUW;gY zAyGA-1F3$aglaWJIBbo|#qs@vMjq_fXS9*_~8BJU1B}zFC#hz_dn5pD3j?FeQPL796Z_ zQM^J7k53jUH+Z}+g7%j{BL!X;9}+`5kl$(ue;(n=FTC;8$n4|BR7GIi4Rsyqa3 z&-~Xo_Wai~{|)d5@V7%E^)boWUjF9H+mDg+rfOQw4=qWPk2~e0j z^%bbUFdrGEUhnVBH3x-ly0B?c=xx@)Tm6uT>+Fu1i{7 zB$o-R=wI_4#TYM4ewvg)SPOsBA5eVw2MQ0rkk@ZELHdz?p?$m>;r{UP88<35spsNfCX^7^5Cf988Z6cu4y5s?AJAEN9AZPx{P zeiEdjCO}RDAF@(#HIu6FSnLM)r>)_j9(N G9{&#_Hfg>9 literal 0 HcmV?d00001 diff --git a/assets/scenarios/empires.save b/assets/scenarios/empires.save index da432864b0cabd712661bd50c46e005152796718..51b9795e2f48d493820a9a9894a8ec478a0515d3 100644 GIT binary patch literal 54 zcmZQ#c+7O7fPvvZ0~5n4Ao-u6p25TW%I5zJ3=C`x|AACJ5QBIi@_z^eLkN%t0P0r} AhX4Qo literal 70 xcmZQ#Q1w%7U|{&qzy`!X`UZ%72f_yNf!M?Q%4QIQje!M7{m+7kf>lFR006iR6IB2J diff --git a/cmake/executable.cmake b/cmake/executable.cmake new file mode 100644 index 0000000..eb0f0ed --- /dev/null +++ b/cmake/executable.cmake @@ -0,0 +1,52 @@ +function(add_executable_target TARGET_NAME) + + set(CMAKE_CXX_STANDARD 23) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + + + project(${TARGET_NAME} LANGUAGES CXX) + add_executable(${TARGET_NAME}) + + file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS + src/*.cpp + src/*.c + ) + + file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS + include/*.hpp + include/*.h + ) + + file(GLOB_RECURSE MODULES CONFIGURE_DEPENDS + modules/*.cppm + modules/*.ixx + ) + + target_sources(${TARGET_NAME} PUBLIC FILE_SET modules TYPE CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${MODULES}) + target_sources(${TARGET_NAME} PUBLIC FILE_SET headers TYPE HEADERS BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${HEADERS}) + target_sources(${TARGET_NAME} PRIVATE ${SOURCES}) + + # MSVC STD module linking + # target_compile_options(${TARGET_NAME} PRIVATE + # /EHsc + # "SHELL:/reference \"std=$ENV{STD_MODULE_DIR}/std.ifc\"" + # "SHELL:/reference \"std.compat=$ENV{STD_MODULE_DIR}/std.compat.ifc\"" + #) + #target_link_libraries(${TARGET_NAME} PRIVATE "$ENV{STD_MODULE_DIR}/std.obj") + # target_link_libraries(${TARGET_NAME} PRIVATE "$ENV{STD_MODULE_DIR}/std.compat.obj") + #target_compile_options(${TARGET_NAME} PRIVATE + # /wd5050 + #) + #target_compile_features(${TARGET_NAME} PRIVATE cxx_std_23 INTERFACE cxx_std_23) + + # Clang modules +# target_compile_options(${TARGET_NAME} PRIVATE +# -fmodules +# -fcxx-modules +# -fbuiltin-module-map +# -fimplicit-module-maps +# ) + + target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + +endfunction() diff --git a/cmake/library.cmake b/cmake/library.cmake new file mode 100644 index 0000000..43c51c9 --- /dev/null +++ b/cmake/library.cmake @@ -0,0 +1,52 @@ +function(add_library_target TARGET_NAME) + + set(CMAKE_CXX_STANDARD 23) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + + + project(${TARGET_NAME} LANGUAGES CXX) + add_library(${TARGET_NAME}) + + file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS + src/*.cpp + src/*.c + ) + + file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS + include/*.hpp + include/*.h + ) + + file(GLOB_RECURSE MODULES CONFIGURE_DEPENDS + modules/*.cppm + modules/*.ixx + ) + + target_sources(${TARGET_NAME} PUBLIC FILE_SET modules TYPE CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${MODULES}) + target_sources(${TARGET_NAME} PUBLIC FILE_SET headers TYPE HEADERS BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${HEADERS}) + target_sources(${TARGET_NAME} PRIVATE ${SOURCES}) + + # MSVC STD module linking + # target_compile_options(${TARGET_NAME} PRIVATE + # /EHsc + # "SHELL:/reference \"std=$ENV{STD_MODULE_DIR}/std.ifc\"" + # "SHELL:/reference \"std.compat=$ENV{STD_MODULE_DIR}/std.compat.ifc\"" + #) + #target_link_libraries(${TARGET_NAME} PRIVATE "$ENV{STD_MODULE_DIR}/std.obj") + # target_link_libraries(${TARGET_NAME} PRIVATE "$ENV{STD_MODULE_DIR}/std.compat.obj") + #target_compile_options(${TARGET_NAME} PRIVATE + # /wd5050 + #) + #target_compile_features(${TARGET_NAME} PRIVATE cxx_std_23 INTERFACE cxx_std_23) + + # Clang modules +# target_compile_options(${TARGET_NAME} PRIVATE +# -fmodules +# -fcxx-modules +# -fbuiltin-module-map +# -fimplicit-module-maps +# ) + + target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + +endfunction() diff --git a/engine-api/CMakeLists.txt b/engine-api/CMakeLists.txt index 853ba5e..ad9bd7f 100644 --- a/engine-api/CMakeLists.txt +++ b/engine-api/CMakeLists.txt @@ -1,36 +1,18 @@ -if (POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) - set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") -endif() - -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - - project(engine-api) -file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS - "src/*.cpp" - "src/*.c" - "include/*.hpp" - "include/*.h" -) - +include(${CMAKE_SOURCE_DIR}/cmake/library.cmake) # Find dependencies find_package(glfw3 CONFIG REQUIRED) +find_package(glm CONFIG REQUIRED) # Link library -add_library(${PROJECT_NAME} ${SOURCES}) +add_library_target(${PROJECT_NAME}) target_link_libraries(${PROJECT_NAME} PRIVATE p7) +target_link_libraries(${PROJECT_NAME} PUBLIC server) target_link_libraries(${PROJECT_NAME} PUBLIC utils) target_link_libraries(${PROJECT_NAME} PRIVATE glfw) - -target_include_directories(${PROJECT_NAME} PUBLIC include/) - -if (CMAKE_VERSION VERSION_GREATER 3.12) - set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) -endif() \ No newline at end of file +target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm) \ No newline at end of file diff --git a/engine-api/include/ee_engine_api/AssetData.hpp b/engine-api/include/ee_engine_api/AssetData.hpp deleted file mode 100644 index 33b1c75..0000000 --- a/engine-api/include/ee_engine_api/AssetData.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once -#include "GameData.hpp" -#include "Map.hpp" -#include -#include -#include - -namespace ee_assets -{ - struct AssetData {}; - template concept Asset = std::derived_from; - - enum AssetType - { - BINARY, - - MAP_MESH, - SAVE, - - SHADER, - MATERIAL, - IMAGE - }; - - struct AssetBinary : public AssetData - { - uint8_t* content = nullptr; - size_t size = 0; - - AssetBinary(uint8_t* &source, const size_t sourceSize); - ~AssetBinary(); - }; - - struct AssetMapMesh : public AssetData - { - ee_engine::MapMesh content; - - uint8_t* Serialize(size_t &size); - AssetMapMesh() {}; - AssetMapMesh(uint8_t* &source, const size_t sourceSize); - }; - - struct AssetSave : public AssetData - { - std::vector subjects; - - uint8_t* Serialize(size_t &size); - AssetSave() {}; - AssetSave(uint8_t* &source, const size_t sourceSize); - }; - - #define AssetShader AssetBinary - - struct AssetMaterial : public AssetData - { - uint32_t vertexShaderAssetID; - uint32_t fragmentShaderAssetID; - }; -} \ No newline at end of file diff --git a/engine-api/include/ee_engine_api/GameData.hpp b/engine-api/include/ee_engine_api/GameData.hpp deleted file mode 100644 index cb8e3d7..0000000 --- a/engine-api/include/ee_engine_api/GameData.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include -#include - -namespace ee_data -{ - struct Subject - { - uint32_t tag; - uint32_t color; - std::vector regions; - }; -} \ No newline at end of file diff --git a/engine-api/include/ee_engine_api/Map.hpp b/engine-api/include/ee_engine_api/Map.hpp deleted file mode 100644 index 03997f3..0000000 --- a/engine-api/include/ee_engine_api/Map.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace ee_engine -{ - struct MapMesh - { - struct Province - { - std::vector vertices; - std::vector indices; - }; - std::unordered_map> states; - }; - - struct ProvinceSSBO - { - uint32_t stateId; - uint32_t color; - }; -} \ No newline at end of file diff --git a/engine-api/modules/AssetData.cppm b/engine-api/modules/AssetData.cppm new file mode 100644 index 0000000..8679207 --- /dev/null +++ b/engine-api/modules/AssetData.cppm @@ -0,0 +1,63 @@ +module; + +#include +#include +#include +#include + +export module AssetData; +import GameData; +import MapView; + +export namespace ee_assets +{ + struct AssetData {}; + template concept Asset = std::is_base_of_v; + + enum AssetType + { + BINARY, + + MAP_MESH, + SAVE, + + SHADER, + MATERIAL, + IMAGE + }; + + struct AssetBinary : public AssetData + { + std::uint8_t* content = nullptr; + std::size_t size = 0; + + AssetBinary(std::uint8_t* &source, const std::size_t sourceSize); + ~AssetBinary(); + }; + + struct AssetMapMesh : public AssetData + { + ee_engine::MapMesh content; + + std::uint8_t* Serialize(std::size_t &size); + AssetMapMesh() {}; + AssetMapMesh(std::uint8_t* &source, const std::size_t sourceSize); + }; + + struct AssetSave : public AssetData + { + ee_data::GameState content; + + std::uint8_t* Serialize(std::size_t &size); + AssetSave() {}; + AssetSave(std::uint8_t* &source, const std::size_t sourceSize); + }; + + using AssetShader = AssetBinary; + + struct AssetMaterial : public AssetData + { + std::uint32_t vertexShaderAssetID; + std::uint32_t fragmentShaderAssetID; + }; +} \ No newline at end of file diff --git a/engine-api/include/ee_engine_api/InputInterface.hpp b/engine-api/modules/Input.cppm similarity index 87% rename from engine-api/include/ee_engine_api/InputInterface.hpp rename to engine-api/modules/Input.cppm index ca9ee43..3b5c162 100644 --- a/engine-api/include/ee_engine_api/InputInterface.hpp +++ b/engine-api/modules/Input.cppm @@ -1,7 +1,10 @@ -#pragma once +module; + #include -namespace ee_engine +export module Input; + +export namespace ee_engine { struct InputHandlers { diff --git a/engine-api/include/ee_engine_api/RenderInterface.hpp b/engine-api/modules/Render.cppm similarity index 50% rename from engine-api/include/ee_engine_api/RenderInterface.hpp rename to engine-api/modules/Render.cppm index 06ac6a6..e043d7c 100644 --- a/engine-api/include/ee_engine_api/RenderInterface.hpp +++ b/engine-api/modules/Render.cppm @@ -1,62 +1,102 @@ -#pragma once -#include -#include "Map.hpp" -#include "AssetData.hpp" +module; -namespace ee_engine +#include +#include +#include +#include +#include +#include + +export module Render; +import worker; +import MapView; +import AssetData; + +export namespace ee_engine { struct ShaderRefs { ee_assets::AssetShader *vertProvinces; ee_assets::AssetShader *fragProvinces; }; - + struct CameraTransform { glm::vec2 position {0.0f, 0.0f}; float zoom = 1.0f; }; - + struct MeshTransform { glm::vec2 position {0.0f, 0.0f}; glm::vec2 scale {1.0f, 1.0f}; float rotation; }; - - class IRenderer + + struct RendererCommand : public ee_utils::WorkerCommand + { + enum Type : std::uint8_t + { + NONE, + + UPDATE_REGION, + + COMPLETED + }; + + struct RegionPayload { std::uint32_t id; ProvinceSSBO data; }; + + union { + RegionPayload region; + }; + }; + + class IRenderer : public ee_utils::Worker { public: virtual ~IRenderer(); - + + constexpr bool isReady() const noexcept {return _isReady;} + void RegisterMaterials(const ShaderRefs &shaders); void RegisterMapMesh(MapMesh *mapMesh); - + virtual void Init() = 0; virtual void Shutdown() = 0; void Draw(); - + virtual void ResizeWindow(int width, int height); void SetCamera(const CameraTransform &camera); - CameraTransform getCamera(); - + constexpr CameraTransform getCamera() const noexcept {return camera;}; + + + protected: + bool _isReady; int screenWidth, screenHeight; float screenAspect; CameraTransform camera; glm::mat4 viewProjection; - + GLFWwindow *window; MapMesh *mapMesh; ShaderRefs shaders; - + + struct RegionIndecies {std::size_t startIndex; std::size_t provincesCount;}; + std::unordered_map regionsMapping; + explicit IRenderer(GLFWwindow *window); - + virtual void Clear() = 0; virtual void DrawMap() = 0; virtual void DrawUI() = 0; - + virtual void ApplyCamera() = 0; + + virtual void UpdateProvinces(const std::size_t index, const std::vector &data) = 0; + + private: + void UpdateRegionCmd(RendererCommand &command); }; } \ No newline at end of file diff --git a/engine-api/modules/views/MapView.cppm b/engine-api/modules/views/MapView.cppm new file mode 100644 index 0000000..cd71529 --- /dev/null +++ b/engine-api/modules/views/MapView.cppm @@ -0,0 +1,28 @@ +module; + +#include +#include +#include +#include + +//TODO: module Views +export module MapView; + +export namespace ee_engine +{ + struct MapMesh + { + struct Province + { + std::vector vertices; + std::vector indices; + }; + std::unordered_map> regions; + }; + + struct ProvinceSSBO + { + std::uint32_t regionId; + std::uint32_t color; + }; +} \ No newline at end of file diff --git a/engine-api/src/AssetData.cpp b/engine-api/src/AssetData.cpp index 6810b73..1f8fbcb 100644 --- a/engine-api/src/AssetData.cpp +++ b/engine-api/src/AssetData.cpp @@ -1,7 +1,12 @@ -#include -#include -#include +module; + #include +#include +#include + +module AssetData; +import allocator; +import buffers; /* @@ -9,12 +14,11 @@ YOU CAN PREVENT SOURCE BUFFER FROM CLOSING. IT CAN BE USED FOR STORING ASSET DATA WITHOUT COPY. IN THIS CASE, YOU MUST SET SOURCE TO NULLPTR AND FREE BUFFER YOURSELF. -TODO: make binary format describing for common functions instead of individual serialize/deserialize functions -TODO: parallelize convertion loops +TODO: make universal binary format, think about flatbuffers or msgpacks */ -ee_assets::AssetBinary::AssetBinary(uint8_t* &source, const size_t sourceSize) +ee_assets::AssetBinary::AssetBinary(std::uint8_t* &source, const std::size_t sourceSize) { content = source; size = sourceSize; @@ -29,62 +33,62 @@ ee_assets::AssetBinary::~AssetBinary() -ee_assets::AssetMapMesh::AssetMapMesh(uint8_t* &source, const size_t sourceSize) +ee_assets::AssetMapMesh::AssetMapMesh(std::uint8_t* &source, const std::size_t sourceSize) { - uint8_t* buffer = source; - uint8_t* pointer = source; - size_t leftoverSize = sourceSize; + std::uint8_t* buffer = source; + std::uint8_t* pointer = source; + std::size_t leftoverSize = sourceSize; source = nullptr; - uint32_t statesCount = 0; - ee_utils::readNext(&statesCount, pointer, leftoverSize, sizeof(uint32_t)); + std::uint32_t statesCount = 0; + ee_utils::readNext(&statesCount, pointer, leftoverSize, sizeof(std::uint32_t)); - for (uint32_t state = 0; state < statesCount; state++) + for (std::uint32_t state = 0; state < statesCount; state++) { - uint32_t id = 0; + std::uint32_t id = 0; glm::u8vec3 color {}; if (!ee_utils::readNext(&color, pointer, leftoverSize, sizeof(glm::u8vec3))) break; - id = static_cast(color.r) << 16 | - static_cast(color.g) << 8 | - static_cast(color.b); - - uint32_t provincesCount = 0; - ee_utils::readNext(&provincesCount, pointer, leftoverSize, sizeof(uint32_t)); + id = static_cast(color.r) << 16 | + static_cast(color.g) << 8 | + static_cast(color.b); - for (uint32_t pi = 0; pi < provincesCount; pi++) + std::uint32_t provincesCount = 0; + ee_utils::readNext(&provincesCount, pointer, leftoverSize, sizeof(std::uint32_t)); + + for (std::uint32_t pi = 0; pi < provincesCount; pi++) { ee_engine::MapMesh::Province prov; - uint32_t verticesCount = 0; - if (!ee_utils::readNext(&verticesCount, pointer, leftoverSize, sizeof(uint32_t))) + std::uint32_t verticesCount = 0; + if (!ee_utils::readNext(&verticesCount, pointer, leftoverSize, sizeof(std::uint32_t))) break; prov.vertices.reserve(verticesCount); - for (uint32_t vi = 0; vi < verticesCount; vi++) + for (std::uint32_t vi = 0; vi < verticesCount; vi++) { glm::vec2 vertex; if (!ee_utils::readNext(&vertex, pointer, leftoverSize, sizeof(glm::vec2))) break; - + prov.vertices.push_back(vertex); } - uint32_t indicesCount = 0; - if (!ee_utils::readNext(&indicesCount, pointer, leftoverSize, sizeof(uint32_t))) + std::uint32_t indicesCount = 0; + if (!ee_utils::readNext(&indicesCount, pointer, leftoverSize, sizeof(std::uint32_t))) break; prov.indices.reserve(indicesCount); - for(uint32_t ii = 0; ii < indicesCount; ii++) + for(std::uint32_t ii = 0; ii < indicesCount; ii++) { - uint16_t index = 0; - if (!ee_utils::readNext(&index, pointer, leftoverSize, sizeof(uint16_t))) + std::uint16_t index = 0; + if (!ee_utils::readNext(&index, pointer, leftoverSize, sizeof(std::uint16_t))) break; - + prov.indices.push_back(index); } - content.states[id].push_back(prov); + content.regions[id].push_back(prov); } } @@ -92,34 +96,34 @@ ee_assets::AssetMapMesh::AssetMapMesh(uint8_t* &source, const size_t sourceSize) } -ee_assets::AssetSave::AssetSave(uint8_t* &source, const size_t sourceSize) +ee_assets::AssetSave::AssetSave(std::uint8_t* &source, const std::size_t sourceSize) { - uint8_t* buffer = source; - uint8_t* pointer = source; - size_t leftoverSize = sourceSize; + std::uint8_t* buffer = source; + std::uint8_t* pointer = source; + std::size_t leftoverSize = sourceSize; source = nullptr; - uint16_t subjectsCount = static_cast(subjects.size()); - ee_utils::readNext(&subjectsCount, pointer, leftoverSize, sizeof(uint16_t)); + std::uint16_t subjectsCount = static_cast(content.subjects.size()); + ee_utils::readNext(&subjectsCount, pointer, leftoverSize, sizeof(std::uint16_t)); - for (uint16_t i = 0; i < subjectsCount; i++) + for (std::uint16_t i = 0; i < subjectsCount; i++) { ee_data::Subject subject; ee_utils::readNext(&subject.tag, pointer, leftoverSize, sizeof(subject.tag)); ee_utils::readNext(&subject.color, pointer, leftoverSize, sizeof(subject.color)); - - uint16_t regionsCount = 0; - ee_utils::readNext(®ionsCount, pointer, leftoverSize, sizeof(uint16_t)); + + std::uint16_t regionsCount = 0; + ee_utils::readNext(®ionsCount, pointer, leftoverSize, sizeof(std::uint16_t)); subject.regions.resize(regionsCount); ee_utils::readNext( - subject.regions.data(), - pointer, - leftoverSize, - subject.regions.size() * sizeof(uint32_t) + subject.regions.data(), + pointer, + leftoverSize, + subject.regions.size() * sizeof(std::uint32_t) ); - subjects.push_back(subject); + content.subjects.push_back(subject); } DeallocateArray(buffer); @@ -131,35 +135,35 @@ ee_assets::AssetSave::AssetSave(uint8_t* &source, const size_t sourceSize) // SERIALIZERS -uint8_t* ee_assets::AssetSave::Serialize(size_t &size) +std::uint8_t* ee_assets::AssetSave::Serialize(std::size_t &size) { - size = sizeof(uint16_t); - for (ee_data::Subject &subject : subjects) + size = sizeof(std::uint16_t); + for (ee_data::Subject &subject : content.subjects) { size += sizeof(subject.tag); size += sizeof(subject.color); - size += sizeof(uint16_t) + subject.regions.size() * sizeof(uint32_t); + size += sizeof(std::uint16_t) + subject.regions.size() * sizeof(std::uint32_t); } - size_t leftover = size; - uint8_t *result = AllocateArray(size); - uint8_t *pointer = result; + std::size_t leftover = size; + std::uint8_t *result = AllocateArray(size); + std::uint8_t *pointer = result; - uint16_t subjectsCount = static_cast(subjects.size()); - ee_utils::writeNext(pointer, &subjectsCount, leftover, sizeof(uint16_t)); + std::uint16_t subjectsCount = static_cast(content.subjects.size()); + ee_utils::writeNext(pointer, &subjectsCount, leftover, sizeof(std::uint16_t)); - for (ee_data::Subject &subject : subjects) + for (ee_data::Subject &subject : content.subjects) { ee_utils::writeNext(pointer, &subject.tag, leftover, sizeof(subject.tag)); ee_utils::writeNext(pointer, &subject.color, leftover, sizeof(subject.color)); - - uint16_t regionsCount = static_cast(subject.regions.size()); - ee_utils::writeNext(pointer, ®ionsCount, leftover, sizeof(uint16_t)); + + std::uint16_t regionsCount = static_cast(subject.regions.size()); + ee_utils::writeNext(pointer, ®ionsCount, leftover, sizeof(std::uint16_t)); ee_utils::writeNext( - pointer, - subject.regions.data(), - leftover, - subject.regions.size() * sizeof(uint32_t) + pointer, + subject.regions.data(), + leftover, + subject.regions.size() * sizeof(std::uint32_t) ); } diff --git a/engine-api/src/Render.cpp b/engine-api/src/Render.cpp new file mode 100644 index 0000000..32d0976 --- /dev/null +++ b/engine-api/src/Render.cpp @@ -0,0 +1,104 @@ +module; + +#include "Logger.h" +#include +#include +#include +#include +#include +#include + +module Render; + +ee_engine::IRenderer::IRenderer(GLFWwindow *window) +{ + commandsMapping[RendererCommand::UPDATE_REGION] = MAP_WORKER_COMMAND(RendererCommand, UpdateRegionCmd); + + this->window = window; + glfwGetFramebufferSize(window, &screenWidth, &screenHeight); + screenAspect = static_cast(screenWidth) / static_cast(screenHeight); +} + +ee_engine::IRenderer::~IRenderer() +{ + +} + +void ee_engine::IRenderer::RegisterMaterials(const ShaderRefs &shaders) +{ + this->shaders = shaders; +} + +void ee_engine::IRenderer::RegisterMapMesh(MapMesh* mapMesh) +{ + this->mapMesh = mapMesh; +} + +void ee_engine::IRenderer::Draw() +{ + Clear(); + DrawMap(); + DrawUI(); +} + +void ee_engine::IRenderer::ResizeWindow(int width, int height) +{ + screenWidth = width; + screenHeight = height; + screenAspect = static_cast(screenWidth) / static_cast(screenHeight); +} + +void ee_engine::IRenderer::SetCamera(const CameraTransform &camera) +{ + if (camera.zoom <= 0) + { + LOG(WARNING, "Camera zoom cannot be zero or less!"); + return; + } + + this->camera = camera; + + float halfHeight = camera.zoom; + float halfWidth = camera.zoom * screenAspect; + + glm::mat4 P = glm::ortho( + -halfWidth, +halfWidth, + -halfHeight, +halfHeight + ); + + glm::mat4 V = glm::translate( + glm::mat4(1.0f), + glm::vec3(-camera.position, 0.0f) + ); + + viewProjection = P * V; + + ApplyCamera(); +} + +void ee_engine::IRenderer::UpdateRegionCmd(ee_engine::RendererCommand &command) +{ + if (!regionsMapping.contains(command.region.id)) + { + LOG(WARNING, "Updating unregistered region with id: %d", command.region.id); + return; + } + + if (command.region.id != command.region.data.regionId) + { + LOG(ERROR, "Updating regions ID is not supported! Region: %d Changed ID: %d", + command.region.id, command.region.data.regionId); + } + + RegionIndecies mapping = regionsMapping[command.region.id]; + std::vector buffer; + buffer.reserve(mapping.provincesCount); + for (std::size_t i = 0; i < mapping.provincesCount; i++) + { + buffer.push_back(command.region.data); + } + + UpdateProvinces(mapping.startIndex, buffer); + + command.type = ee_engine::RendererCommand::COMPLETED; +} \ No newline at end of file diff --git a/engine-api/src/RenderInterface.cpp b/engine-api/src/RenderInterface.cpp deleted file mode 100644 index 1c886eb..0000000 --- a/engine-api/src/RenderInterface.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include "Logger.h" - -ee_engine::IRenderer::IRenderer(GLFWwindow *window) -{ - this->window = window; - glfwGetFramebufferSize(window, &screenWidth, &screenHeight); - screenAspect = static_cast(screenWidth) / static_cast(screenHeight); -} - -ee_engine::IRenderer::~IRenderer() -{ - -} - -void ee_engine::IRenderer::RegisterMaterials(const ShaderRefs &shaders) -{ - this->shaders = shaders; -} - -void ee_engine::IRenderer::RegisterMapMesh(MapMesh* mapMesh) -{ - this->mapMesh = mapMesh; -} - -void ee_engine::IRenderer::Draw() -{ - Clear(); - DrawMap(); - DrawUI(); -} - -void ee_engine::IRenderer::ResizeWindow(int width, int height) -{ - screenWidth = width; - screenHeight = height; - screenAspect = static_cast(screenWidth) / static_cast(screenHeight); -} - -void ee_engine::IRenderer::SetCamera(const CameraTransform &camera) -{ - if (camera.zoom <= 0) - { - LOG(WARNING, "Camera zoom cannot be zero or less!"); - return; - } - - this->camera = camera; - - float halfHeight = camera.zoom; - float halfWidth = camera.zoom * screenAspect; - - glm::mat4 P = glm::ortho( - -halfWidth, +halfWidth, - -halfHeight, +halfHeight - ); - - glm::mat4 V = glm::translate( - glm::mat4(1.0f), - glm::vec3(-camera.position, 0.0f) - ); - - viewProjection = P * V; - - ApplyCamera(); -} - -ee_engine::CameraTransform ee_engine::IRenderer::getCamera() {return this->camera;} \ No newline at end of file diff --git a/engine/.vscode/launch.json b/engine/.vscode/launch.json deleted file mode 100644 index e8338f2..0000000 --- a/engine/.vscode/launch.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "configurations": [ - { - "type": "cmake", - "request": "launch", - "name": "Debug portfile(s)", - "cmakeDebugType": "external", - "pipeName": "\\\\.\\pipe\\vcpkg_ext_portfile_dbg", - "preLaunchTask": "Debug vcpkg commands" - } - ] -} \ No newline at end of file diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 09cbd2a..b31ea13 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -1,24 +1,6 @@ -cmake_minimum_required (VERSION 3.8) +include(${CMAKE_SOURCE_DIR}/cmake/executable.cmake) -if (POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) - set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") -endif() - -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -project (engine) - - -# List sources - -file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS - "src/*.cpp" - "src/*.c" - "include/*.hpp" - "include/*.h" -) +set(EXE engine) # Find dependencies @@ -29,45 +11,38 @@ find_package(glm CONFIG REQUIRED) # Link library -add_executable(${PROJECT_NAME} ${SOURCES}) +add_executable_target(${EXE}) -target_link_libraries(${PROJECT_NAME} PUBLIC utils) -target_link_libraries(${PROJECT_NAME} PUBLIC engine-api) -target_link_libraries(${PROJECT_NAME} PUBLIC magnum-renderer) +target_link_libraries(${EXE} PUBLIC utils) +target_link_libraries(${EXE} PUBLIC engine-api) +target_link_libraries(${EXE} PUBLIC magnum-renderer) -target_link_libraries(${PROJECT_NAME} PRIVATE Boost::lockfree) -target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash) -target_link_libraries(${PROJECT_NAME} PRIVATE p7) -target_link_libraries(${PROJECT_NAME} PRIVATE glfw) -target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm) - -target_include_directories(${PROJECT_NAME} PUBLIC include/) - -if (CMAKE_VERSION VERSION_GREATER 3.12) - set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) -endif() +target_link_libraries(${EXE} PRIVATE Boost::lockfree) +target_link_libraries(${EXE} PRIVATE xxHash::xxhash) +target_link_libraries(${EXE} PRIVATE p7) +target_link_libraries(${EXE} PRIVATE glfw) +target_link_libraries(${EXE} PRIVATE glm::glm) # Compile options if (APP_VERSION) - string(REPLACE "." ";" APP_VERSION_LIST ${APP_VERSION}) - list(GET APP_VERSION_LIST 0 MAJOR_VERSION) - list(GET APP_VERSION_LIST 1 MINOR_VERSION) - list(GET APP_VERSION_LIST 2 PATCH_VERSION) - target_compile_definitions(${PROJECT_NAME} - PRIVATE APP_VERSION - PRIVATE MAJOR_VERSION=${MAJOR_VERSION} - PRIVATE MINOR_VERSION=${MINOR_VERSION} - PRIVATE PATCH_VERSION=${PATCH_VERSION} - ) + string(REPLACE "." ";" APP_VERSION_LIST ${APP_VERSION}) + list(GET APP_VERSION_LIST 0 MAJOR_VERSION) + list(GET APP_VERSION_LIST 1 MINOR_VERSION) + list(GET APP_VERSION_LIST 2 PATCH_VERSION) + target_compile_definitions(${EXE} + PRIVATE APP_VERSION + PRIVATE MAJOR_VERSION=${MAJOR_VERSION} + PRIVATE MINOR_VERSION=${MINOR_VERSION} + PRIVATE PATCH_VERSION=${PATCH_VERSION} + ) endif() # Set a symbolic link so executable can find the /assets folder set(link_src "${CMAKE_SOURCE_DIR}/assets") set(link_dst "${CMAKE_CURRENT_BINARY_DIR}/assets") -add_custom_command( - TARGET ${PROJECT_NAME} - POST_BUILD COMMAND ${CMAKE_COMMAND} - -E create_symlink ${link_src} ${link_dst} - DEPENDS ${link_dst} - COMMENT "symbolic link ${link_src} => ${link_dst}" +add_custom_command( + TARGET ${EXE} + POST_BUILD COMMAND ${CMAKE_COMMAND} + -E create_symlink ${link_src} ${link_dst} + COMMENT "symbolic link ${link_src} => ${link_dst}" ) \ No newline at end of file diff --git a/engine/include/Actions.hpp b/engine/include/Actions.hpp deleted file mode 100644 index 4a7ff4d..0000000 --- a/engine/include/Actions.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include - -class Actions -{ -public: - static ee_engine::InputHandlers mappings; - -private: - static void Zoom(float dx, float dy); - static void MapScroll(float dx, float dy); - - Actions(); -}; \ No newline at end of file diff --git a/engine/include/AssetManager.hpp b/engine/include/AssetManager.hpp deleted file mode 100644 index fe8628e..0000000 --- a/engine/include/AssetManager.hpp +++ /dev/null @@ -1,172 +0,0 @@ -#pragma once -#include "FileSystem.hpp" -#include - -#include "Logger.h" -#include -#include -#include -#include -#include -#include -#include - -#define INVALID_ASSET_ID UINT32_MAX - -struct AssetAddress -{ - std::atomic resource; -}; - -struct AssetHandle -{ - size_t slot = 0; - uint32_t id = 0; -}; - -class AssetInfo -{ -public: - ee_assets::AssetType type = ee_assets::BINARY; - - std::atomic isReady; - AssetAddress* resourceAddress; - - AssetInfo(void *resource); - - AssetInfo(const AssetInfo&) = delete; - AssetInfo& operator=(const AssetInfo&) = delete; - - AssetInfo(AssetInfo&& other) noexcept; - AssetInfo& operator=(AssetInfo&& other) noexcept; -}; - -struct AssetLoadingEntry -{ - AssetHandle handle; - FileHandle* file; - IFileSystem* fileOwner; -}; - -struct AssetStreamCommand -{ - enum Type - { - NONE, - - LOAD, - FIND, - GET, - - COMPLETED - } type = NONE; - - AssetHandle target; - uint32_t targetId = INVALID_ASSET_ID; - std::filesystem::path targetPath; - ee_assets::AssetType targetType = ee_assets::BINARY; - std::atomic* out; -}; - -class AssetManager -{ -public: - std::atomic isRunning; - - AssetManager(); - ~AssetManager(); - - void Start(); - void Shutdown(); - - void LoadDir(ee_assets::AssetType type, const std::filesystem::path &path); - - void LoadAsync(ee_assets::AssetType type, const std::filesystem::path &path); - AssetHandle& Find(const std::filesystem::path &path); - AssetHandle& Find(const uint32_t &id); - template T& FindOnce(const std::filesystem::path &path); - template T& FindOnce(const uint32_t &id); - void Redirect(AssetHandle &handle, void *resource); - template T& Get(const AssetHandle &handle); - void Free(AssetHandle &handle); - -private: - std::stop_token *stoken; - std::jthread streamingThread; - boost::lockfree::spsc_queue> commands; - - IFileSystem *diskSystem; - - std::vector activeAssets; - std::unordered_map assetsIdMapping; - std::unordered_map assetsMapping; - std::vector freeAssetSlots; - std::vector loadingEntries; - - std::vector binaryStorage; - std::vector savesStorage; - std::vector mapMeshesStorage; - std::vector shadersStorage; - std::vector materialsStorage; - - void Threading(); - void Request(const AssetStreamCommand &command); - void Request(const AssetStreamCommand::Type &type); - void Loop(); - void ProcessCommand(AssetStreamCommand &command); - void Release(); - - template void FinishLoadConstruct(AssetLoadingEntry &loaded, std::vector &storage); - template void FinishLoadPlain(AssetLoadingEntry &loaded, std::vector &storage); - template void ClearStorage(std::vector &storage); -}; - -template T& AssetManager::Get(const AssetHandle &handle) -{ - std::atomic result; - AssetStreamCommand command { - .type = AssetStreamCommand::GET, - .target = handle, - .out = &result - }; - Request(command); - while (command.out->load() == nullptr); - return *reinterpret_cast(command.out->load()); -} - -template T& AssetManager::FindOnce(const std::filesystem::path &path) -{ - return Get(Find(path)); -} - -template T& AssetManager::FindOnce(const uint32_t &id) -{ - return Get(Find(id)); -} - -template void AssetManager::FinishLoadConstruct(AssetLoadingEntry &loaded, std::vector &storage) -{ - T* resource = Allocate(loaded.file->data, loaded.file->size); - storage.push_back(resource); - Redirect(loaded.handle, storage.back()); -} - -template void AssetManager::FinishLoadPlain(AssetLoadingEntry &loaded, std::vector &storage) -{ - T* resource = Allocate(); - if (loaded.file->size < sizeof(T)) - LOG(CRITICAL, "File size is less than needed for asset of type: %d", typeid(T).name()); - std::memcpy(resource, loaded.file->data, sizeof(T)); - storage.push_back(resource); - Redirect(loaded.handle, storage.back()); -} - -template void AssetManager::ClearStorage(std::vector &storage) -{ - for (T* &resource : storage) - { - if (resource != nullptr) - Deallocate(resource); - } - storage.clear(); -} \ No newline at end of file diff --git a/engine/include/Engine.hpp b/engine/include/Engine.hpp deleted file mode 100644 index 8032060..0000000 --- a/engine/include/Engine.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include -#include "AssetManager.hpp" - -class Engine -{ -public: - static GLFWwindow *window; - static ee_engine::IInput *input; - static AssetManager *assetManager; - static ee_engine::IRenderer *renderer; - - static void Shutdown(); - -private: - Engine(); -}; diff --git a/engine/include/FileSystem.hpp b/engine/include/FileSystem.hpp deleted file mode 100644 index 1df5a35..0000000 --- a/engine/include/FileSystem.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -#include -#include -#include - -#ifdef _WIN32 - #include -#endif - -#ifdef __linux__ -#endif - -#define FILE_OPEN_NONE 0 -#define FILE_OPEN_READ (1 << 0) -#define FILE_OPEN_WRITE (1 << 1) -#define FILE_OPEN_MMAP (1 << 2) - -#define FILE_READ_SEQUENTIAL 0 -#define FILE_READ_RANDOM_ACCESS (1 << 0) - -struct FileHandle -{ - size_t id = 0; - - size_t size = 0; - size_t bufferSize = 0; - uint8_t *data = nullptr; - uint8_t *buffer = nullptr; - - #ifndef NDEBUG - std::filesystem::path debugPath; - #endif - - #ifdef _WIN32 - HANDLE win32Handle = INVALID_HANDLE_VALUE; - OVERLAPPED overlapped; - #endif - - #ifdef __linux__ - #endif -}; - -class IFileSystem -{ -public: - virtual FileHandle& Open(const std::filesystem::path &path, const uint32_t flags) = 0; - virtual void ReadAsync(FileHandle &file, const uint32_t bufferSize, const uint32_t flags) = 0; - virtual bool PollReady(FileHandle &file) = 0; - virtual void Close(FileHandle &file) = 0; - - ~IFileSystem(); - -protected: - std::vector activeFiles; - std::vector failedFiles; - std::vector freeFileSlots; -}; - -class NativeFileSystem : public IFileSystem -{ -public: - FileHandle& Open(const std::filesystem::path &path, const uint32_t flags) override; - void ReadAsync(FileHandle &file, const uint32_t bufferSize, uint32_t flags) override; - bool PollReady(FileHandle &file) override; - void Close(FileHandle &file) override; - -private: - -}; \ No newline at end of file diff --git a/engine/include/GLFWInput.hpp b/engine/include/GLFWInput.hpp deleted file mode 100644 index 755cfa0..0000000 --- a/engine/include/GLFWInput.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include -#include - -class GLFWInput : public ee_engine::IInput -{ -public: - GLFWInput(ee_engine::InputHandlers handlers); - void Poll() override; -}; \ No newline at end of file diff --git a/engine/include/compile_config.hpp b/engine/include/compile_config.hpp index 6fe4a2e..fbdbf69 100644 --- a/engine/include/compile_config.hpp +++ b/engine/include/compile_config.hpp @@ -1,17 +1,20 @@ -#pragma once +#ifndef ETREDIAEMPIRES_COMPILE_CONFIG_HPP +#define ETREDIAEMPIRES_COMPILE_CONFIG_HPP #define P7_LOGS_PATH L" /P7.Dir=logs/game/" #ifdef NDEBUG - #define P7_SINK L" /P7.Sink=FileTxt" +#define P7_SINK L" /P7.Sink=FileTxt" #else - #define P7_SINK L" /P7.Sink=Console" +#define P7_SINK L" /P7.Sink=Console" #endif #ifndef APP_VERSION - #define MAJOR_VERSION 0 - #define MINOR_VERSION 0 - #define PATCH_VERSION 0 +#define MAJOR_VERSION 0 +#define MINOR_VERSION 0 +#define PATCH_VERSION 0 #endif -#define ASSETS_HASH_SPACE 0 \ No newline at end of file +#define ASSETS_HASH_SPACE 0 + +#endif //ETREDIAEMPIRES_COMPILE_CONFIG_HPP diff --git a/engine/modules/Actions.cppm b/engine/modules/Actions.cppm new file mode 100644 index 0000000..43ac330 --- /dev/null +++ b/engine/modules/Actions.cppm @@ -0,0 +1,17 @@ +export module Actions; +import Input; + +export +{ + class Actions + { + public: + static ee_engine::InputHandlers mappings; + + private: + static void Zoom(float dx, float dy); + static void MapScroll(float dx, float dy); + + Actions(); + }; +} \ No newline at end of file diff --git a/engine/modules/AssetManager.cppm b/engine/modules/AssetManager.cppm new file mode 100644 index 0000000..60abb68 --- /dev/null +++ b/engine/modules/AssetManager.cppm @@ -0,0 +1,425 @@ +module; + +#include "Logger.h" +#include "compile_config.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +export module AssetManager; + export import AssetData; + +import allocator; +import worker; +import FileSystem; + +export +{ + struct AssetAddress + { + std::atomic resource; + }; + + struct AssetHandle + { + inline static constexpr std::uint32_t INVALID_ASSET_ID = UINT32_MAX; + std::size_t slot = 0; + std::uint32_t id = 0; + }; + + class AssetInfo + { + public: + ee_assets::AssetType type = ee_assets::BINARY; + + std::atomic isReady; + AssetAddress* resourceAddress; + + AssetInfo(void *resource) + { + this->resourceAddress = Allocate(); + this->resourceAddress->resource.store(resource); + } + + AssetInfo(const AssetInfo&) = delete; + AssetInfo& operator=(const AssetInfo&) = delete; + + AssetInfo(AssetInfo&& other) noexcept : + type(other.type), + resourceAddress(other.resourceAddress) + { + isReady.store(other.isReady.load(std::memory_order_relaxed), std::memory_order_relaxed); + + other.resourceAddress = nullptr; + other.isReady.store(false, std::memory_order_relaxed); + } + + AssetInfo& operator=(AssetInfo&& other) noexcept + { + if (this != &other) + { + type = other.type; + resourceAddress = other.resourceAddress; + isReady.store(other.isReady.load(std::memory_order_relaxed), std::memory_order_relaxed); + + other.resourceAddress = nullptr; + other.isReady.store(false, std::memory_order_relaxed); + } + return *this; + } + }; + + struct AssetLoadingEntry + { + AssetHandle handle; + FileHandle* file; + IFileSystem* fileOwner; + }; + + struct AssetStreamCommand : ee_utils::WorkerCommand + { + enum Type : std::uint8_t + { + NONE, + + LOAD, + FIND, + GET, + + COMPLETED + }; + + AssetHandle target; + std::uint32_t targetId = AssetHandle::INVALID_ASSET_ID; + std::filesystem::path targetPath; + ee_assets::AssetType targetType = ee_assets::BINARY; + std::atomic* out = nullptr; + }; + + class AssetManager final : public ee_utils::ThreadedWorker + { + public: + AssetManager() : ee_utils::ThreadedWorker(L"Assets Stream") + { + commandsMapping[AssetStreamCommand::LOAD] = MAP_WORKER_COMMAND(AssetStreamCommand, LoadCmd); + commandsMapping[AssetStreamCommand::FIND] = MAP_WORKER_COMMAND(AssetStreamCommand, FindCmd); + commandsMapping[AssetStreamCommand::GET] = MAP_WORKER_COMMAND(AssetStreamCommand, GetCmd); + + diskSystem = Allocate(); + } + + ~AssetManager() + { + Deallocate(diskSystem); + } + + void LoadDir(ee_assets::AssetType type, const std::filesystem::path &path) + { + for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(path)) + { + if (entry.is_directory()) continue; + LoadAsync(type, entry.path()); + } + } + + void LoadAsync(ee_assets::AssetType type, const std::filesystem::path &path) + { + AssetStreamCommand command; + command.type = AssetStreamCommand::LOAD; + command.targetPath = path; + command.targetType = type; + + Request(command); + } + + AssetHandle& Find(const std::filesystem::path &path) + { + std::atomic result; + AssetStreamCommand command; + command.type = AssetStreamCommand::FIND; + command.targetPath = path; + command.out = &result; + + Request(command); + while (command.out->load() == nullptr); + return *reinterpret_cast(command.out->load()); + } + + AssetHandle& Find(const std::uint32_t &id) + { + std::atomic result; + AssetStreamCommand command; + command.type = AssetStreamCommand::FIND; + command.targetId = id; + command.out = &result; + + Request(command); + while (command.out->load() == nullptr); + return *reinterpret_cast(command.out->load()); + } + + // Returned resource reference should not be stored + template T& FindOnce(const std::filesystem::path &path) + { + return Get(Find(path)); + } + + // Returned resource reference should not be stored + template T& FindOnce(const std::uint32_t &id) + { + return Get(Find(id)); + } + + void Redirect(AssetHandle &handle, void *resource) + { + AssetInfo &asset = activeAssets[handle.slot]; + if (asset.resourceAddress == nullptr) + { + LOG(WARNING, "Attempt to redirect empty handle"); + return; + } + + // TODO: LEAK! Free old resource after redirecting handler to other resource + if (asset.resourceAddress->resource.load() != nullptr) + { + void* oldResource = asset.resourceAddress->resource.exchange(nullptr, std::memory_order_acq_rel); + //if (oldResource) + //Deallocate(oldResource); + } + + asset.resourceAddress->resource.store(resource); + } + + // Returned resource reference should not be stored + template T& Get(const AssetHandle &handle) + { + std::atomic result; + AssetStreamCommand command; + command.type = AssetStreamCommand::GET; + command.target = handle; + command.out = &result; + + Request(command); + while (command.out->load() == nullptr); + return *reinterpret_cast(command.out->load()); + } + + void Free(AssetHandle &handle) + { + AssetInfo &asset = activeAssets[handle.slot]; + Redirect(handle, nullptr); + Deallocate(asset.resourceAddress); + asset.resourceAddress = nullptr; + + freeAssetSlots.push_back(handle.slot); + } + + protected: + void Update() override + { + // TODO: FinishLoadTasks() + for (AssetLoadingEntry &entry : loadingEntries) + { + bool isReady = entry.fileOwner->PollReady(*entry.file); + if (isReady) + { + AssetInfo& asset = activeAssets[entry.handle.slot]; + + switch (asset.type) + { + case ee_assets::MAP_MESH: + FinishLoadConstruct(entry, mapMeshesStorage); + break; + case ee_assets::SAVE: + FinishLoadConstruct(entry, savesStorage); + break; + + case ee_assets::SHADER: + FinishLoadConstruct(entry, shadersStorage); + break; + case ee_assets::MATERIAL: + FinishLoadPlain(entry, materialsStorage); + break; + case ee_assets::IMAGE: + break; + + case ee_assets::BINARY: + default: + FinishLoadConstruct(entry, binaryStorage); + break; + } + + entry.fileOwner->Close(*entry.file); + #ifndef NDEBUG + LOG(INFO, "Asset loaded: [%hs]", entry.file->debugPath.generic_u8string().c_str()); + #endif + entry.file = nullptr; + asset.isReady.store(true); + } + } + + std::erase_if(loadingEntries, [](const AssetLoadingEntry &entry) { + return entry.file == nullptr; + }); + } + + void Release() override + { + for (AssetInfo &asset : activeAssets) + { + //TODO: LEAK! Free resource + if (asset.resourceAddress->resource.load() != nullptr) + { + void* resource = asset.resourceAddress->resource.exchange(nullptr, std::memory_order_acq_rel); + //if (resource) + //Deallocate(resource); + } + Deallocate(asset.resourceAddress); + } + activeAssets.clear(); + + for (auto &mapping : assetsMapping) + Deallocate(mapping.second); + assetsMapping.clear(); + + binaryStorage.clear(); + mapMeshesStorage.clear(); + shadersStorage.clear(); + materialsStorage.clear(); + + LOG(INFO, "Asset Streaming is released"); + isRunning.store(false); + } + + private: + IFileSystem *diskSystem; + + std::vector activeAssets; + std::unordered_map assetsIdMapping; + std::unordered_map assetsMapping; + std::vector freeAssetSlots; + std::vector loadingEntries; + + std::vector binaryStorage; + std::vector savesStorage; + std::vector mapMeshesStorage; + std::vector shadersStorage; + std::vector materialsStorage; + + void LoadCmd(AssetStreamCommand &command) + { + LOG(INFO, "LOAD command: [%hs]", command.targetPath.generic_u8string().c_str()); + + /* TODO: process path to select FS */ + /* TODO: select between async load and sync job task */ + + //Async load of full file without mmap in one thread + FileHandle &file = diskSystem->Open(command.targetPath, IFileSystem::FILE_OPEN_READ); + + diskSystem->ReadAsync(file, static_cast(file.size), IFileSystem::FILE_READ_SEQUENTIAL); + + AssetHandle* handle = Allocate(); + AssetInfo asset(nullptr); + asset.type = command.targetType; + + std::size_t assetPos = 0; + if (freeAssetSlots.size() > 0) + { + assetPos = freeAssetSlots.back(); + Deallocate(activeAssets[assetPos].resourceAddress); + activeAssets[assetPos] = std::move(asset); + freeAssetSlots.pop_back(); + } + else + { + activeAssets.push_back(std::move(asset)); + assetPos = activeAssets.size() - 1; + } + handle->slot = assetPos; + auto assetPath = command.targetPath.generic_u8string(); + std::uint32_t assetId = assetsIdMapping[command.targetPath] = + XXH32(assetPath.data(), assetPath.size(), ASSETS_HASH_SPACE); + handle->id = assetId; + assetsMapping[assetId] = handle; + + AssetLoadingEntry loadingEntry { + .handle = *handle, + .file = &file, + .fileOwner = diskSystem + }; + loadingEntries.push_back(loadingEntry); + + command.type = AssetStreamCommand::COMPLETED; + } + + void FindCmd(AssetStreamCommand &command) + { + std::uint32_t id = command.targetId; + if (id == AssetHandle::INVALID_ASSET_ID) + { + std::unordered_map::iterator idMapping = assetsIdMapping.find(command.targetPath); + if (idMapping == assetsIdMapping.end()) + return; + id = idMapping->second; + } + + std::unordered_map::iterator assetMapping = assetsMapping.find(id); + + if (assetMapping == assetsMapping.end()) + return; + + if (command.out != nullptr) + command.out->store(assetMapping->second); + + command.type = AssetStreamCommand::COMPLETED; + } + + void GetCmd(AssetStreamCommand &command) + { + if (activeAssets.size() <= command.target.slot) + return; + if (!activeAssets[command.target.slot].isReady) + return; + + if (command.out != nullptr) + command.out->store(activeAssets[command.target.slot].resourceAddress->resource); + + command.type = AssetStreamCommand::COMPLETED; + } + + template void FinishLoadConstruct(AssetLoadingEntry &loaded, std::vector &storage) + { + T* resource = Allocate(loaded.file->data, loaded.file->size); + storage.push_back(resource); + Redirect(loaded.handle, storage.back()); + } + + template void FinishLoadPlain(AssetLoadingEntry &loaded, std::vector &storage) + { + T* resource = Allocate(); + if (loaded.file->size < sizeof(T)) + LOG(CRITICAL, "File size is less than needed for asset of type: %d", typeid(T).name()); + std::memcpy(resource, loaded.file->data, sizeof(T)); + storage.push_back(resource); + Redirect(loaded.handle, storage.back()); + } + + template void ClearStorage(std::vector &storage) + { + for (T* &resource : storage) + { + if (resource != nullptr) + Deallocate(resource); + } + storage.clear(); + } + }; +} diff --git a/engine/modules/Client.cppm b/engine/modules/Client.cppm new file mode 100644 index 0000000..b623526 --- /dev/null +++ b/engine/modules/Client.cppm @@ -0,0 +1,51 @@ +module; + +#include + +export module Client; +import worker; +import GameData; +import DataChannel; +import AssetManager; + +export +{ + struct ClientCommand : public ee_utils::WorkerCommand + { + enum Type : std::uint8_t + { + NONE, + + SEND, + + COMPLETED + }; + }; + + class Client final : public ee_utils::ThreadedWorker + { + public: + Client(); + ~Client(); + void Init(); + + //void Send(); -> Request(SEND) + + const IDataChannel* GetConnection(); + void ConnectServer(); + + void LoadSave(const AssetHandle save); + + protected: + void Update() override; + void Release() override; + + private: + NetworkChannel *networkConnection = nullptr; + AssetHandle save; + + void SendCmd(ClientCommand &command); + + void ViewModelSubject(ee_data::Subject subject); + }; +} \ No newline at end of file diff --git a/engine/modules/DataChannel.cppm b/engine/modules/DataChannel.cppm new file mode 100644 index 0000000..d173768 --- /dev/null +++ b/engine/modules/DataChannel.cppm @@ -0,0 +1,24 @@ +module; + +export module DataChannel; + +export +{ + class IDataChannel + { + public: + // virtual void Request() = 0; + // virtual void Listen() = 0; + // virtual void Mute() = 0; + }; + + class NetworkChannel final : public IDataChannel + { + + }; + + class ThreadChannel final : public IDataChannel + { + + }; +} \ No newline at end of file diff --git a/engine/modules/Engine.cppm b/engine/modules/Engine.cppm new file mode 100644 index 0000000..8fcb8d8 --- /dev/null +++ b/engine/modules/Engine.cppm @@ -0,0 +1,59 @@ +module; + +#include + +export module Engine; + export import Render; + export import Input; + export import AssetManager; + export import Client; + +import allocator; +import worker; + +export +{ + class Engine + { + public: + inline static GLFWwindow *window; + inline static ee_engine::IInput *input; + inline static AssetManager *assetManager; + inline static ee_engine::IRenderer *renderer; + inline static Client *client; + + static void Shutdown() + { + if (input != nullptr) + Deallocate(input); + + if (renderer != nullptr) + { + renderer->Shutdown(); + Deallocate(renderer); + } + renderer = nullptr; + + WaitThreadShutdown(assetManager); + WaitThreadShutdown(client); + + glfwDestroyWindow(window); + glfwTerminate(); + } + + template + static void WaitThreadShutdown(T* &thread) + { + if (thread != nullptr) + { + thread->Shutdown(); + while(thread->isRunning.load()) {} + Deallocate(thread); + } + thread = nullptr; + } + + private: + Engine(); + }; +} \ No newline at end of file diff --git a/engine/modules/FileSystem.cppm b/engine/modules/FileSystem.cppm new file mode 100644 index 0000000..484794e --- /dev/null +++ b/engine/modules/FileSystem.cppm @@ -0,0 +1,72 @@ +module; + +#include +#include +#include +#include +#include + +export module FileSystem; + +export +{ + struct FileHandle { + std::size_t id = 0; + + std::size_t size = 0; + std::size_t bufferSize = 0; + std::uint8_t *data = nullptr; + std::uint8_t *buffer = nullptr; + + #ifndef NDEBUG + std::filesystem::path debugPath; + #endif + + #ifdef _WIN32 + HANDLE win32Handle = INVALID_HANDLE_VALUE; + OVERLAPPED overlapped; + #endif + + #ifdef __linux__ + #endif + }; + + class IFileSystem { + public: + inline static constexpr std::uint32_t FILE_OPEN_NONE = 0; + inline static constexpr std::uint32_t FILE_OPEN_READ = (1 << 0); + inline static constexpr std::uint32_t FILE_OPEN_WRITE = (1 << 1); + inline static constexpr std::uint32_t FILE_OPEN_MMAP = (1 << 2); + inline static constexpr std::uint32_t FILE_READ_SEQUENTIAL = 0; + inline static constexpr std::uint32_t FILE_READ_RANDOM_ACCESS = (1 << 0); + + virtual FileHandle &Open(const std::filesystem::path &path, const std::uint32_t flags) = 0; + + virtual void ReadAsync(FileHandle &file, const std::uint32_t bufferSize, const std::uint32_t flags) = 0; + + virtual bool PollReady(FileHandle &file) = 0; + + virtual void Close(FileHandle &file) = 0; + + virtual ~IFileSystem(); + + protected: + std::vector activeFiles; + std::vector failedFiles; + std::vector freeFileSlots; + }; + + class NativeFileSystem : public IFileSystem { + public: + FileHandle &Open(const std::filesystem::path &path, const std::uint32_t flags) override; + + void ReadAsync(FileHandle &file, const std::uint32_t bufferSize, std::uint32_t flags) override; + + bool PollReady(FileHandle &file) override; + + void Close(FileHandle &file) override; + + private: + + }; +} \ No newline at end of file diff --git a/engine/modules/GLFWInput.cppm b/engine/modules/GLFWInput.cppm new file mode 100644 index 0000000..68c6a0d --- /dev/null +++ b/engine/modules/GLFWInput.cppm @@ -0,0 +1,16 @@ +module; + +#include + +export module GLFWInput; +import Input; + +export { + class GLFWInput : public ee_engine::IInput + { + public: + GLFWInput(ee_engine::InputHandlers handlers); + + void Poll() override; + }; +} \ No newline at end of file diff --git a/engine/src/Actions.cpp b/engine/src/Actions.cpp index 76da11e..1d5a755 100644 --- a/engine/src/Actions.cpp +++ b/engine/src/Actions.cpp @@ -1,7 +1,10 @@ -#include "Actions.hpp" -#include "Engine.hpp" +module; + #include +module Actions; +import Engine; + ee_engine::InputHandlers Actions::mappings { .zooming = Zoom, .mapScroll = MapScroll diff --git a/engine/src/AssetManager.cpp b/engine/src/AssetManager.cpp deleted file mode 100644 index ecb2441..0000000 --- a/engine/src/AssetManager.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#include "compile_config.hpp" -#include "AssetManager.hpp" -#include -#include "Logger.h" -#include -#include -#include - - -AssetInfo::AssetInfo(void *resource) -{ - this->resourceAddress = Allocate(); - this->resourceAddress->resource.store(resource); -} - -AssetInfo::AssetInfo(AssetInfo&& other) noexcept : - type(other.type), - resourceAddress(other.resourceAddress) -{ - isReady.store(other.isReady.load(std::memory_order_relaxed), std::memory_order_relaxed); - - other.resourceAddress = nullptr; - other.isReady.store(false, std::memory_order_relaxed); -} - -AssetInfo& AssetInfo::operator=(AssetInfo&& other) noexcept -{ - if (this != &other) - { - type = other.type; - resourceAddress = other.resourceAddress; - isReady.store(other.isReady.load(std::memory_order_relaxed), std::memory_order_relaxed); - - other.resourceAddress = nullptr; - other.isReady.store(false, std::memory_order_relaxed); - } - return *this; -} - -void AssetManager::Redirect(AssetHandle &handle, void* resource) -{ - AssetInfo &asset = activeAssets[handle.slot]; - if (asset.resourceAddress == nullptr) - { - LOG(WARNING, "Attempt to redirect empty handle"); - return; - } - - if (asset.resourceAddress->resource.load() != nullptr) - { - void* oldResource = asset.resourceAddress->resource.exchange(nullptr, std::memory_order_acq_rel); - if (oldResource) - //Deallocate(asset.resourceAddress->resource.load()); - Deallocate(oldResource); - } - - asset.resourceAddress->resource.store(resource); -} - -void AssetManager::Free(AssetHandle &handle) -{ - AssetInfo &asset = activeAssets[handle.slot]; - Redirect(handle, nullptr); - Deallocate(asset.resourceAddress); - asset.resourceAddress = nullptr; - - freeAssetSlots.push_back(handle.slot); -} - -AssetManager::AssetManager() -{ - diskSystem = Allocate(); -} - -AssetManager::~AssetManager() -{ - Deallocate(diskSystem); -} - -void AssetManager::Request(const AssetStreamCommand &command) -{ - commands.push(command); -} - -void AssetManager::Request(const AssetStreamCommand::Type &type) -{ - commands.push(AssetStreamCommand {.type = type}); -} - -void AssetManager::LoadAsync(ee_assets::AssetType type, const std::filesystem::path &path) -{ - AssetStreamCommand command { - .type = AssetStreamCommand::LOAD, - .targetPath = path, - .targetType = type - }; - Request(command); -} - -AssetHandle& AssetManager::Find(const std::filesystem::path &path) -{ - std::atomic result; - AssetStreamCommand command { - .type = AssetStreamCommand::FIND, - .targetPath = path, - .out = &result - }; - Request(command); - while (command.out->load() == nullptr); - return *reinterpret_cast(command.out->load()); -} -AssetHandle& AssetManager::Find(const uint32_t &id) -{ - std::atomic result; - AssetStreamCommand command { - .type = AssetStreamCommand::FIND, - .targetId = id, - .out = &result - }; - Request(command); - while (command.out->load() == nullptr); - return *reinterpret_cast(command.out->load()); -} - -void AssetManager::Start() -{ - if (isRunning) throw std::logic_error("Asset Streaming can be started only once"); - - isRunning.store(true); - streamingThread = std::jthread([this](std::stop_token stop) { - this->stoken = &stop; - Threading(); - }); -} - -void AssetManager::Shutdown() -{ - streamingThread.request_stop(); -} - -void AssetManager::Threading() -{ - Logger::trace->Register_Thread(L"Asset Stream", 0); - LOG(INFO, "Asset Streaming thread started"); - - Loop(); - - Release(); -} - -void AssetManager::Loop() -{ - AssetStreamCommand commandBuffer; - std::vector incompleteCommands; - while (!stoken->stop_requested()) - { - while (commands.pop(commandBuffer)) - { - ProcessCommand(commandBuffer); - if (commandBuffer.type != AssetStreamCommand::COMPLETED) - incompleteCommands.push_back(commandBuffer); - } - for (AssetStreamCommand &command : incompleteCommands) - { - commands.push(command); - } - incompleteCommands.clear(); - - // TODO: FinishLoadTasks() - for (AssetLoadingEntry &entry : loadingEntries) - { - bool isReady = entry.fileOwner->PollReady(*entry.file); - if (isReady) - { - AssetInfo& asset = activeAssets[entry.handle.slot]; - - switch (asset.type) - { - case ee_assets::MAP_MESH: - FinishLoadConstruct(entry, mapMeshesStorage); - break; - case ee_assets::SAVE: - FinishLoadConstruct(entry, savesStorage); - break; - - case ee_assets::SHADER: - FinishLoadConstruct(entry, shadersStorage); - break; - case ee_assets::MATERIAL: - FinishLoadPlain(entry, materialsStorage); - break; - case ee_assets::IMAGE: - break; - - case ee_assets::BINARY: - default: - FinishLoadConstruct(entry, binaryStorage); - break; - } - - entry.fileOwner->Close(*entry.file); -#ifndef NDEBUG - LOG(INFO, "Asset loaded: [%hs]", entry.file->debugPath.generic_u8string().c_str()); -#endif - entry.file = nullptr; - asset.isReady.store(true); - } - } - - std::erase_if(loadingEntries, [](const AssetLoadingEntry &entry) { - return entry.file == nullptr; - }); - } -} -void AssetManager::ProcessCommand(AssetStreamCommand &command) -{ - // TODO: method for each command - switch(command.type) - { - case AssetStreamCommand::LOAD: - { - LOG(INFO, "LOAD command: [%hs]", command.targetPath.generic_u8string().c_str()); - - /* TODO: process path to select FS */ - /* TODO: select between async load and sync job task */ - - //Async load of full file without mmap in one thread - FileHandle &file = diskSystem->Open(command.targetPath, FILE_OPEN_READ); - - diskSystem->ReadAsync(file, static_cast(file.size), FILE_READ_SEQUENTIAL); - - AssetHandle* handle = Allocate(); - AssetInfo asset(nullptr); - asset.type = command.targetType; - - size_t assetPos = 0; - if (freeAssetSlots.size() > 0) - { - assetPos = freeAssetSlots.back(); - Deallocate(activeAssets[assetPos].resourceAddress); - activeAssets[assetPos] = std::move(asset); - freeAssetSlots.pop_back(); - } - else - { - activeAssets.push_back(std::move(asset)); - assetPos = activeAssets.size() - 1; - } - handle->slot = assetPos; - auto assetPath = command.targetPath.generic_u8string(); - uint32_t assetId = assetsIdMapping[command.targetPath] = - XXH32(assetPath.data(), assetPath.size(), ASSETS_HASH_SPACE); - handle->id = assetId; - assetsMapping[assetId] = handle; - - AssetLoadingEntry loadingEntry { - .handle = *handle, - .file = &file, - .fileOwner = diskSystem - }; - loadingEntries.push_back(loadingEntry); - - command.type = AssetStreamCommand::COMPLETED; - break; - } - - case AssetStreamCommand::FIND: - { - uint32_t id = command.targetId; - if (id == INVALID_ASSET_ID) - { - std::unordered_map::iterator idMapping = assetsIdMapping.find(command.targetPath); - if (idMapping == assetsIdMapping.end()) - break; - id = idMapping->second; - } - - std::unordered_map::iterator assetMapping = assetsMapping.find(id); - - if (assetMapping == assetsMapping.end()) - break; - - command.out->store(assetMapping->second); - - command.type = AssetStreamCommand::COMPLETED; - break; - } - - case AssetStreamCommand::GET: - { - if (activeAssets.size() <= command.target.slot) - break; - if (!activeAssets[command.target.slot].isReady) - break; - - command.out->store(activeAssets[command.target.slot].resourceAddress->resource); - - command.type = AssetStreamCommand::COMPLETED; - break; - } - - default: - { - LOG(WARNING, "Unhandled command. Type id: %d", command.type); - break; - } - } -} - -void AssetManager::Release() -{ - for (AssetInfo &asset : activeAssets) - { - if (asset.resourceAddress->resource.load() != nullptr) - { - void* resource = asset.resourceAddress->resource.exchange(nullptr, std::memory_order_acq_rel); - if (resource) - Deallocate(resource); - } - Deallocate(asset.resourceAddress); - } - activeAssets.clear(); - - for (auto &mapping : assetsMapping) - Deallocate(mapping.second); - assetsMapping.clear(); - - binaryStorage.clear(); - mapMeshesStorage.clear(); - shadersStorage.clear(); - materialsStorage.clear(); - - LOG(INFO, "Asset Streaming is released"); - isRunning.store(false); -} - -void AssetManager::LoadDir(ee_assets::AssetType type, const std::filesystem::path &path) -{ - for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(path)) - { - if (entry.is_directory()) continue; - LoadAsync(type, entry.path()); - } -} \ No newline at end of file diff --git a/engine/src/Client.cpp b/engine/src/Client.cpp new file mode 100644 index 0000000..765b1db --- /dev/null +++ b/engine/src/Client.cpp @@ -0,0 +1,93 @@ +module; + +#include "Logger.h" +#include +#include +#include + +module Client; +import allocator; +import MapView; +import Engine; + +Client::Client() : ee_utils::ThreadedWorker(L"Client") +{ + commandsMapping[ClientCommand::SEND] = MAP_WORKER_COMMAND(ClientCommand, SendCmd); + +} + +void Client::Init() +{ + if (Engine::renderer == nullptr || !Engine::renderer->isReady()) + { + LOG(CRITICAL, "Renderer is not ready. Client cannot be created"); + throw std::logic_error("Renderer is not ready"); + } + + // TEST + ee_assets::AssetSave &asset = Engine::assetManager->Get(save); + ViewModelSubject(asset.content.subjects[0]); + ViewModelSubject(asset.content.subjects[1]); +} + +const IDataChannel* Client::GetConnection() +{ + return networkConnection; +} + +void Client::ConnectServer() +{ + if (networkConnection != nullptr) + Deallocate(networkConnection); + + networkConnection = Allocate(); +} + +void Client::LoadSave(const AssetHandle save) +{ + this->save = save; +} + +void Client::Update() +{ + +} + +void Client::Release() +{ + +} + + +void Client::SendCmd(ClientCommand &command) +{ + + + command.type = ClientCommand::COMPLETED; +} + + +void Client::ViewModelSubject(ee_data::Subject subject) +{ + for (const std::uint32_t region : subject.regions) + { + ee_engine::ProvinceSSBO vm { + .regionId = region, + .color = subject.color + }; + + ee_engine::RendererCommand cmd; + cmd.type = ee_engine::RendererCommand::UPDATE_REGION; + cmd.region = {.id = region, .data = vm}; + + Engine::renderer->Request(cmd); + } +} + + + +Client::~Client() +{ + if (networkConnection != nullptr) + Deallocate(networkConnection); +} \ No newline at end of file diff --git a/engine/src/Engine.cpp b/engine/src/Engine.cpp deleted file mode 100644 index f4a47b8..0000000 --- a/engine/src/Engine.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "Engine.hpp" -#include - -GLFWwindow* Engine::window; - -ee_engine::IInput* Engine::input; -AssetManager* Engine::assetManager; -ee_engine::IRenderer* Engine::renderer; - -void Engine::Shutdown() -{ - if (input != nullptr) - Deallocate(input); - - if (renderer != nullptr) - { - renderer->Shutdown(); - Deallocate(renderer); - } - renderer = nullptr; - - if (assetManager != nullptr) - { // Wait for asset manager to clean and shutdown - assetManager->Shutdown(); - while(assetManager->isRunning.load()) {} - Deallocate(assetManager); - } - assetManager = nullptr; - - glfwDestroyWindow(window); - glfwTerminate(); -} \ No newline at end of file diff --git a/engine/src/FileSystem.cpp b/engine/src/FileSystem.cpp index 06b6fb2..ef66758 100644 --- a/engine/src/FileSystem.cpp +++ b/engine/src/FileSystem.cpp @@ -1,6 +1,13 @@ -#include "FileSystem.hpp" +module; + #include "Logger.h" -#include +#include +#include +#include + +module FileSystem; +import allocator; + IFileSystem::~IFileSystem() { @@ -12,13 +19,13 @@ IFileSystem::~IFileSystem() #ifdef _WIN32 -FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const uint32_t flags) +FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const std::uint32_t flags) { FileHandle* result = Allocate(); - #ifndef NDEBUG +#ifndef NDEBUG result->debugPath = path; - #endif +#endif DWORD createFileMode = 0; @@ -28,13 +35,13 @@ FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const uint createFileMode |= GENERIC_WRITE; HANDLE file = CreateFileW( - path.c_str(), - createFileMode, - NULL, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL + path.c_str(), + createFileMode, + NULL, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL ); if (file == INVALID_HANDLE_VALUE) @@ -51,7 +58,7 @@ FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const uint if (freeFileSlots.size() > 0) { - size_t pos = freeFileSlots.back(); + std::size_t pos = freeFileSlots.back(); result->id = pos; activeFiles[pos] = result; freeFileSlots.pop_back(); @@ -65,20 +72,20 @@ FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const uint return *result; } -void NativeFileSystem::ReadAsync(FileHandle &file, const uint32_t bufferSize, const uint32_t flags) +void NativeFileSystem::ReadAsync(FileHandle &file, const std::uint32_t bufferSize, const std::uint32_t flags) { file.overlapped = { - .hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr) + .hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr) }; - file.buffer = AllocateArray(bufferSize); + file.buffer = AllocateArray(bufferSize); file.bufferSize = bufferSize; BOOL isSync = ReadFile( - file.win32Handle, - file.buffer, - bufferSize, - NULL, - &file.overlapped + file.win32Handle, + file.buffer, + bufferSize, + NULL, + &file.overlapped ); if (isSync || GetLastError() != ERROR_IO_PENDING) @@ -116,7 +123,7 @@ bool NativeFileSystem::PollReady(FileHandle &file) return false; } } - + return true; } diff --git a/engine/src/GLFWInput.cpp b/engine/src/GLFWInput.cpp index 68e9028..482a629 100644 --- a/engine/src/GLFWInput.cpp +++ b/engine/src/GLFWInput.cpp @@ -1,6 +1,10 @@ -#include "GLFWInput.hpp" -#include "Engine.hpp" +module; + #include "Logger.h" +#include + +module GLFWInput; +import Engine; GLFWInput::GLFWInput(ee_engine::InputHandlers handlers) : ee_engine::IInput(handlers) { @@ -8,7 +12,7 @@ GLFWInput::GLFWInput(ee_engine::InputHandlers handlers) : ee_engine::IInput(hand glfwSetScrollCallback(Engine::window, [](GLFWwindow *window, double dx, double dy) { reinterpret_cast(glfwGetWindowUserPointer(window))-> - handlers.zooming(static_cast(dx), static_cast(dy)); + handlers.zooming(static_cast(dx), static_cast(dy)); }); LOG(INFO, "Input mappings initialized"); diff --git a/engine/src/main.cpp b/engine/src/main.cpp index 0116605..e8a91aa 100644 --- a/engine/src/main.cpp +++ b/engine/src/main.cpp @@ -1,98 +1,114 @@ +import allocator; + +import Engine; +import Actions; +import MagnumRender; +import GLFWInput; + #include "Logger.h" - -#include -#include - #include "compile_config.hpp" -#include "GLFWInput.hpp" -#include "Actions.hpp" -#include "Engine.hpp" - #include +#include IP7_Trace* Logger::trace; int main(int argc, char **argv) { - // Setup P7 logger - IP7_Client *p7client = P7_Create_Client(P7_SINK P7_LOGS_PATH); - P7_Set_Crash_Handler(); - Logger::trace = P7_Create_Trace(p7client, L"TC 1"); - Logger::trace->Register_Thread(L"Main", 0); + // Setup P7 logger + IP7_Client *p7client = P7_Create_Client(P7_SINK P7_LOGS_PATH); + P7_Set_Crash_Handler(); + Logger::trace = P7_Create_Trace(p7client, L"TC 1"); + Logger::trace->Register_Thread(L"Main", 0); - LOG(INFO, "Etredia Empires, v%d.%d.%d", MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION); + LOG(INFO, "Etredia Empires, v%d.%d.%d", MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION); - // Setup GLFW - glfwInit(); - - // Vulkan only - // glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + // Setup GLFW + glfwInit(); - GLFWwindow *window = glfwCreateWindow(800, 600, "Etredia Empires", nullptr, nullptr); + // Vulkan only + // glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - if (!window) - LOG(CRITICAL, "GLFW Window failed"); - else LOG(INFO, "GLFW Window created"); + GLFWwindow *window = glfwCreateWindow(800, 600, "Etredia Empires", nullptr, nullptr); - glfwMakeContextCurrent(window); - Engine::window = window; + if (!window) + LOG(CRITICAL, "GLFW Window failed"); + else LOG(INFO, "GLFW Window created"); - // Setup Asset Manager - Engine::assetManager = Allocate(); - Engine::assetManager->Start(); - Engine::assetManager->LoadDir(ee_assets::SHADER, "assets/shaders"); - Engine::assetManager->LoadDir(ee_assets::MATERIAL, "assets/materials"); + glfwMakeContextCurrent(window); + Engine::window = window; - // Load assets - Engine::assetManager->LoadAsync(ee_assets::MAP_MESH, "assets/map/states.map"); - Engine::assetManager->LoadAsync(ee_assets::SAVE, "assets/scenarios/empires.save"); + // Setup Asset Manager TODO: builder + Engine::assetManager = Allocate(); + Engine::assetManager->Start(); + Engine::assetManager->LoadDir(ee_assets::SHADER, "assets/shaders"); + Engine::assetManager->LoadDir(ee_assets::MATERIAL, "assets/materials"); - // Setup input manager TODO: builder - Engine::input = Allocate(Actions::mappings); + // Load assets + Engine::assetManager->LoadAsync(ee_assets::MAP_MESH, "assets/map/regions.map"); + Engine::assetManager->LoadAsync(ee_assets::SAVE, "assets/scenarios/empires.save"); - // Setup renderer TODO: builder - Engine::renderer = reinterpret_cast(Allocate(window)); - - ee_assets::AssetMapMesh &states = Engine::assetManager->FindOnce("assets/map/states.map"); - Engine::renderer->RegisterMapMesh(&states.content); - - //TODO: ShaderRefs builder from set of AssetMaterial - ee_assets::AssetMaterial &provincesMaterial = - Engine::assetManager->FindOnce("assets/materials/provinces.mat"); - ee_assets::AssetShader &vertProv = Engine::assetManager->FindOnce(provincesMaterial.vertexShaderAssetID); - ee_assets::AssetShader &fragProv = Engine::assetManager->FindOnce(provincesMaterial.fragmentShaderAssetID); - Engine::renderer->RegisterMaterials({ - .vertProvinces = &vertProv, - .fragProvinces = &fragProv - }); - - Engine::renderer->Init(); - Engine::renderer->SetCamera({ - //.position = {1000.0f, 1000.0f}, - .zoom = 2000.0f - }); - - glfwSetFramebufferSizeCallback(window, [](GLFWwindow *window, int width, int height) { - Engine::renderer->ResizeWindow(width, height); - }); + // Setup input manager TODO: builder + Engine::input = Allocate(Actions::mappings); - // Game loop - while(!glfwWindowShouldClose(window)) - { - Engine::renderer->Draw(); + // Setup renderer TODO: builder + Engine::renderer = reinterpret_cast(Allocate(window)); - glfwSwapBuffers(window); - Engine::input->Poll(); - glfwPollEvents(); - } + ee_assets::AssetMapMesh &states = Engine::assetManager->FindOnce("assets/map/regions.map"); + Engine::renderer->RegisterMapMesh(&states.content); - // Free memory - LOG(INFO, "Exit..."); - Engine::Shutdown(); - //TODO: check Unregister in other threads and make threaded module base class - Logger::trace->Unregister_Thread(0); - Logger::trace->Release(); - p7client->Release(); + //TODO: ShaderRefs builder from set of AssetMaterial + ee_assets::AssetMaterial &provincesMaterial = + Engine::assetManager->FindOnce("assets/materials/provinces.mat"); + ee_assets::AssetShader &vertProv = Engine::assetManager->FindOnce(provincesMaterial.vertexShaderAssetID); + ee_assets::AssetShader &fragProv = Engine::assetManager->FindOnce(provincesMaterial.fragmentShaderAssetID); + Engine::renderer->RegisterMaterials({ + .vertProvinces = &vertProv, + .fragProvinces = &fragProv + }); - return 0; -} \ No newline at end of file + Engine::renderer->Init(); + Engine::renderer->SetCamera({ + //.position = {1000.0f, 1000.0f}, + .zoom = 2000.0f + }); + + glfwSetFramebufferSizeCallback(window, [](GLFWwindow *window, int width, int height) { + Engine::renderer->ResizeWindow(width, height); + }); + + // Setup Client TODO: builder + Engine::client = Allocate(); + AssetHandle save = Engine::assetManager->Find("assets/scenarios/empires.save"); + Engine::client->LoadSave(save); + Engine::client->Init(); + Engine::client->Start(); + + // Game loop + ee_engine::RendererCommand renderCmdBuffer; std::vector renderIncompletesBuffer; + while(!glfwWindowShouldClose(window)) + { + Engine::renderer->ProcessQueue(renderCmdBuffer, renderIncompletesBuffer); + Engine::renderer->Draw(); + + glfwSwapBuffers(window); + Engine::input->Poll(); + glfwPollEvents(); + } + + // Free memory + LOG(INFO, "Exit..."); + Engine::Shutdown(); + //TODO: check Unregister in other threads and make threaded module base class + Logger::trace->Unregister_Thread(0); + Logger::trace->Release(); + p7client->Release(); + + return 0; +} + +// TODO: Rename states to regions in old sources +// TODO: Remove unneccesary address providing like (const type &arg) for small primitives +// TODO: Use CRTP where possible in classes with virtual/override +// TODO: Use final in classes with override +// TODO: Implementations of API as partition modules +// TODO: Leaks detection \ No newline at end of file diff --git a/p7lib/CMakeLists.txt b/p7lib/CMakeLists.txt index 4ab7ed0..f1dabdc 100644 --- a/p7lib/CMakeLists.txt +++ b/p7lib/CMakeLists.txt @@ -53,7 +53,7 @@ else() enable_cxx_compiler_flag_if_supported("-Wno-long-long") enable_cxx_compiler_flag_if_supported("-Wno-missing-field-initializers") enable_cxx_compiler_flag_if_supported("-Wno-unknown-pragmas") - enable_cxx_compiler_flag_if_supported("-fPIC") + #enable_cxx_compiler_flag_if_supported("-fPIC") macro(set_ide_folder _project_name) endmacro() diff --git a/p7lib/Sources/CMakeLists.txt b/p7lib/Sources/CMakeLists.txt index 23d6656..e4169d4 100644 --- a/p7lib/Sources/CMakeLists.txt +++ b/p7lib/Sources/CMakeLists.txt @@ -36,11 +36,11 @@ if(P7_BUILD_SHARED) target_link_libraries(${PROJECT_NAME}-shared ${P7_PLATFORM_LIBS}) endif() -set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) +#set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) -if(P7_BUILD_SHARED) - set_property(TARGET ${PROJECT_NAME}-shared PROPERTY POSITION_INDEPENDENT_CODE ON) -endif() +#if(P7_BUILD_SHARED) +# set_property(TARGET ${PROJECT_NAME}-shared PROPERTY POSITION_INDEPENDENT_CODE ON) +#endif() target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../Headers/") diff --git a/renderers/magnum-renderer/CMakeLists.txt b/renderers/magnum-renderer/CMakeLists.txt index 55e3757..0a64544 100644 --- a/renderers/magnum-renderer/CMakeLists.txt +++ b/renderers/magnum-renderer/CMakeLists.txt @@ -1,23 +1,6 @@ -cmake_minimum_required (VERSION 3.8) +include(${CMAKE_SOURCE_DIR}/cmake/library.cmake) -if (POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) - set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") -endif() - -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -project (magnum-renderer) - -# List sources - -file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS - "src/*.cpp" - "src/*.c" - "include/*.hpp" - "include/*.h" -) +set(LIB magnum-renderer) # Find dependencies @@ -38,20 +21,14 @@ find_package(Magnum REQUIRED # Link library -add_library(${PROJECT_NAME} ${SOURCES}) +add_library_target(${LIB}) -target_link_libraries(${PROJECT_NAME} PUBLIC engine-api) -target_link_libraries(${PROJECT_NAME} PUBLIC utils) +target_link_libraries(${LIB} PUBLIC engine-api) +target_link_libraries(${LIB} PUBLIC utils) -target_link_libraries(${PROJECT_NAME} PUBLIC p7) -target_link_libraries(${PROJECT_NAME} PRIVATE +target_link_libraries(${LIB} PUBLIC p7) +target_link_libraries(${LIB} PRIVATE Magnum::GL Magnum::GlfwApplication Magnum::Shaders - Magnum::Magnum) - -target_include_directories(${PROJECT_NAME} PUBLIC include/) - -if (CMAKE_VERSION VERSION_GREATER 3.12) - set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) -endif() \ No newline at end of file + Magnum::Magnum) \ No newline at end of file diff --git a/renderers/magnum-renderer/include/ee_magnum/Materials.hpp b/renderers/magnum-renderer/modules/Materials.cppm similarity index 57% rename from renderers/magnum-renderer/include/ee_magnum/Materials.hpp rename to renderers/magnum-renderer/modules/Materials.cppm index 004531c..a23fd3d 100644 --- a/renderers/magnum-renderer/include/ee_magnum/Materials.hpp +++ b/renderers/magnum-renderer/modules/Materials.cppm @@ -1,39 +1,42 @@ -#pragma once +module; -#undef min -#undef max +#define NOMINMAX #include #include #include #include -#include +#include +#include -#define PROVINCES_SSBO_BINDING 0 -#define CAMERA_UNIFORM 1 -//TODO: push constant -#define TRANSFORM_UNIFORM 2 -#define PROVINCES_ID_UNIFORM 3 +export module Materials; using namespace Magnum; -namespace ee_magnum +export namespace ee_magnum { class BaseMaterial : public GL::AbstractShaderProgram { public: + inline static constexpr std::int32_t CAMERA_BINDING = 1; + //TODO: push constant + inline static constexpr std::int32_t TRANSFORM_BINDING = 2; + void setModel(const Matrix4 &model); void setViewProjection(const Matrix4 &vewProjection); - + protected: explicit BaseMaterial(const std::string &vertSrc, const std::string &fragSrc); }; - + class ProvinceMaterial : public BaseMaterial { public: + inline static constexpr std::int32_t PROVINCES_DATA_BINDING = 0; + inline static constexpr std::int32_t PROVINCES_ID_BINDING = 3; + explicit ProvinceMaterial(const std::string &vertSrc, const std::string &fragSrc); - - void setId(const uint32_t &id); + + void setId(const std::uint32_t &id); }; -} \ No newline at end of file +} diff --git a/renderers/magnum-renderer/include/ee_magnum/Renderer.hpp b/renderers/magnum-renderer/modules/Render.cppm similarity index 68% rename from renderers/magnum-renderer/include/ee_magnum/Renderer.hpp rename to renderers/magnum-renderer/modules/Render.cppm index d48a14f..d2d7b65 100644 --- a/renderers/magnum-renderer/include/ee_magnum/Renderer.hpp +++ b/renderers/magnum-renderer/modules/Render.cppm @@ -1,47 +1,51 @@ -#pragma once +module; -#undef min -#undef max +#define NOMINMAX #include #include #include #include +#include -#include "Materials.hpp" -#include +export module MagnumRender; +import MapView; +import Materials; +import Render; using namespace Magnum; -namespace ee_magnum +export namespace ee_magnum { - class MagnumRenderer : public ee_engine::IRenderer + class MagnumRenderer final : public ee_engine::IRenderer { public: MagnumRenderer(GLFWwindow *window); ~MagnumRenderer(); - + void Init() override; void Shutdown() override; - + protected: void Clear() override; void DrawMap() override; void DrawUI() override; - + void ApplyCamera() override; - + + virtual void UpdateProvinces(const std::size_t index, const std::vector &data) override; + private: Platform::GLContext context; - + std::vector provinceMeshes; GL::Buffer provinceSSBO; ProvinceMaterial *provinceMaterial; - + void ValidateSupport(); void LoadShaders(); void LoadProvinces(); - + void ApplyMapMVP(); }; } \ No newline at end of file diff --git a/renderers/magnum-renderer/src/Materials.cpp b/renderers/magnum-renderer/src/Material.cpp similarity index 72% rename from renderers/magnum-renderer/src/Materials.cpp rename to renderers/magnum-renderer/src/Material.cpp index b4cb02f..0cdc11a 100644 --- a/renderers/magnum-renderer/src/Materials.cpp +++ b/renderers/magnum-renderer/src/Material.cpp @@ -1,5 +1,17 @@ -#include +module; + +#define NOMINMAX + +#include +#include +#include +#include + #include "Logger.h" +#include +#include + +module Materials; ee_magnum::BaseMaterial::BaseMaterial(const std::string &vertSrc, const std::string &fragSrc) { @@ -16,18 +28,18 @@ ee_magnum::BaseMaterial::BaseMaterial(const std::string &vertSrc, const std::str attachShader(vert); attachShader(frag); - + link(); } void ee_magnum::BaseMaterial::setModel(const Matrix4 &m) { - setUniform(TRANSFORM_UNIFORM, m); + setUniform(TRANSFORM_BINDING, m); } void ee_magnum::BaseMaterial::setViewProjection(const Matrix4 &vp) { - setUniform(CAMERA_UNIFORM, vp); + setUniform(CAMERA_BINDING, vp); } ee_magnum::ProvinceMaterial::ProvinceMaterial(const std::string &vertSrc, const std::string &fragSrc): BaseMaterial(vertSrc, fragSrc) @@ -37,5 +49,5 @@ ee_magnum::ProvinceMaterial::ProvinceMaterial(const std::string &vertSrc, const void ee_magnum::ProvinceMaterial::setId(const uint32_t &id) { - setUniform(PROVINCES_ID_UNIFORM, id); -} \ No newline at end of file + setUniform(PROVINCES_ID_BINDING, id); +} diff --git a/renderers/magnum-renderer/src/Renderer.cpp b/renderers/magnum-renderer/src/Render.cpp similarity index 61% rename from renderers/magnum-renderer/src/Renderer.cpp rename to renderers/magnum-renderer/src/Render.cpp index 8648b86..85cbc0c 100644 --- a/renderers/magnum-renderer/src/Renderer.cpp +++ b/renderers/magnum-renderer/src/Render.cpp @@ -1,24 +1,33 @@ -#include "Logger.h" -#include "ee_utils/allocator.hpp" -#include +module; +#define NOMINMAX + +#include "Logger.h" + +#include +#include #include #include -#include #include #include #include +#include +#include +#include #include #include +module MagnumRender; +import allocator; + using namespace Math::Literals; ee_magnum::MagnumRenderer::MagnumRenderer(GLFWwindow *window) : IRenderer(window) { - ValidateSupport(); + ValidateSupport(); - LOG(INFO, "Renderer created"); + LOG(INFO, "Renderer created"); } void ee_magnum::MagnumRenderer::Init() @@ -28,6 +37,7 @@ void ee_magnum::MagnumRenderer::Init() LoadShaders(); LoadProvinces(); + _isReady = true; LOG(INFO, "Renderer initialized"); } @@ -39,7 +49,7 @@ void ee_magnum::MagnumRenderer::Clear() void ee_magnum::MagnumRenderer::DrawMap() { ApplyCamera(); - for (uint32_t i = 0; i < provinceMeshes.size(); i++) + for (std::uint32_t i = 0; i < provinceMeshes.size(); i++) { provinceMaterial->setId(i); provinceMaterial->draw(provinceMeshes[i]); @@ -48,12 +58,12 @@ void ee_magnum::MagnumRenderer::DrawMap() void ee_magnum::MagnumRenderer::DrawUI() { - + } void ee_magnum::MagnumRenderer::ValidateSupport() { - + } void ee_magnum::MagnumRenderer::ApplyCamera() @@ -67,11 +77,11 @@ void ee_magnum::MagnumRenderer::ApplyCamera() void ee_magnum::MagnumRenderer::LoadShaders() { provinceMaterial = Allocate(std::string( - reinterpret_cast(shaders.vertProvinces->content), - shaders.vertProvinces->size + reinterpret_cast(shaders.vertProvinces->content), + shaders.vertProvinces->size ) + '\0', std::string( - reinterpret_cast(shaders.fragProvinces->content), - shaders.fragProvinces->size + reinterpret_cast(shaders.fragProvinces->content), + shaders.fragProvinces->size )) + '\0'; LOG(INFO, "Shaders loaded"); @@ -80,36 +90,47 @@ void ee_magnum::MagnumRenderer::LoadShaders() void ee_magnum::MagnumRenderer::LoadProvinces() { std::vector provincesData; - for (auto& [state, provs]: mapMesh->states) + + std::size_t regionIndex = 0; + for (auto& [region, provs]: mapMesh->regions) { for (ee_engine::MapMesh::Province &province: provs) { GL::Mesh stateMesh; stateMesh.setPrimitive(GL::MeshPrimitive::Triangles) - .setCount(static_cast(province.indices.size())) - .addVertexBuffer(GL::Buffer{province.vertices}, 0, GL::Attribute<0, Magnum::Vector2>{}) - .setIndexBuffer(GL::Buffer{province.indices}, 0, GL::MeshIndexType::UnsignedShort); + .setCount(static_cast(province.indices.size())) + .addVertexBuffer(GL::Buffer{province.vertices}, 0, GL::Attribute<0, Magnum::Vector2>{}) + .setIndexBuffer(GL::Buffer{province.indices}, 0, GL::MeshIndexType::UnsignedShort); provinceMeshes.push_back(std::move(stateMesh)); ee_engine::ProvinceSSBO data { - .stateId = state, - .color = state + .regionId = region, + //.color = region + .color = 0xFFFFFF }; provincesData.push_back(data); } + + regionsMapping[region] = {.startIndex = regionIndex, .provincesCount = provs.size()}; + regionIndex += provs.size() * sizeof(ee_engine::ProvinceSSBO); } LOG(INFO, "Registered %d province meshes in renderer", provinceMeshes.size()); provinceSSBO.setTargetHint(GL::Buffer::TargetHint::ShaderStorage); provinceSSBO.setData(provincesData, GL::BufferUsage::DynamicDraw); - provinceSSBO.bind(GL::Buffer::Target::ShaderStorage, PROVINCES_SSBO_BINDING); + provinceSSBO.bind(GL::Buffer::Target::ShaderStorage, ProvinceMaterial::PROVINCES_DATA_BINDING); } +void ee_magnum::MagnumRenderer::UpdateProvinces(const std::size_t index, const std::vector &data) +{ + provinceSSBO.setSubData(index, data); +} + void ee_magnum::MagnumRenderer::Shutdown() { provinceMeshes.clear(); @@ -121,5 +142,5 @@ void ee_magnum::MagnumRenderer::Shutdown() ee_magnum::MagnumRenderer::~MagnumRenderer() { - + } \ No newline at end of file diff --git a/sdk/assets/CMakeLists.txt b/sdk/assets/CMakeLists.txt index 047078b..aab223f 100644 --- a/sdk/assets/CMakeLists.txt +++ b/sdk/assets/CMakeLists.txt @@ -13,10 +13,13 @@ project (compile_assets) find_package(nlohmann_json CONFIG REQUIRED) find_package(xxHash CONFIG REQUIRED) -add_executable(${PROJECT_NAME} compile_assets.cpp) +add_executable(${PROJECT_NAME} compile_assets.cpp define/regions.def) target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json::nlohmann_json) target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash) target_link_libraries(${PROJECT_NAME} PUBLIC engine-api) +target_link_libraries(${PROJECT_NAME} PUBLIC server) + +target_compile_options(${PROJECT_NAME} PRIVATE /Zc:preprocessor) if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) diff --git a/sdk/assets/compile_assets.cpp b/sdk/assets/compile_assets.cpp index 868eb2b..c4f9566 100644 --- a/sdk/assets/compile_assets.cpp +++ b/sdk/assets/compile_assets.cpp @@ -1,3 +1,6 @@ +import AssetData; +import GameData; + #include #include #include @@ -7,7 +10,6 @@ #include #include #include -#include using json = nlohmann::json; @@ -23,11 +25,19 @@ namespace ee_data ) } +namespace ee_data +{ + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( + GameState, + subjects + ) +} + namespace ee_assets { NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( AssetSave, - subjects + content ) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( @@ -124,7 +134,7 @@ int main(int argc, char **argv) // Compile colors CompileRecursive(data, [](const std::basic_string &key, json &value) { if (!value.is_string()) return; - + const char* color_str = value.get_ref().c_str() + 1; uint8_t b = 0, g = 0, r = 0; uint32_t hex = 0; diff --git a/sdk/assets/define/regions.def b/sdk/assets/define/regions.def index 68f1761..5af5463 100644 --- a/sdk/assets/define/regions.def +++ b/sdk/assets/define/regions.def @@ -2,18 +2,14 @@ #define MAP(name, color) #endif -MAP(elnia, 0xFF0000) -MAP(south_hleria, 0xFFD800) -MAP(siburia_central, 0xFF00DC) -MAP(siburia, 0xFF0000) -MAP(savatia, 0xFF0000) -MAP(east_monfua, 0xFF0000) +MAP(pepene, 0xAA00FF) +MAP(scarna, 0xFF007F) -MAP(dineria, 0x0400FF) -MAP(perdania, 0xFF6A00) +MAP(dineria, 0xFFFF00) +MAP(perdania, 0x7FFF00) MAP(arstinia, 0xFF0000) -MAP(ortostan, 0xFF0000) -MAP(zerandia, 0xFF0000) -MAP(mgahvatia, 0xFF0000) +MAP(alende, 0x0000FF) +MAP(zerandia, 0xFF5400) +MAP(mgahvatia, 0x5400FF) #undef MAP \ No newline at end of file diff --git a/sdk/assets/saves/empires.save.json b/sdk/assets/saves/empires.save.json index 1c13b51..f0fab0b 100644 --- a/sdk/assets/saves/empires.save.json +++ b/sdk/assets/saves/empires.save.json @@ -1,33 +1,26 @@ { + "content": { "subjects": [ - - { - "tag": "ESH", - "color": "#FF0000", - - "regions": [ - "elnia", - "south_hleria", - "siburia_central", - "siburia", - "savatia", - "east_monfua" - ] - }, - - { - "tag": "UCB", - "color": "#00FF00", - - "regions": [ - "dineria", - "perdania", - "arstinia", - "ortostan", - "zerandia", - "mgahvatia" - ] - } - + { + "tag": "FSC", + "color": "#FF0000", + "regions": [ + "pepene", + "scarna" + ] + }, + { + "tag": "UCB", + "color": "#0000FF", + "regions": [ + "dineria", + "perdania", + "arstinia", + "alende", + "zerandia", + "mgahvatia" + ] + } ] + } } \ No newline at end of file diff --git a/sdk/map/regions.bmp b/sdk/map/regions.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ee3812a9438aecbcfe4af8949c98facf4b0d4f6a GIT binary patch literal 373086 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 literal 0 HcmV?d00001 diff --git a/sdk/map/run.cmd b/sdk/map/run.cmd index 11b0a5b..21b3933 100644 --- a/sdk/map/run.cmd +++ b/sdk/map/run.cmd @@ -1,2 +1,2 @@ @echo off -"%CD%/../../out/build/DEBUG/sdk/map/convert_map.exe" states.bmp ../../assets/map/states.map \ No newline at end of file +"%CD%/../../out/build/DEBUG/sdk/map/convert_map.exe" regions.bmp ../../assets/map/regions.map \ No newline at end of file diff --git a/server/.vscode/launch.json b/server/.vscode/launch.json deleted file mode 100644 index e8338f2..0000000 --- a/server/.vscode/launch.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "configurations": [ - { - "type": "cmake", - "request": "launch", - "name": "Debug portfile(s)", - "cmakeDebugType": "external", - "pipeName": "\\\\.\\pipe\\vcpkg_ext_portfile_dbg", - "preLaunchTask": "Debug vcpkg commands" - } - ] -} \ No newline at end of file diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt deleted file mode 100644 index 8999193..0000000 --- a/server/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -cmake_minimum_required (VERSION 3.8) - -if (POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) - set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") -endif() - -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -project ("server") - -add_subdirectory ("economy") -add_subdirectory ("economy/test") - -add_subdirectory ("ecs") -add_subdirectory ("ecs/test") \ No newline at end of file diff --git a/server/economy/CMakeLists.txt b/server/economy/CMakeLists.txt deleted file mode 100644 index 7e11e37..0000000 --- a/server/economy/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -project(Economy) - -# List sources - -set(HEADERS "economy.hpp" "defines.hpp" "enterprise_defaults.hpp" "systems.hpp") -set(HEADERS_COMPONENTS "container.hpp" "enterprise.hpp" "state.hpp" "tags.hpp" - "miner.hpp" "producer.hpp" "deliverer.hpp") - -set(SOURCES "Economy.cpp") -set(SOURCES_SYSTEMS "enterprise_routine.cpp" "mining.cpp" "delivering.cpp") - -list(TRANSFORM HEADERS PREPEND "include/ee_economy/") -list(TRANSFORM HEADERS_COMPONENTS PREPEND "include/ee_economy/components/") - -list(TRANSFORM SOURCES PREPEND "src/") -list(TRANSFORM SOURCES_SYSTEMS PREPEND "src/systems/") - -# Find dependencies - -find_package(EnTT CONFIG REQUIRED) - -# Link library - -add_library(${PROJECT_NAME} ${HEADERS} ${HEADERS_COMPONENTS} ${SOURCES} ${SOURCES_SYSTEMS}) -add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) - -target_link_libraries(${PROJECT_NAME} PRIVATE EnTT::EnTT) - -target_include_directories(${PROJECT_NAME} PUBLIC include/) - -if (CMAKE_VERSION VERSION_GREATER 3.12) - set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) -endif() \ No newline at end of file diff --git a/server/economy/include/ee_economy/components/container.hpp b/server/economy/include/ee_economy/components/container.hpp deleted file mode 100644 index f734244..0000000 --- a/server/economy/include/ee_economy/components/container.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "../defines.hpp" -#include - -namespace ee_economy -{ - struct Container - { - double capacity = 0.; - double total = 0.; - std::unordered_map content; - - void add(RESOURCE_TYPE type, double delta) - { - this->content[type] += delta; - this->total += delta; - } - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/components/deliverer.hpp b/server/economy/include/ee_economy/components/deliverer.hpp deleted file mode 100644 index 825a022..0000000 --- a/server/economy/include/ee_economy/components/deliverer.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -#include - -namespace ee_economy -{ - struct DeliverContract - { - entt::entity from; - entt::entity to; - entt::entity sponsor; - - double amount = 0.0; - double cost = 0.0; - double distance = 1.0; - }; - - struct Deliverer - { - RESOURCE_TYPE resource = RESOURCE_TYPE::NONE; - - std::vector contracts; - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/components/enterprise.hpp b/server/economy/include/ee_economy/components/enterprise.hpp deleted file mode 100644 index 2addb79..0000000 --- a/server/economy/include/ee_economy/components/enterprise.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include -#include -#include - -namespace ee_economy -{ - struct Enterprise - { - bool isBuilding = false; - entt::entity state; - ACTION_TYPE action = ACTION_TYPE::STORE; - - /* - * Mining - Amount of mined resource - * Delivering - Amount of resource that can be delivered by one truck - * Production - - */ - double efficiency = 0.; - double baseEfficiency = 0.; - double factorEfficiency = 1.; - - std::vector linksFrom; - std::vector linksTo; - - uint16_t staffSize = 1; - - // This can be splitted in percents between bank enterprises in future - double totalMoney = 0; - double salary = 0; - bool isBankrupt = false; - - void setMoney(double value) - { - totalMoney = value; - } - - inline void updateEfficiency() - { - this->efficiency = this->baseEfficiency * this->factorEfficiency; - } - - void setBaseEfficiency(double value) - { - this->baseEfficiency = value; - updateEfficiency(); - } - - void setFactorEfficiency(double value) - { - this->factorEfficiency = value; - updateEfficiency(); - } - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/components/miner.hpp b/server/economy/include/ee_economy/components/miner.hpp deleted file mode 100644 index 44cb3c2..0000000 --- a/server/economy/include/ee_economy/components/miner.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include -#include - -namespace ee_economy -{ - struct Miner - { - RESOURCE_TYPE resource = RESOURCE_TYPE::NONE; - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/components/producer.hpp b/server/economy/include/ee_economy/components/producer.hpp deleted file mode 100644 index 379f2bc..0000000 --- a/server/economy/include/ee_economy/components/producer.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -namespace ee_economy -{ - struct Producer - { - - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/components/state.hpp b/server/economy/include/ee_economy/components/state.hpp deleted file mode 100644 index 0b5cb1a..0000000 --- a/server/economy/include/ee_economy/components/state.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include - -namespace ee_economy -{ - struct State { - int16_t externalId = -1; - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/components/tags.hpp b/server/economy/include/ee_economy/components/tags.hpp deleted file mode 100644 index ea625ce..0000000 --- a/server/economy/include/ee_economy/components/tags.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace ee_economy -{ - -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/defines.hpp b/server/economy/include/ee_economy/defines.hpp deleted file mode 100644 index 8ea641c..0000000 --- a/server/economy/include/ee_economy/defines.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#include - -namespace ee_economy -{ - const double TOLERANCE = 0.001; - - const double BASE_FUEL_PER_KM = 1.0; - - enum struct ACTION_TYPE : uint8_t - { - MINING, - PRODUCTION, - DELIVERY, - STORE, - DESTRUCTION, - BUILD, - TRADE - }; - - enum struct CONTAINABLE_TYPE : uint8_t - { - RESOURCE, - GOODS, - SERVICE - }; - - enum struct RESOURCE_TYPE : uint8_t - { - NONE, - - AGRICULTURE, - MEAT, - COTTON, - LEATHER, - WOOL, - TIMBER, - COAL, - OIL, - GAS, - IRON, - COPPER, - LITHIUM, - URANIUM, - GOLD, - - FERTILIZER, - FABRIC, - FURNITURE, - LUXURY, - CLOTHING, - ALCOHOL, - PAPER, - GLASS, - PLASTIC, - CEMENT, - STEEL, - FUEL, - AVIATION_FUEL, - ROCKET_FUEL, - ENGINES, - ELECTRICITY, - AUTOMOBILE, - AIRPLANE, - HELICOPTER, - PHONE, - TRUCK, - CONSTRUCTION_EQUIPMENT, - PROCESSOR, - COMPUTER, - ELECTRONIC, - SEMICONDUCTOR, - BATTERY, - SYNTHETIC_RUBBER, - SYNTHETIC_FABRIC, - MACHINE_TOOLS, - MODERN_MACHINE_TOOLS, - POLYMERS, - MILITARY_EQUIPMENT, - MEDICINES, - TACTICAL_MISSILES, - NUCLEAR_MISSILES, - OIL_GAS - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/economy.hpp b/server/economy/include/ee_economy/economy.hpp deleted file mode 100644 index 17bbccd..0000000 --- a/server/economy/include/ee_economy/economy.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "defines.hpp" -#include "enterprise_defaults.hpp" -#include "systems.hpp" - -#include "components/tags.hpp" -#include "components/state.hpp" -#include "components/container.hpp" - -#include "components/enterprise.hpp" -#include "components/miner.hpp" -#include "components/producer.hpp" -#include "components/deliverer.hpp" diff --git a/server/economy/include/ee_economy/enterprise_defaults.hpp b/server/economy/include/ee_economy/enterprise_defaults.hpp deleted file mode 100644 index 64e0164..0000000 --- a/server/economy/include/ee_economy/enterprise_defaults.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "defines.hpp" -#include "components/container.hpp" - -namespace ee_economy -{ - struct EnterpriseDefaults - { - Container container; - - RESOURCE_TYPE resourceTarget = RESOURCE_TYPE::NONE; - double baseEfficiency = 0.0; - double factorEfficiency = 1.0; - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/resources_exchange.hpp b/server/economy/include/ee_economy/resources_exchange.hpp deleted file mode 100644 index 81ac8b0..0000000 --- a/server/economy/include/ee_economy/resources_exchange.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// Rules for resources exchange in base before modifiers applying - -#pragma once -#include -#include "defines.hpp" - -namespace ee_economy -{ - struct ExchangeRule - { - double outValue; - - std::unordered_map consume; - }; - - const std::unordered_map resourcesExchange = { - { - RESOURCE_TYPE::FABRIC, - exchange_rule { - .outValue = 2., - .consume = { - {RESOURCE_TYPE::WOOL, 3.} - } - } - } - }; -} \ No newline at end of file diff --git a/server/economy/include/ee_economy/systems.hpp b/server/economy/include/ee_economy/systems.hpp deleted file mode 100644 index f13bb5e..0000000 --- a/server/economy/include/ee_economy/systems.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - -namespace ee_economy -{ - void enterpriseRoutine(entt::registry& registry); - - void mining(entt::registry& registry); - // void producing(entt::registry& registry); - void delivering(entt::registry& registry); - // void storaging(entt::registry& registry); // consume money for storage time - // void destructing(entt::registry& registry); - // void building(entt::registry& registry); - // void trading(entt::registry& registry); -} \ No newline at end of file diff --git a/server/economy/src/Economy.cpp b/server/economy/src/Economy.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/server/economy/src/systems/delivering.cpp b/server/economy/src/systems/delivering.cpp deleted file mode 100644 index 0f53bd6..0000000 --- a/server/economy/src/systems/delivering.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include - -void ee_economy::delivering(entt::registry ®istry) -{ - auto deliverers = registry.view(); - - for (auto [entity, enterprise, deliverer, storage]: deliverers.each()) - { - if (enterprise.isBankrupt) continue; - - for (DeliverContract &contract: deliverer.contracts) - { - double paidAmount = contract.amount; - - if (contract.cost > 0) - { - Enterprise &sponsor = registry.get(contract.sponsor); - - double costPerOne = contract.cost / contract.amount; - double payment = contract.cost; - - if (payment > sponsor.totalMoney) - { - payment = (int)(sponsor.totalMoney / costPerOne) * costPerOne; - paidAmount = payment / costPerOne; - } - sponsor.setMoney(sponsor.totalMoney - payment); - enterprise.setMoney(enterprise.totalMoney + payment); - contract.cost -= payment; - } - - Container &fromStorage = registry.get(contract.from); - Container &toStorage = registry.get(contract.to); - - double deliverValue = enterprise.efficiency; - if (contract.amount < enterprise.efficiency) - deliverValue = contract.amount; - if (toStorage.total + deliverValue > toStorage.capacity) - deliverValue = toStorage.capacity - toStorage.total; - if (deliverValue > fromStorage.content[deliverer.resource]) - deliverValue = fromStorage.content[deliverer.resource]; - if (deliverValue > paidAmount) - deliverValue = paidAmount; - if (deliverValue < 0.0) - deliverValue = 0.0; - - toStorage.add(deliverer.resource, deliverValue); - fromStorage.add(deliverer.resource, -deliverValue); - contract.amount -= deliverValue; - } - - std::erase_if(deliverer.contracts, [](const DeliverContract &contract) { - return contract.amount <= 0.0; - }); - } -} \ No newline at end of file diff --git a/server/economy/src/systems/enterprise_routine.cpp b/server/economy/src/systems/enterprise_routine.cpp deleted file mode 100644 index c038252..0000000 --- a/server/economy/src/systems/enterprise_routine.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include - -void ee_economy::enterpriseRoutine(entt::registry ®istry) -{ - auto enterprises = registry.view(); - - for (auto [entity, enterprise]: enterprises.each()) - { - double salaryDebt = enterprise.salary * enterprise.staffSize; - if (enterprise.totalMoney < salaryDebt) - { - enterprise.isBankrupt = true; - enterprise.setMoney(0.0); - } - else - { - enterprise.setMoney(enterprise.totalMoney - salaryDebt); - } - } -} \ No newline at end of file diff --git a/server/economy/src/systems/mining.cpp b/server/economy/src/systems/mining.cpp deleted file mode 100644 index 323717c..0000000 --- a/server/economy/src/systems/mining.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include - -void ee_economy::mining(entt::registry ®istry) -{ - auto miners = registry.view(); - - for (auto [entity, enterprise, miner, localStorage]: miners.each()) - { - if (enterprise.isBankrupt) continue; - - Container& state = registry.get(enterprise.state); - - double minedValue = enterprise.efficiency; - if (localStorage.total + minedValue > localStorage.capacity) - minedValue = localStorage.capacity - localStorage.total; - if (minedValue > state.content[miner.resource]) - minedValue = state.content[miner.resource]; - - localStorage.add(miner.resource, minedValue); - state.add(miner.resource, -minedValue); - } -} \ No newline at end of file diff --git a/server/economy/test/CMakeLists.txt b/server/economy/test/CMakeLists.txt deleted file mode 100644 index 36a932f..0000000 --- a/server/economy/test/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -project(economy_tests) - -# List sources - -set(SOURCES "test_conf.hpp" "main.cpp" - "systems/enterprise_routine.cpp" "systems/mining.cpp" "systems/delivering.cpp") - -# Find dependencies - -find_package(GTest CONFIG REQUIRED) - -# Link - -include(GoogleTest) - -add_executable(${PROJECT_NAME} ${SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest_main) -target_link_libraries(${PROJECT_NAME} PRIVATE Economy::Economy) - -# Test - -if (CMAKE_VERSION VERSION_GREATER 3.12) - set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) -endif() - -gtest_discover_tests(${PROJECT_NAME}) \ No newline at end of file diff --git a/server/economy/test/main.cpp b/server/economy/test/main.cpp deleted file mode 100644 index 45acf01..0000000 --- a/server/economy/test/main.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/server/economy/test/systems/delivering.cpp b/server/economy/test/systems/delivering.cpp deleted file mode 100644 index e1dd1c1..0000000 --- a/server/economy/test/systems/delivering.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include -#include "../test_conf.hpp" - -TEST_F(SystemsTest, DeliverySingleNormal) -{ - // [Miner -> Storage] by Deliverer - - ee_economy::Enterprise &delivererEnterprise = registry.get(deliverer); - ee_economy::Deliverer &delivererDeliverer = registry.get(deliverer); - - delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL; - delivererEnterprise.setBaseEfficiency(1.0); - delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0}); - - ee_economy::Container &fromContainer = registry.get(miner); - ee_economy::Container &toContainer = registry.get(storage); - - fromContainer.capacity = 15.0; - fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 15.0); - - toContainer.capacity = 15.0; - - ee_economy::delivering(registry); - - ASSERT_DOUBLE_EQ(fromContainer.total, 14.0); - ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 14.0); - ASSERT_DOUBLE_EQ(toContainer.total, 1.0); - ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 1.0); - ASSERT_EQ(delivererDeliverer.contracts.size(), 1); -} - -TEST_F(SystemsTest, DeliverySingleEmpty) -{ - // [Miner -> Storage] by Deliverer - - ee_economy::Enterprise &delivererEnterprise = registry.get(deliverer); - ee_economy::Deliverer &delivererDeliverer = registry.get(deliverer); - - delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL; - delivererEnterprise.setBaseEfficiency(1.0); - delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0}); - - ee_economy::Container &fromContainer = registry.get(miner); - ee_economy::Container &toContainer = registry.get(storage); - - fromContainer.capacity = 15.0; - toContainer.capacity = 15.0; - - ee_economy::delivering(registry); - - ASSERT_DOUBLE_EQ(fromContainer.total, 0.0); - ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0); - ASSERT_DOUBLE_EQ(toContainer.total, 0.0); - ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0); - ASSERT_EQ(delivererDeliverer.contracts.size(), 1); -} - -TEST_F(SystemsTest, DeliverySinglePoor) -{ - // [Miner -> Storage] by Deliverer - - ee_economy::Enterprise &delivererEnterprise = registry.get(deliverer); - ee_economy::Deliverer &delivererDeliverer = registry.get(deliverer); - - delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL; - delivererEnterprise.setBaseEfficiency(1.0); - delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0}); - - ee_economy::Container &fromContainer = registry.get(miner); - ee_economy::Container &toContainer = registry.get(storage); - - fromContainer.capacity = 15.0; - fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 0.5); - - toContainer.capacity = 15.0; - - ee_economy::delivering(registry); - - ASSERT_DOUBLE_EQ(fromContainer.total, 0.0); - ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0); - ASSERT_DOUBLE_EQ(toContainer.total, 0.5); - ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.5); - ASSERT_EQ(delivererDeliverer.contracts.size(), 1); -} - -TEST_F(SystemsTest, DeliverySingleFinishContract) -{ - // [Miner -> Storage] by Deliverer - - ee_economy::Enterprise &delivererEnterprise = registry.get(deliverer); - ee_economy::Deliverer &delivererDeliverer = registry.get(deliverer); - - delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL; - delivererEnterprise.setBaseEfficiency(15.0); - delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0}); - - ee_economy::Container &fromContainer = registry.get(miner); - ee_economy::Container &toContainer = registry.get(storage); - - fromContainer.capacity = 15.0; - fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 15.0); - - toContainer.capacity = 15.0; - - ee_economy::delivering(registry); - - ASSERT_DOUBLE_EQ(fromContainer.total, 5.0); - ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 5.0); - ASSERT_DOUBLE_EQ(toContainer.total, 10.0); - ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 10.0); - ASSERT_EQ(delivererDeliverer.contracts.size(), 0); -} - -TEST_F(SystemsTest, DeliveryMultipleFinishPoorCycle) -{ - // [Miner -> Storage | Storage -> Miner] by Deliverer - - ee_economy::Enterprise &delivererEnterprise = registry.get(deliverer); - ee_economy::Deliverer &delivererDeliverer = registry.get(deliverer); - - delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL; - delivererEnterprise.setBaseEfficiency(16.0); - delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 20.0}); - delivererDeliverer.contracts.push_back({.from = storage, .to = miner, .amount = 5.0}); - - ee_economy::Container &minerContainer = registry.get(miner); - ee_economy::Container &storageContainer = registry.get(storage); - - minerContainer.capacity = 15.0; - minerContainer.add(ee_economy::RESOURCE_TYPE::COAL, 15.0); - - storageContainer.capacity = 15.0; - - ee_economy::delivering(registry); - - ASSERT_DOUBLE_EQ(minerContainer.total, 5.0); - ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 5.0); - ASSERT_DOUBLE_EQ(storageContainer.total, 10.0); - ASSERT_DOUBLE_EQ(storageContainer.content[ee_economy::RESOURCE_TYPE::COAL], 10.0); - ASSERT_EQ(delivererDeliverer.contracts.size(), 1); - ASSERT_EQ(delivererDeliverer.contracts[0].from, miner); -} - -TEST_F(SystemsTest, DeliveryPayment) -{ - // [Miner -> Storage] by Deliverer for $Miner - // [Miner -> Storage] by Deliverer - - ee_economy::Enterprise &delivererEnterprise = registry.get(deliverer); - ee_economy::Deliverer &delivererDeliverer = registry.get(deliverer); - - delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL; - delivererEnterprise.setBaseEfficiency(10.0); - delivererDeliverer.contracts.push_back({ - .from = miner, - .to = storage, - .sponsor = miner, - .amount = 10.0, - .cost = 100.0 - }); - - ee_economy::Container &fromContainer = registry.get(miner); - ee_economy::Enterprise &fromEnterprise = registry.get(miner); - ee_economy::Container &toContainer = registry.get(storage); - - fromContainer.capacity = 10.0; - fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 10.0); - fromEnterprise.setMoney(95.0); - - toContainer.capacity = 10.0; - - ee_economy::delivering(registry); - - ASSERT_DOUBLE_EQ(fromContainer.total, 1.0); - ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 1.0); - ASSERT_DOUBLE_EQ(toContainer.total, 9.0); - ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 9.0); - ASSERT_DOUBLE_EQ(fromEnterprise.totalMoney, 5.0); - ASSERT_DOUBLE_EQ(delivererEnterprise.totalMoney, 90.0); - - ee_economy::DeliverContract contract = delivererDeliverer.contracts[0]; - ASSERT_DOUBLE_EQ(contract.cost, 10.0); - ASSERT_DOUBLE_EQ(contract.amount, 1.0); -} - -TEST_F(SystemsTest, DeliveryBankrupt) -{ - // [Miner -> Storage] by Deliverer - - ee_economy::Enterprise &delivererEnterprise = registry.get(deliverer); - ee_economy::Deliverer &delivererDeliverer = registry.get(deliverer); - - delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL; - delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0}); - delivererEnterprise.setBaseEfficiency(1.0); - delivererEnterprise.isBankrupt = true; - - ee_economy::Container &fromContainer = registry.get(miner); - ee_economy::Container &toContainer = registry.get(storage); - - fromContainer.capacity = 15.0; - fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 15.0); - - toContainer.capacity = 15.0; - - ee_economy::delivering(registry); - - ASSERT_DOUBLE_EQ(fromContainer.total, 15.0); - ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 15.0); - ASSERT_DOUBLE_EQ(toContainer.total, 0.0); - ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0); - ASSERT_EQ(delivererDeliverer.contracts.size(), 1); -} \ No newline at end of file diff --git a/server/economy/test/systems/enterprise_routine.cpp b/server/economy/test/systems/enterprise_routine.cpp deleted file mode 100644 index 4f814b2..0000000 --- a/server/economy/test/systems/enterprise_routine.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include "../test_conf.hpp" - -TEST_F(SystemsTest, RoutineNormal) -{ - ee_economy::Enterprise &minerEnterprise = registry.get(miner); - minerEnterprise.setMoney(1000000000.0); - minerEnterprise.salary = 100000.0; - minerEnterprise.staffSize = 10; - - ee_economy::enterpriseRoutine(registry); - - ASSERT_DOUBLE_EQ(minerEnterprise.totalMoney, 999000000.0); - ASSERT_FALSE(minerEnterprise.isBankrupt); -} - -TEST_F(SystemsTest, RoutineBankruptcy) -{ - ee_economy::Enterprise &minerEnterprise = registry.get(miner); - minerEnterprise.setMoney(1000000.0); - minerEnterprise.salary = 100000.0; - minerEnterprise.staffSize = 11; - - ee_economy::enterpriseRoutine(registry); - - ASSERT_DOUBLE_EQ(minerEnterprise.totalMoney, 0.0); - ASSERT_TRUE(minerEnterprise.isBankrupt); -} \ No newline at end of file diff --git a/server/economy/test/systems/mining.cpp b/server/economy/test/systems/mining.cpp deleted file mode 100644 index e92ba28..0000000 --- a/server/economy/test/systems/mining.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include "../test_conf.hpp" - -TEST_F(SystemsTest, MiningNormal) -{ - ee_economy::Container &stateContainer = registry.get(state); - ee_economy::Container &minerContainer = registry.get(miner); - ee_economy::Enterprise &minerEnterprise = registry.get(miner); - ee_economy::Miner &minerMiner = registry.get(miner); - - stateContainer.capacity = 15.0; - stateContainer.add(ee_economy::RESOURCE_TYPE::COAL, 10.0); - - minerContainer.capacity = 5.0; - minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL; - minerEnterprise.setBaseEfficiency(0.1); - - ee_economy::mining(registry); - - ASSERT_DOUBLE_EQ(stateContainer.total, 9.9); - ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 9.9); - ASSERT_DOUBLE_EQ(minerContainer.total, 0.1); - ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.1); -} - -TEST_F(SystemsTest, MiningEmptyState) -{ - ee_economy::Container &stateContainer = registry.get(state); - ee_economy::Container &minerContainer = registry.get(miner); - ee_economy::Enterprise &minerEnterprise = registry.get(miner); - ee_economy::Miner &minerMiner = registry.get(miner); - - stateContainer.capacity = 15.0; - - minerContainer.capacity = 5.0; - minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL; - minerEnterprise.setBaseEfficiency(0.1); - - ee_economy::mining(registry); - - ASSERT_DOUBLE_EQ(stateContainer.total, 0.0); - ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0); - ASSERT_DOUBLE_EQ(minerContainer.total, 0.0); - ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0); -} - -TEST_F(SystemsTest, MiningPoorState) -{ - ee_economy::Container &stateContainer = registry.get(state); - ee_economy::Container &minerContainer = registry.get(miner); - ee_economy::Enterprise &minerEnterprise = registry.get(miner); - ee_economy::Miner &minerMiner = registry.get(miner); - - stateContainer.capacity = 15.0; - stateContainer.add(ee_economy::RESOURCE_TYPE::COAL, 0.05); - - minerContainer.capacity = 5.0; - minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL; - minerEnterprise.setBaseEfficiency(0.1); - - ee_economy::mining(registry); - - ASSERT_DOUBLE_EQ(stateContainer.total, 0.0); - ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0); - ASSERT_DOUBLE_EQ(minerContainer.total, 0.05); - ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.05); -} - -TEST_F(SystemsTest, MiningReachCap) -{ - ee_economy::Container &stateContainer = registry.get(state); - ee_economy::Container &minerContainer = registry.get(miner); - ee_economy::Enterprise &minerEnterprise = registry.get(miner); - ee_economy::Miner &minerMiner = registry.get(miner); - - stateContainer.capacity = 15.0; - stateContainer.add(ee_economy::RESOURCE_TYPE::COAL, 10.0); - - minerContainer.capacity = 0.05; - minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL; - minerEnterprise.setBaseEfficiency(0.1); - - ee_economy::mining(registry); - - ASSERT_DOUBLE_EQ(stateContainer.total, 9.95); - ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 9.95); - ASSERT_DOUBLE_EQ(minerContainer.total, 0.05); - ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.05); -} - -TEST_F(SystemsTest, MiningBankrupt) -{ - ee_economy::Container &stateContainer = registry.get(state); - ee_economy::Container &minerContainer = registry.get(miner); - ee_economy::Enterprise &minerEnterprise = registry.get(miner); - ee_economy::Miner &minerMiner = registry.get(miner); - - stateContainer.capacity = 15.0; - stateContainer.add(ee_economy::RESOURCE_TYPE::COAL, 10.0); - - minerContainer.capacity = 5.0; - minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL; - minerEnterprise.setBaseEfficiency(0.1); - minerEnterprise.isBankrupt = true; - - ee_economy::mining(registry); - - ASSERT_DOUBLE_EQ(stateContainer.total, 10.0); - ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 10.0); - ASSERT_DOUBLE_EQ(minerContainer.total, 0.0); - ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0); -} \ No newline at end of file diff --git a/server/economy/test/test_conf.hpp b/server/economy/test/test_conf.hpp deleted file mode 100644 index 7673dc7..0000000 --- a/server/economy/test/test_conf.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include -#include - -struct SystemsTest : testing::Test -{ - entt::registry registry; - - entt::entity state; - - entt::entity miner; - entt::entity storage; - entt::entity deliverer; - - void SetUp() - { - // Create state - state = registry.create(); - registry.emplace(state); - registry.emplace(state); - - // Create miner enterprise - miner = registry.create(); - registry.emplace(miner, false, state); - registry.emplace(miner); - registry.emplace(miner); - - // Create storage enterprise - storage = registry.create(); - registry.emplace(storage, false, state); - registry.emplace(storage); - - // Create delivering enterprise - deliverer = registry.create(); - registry.emplace(deliverer, false, state); - registry.emplace(deliverer); - registry.emplace(deliverer); - } - - void TearDown() - { - } -}; \ No newline at end of file diff --git a/server/ecs/CMakeLists.txt b/server/ecs/CMakeLists.txt deleted file mode 100644 index 34a8fc2..0000000 --- a/server/ecs/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -project(ECS) - -# List sources - -set(HEADERS "ecs.hpp" "api.hpp" "world.hpp") -set(SOURCES "api.cpp" "world.cpp") - -list(TRANSFORM HEADERS PREPEND "include/ee_ecs/") -list(TRANSFORM SOURCES PREPEND "src/") - -# Find dependencies -find_package(EnTT CONFIG REQUIRED) - -# Link library - -add_library(${PROJECT_NAME} ${HEADERS} ${SOURCES}) -add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) - -target_link_libraries(${PROJECT_NAME} PUBLIC Economy::Economy) -target_link_libraries(${PROJECT_NAME} PRIVATE EnTT::EnTT) - -target_include_directories(${PROJECT_NAME} PUBLIC include/) - - -if (CMAKE_VERSION VERSION_GREATER 3.12) - set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) -endif() \ No newline at end of file diff --git a/server/ecs/include/ee_ecs/api.hpp b/server/ecs/include/ee_ecs/api.hpp deleted file mode 100644 index 5350f05..0000000 --- a/server/ecs/include/ee_ecs/api.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include -#include "data.hpp" - -namespace ee_ecs -{ - - void init(InitConfiguration config); - void start(); - - template - const std::vector getAllEnterprises(); - //const EnterpriseInfo getEnterprise(uint32_t id); -} \ No newline at end of file diff --git a/server/ecs/include/ee_ecs/data.hpp b/server/ecs/include/ee_ecs/data.hpp deleted file mode 100644 index a406c6d..0000000 --- a/server/ecs/include/ee_ecs/data.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -#include -#include - -namespace ee_ecs -{ - - struct InitConfiguration - { - std::unordered_map states; - }; - - struct EnterpriseInfo - { - const ee_economy::Enterprise* info = nullptr; - const ee_economy::Container* storage = nullptr; - std::variant< - const ee_economy::Miner*, - const ee_economy::Deliverer* - > specialInfo; - }; - -} \ No newline at end of file diff --git a/server/ecs/include/ee_ecs/ecs.hpp b/server/ecs/include/ee_ecs/ecs.hpp deleted file mode 100644 index 1e527a2..0000000 --- a/server/ecs/include/ee_ecs/ecs.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -#include "api.hpp" -#include "world.hpp" \ No newline at end of file diff --git a/server/ecs/include/ee_ecs/world.hpp b/server/ecs/include/ee_ecs/world.hpp deleted file mode 100644 index 649c4fc..0000000 --- a/server/ecs/include/ee_ecs/world.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include "ee_economy/components/container.hpp" -#include -#include -#include -#include - -namespace ee_ecs -{ - class World - { - private: - entt::registry registry; - std::unordered_map statesTable; - - void updateEnterprises(); - - public: - // Run every registered system - void update(); - - entt::entity registerState(const int16_t id, const ee_economy::Container &resources); - - entt::entity spawnEnterprise( - const bool isBuilding, - const ee_economy::ACTION_TYPE action, - const entt::entity state, - const ee_economy::EnterpriseDefaults &defaults - ); - - entt::registry& getRegistry(); - }; -} \ No newline at end of file diff --git a/server/ecs/src/api.cpp b/server/ecs/src/api.cpp deleted file mode 100644 index 6233eab..0000000 --- a/server/ecs/src/api.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "ee_ecs/world.hpp" -#include - - -static ee_ecs::World worldInstance; - -void ee_ecs::init(ee_ecs::InitConfiguration config) -{ - for (auto& [id, container]: config.states) - { - worldInstance.registerState(id, container); - } -} - -void ee_ecs::start() -{ - while (true) {} -} - -template - const std::vector ee_ecs::getAllEnterprises() -{ - std::vector result; - //TODO: REPLACE VIEWS WITH GROUPS! - auto enterprises = worldInstance.getRegistry().group<>(entt::get< - ee_economy::Enterprise, - ee_economy::Container, - T - >); - result.reserve(enterprises.size_hint()); - - for (auto [entity, enterprise, container, action]: enterprises.each()) - { - EnterpriseInfo eninfo; - eninfo.info = &enterprise; - - eninfo.storage = &container; - eninfo.specialInfo = &action; - - result.push_back(eninfo); - } - - return result; -} diff --git a/server/ecs/src/world.cpp b/server/ecs/src/world.cpp deleted file mode 100644 index f98e20b..0000000 --- a/server/ecs/src/world.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include - -void ee_ecs::World::updateEnterprises() -{ - ee_economy::enterpriseRoutine(this->registry); - - ee_economy::mining(this->registry); - ee_economy::delivering(this->registry); -} - -void ee_ecs::World::update() -{ - this->updateEnterprises(); -} - -entt::entity ee_ecs::World::registerState(const int16_t id, const ee_economy::Container &resources) -{ - if (this->statesTable.contains(id)) - throw std::invalid_argument("State with this Id is already registered"); - - entt::entity entity = this->registry.create(); - - this->registry.emplace(entity, id); - this->registry.emplace( - entity, - resources.capacity, - resources.total, - resources.content - ); - - this->statesTable[id] = entity; - - return entity; -} - -entt::entity ee_ecs::World::spawnEnterprise( - const bool isBuilding, - const ee_economy::ACTION_TYPE action, - const entt::entity state, - const ee_economy::EnterpriseDefaults &defaults -) -{ - entt::entity entity = this->registry.create(); - - this->registry.emplace( - entity, - isBuilding, - state, - action, - - defaults.baseEfficiency * defaults.factorEfficiency, - - defaults.baseEfficiency, - defaults.factorEfficiency - ); - - this->registry.emplace( - entity, - defaults.container.capacity, - defaults.container.total, - defaults.container.content - ); - - switch (action) - { - case ee_economy::ACTION_TYPE::MINING: - { - this->registry.emplace(entity, defaults.resourceTarget); - break; - } - - case ee_economy::ACTION_TYPE::DELIVERY: - { - this->registry.emplace(entity, defaults.resourceTarget); - break; - } - - default: - break; - } - - return entity; -} - -entt::registry& ee_ecs::World::getRegistry() {return this->registry;} \ No newline at end of file diff --git a/server/ecs/test/CMakeLists.txt b/server/ecs/test/CMakeLists.txt deleted file mode 100644 index 2df383f..0000000 --- a/server/ecs/test/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -project(ecs_tests) - -# List sources - -set(SOURCES "test_conf.hpp" "main.cpp" "world.cpp" "benchmark.cpp") - -# Find dependencies - -find_package(GTest CONFIG REQUIRED) - -# Link - -include(GoogleTest) - -add_executable(${PROJECT_NAME} ${SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest_main) -target_link_libraries(${PROJECT_NAME} PRIVATE ECS::ECS) - -# Test - -if (CMAKE_VERSION VERSION_GREATER 3.12) - set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) -endif() - -gtest_discover_tests(${PROJECT_NAME}) \ No newline at end of file diff --git a/server/ecs/test/benchmark.cpp b/server/ecs/test/benchmark.cpp deleted file mode 100644 index 6530535..0000000 --- a/server/ecs/test/benchmark.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include "test_conf.hpp" -#include -#include - -struct timer final { - timer() - : start{std::chrono::system_clock::now()} {} - - void elapsed() { - auto now = std::chrono::system_clock::now(); - std::cout << std::chrono::duration(now - start).count() << " seconds" << std::endl; - } - -private: - std::chrono::time_point start; -}; - -template -void genericWith(Func func) { - timer timer; - func(); - timer.elapsed(); -} - -TEST_F(WorldBenchmark, UpdateSystems) -{ - genericWith([&]() { - world.update(); - }); -} \ No newline at end of file diff --git a/server/ecs/test/main.cpp b/server/ecs/test/main.cpp deleted file mode 100644 index 45acf01..0000000 --- a/server/ecs/test/main.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/server/ecs/test/test_conf.hpp b/server/ecs/test/test_conf.hpp deleted file mode 100644 index 5e6ec9e..0000000 --- a/server/ecs/test/test_conf.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include - -struct WorldBenchmark : testing::Test -{ - ee_ecs::World world; - - void SetUp() - { - for (int16_t i = 0; i < 1000; i++) - { - ee_economy::Container resources {.capacity = 100.0}; - resources.add(ee_economy::RESOURCE_TYPE::COAL, 100.0); - entt::entity state = world.registerState(i, resources); - - ee_economy::EnterpriseDefaults miner { - .container {.capacity = 100.0}, - .resourceTarget = ee_economy::RESOURCE_TYPE::GOLD, - .baseEfficiency = 1.0 - }; - - world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner); - world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner); - world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner); - world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner); - world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner); - } - } - - void TearDown() - { - - } -}; \ No newline at end of file diff --git a/server/ecs/test/world.cpp b/server/ecs/test/world.cpp deleted file mode 100644 index 01d17ef..0000000 --- a/server/ecs/test/world.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include - -TEST(WorldTest, RegisterState) -{ - ee_ecs::World world; - - ee_economy::Container res {.capacity = 100.0}; - res.add(ee_economy::RESOURCE_TYPE::COAL, 98.0); - entt::entity state = world.registerState(10, res); - - ee_economy::State registeredState = world.getRegistry().get(state); - ee_economy::Container registeredContainer = world.getRegistry().get(state); - - ASSERT_EQ(registeredState.externalId, 10); - ASSERT_DOUBLE_EQ(registeredContainer.content[ee_economy::RESOURCE_TYPE::COAL], 98.0); -} - -TEST(WorldTest, RegisterStateDuplicate) -{ - ee_ecs::World world; - - world.registerState(10, {}); - - ASSERT_THROW({ - world.registerState(10, {}); - }, std::invalid_argument); -} - -TEST(WorldTest, SpawnMiner) -{ - ee_ecs::World world; - - entt::entity state = world.getRegistry().create(); - world.getRegistry().emplace(state, (int16_t)0); - world.getRegistry().emplace(state, 100.0); - - ee_economy::EnterpriseDefaults defaults { - .container {.capacity = 100.0 }, - .resourceTarget = ee_economy::RESOURCE_TYPE::COAL, - .baseEfficiency = 1.0, - }; - - entt::entity enterprise = world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, defaults); - - ee_economy::Enterprise registeredEnterprise = world.getRegistry().get(enterprise); - ee_economy::Miner registeredAction = world.getRegistry().get(enterprise); - ee_economy::Container registeredContainer = world.getRegistry().get(enterprise); - - ASSERT_DOUBLE_EQ(registeredEnterprise.baseEfficiency, 1.0); - ASSERT_EQ(registeredAction.resource, ee_economy::RESOURCE_TYPE::COAL); - ASSERT_DOUBLE_EQ(registeredContainer.capacity, 100.0); -} - -TEST(WorldTest, SpawnDeliverer) -{ - ee_ecs::World world; - - entt::entity state = world.getRegistry().create(); - world.getRegistry().emplace(state, (int16_t)0); - world.getRegistry().emplace(state, 100.0); - - ee_economy::EnterpriseDefaults defaults { - .container {.capacity = 100.0 }, - .resourceTarget = ee_economy::RESOURCE_TYPE::COAL, - .baseEfficiency = 1.0, - }; - - entt::entity enterprise = world.spawnEnterprise(false, ee_economy::ACTION_TYPE::DELIVERY, state, defaults); - - ee_economy::Enterprise registeredEnterprise = world.getRegistry().get(enterprise); - ee_economy::Deliverer registeredAction = world.getRegistry().get(enterprise); - ee_economy::Container registeredContainer = world.getRegistry().get(enterprise); - - ASSERT_DOUBLE_EQ(registeredEnterprise.baseEfficiency, 1.0); - ASSERT_EQ(registeredAction.resource, ee_economy::RESOURCE_TYPE::COAL); - ASSERT_DOUBLE_EQ(registeredContainer.capacity, 100.0); -} \ No newline at end of file diff --git a/server/lib/CMakeLists.txt b/server/lib/CMakeLists.txt new file mode 100644 index 0000000..bdb1f22 --- /dev/null +++ b/server/lib/CMakeLists.txt @@ -0,0 +1,5 @@ +include(${CMAKE_SOURCE_DIR}/cmake/library.cmake) + +set(LIB server) + +add_library_target(${LIB}) \ No newline at end of file diff --git a/server/lib/modules/GameData.cppm b/server/lib/modules/GameData.cppm new file mode 100644 index 0000000..ed6dffc --- /dev/null +++ b/server/lib/modules/GameData.cppm @@ -0,0 +1,21 @@ +module; + +#include +#include + +export module GameData; + +export namespace ee_data +{ + struct Subject + { + std::uint32_t tag; + std::uint32_t color; + std::vector regions; + }; + + struct GameState + { + std::vector subjects; + }; +} \ No newline at end of file diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index c3055eb..b7760a8 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -1,26 +1,14 @@ -if (POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) - set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") -endif() - -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - - -project(utils) - -file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS - "src/*.cpp" - "src/*.c" - "include/*.hpp" - "include/*.h" -) +include(${CMAKE_SOURCE_DIR}/cmake/library.cmake) +set(LIB utils) # Find dependencies +find_package(Boost REQUIRED COMPONENTS lockfree) + # Link library -add_library(${PROJECT_NAME} ${SOURCES}) +add_library_target(${LIB}) -target_include_directories(${PROJECT_NAME} PUBLIC include/) \ No newline at end of file +target_link_libraries(${LIB} PUBLIC p7) +target_link_libraries(${LIB} PRIVATE Boost::lockfree) \ No newline at end of file diff --git a/utils/include/ee_utils/allocator.hpp b/utils/include/ee_utils/allocator.hpp deleted file mode 100644 index 88ad59c..0000000 --- a/utils/include/ee_utils/allocator.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include - -template T* Allocate(Args&&... args) -{ - return new T(std::forward(args)...); -} - -template void Deallocate(T* obj) -{ - delete obj; -} - -template T* AllocateArray(size_t size) -{ - return new T[size]; -} - -template void DeallocateArray(T* obj) -{ - delete[] obj; -} \ No newline at end of file diff --git a/utils/include/ee_utils/buffers.hpp b/utils/include/ee_utils/buffers.hpp deleted file mode 100644 index 80224f3..0000000 --- a/utils/include/ee_utils/buffers.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include - -#define as_bytes(value) reinterpret_cast(value) - -namespace ee_utils -{ - bool readNext(void* dst, uint8_t* &srcPointer, size_t &srcLeftoverSize, const size_t &readSize); - bool writeNext(uint8_t* &dstPointer, void* src, size_t &dstLeftoverSize, const size_t &writeSize); -} \ No newline at end of file diff --git a/utils/include/ee_utils/platform.hpp b/utils/include/ee_utils/platform.hpp new file mode 100644 index 0000000..c89380b --- /dev/null +++ b/utils/include/ee_utils/platform.hpp @@ -0,0 +1,11 @@ +#ifndef ETREDIAEMPIRES_PLATFORM_HPP +#define ETREDIAEMPIRES_PLATFORM_HPP + +#ifdef _WIN32 +#include +#endif + +#ifdef __linux__ +#endif + +#endif //ETREDIAEMPIRES_PLATFORM_HPP diff --git a/utils/include/ee_utils/utils.hpp b/utils/include/ee_utils/utils.hpp new file mode 100644 index 0000000..6f93970 --- /dev/null +++ b/utils/include/ee_utils/utils.hpp @@ -0,0 +1,6 @@ +#ifndef ETREDIAEMPIRES_UTILS_HPP +#define ETREDIAEMPIRES_UTILS_HPP + +#define MAP_WORKER_COMMAND(TCommand, method) [this](TCommand &cmd) {this->method(cmd);} + +#endif //ETREDIAEMPIRES_UTILS_HPP diff --git a/utils/modules/allocator.cppm b/utils/modules/allocator.cppm new file mode 100644 index 0000000..a6ee53b --- /dev/null +++ b/utils/modules/allocator.cppm @@ -0,0 +1,27 @@ +module; + +#include + +export module allocator; + +export { + template T* Allocate(Args&&... args) + { + return new T(std::forward(args)...); + } + + template void Deallocate(T* obj) + { + delete obj; + } + + template T* AllocateArray(std::size_t size) + { + return new T[size]; + } + + template void DeallocateArray(T* obj) + { + delete[] obj; + } +} \ No newline at end of file diff --git a/utils/modules/buffers.cppm b/utils/modules/buffers.cppm new file mode 100644 index 0000000..26ef2ed --- /dev/null +++ b/utils/modules/buffers.cppm @@ -0,0 +1,12 @@ +module; + +#include +#include + +export module buffers; + +export namespace ee_utils +{ + bool readNext(void* dst, std::uint8_t* &srcPointer, std::size_t &srcLeftoverSize, const std::size_t &readSize); + bool writeNext(std::uint8_t* &dstPointer, void* src, std::size_t &dstLeftoverSize, const std::size_t &writeSize); +} \ No newline at end of file diff --git a/utils/modules/worker.cppm b/utils/modules/worker.cppm new file mode 100644 index 0000000..c3acb65 --- /dev/null +++ b/utils/modules/worker.cppm @@ -0,0 +1,151 @@ +module; + +#include "Logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +export module worker; + +export namespace ee_utils +{ + struct WorkerCommand + { + uint8_t type = 0; + }; + template concept IWorkerCommand = std::is_base_of_v; + + template + class Worker + { + public: + void Request(const TCommand &command) + { + commands.push(command); + } + + void Request(const std::uint8_t type) + { + commands.push(TCommand {.type = type}); + } + + void ProcessQueue(TCommand &buffer, std::vector &incompletesBuffer) + { + while (this->commands.pop(buffer)) + { + ProcessCommand(buffer); + if (buffer.type != maxCmdType) + incompletesBuffer.push_back(buffer); + } + for (TCommand &command : incompletesBuffer) + { + this->commands.push(command); + } + incompletesBuffer.clear(); + } + + protected: + std::array, maxCmdType + 1> commandsMapping; + // TODO: maybe I should use lockfree::queue ? + boost::lockfree::spsc_queue> commands; + + void ProcessCommand(TCommand &command) + { + if (command.type > maxCmdType || !commandsMapping[command.type]) + { + LOG(WARNING, "Unhandled command. Type id: %d", command.type); + command.type = maxCmdType; + return; + } + + commandsMapping[command.type](command); + } + }; + + class ThreadedWorkerBase { + public: + std::atomic isRunning; + + virtual ~ThreadedWorkerBase() {} + + void Start() + { + if (isRunning) + { + LOG(CRITICAL, "Thread can be started only once before stop"); + throw std::logic_error("Thread can be started only once before stop"); + } + + isRunning.store(true); + thread = std::jthread([this](std::stop_token stop) { + this->stoken = &stop; + Threading(); + }); + } + + void Shutdown() + { + if (isRunning) + thread.request_stop(); + else LOG(WARNING, "Tried to shutdown stopped thread"); + } + + protected: + std::stop_token *stoken{}; + std::jthread thread; + + virtual void Threading() = 0; + }; + template concept IThreadedWorker = std::is_base_of_v; + + template + class ThreadedWorker : public Worker, public ThreadedWorkerBase + { + protected: + const wchar_t *threadName; + + explicit ThreadedWorker(const wchar_t *threadName) + { + this->threadName = threadName; + } + + void Threading() + { + Logger::trace->Register_Thread(threadName, 0); + LOG(INFO, "Thread started"); + + Loop(); + + ReleaseStop(); + } + + void Loop() + { + TCommand commandBuffer{}; + std::vector incompleteCommands; + while (!stoken->stop_requested()) + { + this->ProcessQueue(commandBuffer, incompleteCommands); + + Update(); + } + } + + virtual void Update() = 0; + virtual void Release() = 0; + + private: + void ReleaseStop() + { + Release(); + LOG(INFO, "Client is released"); + isRunning.store(false); + } + }; +} \ No newline at end of file diff --git a/utils/src/buffers.cpp b/utils/src/buffers.cpp index 81cf3a8..b767af9 100644 --- a/utils/src/buffers.cpp +++ b/utils/src/buffers.cpp @@ -1,7 +1,12 @@ -#include +module; + +#include +#include #include -bool ee_utils::readNext(void* dst, uint8_t* &srcPointer, size_t &srcLeftoverSize, const size_t &readSize) +module buffers; + +bool ee_utils::readNext(void* dst, std::uint8_t* &srcPointer, std::size_t &srcLeftoverSize, const std::size_t &readSize) { if (srcLeftoverSize >= readSize) { @@ -15,7 +20,7 @@ bool ee_utils::readNext(void* dst, uint8_t* &srcPointer, size_t &srcLeftoverSize return false; } -bool ee_utils::writeNext(uint8_t* &dstPointer, void* src, size_t &dstLeftoverSize, const size_t &writeSize) +bool ee_utils::writeNext(std::uint8_t* &dstPointer, void* src, std::size_t &dstLeftoverSize, const std::size_t &writeSize) { if (dstLeftoverSize >= writeSize) { diff --git a/utils/src/utils.cpp b/utils/src/utils.cpp deleted file mode 100644 index e69de29..0000000