48 Commits

Author SHA1 Message Date
389fa61fba Merge pull request 'Fixed gitea workflow.' (#18) from NetChannels into main
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 21s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m31s
Build & Release / Linux-AMD64-Build (push) Successful in 15m15s
Reviewed-on: #18
2025-03-25 18:43:47 -07:00
16ef5bbb74 Fixed gitea workflow.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Successful in 14m41s
Build & Release / Windows-AMD64-Build (push) Failing after 23s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m36s
2025-03-25 18:42:56 -07:00
a67197766e Merge pull request 'Fixed gitea workflow.' (#17) from NetChannels into main
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 25s
Build & Release / Linux-AMD64-Build (push) Failing after 11m42s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m39s
Reviewed-on: #17
2025-03-25 18:37:27 -07:00
6cba7d6698 Fixed gitea workflow. 2025-03-25 18:35:52 -07:00
ae414c5c99 Merge pull request 'Added CPU::GetCacheLineSize() definition for Windows.' (#16) from NetChannels into main
Reviewed-on: #16
2025-03-25 16:50:40 -07:00
9ab62d0545 Added CPU::GetCacheLineSize() definition for Windows.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 25s
Build & Release / Linux-AMD64-Build (push) Failing after 13m28s
Build & Release / Linux-AARCH64-Build (push) Failing after 1m0s
2025-03-25 16:45:18 -07:00
b44e55a92c Merge pull request 'NetChannels' (#15) from NetChannels into main
Reviewed-on: EventHorizonStudio/EHS#15
2025-03-23 03:22:41 -07:00
53d86eb539 Merge remote-tracking branch 'origin/NetChannels' into NetChannels
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 9m34s
Build & Release / Linux-AMD64-Build (push) Failing after 1m58s
Build & Release / Linux-AARCH64-Build (push) Failing after 5m21s
2025-03-23 03:11:24 -07:00
352b4d612f First commit for ICMP capabilities, added CPU::GetCacheLineSize(), and removed BaseObj from containers. 2025-03-23 03:10:35 -07:00
89925fe820 Renamed member variables and parameters. 2025-01-30 13:01:01 -08:00
16b56a7084 Made NetChannel methods public in EHC. 2025-01-30 12:32:52 -08:00
62f8a662a0 Backup. 2025-01-29 16:21:11 -08:00
39bbcd0d56 Added missing constructor for NetChannel in NetServerCh. 2025-01-28 04:28:55 -08:00
981b40d3b1 Finished implementing, now for the testing phase. 2025-01-26 21:43:17 -08:00
7bc4b9977d Merge pull request 'Added the capability for custom encryption's to be added to EHC.' (#14) from fix into main
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 6m24s
Build & Release / Linux-AMD64-Build (push) Successful in 13m7s
Build & Release / Linux-AARCH64-Build (push) Successful in 39m52s
Reviewed-on: EventHorizonStudio/EHS#14
2024-10-06 23:20:53 -07:00
79860c7d39 Added the capability for custom encryption's to be added to EHC.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Waiting to run
Build & Release / Linux-AARCH64-Build (push) Has been cancelled
Build & Release / Linux-AMD64-Build (push) Has been cancelled
2024-10-06 23:19:42 -07:00
99bab4a6ef Merge pull request 'New Audio and EHC PR' (#13) from audio into main
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 3m34s
Build & Release / Windows-AMD64-Build (push) Successful in 6m44s
Build & Release / Linux-AARCH64-Build (push) Has been cancelled
Reviewed-on: EventHorizonStudio/EHS#13
2024-10-06 23:00:31 -07:00
8b01ee3c46 Added the capability for custom encryption's to be added to EHC. 2024-10-06 22:54:29 -07:00
1feff0a25c Moved the Event Horizon Communications to this project. 2024-10-06 20:08:22 -07:00
9b42ad6d74 Simplified audio playback & capturing significantly. 2024-10-06 17:24:32 -07:00
9639329df3 Updated readme. 2024-10-06 01:16:04 -07:00
6cd686a17e Updated readme. 2024-10-06 01:14:14 -07:00
3343f8ca28 Fixed workflow.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 7m5s
Build & Release / Linux-AMD64-Build (push) Successful in 12m7s
Build & Release / Linux-AARCH64-Build (push) Successful in 37m1s
2024-10-05 19:05:30 -07:00
3b8159b75f Fixed workflow.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 6m8s
Build & Release / Linux-AMD64-Build (push) Failing after 17m38s
Build & Release / Linux-AARCH64-Build (push) Failing after 36m37s
2024-10-01 21:27:31 -07:00
62e7580d3a Added install dependency for pipewire.
Some checks failed
Build & Release / Linux-AARCH64-Build (push) Failing after 7s
Build & Release / Windows-AMD64-Build (push) Failing after 5m13s
Build & Release / Linux-AMD64-Build (push) Failing after 17m37s
2024-10-01 21:00:00 -07:00
11170006e9 Fixed workflow for Windows.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 8s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Failing after 5m15s
2024-10-01 20:19:38 -07:00
37e3ca9360 Fixed workflow for Windows.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 8s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Failing after 5m19s
2024-10-01 19:58:35 -07:00
daca00603a Fixed workflow for Windows.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 8s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Failing after 6m8s
2024-10-01 19:50:21 -07:00
1f5299ad1b Fixed Win32 audio.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 8s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Failing after 5m56s
2024-10-01 18:58:15 -07:00
dfa260b87c Backup. 2024-09-30 20:24:25 -07:00
fc8b771026 Added vcpkg.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 8s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Failing after 3m52s
2024-09-30 19:55:44 -07:00
0b77c074cf Added vcpkg.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 8s
Build & Release / Linux-AARCH64-Build (push) Failing after 13s
Build & Release / Windows-AMD64-Build (push) Failing after 30s
2024-09-30 19:48:07 -07:00
5007a1047a Added vcpkg.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 7s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Failing after 30s
2024-09-30 19:22:22 -07:00
25860dc32a Added vcpkg. 2024-09-29 21:07:30 -07:00
d870599a60 Added vcpkg. 2024-09-29 21:06:30 -07:00
9bd3e1cd8d Added vcpkg. 2024-09-29 20:41:37 -07:00
681c0d09be Fixed Mat and CMakeLists 2024-09-16 16:18:49 -07:00
25762b0c29 Backup. 2024-09-03 05:37:23 -07:00
6afa08df82 Updated README.md again. 2024-08-15 19:41:05 -07:00
0a995a3f2c Updated README.md 2024-08-15 19:40:31 -07:00
c607b20bad Cleaned up and fixed some errors in the Json Parser. 2024-08-15 19:28:30 -07:00
2e705627ac Fixed CMakeLists.txt and System_LNX.cpp. 2024-08-15 17:33:04 -07:00
86a35fd668 Added System::GetDirDialog. 2024-08-04 02:09:10 -07:00
8d4420528a Optimized Button class. Added IsPressed and GetPressed methods. 2024-08-04 00:47:38 -07:00
3970b8d402 Fixed Mat and CMakeLists 2024-07-27 18:51:19 -07:00
6522994a1f Fixed Win32 keyboard input. 2024-07-27 10:12:10 -07:00
01a21032a5 Simplified Windows build again. 2024-07-24 15:37:45 -07:00
4d7e7596b6 Simplified Windows build. 2024-07-24 14:58:36 -07:00
104 changed files with 5411 additions and 1402 deletions

View File

@@ -8,6 +8,9 @@ on:
jobs: jobs:
Windows-AMD64-Build: Windows-AMD64-Build:
runs-on: windows-x86_64 runs-on: windows-x86_64
defaults:
run:
shell: powershell
steps: steps:
- name: Check out repository code - name: Check out repository code
uses: actions/checkout@v3 uses: actions/checkout@v3
@@ -19,8 +22,10 @@ jobs:
- name: Building/Compiling/Installing Project - name: Building/Compiling/Installing Project
run: | run: |
cd ${{ gitea.workspace }} cd ${{ gitea.workspace }}
cmake -A x64 -DCMAKE_BUILD_TYPE=Release --preset=default . vcpkg install
mkdir build
cd build cd build
cmake -A x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake ..
cmake --build . --config Release cmake --build . --config Release
cmake --install . cmake --install .
@@ -28,10 +33,12 @@ jobs:
run: | run: |
cd ${{ gitea.workspace }} cd ${{ gitea.workspace }}
mkdir bin mkdir bin
mv build/Release/EHS_Dyn.dll bin
mv build/Release/StrToHash.exe bin mv build/Release/StrToHash.exe bin
mv build/Release/zlib1.dll bin mv build/Release/zlib1.dll bin
mkdir lib mkdir lib
mv build/Release/EHS.lib lib mv build/Release/EHS_Stc.lib lib
mv build/Release/EHS_Dyn.lib lib
- name: Zipping Binaries - name: Zipping Binaries
run: | run: |
@@ -58,7 +65,7 @@ jobs:
- name: Installing Dependencies - name: Installing Dependencies
run: | run: |
sudo pacman -S --noconfirm doxygen zip alsa-lib libxcb xcb-util-cursor sudo pacman -S --noconfirm doxygen zip alsa-lib libxcb xcb-util-cursor pipewire
- name: Generating Documentation - name: Generating Documentation
run: | run: |
@@ -73,10 +80,12 @@ jobs:
- name: Creating Appropriate Directories - name: Creating Appropriate Directories
run: | run: |
cd ${{ gitea.workspace }}
mkdir bin mkdir bin
mv libEHS_Dyn.so bin
mv StrToHash bin mv StrToHash bin
mkdir lib mkdir lib
mv libEHS.a lib mv libEHS_Stc.a lib
- name: Zipping Binaries - name: Zipping Binaries
run: zip -r ehs-linux-amd64.zip include bin lib docs LICENSE RADME.md run: zip -r ehs-linux-amd64.zip include bin lib docs LICENSE RADME.md
@@ -100,7 +109,7 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Installing Dependencies - name: Installing Dependencies
run: sudo apt install -y doxygen zip libasound2-dev libxcb1-dev libxcb-xinput-dev libxcb-cursor-dev run: sudo apt install -y doxygen zip libasound2-dev libxcb1-dev libxcb-xinput-dev libxcb-cursor-dev libpipewire-0.3-dev
- name: Generating Documentation - name: Generating Documentation
run: | run: |
@@ -115,10 +124,12 @@ jobs:
- name: Creating Appropriate Directories - name: Creating Appropriate Directories
run: | run: |
cd ${{ gitea.workspace }}
mkdir bin mkdir bin
mv libEHS_Dyn.so bin
mv StrToHash bin mv StrToHash bin
mkdir lib mkdir lib
mv libEHS.a lib mv libEHS_Stc.a lib
- name: Zipping Binaries - name: Zipping Binaries
run: zip -r ehs-linux-aarch64.zip include bin lib docs LICENSE README.md run: zip -r ehs-linux-aarch64.zip include bin lib docs LICENSE README.md

View File

@@ -13,7 +13,8 @@ project(EHS CXX C)
if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
set(IS_OS_WINDOWS TRUE) set(IS_OS_WINDOWS TRUE)
set(USER_HOME_DIRECTORY $ENV{USERPROFILE}) set(USER_HOME_DIRECTORY "$ENV{USERPROFILE}")
string(REPLACE "\\" "/" USER_HOME_DIRECTORY "${USER_HOME_DIRECTORY}")
message("Building for the Windows operating system.") message("Building for the Windows operating system.")
elseif (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux") elseif (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux")
set(IS_OS_LINUX TRUE) set(IS_OS_LINUX TRUE)
@@ -39,182 +40,203 @@ endif ()
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(EHS_SOURCES set(EHS_SOURCES
src/EHS.cpp include/ehs/EHS.h src/EHS.cpp include/ehs/EHS.h
src/Type.cpp include/ehs/Type.h src/Type.cpp include/ehs/Type.h
src/BaseObj.cpp include/ehs/BaseObj.h src/BaseObj.cpp include/ehs/BaseObj.h
src/GC.cpp include/ehs/GC.h src/GC.cpp include/ehs/GC.h
src/Log.cpp include/ehs/Log.h src/Log.cpp include/ehs/Log.h
src/URI.cpp include/ehs/URI.h src/URI.cpp include/ehs/URI.h
src/Math.cpp include/ehs/Math.h src/Math.cpp include/ehs/Math.h
src/Color4.cpp include/ehs/Color4.h src/Color4.cpp include/ehs/Color4.h
src/Color3.cpp include/ehs/Color3.h src/Color3.cpp include/ehs/Color3.h
src/Version.cpp include/ehs/Version.h src/Version.cpp include/ehs/Version.h
src/Base64.cpp include/ehs/Base64.h src/Base64.cpp include/ehs/Base64.h
src/Data.cpp include/ehs/Data.h src/Data.cpp include/ehs/Data.h
src/Range.cpp include/ehs/Range.h src/Range.cpp include/ehs/Range.h
src/Util.cpp include/ehs/Util.h src/Util.cpp include/ehs/Util.h
src/Task.cpp include/ehs/Task.h src/Task.cpp include/ehs/Task.h
src/DataType.cpp include/ehs/DataType.h src/DataType.cpp include/ehs/DataType.h
include/ehs/Anchor.h include/ehs/Anchor.h
include/ehs/Dock.h include/ehs/Dock.h
include/ehs/HashMap.h include/ehs/HashMap.h
include/ehs/HRNG.h include/ehs/HRNG.h
include/ehs/Link.h include/ehs/Link.h
include/ehs/LinkedList.h include/ehs/LinkedList.h
include/ehs/Mat2.h include/ehs/Mat2.h
include/ehs/Mat3.h include/ehs/Mat3.h
include/ehs/Mat4.h include/ehs/Mat4.h
include/ehs/PRNG.h include/ehs/PRNG.h
include/ehs/Quat.h include/ehs/Quat.h
include/ehs/Rect.h include/ehs/Rect.h
include/ehs/Str.h include/ehs/Str.h
include/ehs/Types.h include/ehs/Types.h
include/ehs/UTF.h include/ehs/UTF.h
include/ehs/Vec2.h include/ehs/Vec2.h
include/ehs/Vec3.h include/ehs/Vec3.h
include/ehs/Vec4.h include/ehs/Vec4.h
include/ehs/Serializer.h include/ehs/Serializer.h
include/ehs/Array.h include/ehs/Array.h
include/ehs/Vector.h include/ehs/Vector.h
include/ehs/SArray.h include/ehs/SArray.h
src/PtrData.cpp include/ehs/PtrData.h src/PtrData.cpp include/ehs/PtrData.h
include/ehs/UniPtr.h include/ehs/UniPtr.h
include/ehs/ShdPtr.h include/ehs/ShdPtr.h
include/ehs/WkPtr.h include/ehs/WkPtr.h
src/db/DbVarTmpl.cpp include/ehs/db/DbVarTmpl.h src/db/DbVarTmpl.cpp include/ehs/db/DbVarTmpl.h
src/system/CPU.cpp include/ehs/system/CPU.h src/system/CPU.cpp include/ehs/system/CPU.h
src/system/Thread.cpp include/ehs/system/Thread.h src/system/Thread.cpp include/ehs/system/Thread.h
src/system/BaseMutex.cpp include/ehs/system/BaseMutex.h src/system/BaseMutex.cpp include/ehs/system/BaseMutex.h
src/system/BaseSemaphore.cpp include/ehs/system/BaseSemaphore.h src/system/BaseSemaphore.cpp include/ehs/system/BaseSemaphore.h
src/system/BaseSystem.cpp include/ehs/system/BaseSystem.h src/system/BaseSystem.cpp include/ehs/system/BaseSystem.h
src/system/BaseOpen.cpp include/ehs/system/BaseOpen.h src/system/BaseOpen.cpp include/ehs/system/BaseOpen.h
include/ehs/system/Architecture.h include/ehs/system/Architecture.h
include/ehs/system/Mutex.h include/ehs/system/Mutex.h
include/ehs/system/Open.h include/ehs/system/Open.h
include/ehs/system/OS.h include/ehs/system/OS.h
include/ehs/system/Semaphore.h include/ehs/system/Semaphore.h
include/ehs/system/System.h include/ehs/system/System.h
src/json/Json.cpp include/ehs/json/Json.h src/json/Json.cpp include/ehs/json/Json.h
src/json/JsonBase.cpp include/ehs/json/JsonBase.h src/json/JsonBase.cpp include/ehs/json/JsonBase.h
src/json/JsonNum.cpp include/ehs/json/JsonNum.h src/json/JsonNum.cpp include/ehs/json/JsonNum.h
src/json/JsonBool.cpp include/ehs/json/JsonBool.h src/json/JsonBool.cpp include/ehs/json/JsonBool.h
src/json/JsonStr.cpp include/ehs/json/JsonStr.h src/json/JsonStr.cpp include/ehs/json/JsonStr.h
src/json/JsonObj.cpp include/ehs/json/JsonObj.h src/json/JsonObj.cpp include/ehs/json/JsonObj.h
src/json/JsonArray.cpp include/ehs/json/JsonArray.h src/json/JsonArray.cpp include/ehs/json/JsonArray.h
src/json/JsonVar.cpp include/ehs/json/JsonVar.h src/json/JsonVar.cpp include/ehs/json/JsonVar.h
src/io/Resource.cpp include/ehs/io/Resource.h src/io/Resource.cpp include/ehs/io/Resource.h
src/io/Console.cpp include/ehs/io/Console.h src/io/Console.cpp include/ehs/io/Console.h
src/io/RIFF_Chunk.cpp include/ehs/io/RIFF_Chunk.h src/io/RIFF_Chunk.cpp include/ehs/io/RIFF_Chunk.h
src/io/RIFF.cpp include/ehs/io/RIFF.h src/io/RIFF.cpp include/ehs/io/RIFF.h
src/io/BaseWindow.cpp include/ehs/io/BaseWindow.h src/io/BaseWindow.cpp include/ehs/io/BaseWindow.h
src/io/BaseFile.cpp include/ehs/io/BaseFile.h src/io/BaseFile.cpp include/ehs/io/BaseFile.h
src/io/Glyph.cpp include/ehs/io/Glyph.h src/io/Glyph.cpp include/ehs/io/Glyph.h
src/io/FontAtlas.cpp include/ehs/io/FontAtlas.h src/io/FontAtlas.cpp include/ehs/io/FontAtlas.h
src/io/BaseFileMonitor.cpp include/ehs/io/BaseFileMonitor.h src/io/BaseFileMonitor.cpp include/ehs/io/BaseFileMonitor.h
include/ehs/io/COM.h include/ehs/io/COM.h
include/ehs/io/File.h include/ehs/io/File.h
include/ehs/io/FileMonitor.h include/ehs/io/FileMonitor.h
include/ehs/io/Window.h include/ehs/io/Window.h
src/io/socket/Request.cpp include/ehs/io/socket/Request.h include/ehs/io/socket/Socket.h
src/io/socket/Response.cpp include/ehs/io/socket/Response.h src/io/socket/Request.cpp include/ehs/io/socket/Request.h
src/io/socket/BaseDNS.cpp include/ehs/io/socket/BaseDNS.h src/io/socket/Response.cpp include/ehs/io/socket/Response.h
src/io/socket/BaseUDP.cpp include/ehs/io/socket/BaseUDP.h src/io/socket/BaseDNS.cpp include/ehs/io/socket/BaseDNS.h
src/io/socket/BaseTCP.cpp include/ehs/io/socket/BaseTCP.h include/ehs/io/socket/DNS.h
src/io/socket/SSL.cpp include/ehs/io/socket/SSL.h src/io/socket/BaseUDP.cpp include/ehs/io/socket/BaseUDP.h
include/ehs/io/socket/UDP.h
src/io/socket/BaseTCP.cpp include/ehs/io/socket/BaseTCP.h
include/ehs/io/socket/TCP.h
src/io/socket/SSL.cpp include/ehs/io/socket/SSL.h
src/io/socket/rest/Twitch.cpp include/ehs/io/socket/rest/Twitch.h include/ehs/io/socket/ehc/NetUtils.h
src/io/socket/rest/TwitchChat.cpp include/ehs/io/socket/rest/TwitchChat.h src/io/socket/EHC.cpp include/ehs/io/socket/EHC.h
src/io/socket/rest/Spotify.cpp include/ehs/io/socket/rest/Spotify.h src/io/socket/ehc/NetFrag.cpp include/ehs/io/socket/ehc/NetFrag.h
include/ehs/io/socket/Socket.h src/io/socket/ehc/NetEnd.cpp include/ehs/io/socket/ehc/NetEnd.h
include/ehs/io/socket/TCP.h src/io/socket/ehc/NetSys.cpp include/ehs/io/socket/ehc/NetSys.h
include/ehs/io/socket/UDP.h src/io/socket/ehc/NetOp.cpp include/ehs/io/socket/ehc/NetOp.h
include/ehs/io/socket/DNS.h
src/io/audio/Audio.cpp include/ehs/io/audio/Audio.h src/io/socket/rest/Twitch.cpp include/ehs/io/socket/rest/Twitch.h
src/io/audio/BaseAudioDevice.cpp include/ehs/io/audio/BaseAudioDevice.h src/io/socket/rest/TwitchChat.cpp include/ehs/io/socket/rest/TwitchChat.h
src/io/audio/AudioCodec.cpp include/ehs/io/audio/AudioCodec.h src/io/socket/rest/Spotify.cpp include/ehs/io/socket/rest/Spotify.h
include/ehs/io/audio/AudioDevice.h
src/io/img/PNG.cpp include/ehs/io/img/PNG.h src/io/audio/Audio.cpp include/ehs/io/audio/Audio.h
src/io/img/Img.cpp include/ehs/io/img/Img.h src/io/audio/BaseAudioDevice.cpp include/ehs/io/audio/BaseAudioDevice.h
src/io/img/PNG_Chunk.cpp include/ehs/io/img/PNG_Chunk.h src/io/audio/AudioCodec.cpp include/ehs/io/audio/AudioCodec.h
src/io/img/ImgCodec.cpp include/ehs/io/img/ImgCodec.h include/ehs/io/audio/AudioDevice.h
include/ehs/io/mdl/Vertex.h src/io/img/PNG.cpp include/ehs/io/img/PNG.h
src/io/model/Mesh.cpp include/ehs/io/mdl/Mesh.h src/io/img/Img.cpp include/ehs/io/img/Img.h
src/io/model/Bone.cpp include/ehs/io/mdl/Bone.h src/io/img/PNG_Chunk.cpp include/ehs/io/img/PNG_Chunk.h
src/io/model/Mdl.cpp include/ehs/io/mdl/Mdl.h src/io/img/ImgCodec.cpp include/ehs/io/img/ImgCodec.h
src/io/model/Animation.cpp include/ehs/io/mdl/Animation.h
src/io/model/AnimBone.cpp include/ehs/io/mdl/AnimBone.h
src/io/model/KeyFrame.cpp include/ehs/io/mdl/KeyFrame.h
src/io/model/PropertyChange.cpp include/ehs/io/mdl/PropertyChange.h
src/io/hid/ButtonState.cpp include/ehs/io/hid/ButtonState.h include/ehs/io/mdl/Vertex.h
src/io/hid/Button.cpp include/ehs/io/hid/Button.h src/io/model/Mesh.cpp include/ehs/io/mdl/Mesh.h
src/io/hid/Mouse.cpp include/ehs/io/hid/Mouse.h src/io/model/Bone.cpp include/ehs/io/mdl/Bone.h
src/io/hid/Keyboard.cpp include/ehs/io/hid/Keyboard.h src/io/model/Mdl.cpp include/ehs/io/mdl/Mdl.h
src/io/hid/HID.cpp include/ehs/io/hid/HID.h src/io/model/Animation.cpp include/ehs/io/mdl/Animation.h
src/io/hid/InputHandler.cpp include/ehs/io/hid/InputHandler.h src/io/model/AnimBone.cpp include/ehs/io/mdl/AnimBone.h
src/io/hid/Input.cpp include/ehs/io/hid/Input.h src/io/model/KeyFrame.cpp include/ehs/io/mdl/KeyFrame.h
src/io/model/MdlCodec.cpp src/io/model/PropertyChange.cpp include/ehs/io/mdl/PropertyChange.h
include/ehs/io/mdl/MdlCodec.h
include/ehs/io/UsbBase.h src/io/hid/ButtonState.cpp include/ehs/io/hid/ButtonState.h
src/io/UsbBase.cpp src/io/hid/Button.cpp include/ehs/io/hid/Button.h
include/ehs/db/DbTable.h src/io/hid/Mouse.cpp include/ehs/io/hid/Mouse.h
include/ehs/db/DbObject.h src/io/hid/Keyboard.cpp include/ehs/io/hid/Keyboard.h
include/ehs/db/DbVar.h src/io/hid/HID.cpp include/ehs/io/hid/HID.h
src/db/DbVar.cpp src/io/hid/InputHandler.cpp include/ehs/io/hid/InputHandler.h
include/ehs/db/Database.h src/io/hid/Input.cpp include/ehs/io/hid/Input.h
src/db/DbObject.cpp src/io/model/MdlCodec.cpp
src/db/Database.cpp include/ehs/io/mdl/MdlCodec.h
src/db/Database.cpp include/ehs/io/UsbBase.h
src/db/DbTable.cpp src/io/UsbBase.cpp
include/ehs/io/BaseDirectory.h include/ehs/db/DbTable.h
src/io/BaseDirectory.cpp include/ehs/db/DbObject.h
include/ehs/io/Directory.h include/ehs/db/DbVar.h
src/db/DbVar.cpp
include/ehs/db/Database.h
src/db/DbObject.cpp
src/db/Database.cpp
src/db/Database.cpp
src/db/DbTable.cpp
include/ehs/io/BaseDirectory.h
src/io/BaseDirectory.cpp
include/ehs/io/Directory.h
include/ehs/io/socket/ehc/NetEnc.h
src/io/socket/ehc/NetEnc.cpp
include/ehs/io/socket/ehc/NetChannel.h
src/io/socket/ehc/NetChannel.cpp
include/ehs/io/socket/ehc/NetServerCh.h
include/ehs/io/socket/ehc/NetClientCh.h
src/io/socket/ehc/NetClientCh.cpp
src/io/socket/ehc/NetServerCh.cpp
src/io/socket/ehc/NetUtils.cpp
src/io/socket/BaseICMP.cpp
include/ehs/io/socket/ICMP_LNX.h
src/io/socket/ICMP_LNX.cpp
include/ehs/io/socket/ICMP.h
src/io/socket/ICMP_LNX.cpp
) )
if (IS_OS_WINDOWS) if (IS_OS_WINDOWS)
list(APPEND EHS_SOURCES list(APPEND EHS_SOURCES
src/io/socket/UDP_W32.cpp include/ehs/io/socket/UDP_W32.h src/io/socket/UDP_W32.cpp include/ehs/io/socket/UDP_W32.h
src/io/socket/TCP_W32.cpp include/ehs/io/socket/TCP_W32.h src/io/socket/TCP_W32.cpp include/ehs/io/socket/TCP_W32.h
src/io/socket/DNS_W32.cpp include/ehs/io/socket/DNS_W32.h src/io/socket/DNS_W32.cpp include/ehs/io/socket/DNS_W32.h
src/system/Semaphore_W32.cpp include/ehs/system/Semaphore_W32.h src/system/Semaphore_W32.cpp include/ehs/system/Semaphore_W32.h
src/system/System_W32.cpp include/ehs/system/System_W32.h src/system/System_W32.cpp include/ehs/system/System_W32.h
src/system/Mutex_W32.cpp include/ehs/system/Mutex_W32.h src/system/Mutex_W32.cpp include/ehs/system/Mutex_W32.h
src/system/Open_W32.cpp include/ehs/system/Open_W32.h src/system/Open_W32.cpp include/ehs/system/Open_W32.h
src/io/audio/audioDevice_W32.cpp include/ehs/io/audio/audioDevice_W32.h src/io/audio/audioDevice_W32.cpp include/ehs/io/audio/audioDevice_W32.h
src/io/File_W32.cpp include/ehs/io/File_W32.h src/io/File_W32.cpp include/ehs/io/File_W32.h
src/io/FileMonitor_W32.cpp include/ehs/io/FileMonitor_W32.h src/io/FileMonitor_W32.cpp include/ehs/io/FileMonitor_W32.h
src/io/Window_W32.cpp include/ehs/io/Window_W32.h src/io/Window_W32.cpp include/ehs/io/Window_W32.h
src/io/COM.cpp include/ehs/io/COM.h src/io/COM.cpp include/ehs/io/COM.h
src/system/CPU_MSVC_AMD64.asm src/HRNG_MSVC.asm src/Math_MSVC_AMD64.asm src/system/CPU_MSVC_AMD64.asm src/HRNG_MSVC.asm src/Math_MSVC_AMD64.asm
src/io/Directory_W32.cpp include/ehs/io/Directory_W32.h src/io/Directory_W32.cpp include/ehs/io/Directory_W32.h
) )
elseif (IS_OS_LINUX) elseif (IS_OS_LINUX)
list(APPEND EHS_SOURCES list(APPEND EHS_SOURCES
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h
src/io/socket/TCP_BSD.cpp include/ehs/io/socket/TCP_BSD.h src/io/socket/TCP_BSD.cpp include/ehs/io/socket/TCP_BSD.h
src/io/socket/DNS_LNX.cpp include/ehs/io/socket/DNS_LNX.h src/io/socket/DNS_LNX.cpp include/ehs/io/socket/DNS_LNX.h
src/system/Semaphore_P.cpp include/ehs/system/Semaphore_P.h src/system/Semaphore_P.cpp include/ehs/system/Semaphore_P.h
src/system/System_LNX.cpp include/ehs/system/System_LNX.h src/system/System_LNX.cpp include/ehs/system/System_LNX.h
src/system/Open_UNX.cpp include/ehs/system/Open_UNX.h src/system/Open_UNX.cpp include/ehs/system/Open_UNX.h
src/io/File_UNX.cpp include/ehs/io/File_UNX.h src/io/File_UNX.cpp include/ehs/io/File_UNX.h
src/io/FileMonitor_UNX.cpp include/ehs/io/FileMonitor_UNX.h src/io/FileMonitor_UNX.cpp include/ehs/io/FileMonitor_UNX.h
src/system/Mutex_PT.cpp include/ehs/system/Mutex_PT.h src/system/Mutex_PT.cpp include/ehs/system/Mutex_PT.h
src/io/audio/AudioDevice_ALSA.cpp include/ehs/io/audio/AudioDevice_ALSA.h src/io/audio/AudioDevice_PW.cpp include/ehs/io/audio/AudioDevice_PW.h
src/system/FileSystem.cpp include/ehs/system/FileSystem.h src/system/FileSystem.cpp include/ehs/system/FileSystem.h
src/system/User.cpp include/ehs/system/User.h src/system/User.cpp include/ehs/system/User.h
src/io/Directory_LNX.cpp include/ehs/io/Directory_LNX.h src/io/Directory_LNX.cpp include/ehs/io/Directory_LNX.h
src/io/Usb_LNX.cpp include/ehs/io/Usb_LNX.h src/io/Usb_LNX.cpp include/ehs/io/Usb_LNX.h
) )
set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System") #set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System")
if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland") if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland")
add_compile_definitions(EHS_WS_WAYLAND) add_compile_definitions(EHS_WS_WAYLAND)
@@ -239,27 +261,38 @@ endif()
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
#message("${CMAKE_CXX_FLAGS}") #message("${CMAKE_CXX_FLAGS}")
add_library(EHS_STC STATIC ${EHS_SOURCES}) add_library(EHS_Stc STATIC ${EHS_SOURCES})
add_library(EHS_DYN SHARED ${EHS_SOURCES}) add_library(EHS_Dyn SHARED ${EHS_SOURCES}
include/ehs/io/socket/BaseICMP.h)
add_executable(StrToHash src/StrToHash.cpp) add_executable(StrToHash src/StrToHash.cpp)
target_compile_definitions(EHS_DYN PRIVATE EHS_LIB_EXPORT) target_compile_definitions(EHS_Dyn PRIVATE EHS_LIB_EXPORT)
target_include_directories(EHS_STC PUBLIC ${PROJECT_SOURCE_DIR}/include) target_include_directories(EHS_Stc PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_include_directories(EHS_DYN PUBLIC ${PROJECT_SOURCE_DIR}/include) target_include_directories(EHS_Dyn PUBLIC ${PROJECT_SOURCE_DIR}/include)
if (IS_OS_LINUX) if (IS_OS_LINUX)
set(CMAKE_INSTALL_PREFIX "${USER_HOME_DIRECTORY}/.local") set(CMAKE_INSTALL_PREFIX "${USER_HOME_DIRECTORY}/.local")
install(TARGETS EHS_Dyn LIBRARY DESTINATION "bin")
find_package(PkgConfig REQUIRED)
pkg_check_modules(PIPEWIRE REQUIRED libpipewire-0.3)
target_include_directories(EHS_Stc PRIVATE ${PIPEWIRE_INCLUDE_DIRS})
target_include_directories(EHS_Dyn PRIVATE ${PIPEWIRE_INCLUDE_DIRS})
elseif (IS_OS_WINDOWS) elseif (IS_OS_WINDOWS)
set(CMAKE_INSTALL_PREFIX "${USER_HOME_DIRECTORY}/EHS") set(CMAKE_INSTALL_PREFIX "${USER_HOME_DIRECTORY}/EHS")
install(TARGETS EHS_Dyn LIBRARY DESTINATION "lib")
install(TARGETS EHS_Dyn RUNTIME DESTINATION "bin")
file(GLOB DLL_FILES "${CMAKE_CURRENT_BINARY_DIR}/*.dll")
install(FILES ${DLL_FILES} DESTINATION "bin")
endif () endif ()
install(TARGETS EHS_STC DESTINATION lib) install(TARGETS EHS_Stc DESTINATION "lib")
install(TARGETS EHS_DYN RUNTIME DESTINATION bin) install(TARGETS StrToHash DESTINATION "bin")
install(TARGETS EHS_DYN LIBRARY DESTINATION lib)
install(TARGETS StrToHash DESTINATION bin)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION "include")
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
if (ZLIB_FOUND) if (ZLIB_FOUND)
@@ -275,17 +308,22 @@ else ()
message(STATUS "OpenSSL was not found.") message(STATUS "OpenSSL was not found.")
endif () endif ()
target_link_libraries(EHS_STC OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB) target_link_libraries(EHS_Stc OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB)
target_link_libraries(EHS_DYN OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB avrt ws2_32) target_link_libraries(EHS_Dyn OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB)
target_link_libraries(StrToHash OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB)
if (IS_OS_WINDOWS) if (IS_OS_WINDOWS)
target_link_libraries(StrToHash ws2_32 avrt EHS_STC) target_link_libraries(EHS_Dyn avrt ws2_32)
target_link_libraries(StrToHash ws2_32 avrt EHS_Stc)
elseif (IS_OS_LINUX) elseif (IS_OS_LINUX)
if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland") if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland")
target_link_libraries(EHS_Dyn wayland-client)
target_link_libraries(StrToHash wayland-client) target_link_libraries(StrToHash wayland-client)
elseif (LINUX_WINDOW_SYSTEM STREQUAL "XCB") elseif (LINUX_WINDOW_SYSTEM STREQUAL "XCB")
target_link_libraries(EHS_Dyn xcb xcb-cursor xcb-xfixes xcb-xinput)
target_link_libraries(StrToHash xcb xcb-cursor xcb-xfixes xcb-xinput) target_link_libraries(StrToHash xcb xcb-cursor xcb-xfixes xcb-xinput)
endif () endif ()
target_link_libraries(StrToHash z asound EHS_STC) target_link_libraries(EHS_Dyn z asound pipewire-0.3)
target_link_libraries(StrToHash z asound EHS_Stc)
endif () endif ()

View File

@@ -1,12 +0,0 @@
{
"version": 3,
"configurePresets": [
{
"name": "default",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
}
]
}

View File

@@ -73,8 +73,10 @@ Wayland Window System. Wayland support is currently not fully supported yet, use
- [CMake](https://cmake.org/) - [CMake](https://cmake.org/)
- [vcpkg](https://learn.microsoft.com/en-us/vcpkg/get_started/get-started?pivots=shell-cmd) - [vcpkg](https://learn.microsoft.com/en-us/vcpkg/get_started/get-started?pivots=shell-cmd)
`vcpkg install` - Use this command in the directory where `vcpkg.json` is located to download/install dependencies.
### Building ### Building
`cmake -A x64 -DCMAKE_BUILD_TYPE=Release --preset=default /path/to/source` `cmake -A x64 -DCMAKE_BUILD_TYPE=Release /path/to/source`
### Compiling ### Compiling
`cmake --build /path/to/build --config Release` `cmake --build /path/to/build --config Release`
@@ -89,12 +91,10 @@ This will require the terminal to be running in administrator mode.
#include <ehs/EHS.h> #include <ehs/EHS.h>
#include <ehs/io/Console.h> #include <ehs/io/Console.h>
ehs::Int_32 Main(ehs::Str_8* appName, ehs::Str_8* appVerId, ehs::Version* appVer) int main()
{ {
// Simple identifying meta-data for the logger. // Simple identifying meta-data for the logger.
*appName = "Simple Example App"; // The application's name ehs::Initialize("Simple Example App", "Release", {1, 0, 0});
*appVerId = "Release"; // The app's version prefix; i.e. Alpha, Beta or Release as an example.
*appVer = {1, 0, 0}; // The app's version major, minor and patch number.
ehs::Console::Write_8("How old are you?"); // Write to the console in UTF_8 character encoding. ehs::Console::Write_8("How old are you?"); // Write to the console in UTF_8 character encoding.
@@ -103,13 +103,15 @@ ehs::Int_32 Main(ehs::Str_8* appName, ehs::Str_8* appVerId, ehs::Version* appVer
if (!response.IsNum()) if (!response.IsNum())
{ {
ehs::Console::Clear(); // Clear the console's buffer. ehs::Console::Clear(); // Clear the console's buffer.
return Main(appName, appVerId, appVer); // Repeat process if given response is not a number. return main(); // Repeat process if given response is not a number.
} }
ehs::UInt_8 age = response.ToDecimal<ehs::UInt_8>(); // Converts the string number into a number based primitive. ehs::UInt_8 age = response.ToDecimal<ehs::UInt_8>(); // Converts the string number into a number based primitive.
ehs::Console::Write("Your age is " + ehs::Str_8::FromNum(age) + "."); // Write the console with the age converted back to string. ehs::Console::Write("Your age is " + ehs::Str_8::FromNum(age) + "."); // Write the console with the age converted back to string.
ehs::Uninitialize();
return 0; return 0;
} }
``` ```

View File

@@ -12,7 +12,7 @@ namespace ehs
/// @tparam T Array data type to use. /// @tparam T Array data type to use.
/// @tparam N Number data type to use. /// @tparam N Number data type to use.
template<typename T, typename N = UInt_64> template<typename T, typename N = UInt_64>
class Array : public BaseObj class Array
{ {
protected: protected:
T* data; T* data;
@@ -20,7 +20,7 @@ namespace ehs
public: public:
/// Frees any data created on the heap. /// Frees any data created on the heap.
~Array() override ~Array()
{ {
delete[] data; delete[] data;
} }
@@ -29,7 +29,6 @@ namespace ehs
Array() Array()
: data(nullptr), size(0) : data(nullptr), size(0)
{ {
AddType("Array");
} }
/// Initializes an empty array with the given size. /// Initializes an empty array with the given size.
@@ -37,7 +36,6 @@ namespace ehs
explicit Array(const N size) explicit Array(const N size)
: data(new T[size]), size(size) : data(new T[size]), size(size)
{ {
AddType("Array");
} }
/// Initializes this array with an initializer list object. /// Initializes this array with an initializer list object.
@@ -45,8 +43,6 @@ namespace ehs
Array(std::initializer_list<T> list) Array(std::initializer_list<T> list)
: data(new T[list.size()]), size(list.size()) : data(new T[list.size()]), size(list.size())
{ {
AddType("Array");
N i = 0; N i = 0;
for (auto v = list.begin(); v != list.end(); ++v) for (auto v = list.begin(); v != list.end(); ++v)
data[i++] = std::move(*v); data[i++] = std::move(*v);
@@ -58,14 +54,12 @@ namespace ehs
Array(const T* const data, const N size) Array(const T* const data, const N size)
: data(new T[size]), size(size) : data(new T[size]), size(size)
{ {
AddType("Array");
for (N i = 0; i < size; ++i) for (N i = 0; i < size; ++i)
this->data[i] = data[i]; this->data[i] = data[i];
} }
Array(Array&& array) noexcept Array(Array&& array) noexcept
: BaseObj(array), data(array.data), size(array.size) : data(array.data), size(array.size)
{ {
array.data = nullptr; array.data = nullptr;
array.size = 0; array.size = 0;
@@ -74,7 +68,7 @@ namespace ehs
/// Copies all members from the given array object. /// Copies all members from the given array object.
/// @param [in] array The array object to copy from. /// @param [in] array The array object to copy from.
Array(const Array& array) Array(const Array& array)
: BaseObj((BaseObj&&)array), data(new T[array.size]), size(array.size) : data(new T[array.size]), size(array.size)
{ {
for (N i = 0; i < size; ++i) for (N i = 0; i < size; ++i)
data[i] = array.data[i]; data[i] = array.data[i];
@@ -85,8 +79,6 @@ namespace ehs
if (this == &array) if (this == &array)
return *this; return *this;
BaseObj::operator=((BaseObj&&)array);
delete[] data; delete[] data;
data = array.data; data = array.data;
size = array.size; size = array.size;
@@ -105,8 +97,6 @@ namespace ehs
if (this == &array) if (this == &array)
return *this; return *this;
BaseObj::operator=(array);
delete[] data; delete[] data;
data = new T[array.size]; data = new T[array.size];
for (N i = 0; i < array.size; ++i) for (N i = 0; i < array.size; ++i)

View File

@@ -332,14 +332,14 @@ namespace ehs
static Mat4<T> YawRotate(const T angle) static Mat4<T> YawRotate(const T angle)
{ {
T radians = Math::Rads(angle); T radians = Math::Rads<T>(angle);
Mat4<T> result; Mat4<T> result;
result.data[0] = Math::Cos(radians); result.data[0] = Math::Cos<T>(radians);
result.data[2] = -Math::Sin(radians); result.data[2] = -Math::Sin<T>(radians);
result.data[5] = 1; result.data[5] = 1;
result.data[8] = Math::Sin(radians); result.data[8] = Math::Sin<T>(radians);
result.data[10] = Math::Cos(radians); result.data[10] = Math::Cos<T>(radians);
result.data[15] = 1; result.data[15] = 1;
return result; return result;
@@ -347,7 +347,7 @@ namespace ehs
static Mat4<T> RollRotate(const T angle) static Mat4<T> RollRotate(const T angle)
{ {
T radians = Math::Rads(angle); T radians = Math::Rads<T>(angle);
Mat4<T> result; Mat4<T> result;
result.data[0] = Math::Cos(radians); result.data[0] = Math::Cos(radians);
@@ -367,7 +367,7 @@ namespace ehs
static Mat4<T> RH_Perspective(const T fov, const T aspect, const T zNear, const T zFar) static Mat4<T> RH_Perspective(const T fov, const T aspect, const T zNear, const T zFar)
{ {
const float tanHalfFovy = tan(Math::Rads(fov) / 2.0f); const T tanHalfFovy = Math::Tan<T>(Math::Rads(fov) / 2.0f);
Mat4<T> result; Mat4<T> result;
result[0] = 1.0f / (aspect * tanHalfFovy); result[0] = 1.0f / (aspect * tanHalfFovy);
@@ -380,7 +380,7 @@ namespace ehs
static Mat4<T> LH_Perspective(const T fov, const T aspect, const T zNear, const T zFar) static Mat4<T> LH_Perspective(const T fov, const T aspect, const T zNear, const T zFar)
{ {
const float tanHalfFovy = Math::Tan(Math::Rads(fov) / 2.0f); const T tanHalfFovy = Math::Tan<T>(Math::Rads(fov) / 2.0f);
Mat4<T> result; Mat4<T> result;
result[0] = 1.0f / (aspect * tanHalfFovy); result[0] = 1.0f / (aspect * tanHalfFovy);

View File

@@ -21,7 +21,7 @@
namespace ehs namespace ehs
{ {
template<typename N = UInt_64> template<typename N = UInt_64>
class Serializer : public BaseObj class Serializer
{ {
private: private:
Endianness endianness; Endianness endianness;
@@ -30,7 +30,7 @@ namespace ehs
N offset; N offset;
public: public:
~Serializer() override ~Serializer()
{ {
delete[] data; delete[] data;
} }
@@ -38,32 +38,27 @@ namespace ehs
Serializer() Serializer()
: endianness(Endianness::BE), data(nullptr), size(0), offset(0) : endianness(Endianness::BE), data(nullptr), size(0), offset(0)
{ {
AddType("Serializer");
} }
Serializer(const Endianness endianness) Serializer(const Endianness endianness)
: endianness(endianness), data(nullptr), size(0), offset(0) : endianness(endianness), data(nullptr), size(0), offset(0)
{ {
AddType("Serializer");
} }
Serializer(const Endianness endianness, const N size) Serializer(const Endianness endianness, const N size)
: endianness(endianness), data(new Byte[size]), size(size), offset(0) : endianness(endianness), data(new Byte[size]), size(size), offset(0)
{ {
AddType("Serializer");
} }
Serializer(const Endianness endianness, const Byte* const data, const N size, const N offset = 0) Serializer(const Endianness endianness, const Byte* const data, const N size, const N offset = 0)
: endianness(endianness), data(new Byte[size]), size(size), offset(offset) : endianness(endianness), data(new Byte[size]), size(size), offset(offset)
{ {
AddType("Serializer");
for (N i = 0; i < size; ++i) for (N i = 0; i < size; ++i)
this->data[i] = data[i]; this->data[i] = data[i];
} }
Serializer(Serializer&& serializer) noexcept Serializer(Serializer&& serializer) noexcept
: BaseObj((BaseObj&&)serializer), endianness(serializer.endianness), data(serializer.data), : endianness(serializer.endianness), data(serializer.data),
size(serializer.size), offset(serializer.offset) size(serializer.size), offset(serializer.offset)
{ {
serializer.data = nullptr; serializer.data = nullptr;
@@ -72,7 +67,7 @@ namespace ehs
} }
Serializer(const Serializer& serializer) Serializer(const Serializer& serializer)
: BaseObj(serializer), endianness(serializer.endianness), data(new Byte[serializer.size]), : endianness(serializer.endianness), data(new Byte[serializer.size]),
size(serializer.size), offset(serializer.offset) size(serializer.size), offset(serializer.offset)
{ {
for (N i = 0; i < serializer.size; ++i) for (N i = 0; i < serializer.size; ++i)
@@ -84,8 +79,6 @@ namespace ehs
if (this == &serializer) if (this == &serializer)
return *this; return *this;
BaseObj::operator=((Serializer&&)serializer);
endianness = serializer.endianness; endianness = serializer.endianness;
delete[] data; delete[] data;
data = serializer.data; data = serializer.data;
@@ -104,8 +97,6 @@ namespace ehs
if (this == &serializer) if (this == &serializer)
return *this; return *this;
BaseObj::operator=(serializer);
endianness = serializer.endianness; endianness = serializer.endianness;
delete[] data; delete[] data;
@@ -1228,7 +1219,7 @@ namespace ehs
void Resize(const N newSize) void Resize(const N newSize)
{ {
Byte* result = new Byte[newSize]; Byte* result = new Byte[newSize];
Util::Copy(result, data, size); Util::Copy(result, data, newSize >= size ? size : newSize);
delete[] data; delete[] data;
data = result; data = result;
size = newSize; size = newSize;

View File

@@ -25,7 +25,7 @@ namespace ehs
/// @tparam T The character's data type to use. /// @tparam T The character's data type to use.
/// @tparam N The number data type to use. /// @tparam N The number data type to use.
template<typename T = Char_8, typename N = UInt_64> template<typename T = Char_8, typename N = UInt_64>
class Str : public BaseObj class Str
{ {
private: private:
N size; N size;
@@ -33,7 +33,7 @@ namespace ehs
public: public:
/// Frees any data created on the heap. /// Frees any data created on the heap.
~Str() override ~Str()
{ {
delete[] data; delete[] data;
} }
@@ -42,7 +42,6 @@ namespace ehs
Str() Str()
: size(0), data(nullptr) : size(0), data(nullptr)
{ {
AddType("Str");
} }
/// Initializes members with given C-style string. /// Initializes members with given C-style string.
@@ -56,8 +55,6 @@ namespace ehs
Util::Copy(data, str, Size(true)); Util::Copy(data, str, Size(true));
data[this->size] = 0; data[this->size] = 0;
AddType("Str");
} }
/// Initializes members with given C-style string. /// Initializes members with given C-style string.
@@ -70,8 +67,6 @@ namespace ehs
Util::Copy(data, str, Size(true)); Util::Copy(data, str, Size(true));
data[size] = 0; data[size] = 0;
AddType("Str");
} }
/// Initializes string with the given size. /// Initializes string with the given size.
@@ -80,13 +75,11 @@ namespace ehs
: size(size), data(new T[size + 1]) : size(size), data(new T[size + 1])
{ {
data[size] = 0; data[size] = 0;
AddType("Str");
} }
/// A move constructor. /// A move constructor.
Str(Str&& str) noexcept Str(Str&& str) noexcept
: BaseObj((BaseObj&&)str), size(str.size), data(str.data) : size(str.size), data(str.data)
{ {
str.size = 0; str.size = 0;
str.data = nullptr; str.data = nullptr;
@@ -95,7 +88,7 @@ namespace ehs
/// Copies all members from the given string object. /// Copies all members from the given string object.
/// @param [in] str The string object to copy from. /// @param [in] str The string object to copy from.
Str(const Str& str) Str(const Str& str)
: BaseObj(str), size(str.size), data(new T[size + 1]) : size(str.size), data(new T[size + 1])
{ {
Util::Copy(data, str.data, Size(true)); Util::Copy(data, str.data, Size(true));
@@ -107,8 +100,6 @@ namespace ehs
if (this == &str) if (this == &str)
return *this; return *this;
BaseObj::operator=((BaseObj&&)str);
size = str.size; size = str.size;
delete[] data; delete[] data;
data = str.data; data = str.data;
@@ -127,8 +118,6 @@ namespace ehs
if (&str == this) if (&str == this)
return *this; return *this;
BaseObj::operator=(str);
size = str.size; size = str.size;
delete[] data; delete[] data;
@@ -1879,6 +1868,9 @@ namespace ehs
/// @returns The character count. /// @returns The character count.
static N Len(const T* const str) static N Len(const T* const str)
{ {
if (!str)
return 0;
N count = 0; N count = 0;
while (str[count]) while (str[count])
++count; ++count;

View File

@@ -14,7 +14,7 @@ namespace ehs
/// @tparam N Number data type to use. /// @tparam N Number data type to use.
/// @note If extra memory is set to five then each time that memory is filled it will add five extra. /// @note If extra memory is set to five then each time that memory is filled it will add five extra.
template<typename T, typename N = UInt_64> template<typename T, typename N = UInt_64>
class Vector : public BaseObj class Vector
{ {
protected: protected:
N rawSize; N rawSize;
@@ -24,7 +24,7 @@ namespace ehs
public: public:
/// Frees any data created on the heap. /// Frees any data created on the heap.
~Vector() override ~Vector()
{ {
delete[] data; delete[] data;
} }
@@ -33,7 +33,6 @@ namespace ehs
Vector() Vector()
: rawSize(0), size(0), stride(5), data(nullptr) : rawSize(0), size(0), stride(5), data(nullptr)
{ {
AddType("Vector");
} }
/// Initializes members for pre-allocated memory to write to later. /// Initializes members for pre-allocated memory to write to later.
@@ -42,7 +41,6 @@ namespace ehs
Vector(const N size, const N stride) Vector(const N size, const N stride)
: rawSize(size + stride), size(size), stride(stride), data(new T[rawSize]) : rawSize(size + stride), size(size), stride(stride), data(new T[rawSize])
{ {
AddType("Vector");
} }
/// Initializes this vector with an initializer list object. /// Initializes this vector with an initializer list object.
@@ -51,8 +49,6 @@ namespace ehs
Vector(std::initializer_list<T> list, const N stride = 5) Vector(std::initializer_list<T> list, const N stride = 5)
: rawSize(0), size(list.size()), stride(stride), data(nullptr) : rawSize(0), size(list.size()), stride(stride), data(nullptr)
{ {
AddType("Vector");
if (stride) if (stride)
{ {
rawSize = list.size() / stride * stride; rawSize = list.size() / stride * stride;
@@ -78,8 +74,6 @@ namespace ehs
Vector(const T* data, const N size, const N stride) Vector(const T* data, const N size, const N stride)
: rawSize(0), size(size), stride(stride), data(nullptr) : rawSize(0), size(size), stride(stride), data(nullptr)
{ {
AddType("Vector");
if (stride) if (stride)
{ {
rawSize = size / stride * stride; rawSize = size / stride * stride;
@@ -100,14 +94,14 @@ namespace ehs
/// Copies all members from the given vector object. /// Copies all members from the given vector object.
/// @param [in] vec The vector object to copy from. /// @param [in] vec The vector object to copy from.
Vector(const Vector& vec) Vector(const Vector& vec)
: BaseObj(vec), rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(new T[rawSize]) : rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(new T[rawSize])
{ {
for (N i = 0; i < size; ++i) for (N i = 0; i < size; ++i)
data[i] = vec.data[i]; data[i] = vec.data[i];
} }
Vector(Vector&& vec) noexcept Vector(Vector&& vec) noexcept
: BaseObj((BaseObj&&)vec), rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(vec.data) : rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(vec.data)
{ {
vec.rawSize = 0; vec.rawSize = 0;
vec.size = 0; vec.size = 0;
@@ -123,8 +117,6 @@ namespace ehs
if (this == &vec) if (this == &vec)
return *this; return *this;
BaseObj::operator=(vec);
rawSize = vec.rawSize; rawSize = vec.rawSize;
size = vec.size; size = vec.size;
stride = vec.stride; stride = vec.stride;
@@ -143,8 +135,6 @@ namespace ehs
if (this == &vec) if (this == &vec)
return *this; return *this;
BaseObj::operator=((BaseObj&&)vec);
rawSize = vec.rawSize; rawSize = vec.rawSize;
size = vec.size; size = vec.size;
stride = vec.stride; stride = vec.stride;

View File

@@ -81,10 +81,14 @@ namespace ehs
UInt_64 GetSampleCount() const; UInt_64 GetSampleCount() const;
UInt_8 GetFrameSize() const;
UInt_64 GetSize() const; UInt_64 GetSize() const;
float GetLength() const; float GetLength() const;
Byte* GetFrame(UInt_64 frameIndex) const;
Array<Byte> FrameAsMono(UInt_64 frameIndex) const; Array<Byte> FrameAsMono(UInt_64 frameIndex) const;
Array<Byte> FrameAsStereo(UInt_64 frameIndex) const; Array<Byte> FrameAsStereo(UInt_64 frameIndex) const;

View File

@@ -5,5 +5,5 @@
#if defined(EHS_OS_WINDOWS) #if defined(EHS_OS_WINDOWS)
#include "AudioDevice_W32.h" #include "AudioDevice_W32.h"
#elif defined(EHS_OS_LINUX) #elif defined(EHS_OS_LINUX)
#include "AudioDevice_ALSA.h" #include "AudioDevice_PW.h"
#endif #endif

View File

@@ -1,46 +0,0 @@
#pragma once
#include "ehs/EHS.h"
#include "BaseAudioDevice.h"
#include <alsa/asoundlib.h>
namespace ehs
{
class EHS_LIB_IO AudioDevice : public BaseAudioDevice
{
private:
snd_pcm_t* hdl;
public:
~AudioDevice() override;
AudioDevice();
AudioDevice(AudioDevice&& device) noexcept;
AudioDevice(const AudioDevice& device);
AudioDevice& operator=(AudioDevice&& device) noexcept;
AudioDevice& operator=(const AudioDevice& device);
void Release() override;
void OpenStream() override;
void CloseStream() override;
UInt_64 GetAvailFrames() const override;
Byte* Map(UInt_64* offset, UInt_64* frames) override;
void UnMap(const UInt_64 offset, const UInt_64 frames) override;
bool IsValid() const override;
static AudioDevice GetDefault(const AudioDeviceType type);
static Array<AudioDevice> Get(const AudioDeviceType type, const AudioDeviceState state);
};
}

View File

@@ -0,0 +1,67 @@
#pragma once
#include "ehs/EHS.h"
#include "BaseAudioDevice.h"
#include <pipewire/pipewire.h>
#include <pipewire/loop.h>
#include <pipewire/context.h>
#include <pipewire/stream.h>
#include <spa/param/audio/format-utils.h>
namespace ehs
{
class EHS_LIB_IO AudioDevice final : public BaseAudioDevice
{
private:
static Array<AudioDevice> devices;
static AudioDevice defOut;
static AudioDevice defIn;
UInt_32 id;
Str_8 name;
pw_loop *loop;
pw_context *context;
pw_core *core;
pw_stream *input;
pw_stream *output;
static void RegistryEventGlobal(void *data, UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props);
static void RegistryEventGlobalRemove(void *data, UInt_32 id);
static void OnParamChanged(void *data, UInt_32 id, const spa_pod *param);
public:
~AudioDevice() override;
AudioDevice();
AudioDevice(AudioDevice&& device) noexcept;
AudioDevice(const AudioDevice& device);
AudioDevice& operator=(AudioDevice&& device) noexcept;
AudioDevice& operator=(const AudioDevice& device);
void OpenStream() override;
void CloseStream() override;
UInt_64 SendStream(const void *data, UInt_64 size) override;
UInt_64 ReceiveStream(void *data, UInt_64 size) override;
bool IsStreaming() const override;
bool IsValid() const override;
static AudioDevice GetDefault(AudioDeviceType type);
static Array<AudioDevice> Get(AudioDeviceType type, AudioDeviceState state);
private:
Str_8 GetCategory() const;
};
}

View File

@@ -12,7 +12,7 @@ struct IMMDevice;
namespace ehs namespace ehs
{ {
class EHS_LIB_IO AudioDevice : public BaseAudioDevice class EHS_LIB_IO AudioDevice final : public BaseAudioDevice
{ {
private: private:
IMMDevice* hdl; IMMDevice* hdl;
@@ -33,17 +33,13 @@ namespace ehs
AudioDevice& operator=(const AudioDevice& device); AudioDevice& operator=(const AudioDevice& device);
void Release() override;
void OpenStream() override; void OpenStream() override;
void CloseStream() override; void CloseStream() override;
UInt_64 GetAvailFrames() const override; UInt_64 SendStream(const void *data, UInt_64 outFrameSize) override;
Byte* Map(UInt_64* offset, UInt_64* frames) override; UInt_64 ReceiveStream(void *data, UInt_64 inFrameSize) override;
void UnMap(const UInt_64 offset, const UInt_64 frames) override;
Str_32 GetInterfaceName_32() const; Str_32 GetInterfaceName_32() const;
@@ -57,10 +53,12 @@ namespace ehs
Str_8 GetName_8() const; Str_8 GetName_8() const;
bool IsStreaming() const override;
bool IsValid() const override; bool IsValid() const override;
static AudioDevice GetDefault(const AudioDeviceType type); static AudioDevice GetDefault(AudioDeviceType type);
static Array<AudioDevice> Get(const AudioDeviceType type, const AudioDeviceState state); static Array<AudioDevice> Get(AudioDeviceType type, AudioDeviceState state);
}; };
} }

View File

@@ -10,8 +10,8 @@ namespace ehs
{ {
enum class AudioDeviceType enum class AudioDeviceType
{ {
OUTPUT = 0x0,
INPUT = 0x1, INPUT = 0x1,
OUTPUT = 0x0,
ALL = 0x2 ALL = 0x2
}; };
@@ -28,13 +28,12 @@ namespace ehs
protected: protected:
AudioDeviceType type; AudioDeviceType type;
DataType dataType; DataType dataType;
UInt_16 bitDepth; UInt_16 byteDepth;
UInt_32 sampleRate; UInt_32 sampleRate;
UInt_32 channels; UInt_32 channels;
UInt_32 period; UInt_32 period;
UInt_32 latency; UInt_32 latency;
UInt_64 maxFrames; UInt_64 maxFrames;
bool streaming;
public: public:
virtual ~BaseAudioDevice() = default; virtual ~BaseAudioDevice() = default;
@@ -45,21 +44,21 @@ namespace ehs
BaseAudioDevice& operator=(const BaseAudioDevice& device); BaseAudioDevice& operator=(const BaseAudioDevice& device);
virtual void Release();
virtual void OpenStream(); virtual void OpenStream();
virtual void CloseStream(); virtual void CloseStream();
virtual UInt_64 GetAvailFrames() const; virtual UInt_64 SendStream(const void *data, UInt_64 size);
virtual Byte* Map(UInt_64* offset, UInt_64* frames); virtual UInt_64 ReceiveStream(void *data, UInt_64 size);
virtual void UnMap(const UInt_64 offset, const UInt_64 frames); void BridgeStreams(BaseAudioDevice *input, UInt_64 frameBufferSize);
void BridgeStreams(UInt_64 frameBufferSize);
AudioDeviceType GetType() const; AudioDeviceType GetType() const;
void SetDataType(const DataType newDataType); void SetDataType(DataType newDataType);
DataType GetDataType() const; DataType GetDataType() const;
@@ -67,39 +66,39 @@ namespace ehs
UInt_16 GetBitDepth() const; UInt_16 GetBitDepth() const;
void SetSampleRate(const UInt_32 newSampleRate); void SetSampleRate(UInt_32 newSampleRate);
UInt_32 GetSampleRate() const; UInt_32 GetSampleRate() const;
void SetChannels(const UInt_32 newChannels); void SetChannels(UInt_32 newChannels);
UInt_16 GetChannels() const; UInt_16 GetChannels() const;
UInt_32 GetFrameSize() const; UInt_32 GetFrameSize() const;
void SetPeriod(const UInt_32 newPeriod); void SetPeriod(UInt_32 newPeriod);
UInt_32 GetPeriod() const; UInt_32 GetPeriod() const;
void SetLatency(const UInt_32 newLatency); void SetLatency(UInt_32 newLatency);
UInt_32 GetLatency() const; UInt_32 GetLatency() const;
UInt_64 GetMaxFrames() const; UInt_64 GetMaxFrames() const;
bool IsStreaming() const; virtual bool IsStreaming() const;
virtual bool IsValid() const; virtual bool IsValid() const;
/// Retrieves the default audio input/output device. /// Retrieves the default audio input/output device.
/// @param [in] type The audio device type to retrieve. /// @param [in] type The audio device type to retrieve.
/// @param [out] device The default audio device. /// @param [out] device The default audio device.
static BaseAudioDevice GetDefault(const AudioDeviceType type); static BaseAudioDevice GetDefault(AudioDeviceType type);
/// Retrieves a list of audio input/output devices. /// Retrieves a list of audio input/output devices.
/// @param [in] type The audio device type to retrieve. /// @param [in] type The audio device type to retrieve.
/// @param [in] state The audio device state to retrieve. /// @param [in] state The audio device state to retrieve.
/// @param [out] devices The list of audio devices. /// @param [out] devices The list of audio devices.
static Array<BaseAudioDevice> Get(const AudioDeviceType type, const AudioDeviceState state); static Array<BaseAudioDevice> Get(AudioDeviceType type, AudioDeviceState state);
}; };
} }

View File

@@ -8,24 +8,30 @@ namespace ehs
class EHS_LIB_IO Button class EHS_LIB_IO Button
{ {
private: private:
Str_8 name;
UInt_32 hash; UInt_32 hash;
Str_8 name;
public: public:
Button(); Button();
Button(const Str_8& name); Button(Str_8 name);
Button(const Button& key); Button(Button &&key) noexcept;
Button& operator=(const Button& key); Button(const Button &key);
bool operator==(const Button& key) const; Button &operator=(Button &&key) noexcept;
bool operator!=(const Button& key) const; Button &operator=(const Button &key);
bool operator==(const Button &key) const;
bool operator!=(const Button &key) const;
UInt_32 GetHash() const;
Str_8 GetName() const; Str_8 GetName() const;
UInt_32 GetHash() const; bool IsValid() const;
}; };
} }

View File

@@ -15,11 +15,15 @@ namespace ehs
Str_8 name; Str_8 name;
UInt_64 id; UInt_64 id;
Array<ButtonState> states; Array<ButtonState> states;
Button lastState;
float heldTime;
float activateTime;
bool active;
public: public:
HID(); HID();
HID(const UInt_8 type, Str_8 name, const UInt_64 id); HID(UInt_8 type, Str_8 name, UInt_64 id);
HID(HID&& hid) noexcept; HID(HID&& hid) noexcept;
@@ -33,11 +37,11 @@ namespace ehs
bool operator!=(const HID& other) const; bool operator!=(const HID& other) const;
bool operator==(const UInt_64 otherId) const; bool operator==(UInt_64 otherId) const;
bool operator!=(const UInt_64 otherId) const; bool operator!=(UInt_64 otherId) const;
virtual void Poll(); virtual void Poll(float delta);
UInt_8 GetType() const; UInt_8 GetType() const;
@@ -71,6 +75,10 @@ namespace ehs
const ButtonState* IsUp() const; const ButtonState* IsUp() const;
const ButtonState *IsPressed(const Button &button);
const ButtonState *GetPressed();
void ButtonDown(const Button& button); void ButtonDown(const Button& button);
void ButtonUp(const Button& button); void ButtonUp(const Button& button);
@@ -87,5 +95,11 @@ namespace ehs
bool AddState(const ButtonState& state); bool AddState(const ButtonState& state);
ButtonState* GetState(const Button& button); ButtonState* GetState(const Button& button);
bool TickHoldTime(float delta);
void ResetTime();
void TickActivateTime(float delta);
}; };
} }

View File

@@ -10,6 +10,8 @@ namespace ehs
private: private:
UInt_64 hashId; UInt_64 hashId;
Str_8 id; Str_8 id;
UInt_64 start;
UInt_64 delta;
protected: protected:
Array<HID*> devices; Array<HID*> devices;
@@ -29,9 +31,9 @@ namespace ehs
InputHandler& operator=(const InputHandler& ih); InputHandler& operator=(const InputHandler& ih);
bool operator==(const UInt_64 otherHashId); bool operator==(const UInt_64 otherHashId) const;
bool operator!=(const UInt_64 otherHashId); bool operator!=(const UInt_64 otherHashId) const;
virtual bool Initialize(); virtual bool Initialize();

View File

@@ -23,7 +23,7 @@ namespace ehs
Keyboard& operator=(const Keyboard& hid); Keyboard& operator=(const Keyboard& hid);
void Poll() override; void Poll(float delta) override;
Keyboard* Clone() const override; Keyboard* Clone() const override;

View File

@@ -19,7 +19,7 @@ namespace ehs
public: public:
Mouse(); Mouse();
Mouse(Str_8 name, const UInt_64 id); Mouse(Str_8 name, UInt_64 id);
Mouse(Mouse&& hid) noexcept = default; Mouse(Mouse&& hid) noexcept = default;
@@ -29,7 +29,7 @@ namespace ehs
Mouse& operator=(const Mouse& hid); Mouse& operator=(const Mouse& hid);
void Poll() override; void Poll(float delta) override;
void SetDelta(const Vec2_s32& newDelta); void SetDelta(const Vec2_s32& newDelta);

View File

@@ -8,7 +8,7 @@ namespace ehs
class EHS_LIB_IO BaseDNS class EHS_LIB_IO BaseDNS
{ {
public: public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname); static Str_8 Resolve(IP type, const Str_8 &hostname);
/// Resolves a hostname to an ip address. /// Resolves a hostname to an ip address.
/// @param [in] hostname The given hostname to resolve. /// @param [in] hostname The given hostname to resolve.

View File

@@ -0,0 +1,53 @@
#pragma once
#include "ehs/Serializer.h"
#include "ehs/Types.h"
#include "ehs/io/socket/Socket.h"
namespace ehs
{
struct ICMP_Header
{
UInt_8 type;
UInt_8 code;
UInt_16 checksum;
};
struct ICMP_EchoRequest
{
UInt_16 id;
UInt_16 sequence;
};
class BaseICMP
{
private:
IP version;
public:
BaseICMP();
BaseICMP(IP version);
BaseICMP(BaseICMP &&icmp) noexcept;
BaseICMP(const BaseICMP &icmp);
BaseICMP &operator=(BaseICMP &&icmp) noexcept;
BaseICMP &operator=(const BaseICMP &icmp);
virtual UInt_64 Send(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size);
virtual UInt_64 Receive(Str_8 &address, ICMP_Header header, Serializer<UInt_64> &data);
void SendEchoRequest(const Str_8 &address, ICMP_EchoRequest er, const Byte *data, UInt_64 size);
virtual void SetReceiveTimeout(UInt_64 timeout);
virtual bool IsValid() const;
protected:
static UInt_16 ComputeChecksum(UInt_16 *buffer, Size length);
};
}

View File

@@ -12,7 +12,7 @@ namespace ehs
class EHS_LIB_IO BaseTCP class EHS_LIB_IO BaseTCP
{ {
protected: protected:
AddrType addrType; IP ip;
Str_8 localAddr; Str_8 localAddr;
UInt_16 localPort; UInt_16 localPort;
Str_8 remoteHostName; Str_8 remoteHostName;
@@ -35,7 +35,7 @@ namespace ehs
/// Properly initializes the socket. /// Properly initializes the socket.
/// @param [in] type The ip version to initialize the socket with. /// @param [in] type The ip version to initialize the socket with.
BaseTCP(AddrType addrType); BaseTCP(IP ip);
BaseTCP(BaseTCP&& tcp) noexcept; BaseTCP(BaseTCP&& tcp) noexcept;
@@ -104,7 +104,7 @@ namespace ehs
/// Retrieves the sockets ip version. /// Retrieves the sockets ip version.
/// @returns The ip version. /// @returns The ip version.
AddrType GetAddressType() const; IP GetAddressType() const;
/// Retrieves the bound ip address. /// Retrieves the bound ip address.
/// @returns The ip address. /// @returns The ip address.

View File

@@ -9,9 +9,7 @@ namespace ehs
class EHS_LIB_IO BaseUDP class EHS_LIB_IO BaseUDP
{ {
protected: protected:
AddrType type; Endpoint localEndpoint;
Str_8 address;
UInt_16 port;
bool bound; bool bound;
public: public:
@@ -22,7 +20,7 @@ namespace ehs
/// Properly initializes the socket. /// Properly initializes the socket.
/// @param [in] type The ip version to initialize the socket with. /// @param [in] type The ip version to initialize the socket with.
BaseUDP(AddrType type); BaseUDP(IP version);
BaseUDP(BaseUDP&& udp) noexcept; BaseUDP(BaseUDP&& udp) noexcept;
@@ -40,13 +38,13 @@ namespace ehs
/// @param [in] address The ip address to bind to. /// @param [in] address The ip address to bind to.
/// @param [in] port The port to bind to. /// @param [in] port The port to bind to.
/// @note Used for servers. /// @note Used for servers.
virtual void Bind(AddrType type, const Str_8& address, UInt_16 port) = 0; virtual void Bind(const Endpoint &endpoint) = 0;
/// Sends data to the endpoint. /// Sends data to the endpoint.
/// @param [in] type The ip version of the endpoint. /// @param [in] type The ip version of the endpoint.
/// @param [in] address The ip address of the endpoint. /// @param [in] address The ip address of the endpoint.
/// @param [in] port The port of the endpoint is bound to. /// @param [in] port The port of the endpoint is bound to.
virtual UInt_64 Send(AddrType type, const Str_8& address, UInt_16 port, const Byte* data, UInt_64 size) = 0; virtual UInt_64 Send(const Endpoint &endpoint, const Byte *data, UInt_64 size) = 0;
/// Receives data from the endpoint. /// Receives data from the endpoint.
/// @param [out] type The ip version of the endpoint. /// @param [out] type The ip version of the endpoint.
@@ -55,7 +53,7 @@ namespace ehs
/// @param [out] data The incoming data from the endpoint. /// @param [out] data The incoming data from the endpoint.
/// @param [in] size The max size of the buffer in bytes to store the data. /// @param [in] size The max size of the buffer in bytes to store the data.
/// @returns The size of the incoming data in bytes. /// @returns The size of the incoming data in bytes.
virtual UInt_64 Receive(AddrType* type, Str_8* address, UInt_16* port, Byte* data, UInt_64 size) = 0; virtual UInt_64 Receive(Endpoint *endpoint, Byte *data, UInt_64 size) = 0;
/// Retrieves whether or not this socket is bound to an ip address and port. /// Retrieves whether or not this socket is bound to an ip address and port.
/// @returns The result. /// @returns The result.
@@ -73,17 +71,7 @@ namespace ehs
virtual bool IsIPv6Only() const = 0; virtual bool IsIPv6Only() const = 0;
/// Retrieves the bound ip version. Endpoint GetLocalEndpoint() const;
/// @returns The result.
AddrType GetLocalAddressType() const;
/// Retrieves the bound ip address.
/// @returns The bound ip address.
Str_8 GetLocalAddress() const;
/// Retrieves the bound port.
/// @returns The bound port.
UInt_16 GetLocalPort() const;
/// Retrieves whether or not this socket was initialized. /// Retrieves whether or not this socket was initialized.
/// @returns The result. /// @returns The result.

View File

@@ -10,7 +10,7 @@ namespace ehs
class EHS_LIB_IO DNS final : public BaseDNS class EHS_LIB_IO DNS final : public BaseDNS
{ {
public: public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname); static Str_8 Resolve(IP type, const Str_8 &hostname);
static Str_8 Resolve(const Str_8 &hostname); static Str_8 Resolve(const Str_8 &hostname);
}; };

View File

@@ -7,7 +7,7 @@ namespace ehs
class EHS_LIB_IO DNS final : public BaseDNS class EHS_LIB_IO DNS final : public BaseDNS
{ {
public: public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname); static Str_8 Resolve(IP type, const Str_8 &hostname);
static Str_8 Resolve(const Str_8 &hostname); static Str_8 Resolve(const Str_8 &hostname);
}; };

View File

@@ -0,0 +1,95 @@
#pragma once
#include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/Array.h"
#include "Socket.h"
#include "UDP.h"
namespace ehs
{
class NetServerCh;
class NetClientCh;
class NetEnd;
class EHC;
class EHC
{
private:
friend class NetEnc;
friend class NetChannel;
friend class NetServerCh;
friend class NetClientCh;
friend class NetEnd;
static const Version version;
UDP udp;
Byte* buffer;
UInt_32 bufferSize;
UInt_64 lastTSC;
float delta;
Array<NetEnc *> encryptions;
Array<NetServerCh *> servers;
Array<NetClientCh *> clients;
public:
~EHC();
EHC(IP version = IP::V6);
EHC(EHC &&sock) noexcept;
EHC(const EHC &sock);
EHC &operator=(EHC&& sock) noexcept;
EHC &operator=(const EHC &sock);
void Initialize();
void Release();
void Bind(const Endpoint &endpoint);
void Poll();
bool IsInitialized() const;
Endpoint GetLocalEndpoint() const;
bool IsBound() const;
static Version GetVersion();
bool AddEncryption(NetEnc *enc);
bool HasServer(UInt_64 serverId) const;
bool HasServer(const Str_8& serverName) const;
bool AddServer(NetServerCh *server);
NetServerCh *GetServer(UInt_64 serverId) const;
NetServerCh *GetServer(const Str_8& serverName) const;
bool HasClient(UInt_64 clientId) const;
bool HasClient(const Str_8& clientName) const;
bool AddClient(NetClientCh *channel);
NetClientCh *GetClient(UInt_64 clientId) const;
NetClientCh *GetClient(const Str_8& clientName) const;
private:
bool HasEncryption(UInt_64 encId) const;
bool HasEncryption(const Str_8& encName) const;
NetEnc* GetEncryption(UInt_64 encId) const;
NetEnc* GetEncryption(const Str_8& encName) const;
};
}

View File

@@ -0,0 +1,7 @@
#pragma once
#ifdef EHS_OS_WINDOWS
#include "BaseICMP.h"
#else
#include "ICMP_LNX.h"
#endif

View File

@@ -0,0 +1,33 @@
#pragma once
#include "BaseICMP.h"
namespace ehs
{
class ICMP : public BaseICMP
{
private:
Int_32 hdl;
public:
ICMP();
ICMP(IP version);
ICMP(ICMP &&icmp) noexcept;
ICMP(const ICMP &icmp);
ICMP &operator=(ICMP &&icmp) noexcept;
ICMP &operator=(const ICMP &icmp);
UInt_64 Send(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size) override;
UInt_64 Receive(Str_8 &address, ICMP_Header header, Serializer<UInt_64> &data) override;
void SetReceiveTimeout(UInt_64 timeout) override;
bool IsValid() const override;
};
}

View File

@@ -23,7 +23,7 @@ namespace ehs
SSL(); SSL();
SSL(const AddrType type); SSL(const IP type);
SSL(TCP&& tcp) noexcept; SSL(TCP&& tcp) noexcept;

View File

@@ -1,7 +1,10 @@
#pragma once #pragma once
#include "ehs/Str.h"
#ifndef EHS_IPV4_HEADER #ifndef EHS_IPV4_HEADER
#define EHS_IPV4_HEADER 60 #define EHS_IPV4_HEADER 60
#include <string>
#endif #endif
#ifndef EHS_IPV6_HEADER #ifndef EHS_IPV6_HEADER
@@ -22,10 +25,10 @@
namespace ehs namespace ehs
{ {
enum class AddrType enum class IP
{ {
IPV6, V4,
IPV4 V6
}; };
enum class ContentType enum class ContentType
@@ -41,6 +44,13 @@ namespace ehs
NONE NONE
}; };
struct Endpoint
{
IP version = IP::V6;
Str_8 address;
UInt_16 port = 0;
};
#if defined(EHS_OS_WINDOWS) #if defined(EHS_OS_WINDOWS)
typedef UInt_64 Socket; typedef UInt_64 Socket;
#define EHS_INVALID_SOCKET EHS_UINT_64_MAX #define EHS_INVALID_SOCKET EHS_UINT_64_MAX

View File

@@ -22,7 +22,7 @@ namespace ehs
/// Default members initialization. /// Default members initialization.
TCP(); TCP();
TCP(AddrType addrType); TCP(IP IP);
TCP(TCP&& tcp) noexcept; TCP(TCP&& tcp) noexcept;

View File

@@ -22,7 +22,7 @@ namespace ehs
/// Default members initialization. /// Default members initialization.
TCP(); TCP();
TCP(AddrType addrType); TCP(IP IP);
TCP(TCP&& tcp) noexcept; TCP(TCP&& tcp) noexcept;

View File

@@ -19,7 +19,7 @@ namespace ehs
UDP(); UDP();
/// Default members initialization. /// Default members initialization.
UDP(AddrType type); UDP(IP version);
UDP(UDP&& udp) noexcept; UDP(UDP&& udp) noexcept;
@@ -41,7 +41,7 @@ namespace ehs
/// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
/// @param [in] port The port to bind to. /// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called. /// @note Requires the port given to be forwarded if this is called.
void Bind(AddrType type, const Str_8& address, UInt_16 port) override; void Bind(const Endpoint &endpoint) override;
/// Sends data using a C-style byte array. /// Sends data using a C-style byte array.
/// @param [in] addr The remote Ipv4 or Ipv6 address to send to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param [in] addr The remote Ipv4 or Ipv6 address to send to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
@@ -49,7 +49,7 @@ namespace ehs
/// @param [in] data The C-style byte array to send. /// @param [in] data The C-style byte array to send.
/// @param [in] size The size of the C-style byte array. /// @param [in] size The size of the C-style byte array.
/// @note The size of data to be sent cannot exceed "UDP::maxPayloadIpv4" or "UDP::maxPayloadIpv6". /// @note The size of data to be sent cannot exceed "UDP::maxPayloadIpv4" or "UDP::maxPayloadIpv6".
UInt_64 Send(AddrType type, const Str_8& address, UInt_16 port, const Byte* data, UInt_64 size) override; UInt_64 Send(const Endpoint &endpoint, const Byte* data, UInt_64 size) override;
/// Receives data using the packet helper class. /// Receives data using the packet helper class.
/// @param [out] addr The Ipv4 or Ipv6 address of the sender. /// @param [out] addr The Ipv4 or Ipv6 address of the sender.
@@ -58,7 +58,7 @@ namespace ehs
/// @param [in] size The size of the pre-allocated C-style byte array. /// @param [in] size The size of the pre-allocated C-style byte array.
/// @returns The size of the data received. /// @returns The size of the data received.
/// @warning The provided C-style byte array must be freed when finished using. /// @warning The provided C-style byte array must be freed when finished using.
UInt_64 Receive(AddrType* type, Str_8* address, UInt_16* port, Byte* data, UInt_64 size) override; UInt_64 Receive(Endpoint *endpoint, Byte* data, UInt_64 size) override;
/// Sets whether or not receiving data blocks the next task. /// Sets whether or not receiving data blocks the next task.
/// @param [in] blocking Whether or not to block. /// @param [in] blocking Whether or not to block.

View File

@@ -19,7 +19,7 @@ namespace ehs
UDP(); UDP();
/// Default members initialization. /// Default members initialization.
UDP(const AddrType addrType); UDP(const IP IP);
UDP(UDP&& udp) noexcept; UDP(UDP&& udp) noexcept;
@@ -41,7 +41,7 @@ namespace ehs
/// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
/// @param [in] port The port to bind to. /// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called. /// @note Requires the port given to be forwarded if this is called.
void Bind(AddrType type, const Str_8& address, UInt_16 port) override; void Bind(const Endpoint &endpoint) override;
/// Sends data using a C-style byte array. /// Sends data using a C-style byte array.
/// @param [in] addr The remote Ipv4 or Ipv6 address to send to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param [in] addr The remote Ipv4 or Ipv6 address to send to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
@@ -49,7 +49,7 @@ namespace ehs
/// @param [in] data The C-style byte array to send. /// @param [in] data The C-style byte array to send.
/// @param [in] size The size of the C-style byte array. /// @param [in] size The size of the C-style byte array.
/// @note The size of data to be sent cannot exceed "UDP::maxPayloadIpv4" or "UDP::maxPayloadIpv6". /// @note The size of data to be sent cannot exceed "UDP::maxPayloadIpv4" or "UDP::maxPayloadIpv6".
UInt_64 Send(AddrType type, const Str_8& addr, UInt_16 port, const Byte* data, UInt_64 size) override; UInt_64 Send(const Endpoint &endpoint, const Byte* data, UInt_64 size) override;
/// Receives data using the packet helper class. /// Receives data using the packet helper class.
/// @param [out] addr The Ipv4 or Ipv6 address of the sender. /// @param [out] addr The Ipv4 or Ipv6 address of the sender.
@@ -58,7 +58,7 @@ namespace ehs
/// @param [in] size The size of the pre-allocated C-style byte array. /// @param [in] size The size of the pre-allocated C-style byte array.
/// @returns The size of the data received. /// @returns The size of the data received.
/// @warning The provided C-style byte array must be freed when finished using. /// @warning The provided C-style byte array must be freed when finished using.
UInt_64 Receive(AddrType* type, Str_8* addr, UInt_16* port, Byte* data, UInt_64 size) override; UInt_64 Receive(Endpoint *endpoint, Byte* data, UInt_64 size) override;
/// Sets whether or not receiving data blocks the next task. /// Sets whether or not receiving data blocks the next task.
/// @param [in] blocking Whether or not to block. /// @param [in] blocking Whether or not to block.

View File

@@ -0,0 +1,94 @@
#pragma once
#include "ehs/Str.h"
#include "ehs/Array.h"
#include "ehs/io/socket/Socket.h"
#include "NetUtils.h"
namespace ehs
{
class EHC;
class NetEnd;
class NetSys;
class NetChannel
{
protected:
static const UInt_64 internalSys;
static const UInt_64 connectOp;
static const UInt_64 connectedOp;
static const UInt_64 rejectedOp;
static const UInt_64 disconnectOp;
static const UInt_64 disconnectedOp;
static const UInt_64 statusUpdateOp;
static const UInt_64 pingOp;
static const UInt_64 pongOp;
static const UInt_64 latencyOp;
static const UInt_64 receivedOp;
private:
friend class EHC;
EHC *owner;
UInt_64 id;
Str_8 name;
Version version;
float maxTimeout;
float resendRate;
bool dropPackets;
Array<NetSys *> systems;
public:
virtual ~NetChannel();
NetChannel();
NetChannel(Str_8 name, const Version &version);
NetChannel(NetChannel &&channel) noexcept;
NetChannel(const NetChannel &channel);
NetChannel &operator=(NetChannel &&channel) noexcept;
NetChannel &operator=(const NetChannel &channel);
EHC *GetOwner() const;
UInt_64 GetId() const;
Str_8 GetName() const;
Version GetVersion() const;
void SetMaxTimeout(float seconds);
float GetMaxTimeout() const;
void SetResendRate(float seconds);
float GetResendRate() const;
void EnableDropPackets(bool enable);
bool IsDropPacketsEnabled() const;
bool AddSystem(NetSys *sys);
bool IsValid() const;
private:
virtual void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload);
virtual void Poll(const float &delta);
protected:
bool HasSystem(UInt_64 sysId) const;
bool HasSystem(const Str_8& sysName) const;
NetSys* GetSystem(UInt_64 sysId) const;
NetSys* GetSystem(const Str_8& sysName) const;
};
}

View File

@@ -0,0 +1,81 @@
#pragma once
#include "NetChannel.h"
#include "ehs/io/socket/Socket.h"
#include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/io/socket/ehc/NetFrag.h"
namespace ehs
{
class NetClientCh : public NetChannel
{
private:
friend class EHC;
Endpoint remoteEndpoint;
Char_8 token[64];
NetStatus status;
UInt_64 queueSlot;
float deltaDuration;
float deltaRate;
float lastPing;
float latency;
float timeout;
UInt_64 nextSendId;
Vector<Insurance> sent;
UInt_64 nextRecvId;
Vector<NetFrag> received;
public:
~NetClientCh();
NetClientCh();
NetClientCh(Str_8 name, const Version &version, Endpoint remoteEndpoint);
NetClientCh(NetClientCh &&client) noexcept;
NetClientCh(const NetClientCh &client);
NetClientCh &operator=(NetClientCh &&client) noexcept;
NetClientCh &operator=(const NetClientCh &client);
virtual void OnConnected(Serializer<UInt_64> data);
virtual void OnActive(Serializer<UInt_64> data);
virtual void OnQueueUpdate(Serializer<UInt_64> data);
virtual void OnDisconnected(Serializer<UInt_64> data);
virtual void OnRejected(Serializer<UInt_64> data);
virtual void OnTimeout(Serializer<UInt_64> data);
void Connect(const Endpoint &endpoint, const Serializer<UInt_64>& payload);
bool Disconnect(const Serializer<UInt_64>& payload);
void Send(bool deltaLocked, UInt_64 encId, bool ensure, UInt_64 sysId, UInt_64 opId, const Serializer<UInt_64>& payload);
void Send(bool deltaLocked, const Str_8 &encName, bool ensure, const Str_8& sysName, const Str_8& opName, const Serializer<UInt_64>& payload);
NetStatus GetStatus() const;
private:
void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload) override;
void Poll(const float &delta) override;
NetFrag FragmentData(IP version, const Header& header, const Serializer<>& data);
void Send(NetEnc *enc, const Header& header, const Serializer<>& payload);
void Pong(float delta);
void RemoveInsurance(UInt_64 msgId, UInt_64 fragment);
void AddReceived(const Header& header, const Serializer<>& payload);
};
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include "ehs/Str.h"
#include "ehs/Version.h"
namespace ehs
{
class EHC;
class NetEnc
{
private:
friend class EHC;
UInt_64 id;
Str_8 name;
Version version;
public:
virtual ~NetEnc() = default;
NetEnc();
NetEnc(Str_8 name, const Version &version);
NetEnc(NetEnc &&enc) noexcept;
NetEnc(const NetEnc &enc);
NetEnc &operator=(NetEnc &&enc) noexcept;
NetEnc &operator=(const NetEnc &enc);
UInt_64 GetId() const;
Str_8 GetName() const;
Version GetVersion() const;
virtual void Encrypt(Byte *data, UInt_64 size) const;
virtual void Decrypt(Byte *data, UInt_64 size) const;
};
}

View File

@@ -0,0 +1,122 @@
#pragma once
#include "NetUtils.h"
#include "NetFrag.h"
#include "ehs/Str.h"
#include "ehs/Vector.h"
#include "ehs/Serializer.h"
#include "ehs/io/socket/Socket.h"
namespace ehs
{
class NetServerCh;
class NetEnd
{
private:
friend class NetServerCh;
NetServerCh* owner;
UInt_64 id;
Str_8 name;
NetStatus status;
Char_8 token[64];
UInt_64 nextSendId;
Vector<Insurance> sent;
UInt_64 nextRecvId;
Vector<NetFrag> received;
Endpoint endpoint;
float deltaDuration;
float deltaRate;
float timeout;
float lastPing;
float oldLatency;
float latency;
UInt_64 queueSlot;
public:
NetEnd();
NetEnd(Str_8 id, Endpoint endpoint);
NetEnd(Endpoint endpoint);
NetEnd(NetEnd &&end) noexcept;
NetEnd(const NetEnd &end);
NetEnd &operator=(NetEnd &&end) noexcept;
NetEnd &operator=(const NetEnd &end);
UInt_64 GetId() const;
Str_8 GetName() const;
NetStatus GetStatus() const;
UInt_64 GetNextSendId() const;
/// Sends data to the remote endpoint.
/// @param [in] deltaLocked Whether or not to match the remote endpoint's delta time to prevent overloading the client. This will drop data if delta time does not match.
/// @param [in] encHashId The hash id of the encryption to use. Can be zero for none.
/// @param [in] ensure Whether or not to ensure the data was received by the remote endpoint.
/// @param [in] sys The system hash id to execute an operation from.
/// @param [in] op The operation hash id in the system to execute.
/// @param [in] payload Additional parameters and data to send to the remote endpoint.
void Send(bool deltaLocked, UInt_64 encId, bool ensure, UInt_64 sysId, UInt_64 opId, const Serializer<UInt_64>& payload);
/// Sends data to the remote endpoint.
/// @param [in] deltaLocked Whether or not to match the remote endpoint's delta time to prevent overloading the client. This will drop data if delta time does not match.
/// @param [in] encId The id of the encryption to use. Can be empty for none.
/// @param [in] ensure Whether or not to ensure the data was received by the remote endpoint.
/// @param [in] sys The system string id to execute an operation from.
/// @param [in] op The operation string id in the system to execute.
/// @param [in] payload Additional parameters and data to send to the remote endpoint.
void Send(bool deltaLocked, const Str_8 &encName, bool ensure, const Str_8& sysName, const Str_8& opName, const Serializer<UInt_64>& payload);
UInt_64 GetNextRecvId() const;
Endpoint GetEndpoint() const;
void SetDeltaRate(float newDeltaRate);
float GetDeltaRate() const;
float GetTimeout() const;
float GetLastPing() const;
void SendLatency();
float GetLatency() const;
UInt_64 GetQueueSlot() const;
private:
void Poll(float delta);
void SetStatus(NetStatus newStatus);
void RemoveInsurance(UInt_64 msgId, UInt_64 fragment);
void AddReceived(const Header& header, const Serializer<>& payload);
Vector<NetFrag>* GetReceived();
void Ping(float delta);
void SetLatency(float newLatency);
void SetQueueSlot(UInt_64 slot);
NetFrag FragmentData(const Header& header, const Serializer<>& data);
void Send(const Header& header, const Serializer<>& payload);
bool SortingNeeded() const;
void SortReceived();
};
}

View File

@@ -0,0 +1,43 @@
#pragma once
#include "NetUtils.h"
#include <ehs/Serializer.h>
namespace ehs
{
class NetFrag
{
private:
Header header;
Serializer<UInt_64>* data;
UInt_64 size;
public:
~NetFrag();
NetFrag();
NetFrag(const Header &header, const Serializer<UInt_64> &payload);
NetFrag(const Header &header, UInt_64 size);
NetFrag(NetFrag &&frags) noexcept;
NetFrag(const NetFrag &frags);
NetFrag &operator=(NetFrag &&frags) noexcept;
NetFrag &operator=(const NetFrag &frags);
operator Serializer<UInt_64> *() const;
Header GetHeader() const;
UInt_64 Size() const;
bool IsComplete() const;
Packet Combine() const;
};
}

View File

@@ -0,0 +1,42 @@
#pragma once
#include "ehs/Str.h"
#include "ehs/Serializer.h"
namespace ehs
{
class NetChannel;
class NetSys;
class NetEnd;
class NetOp
{
private:
friend class NetSys;
UInt_64 id;
Str_8 name;
public:
virtual ~NetOp() = default;
NetOp();
NetOp(Str_8 name);
NetOp(NetOp &&op) noexcept;
NetOp(const NetOp &op);
NetOp &operator=(NetOp &&op) noexcept;
NetOp &operator=(const NetOp &op);
UInt_64 GetId() const;
Str_8 GetName() const;
private:
virtual void Execute(NetChannel *channel, NetEnd *issuer, NetSys *sys, Serializer<UInt_64> &payload);
};
}

View File

@@ -0,0 +1,105 @@
#pragma once
#include "NetChannel.h"
namespace ehs
{
class NetEnd;
class NetServerCh : public NetChannel
{
private:
friend class EHC;
Vector<NetEnd *> endpoints;
UInt_64 maxEndpoints;
public:
~NetServerCh() override;
NetServerCh();
NetServerCh(Str_8 name, const Version &version, UInt_64 maxEndpoints);
NetServerCh(NetServerCh &&server) noexcept;
NetServerCh(const NetServerCh &server);
NetServerCh &operator=(NetServerCh &&server) noexcept;
NetServerCh &operator=(const NetServerCh &server);
virtual bool OnEndpointConnect(NetEnd *endpoint, Serializer<UInt_64> payload);
virtual Serializer<UInt_64> OnEndpointAccepted(NetEnd *endpoint);
virtual void OnEndpointDisconnect(NetEnd *endpoint, Serializer<UInt_64> payload);
virtual void OnEndpointTimeout(NetEnd *endpoint);
virtual void OnEndpointActive(NetEnd *endpoint);
virtual Serializer<UInt_64> OnShutdown();
void Broadcast(NetStatus endStatus, bool deltaLocked, UInt_64 encHashId,
bool ensure, UInt_64 sysHashId, UInt_64 opHashId,
const Serializer<UInt_64> &payload);
void Broadcast(NetStatus endStatus, bool deltaLocked, const Str_8 &encId,
bool ensure, const Str_8 &sysId, const Str_8 &opId,
const Serializer<UInt_64> &payload);
bool HasEndpoint(NetStatus endStatus, const Char_8 token[64]) const;
bool HasEndpoint(NetStatus endStatus, UInt_64 hashId) const;
bool HasEndpoint(NetStatus endStatus, const Str_8 &id) const;
bool HasEndpoint(const Char_8 token[64]) const;
bool HasEndpoint(UInt_64 hashId) const;
bool HasEndpoint(const Str_8 &id) const;
bool HasEndpoint(const Endpoint &endpoint) const;
NetEnd *GetEndpoint(NetStatus endStatus, const Char_8 token[64]) const;
NetEnd *GetEndpoint(NetStatus endStatus, UInt_64 hashId) const;
NetEnd *GetEndpoint(NetStatus endStatus, const Str_8 &id) const;
NetEnd *GetEndpoint(const Char_8 token[64]) const;
NetEnd *GetEndpoint(UInt_64 hashId) const;
NetEnd *GetEndpoint(const Str_8 &id) const;
NetEnd *GetEndpoint(const Endpoint &endpoint) const;
Array<NetEnd *> GetEndpoints(NetStatus endStatus);
UInt_64 GetEndpointsCount(NetStatus endStatus);
UInt_64 GetMaxEndpoints() const;
private:
void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload) override;
void GenerateToken(Char_8 in[64]);
void UpdateQueue(UInt_64 active);
void UpdateQueue();
bool RemoveEndpoint(const Char_8 token[64]);
bool RemoveEndpoint(const Endpoint &endpoint);
bool RemoveEndpoint(const NetEnd* end);
void Poll(const float &delta) override;
void Shutdown();
};
}

View File

@@ -0,0 +1,50 @@
#pragma once
#include "ehs/Str.h"
#include "ehs/Array.h"
#include "ehs/Serializer.h"
namespace ehs
{
class NetChannel;
class NetEnd;
class NetOp;
class NetSys
{
private:
friend class NetChannel;
friend class NetServerCh;
friend class NetClientCh;
UInt_64 id;
Str_8 name;
Array<NetOp*> ops;
public:
virtual ~NetSys();
NetSys();
NetSys(Str_8 name);
NetSys(NetSys &&sys) noexcept;
NetSys(const NetSys &sys);
NetSys &operator=(NetSys &&sys) noexcept;
NetSys &operator=(const NetSys &sys);
UInt_64 GetId() const;
Str_8 GetName() const;
bool HasOperation(UInt_64 id) const;
bool AddOperation(NetOp *op);
private:
void Execute(NetChannel *channel, NetEnd *issuer, UInt_64 opId, Serializer<UInt_64> &payload);
};
}

View File

@@ -0,0 +1,62 @@
#pragma once
#include "ehs/Serializer.h"
namespace ehs
{
enum class NetStatus : UInt_8
{
DISCONNECTED,
ACTIVE,
PENDING,
QUEUED
};
enum class NetChannelType : UInt_8
{
SERVER,
CLIENT
};
struct Header
{
Version version = {};
UInt_64 encId = 0;
Version encVer = {};
UInt_64 channelId = 0;
NetChannelType channelType = NetChannelType::SERVER;
Version channelVer = {};
UInt_64 id = 0;
UInt_64 fragmentCount = 0;
UInt_64 fragment = 0;
bool ensure = false;
Char_8 token[64] = {};
UInt_64 systemId = 0;
UInt_64 opId = 0;
};
void WriteHeader(const Header &header, Serializer<UInt_64> &data);
Header ReadHeader(Serializer<UInt_64> &data);
struct Packet
{
Header header;
Serializer<UInt_64> payload;
};
struct Insurance
{
Header header;
Serializer<UInt_64> payload;
float lastResend;
};
}
#ifndef EHC_IPV4_PAYLOAD
#define EHC_IPV4_PAYLOAD (EHS_IPV4_UDP_PAYLOAD - (UInt_16)sizeof(Header))
#endif
#ifndef EHC_IPV6_PAYLOAD
#define EHC_IPV6_PAYLOAD (EHS_IPV6_UDP_PAYLOAD - (UInt_16)sizeof(Header))
#endif

View File

@@ -12,57 +12,57 @@
namespace ehs namespace ehs
{ {
class EHS_LIB_IO Json class EHS_LIB_IO Json final
{ {
private: private:
JsonBase* value; JsonBase *value;
public: public:
virtual ~Json(); ~Json();
Json(); Json();
Json(const JsonBase& value); Json(const JsonBase &value);
Json(const JsonObj& value); Json(const JsonObj &value);
Json(const JsonArray& value); Json(const JsonArray &value);
Json(const JsonBool& value); Json(const JsonBool &value);
Json(const JsonNum& value); Json(const JsonNum &value);
Json(const JsonStr& value); Json(const JsonStr &value);
Json(const char* data, const UInt_64 size, const UInt_64 extra); Json(const char *data, UInt_64 size, UInt_64 extra);
Json(const Str_8& data, const UInt_64 extra); Json(const Str_8 &data, UInt_64 extra);
Json(Json&& json) noexcept; Json(Json &&json) noexcept;
Json(const Json &json); Json(const Json &json);
Json& operator=(Json&& json) noexcept; Json &operator=(Json &&json) noexcept;
Json& operator=(const Json& json); Json &operator=(const Json &json);
JsonBase* GetValue(); JsonBase *GetValue();
JsonBase* RetrieveValue(const Str_8& access); JsonBase *RetrieveValue(const Str_8 &access);
Str_8 ToStr(const bool compact) const; Str_8 ToStr(bool compact) const;
private: private:
static Vector<Str_8> ParseAccess(const Str_8& access); static Vector<Str_8> ParseAccess(const Str_8 &access);
void ParseValue(JsonVar* var, const Char_8** begin, const Char_8* end, const UInt_64 extra); void ParseValue(JsonVar *var, const Char_8 **begin, const Char_8 *end, UInt_64 extra);
JsonVar ParseVar(const Char_8** begin, const Char_8* end, const UInt_64 extra); JsonVar ParseVar(const Char_8 **begin, const Char_8 *end, UInt_64 extra);
void ParseObject(JsonObj* obj, const Char_8** begin, const Char_8* end, const UInt_64 extra); void ParseObject(JsonObj *obj, const Char_8 **begin, const Char_8 *end, UInt_64 extra);
void ParseArray(JsonArray* arr, const Char_8** begin, const Char_8* end, const UInt_64 extra); void ParseArray(JsonArray *arr, const Char_8 **begin, const Char_8 *end, UInt_64 extra);
void Parse(const Str_8& data, const UInt_64 extra); void Parse(const Str_8 &data, UInt_64 extra);
}; };
} }

View File

@@ -20,13 +20,13 @@ namespace ehs
JsonBase** data; JsonBase** data;
public: public:
virtual ~JsonArray(); ~JsonArray() override;
JsonArray(); JsonArray();
JsonArray(const UInt_64 extra); JsonArray(UInt_64 extra);
JsonArray(const UInt_64 size, const UInt_64 extra); JsonArray(UInt_64 size, UInt_64 extra);
JsonArray(JsonArray&& ja) noexcept; JsonArray(JsonArray&& ja) noexcept;
@@ -46,9 +46,9 @@ namespace ehs
UInt_64 Size() const; UInt_64 Size() const;
void Insert(const UInt_64 index, const JsonBase* const value); void Insert(UInt_64 index, const JsonBase* value);
void Push(const JsonBase* const value); void Push(const JsonBase* value);
void Push(const JsonBase& value); void Push(const JsonBase& value);
@@ -58,20 +58,20 @@ namespace ehs
void Push(const JsonBool& value); void Push(const JsonBool& value);
void Push(const bool value); void Push(bool value);
void Push(const JsonNum& value); void Push(const JsonNum& value);
void Push(const float value); void Push(float value);
void Push(const JsonStr& value); void Push(const JsonStr& value);
void Push(const Char_8* value, const UInt_64 size = 0); void Push(const Char_8* value, UInt_64 size = 0);
void Push(const Str_8& value); void Push(const Str_8& value);
void Pop(); void Pop();
Str_8 ToStr(const UInt_64 level, const bool compact) const; Str_8 ToStr(UInt_64 level, bool compact) const override;
}; };
} }

View File

@@ -21,14 +21,16 @@ namespace ehs
JsonType type; JsonType type;
public: public:
virtual ~JsonBase() = default;
JsonBase(); JsonBase();
JsonBase(const JsonType type); JsonBase(JsonType type);
JsonBase(const JsonBase& base) = default; JsonBase(const JsonBase& base) = default;
JsonType GetType() const; JsonType GetType() const;
virtual Str_8 ToStr(const UInt_64 level, const bool compact) const; virtual Str_8 ToStr(UInt_64 level, bool compact) const;
}; };
} }

View File

@@ -7,14 +7,14 @@
namespace ehs namespace ehs
{ {
class EHS_LIB_IO JsonBool : public JsonBase class EHS_LIB_IO JsonBool final : public JsonBase
{ {
public: public:
bool value; bool value;
JsonBool(); JsonBool();
JsonBool(const bool value); JsonBool(bool value);
JsonBool(const JsonBool& jb) = default; JsonBool(const JsonBool& jb) = default;
@@ -22,6 +22,6 @@ namespace ehs
operator bool&(); operator bool&();
Str_8 ToStr(const UInt_64 level, const bool compact) const; Str_8 ToStr(UInt_64 level, bool compact) const override;
}; };
} }

View File

@@ -7,39 +7,37 @@
namespace ehs namespace ehs
{ {
class EHS_LIB_IO JsonNum : public JsonBase class EHS_LIB_IO JsonNum final : public JsonBase
{ {
public: public:
float value; float value;
JsonNum(); JsonNum();
JsonNum(const SInt_64 value); JsonNum(SInt_64 value);
JsonNum(const UInt_64 value); JsonNum(UInt_64 value);
JsonNum(const SInt_32 value); JsonNum(SInt_32 value);
JsonNum(const UInt_32 value); JsonNum(UInt_32 value);
JsonNum(const SInt_16 value); JsonNum(SInt_16 value);
JsonNum(const UInt_16 value); JsonNum(UInt_16 value);
JsonNum(const SInt_8 value); JsonNum(SInt_8 value);
JsonNum(const UInt_8 value); JsonNum(UInt_8 value);
JsonNum(const double value); JsonNum(double value);
JsonNum(const float value); JsonNum(float value);
JsonNum(const JsonNum& jn) = default; JsonNum(const JsonNum& jn) = default;
operator float() const; operator float() const;
operator float&(); Str_8 ToStr(UInt_64 level, bool compact) const override;
Str_8 ToStr(const UInt_64 level, const bool compact) const;
}; };
} }

View File

@@ -9,7 +9,7 @@ namespace ehs
{ {
class JsonVar; class JsonVar;
class EHS_LIB_IO JsonObj : public JsonBase class EHS_LIB_IO JsonObj final : public JsonBase
{ {
protected: protected:
UInt_64 size; UInt_64 size;
@@ -18,25 +18,23 @@ namespace ehs
JsonVar* vars; JsonVar* vars;
public: public:
virtual ~JsonObj(); ~JsonObj() override;
JsonObj(); JsonObj();
JsonObj(const UInt_64 size, const UInt_64 extra); JsonObj(UInt_64 size, UInt_64 extra);
JsonObj(const UInt_64 extra); JsonObj(UInt_64 extra);
JsonObj(JsonObj&& value) noexcept; JsonObj(JsonObj &&value) noexcept;
JsonObj(const JsonObj& value); JsonObj(const JsonObj &value);
JsonObj& operator=(JsonObj&& value) noexcept; JsonObj& operator=(JsonObj &&value) noexcept;
JsonObj& operator=(const JsonObj& value); JsonObj& operator=(const JsonObj &value);
operator const JsonVar*() const; operator JsonVar *() const;
operator JsonVar*();
UInt_64 Size() const; UInt_64 Size() const;
@@ -44,20 +42,20 @@ namespace ehs
UInt_64 RawSize() const; UInt_64 RawSize() const;
bool HasVar(const UInt_64 hashId) const; bool HasVar(UInt_64 hashId) const;
bool HasVar(const Str_8& identifier) const; bool HasVar(const Str_8 &identifier) const;
bool AddVar(const JsonVar& var); bool AddVar(const JsonVar &var);
const JsonVar* GetVar(const UInt_64 hashId) const; const JsonVar *GetVar(UInt_64 hashId) const;
const JsonVar* GetVar(const Str_8& identifier) const; const JsonVar *GetVar(const Str_8& identifier) const;
JsonVar* GetVar(const UInt_64 hashId); JsonVar *GetVar(UInt_64 hashId);
JsonVar* GetVar(const Str_8& identifier); JsonVar *GetVar(const Str_8& identifier);
Str_8 ToStr(const UInt_64 level, const bool compact) const; Str_8 ToStr(UInt_64 level, bool compact) const override;
}; };
} }

View File

@@ -7,7 +7,7 @@
namespace ehs namespace ehs
{ {
class EHS_LIB_IO JsonStr : public JsonBase class EHS_LIB_IO JsonStr final : public JsonBase
{ {
public: public:
Str_8 value; Str_8 value;
@@ -16,18 +16,18 @@ namespace ehs
JsonStr(Str_8 value); JsonStr(Str_8 value);
JsonStr(const Char_8* value, const UInt_64 size = 0); JsonStr(const Char_8 *value, UInt_64 size = 0);
JsonStr(JsonStr&& js) noexcept; JsonStr(JsonStr &&js) noexcept;
JsonStr(const JsonStr& js) = default; JsonStr(const JsonStr &js) = default;
JsonStr& operator=(JsonStr&& js) noexcept; JsonStr& operator=(JsonStr &&js) noexcept;
operator Str_8() const; operator Str_8() const;
operator Str_8&(); operator Str_8 &();
Str_8 ToStr(const UInt_64 level, const bool compact) const; Str_8 ToStr(UInt_64 level, bool compact) const override;
}; };
} }

View File

@@ -12,7 +12,7 @@ namespace ehs
class JsonNum; class JsonNum;
class JsonStr; class JsonStr;
class EHS_LIB_IO JsonVar class EHS_LIB_IO JsonVar final
{ {
private: private:
UInt_64 hashId; UInt_64 hashId;
@@ -20,49 +20,49 @@ namespace ehs
JsonBase* value; JsonBase* value;
public: public:
virtual ~JsonVar(); ~JsonVar();
JsonVar(); JsonVar();
JsonVar(Str_8 id); JsonVar(Str_8 id);
JsonVar(Str_8 id, const JsonBase* const value); JsonVar(Str_8 id, const JsonBase *value);
JsonVar(Str_8 id, const JsonBase& value); JsonVar(Str_8 id, const JsonBase &value);
JsonVar(Str_8 id, const JsonObj& value); JsonVar(Str_8 id, const JsonObj &value);
JsonVar(Str_8 id, const JsonArray& value); JsonVar(Str_8 id, const JsonArray &value);
JsonVar(Str_8 id, const JsonBool& value); JsonVar(Str_8 id, const JsonBool &value);
JsonVar(Str_8 id, const bool boolean); JsonVar(Str_8 id, bool boolean);
JsonVar(Str_8 id, const JsonNum& value); JsonVar(Str_8 id, const JsonNum &value);
JsonVar(Str_8 id, const SInt_64 num); JsonVar(Str_8 id, SInt_64 num);
JsonVar(Str_8 id, const UInt_64 num); JsonVar(Str_8 id, UInt_64 num);
JsonVar(Str_8 id, const SInt_32 num); JsonVar(Str_8 id, SInt_32 num);
JsonVar(Str_8 id, const UInt_32 num); JsonVar(Str_8 id, UInt_32 num);
JsonVar(Str_8 id, const SInt_16 num); JsonVar(Str_8 id, SInt_16 num);
JsonVar(Str_8 id, const UInt_16 num); JsonVar(Str_8 id, UInt_16 num);
JsonVar(Str_8 id, const SInt_8 num); JsonVar(Str_8 id, SInt_8 num);
JsonVar(Str_8 id, const UInt_8 num); JsonVar(Str_8 id, UInt_8 num);
JsonVar(Str_8 id, const double num); JsonVar(Str_8 id, double num);
JsonVar(Str_8 id, const float num); JsonVar(Str_8 id, float num);
JsonVar(Str_8 id, const JsonStr& value); JsonVar(Str_8 id, const JsonStr &value);
JsonVar(Str_8 id, const Char_8* str, const UInt_64 size = 0); JsonVar(Str_8 id, const Char_8 *str, UInt_64 size = 0);
JsonVar(Str_8 id, Str_8 str); JsonVar(Str_8 id, Str_8 str);
@@ -78,25 +78,25 @@ namespace ehs
Str_8 GetId() const; Str_8 GetId() const;
void SetValue(const JsonBase* const newValue); void SetValue(const JsonBase *newValue);
void SetValue(const JsonBase& newValue); void SetValue(const JsonBase &newValue);
void SetValue(const JsonObj& newValue); void SetValue(const JsonObj &newValue);
void SetValue(const JsonArray& newValue); void SetValue(const JsonArray &newValue);
void SetValue(const JsonBool& newValue); void SetValue(const JsonBool &newValue);
void SetValue(const bool newValue); void SetValue(bool newValue);
void SetValue(const JsonNum& newValue); void SetValue(const JsonNum& newValue);
void SetValue(const float newValue); void SetValue(float newValue);
void SetValue(const JsonStr& newValue); void SetValue(const JsonStr& newValue);
void SetValue(const Char_8* newValue, const UInt_64 size = 0); void SetValue(const Char_8* newValue, UInt_64 size = 0);
void SetValue(const Str_8& newValue); void SetValue(const Str_8& newValue);
@@ -104,6 +104,6 @@ namespace ehs
JsonBase* GetValue(); JsonBase* GetValue();
Str_8 ToStr(const UInt_64 level, const bool compact) const; Str_8 ToStr(UInt_64 level, bool compact) const;
}; };
} }

View File

@@ -9,5 +9,9 @@ namespace ehs
{ {
public: public:
static void OpenURI(const Str_8& uri); static void OpenURI(const Str_8& uri);
static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters);
static Str_8 GetDirDialog(const Str_8 &dir);
}; };
} }

View File

@@ -210,6 +210,8 @@ namespace ehs
/// @param[out] input A 48 byte character array representing the brand. /// @param[out] input A 48 byte character array representing the brand.
static void GetBrand(Char_8* input); static void GetBrand(Char_8* input);
static UInt_8 GetCacheLineSize();
//static Str_8 ToStr(); //static Str_8 ToStr();
private: private:

View File

@@ -9,5 +9,9 @@ namespace ehs
{ {
public: public:
static void OpenURI(const Str_8& uri); static void OpenURI(const Str_8& uri);
static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters);
static Str_8 GetDirDialog(const Str_8 &dir);
}; };
} }

View File

@@ -383,7 +383,7 @@ namespace ehs
rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC; rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
rid[0].usUsage = HID_USAGE_GENERIC_MOUSE; rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
rid[0].dwFlags = RIDEV_INPUTSINK; rid[0].dwFlags = 0;
rid[0].hwndTarget = hdl; rid[0].hwndTarget = hdl;
rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC; rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
@@ -703,11 +703,118 @@ namespace ehs
Serializer<UInt_64> Window::GetClipboard() Serializer<UInt_64> Window::GetClipboard()
{ {
return {}; if (!OpenClipboard(hdl))
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to open Clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return {};
}
HANDLE hData = GetClipboardData(CF_TEXT);
if (!hData)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to get clipboard handle with error #" + Str_8::FromNum(GetLastError()) + ".");
if (!CloseClipboard())
EHS_LOG_INT(LogType::ERR, 4, "Failed to close clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return {};
}
Char_8* text = (Char_8 *)GlobalLock(hData);
if (!text)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to get clipboard data with error #" + Str_8::FromNum(GetLastError()) + ".");
return {};
}
Serializer<UInt_64> data(Endianness::LE, (Byte *)text, Str_8::Len(text));
if (!GlobalUnlock(hData))
{
EHS_LOG_INT(LogType::ERR, 3, "Failed to free clipboard data with error #" + Str_8::FromNum(GetLastError()) + ".");
return data;
}
if (!CloseClipboard())
{
EHS_LOG_INT(LogType::ERR, 4, "Failed to close clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return data;
}
EHS_LOG_SUCCESS();
return data;
} }
void Window::SetClipboard(Serializer<UInt_64> data) void Window::SetClipboard(Serializer<UInt_64> data)
{ {
if (!OpenClipboard(hdl))
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to open Clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
if (!EmptyClipboard())
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to empty clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
if (!CloseClipboard())
EHS_LOG_INT(LogType::ERR, 6, "Failed to close clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE, data.Size());
if (!hGlob)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to allocate clipboard data with error #" + Str_8::FromNum(GetLastError()) + ".");
if (!CloseClipboard())
EHS_LOG_INT(LogType::ERR, 6, "Failed to close clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
Byte* result = (Byte *)GlobalLock(hGlob);
if (!result)
{
EHS_LOG_INT(LogType::ERR, 3, "Failed to lock data with error #" + Str_8::FromNum(GetLastError()) + ".");
GlobalFree(hGlob);
if (!CloseClipboard())
EHS_LOG_INT(LogType::ERR, 6, "Failed to close clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
Util::Copy(result, &data[0], data.Size());
GlobalUnlock(hGlob);
HANDLE hData = SetClipboardData(CF_TEXT, hGlob);
if (!hData)
{
EHS_LOG_INT(LogType::ERR, 5, "Failed to get clipboard handle with error #" + Str_8::FromNum(GetLastError()) + ".");
GlobalFree(hGlob);
if (!CloseClipboard())
EHS_LOG_INT(LogType::ERR, 6, "Failed to close clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
if (!CloseClipboard())
{
EHS_LOG_INT(LogType::ERR, 6, "Failed to close clipboard with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
EHS_LOG_SUCCESS();
} }
void Window::SetCursorImg(CursorImg img) void Window::SetCursorImg(CursorImg img)

View File

@@ -290,6 +290,11 @@ namespace ehs
return channels * frames; return channels * frames;
} }
UInt_8 Audio::GetFrameSize() const
{
return byteDepth * channels;
}
UInt_64 Audio::GetSize() const UInt_64 Audio::GetSize() const
{ {
return byteDepth * channels * frames; return byteDepth * channels * frames;
@@ -300,6 +305,11 @@ namespace ehs
return length; return length;
} }
Byte* Audio::GetFrame(UInt_64 frameIndex) const
{
return &data[frameIndex * GetFrameSize()];
}
Array<Byte> Audio::FrameAsMono(const UInt_64 frameIndex) const Array<Byte> Audio::FrameAsMono(const UInt_64 frameIndex) const
{ {
Array<Byte> result(byteDepth); Array<Byte> result(byteDepth);
@@ -1743,161 +1753,161 @@ namespace ehs
void Audio::SInt_16_to_SInt_8(Byte* newData, Byte* newPeak) const void Audio::SInt_16_to_SInt_8(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
newData[a] = (Byte)((float)((SInt_16*)data)[a] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_8_MAX); newData[a] = (Byte)((double)((SInt_16*)data)[a] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_8_MAX);
*(SInt_8*)newPeak = (SInt_8)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_8_MAX); *(SInt_8*)newPeak = (SInt_8)((double)*(SInt_16*)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_8_MAX);
} }
void Audio::Float_to_SInt_8(Byte* newData, Byte* newPeak) const void Audio::Float_to_SInt_8(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_8*)newData)[a] = (SInt_8)(((float*)data)[a] * (float)EHS_SINT_8_MAX); ((SInt_8*)newData)[a] = (SInt_8)((double)((float*)data)[a] * (double)EHS_SINT_8_MAX);
*(SInt_8*)newPeak = (SInt_8)(*(float*)peak * (float)EHS_SINT_8_MAX); *(SInt_8*)newPeak = (SInt_8)((double)(*(float*)peak) * (double)EHS_SINT_8_MAX);
} }
void Audio::SInt_32_to_SInt_8(Byte* newData, Byte* newPeak) const void Audio::SInt_32_to_SInt_8(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
newData[a] = (Byte)((float)((SInt_32*)data)[a] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_8_MAX); newData[a] = (Byte)((double)((SInt_32*)data)[a] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_8_MAX);
*(SInt_8*)newPeak = (SInt_8)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_8_MAX); *(SInt_8*)newPeak = (SInt_8)((double)*(SInt_32*)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_8_MAX);
} }
void Audio::SInt_64_to_SInt_8(Byte* newData, Byte* newPeak) const void Audio::SInt_64_to_SInt_8(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
newData[a] = (Byte)((float)((SInt_64*)data)[a] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_8_MAX); newData[a] = (Byte)((double)((SInt_64*)data)[a] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_8_MAX);
*(SInt_8*)newPeak = (SInt_8)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_8_MAX); *(SInt_8*)newPeak = (SInt_8)((double)*(SInt_64*)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_8_MAX);
} }
void Audio::SInt_8_to_SInt_16(Byte* newData, Byte* newPeak) const void Audio::SInt_8_to_SInt_16(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_16*)newData)[a] = (SInt_16)((float)(SInt_8)data[a] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_16_MAX); ((SInt_16*)newData)[a] = (SInt_16)((double)(SInt_8)data[a] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_16_MAX);
*(SInt_16*)newPeak = (SInt_16)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_16_MAX); *(SInt_16*)newPeak = (SInt_16)((double)*(SInt_8*)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_16_MAX);
} }
void Audio::Float_to_SInt_16(Byte* newData, Byte* newPeak) const void Audio::Float_to_SInt_16(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_16*)newData)[a] = (SInt_16)(((float*)data)[a] * (float)EHS_SINT_16_MAX); ((SInt_16*)newData)[a] = (SInt_16)((double)((float*)data)[a] * (double)EHS_SINT_16_MAX);
*(SInt_16*)newPeak = (SInt_16)(*(float*)peak * (float)EHS_SINT_16_MAX); *(SInt_16*)newPeak = (SInt_16)((double)(*(float*)peak) * (double)EHS_SINT_16_MAX);
} }
void Audio::SInt_32_to_SInt_16(Byte* newData, Byte* newPeak) const void Audio::SInt_32_to_SInt_16(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_16*)newData)[a] = (SInt_16)((float)((SInt_32*)data)[a] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_16_MAX); ((SInt_16*)newData)[a] = (SInt_16)((double)((SInt_32*)data)[a] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_16_MAX);
*(SInt_16*)newPeak = (SInt_16)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_16_MAX); *(SInt_16*)newPeak = (SInt_16)((double)*(SInt_32*)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_16_MAX);
} }
void Audio::SInt_64_to_SInt_16(Byte* newData, Byte* newPeak) const void Audio::SInt_64_to_SInt_16(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_16*)newData)[a] = (SInt_16)((float)((SInt_64*)data)[a] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_16_MAX); ((SInt_16*)newData)[a] = (SInt_16)((double)((SInt_64*)data)[a] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_16_MAX);
*(SInt_16*)newPeak = (SInt_16)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_16_MAX); *(SInt_16*)newPeak = (SInt_16)((double)*(SInt_64*)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_16_MAX);
} }
void Audio::SInt_8_to_Float(Byte* newData, Byte* newPeak) const void Audio::SInt_8_to_Float(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((float*)newData)[a] = (float)(((SInt_8*)data)[a]) / (float)EHS_SINT_8_MAX; ((float*)newData)[a] = (float)((double)(((SInt_8*)data)[a]) / (double)EHS_SINT_8_MAX);
*(float*)newPeak = (float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX; *(float*)newPeak = (float)((double)*(SInt_8*)peak / (double)EHS_SINT_8_MAX);
} }
void Audio::SInt_16_to_Float(Byte* newData, Byte* newPeak) const void Audio::SInt_16_to_Float(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((float*)newData)[a] = (float)(((SInt_16*)data)[a]) / (float)EHS_SINT_16_MAX; ((float*)newData)[a] = (float)((double)(((SInt_16*)data)[a]) / (double)EHS_SINT_16_MAX);
*(float*)newPeak = (float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX; *(float*)newPeak = (float)((double)*(SInt_16*)peak / (double)EHS_SINT_16_MAX);
} }
void Audio::SInt_32_to_Float(Byte* newData, Byte* newPeak) const void Audio::SInt_32_to_Float(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((float*)newData)[a] = (float)(((SInt_32*)data)[a]) / (float)EHS_SINT_32_MAX; ((float*)newData)[a] = (float)((double)(((SInt_32*)data)[a]) / (double)EHS_SINT_32_MAX);
*(float*)newPeak = (float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX; *(float*)newPeak = (float)((double)*(SInt_32*)peak / (double)EHS_SINT_32_MAX);
} }
void Audio::SInt_64_to_Float(Byte* newData, Byte* newPeak) const void Audio::SInt_64_to_Float(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((float*)newData)[a] = (float)(((SInt_64*)data)[a]) / (float)EHS_SINT_64_MAX; ((float*)newData)[a] = (float)((double)(((SInt_64*)data)[a]) / (double)EHS_SINT_64_MAX);
*(float*)newPeak = (float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX; *(float*)newPeak = (float)((double)*(SInt_64*)peak / (double)EHS_SINT_64_MAX);
} }
void Audio::SInt_8_to_SInt_32(Byte* newData, Byte* newPeak) const void Audio::SInt_8_to_SInt_32(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_32*)newData)[a] = (SInt_32)((float)(SInt_8)data[a] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_32_MAX); ((SInt_32*)newData)[a] = (SInt_32)((double)(SInt_8)data[a] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_32_MAX);
*(SInt_32*)newPeak = (SInt_32)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_32_MAX); *(SInt_32*)newPeak = (SInt_32)((double)*(SInt_8*)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_32_MAX);
} }
void Audio::SInt_16_to_SInt_32(Byte* newData, Byte* newPeak) const void Audio::SInt_16_to_SInt_32(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_32*)newData)[a] = (SInt_32)((float)((SInt_16*)data)[a] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_32_MAX); ((SInt_32*)newData)[a] = (SInt_32)((double)((SInt_16*)data)[a] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_32_MAX);
*(SInt_32*)newPeak = (SInt_32)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_32_MAX); *(SInt_32*)newPeak = (SInt_32)((double)*(SInt_16*)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_32_MAX);
} }
void Audio::Float_to_SInt_32(Byte* newData, Byte* newPeak) const void Audio::Float_to_SInt_32(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_32*)newData)[a] = (SInt_32)(((float*)data)[a] * (float)EHS_SINT_32_MAX); ((SInt_32*)newData)[a] = (SInt_32)(((double*)data)[a] * (double)EHS_SINT_32_MAX);
*(SInt_32*)newPeak = (SInt_32)(*(float*)peak * (float)EHS_SINT_32_MAX); *(SInt_32*)newPeak = (SInt_32)(*(double*)peak * (double)EHS_SINT_32_MAX);
} }
void Audio::SInt_64_to_SInt_32(Byte* newData, Byte* newPeak) const void Audio::SInt_64_to_SInt_32(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_32*)newData)[a] = (SInt_32)((float)((SInt_64*)data)[a] / (float)EHS_SINT_64_MAX * (float)EHS_SINT_32_MAX); ((SInt_32*)newData)[a] = (SInt_32)((double)((SInt_64*)data)[a] / (double)EHS_SINT_64_MAX * (double)EHS_SINT_32_MAX);
*(SInt_32*)newPeak = (SInt_32)((float)*(SInt_64*)peak / (float)EHS_SINT_64_MAX * (float)EHS_SINT_32_MAX); *(SInt_32*)newPeak = (SInt_32)((double)*(SInt_64*)peak / (double)EHS_SINT_64_MAX * (double)EHS_SINT_32_MAX);
} }
void Audio::SInt_8_to_SInt_64(Byte* newData, Byte* newPeak) const void Audio::SInt_8_to_SInt_64(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_64*)newData)[a] = (SInt_64)((float)(SInt_8)data[a] / (float)EHS_SINT_8_MAX * (float)EHS_SINT_64_MAX); ((SInt_64*)newData)[a] = (SInt_64)((double)(SInt_8)data[a] / (double)EHS_SINT_8_MAX * (double)EHS_SINT_64_MAX);
*(SInt_64*)newPeak = (SInt_64)((float)*(SInt_8*)peak / (float)EHS_SINT_8_MAX * (float)EHS_SINT_64_MAX); *(SInt_64*)newPeak = (SInt_64)((double)*(SInt_8*)peak / (double)EHS_SINT_8_MAX * (double)EHS_SINT_64_MAX);
} }
void Audio::SInt_16_to_SInt_64(Byte* newData, Byte* newPeak) const void Audio::SInt_16_to_SInt_64(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_64*)newData)[a] = (SInt_64)((float)((SInt_16*)data)[a] / (float)EHS_SINT_16_MAX * (float)EHS_SINT_64_MAX); ((SInt_64*)newData)[a] = (SInt_64)((double)((SInt_16*)data)[a] / (double)EHS_SINT_16_MAX * (double)EHS_SINT_64_MAX);
*(SInt_64*)newPeak = (SInt_64)((float)*(SInt_16*)peak / (float)EHS_SINT_16_MAX * (float)EHS_SINT_64_MAX); *(SInt_64*)newPeak = (SInt_64)((double)*(SInt_16*)peak / (double)EHS_SINT_16_MAX * (double)EHS_SINT_64_MAX);
} }
void Audio::Float_to_SInt_64(Byte* newData, Byte* newPeak) const void Audio::Float_to_SInt_64(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_64*)newData)[a] = (SInt_64)(((float*)data)[a] * (float)EHS_SINT_64_MAX); ((SInt_64*)newData)[a] = (SInt_64)(((double*)data)[a] * (double)EHS_SINT_64_MAX);
*(SInt_64*)newPeak = (SInt_64)(*(float*)peak * (float)EHS_SINT_64_MAX); *(SInt_64*)newPeak = (SInt_64)(*(double*)peak * (double)EHS_SINT_64_MAX);
} }
void Audio::SInt_32_to_SInt_64(Byte* newData, Byte* newPeak) const void Audio::SInt_32_to_SInt_64(Byte* newData, Byte* newPeak) const
{ {
for (UInt_64 a = 0; a < GetSampleCount(); ++a) for (UInt_64 a = 0; a < GetSampleCount(); ++a)
((SInt_64*)newData)[a] = (SInt_64)((float)((SInt_32*)data)[a] / (float)EHS_SINT_32_MAX * (float)EHS_SINT_64_MAX); ((SInt_64*)newData)[a] = (SInt_64)((double)((SInt_32*)data)[a] / (double)EHS_SINT_32_MAX * (double)EHS_SINT_64_MAX);
*(SInt_64*)newPeak = (SInt_64)((float)*(SInt_32*)peak / (float)EHS_SINT_32_MAX * (float)EHS_SINT_64_MAX); *(SInt_64*)newPeak = (SInt_64)((double)*(SInt_32*)peak / (double)EHS_SINT_32_MAX * (double)EHS_SINT_64_MAX);
} }
bool EncodeEHA(const ehs::AudioCodec* const codec, ehs::Serializer<ehs::UInt_64>& out, const ehs::Audio* const in) bool EncodeEHA(const ehs::AudioCodec* const codec, ehs::Serializer<ehs::UInt_64>& out, const ehs::Audio* const in)

View File

@@ -1,392 +0,0 @@
#include "ehs/io/audio/AudioDevice_ALSA.h"
#include "ehs/EHS.h"
#include "ehs/Log.h"
#include "ehs/io/Console.h"
namespace ehs
{
AudioDevice::~AudioDevice()
{
if (!hdl)
return;
snd_pcm_drain(hdl);
snd_pcm_close(hdl);
}
AudioDevice::AudioDevice()
: hdl(nullptr)
{
}
AudioDevice::AudioDevice(AudioDevice&& device) noexcept
: BaseAudioDevice(device), hdl(device.hdl)
{
device.hdl = nullptr;
}
AudioDevice::AudioDevice(const AudioDevice& device)
: BaseAudioDevice(device), hdl(nullptr)
{
}
AudioDevice& AudioDevice::operator=(AudioDevice&& device) noexcept
{
if (this == &device)
return *this;
BaseAudioDevice::operator=(device);
hdl = device.hdl;
device.hdl = nullptr;
return *this;
}
AudioDevice& AudioDevice::operator=(const AudioDevice& device)
{
if (this == &device)
return *this;
BaseAudioDevice::operator=(device);
hdl = nullptr;
return *this;
}
void AudioDevice::Release()
{
if (!IsValid())
return;
snd_pcm_drain(hdl);
snd_pcm_close(hdl);
hdl = nullptr;
}
void AudioDevice::OpenStream()
{
if (streaming)
return;
snd_pcm_hw_params_t* params;
snd_pcm_hw_params_alloca(&params);
snd_pcm_hw_params_any(hdl, params);
if (snd_pcm_hw_params_set_access(hdl, params, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to set access.");
return;
}
if (bitDepth)
{
snd_pcm_format_t format;
switch (dataType)
{
case DataType::FLOAT:
{
format = SND_PCM_FORMAT_FLOAT;
break;
}
case DataType::SINT_32:
{
format = SND_PCM_FORMAT_S32;
break;
}
case DataType::SINT_24:
{
format = SND_PCM_FORMAT_S24;
break;
}
case DataType::SINT_16:
{
format = SND_PCM_FORMAT_S16;
break;
}
case DataType::SINT_8:
{
format = SND_PCM_FORMAT_S8;
break;
}
default:
{
EHS_LOG_INT(LogType::ERR, 0, "Invalid data type.");
return;
}
}
snd_pcm_hw_params_set_format(hdl, params, format);
}
if (channels)
{
if (snd_pcm_hw_params_set_channels_near(hdl, params, &channels) < 0)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to set channels.");
return;
}
}
if (sampleRate)
{
if (snd_pcm_hw_params_set_rate_near(hdl, params, &sampleRate, nullptr) < 0)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set sample rate.");
return;
}
}
if (snd_pcm_hw_params_set_period_time_near(hdl, params, &period, nullptr) < 0)
{
EHS_LOG_INT(LogType::ERR, 3, "Failed to set period.");
return;
}
if (snd_pcm_hw_params_set_buffer_time_near(hdl, params, &latency, nullptr) < 0)
{
EHS_LOG_INT(LogType::ERR, 4, "Failed to set latency.");
return;
}
if (snd_pcm_hw_params(hdl, params) < 0)
{
EHS_LOG_INT(LogType::ERR, 5, "Failed to apply hardware parameters.");
return;
}
if (!bitDepth)
{
snd_pcm_format_t format;
if (snd_pcm_hw_params_get_format(params, &format) < 0)
{
EHS_LOG_INT(LogType::ERR, 6, "Failed to retrieve audio device properties.");
return;
}
switch (format)
{
case SND_PCM_FORMAT_FLOAT:
{
dataType = DataType::FLOAT;
bitDepth = 32;
break;
}
case SND_PCM_FORMAT_S32:
{
dataType = DataType::SINT_32;
bitDepth = 32;
break;
}
case SND_PCM_FORMAT_S24:
{
dataType = DataType::SINT_24;
bitDepth = 24;
break;
}
case SND_PCM_FORMAT_S16:
{
dataType = DataType::SINT_16;
bitDepth = 16;
break;
}
case SND_PCM_FORMAT_S8:
{
dataType = DataType::SINT_8;
bitDepth = 8;
break;
}
default:
{
EHS_LOG_INT(LogType::ERR, 7, "Format unsupported.");
break;
}
}
}
if (!channels)
{
if (snd_pcm_hw_params_get_channels(params, &channels) < 0)
{
EHS_LOG_INT(LogType::ERR, 8, "Failed to retrieve channel count.");
return;
}
}
if (!sampleRate)
{
int dir;
if (snd_pcm_hw_params_get_rate(params, &sampleRate, &dir) < 0)
{
EHS_LOG_INT(LogType::ERR, 9, "Failed to retrieve sample rate.");
return;
}
}
if (snd_pcm_hw_params_get_buffer_size(params, &maxFrames) < 0)
{
EHS_LOG_INT(LogType::ERR, 10, "Failed to retrieve buffer size.");
}
snd_pcm_sw_params_t* swParams = nullptr;
snd_pcm_sw_params_alloca(&swParams);
if (snd_pcm_sw_params_current(hdl, swParams) < 0)
{
EHS_LOG_INT(LogType::ERR, 11, "Failed to retrieve software parameters.");
return;
}
if (snd_pcm_sw_params_set_silence_threshold(hdl, swParams, maxFrames) < 0)
{
EHS_LOG_INT(LogType::ERR, 12, "Failed to set silence threshold.");
return;
}
if (snd_pcm_sw_params_set_silence_size(hdl, swParams, maxFrames) < 0)
{
EHS_LOG_INT(LogType::ERR, 12, "Failed to set silence size.");
return;
}
if (snd_pcm_sw_params(hdl, swParams) < 0)
{
EHS_LOG_INT(LogType::ERR, 13, "Failed to set software parameters.");
return;
}
if (snd_pcm_prepare(hdl) < 0)
{
EHS_LOG_INT(LogType::ERR, 14, "Failed to prepare audio stream.");
return;
}
streaming = true;
}
void AudioDevice::CloseStream()
{
if (!streaming)
return;
snd_pcm_drain(hdl);
streaming = false;
}
UInt_64 AudioDevice::GetAvailFrames() const
{
snd_pcm_state_t state = snd_pcm_state(hdl);
if (state == SND_PCM_STATE_XRUN)
{
EHS_LOG_INT(LogType::WARN, 0, "Buffer overrun/underrun occurred.");
if (snd_pcm_recover(hdl, -EPIPE, 0) < 0)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to recover from buffer overrun/underrun.");
return 0;
}
return GetAvailFrames();
}
else if (state == SND_PCM_STATE_PREPARED)
{
if (snd_pcm_start(hdl) < 0)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to start audio stream.");
return 0;
}
return GetAvailFrames();
}
snd_pcm_sframes_t frames = snd_pcm_avail_update(hdl);
if (frames < 0)
{
if (frames == -EPIPE)
{
EHS_LOG_INT(LogType::WARN, 3, "Buffer overrun/underrun occurred.");
if (snd_pcm_recover(hdl, -EPIPE, 1) < 0)
{
EHS_LOG_INT(LogType::ERR, 4, "Failed to recover from buffer overrun/underrun.");
return 0;
}
return GetAvailFrames();
}
else
{
EHS_LOG_INT(LogType::ERR, 5, "Failed to retrieve available frames with error #" + Str_8::FromNum(frames) + ".");
return 0;
}
}
return frames;
}
Byte* AudioDevice::Map(UInt_64* offset, UInt_64* frames)
{
const snd_pcm_channel_area_t* areas;
if (snd_pcm_mmap_begin(hdl, &areas, offset, frames) < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to map audio buffer.");
return nullptr;
}
return (Byte*)areas->addr + areas->first / 8;
}
void AudioDevice::UnMap(const UInt_64 offset, const UInt_64 frames)
{
snd_pcm_sframes_t committed = snd_pcm_mmap_commit(hdl, offset, frames);
if (committed < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to commit mapped audio buffer.");
return;
}
}
bool AudioDevice::IsValid() const
{
return hdl;
}
AudioDevice AudioDevice::GetDefault(const AudioDeviceType type)
{
AudioDevice result;
snd_pcm_stream_t rType;
if (type == AudioDeviceType::INPUT)
{
rType = SND_PCM_STREAM_CAPTURE;
}
else if (type == AudioDeviceType::OUTPUT)
{
rType = SND_PCM_STREAM_PLAYBACK;
}
else
{
EHS_LOG_INT(LogType::ERR, 1, "Wrong value for the audio device type.");
return {};
}
int err = snd_pcm_open(&result.hdl, "default", rType, SND_PCM_NONBLOCK);
if (err < 0)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve default audio device with error #" + Str_8::FromNum(err) + ".");
return {};
}
result.type = AudioDeviceType::OUTPUT;
EHS_LOG_SUCCESS();
return result;
}
Array<AudioDevice> AudioDevice::Get(const AudioDeviceType type, const AudioDeviceState state)
{
return {};
}
}

View File

@@ -0,0 +1,409 @@
#include "ehs/io/audio/AudioDevice_PW.h"
#include "ehs/EHS.h"
#include "ehs/Log.h"
#include "ehs/system/Semaphore.h"
#include <spa/utils/result.h>
#include <spa/utils/dict.h>
#include <spa/buffer/buffer.h>
#include <spa/param/latency-utils.h>
namespace ehs
{
Array<AudioDevice> AudioDevice::devices;
void AudioDevice::RegistryEventGlobal(void *data, const UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props)
{
if (Str_8::Cmp(type, PW_TYPE_INTERFACE_Node))
{
const Str_8 mediaClass = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
if (mediaClass.Size() && (mediaClass == "Audio/Sink" || mediaClass == "Audio/Source"))
{
AudioDevice device;
if (mediaClass == "Audio/Sink")
device.type = AudioDeviceType::OUTPUT;
else if (mediaClass == "Audio/Source")
device.type = AudioDeviceType::INPUT;
device.id = id;
device.name = spa_dict_lookup(props, PW_KEY_NODE_NAME);
EHS_LOG_INT(LogType::INFO, 1, "\nDevice Name: " + device.name + "\nId: " + Str_8::FromNum(device.id));
devices.Push(device);
}
}
}
void AudioDevice::RegistryEventGlobalRemove(void *data, UInt_32 id)
{
}
void AudioDevice::OnParamChanged(void *data, UInt_32 id, const spa_pod *param)
{
if (!param)
return;
if (id == SPA_PARAM_Buffers)
{
AudioDevice *device = (AudioDevice *)data;
spa_pod_object *obj = (spa_pod_object *)param;
spa_pod_prop *prop;
SPA_POD_OBJECT_FOREACH(obj, prop)
{
if (prop->key == SPA_PARAM_BUFFERS_size)
{
spa_pod_get_int(&prop->value, (int32_t *)&device->maxFrames);
device->maxFrames = device->maxFrames / device->byteDepth / device->channels;
}
}
}
}
AudioDevice::~AudioDevice()
{
if (!IsStreaming())
return;
if (output)
{
pw_stream_disconnect(output);
pw_stream_destroy(output);
output = nullptr;
}
if (input)
{
pw_stream_disconnect(input);
pw_stream_destroy(input);
input = nullptr;
}
pw_core_disconnect(core);
core = nullptr;
pw_context_destroy(context);
context = nullptr;
pw_loop_destroy(loop);
loop = nullptr;
}
AudioDevice::AudioDevice()
: id(0), loop(nullptr), context(nullptr), core(nullptr), input(nullptr), output(nullptr)
{
}
AudioDevice::AudioDevice(AudioDevice&& device) noexcept
: BaseAudioDevice(device), id(device.id), name((Str_8 &&)device.name), loop(device.loop),
context(device.context), core(device.core), input(device.input), output(device.output)
{
device.id = 0;
device.loop = nullptr;
device.context = nullptr;
device.core = nullptr;
device.input = nullptr;
device.output = nullptr;
}
AudioDevice::AudioDevice(const AudioDevice& device)
: BaseAudioDevice(device), id(device.id), name(device.name), loop(nullptr), context(nullptr), core(nullptr),
input(nullptr), output(nullptr)
{
}
AudioDevice& AudioDevice::operator=(AudioDevice&& device) noexcept
{
if (this == &device)
return *this;
BaseAudioDevice::operator=(device);
id = device.id;
name = (Str_8 &&)device.name;
loop = device.loop;
context = device.context;
core = device.core;
input = device.input;
output = device.output;
device.id = 0;
device.loop = nullptr;
device.context = nullptr;
device.core = nullptr;
device.input = nullptr;
device.output = nullptr;
return *this;
}
AudioDevice& AudioDevice::operator=(const AudioDevice& device)
{
if (this == &device)
return *this;
BaseAudioDevice::operator=(device);
id = device.id;
name = device.name;
loop = nullptr;
context = nullptr;
core = nullptr;
input = nullptr;
output = nullptr;
return *this;
}
void AudioDevice::OpenStream()
{
if (!IsValid() || IsStreaming())
return;
loop = pw_loop_new(nullptr);
context = pw_context_new(loop, nullptr, 0);
core = pw_context_connect(context, nullptr, 0);
spa_audio_info_raw info = {
.format = SPA_AUDIO_FORMAT_F32,
.rate = GetSampleRate(),
.channels = GetChannels(),
.position = {
SPA_AUDIO_CHANNEL_FL,
SPA_AUDIO_CHANNEL_FR,
SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_LFE,
SPA_AUDIO_CHANNEL_SL,
SPA_AUDIO_CHANNEL_SR,
SPA_AUDIO_CHANNEL_RL,
SPA_AUDIO_CHANNEL_RR
}
};
pw_properties *props = pw_properties_new(
PW_KEY_MEDIA_TYPE, "Audio",
PW_KEY_MEDIA_CATEGORY, GetCategory(),
PW_KEY_MEDIA_ROLE, "Game",
nullptr
);
spa_pod_builder b = {};
Byte buffer[1024];
spa_pod_builder_init(&b, buffer, sizeof(buffer));
const spa_pod *pod[] = {spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &info)};
if (GetType() == AudioDeviceType::INPUT || GetType() == AudioDeviceType::ALL)
{
input = pw_stream_new(core, "", props);
if (!input)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to create input stream for audio device.");
return;
}
pw_stream_connect(
output,
PW_DIRECTION_INPUT,
id,
(pw_stream_flags)(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS),
pod,
1
);
}
if (GetType() == AudioDeviceType::OUTPUT || GetType() == AudioDeviceType::ALL)
{
output = pw_stream_new(core, "", props);
if (!output)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to create output stream for audio device.");
return;
}
pw_stream_connect(
output,
PW_DIRECTION_OUTPUT,
id,
(pw_stream_flags)(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS),
pod,
1
);
}
static constexpr pw_stream_events streamEvents = {
.version = PW_VERSION_STREAM_EVENTS,
.param_changed = OnParamChanged
};
spa_hook streamListener = {};
pw_stream_add_listener(output, &streamListener, &streamEvents, this);
EHS_LOG_SUCCESS();
}
void AudioDevice::CloseStream()
{
if (!IsStreaming())
return;
if (output)
{
pw_stream_disconnect(output);
pw_stream_destroy(output);
output = nullptr;
}
if (input)
{
pw_stream_disconnect(input);
pw_stream_destroy(input);
input = nullptr;
}
pw_core_disconnect(core);
core = nullptr;
pw_context_destroy(context);
context = nullptr;
pw_loop_destroy(loop);
loop = nullptr;
}
UInt_64 AudioDevice::SendStream(const void *data, const UInt_64 size)
{
if (GetType() != AudioDeviceType::OUTPUT && GetType() != AudioDeviceType::ALL)
{
EHS_LOG_INT(LogType::ERR, 0, "You can only send an audio stream on an output audio device.");
return 0;
}
pw_loop_iterate(loop, 0);
if (pw_stream_get_state(output, nullptr) != PW_STREAM_STATE_STREAMING)
return 0;
pw_buffer *buf = pw_stream_dequeue_buffer(output);
if (!buf)
return 0;
UInt_64 out = 0;
spa_data &result = buf->buffer->datas[0];
if (size > result.maxsize)
out = result.maxsize;
else
out = size;
Util::Copy(result.data, data, out);
pw_stream_queue_buffer(output, buf);
EHS_LOG_SUCCESS();
return out;
}
UInt_64 AudioDevice::ReceiveStream(void *data, const UInt_64 size)
{
if (GetType() != AudioDeviceType::INPUT && GetType() != AudioDeviceType::ALL)
{
EHS_LOG_INT(LogType::ERR, 0, "You can only send an audio stream on an input audio device.");
return 0;
}
pw_loop_iterate(loop, 0);
if (pw_stream_get_state(input, nullptr) != PW_STREAM_STATE_STREAMING)
return 0;
pw_buffer *buf = pw_stream_dequeue_buffer(input);
if (!buf)
return 0;
spa_data &result = buf->buffer->datas[0];
UInt_64 in;
if (result.chunk->size <= size)
in = result.chunk->size;
else
in = size;
Util::Copy(data, result.data, in);
pw_stream_queue_buffer(input, buf);
EHS_LOG_SUCCESS();
return in;
}
bool AudioDevice::IsStreaming() const
{
return loop && context && core && (input || output);
}
bool AudioDevice::IsValid() const
{
return id;
}
AudioDevice AudioDevice::GetDefault(const AudioDeviceType type)
{
pw_init(nullptr, nullptr);
AudioDevice result;
result.type = type;
result.id = PW_ID_ANY;
return result;
}
Array<AudioDevice> AudioDevice::Get(const AudioDeviceType type, const AudioDeviceState state)
{
pw_init(nullptr, nullptr);
pw_loop *loop = pw_loop_new(nullptr);
pw_context *context = pw_context_new(loop, nullptr, 0);
pw_core *core = pw_context_connect(context, nullptr, 0);
pw_registry *registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, 0);
spa_hook listener = {};
static constexpr pw_registry_events events = {
.version = PW_VERSION_REGISTRY_EVENTS,
.global = RegistryEventGlobal,
.global_remove = RegistryEventGlobalRemove
};
pw_registry_add_listener(registry, &listener, &events, registry);
while (pw_loop_iterate(loop, 10));
pw_core_disconnect(core);
pw_context_destroy(context);
pw_loop_destroy(loop);
return devices;
}
Str_8 AudioDevice::GetCategory() const
{
switch (GetType())
{
case AudioDeviceType::INPUT:
return "Capture";
case AudioDeviceType::OUTPUT:
return "Playback";
case AudioDeviceType::ALL:
return "Duplex";
default:
return "";
}
}
}

View File

@@ -68,37 +68,9 @@ namespace ehs
return *this; return *this;
} }
void AudioDevice::Release()
{
if (captureClient)
{
captureClient->Release();
captureClient = nullptr;
}
if (playbackClient)
{
playbackClient->Release();
playbackClient = nullptr;
}
if (hdl)
{
HRESULT r = client->Stop();
if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to stop audio with error #" + Str_8::FromNum(r) + ".");
return;
}
hdl->Release();
hdl = nullptr;
}
}
void AudioDevice::OpenStream() void AudioDevice::OpenStream()
{ {
if (streaming) if (IsStreaming())
return; return;
HRESULT r = hdl->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&client); HRESULT r = hdl->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&client);
@@ -108,14 +80,14 @@ namespace ehs
WAVEFORMATEXTENSIBLE* format; WAVEFORMATEXTENSIBLE* format;
client->GetMixFormat((WAVEFORMATEX**)&format); client->GetMixFormat((WAVEFORMATEX**)&format);
if (bitDepth) if (byteDepth)
{ {
if (dataType == DataType::FLOAT) if (dataType == DataType::FLOAT)
format->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; format->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
else else
format->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; format->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
format->Format.wBitsPerSample = bitDepth; format->Format.wBitsPerSample = byteDepth * 8;
} }
else else
{ {
@@ -124,7 +96,7 @@ namespace ehs
else else
dataType = FromAudioBitDepth(format->Format.wBitsPerSample); dataType = FromAudioBitDepth(format->Format.wBitsPerSample);
bitDepth = format->Format.wBitsPerSample; byteDepth = format->Format.wBitsPerSample / 8;
} }
if (sampleRate) if (sampleRate)
@@ -137,7 +109,7 @@ namespace ehs
else else
channels = format->Format.nChannels; channels = format->Format.nChannels;
format->Format.nBlockAlign = bitDepth / 8 * channels; format->Format.nBlockAlign = byteDepth * channels;
format->Format.nAvgBytesPerSec = format->Format.nBlockAlign * sampleRate; format->Format.nAvgBytesPerSec = format->Format.nBlockAlign * sampleRate;
WAVEFORMATEX* match = {}; WAVEFORMATEX* match = {};
@@ -293,12 +265,12 @@ namespace ehs
return; return;
} }
streaming = true; EHS_LOG_SUCCESS();
} }
void AudioDevice::CloseStream() void AudioDevice::CloseStream()
{ {
if (!streaming) if (!IsStreaming())
return; return;
if (playbackClient) if (playbackClient)
@@ -324,98 +296,134 @@ namespace ehs
client->Release(); client->Release();
client = nullptr; client = nullptr;
hdl->Release();
hdl = nullptr;
} }
streaming = false; EHS_LOG_SUCCESS();
} }
UInt_64 AudioDevice::GetAvailFrames() const UInt_64 AudioDevice::SendStream(const void *data, UInt_64 outFrameSize)
{ {
if (!IsValid() || !streaming) if (!IsValid() || !IsStreaming() || !playbackClient || !data || !outFrameSize)
return 0; return 0;
UInt_32 sampleSize = 0; UInt_32 frameOffset = 0;
if (playbackClient) HRESULT r = client->GetCurrentPadding(&frameOffset);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{ {
HRESULT r = client->GetCurrentPadding(&sampleSize); EHS_LOG_INT(LogType::WARN, 0, "The audio device has been invalidated.");
if (r == AUDCLNT_E_DEVICE_INVALIDATED) return 0;
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
sampleSize = maxFrames - sampleSize;
} }
else if (captureClient) else if (FAILED(r))
{ {
HRESULT r = captureClient->GetNextPacketSize(&sampleSize); EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
if (r == AUDCLNT_E_DEVICE_INVALIDATED) return 0;
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples size with error #" + Str_8::FromNum(r) + ".");
} }
return sampleSize; UInt_32 frameSize = maxFrames - frameOffset;
if (frameSize > outFrameSize)
frameSize = outFrameSize;
Byte *buffer = nullptr;
r = playbackClient->GetBuffer(frameSize, &buffer);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{
EHS_LOG_INT(LogType::WARN, 2, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 3, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
return 0;
}
Util::Copy(buffer, data, frameSize * byteDepth * channels);
r = playbackClient->ReleaseBuffer(frameSize, 0);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{
EHS_LOG_INT(LogType::WARN, 4, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 5, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
return 0;
}
return frameSize;
} }
Byte* AudioDevice::Map(UInt_64* offset, UInt_64* frames) UInt_64 AudioDevice::ReceiveStream(void *data, UInt_64 inFrameSize)
{ {
if (!IsValid() || !IsStreaming() || !captureClient || !data || !inFrameSize)
return 0;
UInt_32 frameSize = 0;
HRESULT r = captureClient->GetNextPacketSize(&frameSize);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{
EHS_LOG_INT(LogType::WARN, 0, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples size with error #" + Str_8::FromNum(r) + ".");
return 0;
}
if (frameSize > inFrameSize)
frameSize = inFrameSize;
UInt_64 frameOffset = 0;
r = client->GetCurrentPadding((UINT32*)&frameOffset);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
{
EHS_LOG_INT(LogType::WARN, 2, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 3, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
return 0;
}
UInt_32 flags = 0;
Byte* buffer = nullptr; Byte* buffer = nullptr;
if (!IsValid()) r = captureClient->GetBuffer(&buffer, (UINT32*)&frameSize, (DWORD*)&flags, nullptr, nullptr);
return buffer;
HRESULT r = client->GetCurrentPadding((UINT32*)&offset);
if (r == AUDCLNT_E_DEVICE_INVALIDATED) if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated."); {
EHS_LOG_INT(LogType::WARN, 4, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r)) else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to retrieve samples padding with error #" + Str_8::FromNum(r) + ".");
if (playbackClient)
{ {
r = playbackClient->GetBuffer(*frames, &buffer); EHS_LOG_INT(LogType::ERR, 5, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
if (r == AUDCLNT_E_BUFFER_TOO_LARGE) return 0;
EHS_LOG_INT(LogType::ERR, 0, "The given frame size, " + Str_8::FromNum(*frames) + ", must be less than or equal to, " + Str_8::FromNum(maxFrames - *offset) + ".");
else if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 1, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
}
else if (captureClient)
{
UInt_32 flags = 0;
r = captureClient->GetBuffer(&buffer, (UINT32*)frames, (DWORD*)&flags, nullptr, nullptr);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 1, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve buffer with error #" + Str_8::FromNum(r) + ".");
} }
return buffer; Util::Copy(data, &buffer[frameOffset], frameSize * byteDepth * channels);
}
void AudioDevice::UnMap(const UInt_64 offset, const UInt_64 frames) r = captureClient->ReleaseBuffer(frameSize);
{ if (r == AUDCLNT_E_DEVICE_INVALIDATED)
if (!IsValid() || !streaming) {
return; EHS_LOG_INT(LogType::WARN, 6, "The audio device has been invalidated.");
return 0;
}
else if (FAILED(r))
{
EHS_LOG_INT(LogType::ERR, 7, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
return 0;
}
if (playbackClient) EHS_LOG_SUCCESS();
{
HRESULT r = playbackClient->ReleaseBuffer(frames, 0); return frameSize;
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
}
else if (captureClient)
{
HRESULT r = captureClient->ReleaseBuffer(frames);
if (r == AUDCLNT_E_DEVICE_INVALIDATED)
EHS_LOG_INT(LogType::ERR, 0, "The audio device has been invalidated.");
else if (FAILED(r))
EHS_LOG_INT(LogType::ERR, 1, "Failed to release buffer with error #" + Str_8::FromNum(r) + ".");
}
} }
Str_32 AudioDevice::GetInterfaceName_32() const Str_32 AudioDevice::GetInterfaceName_32() const
@@ -484,6 +492,11 @@ namespace ehs
return UTF::To_8(GetName_16()); return UTF::To_8(GetName_16());
} }
bool AudioDevice::IsStreaming() const
{
return hdl && client && (playbackClient || captureClient);
}
bool AudioDevice::IsValid() const bool AudioDevice::IsValid() const
{ {
return hdl; return hdl;

View File

@@ -1,16 +1,17 @@
#include "ehs/io/audio/BaseAudioDevice.h" #include "ehs/io/audio/BaseAudioDevice.h"
#include "ehs/Log.h"
namespace ehs namespace ehs
{ {
BaseAudioDevice::BaseAudioDevice() BaseAudioDevice::BaseAudioDevice()
: type(AudioDeviceType::ALL), dataType(DataType::SINT_8), bitDepth(0), sampleRate(0), channels(0), : type(AudioDeviceType::ALL), dataType(DataType::SINT_8), byteDepth(0), sampleRate(0), channels(0),
period(20000), latency(150000), maxFrames(0), streaming(false) period(20000), latency(150000), maxFrames(0)
{ {
} }
BaseAudioDevice::BaseAudioDevice(const BaseAudioDevice& device) BaseAudioDevice::BaseAudioDevice(const BaseAudioDevice& device)
: type(device.type), dataType(device.dataType), bitDepth(device.bitDepth), sampleRate(device.sampleRate), : type(device.type), dataType(device.dataType), byteDepth(device.byteDepth), sampleRate(device.sampleRate),
channels(device.channels), period(device.period), latency(device.latency), maxFrames(0), streaming(false) channels(device.channels), period(device.period), latency(device.latency), maxFrames(0)
{ {
} }
@@ -21,21 +22,16 @@ namespace ehs
type = device.type; type = device.type;
dataType = device.dataType; dataType = device.dataType;
bitDepth = device.bitDepth; byteDepth = device.byteDepth;
sampleRate = device.sampleRate; sampleRate = device.sampleRate;
channels = device.channels; channels = device.channels;
period = device.period; period = device.period;
latency = device.latency; latency = device.latency;
maxFrames = device.maxFrames; maxFrames = device.maxFrames;
streaming = false;
return *this; return *this;
} }
void BaseAudioDevice::Release()
{
}
void BaseAudioDevice::OpenStream() void BaseAudioDevice::OpenStream()
{ {
} }
@@ -44,32 +40,72 @@ namespace ehs
{ {
} }
UInt_64 BaseAudioDevice::GetAvailFrames() const UInt_64 BaseAudioDevice::SendStream(const void *data, const UInt_64 size)
{ {
return 0; return 0;
} }
Byte* BaseAudioDevice::Map(UInt_64* offset, UInt_64* frames) UInt_64 BaseAudioDevice::ReceiveStream(void *data, const UInt_64 size)
{ {
return nullptr; return 0;
} }
void BaseAudioDevice::UnMap(const UInt_64 offset, const UInt_64 frames) void BaseAudioDevice::BridgeStreams(BaseAudioDevice* input, UInt_64 frameBufferSize)
{ {
if (type != AudioDeviceType::OUTPUT)
{
EHS_LOG_INT(LogType::WARN, 0, "The current audio device object is not an output device.");
return;
}
if (input->type != AudioDeviceType::INPUT)
{
EHS_LOG_INT(LogType::WARN, 1, "The provided audio device is not an input device.");
return;
}
Byte* buffer = new Byte[frameBufferSize * GetFrameSize()];
UInt_64 result = 0;
while (result < frameBufferSize)
result += input->ReceiveStream(&buffer[result * GetFrameSize()], frameBufferSize - result);
while (result)
result -= SendStream(&buffer[(frameBufferSize - result) * GetFrameSize()], result);
delete[] buffer;
EHS_LOG_SUCCESS();
} }
AudioDeviceType BaseAudioDevice::GetType() const void BaseAudioDevice::BridgeStreams(const UInt_64 frameBufferSize)
{
Byte* buffer = new Byte[frameBufferSize * GetFrameSize()];
UInt_64 result = ReceiveStream(buffer, frameBufferSize);
while (result < frameBufferSize)
result += ReceiveStream(&buffer[result * GetFrameSize()], frameBufferSize - result);
while (result)
result -= SendStream(&buffer[(frameBufferSize - result) * GetFrameSize()], result);
delete[] buffer;
EHS_LOG_SUCCESS();
}
AudioDeviceType BaseAudioDevice::GetType() const
{ {
return type; return type;
} }
void BaseAudioDevice::SetDataType(const DataType newDataType) void BaseAudioDevice::SetDataType(const DataType newDataType)
{ {
if (streaming) if (IsStreaming())
return; return;
dataType = newDataType; dataType = newDataType;
bitDepth = ToBitDepth(newDataType); byteDepth = ToByteDepth(newDataType);
} }
DataType BaseAudioDevice::GetDataType() const DataType BaseAudioDevice::GetDataType() const
@@ -79,17 +115,17 @@ namespace ehs
UInt_8 BaseAudioDevice::GetByteDepth() const UInt_8 BaseAudioDevice::GetByteDepth() const
{ {
return bitDepth / 8; return byteDepth;
} }
UInt_16 BaseAudioDevice::GetBitDepth() const UInt_16 BaseAudioDevice::GetBitDepth() const
{ {
return bitDepth; return byteDepth * 8;
} }
void BaseAudioDevice::SetSampleRate(const UInt_32 newSampleRate) void BaseAudioDevice::SetSampleRate(const UInt_32 newSampleRate)
{ {
if (streaming) if (IsStreaming())
return; return;
sampleRate = newSampleRate; sampleRate = newSampleRate;
@@ -102,7 +138,7 @@ namespace ehs
void BaseAudioDevice::SetChannels(const UInt_32 newChannels) void BaseAudioDevice::SetChannels(const UInt_32 newChannels)
{ {
if (streaming) if (IsStreaming())
return; return;
channels = newChannels; channels = newChannels;
@@ -115,12 +151,12 @@ namespace ehs
UInt_32 BaseAudioDevice::GetFrameSize() const UInt_32 BaseAudioDevice::GetFrameSize() const
{ {
return bitDepth / 8 * channels; return byteDepth * channels;
} }
void BaseAudioDevice::SetPeriod(const UInt_32 newPeriod) void BaseAudioDevice::SetPeriod(const UInt_32 newPeriod)
{ {
if (streaming) if (IsStreaming())
return; return;
period = newPeriod; period = newPeriod;
@@ -133,7 +169,7 @@ namespace ehs
void BaseAudioDevice::SetLatency(const UInt_32 newLatency) void BaseAudioDevice::SetLatency(const UInt_32 newLatency)
{ {
if (streaming) if (IsStreaming())
return; return;
latency = newLatency; latency = newLatency;
@@ -151,7 +187,7 @@ namespace ehs
bool BaseAudioDevice::IsStreaming() const bool BaseAudioDevice::IsStreaming() const
{ {
return streaming; return false;
} }
bool BaseAudioDevice::IsValid() const bool BaseAudioDevice::IsValid() const

View File

@@ -7,44 +7,68 @@ namespace ehs
{ {
} }
Button::Button(const Str_8& name) Button::Button(Str_8 name)
: name(name), hash(name.Hash_32()) : hash(name.Hash_32()), name((Str_8 &&)name)
{ {
} }
Button::Button(const Button& key) Button::Button(Button &&key) noexcept
: name(key.name), hash(key.hash) : hash(key.hash), name((Str_8 &&)key.name)
{
key.hash = 0;
}
Button::Button(const Button &key)
: hash(key.hash), name(key.name)
{ {
} }
Button& Button::operator=(const Button& key) Button & Button::operator=(Button &&key) noexcept
{ {
if (this == &key) if (this == &key)
return *this; return *this;
name = key.name;
hash = key.hash; hash = key.hash;
name = (Str_8 &&)key.name;
key.hash = 0;
return *this; return *this;
} }
bool Button::operator==(const Button& key) const Button &Button::operator=(const Button &key)
{
if (this == &key)
return *this;
hash = key.hash;
name = key.name;
return *this;
}
bool Button::operator==(const Button &key) const
{ {
return key.hash == hash; return key.hash == hash;
} }
bool Button::operator!=(const Button& key) const bool Button::operator!=(const Button &key) const
{ {
return key.hash != hash; return key.hash != hash;
} }
UInt_32 Button::GetHash() const
{
return hash;
}
Str_8 Button::GetName() const Str_8 Button::GetName() const
{ {
return name; return name;
} }
UInt_32 Button::GetHash() const bool Button::IsValid() const
{ {
return hash; return hash;
} }
} }

View File

@@ -1,26 +1,39 @@
#include "ehs/io/hid/HID.h" #include "ehs/io/hid/HID.h"
#include "ehs/Log.h"
#include "ehs/Math.h"
#include "ehs/io/hid/Keyboard.h"
namespace ehs namespace ehs
{ {
HID::HID() HID::HID()
: type(EHS_HID_UNKNOWN), id(0) : type(EHS_HID_UNKNOWN), hashName(0), id(0), heldTime(0.0), activateTime(0.0f), active(false)
{ {
} }
HID::HID(const UInt_8 type, Str_8 name, const UInt_64 id) HID::HID(const UInt_8 type, Str_8 name, const UInt_64 id)
: type(type), name((Str_8&&)name), id(id) : type(type), hashName(name.Hash_64()), name((Str_8 &&)name), id(id), heldTime(0.0f), activateTime(0.0f),
active(false)
{ {
} }
HID::HID(HID&& hid) noexcept HID::HID(HID&& hid) noexcept
: type(hid.type), name((Str_8&&)hid.name), id(hid.id), states((Array<ButtonState>&&)hid.states) : type(hid.type), hashName(hid.hashName), name((Str_8&&)hid.name), id(hid.id),
states((Array<ButtonState> &&)hid.states), lastState((Button &&)hid.lastState), heldTime(hid.heldTime),
activateTime(hid.activateTime), active(hid.active)
{ {
hid.type = EHS_HID_UNKNOWN; hid.type = EHS_HID_UNKNOWN;
hid.hashName = 0;
hid.id = 0; hid.id = 0;
hid.lastState = {};
hid.heldTime = 0.0f;
hid.activateTime = 0.0f;
hid.active = false;
} }
HID::HID(const HID& hid) HID::HID(const HID& hid)
: type(hid.type), name(hid.name), id(hid.id), states(hid.states) : type(hid.type), hashName(hid.hashName), name(hid.name), id(hid.id), states(hid.states), heldTime(0.0f),
activateTime(0.0f), active(false)
{ {
} }
@@ -30,12 +43,22 @@ namespace ehs
return *this; return *this;
type = hid.type; type = hid.type;
hashName = hid.hashName;
name = (Str_8&&)hid.name; name = (Str_8&&)hid.name;
id = hid.id; id = hid.id;
states = (Array<ButtonState>&&)hid.states; states = (Array<ButtonState> &&)hid.states;
lastState = (Button &&)hid.lastState;
heldTime = hid.heldTime;
activateTime = hid.activateTime;
active = hid.active;
hid.type = EHS_HID_UNKNOWN; hid.type = EHS_HID_UNKNOWN;
hid.hashName = 0;
hid.id = 0; hid.id = 0;
hid.lastState = {};
hid.heldTime = 0.0f;
hid.activateTime = 0.0f;
hid.active = false;
return *this; return *this;
} }
@@ -46,9 +69,14 @@ namespace ehs
return *this; return *this;
type = hid.type; type = hid.type;
hashName = hid.hashName;
name = hid.name; name = hid.name;
id = hid.id; id = hid.id;
states = hid.states; states = hid.states;
lastState = {};
heldTime = 0.0f;
activateTime = 0.0f;
active = false;
return *this; return *this;
} }
@@ -73,16 +101,30 @@ namespace ehs
return id != otherId; return id != otherId;
} }
void HID::Poll() void HID::Poll(const float delta)
{ {
for (UInt_64 i = 0; i < states.Size(); ++i) for (UInt_64 i = 0; i < states.Size(); ++i)
{ {
if (states[i].IsPressed()) if (states[i].IsPressed())
{ {
if (states[i].GetState() == State::RELEASED) if (states[i].GetState() == State::RELEASED)
{
states[i].SetState(State::TOUCHED); states[i].SetState(State::TOUCHED);
lastState = states[i].GetButton();
ResetTime();
active = true;
}
else else
{
states[i].SetState(State::PRESSED); states[i].SetState(State::PRESSED);
if (lastState == states[i].GetButton())
{
if (TickHoldTime(delta))
TickActivateTime(delta);
}
}
} }
else else
{ {
@@ -90,6 +132,13 @@ namespace ehs
states[i].SetState(State::JUST_RELEASED); states[i].SetState(State::JUST_RELEASED);
else else
states[i].SetState(State::RELEASED); states[i].SetState(State::RELEASED);
if (lastState == states[i].GetButton())
{
lastState = {};
ResetTime();
active = false;
}
} }
} }
} }
@@ -149,7 +198,7 @@ namespace ehs
Vector<const ButtonState*> result(0, states.Size() + 1); Vector<const ButtonState*> result(0, states.Size() + 1);
for (UInt_64 i = 0; i < states.Size(); i++) for (UInt_64 i = 0; i < states.Size(); i++)
if (states[i] == State::PRESSED || states[i] == State::TOUCHED) if (states[i] == State::PRESSED)
result.Push(&states[i]); result.Push(&states[i]);
return result; return result;
@@ -158,7 +207,7 @@ namespace ehs
const ButtonState* HID::IsDown(const Button& button) const const ButtonState* HID::IsDown(const Button& button) const
{ {
const ButtonState* state = GetState(button); const ButtonState* state = GetState(button);
if (!state || (*state != State::PRESSED && *state != State::TOUCHED)) if (!state || (*state != State::PRESSED))
return nullptr; return nullptr;
return state; return state;
@@ -167,7 +216,7 @@ namespace ehs
const ButtonState* HID::IsDown() const const ButtonState* HID::IsDown() const
{ {
for (UInt_64 i = 0; i < states.Size(); i++) for (UInt_64 i = 0; i < states.Size(); i++)
if (states[i] == State::PRESSED || states[i] == State::TOUCHED) if (states[i] == State::PRESSED)
return &states[i]; return &states[i];
return nullptr; return nullptr;
@@ -231,6 +280,22 @@ namespace ehs
return nullptr; return nullptr;
} }
const ButtonState *HID::IsPressed(const Button &button)
{
if (active && lastState == button)
return GetState(lastState);
return nullptr;
}
const ButtonState *HID::GetPressed()
{
if (active)
return GetState(lastState);
return nullptr;
}
void HID::ButtonDown(const Button& button) void HID::ButtonDown(const Button& button)
{ {
if (ButtonState* state = GetState(button); state) if (ButtonState* state = GetState(button); state)
@@ -249,6 +314,9 @@ namespace ehs
const ButtonState* HID::GetState(const Button& button) const const ButtonState* HID::GetState(const Button& button) const
{ {
if (!button.IsValid())
return nullptr;
for (UInt_64 i = 0; i < states.Size(); ++i) for (UInt_64 i = 0; i < states.Size(); ++i)
if (states[i] == button) if (states[i] == button)
return &states[i]; return &states[i];
@@ -287,10 +355,42 @@ namespace ehs
ButtonState* HID::GetState(const Button& button) ButtonState* HID::GetState(const Button& button)
{ {
if (!button.IsValid())
return nullptr;
for (UInt_64 i = 0; i < states.Size(); i++) for (UInt_64 i = 0; i < states.Size(); i++)
if (states[i].GetButton() == button) if (states[i].GetButton() == button)
return &states[i]; return &states[i];
return nullptr; return nullptr;
} }
}
bool HID::TickHoldTime(const float delta)
{
if ((heldTime += delta) > 0.5f)
return true;
active = false;
return false;
}
void HID::ResetTime()
{
heldTime = 0.0f;
activateTime = 0.0f;
}
void HID::TickActivateTime(const float delta)
{
if ((activateTime += delta) > 0.075f)
{
activateTime = ehs::Math::Mod(activateTime, 0.075f);
active = true;
}
else
{
active = false;
}
}
}

View File

@@ -1,5 +1,7 @@
#include "ehs/io/hid/InputHandler.h" #include "ehs/io/hid/InputHandler.h"
#include "ehs/system/CPU.h"
namespace ehs namespace ehs
{ {
InputHandler::~InputHandler() InputHandler::~InputHandler()
@@ -9,23 +11,24 @@ namespace ehs
} }
InputHandler::InputHandler() InputHandler::InputHandler()
: hashId(0) : hashId(0), start(0)
{ {
} }
InputHandler::InputHandler(Str_8 id) InputHandler::InputHandler(Str_8 id)
: hashId(id.Hash_64()), id((Str_8&&)id) : hashId(id.Hash_64()), id((Str_8&&)id), start(CPU::GetTSC())
{ {
} }
InputHandler::InputHandler(InputHandler&& ih) noexcept InputHandler::InputHandler(InputHandler&& ih) noexcept
: hashId(ih.hashId), id((Str_8&&)ih.id), devices((Array<HID*>&&)ih.devices) : hashId(ih.hashId), id((Str_8&&)ih.id), devices((Array<HID*>&&)ih.devices), start(ih.start)
{ {
ih.hashId = 0; ih.hashId = 0;
ih.start = 0;
} }
InputHandler::InputHandler(const InputHandler& ih) InputHandler::InputHandler(const InputHandler& ih)
: hashId(ih.hashId), id(ih.id), devices(ih.devices.Size()) : hashId(ih.hashId), id(ih.id), devices(ih.devices.Size()), start(ih.start)
{ {
for (UInt_64 i = 0; i < devices.Size(); i++) for (UInt_64 i = 0; i < devices.Size(); i++)
devices[i] = ih.devices[i]->Clone(); devices[i] = ih.devices[i]->Clone();
@@ -39,8 +42,10 @@ namespace ehs
hashId = ih.hashId; hashId = ih.hashId;
id = (Str_8&&)ih.id; id = (Str_8&&)ih.id;
devices = (Array<HID*>&&)ih.devices; devices = (Array<HID*>&&)ih.devices;
start = ih.start;
ih.hashId = 0; ih.hashId = 0;
ih.start = 0;
return *this; return *this;
} }
@@ -56,6 +61,7 @@ namespace ehs
hashId = ih.hashId; hashId = ih.hashId;
id = ih.id; id = ih.id;
devices = Array<HID*>(ih.devices.Size()); devices = Array<HID*>(ih.devices.Size());
start = ih.start;
for (UInt_64 i = 0; i < devices.Size(); i++) for (UInt_64 i = 0; i < devices.Size(); i++)
devices[i] = ih.devices[i]->Clone(); devices[i] = ih.devices[i]->Clone();
@@ -63,12 +69,12 @@ namespace ehs
return *this; return *this;
} }
bool InputHandler::operator==(const UInt_64 otherHashId) bool InputHandler::operator==(const UInt_64 otherHashId) const
{ {
return hashId == otherHashId; return hashId == otherHashId;
} }
bool InputHandler::operator!=(const UInt_64 otherHashId) bool InputHandler::operator!=(const UInt_64 otherHashId) const
{ {
return hashId != otherHashId; return hashId != otherHashId;
} }
@@ -96,8 +102,14 @@ namespace ehs
void InputHandler::Poll() void InputHandler::Poll()
{ {
static UInt_64 freq = CPU::GetTSC_Freq();
const UInt_64 newTSC = CPU::GetTSC();
delta = newTSC - start;
start = newTSC;
for (UInt_64 i = 0; i < devices.Size(); i++) for (UInt_64 i = 0; i < devices.Size(); i++)
devices[i]->Poll(); devices[i]->Poll((float)delta / (float)freq);
} }
UInt_64 InputHandler::GetHashId() const UInt_64 InputHandler::GetHashId() const
@@ -157,4 +169,4 @@ namespace ehs
{ {
return false; return false;
} }
} }

View File

@@ -7,7 +7,7 @@ namespace ehs
} }
Keyboard::Keyboard(Str_8 name, const UInt_64 id) Keyboard::Keyboard(Str_8 name, const UInt_64 id)
: HID(EHS_HID_KEYBOARD, (Str_8&&)name, id) : HID(EHS_HID_KEYBOARD, (Str_8 &&)name, id)
{ {
} }
@@ -26,9 +26,9 @@ namespace ehs
return *this; return *this;
} }
void Keyboard::Poll() void Keyboard::Poll(const float delta)
{ {
HID::Poll(); HID::Poll(delta);
} }
Keyboard* Keyboard::Clone() const Keyboard* Keyboard::Clone() const
@@ -268,23 +268,23 @@ namespace ehs
case 71: case 71:
return Keyboard::F13; return Keyboard::F13;
case 72: case 72:
return Keyboard::F14; return Keyboard::Up;
case 73: case 73:
return Keyboard::F15; return Keyboard::F15;
case 74: case 74:
return Keyboard::F16; return Keyboard::F16;
case 75: case 75:
return Keyboard::F17; return Keyboard::Left;
case 76: case 76:
return Keyboard::F18; return Keyboard::F18;
case 77: case 77:
return Keyboard::F19; return Keyboard::Right;
case 78: case 78:
return Keyboard::F20; return Keyboard::F20;
case 79: case 79:
return Keyboard::F21; return Keyboard::F21;
case 80: case 80:
return Keyboard::F22; return Keyboard::Down;
case 81: case 81:
return Keyboard::F23; return Keyboard::F23;
case 82: case 82:

View File

@@ -28,11 +28,11 @@ namespace ehs
return *this; return *this;
} }
void Mouse::Poll() void Mouse::Poll(const float delta)
{ {
delta = {}; this->delta = {};
HID::Poll(); HID::Poll(delta);
} }
void Mouse::SetDelta(const Vec2_s32& newDelta) void Mouse::SetDelta(const Vec2_s32& newDelta)

View File

@@ -4,7 +4,7 @@
namespace ehs namespace ehs
{ {
Str_8 BaseDNS::Resolve(const AddrType type, const Str_8 &hostname) Str_8 BaseDNS::Resolve(const IP type, const Str_8 &hostname)
{ {
EHS_LOG_INT(LogType::ERR, 0, "Unsupported Operating System."); EHS_LOG_INT(LogType::ERR, 0, "Unsupported Operating System.");
return {}; return {};

112
src/io/socket/BaseICMP.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include "ehs/io/socket/BaseICMP.h"
#include "ehs/Serializer.h"
#include <netinet/ip.h>
namespace ehs
{
BaseICMP::BaseICMP()
: version(IP::V6)
{
}
BaseICMP::BaseICMP(const IP version)
: version(version)
{
}
BaseICMP::BaseICMP(BaseICMP &&icmp) noexcept
: version(icmp.version)
{
}
BaseICMP::BaseICMP(const BaseICMP &icmp)
: version(icmp.version)
{
}
BaseICMP & BaseICMP::operator=(BaseICMP &&icmp) noexcept
{
if (this == &icmp)
return *this;
version = icmp.version;
return *this;
}
BaseICMP & BaseICMP::operator=(const BaseICMP &icmp)
{
if (this == &icmp)
return *this;
version = icmp.version;
return *this;
}
UInt_64 BaseICMP::Send(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size)
{
return 0;
}
UInt_64 BaseICMP::Receive(Str_8 &address, ICMP_Header header, Serializer<UInt_64> &data)
{
return 0;
}
void BaseICMP::SendEchoRequest(const Str_8 &address, ICMP_EchoRequest er, const Byte *data, UInt_64 size)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return;
}
ICMP_Header header = {
8,
0,
0
};
Serializer<UInt_64> payload(Endianness::LE);
payload.Write(er);
payload.Resize(payload.Size() + size);
Util::Copy(&payload[payload.GetOffset()], data, size);
payload.SetOffset(payload.GetOffset() + size);
Send(address, header, &payload[0], payload.Size());
}
void BaseICMP::SetReceiveTimeout(UInt_64 timeout)
{
}
bool BaseICMP::IsValid() const
{
return false;
}
UInt_16 BaseICMP::ComputeChecksum(UInt_16 *buffer, Size length)
{
Size sum = 0;
while (length > 1)
{
sum += *buffer++;
length -= sizeof(UInt_16);
}
if (length == 1)
sum += *(UInt_8 *)buffer;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (UInt_16)~sum;
}
}

View File

@@ -4,26 +4,26 @@
namespace ehs namespace ehs
{ {
BaseTCP::BaseTCP() BaseTCP::BaseTCP()
: addrType(AddrType::IPV6), localPort(0), remotePort(0), connection(false), bound(false), listening(false), : ip(IP::V6), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
connected(false) connected(false)
{ {
} }
BaseTCP::BaseTCP(const AddrType addrType) BaseTCP::BaseTCP(const IP ip)
: addrType(addrType), localPort(0), remotePort(0), connection(false), bound(false), listening(false), : ip(ip), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
connected(false) connected(false)
{ {
} }
BaseTCP::BaseTCP(BaseTCP&& tcp) noexcept BaseTCP::BaseTCP(BaseTCP&& tcp) noexcept
: addrType(tcp.addrType), localAddr(std::move(tcp.localAddr)), localPort(tcp.localPort), : ip(tcp.ip), localAddr(std::move(tcp.localAddr)), localPort(tcp.localPort),
remoteHostName(std::move(tcp.remoteHostName)), remoteAddr(std::move(tcp.remoteAddr)), remotePort(tcp.remotePort), remoteHostName(std::move(tcp.remoteHostName)), remoteAddr(std::move(tcp.remoteAddr)), remotePort(tcp.remotePort),
connection(tcp.connection), bound(tcp.bound), listening(tcp.listening), connected(tcp.connected) connection(tcp.connection), bound(tcp.bound), listening(tcp.listening), connected(tcp.connected)
{ {
} }
BaseTCP::BaseTCP(const BaseTCP& tcp) BaseTCP::BaseTCP(const BaseTCP& tcp)
: addrType(tcp.addrType), localPort(0), remotePort(0), connection(false), bound(false), listening(false), : ip(tcp.ip), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
connected(false) connected(false)
{ {
} }
@@ -33,7 +33,7 @@ namespace ehs
if (this == &tcp) if (this == &tcp)
return *this; return *this;
addrType = tcp.addrType; ip = tcp.ip;
localAddr = std::move(tcp.localAddr); localAddr = std::move(tcp.localAddr);
localPort = tcp.localPort; localPort = tcp.localPort;
remoteHostName = std::move(tcp.remoteHostName); remoteHostName = std::move(tcp.remoteHostName);
@@ -44,7 +44,7 @@ namespace ehs
listening = tcp.listening; listening = tcp.listening;
connected = tcp.connected; connected = tcp.connected;
tcp.addrType = AddrType::IPV6; tcp.ip = IP::V6;
tcp.localPort = 0; tcp.localPort = 0;
tcp.remotePort = 0; tcp.remotePort = 0;
tcp.connection = false; tcp.connection = false;
@@ -60,7 +60,7 @@ namespace ehs
if (this == &tcp) if (this == &tcp)
return *this; return *this;
addrType = tcp.addrType; ip = tcp.ip;
localAddr = Str_8(); localAddr = Str_8();
localPort = 0; localPort = 0;
remoteHostName = Str_8(); remoteHostName = Str_8();
@@ -188,9 +188,9 @@ namespace ehs
return request; return request;
} }
AddrType BaseTCP::GetAddressType() const IP BaseTCP::GetAddressType() const
{ {
return addrType; return ip;
} }
Str_8 BaseTCP::GetLocalAddress() const Str_8 BaseTCP::GetLocalAddress() const

View File

@@ -3,25 +3,23 @@
namespace ehs namespace ehs
{ {
BaseUDP::BaseUDP() BaseUDP::BaseUDP()
: type(AddrType::IPV6), port(0), bound(false) : bound(false)
{ {
} }
BaseUDP::BaseUDP(const AddrType type) BaseUDP::BaseUDP(const IP version)
: type(type), port(0), bound(false) : localEndpoint{version, "", 0}, bound(false)
{ {
} }
BaseUDP::BaseUDP(BaseUDP&& udp) noexcept BaseUDP::BaseUDP(BaseUDP&& udp) noexcept
: type(udp.type), address(std::move(udp.address)), port(udp.port), bound(true) : localEndpoint((Endpoint &&)udp.localEndpoint), bound(true)
{ {
udp.type = AddrType::IPV6;
udp.port = 0;
udp.bound = false; udp.bound = false;
} }
BaseUDP::BaseUDP(const BaseUDP& udp) BaseUDP::BaseUDP(const BaseUDP& udp)
: type(udp.type), address(udp.address), port(udp.port), bound(false) : localEndpoint(udp.localEndpoint), bound(false)
{ {
} }
@@ -30,13 +28,9 @@ namespace ehs
if (this == &udp) if (this == &udp)
return *this; return *this;
type = udp.type; localEndpoint = (Endpoint &&)udp.localEndpoint;
address = std::move(udp.address);
port = udp.port;
bound = udp.bound; bound = udp.bound;
udp.type = AddrType::IPV6;
udp.port = 0;
udp.bound = false; udp.bound = false;
return *this; return *this;
@@ -47,9 +41,7 @@ namespace ehs
if (this == &udp) if (this == &udp)
return *this; return *this;
type = udp.type; localEndpoint = udp.localEndpoint;
address = udp.address;
port = udp.port;
bound = false; bound = false;
return *this; return *this;
@@ -60,18 +52,8 @@ namespace ehs
return bound; return bound;
} }
AddrType BaseUDP::GetLocalAddressType() const Endpoint BaseUDP::GetLocalEndpoint() const
{ {
return type; return localEndpoint;
}
Str_8 BaseUDP::GetLocalAddress() const
{
return address;
}
UInt_16 BaseUDP::GetLocalPort() const
{
return port;
} }
} }

View File

@@ -7,14 +7,14 @@
namespace ehs namespace ehs
{ {
Str_8 DNS::Resolve(const AddrType type, const Str_8 &hostname) Str_8 DNS::Resolve(const IP type, const Str_8 &hostname)
{ {
addrinfo* result = nullptr; addrinfo* result = nullptr;
addrinfo req = {}; addrinfo req = {};
if (type == AddrType::IPV6) if (type == IP::V6)
req.ai_family = AF_INET6; req.ai_family = AF_INET6;
else if (type == AddrType::IPV4) else if (type == IP::V4)
req.ai_family = AF_INET; req.ai_family = AF_INET;
Int_32 code = getaddrinfo(hostname, nullptr, &req, &result); Int_32 code = getaddrinfo(hostname, nullptr, &req, &result);

View File

@@ -6,7 +6,7 @@
namespace ehs namespace ehs
{ {
Str_8 DNS::Resolve(const AddrType type, const Str_8 &hostname) Str_8 DNS::Resolve(const IP type, const Str_8 &hostname)
{ {
WSADATA data = {}; WSADATA data = {};
@@ -20,9 +20,9 @@ namespace ehs
addrinfo* result = nullptr; addrinfo* result = nullptr;
addrinfo req = {}; addrinfo req = {};
if (type == AddrType::IPV6) if (type == IP::V6)
req.ai_family = AF_INET6; req.ai_family = AF_INET6;
else if (type == AddrType::IPV4) else if (type == IP::V4)
req.ai_family = AF_INET; req.ai_family = AF_INET;
Int_32 code = getaddrinfo(hostname, nullptr, &req, &result); Int_32 code = getaddrinfo(hostname, nullptr, &req, &result);

380
src/io/socket/EHC.cpp Normal file
View File

@@ -0,0 +1,380 @@
#include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/io/socket/ehc/NetServerCh.h"
#include "ehs/io/socket/ehc/NetClientCh.h"
#include "ehs/io/socket/ehc/NetSys.h"
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/PRNG.h"
namespace ehs
{
const Version EHC::version(1, 0, 0);
EHC::~EHC()
{
Release();
}
EHC::EHC(const IP version)
: udp(version), buffer(nullptr), bufferSize(0), lastTSC(0), delta(0.0f)
{
}
EHC::EHC(EHC &&sock) noexcept
: udp((UDP&&)sock.udp), buffer(sock.buffer), bufferSize(sock.bufferSize), lastTSC(sock.lastTSC), delta(sock.delta),
encryptions((Array<NetEnc *> &&)sock.encryptions), servers((Array<NetServerCh *> &&)sock.servers),
clients((Array<NetClientCh *> &&)sock.clients)
{
for (UInt_64 i = 0; i < servers.Size(); i++)
servers[i]->owner = this;
for (UInt_64 i = 0; i < clients.Size(); i++)
clients[i]->owner = this;
sock.buffer = nullptr;
sock.bufferSize = 0;
sock.lastTSC = 0;
sock.delta = 0.0f;
}
EHC::EHC(const EHC &sock)
: udp(sock.udp), buffer(nullptr), bufferSize(0), lastTSC(CPU::GetTSC()), delta(0.0f),
encryptions(sock.encryptions), servers(sock.servers), clients(sock.clients)
{
for (UInt_64 i = 0; i < servers.Size(); i++)
servers[i]->owner = this;
for (UInt_64 i = 0; i < clients.Size(); i++)
clients[i]->owner = this;
Initialize();
}
EHC &EHC::operator=(EHC &&sock) noexcept
{
if (this == &sock)
return *this;
udp = (UDP &&)sock.udp;
delete[] buffer;
buffer = sock.buffer;
bufferSize = sock.bufferSize;
lastTSC = sock.lastTSC;
delta = sock.delta;
for (UInt_64 i = 0; i < encryptions.Size(); i++)
delete encryptions[i];
encryptions = (Array<NetEnc *> &&)sock.encryptions;
for (UInt_64 i = 0; i < servers.Size(); i++)
delete servers[i];
servers = (Array<NetServerCh *> &&)sock.servers;
for (UInt_64 i = 0; i < servers.Size(); i++)
servers[i]->owner = this;
for (UInt_64 i = 0; i < clients.Size(); i++)
delete clients[i];
clients = (Array<NetClientCh *> &&)sock.clients;
for (UInt_64 i = 0; i < clients.Size(); i++)
clients[i]->owner = this;
sock.buffer = nullptr;
sock.bufferSize = 0;
sock.lastTSC = 0;
sock.delta = 0.0f;
return *this;
}
EHC &EHC::operator=(const EHC &sock)
{
if (this == &sock)
return *this;
udp = sock.udp;
delete[] buffer;
buffer = nullptr;
bufferSize = 0;
lastTSC = 0;
delta = 0.0f;
for (UInt_64 i = 0; i < encryptions.Size(); i++)
delete encryptions[i];
encryptions = sock.encryptions;
for (UInt_64 i = 0; i < servers.Size(); i++)
delete servers[i];
servers = sock.servers;
for (UInt_64 i = 0; i < servers.Size(); i++)
servers[i]->owner = this;
for (UInt_64 i = 0; i < clients.Size(); i++)
delete clients[i];
clients = sock.clients;
for (UInt_64 i = 0; i < clients.Size(); i++)
clients[i]->owner = this;
Initialize();
return *this;
}
void EHC::Initialize()
{
if (!udp.IsValid())
return;
udp.SetBlocking(false);
if (udp.GetLocalEndpoint().version == IP::V4)
{
buffer = new Byte[EHS_IPV4_UDP_PAYLOAD];
bufferSize = EHS_IPV4_UDP_PAYLOAD;
}
else if (udp.GetLocalEndpoint().version == IP::V6)
{
buffer = new Byte[EHS_IPV6_UDP_PAYLOAD];
bufferSize = EHS_IPV6_UDP_PAYLOAD;
}
}
void EHC::Release()
{
if (!udp.IsValid())
return;
delete[] buffer;
buffer = nullptr;
bufferSize = 0;
for (UInt_64 i = 0; i < encryptions.Size(); i++)
delete encryptions[i];
encryptions.Clear();
for (UInt_64 i = 0; i < servers.Size(); i++)
delete servers[i];
servers.Clear();
for (UInt_64 i = 0; i < clients.Size(); i++)
delete clients[i];
clients.Clear();
udp.Release();
}
void EHC::Bind(const Endpoint &endpoint)
{
udp.Bind(endpoint);
}
void EHC::Poll()
{
if (!udp.IsValid())
return;
UInt_64 newTSC = CPU::GetTSC();
delta = (float)(newTSC - lastTSC) / (float)CPU::GetTSC_Freq();
lastTSC = newTSC;
Endpoint remoteEndpoint;
UInt_16 received;
while ((received = udp.Receive(&remoteEndpoint, buffer, bufferSize)))
{
Serializer<UInt_64> payload(Endianness::LE, buffer, received);
Version remoteVer = payload.ReadVersion();
if (remoteVer != version)
continue;
UInt_64 encId = payload.Read<UInt_64>();
if (encId)
{
Version remoteEncVersion = payload.ReadVersion();
NetEnc* enc = GetEncryption(encId);
if (!enc || enc->GetVersion() != remoteEncVersion)
continue;
enc->Decrypt(&payload[payload.GetOffset()], payload.Size() - payload.GetOffset());
}
payload.SetOffset(0);
Header header = ReadHeader(payload);
if (!header.channelId)
continue;
if (header.channelType == NetChannelType::SERVER)
{
NetServerCh *server = GetServer(header.channelId);
if (!server)
continue;
server->Process(delta, remoteEndpoint, header, payload);
}
else if (header.channelType == NetChannelType::CLIENT)
{
NetClientCh *client = GetClient(header.channelId);
if (!client)
continue;
client->Process(delta, remoteEndpoint, header, payload);
}
}
for (UInt_64 i = 0; i < servers.Size(); ++i)
servers[i]->Poll(delta);
for (UInt_64 i = 0; i < clients.Size(); ++i)
clients[i]->Poll(delta);
}
bool EHC::IsInitialized() const
{
return udp.IsValid();
}
Endpoint EHC::GetLocalEndpoint() const
{
return udp.GetLocalEndpoint();
}
bool EHC::IsBound() const
{
return udp.IsBound();
}
Version EHC::GetVersion()
{
return version;
}
bool EHC::AddEncryption(NetEnc* enc)
{
if (HasEncryption(enc->GetId()))
return false;
encryptions.Push(enc);
return true;
}
bool EHC::HasServer(const UInt_64 serverId) const
{
for (UInt_64 i = 0; i < servers.Size(); ++i)
if (servers[i]->GetId() == serverId)
return true;
return false;
}
bool EHC::HasServer(const Str_8 &serverName) const
{
return HasServer(serverName.Hash_64());
}
bool EHC::AddServer(NetServerCh *server)
{
if (HasServer(server->GetId()))
return false;
server->owner = this;
servers.Push(server);
return true;
}
NetServerCh *EHC::GetServer(const UInt_64 serverId) const
{
for (UInt_64 i = 0; i < servers.Size(); ++i)
if (servers[i]->GetId() == serverId)
return servers[i];
return nullptr;
}
NetServerCh *EHC::GetServer(const Str_8 &serverName) const
{
return GetServer(serverName.Hash_64());
}
bool EHC::HasClient(const UInt_64 clientId) const
{
for (UInt_64 i = 0; i < clients.Size(); ++i)
if (clients[i]->GetId() == clientId)
return true;
return false;
}
bool EHC::HasClient(const Str_8 &clientName) const
{
return HasClient(clientName.Hash_64());
}
bool EHC::AddClient(NetClientCh *client)
{
if (HasServer(client->GetId()))
return false;
client->owner = this;
clients.Push(client);
return true;
}
NetClientCh *EHC::GetClient(const UInt_64 clientId) const
{
for (UInt_64 i = 0; i < clients.Size(); ++i)
if (clients[i]->GetId() == clientId)
return clients[i];
return nullptr;
}
NetClientCh *EHC::GetClient(const Str_8 &clientName) const
{
return GetClient(clientName.Hash_64());
}
bool EHC::HasEncryption(UInt_64 encId) const
{
for (UInt_64 i = 0; i < encryptions.Size(); ++i)
if (encryptions[i]->GetId() == encId)
return true;
return false;
}
bool EHC::HasEncryption(const Str_8& encName) const
{
return HasEncryption(encName.Hash_64());
}
NetEnc* EHC::GetEncryption(UInt_64 encId) const
{
for (UInt_64 i = 0; i < encryptions.Size(); ++i)
if (encryptions[i]->GetId() == encId)
return encryptions[i];
return nullptr;
}
NetEnc* EHC::GetEncryption(const Str_8& encName) const
{
return GetEncryption(encName.Hash_64());
}
}

176
src/io/socket/ICMP_LNX.cpp Normal file
View File

@@ -0,0 +1,176 @@
#include "ehs/io/socket/ICMP_LNX.h"
#include "ehs/Serializer.h"
#include "ehs/Log.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
namespace ehs
{
ICMP::ICMP()
: hdl(EHS_INVALID_SOCKET)
{
}
ICMP::ICMP(const IP version)
: BaseICMP(version)
{
hdl = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (hdl < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to create ICMP socket with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
ICMP::ICMP(ICMP &&icmp) noexcept
: BaseICMP((BaseICMP &&)icmp), hdl(icmp.hdl)
{
icmp.hdl = EHS_INVALID_SOCKET;
}
ICMP::ICMP(const ICMP &icmp)
: BaseICMP(icmp), hdl(icmp.hdl)
{
}
ICMP & ICMP::operator=(ICMP &&icmp) noexcept
{
if (this == &icmp)
return *this;
BaseICMP::operator=((BaseICMP &&)icmp);
hdl = icmp.hdl;
icmp.hdl = EHS_INVALID_SOCKET;
return *this;
}
ICMP & ICMP::operator=(const ICMP &icmp)
{
if (this == &icmp)
return *this;
BaseICMP::operator=(icmp);
hdl = icmp.hdl;
return *this;
}
UInt_64 ICMP::Send(const Str_8 &address, ICMP_Header header, const Byte *data, const UInt_64 size)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
header.checksum = 0;
Serializer<UInt_64> payload(Endianness::LE);
payload.Write(header);
payload.Resize(payload.Size() + size);
Util::Copy(&payload[payload.GetOffset()], data, size);
payload.SetOffset(payload.GetOffset() + size);
header.checksum = ComputeChecksum((UInt_16 *)&payload[0], payload.Size());
payload.SetOffset(0);
payload.Write(header);
payload.SetOffset(payload.Size());
sockaddr_in dst_addr = {};
dst_addr.sin_family = AF_INET;
inet_pton(AF_INET, address, &(dst_addr.sin_addr));
SInt_64 sent = sendto(hdl, payload, payload.Size(), 0, (sockaddr *)&dst_addr, sizeof(dst_addr));
if (sent < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to send packet with error #" + Str_8::FromNum(errno) + ".");
return 0;
}
EHS_LOG_SUCCESS();
return sent;
}
UInt_64 ICMP::Receive(Str_8 &address, ICMP_Header header, Serializer<UInt_64> &data)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
Serializer<UInt_64> payload(Endianness::LE);
payload.Resize(1500);
sockaddr_in remote = {};
socklen_t from_len = sizeof(remote);
SInt_64 recv = recvfrom(hdl, payload, 1500, 0, (sockaddr *)&remote, &from_len);
if (recv < 0)
{
int code = errno;
if (code == EAGAIN)
EHS_LOG_SUCCESS();
else
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive packet with error #" + Str_8::FromNum(code) + ".");
return 0;
}
payload.Resize(recv);
char tmpAddr[INET_ADDRSTRLEN];
if (!inet_ntop(remote.sin_family, &remote.sin_addr, tmpAddr, INET_ADDRSTRLEN))
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to convert IPv4 address with error #" + Str_8::FromNum(errno) + ".");
return recv;
}
address = tmpAddr;
iphdr ipHeader = payload.Read<iphdr>();
header = payload.Read<ICMP_Header>();
data = Serializer<UInt_64>(payload.GetEndianness(), &payload[payload.GetOffset()], payload.Size() - payload.GetOffset());
EHS_LOG_SUCCESS();
return recv;
}
void ICMP::SetReceiveTimeout(UInt_64 timeout)
{
timeval result = {};
result.tv_sec = (long)timeout;
result.tv_usec = 0;
if (setsockopt(hdl, SOL_SOCKET, SO_RCVTIMEO, &result, sizeof(result)) < 0)
{
EHS_LOG_INT(LogType::WARN, 0, "Failed to set receive timeout with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
bool ICMP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;
}
}

View File

@@ -29,7 +29,7 @@ namespace ehs
{ {
} }
SSL::SSL(const AddrType type) SSL::SSL(const IP type)
: TCP(type), ctx(nullptr), sslHdl(nullptr) : TCP(type), ctx(nullptr), sslHdl(nullptr)
{ {
SSL::Initialize(); SSL::Initialize();

View File

@@ -38,7 +38,7 @@ namespace ehc
} }
Socket::Socket() Socket::Socket()
: hdl(EHS_INVALID_SOCKET), type(AddrType::IPV4), port(0), bound(false), appVer(0, 0, 0), : hdl(EHS_INVALID_SOCKET), type(IP::V4), port(0), bound(false), appVer(0, 0, 0),
disposition(Disposition::UNKNOWN), dropPackets(false), hashId(0), buffer(nullptr), bufferSize(0), disposition(Disposition::UNKNOWN), dropPackets(false), hashId(0), buffer(nullptr), bufferSize(0),
maxEndpoints(0), lastTSC(0), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectedCb(nullptr), maxEndpoints(0), lastTSC(0), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectedCb(nullptr),
activeCb(nullptr), disconnectedCb(nullptr) activeCb(nullptr), disconnectedCb(nullptr)
@@ -47,7 +47,7 @@ namespace ehc
} }
Socket::Socket(const Version& ver, const Disposition disposition, const Str_8& id, const UInt_64 maxEndpoints) Socket::Socket(const Version& ver, const Disposition disposition, const Str_8& id, const UInt_64 maxEndpoints)
: hdl(EHS_INVALID_SOCKET), type(AddrType::IPV4), port(0), bound(false), appVer(ver), disposition(disposition), : hdl(EHS_INVALID_SOCKET), type(IP::V4), port(0), bound(false), appVer(ver), disposition(disposition),
dropPackets(false), id(id), hashId(id.Hash_32()), buffer(nullptr), bufferSize(0), dropPackets(false), id(id), hashId(id.Hash_32()), buffer(nullptr), bufferSize(0),
maxEndpoints(maxEndpoints), lastTSC(CPU::GetTSC()), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), maxEndpoints(maxEndpoints), lastTSC(CPU::GetTSC()), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f),
connectedCb(nullptr), activeCb(nullptr), disconnectedCb(nullptr) connectedCb(nullptr), activeCb(nullptr), disconnectedCb(nullptr)
@@ -113,9 +113,9 @@ namespace ehc
} }
#endif #endif
if (type == AddrType::IPV6) if (type == IP::V6)
hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
else if (type == AddrType::IPV4) else if (type == IP::V4)
hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
else else
return; return;
@@ -140,12 +140,12 @@ namespace ehc
return; return;
} }
if (type == AddrType::IPV4) if (type == IP::V4)
{ {
buffer = new Byte[EHS_IPV4_UDP_PAYLOAD]; buffer = new Byte[EHS_IPV4_UDP_PAYLOAD];
bufferSize = EHS_IPV4_UDP_PAYLOAD; bufferSize = EHS_IPV4_UDP_PAYLOAD;
} }
else if (type == AddrType::IPV6) else if (type == IP::V6)
{ {
buffer = new Byte[EHS_IPV6_UDP_PAYLOAD]; buffer = new Byte[EHS_IPV6_UDP_PAYLOAD];
bufferSize = EHS_IPV6_UDP_PAYLOAD; bufferSize = EHS_IPV6_UDP_PAYLOAD;
@@ -204,9 +204,9 @@ namespace ehc
if (hdl == EHS_INVALID_SOCKET || bound) if (hdl == EHS_INVALID_SOCKET || bound)
return; return;
if (type == AddrType::IPV6) if (type == IP::V6)
Bind_v6(newAddress, newPort); Bind_v6(newAddress, newPort);
else if (type == AddrType::IPV4) else if (type == IP::V4)
Bind_v4(newAddress, newPort); Bind_v4(newAddress, newPort);
address = newAddress; address = newAddress;
@@ -580,7 +580,7 @@ namespace ehc
return hdl != EHS_INVALID_SOCKET; return hdl != EHS_INVALID_SOCKET;
} }
void Socket::SetAddressType(const AddrType newType) void Socket::SetAddressType(const IP newType)
{ {
if (hdl != EHS_INVALID_SOCKET) if (hdl != EHS_INVALID_SOCKET)
return; return;
@@ -588,7 +588,7 @@ namespace ehc
type = newType; type = newType;
} }
AddrType Socket::GetAddressType() const IP Socket::GetAddressType() const
{ {
return type; return type;
} }
@@ -1219,14 +1219,14 @@ namespace ehc
return 0; return 0;
} }
if (type == AddrType::IPV4 && size > EHS_IPV4_UDP_PAYLOAD) if (type == IP::V4 && size > EHS_IPV4_UDP_PAYLOAD)
{ {
EHS_LOG_INT(LogType::ERR, 1, "Attempted to receive with a buffer size of, \"" + Str_8::FromNum(size) EHS_LOG_INT(LogType::ERR, 1, "Attempted to receive with a buffer size of, \"" + Str_8::FromNum(size)
+ "\", that exceeds, \"" + Str_8::FromNum(EHS_IPV4_UDP_PAYLOAD) + "."); + "\", that exceeds, \"" + Str_8::FromNum(EHS_IPV4_UDP_PAYLOAD) + ".");
} }
sockaddr_in6 remote = {}; sockaddr_in6 remote = {};
UInt_32 addrLen = type == AddrType::IPV6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); UInt_32 addrLen = type == IP::V6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);
SInt_64 received = 0; SInt_64 received = 0;
#if defined(EHS_OS_WINDOWS) #if defined(EHS_OS_WINDOWS)

View File

@@ -30,8 +30,8 @@ namespace ehs
{ {
} }
TCP::TCP(const AddrType addrType) TCP::TCP(const IP IP)
: BaseTCP(addrType), hdl(EHS_INVALID_SOCKET) : BaseTCP(IP), hdl(EHS_INVALID_SOCKET)
{ {
TCP::Initialize(); TCP::Initialize();
} }
@@ -78,9 +78,9 @@ namespace ehs
if (IsValid()) if (IsValid())
return; return;
if (addrType == AddrType::IPV6) if (ip == IP::V6)
hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
else if (addrType == AddrType::IPV4) else if (ip == IP::V4)
hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
else else
return; return;
@@ -119,9 +119,9 @@ namespace ehs
if (!IsValid() || bound || connection) if (!IsValid() || bound || connection)
return; return;
if (addrType == AddrType::IPV6) if (ip == IP::V6)
Bind_v6(address, port); Bind_v6(address, port);
else if (addrType == AddrType::IPV4) else if (ip == IP::V4)
Bind_v4(address, port); Bind_v4(address, port);
this->localAddr = address; this->localAddr = address;
@@ -155,7 +155,7 @@ namespace ehs
UInt_32 addrLen = sizeof(sockaddr_in6); UInt_32 addrLen = sizeof(sockaddr_in6);
TCP* client = new TCP(); TCP* client = new TCP();
client->addrType = addrType; client->ip = ip;
client->localAddr = localAddr; client->localAddr = localAddr;
client->localPort = localPort; client->localPort = localPort;
client->connection = true; client->connection = true;
@@ -215,18 +215,18 @@ namespace ehs
remoteHostName = address; remoteHostName = address;
remotePort = port; remotePort = port;
if (addrType == AddrType::IPV6) if (ip == IP::V6)
{ {
if (IsIPv6Only()) if (IsIPv6Only())
remoteAddr = DNS::Resolve(AddrType::IPV6, address); remoteAddr = DNS::Resolve(IP::V6, address);
else else
remoteAddr = DNS::Resolve(address); remoteAddr = DNS::Resolve(address);
Connect_v6(remoteAddr, port); Connect_v6(remoteAddr, port);
} }
else if (addrType == AddrType::IPV4) else if (ip == IP::V4)
{ {
remoteAddr = DNS::Resolve(AddrType::IPV4, address); remoteAddr = DNS::Resolve(IP::V4, address);
Connect_v4(remoteAddr, port); Connect_v4(remoteAddr, port);
} }
@@ -338,7 +338,7 @@ namespace ehs
void TCP::SetIPv6Only(const bool value) void TCP::SetIPv6Only(const bool value)
{ {
if (addrType != AddrType::IPV6) if (ip != IP::V6)
{ {
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6."); EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return; return;
@@ -362,7 +362,7 @@ namespace ehs
bool TCP::IsIPv6Only() const bool TCP::IsIPv6Only() const
{ {
if (addrType != AddrType::IPV6) if (ip != IP::V6)
return false; return false;
if (!IsValid()) if (!IsValid())

View File

@@ -33,8 +33,8 @@ namespace ehs
{ {
} }
TCP::TCP(const AddrType addrType) TCP::TCP(const IP IP)
: BaseTCP(addrType), hdl(EHS_INVALID_SOCKET) : BaseTCP(IP), hdl(EHS_INVALID_SOCKET)
{ {
TCP::Initialize(); TCP::Initialize();
} }
@@ -90,9 +90,9 @@ namespace ehs
return; return;
} }
if (addrType == AddrType::IPV6) if (ip == IP::V6)
hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
else if (addrType == AddrType::IPV4) else if (ip == IP::V4)
hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
else else
return; return;
@@ -142,9 +142,9 @@ namespace ehs
if (!IsValid() || bound || connection) if (!IsValid() || bound || connection)
return; return;
if (addrType == AddrType::IPV6) if (ip == IP::V6)
Bind_v6(address, port); Bind_v6(address, port);
else if (addrType == AddrType::IPV4) else if (ip == IP::V4)
Bind_v4(address, port); Bind_v4(address, port);
this->localAddr = address; this->localAddr = address;
@@ -178,7 +178,7 @@ namespace ehs
UInt_32 addrLen = sizeof(sockaddr_in6); UInt_32 addrLen = sizeof(sockaddr_in6);
TCP* client = new TCP(); TCP* client = new TCP();
client->addrType = addrType; client->ip = ip;
client->localAddr = localAddr; client->localAddr = localAddr;
client->localPort = localPort; client->localPort = localPort;
client->connection = true; client->connection = true;
@@ -244,18 +244,18 @@ namespace ehs
remoteHostName = address; remoteHostName = address;
remotePort = port; remotePort = port;
if (addrType == AddrType::IPV6) if (ip == IP::V6)
{ {
if (IsIPv6Only()) if (IsIPv6Only())
remoteAddr = DNS::Resolve(AddrType::IPV6, address); remoteAddr = DNS::Resolve(IP::V6, address);
else else
remoteAddr = DNS::Resolve(address); remoteAddr = DNS::Resolve(address);
Connect_v6(remoteAddr, port); Connect_v6(remoteAddr, port);
} }
else if (addrType == AddrType::IPV4) else if (ip == IP::V4)
{ {
remoteAddr = DNS::Resolve(AddrType::IPV4, address); remoteAddr = DNS::Resolve(IP::V4, address);
Connect_v4(remoteAddr, port); Connect_v4(remoteAddr, port);
} }
@@ -359,7 +359,7 @@ namespace ehs
void TCP::SetIPv6Only(const bool value) void TCP::SetIPv6Only(const bool value)
{ {
if (addrType != AddrType::IPV6) if (ip != IP::V6)
{ {
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6."); EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return; return;
@@ -383,7 +383,7 @@ namespace ehs
bool TCP::IsIPv6Only() const bool TCP::IsIPv6Only() const
{ {
if (addrType != AddrType::IPV6) if (ip != IP::V6)
return false; return false;
if (!IsValid()) if (!IsValid())

View File

@@ -25,12 +25,12 @@ namespace ehs
{ {
} }
UDP::UDP(const AddrType addrType) UDP::UDP(const IP version)
: BaseUDP(addrType), hdl(EHS_INVALID_SOCKET) : BaseUDP(version), hdl(EHS_INVALID_SOCKET)
{ {
if (addrType == AddrType::IPV6) if (version == IP::V6)
hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
else if (addrType == AddrType::IPV4) else if (version == IP::V4)
hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
else else
return; return;
@@ -96,33 +96,32 @@ namespace ehs
bound = false; bound = false;
} }
void UDP::Bind(const AddrType type, const Str_8& address, const UInt_16 port) void UDP::Bind(const Endpoint &endpoint)
{ {
if (!IsValid() || bound) if (!IsValid() || bound)
return; return;
if (type == AddrType::IPV6) if (endpoint.version == IP::V6)
Bind_v6(address, port); Bind_v6(endpoint.address, endpoint.port);
else if (type == AddrType::IPV4) else if (endpoint.version == IP::V4)
Bind_v4(address, port); Bind_v4(endpoint.address, endpoint.port);
this->address = address; localEndpoint = endpoint;
this->port = port;
bound = true; bound = true;
} }
UInt_64 UDP::Send(const AddrType type, const Str_8& address, const UInt_16 port, const Byte *const data, const UInt_64 size) UInt_64 UDP::Send(const Endpoint &endpoint, const Byte *const data, const UInt_64 size)
{ {
if (type == AddrType::IPV6) if (endpoint.version == IP::V6)
return Send_v6(address, port, data, size); return Send_v6(endpoint.address, endpoint.port, data, size);
else if (type == AddrType::IPV4) else if (endpoint.version == IP::V4)
return Send_v4(address, port, data, size); return Send_v4(endpoint.address, endpoint.port, data, size);
return 0; return 0;
} }
UInt_64 UDP::Receive(AddrType* const type, Str_8* const address, UInt_16* const port, Byte* const data, const UInt_64 size) UInt_64 UDP::Receive(Endpoint *endpoint, Byte* const data, const UInt_64 size)
{ {
if (!IsValid()) if (!IsValid())
{ {
@@ -161,9 +160,7 @@ namespace ehs
return received; return received;
} }
*type = AddrType::IPV6; *endpoint = {IP::V6, tmpAddr, remote.sin6_port};
*address = tmpAddr;
*port = ntohs(remote.sin6_port);
} }
else if (addrLen == sizeof(sockaddr_in)) else if (addrLen == sizeof(sockaddr_in))
{ {
@@ -178,9 +175,7 @@ namespace ehs
return received; return received;
} }
*type = AddrType::IPV4; *endpoint = {IP::V4, tmpAddr, ntohs(((sockaddr_in*)&remote)->sin_port)};
*address = tmpAddr;
*port = ntohs(((sockaddr_in*)&remote)->sin_port);
} }
return received; return received;
@@ -205,7 +200,7 @@ namespace ehs
void UDP::SetIPv6Only(const bool value) void UDP::SetIPv6Only(const bool value)
{ {
if (type != AddrType::IPV6) if (localEndpoint.version != IP::V6)
{ {
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6."); EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return; return;
@@ -229,7 +224,7 @@ namespace ehs
bool UDP::IsIPv6Only() const bool UDP::IsIPv6Only() const
{ {
if (type != AddrType::IPV6) if (localEndpoint.version != IP::V6)
return false; return false;
if (!IsValid()) if (!IsValid())

View File

@@ -24,8 +24,8 @@ namespace ehs
{ {
} }
UDP::UDP(const AddrType addrType) UDP::UDP(const IP IP)
: BaseUDP(addrType), hdl(EHS_INVALID_SOCKET) : BaseUDP(IP), hdl(EHS_INVALID_SOCKET)
{ {
WSADATA data = {}; WSADATA data = {};
@@ -36,9 +36,9 @@ namespace ehs
return; return;
} }
if (addrType == AddrType::IPV6) if (IP == IP::V6)
hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
else if (addrType == AddrType::IPV4) else if (IP == IP::V4)
hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
else else
return; return;
@@ -110,33 +110,32 @@ namespace ehs
bound = false; bound = false;
} }
void UDP::Bind(const AddrType type, const Str_8& address, const UInt_16 port) void UDP::Bind(const Endpoint &endpoint)
{ {
if (!IsValid() || bound) if (!IsValid() || bound)
return; return;
if (type == AddrType::IPV6) if (endpoint.version == IP::V6)
Bind_v6(address, port); Bind_v6(endpoint.address, endpoint.port);
else if (type == AddrType::IPV4) else if (endpoint.version == IP::V4)
Bind_v4(address, port); Bind_v4(endpoint.address, endpoint.port);
this->address = address; localEndpoint = endpoint;
this->port = port;
bound = true; bound = true;
} }
UInt_64 UDP::Send(const AddrType type, const Str_8& address, const UInt_16 port, const Byte *const data, const UInt_64 size) UInt_64 UDP::Send(const Endpoint &endpoint, const Byte *const data, const UInt_64 size)
{ {
if (type == AddrType::IPV6) if (endpoint.version == IP::V6)
return Send_v6(address, port, data, size); return Send_v6(endpoint.address, endpoint.port, data, size);
else if (type == AddrType::IPV4) else if (endpoint.version == IP::V4)
return Send_v4(address, port, data, size); return Send_v4(endpoint.address, endpoint.port, data, size);
return 0; return 0;
} }
UInt_64 UDP::Receive(AddrType* type, Str_8* const address, UInt_16* const port, Byte* const data, const UInt_64 size) UInt_64 UDP::Receive(Endpoint *endpoint, Byte* const data, const UInt_64 size)
{ {
if (!IsValid()) if (!IsValid())
{ {
@@ -174,9 +173,11 @@ namespace ehs
return received; return received;
} }
*type = AddrType::IPV6; *endpoint = {
*address = tmpAddr; IP::V6,
*port = ntohs(remote.sin6_port); tmpAddr,
ntohs(remote.sin6_port)
};
} }
else if (addrLen == sizeof(sockaddr_in)) else if (addrLen == sizeof(sockaddr_in))
{ {
@@ -191,9 +192,11 @@ namespace ehs
return received; return received;
} }
*type = AddrType::IPV4; *endpoint = {
*address = tmpAddr; IP::V4,
*port = ntohs(((sockaddr_in*)&remote)->sin_port); tmpAddr,
ntohs(((sockaddr_in*)&remote)->sin_port)
};
} }
return received; return received;
@@ -225,7 +228,7 @@ namespace ehs
void UDP::SetIPv6Only(const bool value) void UDP::SetIPv6Only(const bool value)
{ {
if (type != AddrType::IPV6) if (localEndpoint.version != IP::V6)
{ {
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6."); EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return; return;
@@ -249,7 +252,7 @@ namespace ehs
bool UDP::IsIPv6Only() const bool UDP::IsIPv6Only() const
{ {
if (type != AddrType::IPV6) if (localEndpoint.version != IP::V6)
return false; return false;
if (!IsValid()) if (!IsValid())
@@ -362,7 +365,7 @@ namespace ehs
Int_32 code = inet_pton(AF_INET6, addr, &result.sin6_addr); Int_32 code = inet_pton(AF_INET6, addr, &result.sin6_addr);
if (!code) if (!code)
{ {
EHS_LOG_INT(LogType::ERR, 1, "The given address, \"" + address + "\" is not valid."); EHS_LOG_INT(LogType::ERR, 1, "The given address, \"" + addr + "\" is not valid.");
return 0; return 0;
} }
else if (code == -1) else if (code == -1)
@@ -403,7 +406,7 @@ namespace ehs
int code = inet_pton(AF_INET, addr, &result.sin_addr); int code = inet_pton(AF_INET, addr, &result.sin_addr);
if (!code) if (!code)
{ {
EHS_LOG_INT(LogType::ERR, 1, "The given address, \"" + address + "\" is not valid."); EHS_LOG_INT(LogType::ERR, 1, "The given address, \"" + addr + "\" is not valid.");
return 0; return 0;
} }
else if (code == -1) else if (code == -1)

View File

@@ -0,0 +1,193 @@
#include "ehs/io/socket/ehc/NetChannel.h"
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetSys.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/PRNG.h"
namespace ehs
{
const UInt_64 NetChannel::internalSys = Str_8::Hash_64("Internal");
const UInt_64 NetChannel::connectOp = Str_8::Hash_64("Connect");
const UInt_64 NetChannel::connectedOp = Str_8::Hash_64("Connected");
const UInt_64 NetChannel::rejectedOp = Str_8::Hash_64("Rejected");
const UInt_64 NetChannel::disconnectOp = Str_8::Hash_64("Disconnect");
const UInt_64 NetChannel::disconnectedOp = Str_8::Hash_64("Disconnected");
const UInt_64 NetChannel::statusUpdateOp = Str_8::Hash_64("StatusUpdate");
const UInt_64 NetChannel::pingOp = Str_8::Hash_64("Ping");
const UInt_64 NetChannel::pongOp = Str_8::Hash_64("Pong");
const UInt_64 NetChannel::latencyOp = Str_8::Hash_64("Latency");
const UInt_64 NetChannel::receivedOp = Str_8::Hash_64("Received");
NetChannel::~NetChannel()
{
}
NetChannel::NetChannel()
: owner(nullptr), id(0), maxTimeout(5.0f), resendRate(0.5f)
{
}
NetChannel::NetChannel(Str_8 name, const Version &version)
: owner(nullptr), id(name.Hash_64()), name((Str_8 &&)name), version(version), maxTimeout(5.0f),
resendRate(0.5f)
{
}
NetChannel::NetChannel(NetChannel &&channel) noexcept
: owner(channel.owner), id(channel.id), name((Str_8 &&)channel.name), version(channel.version),
maxTimeout(channel.maxTimeout), resendRate(channel.resendRate)
{
channel.owner = nullptr;
channel.id = 0;
channel.version = {};
channel.maxTimeout = 5.0f;
channel.resendRate = 0.5f;
}
NetChannel::NetChannel(const NetChannel &channel)
: owner(nullptr), id(channel.id), name(channel.name), version(channel.version),
maxTimeout(channel.maxTimeout), resendRate(channel.resendRate)
{
}
NetChannel &NetChannel::operator=(NetChannel &&channel) noexcept
{
if (this == &channel)
return *this;
owner = channel.owner;
id = channel.id;
name = (Str_8 &&)channel.name;
version = channel.version;
maxTimeout = channel.maxTimeout;
resendRate = channel.resendRate;
channel.owner = nullptr;
channel.id = 0;
channel.version = {};
channel.maxTimeout = 5.0f;
channel.resendRate = 0.5f;
return *this;
}
NetChannel &NetChannel::operator=(const NetChannel &channel)
{
if (this == &channel)
return *this;
owner = nullptr;
id = channel.id;
name = channel.name;
version = channel.version;
maxTimeout = channel.maxTimeout;
resendRate = channel.resendRate;
return *this;
}
EHC *NetChannel::GetOwner() const
{
return owner;
}
UInt_64 NetChannel::GetId() const
{
return id;
}
Str_8 NetChannel::GetName() const
{
return name;
}
Version NetChannel::GetVersion() const
{
return version;
}
void NetChannel::SetMaxTimeout(const float seconds)
{
maxTimeout = seconds;
}
float NetChannel::GetMaxTimeout() const
{
return maxTimeout;
}
void NetChannel::SetResendRate(const float seconds)
{
resendRate = seconds;
}
float NetChannel::GetResendRate() const
{
return resendRate;
}
void NetChannel::EnableDropPackets(const bool enable)
{
dropPackets = enable;
}
bool NetChannel::IsDropPacketsEnabled() const
{
return dropPackets;
}
bool NetChannel::AddSystem(NetSys *sys)
{
if (sys->GetId() == internalSys)
return false;
if (HasSystem(sys->GetId()))
return false;
systems.Push(sys);
return true;
}
bool NetChannel::IsValid() const
{
return owner && id;
}
void NetChannel::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload)
{
}
void NetChannel::Poll(const float &delta)
{
}
bool NetChannel::HasSystem(const UInt_64 sysId) const
{
for (UInt_64 i = 0; i < systems.Size(); ++i)
if (systems[i]->GetId() == sysId)
return true;
return false;
}
bool NetChannel::HasSystem(const Str_8& sysName) const
{
return HasSystem(sysName.Hash_64());
}
NetSys* NetChannel::GetSystem(const UInt_64 sysId) const
{
for (UInt_64 i = 0; i < systems.Size(); ++i)
if (systems[i]->GetId() == sysId)
return systems[i];
return nullptr;
}
NetSys* NetChannel::GetSystem(const Str_8& sysName) const
{
return GetSystem(sysName.Hash_64());
}
}

View File

@@ -0,0 +1,385 @@
#include "ehs/io/socket/ehc/NetClientCh.h"
#include "ehs/io/socket/EHC.h"
namespace ehs
{
NetClientCh::~NetClientCh()
{
}
NetClientCh::NetClientCh()
: token{}, status(NetStatus::DISCONNECTED), queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f),
latency(0.0f), timeout(5.0f), nextSendId(0), nextRecvId(0)
{
}
NetClientCh::NetClientCh(Str_8 name, const Version &version, Endpoint remoteEndpoint)
: NetChannel((Str_8 &&)name, version), remoteEndpoint((Endpoint &&)remoteEndpoint), token{},
status(NetStatus::DISCONNECTED), queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f),
latency(0.0f), timeout(0.0f), nextSendId(0), nextRecvId(0)
{
}
NetClientCh::NetClientCh(NetClientCh &&client) noexcept
: NetChannel((NetChannel &&)client), remoteEndpoint((Endpoint &&)client.remoteEndpoint), token{},
status(client.status), queueSlot(client.queueSlot), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f),
latency(0.0f), timeout(0.0f), nextSendId(0), sent((Vector<Insurance> &&)client.sent), nextRecvId(0),
received((Vector<NetFrag> &&)client.received)
{
Util::Copy(token, client.token, 64);
Util::Zero(client.token, 64);
client.status = NetStatus::DISCONNECTED;
client.queueSlot = 0;
client.deltaDuration = 0.0f;
client.deltaRate = 0.0f;
client.lastPing = 0.0f;
client.latency = 0.0f;
client.timeout = 0.0f;
client.nextSendId = 0;
client.nextRecvId = 0;
}
NetClientCh::NetClientCh(const NetClientCh &client)
: NetChannel(client), remoteEndpoint(client.remoteEndpoint), token{}, status(NetStatus::DISCONNECTED),
queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f), latency(0.0f), timeout(0.0f), nextSendId(0),
nextRecvId(0)
{
}
NetClientCh & NetClientCh::operator=(NetClientCh &&client) noexcept
{
if (this == &client)
return *this;
NetChannel::operator=((NetChannel &&)client);
remoteEndpoint = (Endpoint &&)client.remoteEndpoint;
Util::Copy(token, client.token, 64);
status = client.status;
queueSlot = client.queueSlot;
deltaDuration = client.deltaDuration;
deltaRate = client.deltaRate;
lastPing = client.lastPing;
latency = client.latency;
timeout = client.timeout;
nextSendId = client.nextSendId;
sent = (Vector<Insurance> &&)client.sent;
nextRecvId = client.nextRecvId;
received = (Vector<NetFrag> &&)client.received;
Util::Zero(client.token, 64);
client.status = NetStatus::DISCONNECTED;
client.queueSlot = 0;
client.deltaDuration = 0.0f;
client.deltaRate = 0.0f;
client.lastPing = 0.0f;
client.latency = 0.0f;
client.timeout = 0.0f;
client.nextSendId = 0;
client.nextRecvId = 0;
return *this;
}
NetClientCh & NetClientCh::operator=(const NetClientCh &client)
{
if (this == &client)
return *this;
remoteEndpoint = client.remoteEndpoint;
Util::Zero(token, 64);
status = NetStatus::DISCONNECTED;
queueSlot = 0;
deltaDuration = 0.0f;
deltaRate = 0.0f;
lastPing = 0.0f;
latency = 0.0f;
timeout = 0.0f;
nextSendId = 0;
sent = {};
nextRecvId = 0;
received = {};
return *this;
}
void NetClientCh::OnConnected(Serializer<UInt_64> data)
{
}
void NetClientCh::OnActive(Serializer<UInt_64> data)
{
}
void NetClientCh::OnQueueUpdate(Serializer<UInt_64> data)
{
}
void NetClientCh::OnDisconnected(Serializer<UInt_64> data)
{
}
void NetClientCh::OnRejected(Serializer<UInt_64> data)
{
}
void NetClientCh::OnTimeout(Serializer<UInt_64> data)
{
}
void NetClientCh::Connect(const Endpoint &endpoint, const Serializer<UInt_64> &payload)
{
if (!GetOwner()->udp.IsValid())
return;
Send(false, true, false, internalSys, connectOp, payload);
status = NetStatus::PENDING;
}
bool NetClientCh::Disconnect(const Serializer<UInt_64> &payload)
{
if (!GetOwner()->udp.IsValid())
return false;
Send(false, true, false, internalSys, disconnectOp, payload);
return true;
}
void NetClientCh::Send(const bool deltaLocked, UInt_64 encId, const bool ensure, UInt_64 sysId, UInt_64 opId,
const Serializer<UInt_64> &payload)
{
if (!IsValid() || (deltaLocked && deltaDuration < deltaRate))
return;
const EHC *owner = GetOwner();
NetEnc *enc = owner->GetEncryption(encId);
if (!enc)
{
EHS_LOG_INT(LogType::WARN, 0, "Encryption with the Id, \"" + Str_8::FromNum(encId) + "\", does not exist.");
return;
}
Header header = {
EHC::GetVersion(),
encId,
enc->GetVersion(),
GetId(),
NetChannelType::SERVER,
GetVersion(),
nextSendId++,
1,
0,
ensure,
"",
sysId,
opId
};
Util::Copy(header.token, token, 64);
const Endpoint localEndpoint = owner->GetLocalEndpoint();
if ((localEndpoint.version == IP::V6 && payload.Size() > EHC_IPV6_PAYLOAD) || (localEndpoint.version == IP::V4 && payload.Size() > EHC_IPV4_PAYLOAD))
{
NetFrag frags = FragmentData(localEndpoint.version, header, payload);
for (UInt_64 i = 0; i < frags.Size(); ++i)
{
Header newHeader = frags.GetHeader();
newHeader.fragment = i;
Send(enc, newHeader, frags[i]);
}
}
else
{
Send(enc, header, payload);
}
}
void NetClientCh::Send(const bool deltaLocked, const Str_8 &encName, const bool ensure, const Str_8 &sysName,
const Str_8 &opName, const Serializer<UInt_64> &payload)
{
Send(deltaLocked, encName.Hash_64(), ensure, sysName.Hash_64(), opName.Hash_64(), payload);
}
NetStatus NetClientCh::GetStatus() const
{
return status;
}
void NetClientCh::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload)
{
if (!Util::Compare(token, header.token, 64))
return;
if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == connectedOp)
{
if (status != NetStatus::PENDING)
return;
Util::Copy(token, header.token, 64);
status = payload.Read<NetStatus>();
queueSlot = payload.Read<UInt_64>();
OnConnected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == disconnectedOp)
{
OnDisconnected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == rejectedOp)
{
OnRejected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == statusUpdateOp)
{
const NetStatus newStatus = payload.Read<NetStatus>();
queueSlot = payload.Read<UInt_64>();
if (status == NetStatus::ACTIVE)
OnActive({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
else if (status == NetStatus::QUEUED && newStatus == NetStatus::QUEUED)
OnQueueUpdate({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
status = newStatus;
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == receivedOp)
{
const UInt_64 msgId = payload.Read<UInt_64>();
const UInt_64 fragment = payload.Read<UInt_64>();
RemoveInsurance(msgId, fragment);
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == pingOp)
{
deltaRate = payload.Read<float>();
Pong(delta);
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == latencyOp)
{
latency = payload.Read<float>();
}
}
void NetClientCh::Poll(const float &delta)
{
}
NetFrag NetClientCh::FragmentData(const IP version, const Header& header, const Serializer<>& data)
{
NetFrag result;
if (version == IP::V6)
{
UInt_64 frags = data.Size() / EHC_IPV6_PAYLOAD;
if (data.Size() % EHC_IPV6_PAYLOAD)
++frags;
result = NetFrag(header, frags);
UInt_64 size = EHC_IPV6_PAYLOAD;
for (UInt_64 i = 0; i < result.Size(); ++i)
{
size = EHC_IPV6_PAYLOAD;
if (i == result.Size() - 1)
size = data.Size() % EHC_IPV6_PAYLOAD;
result[i] = {data.GetEndianness(), &data[i * EHC_IPV6_PAYLOAD], size};
}
}
else if (version == IP::V4)
{
UInt_64 frags = data.Size() / EHC_IPV4_PAYLOAD;
if (data.Size() % EHC_IPV4_PAYLOAD)
++frags;
result = NetFrag(header, frags);
UInt_64 size = EHC_IPV4_PAYLOAD;
for (UInt_64 i = 0; i < result.Size(); ++i)
{
size = EHC_IPV4_PAYLOAD;
if (i == result.Size() - 1)
size = data.Size() % EHC_IPV4_PAYLOAD;
result[i] = {data.GetEndianness(), &data[i * EHC_IPV4_PAYLOAD], size};
}
}
return result;
}
void NetClientCh::Send(NetEnc *enc, const Header& header, const Serializer<UInt_64>& payload)
{
Serializer result(Endianness::LE);
result.Write(header);
result.WriteSer(payload);
enc->Encrypt(&result[sizeof(bool)], result.Size() - sizeof(bool));
if (header.ensure)
sent.Push({header, payload});
GetOwner()->udp.Send(remoteEndpoint, result, result.Size());
}
void NetClientCh::Pong(const float delta)
{
Serializer payload(Endianness::LE);
payload.Write(delta);
Send(false, true, false, internalSys, pongOp, payload);
timeout = 0.0f;
}
void NetClientCh::RemoveInsurance(const UInt_64 msgId, const UInt_64 fragment)
{
for (UInt_64 i = 0; i < sent.Size(); ++i)
{
if (sent[i].header.id == msgId && sent[i].header.fragment == fragment)
{
sent.Remove(i);
break;
}
}
timeout = 0.0f;
}
void NetClientCh::AddReceived(const Header& header, const Serializer<>& payload)
{
NetFrag* frags = nullptr;
for (UInt_64 i = 0; i < received.Size(); ++i)
{
if (received[i].GetHeader().id == header.id)
{
if (received[i][header.fragment].Size())
return;
frags = &received[i];
break;
}
}
if (header.id > nextRecvId)
nextRecvId = header.id + 1;
if (frags)
(*frags)[header.fragment] = payload;
else
received.Push({header, payload});
timeout = 0.0f;
}
}

View File

@@ -0,0 +1,76 @@
#include "ehs/io/socket/ehc/NetEnc.h"
namespace ehs
{
NetEnc::NetEnc()
: id(0)
{
}
NetEnc::NetEnc(Str_8 name, const Version &version)
: id(name.Hash_64()), name((Str_8 &&)name), version(version)
{
}
NetEnc::NetEnc(NetEnc&& enc) noexcept
: id(enc.id), name((Str_8 &&)enc.name), version(enc.version)
{
enc.id = 0;
enc.version = {};
}
NetEnc::NetEnc(const NetEnc& enc)
: id(enc.id), name(enc.name), version(enc.version)
{
}
NetEnc& NetEnc::operator=(NetEnc&& enc) noexcept
{
if (this == &enc)
return *this;
id = enc.id;
name = (Str_8 &&)enc.name;
version = enc.version;
enc.id = 0;
enc.version = {};
return *this;
}
NetEnc& NetEnc::operator=(const NetEnc& enc)
{
if (this == &enc)
return *this;
id = enc.id;
name = enc.name;
version = enc.version;
return *this;
}
UInt_64 NetEnc::GetId() const
{
return id;
}
Str_8 NetEnc::GetName() const
{
return name;
}
Version NetEnc::GetVersion() const
{
return version;
}
void NetEnc::Encrypt(Byte *data, UInt_64 size) const
{
}
void NetEnc::Decrypt(Byte *data, UInt_64 size) const
{
}
}

View File

@@ -0,0 +1,511 @@
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/io/socket/ehc/NetServerCh.h"
#include "ehs/system/CPU.h"
namespace ehs
{
NetEnd::NetEnd()
: owner(nullptr), id(0), status(NetStatus::PENDING), token{}, nextSendId(0), nextRecvId(0),
deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f),
latency(0.0f), queueSlot(0)
{
}
NetEnd::NetEnd(Str_8 id, Endpoint endpoint)
: owner(nullptr), id(id.Hash_64()), name((Str_8&&)id), status(NetStatus::ACTIVE), token{}, nextSendId(0),
nextRecvId(0), endpoint((Endpoint &&)endpoint), deltaDuration(0.0f), deltaRate(1.0f / 60.0f),
timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), queueSlot(0)
{
}
NetEnd::NetEnd(Endpoint endpoint)
: owner(nullptr), id(0), status(NetStatus::PENDING), token{}, nextSendId(0), nextRecvId(0),
endpoint((Endpoint &&)endpoint), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f),
oldLatency(0.0f), latency(0.0f), queueSlot(0)
{
}
NetEnd::NetEnd(NetEnd &&end) noexcept
: owner(end.owner), id(end.id), name((Str_8&&)end.name), status(end.status), token{},
nextSendId(end.nextSendId), sent((Vector<Insurance>&&)end.sent), nextRecvId(end.nextRecvId),
received((Vector<NetFrag>&&)end.received), endpoint((Endpoint &&)end.endpoint),
deltaDuration(end.deltaDuration), deltaRate(end.deltaRate), timeout(end.timeout), lastPing(end.lastPing),
oldLatency(end.oldLatency), latency(end.latency), queueSlot(end.queueSlot)
{
end.owner = nullptr;
end.id = 0;
end.status = NetStatus::PENDING;
Util::Copy(token, end.token, 64);
Util::Zero(end.token, 64);
end.nextSendId = 0;
end.nextRecvId = 0;
end.deltaDuration = 0.0f;
end.deltaRate = 1.0f / 60.0f;
end.timeout = 0.0f;
end.lastPing = 0.0f;
end.oldLatency = 0.0f;
end.latency = 0.0f;
end.queueSlot = 0;
}
NetEnd::NetEnd(const NetEnd& end)
: owner(nullptr), id(end.id), name(end.name), status(NetStatus::PENDING), token{}, nextSendId(0),
nextRecvId(0), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f),
latency(0.0f), queueSlot(0)
{
}
NetEnd& NetEnd::operator=(NetEnd&& end) noexcept
{
if (this == &end)
return *this;
owner = end.owner;
id = end.id;
name = (Str_8&&)end.name;
status = end.status;
Util::Copy(token, end.token, 64);
nextSendId = end.nextSendId;
sent = (Vector<Insurance>&&)end.sent;
nextRecvId = end.nextRecvId;
received = (Vector<NetFrag>&&)end.received;
endpoint = (Endpoint &&)end.endpoint;
deltaDuration = end.deltaDuration;
deltaRate = end.deltaRate;
timeout = end.timeout;
lastPing = end.lastPing;
oldLatency = end.oldLatency;
latency = end.latency;
queueSlot = end.queueSlot;
end.owner = nullptr;
end.id = 0;
end.status = NetStatus::PENDING;
Util::Zero(end.token, 64);
end.nextSendId = 0;
end.nextRecvId = 0;
end.deltaDuration = 0.0f;
end.deltaRate = 1.0f / 60.0f;
end.timeout = 0.0f;
end.lastPing = 0.0f;
end.oldLatency = 0.0f;
end.latency = 0.0f;
end.queueSlot = 0;
return *this;
}
NetEnd &NetEnd::operator=(const NetEnd &end)
{
if (this == &end)
return *this;
owner = nullptr;
id = end.id;
name = end.name;
status = NetStatus::PENDING;
Util::Zero(token, 64);
nextSendId = 0;
sent = {};
nextRecvId = 0;
received = {};
endpoint = {};
deltaDuration = 0.0f;
deltaRate = 1.0f / 60.0f;
timeout = 0.0f;
lastPing = 0.0f;
oldLatency = 0.0f;
latency = 0.0f;
queueSlot = 0;
return *this;
}
UInt_64 NetEnd::GetId() const
{
return id;
}
Str_8 NetEnd::GetName() const
{
return name;
}
NetStatus NetEnd::GetStatus() const
{
return status;
}
UInt_64 NetEnd::GetNextSendId() const
{
return nextSendId;
}
void NetEnd::Send(const bool deltaLocked, const UInt_64 encId, const bool ensure, const UInt_64 sysId,
const UInt_64 opId, const Serializer<UInt_64> &payload)
{
if (!owner || !owner->GetOwner() || (deltaLocked && deltaDuration < deltaRate))
return;
EHC *ehc = owner->GetOwner();
NetEnc *enc = ehc->GetEncryption(encId);
if (!enc)
{
EHS_LOG_INT(LogType::WARN, 0, "Encryption with the Id, \"" + Str_8::FromNum(encId) + "\", does not exist.");
return;
}
Header header = {
EHC::GetVersion(),
encId,
enc->GetVersion(),
GetId(),
NetChannelType::SERVER,
GetVersion(),
nextSendId++,
1,
0,
ensure,
"",
sysId,
opId
};
Util::Copy(header.token, token, 64);
if ((ehc->GetLocalEndpoint().version == IP::V6 && payload.Size() > EHC_IPV6_PAYLOAD) ||
(ehc->GetLocalEndpoint().version == IP::V4 && payload.Size() > EHC_IPV4_PAYLOAD))
{
NetFrag frags = FragmentData(header, payload);
for (UInt_64 i = 0; i < frags.Size(); ++i)
{
Header newHeader = frags.GetHeader();
newHeader.fragment = i;
Send(newHeader, frags[i]);
}
}
else
{
Send(header, payload);
}
}
void NetEnd::Send(const bool deltaLocked, const Str_8 &encName, const bool ensure, const Str_8& sysName,
const Str_8& opName, const Serializer<>& payload)
{
Send(deltaLocked, encName.Hash_64(), ensure, sysName.Hash_64(), opName.Hash_64(), payload);
}
UInt_64 NetEnd::GetNextRecvId() const
{
return nextRecvId;
}
Endpoint NetEnd::GetEndpoint() const
{
return endpoint;
}
float NetEnd::GetDeltaRate() const
{
return deltaRate;
}
float NetEnd::GetTimeout() const
{
return timeout;
}
float NetEnd::GetLastPing() const
{
return lastPing;
}
float NetEnd::GetLatency() const
{
return oldLatency;
}
UInt_64 NetEnd::GetQueueSlot() const
{
return queueSlot;
}
void NetEnd::Poll(const float delta)
{
SortReceived();
if (deltaDuration >= deltaRate)
deltaDuration = Math::Mod(deltaDuration, deltaRate);
deltaDuration += delta;
timeout += delta;
latency += delta;
if (sent.Size())
{
for (UInt_64 i = 0; i < sent.Size(); ++i)
{
sent[i].lastResend += delta;
if (sent[i].lastResend >= owner->GetResendRate())
{
EHC *ehc = owner->GetOwner();
Serializer result(Endianness::LE);
result.Write(sent[i].header);
result.WriteSer(sent[i].payload);
if (sent[i].header.encId)
{
NetEnc *enc = ehc->GetEncryption(sent[i].header.encId);
if (!enc)
{
EHS_LOG_INT(LogType::WARN, 0, "The network encryption with the hash id " +
Str_8::FromNum(sent[i].header.encId) + ", does not exist.");
continue;
}
enc->Encrypt(&result[sizeof(bool)], result.Size() - sizeof(bool));
}
ehc->udp.Send(endpoint, result, result.Size());
sent[i].lastResend = Math::Mod(sent[i].lastResend, owner->GetResendRate());
}
}
}
lastPing += delta;
if (lastPing >= 1.0f)
Ping(delta);
EHS_LOG_SUCCESS();
}
void NetEnd::SetStatus(const NetStatus newStatus)
{
status = newStatus;
}
void NetEnd::RemoveInsurance(const UInt_64 msgId, const UInt_64 fragment)
{
for (UInt_64 i = 0; i < sent.Size(); ++i)
{
if (sent[i].header.id == msgId && sent[i].header.fragment == fragment)
{
sent.Remove(i);
break;
}
}
timeout = 0.0f;
}
void NetEnd::AddReceived(const Header& header, const Serializer<>& payload)
{
NetFrag* frags = nullptr;
for (UInt_64 i = 0; i < received.Size(); ++i)
{
if (received[i].GetHeader().id == header.id)
{
if (received[i][header.fragment].Size())
return;
frags = &received[i];
break;
}
}
if (header.id > nextRecvId)
nextRecvId = header.id + 1;
if (frags)
(*frags)[header.fragment] = payload;
else
received.Push({header, payload});
timeout = 0.0f;
}
Vector<NetFrag>* NetEnd::GetReceived()
{
return &received;
}
void NetEnd::SetDeltaRate(const float newDeltaRate)
{
deltaRate = newDeltaRate;
}
void NetEnd::Ping(const float delta)
{
Serializer payload(Endianness::LE);
payload.Write(delta);
Send(false, true, false, "Internal", "Ping", payload);
lastPing = 0.0f;
latency = 0.0f;
}
void NetEnd::SendLatency()
{
oldLatency = latency * 1000;
Serializer sPayload(Endianness::LE);
sPayload.Write(oldLatency);
Send(false, true, false, "Internal", "Latency", sPayload);
latency = 0.0f;
timeout = 0.0f;
}
void NetEnd::SetLatency(const float newLatency)
{
oldLatency = newLatency;
}
void NetEnd::SetQueueSlot(const UInt_64 slot)
{
queueSlot = slot;
}
NetFrag NetEnd::FragmentData(const Header& header, const Serializer<>& data)
{
NetFrag result;
EHC *ehc = owner->GetOwner();
if (ehc->GetLocalEndpoint().version == IP::V6)
{
UInt_64 frags = data.Size() / EHC_IPV6_PAYLOAD;
if (data.Size() % EHC_IPV6_PAYLOAD)
++frags;
result = NetFrag(header, frags);
UInt_64 size = EHC_IPV6_PAYLOAD;
for (UInt_64 i = 0; i < result.Size(); ++i)
{
size = EHC_IPV6_PAYLOAD;
if (i == result.Size() - 1)
size = data.Size() % EHC_IPV6_PAYLOAD;
result[i] = {data.GetEndianness(), &data[i * EHC_IPV6_PAYLOAD], size};
}
}
else if (ehc->GetLocalEndpoint().version == IP::V4)
{
UInt_64 frags = data.Size() / EHC_IPV4_PAYLOAD;
if (data.Size() % EHC_IPV4_PAYLOAD)
++frags;
result = NetFrag(header, frags);
UInt_64 size = EHC_IPV4_PAYLOAD;
for (UInt_64 i = 0; i < result.Size(); ++i)
{
size = EHC_IPV4_PAYLOAD;
if (i == result.Size() - 1)
size = data.Size() % EHC_IPV4_PAYLOAD;
result[i] = {data.GetEndianness(), &data[i * EHC_IPV4_PAYLOAD], size};
}
}
return result;
}
void NetEnd::Send(const Header& header, const Serializer<UInt_64>& payload)
{
EHC *ehc = owner->GetOwner();
Serializer result(Endianness::LE);
result.Write(header);
result.WriteSer(payload);
if (header.encId)
{
NetEnc *enc = ehc->GetEncryption(header.encId);
if (!enc)
{
EHS_LOG_INT(LogType::WARN, 0, "The network encryption with the hash id " +
Str_8::FromNum(header.encId) + ", does not exist.");
return;
}
enc->Encrypt(&result[sizeof(bool)], result.Size() - sizeof(bool));
}
if (header.ensure)
sent.Push({header, payload});
ehc->udp.Send(endpoint, result, result.Size());
}
bool NetEnd::SortingNeeded() const
{
UInt_64 lastPacket = 0;
for (UInt_64 i = 0; i < received.Size(); ++i)
{
if (received[i].GetHeader().id < lastPacket)
return true;
else
lastPacket = received[i].GetHeader().id;
}
return false;
}
void NetEnd::SortReceived()
{
if (!SortingNeeded())
return;
Vector<NetFrag> sorted(0, received.Stride());
for (UInt_64 a = 0; a < received.Size(); ++a)
{
if (sorted.Size())
{
for (UInt_64 b = sorted.Size(); b; --b)
{
if (received[a].GetHeader().id > sorted[b - 1].GetHeader().id)
{
if (b == sorted.Size())
sorted.Push(received[a]);
else
sorted.Insert(b, received[a]);
break;
}
else
{
sorted.Insert(b - 1, received[a]);
break;
}
}
}
else
{
sorted.Push(received[a]);
}
}
received = sorted;
}
}

View File

@@ -0,0 +1,122 @@
#include "ehs/io/socket/ehc/NetFrag.h"
namespace ehs
{
NetFrag::~NetFrag()
{
delete[] data;
}
NetFrag::NetFrag()
: data(nullptr), size(0)
{
}
NetFrag::NetFrag(const Header &header, const Serializer<UInt_64> &payload)
: header(header), data(new Serializer<UInt_64>[header.fragmentCount]), size(header.fragmentCount)
{
this->header.fragment = 0;
data[header.fragment] = payload;
}
NetFrag::NetFrag(const Header &header, const UInt_64 size)
: header(header), data(new Serializer<UInt_64>[size]), size(size)
{
this->header.fragmentCount = size;
this->header.fragment = 0;
}
NetFrag::NetFrag(NetFrag &&frags) noexcept
: header(frags.header), data(frags.data), size(frags.size)
{
frags.header = {};
frags.data = nullptr;
frags.size = 0;
}
NetFrag::NetFrag(const NetFrag &frags)
: header(frags.header), data(new Serializer<UInt_64>[frags.size]), size(frags.size)
{
for (UInt_64 i = 0; i < size; ++i)
data[i] = frags.data[i];
}
NetFrag &NetFrag::operator=(NetFrag &&frags) noexcept
{
if (this == &frags)
return *this;
header = frags.header;
delete[] data;
data = frags.data;
size = frags.size;
frags.header = {};
frags.data = nullptr;
frags.size = 0;
return *this;
}
NetFrag &NetFrag::operator=(const NetFrag &frags)
{
if (this == &frags)
return *this;
header = frags.header;
delete[] data;
data = new Serializer<UInt_64>[frags.size];
for (UInt_64 i = 0; i < frags.size; ++i)
data[i] = frags.data[i];
size = frags.size;
return *this;
}
NetFrag::operator Serializer<UInt_64> *() const
{
return data;
}
Header NetFrag::GetHeader() const
{
return header;
}
UInt_64 NetFrag::Size() const
{
return size;
}
bool NetFrag::IsComplete() const
{
for (UInt_64 i = 0; i < size; ++i)
if (!data[i].Size())
return false;
return true;
}
Packet NetFrag::Combine() const
{
UInt_64 rSize = 0;
for (UInt_64 i = 0; i < size; ++i)
rSize += data[i].Size();
Packet result =
{
header,
{Endianness::LE, rSize}
};
result.header.fragmentCount = 0;
for (UInt_64 i = 0; i < size; ++i)
result.payload.WriteSer(data[i]);
result.payload.SetOffset(0);
return result;
}
}

View File

@@ -0,0 +1,65 @@
#include "ehs/io/socket/ehc/NetOp.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnd.h"
namespace ehs
{
NetOp::NetOp()
: id(0)
{
}
NetOp::NetOp(Str_8 name)
: id(name.Hash_64()), name((Str_8 &&)name)
{
}
NetOp::NetOp(NetOp&& op) noexcept
: id(op.id), name((Str_8 &&)op.name)
{
op.id = 0;
}
NetOp::NetOp(const NetOp &op)
: id(op.id), name(op.name)
{
}
NetOp& NetOp::operator=(NetOp&& op) noexcept
{
if (this == &op)
return *this;
id = op.id;
name = (Str_8 &&)op.name;
op.id = 0;
return *this;
}
NetOp &NetOp::operator=(const NetOp &op)
{
if (this == &op)
return *this;
id = op.id;
name = op.name;
return *this;
}
UInt_64 NetOp::GetId() const
{
return id;
}
Str_8 NetOp::GetName() const
{
return name;
}
void NetOp::Execute(NetChannel *channel, NetEnd *endpoint, NetSys *sys, Serializer<UInt_64> &payload)
{
}
}

View File

@@ -0,0 +1,602 @@
#include "ehs/io/socket/ehc/NetServerCh.h"
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetSys.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/PRNG.h"
namespace ehs
{
NetServerCh::~NetServerCh()
{
Shutdown();
}
NetServerCh::NetServerCh()
: maxEndpoints(0)
{
}
NetServerCh::NetServerCh(Str_8 name, const Version &version, const UInt_64 maxEndpoints)
: NetChannel((Str_8 &&)name, version), maxEndpoints(maxEndpoints)
{
}
NetServerCh::NetServerCh(NetServerCh &&server) noexcept
: NetChannel((NetChannel &&)server), endpoints((Vector<NetEnd *> &&)server.endpoints), maxEndpoints(server.maxEndpoints)
{
for (UInt_64 i = 0; i < endpoints.Size(); i++)
endpoints[i]->owner = this;
}
NetServerCh::NetServerCh(const NetServerCh &server)
: NetChannel(server), maxEndpoints(server.maxEndpoints)
{
}
NetServerCh &NetServerCh::operator=(NetServerCh &&server) noexcept
{
if (this == &server)
return *this;
NetChannel::operator=((NetChannel &&)server);
Shutdown();
endpoints = (Vector<NetEnd *> &&)server.endpoints;
for (UInt_64 i = 0; i < endpoints.Size(); i++)
endpoints[i]->owner = this;
maxEndpoints = server.maxEndpoints;
server.maxEndpoints = 0;
return *this;
}
NetServerCh &NetServerCh::operator=(const NetServerCh &server)
{
if (this == &server)
return *this;
NetChannel::operator=(server);
Shutdown();
endpoints = {};
maxEndpoints = server.maxEndpoints;
return *this;
}
bool NetServerCh::OnEndpointConnect(NetEnd *endpoint, Serializer<UInt_64> payload)
{
return true;
}
Serializer<UInt_64> NetServerCh::OnEndpointAccepted(NetEnd *endpoint)
{
return {};
}
void NetServerCh::OnEndpointDisconnect(NetEnd *endpoint, Serializer<UInt_64> payload)
{
}
void NetServerCh::OnEndpointTimeout(NetEnd *endpoint)
{
}
void NetServerCh::OnEndpointActive(NetEnd *endpoint)
{
}
Serializer<UInt_64> NetServerCh::OnShutdown()
{
return {};
}
Serializer<UInt_64> OnShutdown()
{
return {};
}
void NetServerCh::Broadcast(const NetStatus endStatus, const bool deltaLocked, const UInt_64 encHashId,
const bool ensure, const UInt_64 sysHashId, const UInt_64 opHashId, const Serializer<UInt_64> &payload)
{
if (!GetOwner()->udp.IsValid())
return;
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetStatus() == endStatus)
endpoints[i]->Send(deltaLocked, encHashId, ensure, sysHashId, opHashId, payload);
}
void NetServerCh::Broadcast(const NetStatus endStatus, const bool deltaLocked, const Str_8 &encId, const bool ensure,
const Str_8 &sysId, const Str_8 &opId,
const Serializer<UInt_64> &payload)
{
Broadcast(endStatus, deltaLocked, encId.Hash_64(), ensure, sysId.Hash_64(), opId.Hash_64(), payload);
}
bool NetServerCh::HasEndpoint(const NetStatus endStatus, const Char_8 token[64]) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() != endStatus)
continue;
if (Util::Compare(endpoints[i]->token, token, 64))
return true;
}
return false;
}
bool NetServerCh::HasEndpoint(const NetStatus endStatus, const UInt_64 hashName) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() != endStatus)
continue;
if (endpoints[i]->GetId() == hashName)
return true;
}
return false;
}
bool NetServerCh::HasEndpoint(const NetStatus endStatus, const Str_8 &id) const
{
return HasEndpoint(endStatus, id.Hash_64());
}
bool NetServerCh::HasEndpoint(const Char_8 token[64]) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (Util::Compare(endpoints[i]->token, token, 64))
return true;
return false;
}
bool NetServerCh::HasEndpoint(const UInt_64 hashName) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetId() == hashName)
return true;
return false;
}
bool NetServerCh::HasEndpoint(const Str_8 &id) const
{
return HasEndpoint(id.Hash_64());
}
bool NetServerCh::HasEndpoint(const Endpoint &endpoint) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port)
return true;
return false;
}
NetEnd* NetServerCh::GetEndpoint(const NetStatus endStatus, const Char_8 token[64]) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() != endStatus)
continue;
if (Util::Compare(endpoints[i]->token, token, 64))
return endpoints[i];
}
return nullptr;
}
NetEnd *NetServerCh::GetEndpoint(const NetStatus endStatus, const UInt_64 hashName) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() != endStatus)
continue;
if (endpoints[i]->GetId() == hashName)
return endpoints[i];
}
return nullptr;
}
NetEnd *NetServerCh::GetEndpoint(const NetStatus endStatus, const Str_8 &id) const
{
return GetEndpoint(endStatus, id.Hash_64());
}
NetEnd *NetServerCh::GetEndpoint(const Char_8 token[64]) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (Util::Compare(endpoints[i]->token, token, 64))
return endpoints[i];
return nullptr;
}
NetEnd *NetServerCh::GetEndpoint(const UInt_64 hashName) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetId() == hashName)
return endpoints[i];
return nullptr;
}
NetEnd *NetServerCh::GetEndpoint(const Str_8 &id) const
{
return GetEndpoint(id.Hash_64());
}
NetEnd *NetServerCh::GetEndpoint(const Endpoint &endpoint) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port)
return endpoints[i];
return nullptr;
}
Array<NetEnd *> NetServerCh::GetEndpoints(const NetStatus endStatus)
{
Array<NetEnd*> result(endpoints.Size());
UInt_64 count = 0;
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetStatus() == endStatus)
result[count++] = endpoints[i];
result.Resize(count);
return result;
}
UInt_64 NetServerCh::GetEndpointsCount(const NetStatus endStatus)
{
UInt_64 count = 0;
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetStatus() == endStatus)
++count;
return count;
}
UInt_64 NetServerCh::GetMaxEndpoints() const
{
return maxEndpoints;
}
void NetServerCh::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload)
{
if (header.channelVer != GetVersion())
return;
if (!header.ensure && !header.token[0] && header.systemId == internalSys && header.opId == connectOp)
{
NetEnd* end = new NetEnd(payload.ReadStr(), endpoint);
end->owner = this;
GenerateToken(end->token);
end->SetStatus(NetStatus::PENDING);
Serializer sPayload(Endianness::LE);
if (!OnEndpointConnect(end, {Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}))
{
sPayload.WriteStr<Char_8, UInt_64>("Connection rejected.");
end->Send(false, true, false, internalSys, rejectedOp, sPayload);
return;
}
endpoints.Push(end);
UInt_64 active = GetEndpointsCount(NetStatus::ACTIVE);
if (maxEndpoints && active >= maxEndpoints)
{
end->SetStatus(NetStatus::QUEUED);
UpdateQueue(active);
sPayload.Write(NetStatus::QUEUED);
sPayload.Write(end->GetQueueSlot());
}
else
{
end->SetStatus(NetStatus::ACTIVE);
OnEndpointActive(end);
sPayload.Write(NetStatus::ACTIVE);
sPayload.Write(0);
}
sPayload.WriteSer(OnEndpointAccepted(end));
end->Send(false, 0, false, internalSys, connectedOp, sPayload);
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == disconnectOp)
{
NetEnd* end = GetEndpoint(header.token);
if (!end)
return;
end->Send(false, 0, false, internalSys, disconnectedOp, {});
OnEndpointDisconnect(end, {Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
RemoveEndpoint(end->token);
UpdateQueue();
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == pongOp)
{
NetEnd* end = GetEndpoint(header.token);
if (!end)
return;
end->SetDeltaRate(payload.Read<float>());
end->SendLatency();
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == receivedOp)
{
NetEnd* end = GetEndpoint(header.token);
if (!end)
return;
const UInt_64 msgId = payload.Read<UInt_64>();
const UInt_64 fragment = payload.Read<UInt_64>();
end->RemoveInsurance(msgId, fragment);
}
else if (header.token[0])
{
NetEnd* end = GetEndpoint(header.token);
if (!end)
return;
if (IsDropPacketsEnabled() && !header.ensure && header.id < end->GetNextRecvId())
{
EHS_LOG_INT(LogType::INFO, 6, "Old packet intentionally dropped.");
return;
}
if (header.ensure)
{
Serializer sPayload(Endianness::LE);
sPayload.Write(header.id);
sPayload.Write(header.fragment);
end->Send(false, 0, false, internalSys, receivedOp, sPayload);
}
end->AddReceived(
header,
Serializer<>(Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset())
);
}
else
{
EHS_LOG_INT(LogType::INFO, 7, "Corrupted packet.");
}
}
void NetServerCh::GenerateToken(Char_8 in[64])
{
PRNG_u64 rng(CPU::GetTSC());
for (UInt_64 i = 0; i < 8; ++i)
{
do
((UInt_64*)in)[i] = rng.Generate();
while (!i && ((UInt_64*)in)[i] == 0);
}
if (HasEndpoint(in))
GenerateToken(in);
}
void NetServerCh::UpdateQueue(UInt_64 active)
{
UInt_64 slot = 0;
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() == NetStatus::QUEUED)
{
if (active < maxEndpoints)
{
endpoints[i]->SetStatus(NetStatus::ACTIVE);
endpoints[i]->SetQueueSlot(0);
Serializer payload(Endianness::LE);
payload.Write(NetStatus::ACTIVE);
payload.Write(0);
endpoints[i]->Send(false, true, false, internalSys, statusUpdateOp, payload);
OnEndpointActive(endpoints[i]);
++active;
}
else
{
if (endpoints[i]->GetQueueSlot() != slot)
{
Serializer payload(Endianness::LE);
payload.Write(NetStatus::QUEUED);
payload.Write(slot);
endpoints[i]->Send(false, true, false, internalSys, statusUpdateOp, payload);
endpoints[i]->SetQueueSlot(slot++);
}
else
{
++slot;
}
}
}
}
}
void NetServerCh::UpdateQueue()
{
UpdateQueue(GetEndpointsCount(NetStatus::ACTIVE));
}
bool NetServerCh::RemoveEndpoint(const Char_8 token[64])
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (Util::Compare(endpoints[i]->token, token, 64))
{
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
return true;
}
}
return false;
}
bool NetServerCh::RemoveEndpoint(const Endpoint &endpoint)
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port)
{
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
return true;
}
}
return false;
}
bool NetServerCh::RemoveEndpoint(const NetEnd* const end)
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i] == end)
{
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
return true;
}
}
return false;
}
void NetServerCh::Poll(const float &delta)
{
UInt_64 i = 0;
while (i < endpoints.Size())
{
endpoints[i]->Poll(delta);
if (endpoints[i]->GetStatus() == NetStatus::PENDING)
{
if (endpoints[i]->GetTimeout() >= GetMaxTimeout())
{
OnEndpointTimeout(endpoints[i]);
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
continue;
}
}
else
{
if (endpoints[i]->GetTimeout() >= GetMaxTimeout())
{
OnEndpointTimeout(endpoints[i]);
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
UpdateQueue();
continue;
}
Vector<NetFrag>* frags = endpoints[i]->GetReceived();
UInt_64 f = 0;
while (f < frags->Size())
{
if (!(*frags)[f].IsComplete())
{
++f;
continue;
}
Packet packet = (*frags)[f].Combine();
NetSys* sys = GetSystem(packet.header.systemId);
if (!sys)
{
++f;
continue;
}
sys->Execute(this, endpoints[i], packet.header.opId, packet.payload);
frags->Swap(f, frags->End());
frags->Pop();
}
}
++i;
}
}
void NetServerCh::Shutdown()
{
Serializer<UInt_64> payload = OnShutdown();
for (UInt_64 i = 0; i < endpoints.Size(); i++)
{
endpoints[i]->Send(false, 0, false, internalSys, disconnectOp, payload);
delete endpoints[i];
}
}
}

View File

@@ -0,0 +1,106 @@
#include "ehs/io/socket/ehc/NetSys.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetOp.h"
#include "ehs/io/socket/ehc/NetChannel.h"
namespace ehs
{
NetSys::~NetSys()
{
for (UInt_64 i = 0; i < ops.Size(); ++i)
delete ops[i];
ops.Clear();
}
NetSys::NetSys()
: id(0)
{
}
NetSys::NetSys(Str_8 name)
: id(name.Hash_64()), name((Str_8&&)name)
{
}
NetSys::NetSys(NetSys&& sys) noexcept
: id(sys.id), name((Str_8&&)sys.name), ops((Array<NetOp*>&&)sys.ops)
{
sys.id = 0;
}
NetSys::NetSys(const NetSys& sys)
: id(sys.id), name(sys.name)
{
}
NetSys& NetSys::operator=(NetSys&& sys) noexcept
{
if (this == &sys)
return *this;
id = sys.id;
name = (Str_8&&)sys.name;
ops = (Array<NetOp*>&&)sys.ops;
sys.id = 0;
return *this;
}
NetSys& NetSys::operator=(const NetSys& sys)
{
if (this == &sys)
return *this;
id = sys.id;
name = sys.name;
ops = Array<NetOp*>();
return *this;
}
UInt_64 NetSys::GetId() const
{
return id;
}
Str_8 NetSys::GetName() const
{
return name;
}
bool NetSys::HasOperation(const UInt_64 id) const
{
for (UInt_64 i = 0; i < ops.Size(); ++i)
if (ops[i]->GetId() == id)
return true;
return false;
}
bool NetSys::AddOperation(NetOp* op)
{
if (HasOperation(op->GetId()))
return false;
ops.Push(op);
return true;
}
void NetSys::Execute(NetChannel *channel, NetEnd *endpoint, const UInt_64 hashId, Serializer<UInt_64> &payload)
{
for (UInt_64 i = 0; i < ops.Size(); ++i)
{
if (ops[i]->GetId() == hashId)
{
ops[i]->Execute(channel, endpoint, this, payload);
return;
}
}
EHS_LOG_INT(LogType::INFO, 0, "System not found.");
}
}

View File

@@ -0,0 +1,44 @@
#include "ehs/io/socket/ehc/NetUtils.h"
namespace ehs
{
void WriteHeader(const Header &header, Serializer<UInt_64> &data)
{
data.WriteVersion(header.version);
data.Write(header.encId);
data.WriteVersion(header.encVer);
data.Write(header.channelId);
data.Write(header.channelType);
data.WriteVersion(header.channelVer);
data.Write(header.id);
data.Write(header.fragmentCount);
data.Write(header.fragment);
data.Write(header.ensure);
data.WriteArray(header.token, 64);
data.Write(header.systemId);
data.Write(header.opId);
}
Header ReadHeader(Serializer<UInt_64> &data)
{
Header header = {};
header.version = data.ReadVersion();
header.encId = data.Read<UInt_64>();
header.encVer = data.ReadVersion();
header.channelId = data.Read<UInt_64>();
header.channelType = data.Read<NetChannelType>();
header.channelVer = data.ReadVersion();
header.id = data.Read<UInt_64>();
header.fragmentCount = data.Read<UInt_64>();
header.fragment = data.Read<UInt_64>();
header.ensure = data.Read<bool>();
UInt_64 tokenSize = sizeof(header.token) / sizeof(Char_8);
data.ReadArray<Char_8, UInt_64>(header.token, &tokenSize);
header.systemId = data.Read<UInt_64>();
header.opId = data.Read<UInt_64>();
return header;
}
}

View File

@@ -18,7 +18,7 @@ namespace ehs
} }
Spotify::Spotify(Str_8 clientId, Str_8 secret, Str_8 redURI, Array<Str_8> scopes, const bool forceVerify) Spotify::Spotify(Str_8 clientId, Str_8 secret, Str_8 redURI, Array<Str_8> scopes, const bool forceVerify)
: client(AddrType::IPV4), clientId((Str_8 &&)clientId), secret((Str_8 &&)secret), redURI((Str_8 &&)redURI), : client(IP::V4), clientId((Str_8 &&)clientId), secret((Str_8 &&)secret), redURI((Str_8 &&)redURI),
scopes((Array<Str_8> &&)scopes), forceVerify(forceVerify) scopes((Array<Str_8> &&)scopes), forceVerify(forceVerify)
{ {
} }
@@ -41,7 +41,7 @@ namespace ehs
"&response_type=code&show_dialog=" + (forceVerify ? "true" : "false") + "&scope=" + "&response_type=code&show_dialog=" + (forceVerify ? "true" : "false") + "&scope=" +
scopesFinal; scopesFinal;
TCP server(AddrType::IPV4); TCP server(IP::V4);
server.Initialize(); server.Initialize();
server.Bind("", 65534); server.Bind("", 65534);
server.Listen(); server.Listen();
@@ -73,7 +73,7 @@ namespace ehs
server.Release(); server.Release();
SSL accounts(AddrType::IPV4); SSL accounts(IP::V4);
accounts.Initialize(); accounts.Initialize();
accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port); accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port);
@@ -588,7 +588,7 @@ namespace ehs
bool Spotify::ReAuthorize() bool Spotify::ReAuthorize()
{ {
SSL accounts(AddrType::IPV4); SSL accounts(IP::V4);
accounts.Initialize(); accounts.Initialize();
accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port); accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port);

View File

@@ -16,7 +16,7 @@ namespace ehs
} }
Twitch::Twitch(const Str_8& clientId, const Str_8& secret, const Str_8& redURI, const Array<Str_8>& scopes, const bool forceVerify) Twitch::Twitch(const Str_8& clientId, const Str_8& secret, const Str_8& redURI, const Array<Str_8>& scopes, const bool forceVerify)
: client(AddrType::IPV4), clientId(clientId), secret(secret), redURI(redURI), scopes(scopes), forceVerify(forceVerify) : client(IP::V4), clientId(clientId), secret(secret), redURI(redURI), scopes(scopes), forceVerify(forceVerify)
{ {
} }
@@ -38,7 +38,7 @@ namespace ehs
"&response_type=code&force_verify=" + (forceVerify ? "true" : "false") + "&scope=" + "&response_type=code&force_verify=" + (forceVerify ? "true" : "false") + "&scope=" +
scopesFinal; scopesFinal;
TCP server(AddrType::IPV4); TCP server(IP::V4);
server.Bind("", 65535); server.Bind("", 65535);
server.Listen(); server.Listen();

View File

@@ -53,7 +53,7 @@ namespace ehs
if (initialized) if (initialized)
return; return;
client = TCP(ehs::AddrType::IPV4); client = TCP(ehs::IP::V4);
client.Connect(DNS::Resolve("irc.chat.twitch.tv"), 6667); client.Connect(DNS::Resolve("irc.chat.twitch.tv"), 6667);
client.SetBlocking(false); client.SetBlocking(false);

View File

@@ -13,55 +13,55 @@ namespace ehs
{ {
} }
Json::Json(const JsonBase& value) Json::Json(const JsonBase &value)
: value(new JsonBase(value)) : value(new JsonBase(value))
{ {
} }
Json::Json(const JsonObj& value) Json::Json(const JsonObj &value)
: value((JsonBase*)new JsonObj(value)) : value((JsonBase *)new JsonObj(value))
{ {
} }
Json::Json(const JsonArray& value) Json::Json(const JsonArray &value)
: value((JsonBase*)new JsonArray(value)) : value((JsonBase *)new JsonArray(value))
{ {
} }
Json::Json(const JsonBool& value) Json::Json(const JsonBool &value)
: value((JsonBase*)new JsonBool(value)) : value((JsonBase*)new JsonBool(value))
{ {
} }
Json::Json(const JsonNum& value) Json::Json(const JsonNum &value)
: value((JsonBase*)new JsonNum(value)) : value((JsonBase *)new JsonNum(value))
{ {
} }
Json::Json(const JsonStr& value) Json::Json(const JsonStr &value)
: value((JsonBase*)new JsonStr(value)) : value((JsonBase *)new JsonStr(value))
{ {
} }
Json::Json(const char* data, const UInt_64 size, const UInt_64 extra) Json::Json(const char *data, const UInt_64 size, const UInt_64 extra)
: value(nullptr) : value(nullptr)
{ {
Parse({data, size}, extra); Parse({data, size}, extra);
} }
Json::Json(const Str_8& data, const UInt_64 extra) Json::Json(const Str_8 &data, const UInt_64 extra)
: value(nullptr) : value(nullptr)
{ {
Parse(data, extra); Parse(data, extra);
} }
Json::Json(Json&& json) noexcept Json::Json(Json &&json) noexcept
: value(json.value) : value(json.value)
{ {
json.value = nullptr; json.value = nullptr;
} }
Json::Json(const Json& json) Json::Json(const Json &json)
: value(nullptr) : value(nullptr)
{ {
if (!json.value) if (!json.value)
@@ -70,19 +70,19 @@ namespace ehs
switch (json.value->GetType()) switch (json.value->GetType())
{ {
case JsonType::OBJ: case JsonType::OBJ:
value = (JsonBase*)new JsonObj(*(JsonObj*)json.value); value = (JsonBase *)new JsonObj(*(JsonObj *)json.value);
break; break;
case JsonType::ARRAY: case JsonType::ARRAY:
value = (JsonBase*)new JsonArray(*(JsonArray*)json.value); value = (JsonBase *)new JsonArray(*(JsonArray *)json.value);
break; break;
case JsonType::BOOL: case JsonType::BOOL:
value = (JsonBase*)new JsonBool(*(JsonBool*)json.value); value = (JsonBase *)new JsonBool(*(JsonBool *)json.value);
break; break;
case JsonType::NUM: case JsonType::NUM:
value = (JsonBase*)new JsonNum(*(JsonNum*)json.value); value = (JsonBase *)new JsonNum(*(JsonNum *)json.value);
break; break;
case JsonType::STR: case JsonType::STR:
value = (JsonBase*)new JsonStr(*(JsonStr*)json.value); value = (JsonBase *)new JsonStr(*(JsonStr *)json.value);
break; break;
default: default:
value = new JsonBase(); value = new JsonBase();
@@ -90,7 +90,7 @@ namespace ehs
} }
} }
Json& Json::operator=(Json&& json) noexcept Json& Json::operator=(Json &&json) noexcept
{ {
if (this == &json) if (this == &json)
return *this; return *this;
@@ -103,7 +103,7 @@ namespace ehs
return *this; return *this;
} }
Json& Json::operator=(const Json& json) Json& Json::operator=(const Json &json)
{ {
if (this == &json) if (this == &json)
return *this; return *this;
@@ -117,19 +117,19 @@ namespace ehs
switch (json.value->GetType()) switch (json.value->GetType())
{ {
case JsonType::OBJ: case JsonType::OBJ:
value = (JsonBase*)new JsonObj(*(JsonObj*)json.value); value = (JsonBase *)new JsonObj(*(JsonObj *)json.value);
break; break;
case JsonType::ARRAY: case JsonType::ARRAY:
value = (JsonBase*)new JsonArray(*(JsonArray*)json.value); value = (JsonBase *)new JsonArray(*(JsonArray *)json.value);
break; break;
case JsonType::BOOL: case JsonType::BOOL:
value = (JsonBase*)new JsonBool(*(JsonBool*)json.value); value = (JsonBase *)new JsonBool(*(JsonBool *)json.value);
break; break;
case JsonType::NUM: case JsonType::NUM:
value = (JsonBase*)new JsonNum(*(JsonNum*)json.value); value = (JsonBase *)new JsonNum(*(JsonNum *)json.value);
break; break;
case JsonType::STR: case JsonType::STR:
value = (JsonBase*)new JsonStr(*(JsonStr*)json.value); value = (JsonBase *)new JsonStr(*(JsonStr *)json.value);
break; break;
default: default:
value = new JsonBase(); value = new JsonBase();
@@ -139,12 +139,12 @@ namespace ehs
return *this; return *this;
} }
JsonBase* Json::GetValue() JsonBase *Json::GetValue()
{ {
return value; return value;
} }
JsonBase* Json::RetrieveValue(const Str_8& access) JsonBase *Json::RetrieveValue(const Str_8 &access)
{ {
if (!value || !access.Size()) if (!value || !access.Size())
return nullptr; return nullptr;
@@ -192,8 +192,8 @@ namespace ehs
Vector<Str_8> Json::ParseAccess(const Str_8& access) Vector<Str_8> Json::ParseAccess(const Str_8& access)
{ {
bool isIndex = false; bool isIndex = false;
const Char_8* start = &access[0]; const Char_8 *start = &access[0];
const Char_8* end = &access[access.Size() - 1]; const Char_8 *end = &access[access.Size() - 1];
Vector<Str_8> levels(0, 5); Vector<Str_8> levels(0, 5);
@@ -251,7 +251,7 @@ namespace ehs
return levels; return levels;
} }
void Json::ParseValue(JsonVar* var, const Char_8** begin, const Char_8* end, const UInt_64 extra) void Json::ParseValue(JsonVar *var, const Char_8 **begin, const Char_8 *end, const UInt_64 extra)
{ {
const Char_8* start = nullptr; const Char_8* start = nullptr;
bool isStr = false; bool isStr = false;
@@ -263,7 +263,7 @@ namespace ehs
if (start) if (start)
{ {
if (*begin - start) if (*begin - start)
((JsonStr*)var->GetValue())->value = Str_8(start, *begin - start); ((JsonStr *)var->GetValue())->value = Str_8(start, *begin - start);
++(*begin); ++(*begin);
return; return;
@@ -312,11 +312,11 @@ namespace ehs
} }
} }
JsonVar Json::ParseVar(const Char_8** begin, const Char_8* end, const UInt_64 extra) JsonVar Json::ParseVar(const Char_8 **begin, const Char_8 *end, const UInt_64 extra)
{ {
JsonVar var; JsonVar var;
const Char_8* start = nullptr; const Char_8 *start = nullptr;
for (; *begin <= end; ++(*begin)) for (; *begin <= end; ++(*begin))
{ {
@@ -351,7 +351,7 @@ namespace ehs
return var; return var;
} }
void Json::ParseObject(JsonObj* obj, const Char_8** begin, const Char_8* end, const UInt_64 extra) void Json::ParseObject(JsonObj *obj, const Char_8 **begin, const Char_8 *end, const UInt_64 extra)
{ {
JsonVar var; JsonVar var;
do do
@@ -361,9 +361,9 @@ namespace ehs
while(obj->AddVar(var)); while(obj->AddVar(var));
} }
void Json::ParseArray(JsonArray* arr, const Char_8** begin, const Char_8* end, const UInt_64 extra) void Json::ParseArray(JsonArray *arr, const Char_8 **begin, const Char_8 *end, const UInt_64 extra)
{ {
const Char_8* start = nullptr; const Char_8 *start = nullptr;
for (; *begin <= end; ++(*begin)) for (; *begin <= end; ++(*begin))
{ {
@@ -423,12 +423,12 @@ namespace ehs
} }
} }
void Json::Parse(const Str_8& data, const UInt_64 extra) void Json::Parse(const Str_8 &data, const UInt_64 extra)
{ {
const Char_8* start = nullptr; const Char_8 *start = nullptr;
const Char_8* end = &data[data.Size() - 1]; const Char_8 *end = &data[data.Size() - 1];
for (const Char_8* i = &data[0]; i <= end; ++i) for (const Char_8 *i = &data[0]; i <= end; ++i)
{ {
if (*i == '}' || *i == ']') if (*i == '}' || *i == ']')
{ {

View File

@@ -29,7 +29,7 @@ namespace ehs
{ {
} }
JsonArray::JsonArray(JsonArray&& ja) noexcept JsonArray::JsonArray(JsonArray &&ja) noexcept
: JsonBase(ja), size(ja.size), extra(ja.extra), rawSize(ja.rawSize), data(ja.data) : JsonBase(ja), size(ja.size), extra(ja.extra), rawSize(ja.rawSize), data(ja.data)
{ {
ja.size = 0; ja.size = 0;
@@ -38,7 +38,7 @@ namespace ehs
ja.data = nullptr; ja.data = nullptr;
} }
JsonArray::JsonArray(const JsonArray& ja) JsonArray::JsonArray(const JsonArray &ja)
: JsonBase(ja), size(ja.size), extra(ja.extra), rawSize(ja.rawSize), data(new JsonBase*[ja.rawSize]) : JsonBase(ja), size(ja.size), extra(ja.extra), rawSize(ja.rawSize), data(new JsonBase*[ja.rawSize])
{ {
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
@@ -46,19 +46,19 @@ namespace ehs
switch (ja.data[i]->GetType()) switch (ja.data[i]->GetType())
{ {
case JsonType::OBJ: case JsonType::OBJ:
data[i] = (JsonBase*)new JsonObj(*(JsonObj*)ja.data[i]); data[i] = (JsonBase *)new JsonObj(*(JsonObj *)ja.data[i]);
break; break;
case JsonType::ARRAY: case JsonType::ARRAY:
data[i] = (JsonBase*)new JsonArray(*(JsonArray*)ja.data[i]); data[i] = (JsonBase *)new JsonArray(*(JsonArray *)ja.data[i]);
break; break;
case JsonType::BOOL: case JsonType::BOOL:
data[i] = (JsonBase*)new JsonBool(*(JsonBool*)ja.data[i]); data[i] = (JsonBase *)new JsonBool(*(JsonBool *)ja.data[i]);
break; break;
case JsonType::NUM: case JsonType::NUM:
data[i] = (JsonBase*)new JsonNum(*(JsonNum*)ja.data[i]); data[i] = (JsonBase *)new JsonNum(*(JsonNum *)ja.data[i]);
break; break;
case JsonType::STR: case JsonType::STR:
data[i] = (JsonBase*)new JsonStr(*(JsonStr*)ja.data[i]); data[i] = (JsonBase *)new JsonStr(*(JsonStr *)ja.data[i]);
break; break;
default: default:
data[i] = new JsonBase(); data[i] = new JsonBase();
@@ -67,7 +67,7 @@ namespace ehs
} }
} }
JsonArray& JsonArray::operator=(JsonArray&& ja) noexcept JsonArray &JsonArray::operator=(JsonArray &&ja) noexcept
{ {
if (this == &ja) if (this == &ja)
return *this; return *this;
@@ -88,7 +88,7 @@ namespace ehs
return *this; return *this;
} }
JsonArray& JsonArray::operator=(const JsonArray& ja) JsonArray &JsonArray::operator=(const JsonArray &ja)
{ {
if (this == &ja) if (this == &ja)
return *this; return *this;
@@ -134,7 +134,7 @@ namespace ehs
return data; return data;
} }
JsonArray::operator JsonBase**() JsonArray::operator JsonBase **()
{ {
return data; return data;
} }
@@ -154,12 +154,12 @@ namespace ehs
return size; return size;
} }
void JsonArray::Insert(const UInt_64 index, const JsonBase* const value) void JsonArray::Insert(const UInt_64 index, const JsonBase * const value)
{ {
if (size + 1 >= rawSize) if (size + 1 >= rawSize)
rawSize = size + extra; rawSize = size + extra;
JsonBase** result = new JsonBase*[rawSize]; JsonBase **result = new JsonBase*[rawSize];
for (UInt_64 i = 0; i < index; ++i) for (UInt_64 i = 0; i < index; ++i)
result[i] = data[i]; result[i] = data[i];
@@ -195,12 +195,12 @@ namespace ehs
++size; ++size;
} }
void JsonArray::Push(const JsonBase* const value) void JsonArray::Push(const JsonBase * const value)
{ {
if (size + 1 > rawSize) if (size + 1 > rawSize)
{ {
rawSize = size + extra + 1; rawSize = size + extra + 1;
JsonBase** result = new JsonBase*[rawSize]; JsonBase **result = new JsonBase*[rawSize];
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
@@ -257,12 +257,12 @@ namespace ehs
} }
} }
void JsonArray::Push(const JsonBase& value) void JsonArray::Push(const JsonBase &value)
{ {
if (size + 1 > rawSize) if (size + 1 > rawSize)
{ {
rawSize = size + extra + 1; rawSize = size + extra + 1;
JsonBase** result = new JsonBase*[rawSize]; JsonBase **result = new JsonBase*[rawSize];
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
@@ -279,17 +279,17 @@ namespace ehs
} }
} }
void JsonArray::Push(const JsonObj& value) void JsonArray::Push(const JsonObj &value)
{ {
if (size + 1 > rawSize) if (size + 1 > rawSize)
{ {
rawSize = size + extra + 1; rawSize = size + extra + 1;
JsonBase** result = new JsonBase*[rawSize]; JsonBase **result = new JsonBase*[rawSize];
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
result[size++] = (JsonBase*)new JsonObj(value); result[size++] = (JsonBase *)new JsonObj(value);
delete[] data; delete[] data;
@@ -297,11 +297,11 @@ namespace ehs
} }
else else
{ {
data[size++] = (JsonBase*)new JsonObj(value); data[size++] = (JsonBase *)new JsonObj(value);
} }
} }
void JsonArray::Push(const JsonArray& value) void JsonArray::Push(const JsonArray &value)
{ {
if (size + 1 > rawSize) if (size + 1 > rawSize)
{ {
@@ -311,7 +311,7 @@ namespace ehs
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
result[size++] = (JsonBase*)new JsonArray(value); result[size++] = (JsonBase *)new JsonArray(value);
delete[] data; delete[] data;
@@ -319,11 +319,11 @@ namespace ehs
} }
else else
{ {
data[size++] = (JsonBase*)new JsonArray(value); data[size++] = (JsonBase *)new JsonArray(value);
} }
} }
void JsonArray::Push(const JsonBool& value) void JsonArray::Push(const JsonBool &value)
{ {
if (size + 1 > rawSize) if (size + 1 > rawSize)
{ {
@@ -333,7 +333,7 @@ namespace ehs
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
result[size++] = (JsonBase*)new JsonBool(value); result[size++] = (JsonBase *)new JsonBool(value);
delete[] data; delete[] data;
@@ -341,7 +341,7 @@ namespace ehs
} }
else else
{ {
data[size++] = (JsonBase*)new JsonBool(value); data[size++] = (JsonBase *)new JsonBool(value);
} }
} }
@@ -355,7 +355,7 @@ namespace ehs
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
result[size++] = (JsonBase*)new JsonBool(value); result[size++] = (JsonBase *)new JsonBool(value);
delete[] data; delete[] data;
@@ -363,21 +363,21 @@ namespace ehs
} }
else else
{ {
data[size++] = (JsonBase*)new JsonBool(value); data[size++] = (JsonBase *)new JsonBool(value);
} }
} }
void JsonArray::Push(const JsonNum& value) void JsonArray::Push(const JsonNum &value)
{ {
if (size + 1 > rawSize) if (size + 1 > rawSize)
{ {
rawSize = size + extra + 1; rawSize = size + extra + 1;
JsonBase** result = new JsonBase*[rawSize]; JsonBase **result = new JsonBase*[rawSize];
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
result[size++] = (JsonBase*)new JsonNum(value); result[size++] = (JsonBase *)new JsonNum(value);
delete[] data; delete[] data;
@@ -385,7 +385,7 @@ namespace ehs
} }
else else
{ {
data[size++] = (JsonBase*)new JsonNum(value); data[size++] = (JsonBase *)new JsonNum(value);
} }
} }
@@ -394,12 +394,12 @@ namespace ehs
if (size + 1 > rawSize) if (size + 1 > rawSize)
{ {
rawSize = size + extra + 1; rawSize = size + extra + 1;
JsonBase** result = new JsonBase*[rawSize]; JsonBase **result = new JsonBase*[rawSize];
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
result[size++] = (JsonBase*)new JsonNum(value); result[size++] = (JsonBase *)new JsonNum(value);
delete[] data; delete[] data;
@@ -407,11 +407,11 @@ namespace ehs
} }
else else
{ {
data[size++] = (JsonBase*)new JsonNum(value); data[size++] = (JsonBase *)new JsonNum(value);
} }
} }
void JsonArray::Push(const JsonStr& value) void JsonArray::Push(const JsonStr &value)
{ {
if (size + 1 > rawSize) if (size + 1 > rawSize)
{ {
@@ -421,7 +421,7 @@ namespace ehs
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];
result[size++] = (JsonBase*)new JsonStr(value); result[size++] = (JsonBase *)new JsonStr(value);
delete[] data; delete[] data;
@@ -429,11 +429,11 @@ namespace ehs
} }
else else
{ {
data[size++] = (JsonBase*)new JsonStr(value); data[size++] = (JsonBase *)new JsonStr(value);
} }
} }
void JsonArray::Push(const Char_8* value, const UInt_64 size) void JsonArray::Push(const Char_8 *value, const UInt_64 size)
{ {
if (this->size + 1 > rawSize) if (this->size + 1 > rawSize)
{ {
@@ -443,7 +443,7 @@ namespace ehs
for (UInt_64 i = 0; i < this->size; ++i) for (UInt_64 i = 0; i < this->size; ++i)
result[i] = data[i]; result[i] = data[i];
result[this->size++] = (JsonBase*)new JsonStr(Str_8(value, size)); result[this->size++] = (JsonBase *)new JsonStr(Str_8(value, size));
delete[] data; delete[] data;
@@ -451,11 +451,11 @@ namespace ehs
} }
else else
{ {
data[this->size++] = (JsonBase*)new JsonStr(Str_8(value, size)); data[this->size++] = (JsonBase *)new JsonStr(Str_8(value, size));
} }
} }
void JsonArray::Push(const Str_8& value) void JsonArray::Push(const Str_8 &value)
{ {
if (this->size + 1 > rawSize) if (this->size + 1 > rawSize)
{ {
@@ -465,7 +465,7 @@ namespace ehs
for (UInt_64 i = 0; i < this->size; ++i) for (UInt_64 i = 0; i < this->size; ++i)
result[i] = data[i]; result[i] = data[i];
result[this->size++] = (JsonBase*)new JsonStr(value); result[this->size++] = (JsonBase *)new JsonStr(value);
delete[] data; delete[] data;
@@ -473,7 +473,7 @@ namespace ehs
} }
else else
{ {
data[this->size++] = (JsonBase*)new JsonStr(value); data[this->size++] = (JsonBase *)new JsonStr(value);
} }
} }
@@ -482,7 +482,7 @@ namespace ehs
if (rawSize - --size >= extra * 2) if (rawSize - --size >= extra * 2)
rawSize -= extra; rawSize -= extra;
JsonBase** result = new JsonBase*[rawSize]; JsonBase **result = new JsonBase*[rawSize];
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result[i] = data[i]; result[i] = data[i];

View File

@@ -71,11 +71,6 @@ namespace ehs
return value; return value;
} }
JsonNum::operator float&()
{
return value;
}
Str_8 JsonNum::ToStr(const UInt_64 level, const bool compact) const Str_8 JsonNum::ToStr(const UInt_64 level, const bool compact) const
{ {
Str_8 result; Str_8 result;

View File

@@ -79,12 +79,7 @@ namespace ehs
return *this; return *this;
} }
JsonObj::operator const JsonVar*() const JsonObj::operator JsonVar*() const
{
return vars;
}
JsonObj::operator JsonVar*()
{ {
return vars; return vars;
} }

View File

@@ -13,17 +13,17 @@ namespace ehs
} }
JsonStr::JsonStr(const Char_8* value, const UInt_64 size) JsonStr::JsonStr(const Char_8 *value, const UInt_64 size)
: JsonBase(JsonType::STR), value(value, size) : JsonBase(JsonType::STR), value(value, size)
{ {
} }
JsonStr::JsonStr(JsonStr&& js) noexcept JsonStr::JsonStr(JsonStr &&js) noexcept
: JsonBase(js), value(std::move(js.value)) : JsonBase(js), value(std::move(js.value))
{ {
} }
JsonStr& JsonStr::operator=(JsonStr&& js) noexcept JsonStr& JsonStr::operator=(JsonStr &&js) noexcept
{ {
if (this == &js) if (this == &js)
return *this; return *this;
@@ -40,7 +40,7 @@ namespace ehs
return value; return value;
} }
JsonStr::operator Str_8&() JsonStr::operator Str_8 &()
{ {
return value; return value;
} }

View File

@@ -23,25 +23,25 @@ namespace ehs
{ {
} }
JsonVar::JsonVar(Str_8 id, const JsonBase* const value) JsonVar::JsonVar(Str_8 id, const JsonBase * const value)
: hashId(id.Hash_64()), id(std::move(id)) : hashId(id.Hash_64()), id(std::move(id))
{ {
switch (value->GetType()) switch (value->GetType())
{ {
case JsonType::OBJ: case JsonType::OBJ:
this->value = (JsonBase*)new JsonObj(*(JsonObj*)value); this->value = (JsonBase *)new JsonObj(*(JsonObj *)value);
break; break;
case JsonType::ARRAY: case JsonType::ARRAY:
this->value = (JsonBase*)new JsonArray(*(JsonArray*)value); this->value = (JsonBase *)new JsonArray(*(JsonArray *)value);
break; break;
case JsonType::BOOL: case JsonType::BOOL:
this->value = (JsonBase*)new JsonBool(*(JsonBool*)value); this->value = (JsonBase *)new JsonBool(*(JsonBool *)value);
break; break;
case JsonType::NUM: case JsonType::NUM:
this->value = (JsonBase*)new JsonNum(*(JsonNum*)value); this->value = (JsonBase *)new JsonNum(*(JsonNum *)value);
break; break;
case JsonType::STR: case JsonType::STR:
this->value = (JsonBase*)new JsonStr(*(JsonStr*)value); this->value = (JsonBase *)new JsonStr(*(JsonStr *)value);
break; break;
default: default:
this->value = new JsonBase(JsonType::NULLOBJ); this->value = new JsonBase(JsonType::NULLOBJ);
@@ -49,22 +49,22 @@ namespace ehs
} }
} }
JsonVar::JsonVar(Str_8 id, const JsonBase& value) JsonVar::JsonVar(Str_8 id, const JsonBase &value)
: hashId(id.Hash_64()), id(std::move(id)), value(new JsonBase(value)) : hashId(id.Hash_64()), id(std::move(id)), value(new JsonBase(value))
{ {
} }
JsonVar::JsonVar(Str_8 id, const JsonObj& value) JsonVar::JsonVar(Str_8 id, const JsonObj &value)
: hashId(id.Hash_64()), id(std::move(id)), value((JsonBase*)new JsonObj(value)) : hashId(id.Hash_64()), id(std::move(id)), value((JsonBase*)new JsonObj(value))
{ {
} }
JsonVar::JsonVar(Str_8 id, const JsonArray& value) JsonVar::JsonVar(Str_8 id, const JsonArray &value)
: hashId(id.Hash_64()), id(std::move(id)), value((JsonBase*)new JsonArray(value)) : hashId(id.Hash_64()), id(std::move(id)), value((JsonBase*)new JsonArray(value))
{ {
} }
JsonVar::JsonVar(Str_8 id, const JsonBool& value) JsonVar::JsonVar(Str_8 id, const JsonBool &value)
: hashId(id.Hash_64()), id(std::move(id)), value((JsonBase*)new JsonBool(value)) : hashId(id.Hash_64()), id(std::move(id)), value((JsonBase*)new JsonBool(value))
{ {
} }
@@ -74,7 +74,7 @@ namespace ehs
{ {
} }
JsonVar::JsonVar(Str_8 id, const JsonNum& value) JsonVar::JsonVar(Str_8 id, const JsonNum &value)
: hashId(id.Hash_64()), id(std::move(id)), value((JsonBase*)new JsonNum(value)) : hashId(id.Hash_64()), id(std::move(id)), value((JsonBase*)new JsonNum(value))
{ {
} }
@@ -144,14 +144,14 @@ namespace ehs
{ {
} }
JsonVar::JsonVar(JsonVar&& var) noexcept JsonVar::JsonVar(JsonVar &&var) noexcept
: hashId(var.hashId), id(std::move(var.id)), value(var.value) : hashId(var.hashId), id(std::move(var.id)), value(var.value)
{ {
var.hashId = 0; var.hashId = 0;
var.value = nullptr; var.value = nullptr;
} }
JsonVar::JsonVar(const JsonVar& var) JsonVar::JsonVar(const JsonVar &var)
: hashId(var.hashId), id(var.id), value(nullptr) : hashId(var.hashId), id(var.id), value(nullptr)
{ {
if (!var.value) if (!var.value)
@@ -180,7 +180,7 @@ namespace ehs
} }
} }
JsonVar& JsonVar::operator=(JsonVar&& var) noexcept JsonVar& JsonVar::operator=(JsonVar &&var) noexcept
{ {
if (this == &var) if (this == &var)
return *this; return *this;
@@ -196,7 +196,7 @@ namespace ehs
return *this; return *this;
} }
JsonVar& JsonVar::operator=(const JsonVar& var) JsonVar& JsonVar::operator=(const JsonVar &var)
{ {
if (this == &var) if (this == &var)
return *this; return *this;
@@ -212,19 +212,19 @@ namespace ehs
switch (var.value->GetType()) switch (var.value->GetType())
{ {
case JsonType::OBJ: case JsonType::OBJ:
value = (JsonBase*)new JsonObj(*(JsonObj*)var.value); value = (JsonBase *)new JsonObj(*(JsonObj *)var.value);
break; break;
case JsonType::ARRAY: case JsonType::ARRAY:
value = (JsonBase*)new JsonArray(*(JsonArray*)var.value); value = (JsonBase *)new JsonArray(*(JsonArray *)var.value);
break; break;
case JsonType::BOOL: case JsonType::BOOL:
value = (JsonBase*)new JsonBool(*(JsonBool*)var.value); value = (JsonBase *)new JsonBool(*(JsonBool *)var.value);
break; break;
case JsonType::NUM: case JsonType::NUM:
value = (JsonBase*)new JsonNum(*(JsonNum*)var.value); value = (JsonBase *)new JsonNum(*(JsonNum *)var.value);
break; break;
case JsonType::STR: case JsonType::STR:
value = (JsonBase*)new JsonStr(*(JsonStr*)var.value); value = (JsonBase *)new JsonStr(*(JsonStr *)var.value);
break; break;
default: default:
value = new JsonBase(); value = new JsonBase();
@@ -244,7 +244,7 @@ namespace ehs
return id; return id;
} }
void JsonVar::SetValue(const JsonBase* const newValue) void JsonVar::SetValue(const JsonBase * const newValue)
{ {
if (!newValue) if (!newValue)
return; return;
@@ -254,19 +254,19 @@ namespace ehs
switch (newValue->GetType()) switch (newValue->GetType())
{ {
case JsonType::OBJ: case JsonType::OBJ:
value = (JsonBase*)new JsonObj(*(JsonObj*)newValue); value = (JsonBase *)new JsonObj(*(JsonObj *)newValue);
break; break;
case JsonType::ARRAY: case JsonType::ARRAY:
value = (JsonBase*)new JsonArray(*(JsonArray*)newValue); value = (JsonBase *)new JsonArray(*(JsonArray *)newValue);
break; break;
case JsonType::BOOL: case JsonType::BOOL:
value = (JsonBase*)new JsonBool(*(JsonBool*)newValue); value = (JsonBase *)new JsonBool(*(JsonBool *)newValue);
break; break;
case JsonType::NUM: case JsonType::NUM:
value = (JsonBase*)new JsonNum(*(JsonNum*)newValue); value = (JsonBase *)new JsonNum(*(JsonNum *)newValue);
break; break;
case JsonType::STR: case JsonType::STR:
value = (JsonBase*)new JsonStr(*(JsonStr*)newValue); value = (JsonBase *)new JsonStr(*(JsonStr *)newValue);
break; break;
default: default:
value = new JsonBase(); value = new JsonBase();
@@ -274,72 +274,72 @@ namespace ehs
} }
} }
void JsonVar::SetValue(const JsonBase& newValue) void JsonVar::SetValue(const JsonBase &newValue)
{ {
delete value; delete value;
value = new JsonBase(newValue); value = new JsonBase(newValue);
} }
void JsonVar::SetValue(const JsonObj& newValue) void JsonVar::SetValue(const JsonObj &newValue)
{ {
delete value; delete value;
value = (JsonBase*)new JsonObj(newValue); value = (JsonBase *)new JsonObj(newValue);
} }
void JsonVar::SetValue(const JsonArray& newValue) void JsonVar::SetValue(const JsonArray &newValue)
{ {
delete value; delete value;
value = (JsonBase*)new JsonArray(newValue); value = (JsonBase *)new JsonArray(newValue);
} }
void JsonVar::SetValue(const JsonBool& newValue) void JsonVar::SetValue(const JsonBool &newValue)
{ {
delete value; delete value;
value = (JsonBase*)new JsonBool(newValue); value = (JsonBase *)new JsonBool(newValue);
} }
void JsonVar::SetValue(const bool newValue) void JsonVar::SetValue(const bool newValue)
{ {
delete value; delete value;
value = (JsonBase*)new JsonBool(newValue); value = (JsonBase *)new JsonBool(newValue);
} }
void JsonVar::SetValue(const JsonNum& newValue) void JsonVar::SetValue(const JsonNum &newValue)
{ {
delete value; delete value;
value = (JsonBase*)new JsonNum(newValue); value = (JsonBase *)new JsonNum(newValue);
} }
void JsonVar::SetValue(const float newValue) void JsonVar::SetValue(const float newValue)
{ {
delete value; delete value;
value = (JsonBase*)new JsonNum(newValue); value = (JsonBase *)new JsonNum(newValue);
} }
void JsonVar::SetValue(const JsonStr& newValue) void JsonVar::SetValue(const JsonStr &newValue)
{ {
delete value; delete value;
value = (JsonBase*)new JsonStr(newValue); value = (JsonBase *)new JsonStr(newValue);
} }
void JsonVar::SetValue(const Char_8* newValue, const UInt_64 size) void JsonVar::SetValue(const Char_8 *newValue, const UInt_64 size)
{ {
delete value; delete value;
value = (JsonBase*)new JsonStr(newValue, size); value = (JsonBase *)new JsonStr(newValue, size);
} }
void JsonVar::SetValue(const Str_8& newValue) void JsonVar::SetValue(const Str_8 &newValue)
{ {
delete value; delete value;
value = (JsonBase*)new JsonStr(newValue); value = (JsonBase *)new JsonStr(newValue);
} }
const JsonBase* JsonVar::GetValue() const const JsonBase *JsonVar::GetValue() const
{ {
return value; return value;
} }
JsonBase* JsonVar::GetValue() JsonBase *JsonVar::GetValue()
{ {
return value; return value;
} }

View File

@@ -5,4 +5,14 @@ namespace ehs
void BaseSystem::OpenURI(const Str_8& uri) void BaseSystem::OpenURI(const Str_8& uri)
{ {
} }
}
Str_8 BaseSystem::OpenFileDialog(const Str_8 &dir, const Str_8 &filters)
{
return {};
}
Str_8 BaseSystem::GetDirDialog(const Str_8 &dir)
{
return {};
}
}

View File

@@ -7,6 +7,7 @@ global _ZN3ehs3CPU19GetExtFeatureBits_1Ev
global _ZN3ehs3CPU19GetExtFeatureBits_2Ev global _ZN3ehs3CPU19GetExtFeatureBits_2Ev
global _ZN3ehs3CPU19GetExtFeatureBits_3Ev global _ZN3ehs3CPU19GetExtFeatureBits_3Ev
global _ZN3ehs3CPU8GetBrandEPc global _ZN3ehs3CPU8GetBrandEPc
global _ZN3ehs3CPU16GetCacheLineSizeEv
section .text section .text
_ZN3ehs3CPU6RDTSCPEPNS_3TSCE: _ZN3ehs3CPU6RDTSCPEPNS_3TSCE:
@@ -129,4 +130,17 @@ section .text
POP RBX POP RBX
RET
_ZN3ehs3CPU16GetCacheLineSizeEv:
PUSH RBX
MOV EAX, 0x80000006
CPUID
XOR EAX, EAX
MOV AL, CL
POP RBX
RET RET

Some files were not shown because too many files have changed in this diff Show More