build: lower bundled SFML C++17 to C++14
Convert the C++17 code in the bundled SFML code to C++14 to hopefully allow for targeting macOS 10.10 (Yosemite) instead of 10.15 (Catalina.) Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
parent
4cf6cccbaf
commit
dae4397dff
|
@ -184,6 +184,16 @@ set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
|
||||||
if(NOT TRANSLATIONS_ONLY)
|
if(NOT TRANSLATIONS_ONLY)
|
||||||
add_subdirectory(third_party/include/nonstd)
|
add_subdirectory(third_party/include/nonstd)
|
||||||
add_subdirectory(third_party/include/stb)
|
add_subdirectory(third_party/include/stb)
|
||||||
|
add_subdirectory(third_party/include/ghc)
|
||||||
|
|
||||||
|
if(ENABLE_LINK)
|
||||||
|
include_directories(third_party/sfml/include)
|
||||||
|
add_subdirectory(third_party/sfml/src/SFML/System EXCLUDE_FROM_ALL)
|
||||||
|
add_subdirectory(third_party/sfml/src/SFML/Network EXCLUDE_FROM_ALL)
|
||||||
|
set(SFML_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/sfml/include)
|
||||||
|
set(SFML_LIBRARIES sfml-system sfml-network)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(src/core)
|
add_subdirectory(src/core)
|
||||||
add_subdirectory(src/components)
|
add_subdirectory(src/components)
|
||||||
add_subdirectory(src/sdl)
|
add_subdirectory(src/sdl)
|
||||||
|
|
|
@ -119,10 +119,3 @@ if(ENABLE_LINK OR ENABLE_WX)
|
||||||
message(FATAL_ERROR "NLS requires libintl/gettext")
|
message(FATAL_ERROR "NLS requires libintl/gettext")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_LINK)
|
|
||||||
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/sfml/src/SFML/System EXCLUDE_FROM_ALL)
|
|
||||||
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/sfml/src/SFML/Network EXCLUDE_FROM_ALL)
|
|
||||||
set(SFML_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/sfml/include)
|
|
||||||
set(SFML_LIBRARIES sfml-system sfml-network)
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
#add_compile_options(-std=c++14)
|
||||||
|
|
||||||
if(NOT ENABLE_ASM) # inline asm is not allowed with -fPIC
|
if(NOT ENABLE_ASM) # inline asm is not allowed with -fPIC
|
||||||
add_compile_options(-fPIC)
|
add_compile_options(-fPIC)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -68,6 +68,8 @@ if(CMAKE_VERSION VERSION_LESS "3.25")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:/std:c++14>)
|
||||||
|
|
||||||
set(CMAKE_RC_FLAGS "-c65001 /DWIN32" CACHE STRING "" FORCE)
|
set(CMAKE_RC_FLAGS "-c65001 /DWIN32" CACHE STRING "" FORCE)
|
||||||
|
|
||||||
# We need to explicitly set all of these to override the CMake defaults.
|
# We need to explicitly set all of these to override the CMake defaults.
|
||||||
|
|
|
@ -93,7 +93,7 @@ target_include_directories(vbam-core
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(vbam-core
|
target_link_libraries(vbam-core
|
||||||
PRIVATE vbam-core-apu vbam-fex
|
PRIVATE vbam-core-apu vbam-fex nonstd-lib
|
||||||
PUBLIC vbam-core-base ${ZLIB_LIBRARY}
|
PUBLIC vbam-core-base ${ZLIB_LIBRARY}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ target_include_directories(vbam-core-base
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(vbam-core-base
|
target_link_libraries(vbam-core-base
|
||||||
PRIVATE vbam-fex stb-image
|
PRIVATE vbam-fex stb-image nonstd-lib
|
||||||
PUBLIC ${ZLIB_LIBRARY}
|
PUBLIC ${ZLIB_LIBRARY}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,5 @@ add_library(vbam-core-base-test
|
||||||
notreached.h)
|
notreached.h)
|
||||||
|
|
||||||
target_link_libraries(vbam-core-base-test
|
target_link_libraries(vbam-core-base-test
|
||||||
INTERFACE GTest::gtest)
|
INTERFACE GTest::gtest
|
||||||
|
PRIVATE nonstd-lib)
|
||||||
|
|
|
@ -53,6 +53,7 @@ target_link_libraries(vbam
|
||||||
vbam-components-user-config
|
vbam-components-user-config
|
||||||
${OPENGL_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
${VBAM_SDL2_LIBS}
|
${VBAM_SDL2_LIBS}
|
||||||
|
nonstd-lib
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
@ -238,11 +238,7 @@ function(configure_wx_target target)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# Core emulator.
|
# Core emulator.
|
||||||
_add_link_libraries(vbam-core)
|
_add_link_libraries(vbam-core nonstd-lib ghc-filesystem)
|
||||||
|
|
||||||
# Nonstd.
|
|
||||||
_add_link_libraries(nonstd-lib)
|
|
||||||
_add_include_directories(${NONSTD_INCLUDE_DIR})
|
|
||||||
|
|
||||||
# wxWidgets.
|
# wxWidgets.
|
||||||
_add_link_libraries(${wxWidgets_LIBRARIES})
|
_add_link_libraries(${wxWidgets_LIBRARIES})
|
||||||
|
@ -302,7 +298,6 @@ function(configure_wx_target target)
|
||||||
else()
|
else()
|
||||||
_add_compile_definitions(NO_OGL)
|
_add_compile_definitions(NO_OGL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# Sub-projects.
|
# Sub-projects.
|
||||||
|
@ -520,6 +515,8 @@ if(ENABLE_FFMPEG)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(visualboyadvance-m nonstd-lib)
|
||||||
|
|
||||||
# wxrc does not support xrs files in -c output (> 10x compression)
|
# wxrc does not support xrs files in -c output (> 10x compression)
|
||||||
# we do it using the bin2c.c utility.
|
# we do it using the bin2c.c utility.
|
||||||
set(BIN2C ${CMAKE_BINARY_DIR}/bin2c)
|
set(BIN2C ${CMAKE_BINARY_DIR}/bin2c)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <variant.hpp>
|
#include "variant.hpp"
|
||||||
|
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <variant.hpp>
|
#include "variant.hpp"
|
||||||
|
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <optional.hpp>
|
#include "optional.hpp"
|
||||||
|
|
||||||
#include <wx/clntdata.h>
|
#include <wx/clntdata.h>
|
||||||
#include <wx/event.h>
|
#include <wx/event.h>
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
add_library(ghc-filesystem INTERFACE)
|
||||||
|
|
||||||
|
target_include_directories(ghc-filesystem INTERFACE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_sources(ghc-filesystem INTERFACE
|
||||||
|
filesystem.hpp
|
||||||
|
fs_fwd.hpp
|
||||||
|
fs_impl.hpp
|
||||||
|
fs_std_fwd.hpp
|
||||||
|
fs_std.hpp
|
||||||
|
fs_std_impl.hpp
|
||||||
|
)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_fwd.hpp - The forwarding header for the header/implementation separated usage of
|
||||||
|
// ghc::filesystem.
|
||||||
|
// This file can be include at any place, where ghc::filesystem api is needed while
|
||||||
|
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||||
|
// as long as one cpp includes fs_impl.hpp to deliver the matching implementations.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#ifndef GHC_FILESYSTEM_FWD_H
|
||||||
|
#define GHC_FILESYSTEM_FWD_H
|
||||||
|
#define GHC_FILESYSTEM_FWD
|
||||||
|
#include "filesystem.hpp"
|
||||||
|
#endif // GHC_FILESYSTEM_FWD_H
|
|
@ -0,0 +1,35 @@
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_impl.hpp - The implementation header for the header/implementation separated usage of
|
||||||
|
// ghc::filesystem.
|
||||||
|
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||||
|
// The cpp has to include this before including fs_fwd.hpp directly or via a different
|
||||||
|
// header to work.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||||
|
#include "filesystem.hpp"
|
|
@ -0,0 +1,77 @@
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_std.hpp - The dynamic switching header that includes std::filesystem if detected
|
||||||
|
// or ghc::filesystem if not, and makes the resulting API available in the
|
||||||
|
// namespace fs.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#ifndef GHC_FILESYSTEM_STD_H
|
||||||
|
#define GHC_FILESYSTEM_STD_H
|
||||||
|
|
||||||
|
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
||||||
|
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
||||||
|
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
||||||
|
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
||||||
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
|
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
||||||
|
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
||||||
|
// and watchOS 6.0.
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <Availability.h>
|
||||||
|
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
||||||
|
// released after std::filesystem, where std::filesystem is always available.
|
||||||
|
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
||||||
|
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
||||||
|
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
||||||
|
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
||||||
|
#undef GHC_USE_STD_FS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GHC_USE_STD_FS
|
||||||
|
#include <filesystem>
|
||||||
|
namespace fs {
|
||||||
|
using namespace std::filesystem;
|
||||||
|
using ifstream = std::ifstream;
|
||||||
|
using ofstream = std::ofstream;
|
||||||
|
using fstream = std::fstream;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#include "filesystem.hpp"
|
||||||
|
namespace fs {
|
||||||
|
using namespace ghc::filesystem;
|
||||||
|
using ifstream = ghc::filesystem::ifstream;
|
||||||
|
using ofstream = ghc::filesystem::ofstream;
|
||||||
|
using fstream = ghc::filesystem::fstream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // GHC_FILESYSTEM_STD_H
|
|
@ -0,0 +1,79 @@
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_std_fwd.hpp - The forwarding header for the header/implementation separated usage of
|
||||||
|
// ghc::filesystem that uses std::filesystem if it detects it.
|
||||||
|
// This file can be include at any place, where fs::filesystem api is needed while
|
||||||
|
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||||
|
// as long as one cpp includes fs_std_impl.hpp to deliver the matching implementations.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#ifndef GHC_FILESYSTEM_STD_FWD_H
|
||||||
|
#define GHC_FILESYSTEM_STD_FWD_H
|
||||||
|
|
||||||
|
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
||||||
|
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
||||||
|
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
||||||
|
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
||||||
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
|
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
||||||
|
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
||||||
|
// and watchOS 6.0.
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <Availability.h>
|
||||||
|
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
||||||
|
// released after std::filesystem, where std::filesystem is always available.
|
||||||
|
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
||||||
|
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
||||||
|
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
||||||
|
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
||||||
|
#undef GHC_USE_STD_FS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GHC_USE_STD_FS
|
||||||
|
#include <filesystem>
|
||||||
|
namespace fs {
|
||||||
|
using namespace std::filesystem;
|
||||||
|
using ifstream = std::ifstream;
|
||||||
|
using ofstream = std::ofstream;
|
||||||
|
using fstream = std::fstream;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#include "fs_fwd.hpp"
|
||||||
|
namespace fs {
|
||||||
|
using namespace ghc::filesystem;
|
||||||
|
using ifstream = ghc::filesystem::ifstream;
|
||||||
|
using ofstream = ghc::filesystem::ofstream;
|
||||||
|
using fstream = ghc::filesystem::fstream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // GHC_FILESYSTEM_STD_FWD_H
|
|
@ -0,0 +1,60 @@
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_std_impl.hpp - The implementation header for the header/implementation separated usage of
|
||||||
|
// ghc::filesystem that does nothing if std::filesystem is detected.
|
||||||
|
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||||
|
// The cpp has to include this before including fs_std_fwd.hpp directly or via a different
|
||||||
|
// header to work.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
|
||||||
|
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
|
||||||
|
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
|
||||||
|
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
|
||||||
|
#define GHC_USE_STD_FS
|
||||||
|
|
||||||
|
// Old Apple OSs don't support std::filesystem, though the header is available at compile
|
||||||
|
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
|
||||||
|
// and watchOS 6.0.
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <Availability.h>
|
||||||
|
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
|
||||||
|
// released after std::filesystem, where std::filesystem is always available.
|
||||||
|
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|
||||||
|
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|
||||||
|
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|
||||||
|
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
|
||||||
|
#undef GHC_USE_STD_FS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
#include "fs_impl.hpp"
|
||||||
|
#endif
|
|
@ -1,13 +1,14 @@
|
||||||
# Defines the `NONSTD_INCLUDE_DIR` variable and `nonstd-lib` target.
|
# Defines the `NONSTD_INCLUDE_DIR` variable and `nonstd-lib` target.
|
||||||
|
|
||||||
# nonstd library dependency (header-only).
|
|
||||||
set(NONSTD_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR} PARENT_SCOPE)
|
|
||||||
add_library(nonstd-lib INTERFACE)
|
add_library(nonstd-lib INTERFACE)
|
||||||
target_sources(nonstd-lib
|
|
||||||
INTERFACE
|
target_include_directories(nonstd-lib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
target_sources(nonstd-lib INTERFACE
|
||||||
optional.hpp
|
optional.hpp
|
||||||
variant.hpp
|
variant.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# For C++, default to nonstd::optional and nonstd::variant for now due to mac
|
# For C++, default to nonstd::optional and nonstd::variant for now due to mac
|
||||||
# build issues.
|
# build issues.
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
|
|
|
@ -2,8 +2,14 @@
|
||||||
|
|
||||||
# STB Image library dependency (header-only).
|
# STB Image library dependency (header-only).
|
||||||
set(STB_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR} PARENT_SCOPE)
|
set(STB_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR} PARENT_SCOPE)
|
||||||
|
|
||||||
add_library(stb-image INTERFACE)
|
add_library(stb-image INTERFACE)
|
||||||
target_sources(stb-image
|
|
||||||
INTERFACE
|
target_include_directories(stb-image INTERFACE
|
||||||
|
${STB_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_sources(stb-image INTERFACE
|
||||||
|
stb_image.h
|
||||||
stb_image_write.h
|
stb_image_write.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -114,9 +114,9 @@
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Ensure minimum C++ language standard version is met
|
// Ensure minimum C++ language standard version is met
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#if (defined(_MSVC_LANG) && _MSVC_LANG < 201703L) || (!defined(_MSVC_LANG) && __cplusplus < 201703L)
|
//#if (defined(_MSVC_LANG) && _MSVC_LANG < 201703L) || (!defined(_MSVC_LANG) && __cplusplus < 201703L)
|
||||||
#error "Enable C++17 or newer for your compiler (e.g. -std=c++17 for GCC/Clang or /std:c++17 for MSVC)"
|
//#error "Enable C++17 or newer for your compiler (e.g. -std=c++17 for GCC/Clang or /std:c++17 for MSVC)"
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include "filesystem.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -201,13 +201,13 @@ public:
|
||||||
/// \return Directory name
|
/// \return Directory name
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] const std::filesystem::path& getDirectory() const;
|
[[nodiscard]] const ghc::filesystem::path& getDirectory() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::filesystem::path m_directory; //!< Directory extracted from the response message
|
ghc::filesystem::path m_directory; //!< Directory extracted from the response message
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ public:
|
||||||
/// \see `deleteFile`
|
/// \see `deleteFile`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] Response renameFile(const std::filesystem::path& file, const std::filesystem::path& newName);
|
[[nodiscard]] Response renameFile(const ghc::filesystem::path& file, const ghc::filesystem::path& newName);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Remove an existing file
|
/// \brief Remove an existing file
|
||||||
|
@ -455,7 +455,7 @@ public:
|
||||||
/// \see `renameFile`
|
/// \see `renameFile`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] Response deleteFile(const std::filesystem::path& name);
|
[[nodiscard]] Response deleteFile(const ghc::filesystem::path& name);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Download a file from the server
|
/// \brief Download a file from the server
|
||||||
|
@ -477,8 +477,8 @@ public:
|
||||||
/// \see `upload`
|
/// \see `upload`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] Response download(const std::filesystem::path& remoteFile,
|
[[nodiscard]] Response download(const ghc::filesystem::path& remoteFile,
|
||||||
const std::filesystem::path& localPath,
|
const ghc::filesystem::path& localPath,
|
||||||
TransferMode mode = TransferMode::Binary);
|
TransferMode mode = TransferMode::Binary);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -502,8 +502,8 @@ public:
|
||||||
/// \see `download`
|
/// \see `download`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] Response upload(const std::filesystem::path& localFile,
|
[[nodiscard]] Response upload(const ghc::filesystem::path& localFile,
|
||||||
const std::filesystem::path& remotePath,
|
const ghc::filesystem::path& remotePath,
|
||||||
TransferMode mode = TransferMode::Binary,
|
TransferMode mode = TransferMode::Binary,
|
||||||
bool append = false);
|
bool append = false);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include "optional.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ private:
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
TcpSocket m_connection; //!< Connection to the host
|
TcpSocket m_connection; //!< Connection to the host
|
||||||
std::optional<IpAddress> m_host; //!< Web host address
|
nonstd::optional<IpAddress> m_host; //!< Web host address
|
||||||
std::string m_hostName; //!< Web host name
|
std::string m_hostName; //!< Web host name
|
||||||
unsigned short m_port{}; //!< Port used for connection with host
|
unsigned short m_port{}; //!< Port used for connection with host
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,9 +32,8 @@
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <optional>
|
#include "optional.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
@ -56,10 +55,10 @@ public:
|
||||||
///
|
///
|
||||||
/// \param address IP address or network name
|
/// \param address IP address or network name
|
||||||
///
|
///
|
||||||
/// \return Address if provided argument was valid, otherwise `std::nullopt`
|
/// \return Address if provided argument was valid, otherwise `nonstd::nullopt`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] static std::optional<IpAddress> resolve(std::string_view address);
|
[[nodiscard]] static nonstd::optional<IpAddress> resolve(std::string address);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Construct the address from 4 bytes
|
/// \brief Construct the address from 4 bytes
|
||||||
|
@ -130,12 +129,12 @@ public:
|
||||||
/// Unlike getPublicAddress, this function is fast and may be
|
/// Unlike getPublicAddress, this function is fast and may be
|
||||||
/// used safely anywhere.
|
/// used safely anywhere.
|
||||||
///
|
///
|
||||||
/// \return Local IP address of the computer on success, `std::nullopt` otherwise
|
/// \return Local IP address of the computer on success, `nonstd::nullopt` otherwise
|
||||||
///
|
///
|
||||||
/// \see `getPublicAddress`
|
/// \see `getPublicAddress`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] static std::optional<IpAddress> getLocalAddress();
|
[[nodiscard]] static nonstd::optional<IpAddress> getLocalAddress();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the computer's public address
|
/// \brief Get the computer's public address
|
||||||
|
@ -154,12 +153,12 @@ public:
|
||||||
///
|
///
|
||||||
/// \param timeout Maximum time to wait
|
/// \param timeout Maximum time to wait
|
||||||
///
|
///
|
||||||
/// \return Public IP address of the computer on success, `std::nullopt` otherwise
|
/// \return Public IP address of the computer on success, `nonstd::nullopt` otherwise
|
||||||
///
|
///
|
||||||
/// \see `getLocalAddress`
|
/// \see `getLocalAddress`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] static std::optional<IpAddress> getPublicAddress(Time timeout = Time::Zero);
|
[[nodiscard]] static nonstd::optional<IpAddress> getPublicAddress(Time timeout = Time::Zero);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Static member data
|
// Static member data
|
||||||
|
@ -254,7 +253,7 @@ private:
|
||||||
/// \return Reference to the input stream
|
/// \return Reference to the input stream
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFML_NETWORK_API std::istream& operator>>(std::istream& stream, std::optional<IpAddress>& address);
|
SFML_NETWORK_API std::istream& operator>>(std::istream& stream, nonstd::optional<IpAddress>& address);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Overload of `operator<<` to print an IP address to an output stream
|
/// \brief Overload of `operator<<` to print an IP address to an output stream
|
||||||
|
|
|
@ -423,7 +423,7 @@ private:
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::vector<std::byte> m_data; //!< Data stored in the packet
|
std::vector<unsigned char> m_data; //!< Data stored in the packet
|
||||||
std::size_t m_readPos{}; //!< Current reading position in the packet
|
std::size_t m_readPos{}; //!< Current reading position in the packet
|
||||||
std::size_t m_sendPos{}; //!< Current send position in the packet (for handling partial sends)
|
std::size_t m_sendPos{}; //!< Current send position in the packet (for handling partial sends)
|
||||||
bool m_isValid{true}; //!< Reading state of the packet
|
bool m_isValid{true}; //!< Reading state of the packet
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
|
||||||
#include <optional>
|
#include "optional.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -82,7 +82,7 @@ public:
|
||||||
/// \see `getRemotePort`
|
/// \see `getRemotePort`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] std::optional<IpAddress> getRemoteAddress() const;
|
[[nodiscard]] nonstd::optional<IpAddress> getRemoteAddress() const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the port of the connected peer to which
|
/// \brief Get the port of the connected peer to which
|
||||||
|
@ -225,14 +225,14 @@ private:
|
||||||
{
|
{
|
||||||
std::uint32_t size{}; //!< Data of packet size
|
std::uint32_t size{}; //!< Data of packet size
|
||||||
std::size_t sizeReceived{}; //!< Number of size bytes received so far
|
std::size_t sizeReceived{}; //!< Number of size bytes received so far
|
||||||
std::vector<std::byte> data; //!< Data of the packet
|
std::vector<unsigned char> data; //!< Data of the packet
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
PendingPacket m_pendingPacket; //!< Temporary data of the packet currently being received
|
PendingPacket m_pendingPacket; //!< Temporary data of the packet currently being received
|
||||||
std::vector<std::byte> m_blockToSendBuffer; //!< Buffer used to prepare data being sent from the socket
|
std::vector<unsigned char> m_blockToSendBuffer; //!< Buffer used to prepare data being sent from the socket
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <SFML/Network/IpAddress.hpp>
|
#include <SFML/Network/IpAddress.hpp>
|
||||||
#include <SFML/Network/Socket.hpp>
|
#include <SFML/Network/Socket.hpp>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -156,7 +156,7 @@ public:
|
||||||
[[nodiscard]] Status receive(void* data,
|
[[nodiscard]] Status receive(void* data,
|
||||||
std::size_t size,
|
std::size_t size,
|
||||||
std::size_t& received,
|
std::size_t& received,
|
||||||
std::optional<IpAddress>& remoteAddress,
|
nonstd::optional<IpAddress>& remoteAddress,
|
||||||
unsigned short& remotePort);
|
unsigned short& remotePort);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -192,13 +192,13 @@ public:
|
||||||
/// \see `send`
|
/// \see `send`
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] Status receive(Packet& packet, std::optional<IpAddress>& remoteAddress, unsigned short& remotePort);
|
[[nodiscard]] Status receive(Packet& packet, nonstd::optional<IpAddress>& remoteAddress, unsigned short& remotePort);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::vector<std::byte> m_buffer{MaxDatagramSize}; //!< Temporary buffer holding the received data in Receive(Packet)
|
std::vector<unsigned char> m_buffer; //!< Temporary buffer holding the received data in Receive(Packet)
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -264,7 +264,7 @@ private:
|
||||||
/// // Receive an answer (most likely from 192.168.1.50, but could be anyone else)
|
/// // Receive an answer (most likely from 192.168.1.50, but could be anyone else)
|
||||||
/// std::array<char, 1024> buffer;
|
/// std::array<char, 1024> buffer;
|
||||||
/// std::size_t received = 0;
|
/// std::size_t received = 0;
|
||||||
/// std::optional<sf::IpAddress> sender;
|
/// nonstd::optional<IpAddress> sender;
|
||||||
/// unsigned short port;
|
/// unsigned short port;
|
||||||
/// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done)
|
/// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done)
|
||||||
/// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
|
/// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
|
||||||
|
@ -278,7 +278,7 @@ private:
|
||||||
/// // Receive a message from anyone
|
/// // Receive a message from anyone
|
||||||
/// std::array<char, 1024> buffer;
|
/// std::array<char, 1024> buffer;
|
||||||
/// std::size_t received = 0;
|
/// std::size_t received = 0;
|
||||||
/// std::optional<sf::IpAddress> sender;
|
/// nonstd::optional<IpAddress> sender;
|
||||||
/// unsigned short port;
|
/// unsigned short port;
|
||||||
/// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done)
|
/// if (socket.receive(buffer.data(), buffer.size(), received, sender, port) == sf::Socket::Status::Done)
|
||||||
/// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
|
/// std::cout << sender->toString() << " said: " << buffer.data() << std::endl;
|
||||||
|
|
|
@ -495,10 +495,10 @@ namespace Literals
|
||||||
///
|
///
|
||||||
/// Usage example:
|
/// Usage example:
|
||||||
/// \code
|
/// \code
|
||||||
/// sf::Angle a1 = sf::degrees(90);
|
/// sf::Angle a1 = degrees(90);
|
||||||
/// float radians = a1.asRadians(); // 1.5708f
|
/// float radians = a1.asRadians(); // 1.5708f
|
||||||
///
|
///
|
||||||
/// sf::Angle a2 = sf::radians(3.141592654f);
|
/// sf::Angle a2 = radians(3.141592654f);
|
||||||
/// float degrees = a2.asDegrees(); // 180.0f
|
/// float degrees = a2.asDegrees(); // 180.0f
|
||||||
///
|
///
|
||||||
/// using namespace sf::Literals;
|
/// using namespace sf::Literals;
|
||||||
|
|
|
@ -32,10 +32,8 @@
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
constexpr float pi = 3.141592654f;
|
||||||
{
|
constexpr float tau = pi * 2.f;
|
||||||
inline constexpr float pi = 3.141592654f;
|
|
||||||
inline constexpr float tau = pi * 2.f;
|
|
||||||
|
|
||||||
constexpr float positiveRemainder(float a, float b)
|
constexpr float positiveRemainder(float a, float b)
|
||||||
{
|
{
|
||||||
|
@ -43,12 +41,11 @@ constexpr float positiveRemainder(float a, float b)
|
||||||
const float val = a - static_cast<float>(static_cast<int>(a / b)) * b;
|
const float val = a - static_cast<float>(static_cast<int>(a / b)) * b;
|
||||||
return val >= 0.f ? val : val + b;
|
return val >= 0.f ? val : val + b;
|
||||||
}
|
}
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
constexpr float Angle::asDegrees() const
|
constexpr float Angle::asDegrees() const
|
||||||
{
|
{
|
||||||
return m_radians * (180.f / priv::pi);
|
return m_radians * (180.f / pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,14 +59,14 @@ constexpr float Angle::asRadians() const
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
constexpr Angle Angle::wrapSigned() const
|
constexpr Angle Angle::wrapSigned() const
|
||||||
{
|
{
|
||||||
return radians(priv::positiveRemainder(m_radians + priv::pi, priv::tau) - priv::pi);
|
return radians(positiveRemainder(m_radians + pi, tau) - pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
constexpr Angle Angle::wrapUnsigned() const
|
constexpr Angle Angle::wrapUnsigned() const
|
||||||
{
|
{
|
||||||
return radians(priv::positiveRemainder(m_radians, priv::tau));
|
return radians(positiveRemainder(m_radians, tau));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,7 +79,7 @@ constexpr Angle::Angle(float radians) : m_radians(radians)
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
constexpr Angle degrees(float angle)
|
constexpr Angle degrees(float angle)
|
||||||
{
|
{
|
||||||
return Angle(angle * (priv::pi / 180.f));
|
return Angle(angle * (pi / 180.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,7 +216,7 @@ constexpr float operator/(Angle left, Angle right)
|
||||||
constexpr Angle operator%(Angle left, Angle right)
|
constexpr Angle operator%(Angle left, Angle right)
|
||||||
{
|
{
|
||||||
assert(right.asRadians() != 0.f && "Angle::operator% cannot modulus by 0");
|
assert(right.asRadians() != 0.f && "Angle::operator% cannot modulus by 0");
|
||||||
return radians(priv::positiveRemainder(left.asRadians(), right.asRadians()));
|
return radians(positiveRemainder(left.asRadians(), right.asRadians()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,6 +266,6 @@ constexpr Angle operator""_rad(unsigned long long angle)
|
||||||
|
|
||||||
// Note: the 'inline' keyword here is technically not required, but VS2019 fails
|
// Note: the 'inline' keyword here is technically not required, but VS2019 fails
|
||||||
// to compile with a bogus "multiple definition" error if not explicitly used.
|
// to compile with a bogus "multiple definition" error if not explicitly used.
|
||||||
inline constexpr Angle Angle::Zero;
|
constexpr Angle Angle::Zero;
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
|
@ -40,8 +40,6 @@
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Chooses a monotonic clock of highest resolution
|
/// \brief Chooses a monotonic clock of highest resolution
|
||||||
|
@ -75,10 +73,8 @@ using ClockImpl = std::conditional_t<std::chrono::high_resolution_clock::is_stea
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static_assert(ClockImpl::is_steady, "Provided implementation is not a monotonic clock");
|
static_assert(ClockImpl::is_steady, "Provided implementation is not a monotonic clock");
|
||||||
static_assert(std::ratio_less_equal_v<ClockImpl::period, std::micro>,
|
//static_assert(std::ratio_less_equal_v<ClockImpl::period, std::micro>,
|
||||||
"Clock resolution is too low. Expecting at least a microsecond precision");
|
// "Clock resolution is too low. Expecting at least a microsecond precision");
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
class Time;
|
class Time;
|
||||||
|
|
||||||
|
@ -157,8 +153,8 @@ private:
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
priv::ClockImpl::time_point m_refPoint{priv::ClockImpl::now()}; //!< Time of last reset
|
ClockImpl::time_point m_refPoint{ClockImpl::now()}; //!< Time of last reset
|
||||||
priv::ClockImpl::time_point m_stopPoint; //!< Time of last stop
|
ClockImpl::time_point m_stopPoint; //!< Time of last stop
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
|
@ -33,14 +33,14 @@
|
||||||
|
|
||||||
#include <SFML/System/InputStream.hpp>
|
#include <SFML/System/InputStream.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include "filesystem.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#ifdef SFML_SYSTEM_ANDROID
|
#ifdef SFML_SYSTEM_ANDROID
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
class SFML_SYSTEM_API ResourceStream;
|
class SFML_SYSTEM_API ResourceStream;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ public:
|
||||||
/// \throws sf::Exception on error
|
/// \throws sf::Exception on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
explicit FileInputStream(const std::filesystem::path& filename);
|
explicit FileInputStream(const ghc::filesystem::path& filename);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Open the stream from a file path
|
/// \brief Open the stream from a file path
|
||||||
|
@ -113,7 +113,7 @@ public:
|
||||||
/// \return `true` on success, `false` on error
|
/// \return `true` on success, `false` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] bool open(const std::filesystem::path& filename);
|
[[nodiscard]] bool open(const ghc::filesystem::path& filename);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Read data from the stream
|
/// \brief Read data from the stream
|
||||||
|
@ -124,36 +124,36 @@ public:
|
||||||
/// \param data Buffer where to copy the read data
|
/// \param data Buffer where to copy the read data
|
||||||
/// \param size Desired number of bytes to read
|
/// \param size Desired number of bytes to read
|
||||||
///
|
///
|
||||||
/// \return The number of bytes actually read, or `std::nullopt` on error
|
/// \return The number of bytes actually read, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size) override;
|
[[nodiscard]] nonstd::optional<std::size_t> read(void* data, std::size_t size) override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Change the current reading position
|
/// \brief Change the current reading position
|
||||||
///
|
///
|
||||||
/// \param position The position to seek to, from the beginning
|
/// \param position The position to seek to, from the beginning
|
||||||
///
|
///
|
||||||
/// \return The position actually sought to, or `std::nullopt` on error
|
/// \return The position actually sought to, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] std::optional<std::size_t> seek(std::size_t position) override;
|
[[nodiscard]] nonstd::optional<std::size_t> seek(std::size_t position) override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the current reading position in the stream
|
/// \brief Get the current reading position in the stream
|
||||||
///
|
///
|
||||||
/// \return The current position, or `std::nullopt` on error.
|
/// \return The current position, or `nonstd::nullopt` on error.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] std::optional<std::size_t> tell() override;
|
[[nodiscard]] nonstd::optional<std::size_t> tell() override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Return the size of the stream
|
/// \brief Return the size of the stream
|
||||||
///
|
///
|
||||||
/// \return The total number of bytes available in the stream, or `std::nullopt` on error
|
/// \return The total number of bytes available in the stream, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> getSize() override;
|
nonstd::optional<std::size_t> getSize() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -169,7 +169,7 @@ private:
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#ifdef SFML_SYSTEM_ANDROID
|
#ifdef SFML_SYSTEM_ANDROID
|
||||||
std::unique_ptr<priv::ResourceStream> m_androidFile;
|
std::unique_ptr<ResourceStream> m_androidFile;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::unique_ptr<std::FILE, FileCloser> m_file; //!< stdio file stream
|
std::unique_ptr<std::FILE, FileCloser> m_file; //!< stdio file stream
|
||||||
|
@ -202,7 +202,7 @@ private:
|
||||||
/// \code
|
/// \code
|
||||||
/// void process(InputStream& stream);
|
/// void process(InputStream& stream);
|
||||||
///
|
///
|
||||||
/// std::optional stream = sf::FileInputStream::open("some_file.dat");
|
/// nonstd::optional stream = FileInputStream::open("some_file.dat");
|
||||||
/// if (stream)
|
/// if (stream)
|
||||||
/// process(*stream);
|
/// process(*stream);
|
||||||
/// \endcode
|
/// \endcode
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include <SFML/System/Export.hpp>
|
#include <SFML/System/Export.hpp>
|
||||||
|
|
||||||
#include <optional>
|
#include "optional.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
@ -60,36 +60,36 @@ public:
|
||||||
/// \param data Buffer where to copy the read data
|
/// \param data Buffer where to copy the read data
|
||||||
/// \param size Desired number of bytes to read
|
/// \param size Desired number of bytes to read
|
||||||
///
|
///
|
||||||
/// \return The number of bytes actually read, or `std::nullopt` on error
|
/// \return The number of bytes actually read, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] virtual std::optional<std::size_t> read(void* data, std::size_t size) = 0;
|
[[nodiscard]] virtual nonstd::optional<std::size_t> read(void* data, std::size_t size) = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Change the current reading position
|
/// \brief Change the current reading position
|
||||||
///
|
///
|
||||||
/// \param position The position to seek to, from the beginning
|
/// \param position The position to seek to, from the beginning
|
||||||
///
|
///
|
||||||
/// \return The position actually sought to, or `std::nullopt` on error
|
/// \return The position actually sought to, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] virtual std::optional<std::size_t> seek(std::size_t position) = 0;
|
[[nodiscard]] virtual nonstd::optional<std::size_t> seek(std::size_t position) = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the current reading position in the stream
|
/// \brief Get the current reading position in the stream
|
||||||
///
|
///
|
||||||
/// \return The current position, or `std::nullopt` on error.
|
/// \return The current position, or `nonstd::nullopt` on error.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] virtual std::optional<std::size_t> tell() = 0;
|
[[nodiscard]] virtual nonstd::optional<std::size_t> tell() = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Return the size of the stream
|
/// \brief Return the size of the stream
|
||||||
///
|
///
|
||||||
/// \return The total number of bytes available in the stream, or `std::nullopt` on error
|
/// \return The total number of bytes available in the stream, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual std::optional<std::size_t> getSize() = 0;
|
virtual nonstd::optional<std::size_t> getSize() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -119,15 +119,15 @@ public:
|
||||||
///
|
///
|
||||||
/// ZipStream(const std::string& archive);
|
/// ZipStream(const std::string& archive);
|
||||||
///
|
///
|
||||||
/// [[nodiscard]] bool open(const std::filesystem::path& filename);
|
/// [[nodiscard]] bool open(const ghc::filesystem::path& filename);
|
||||||
///
|
///
|
||||||
/// [[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size);
|
/// [[nodiscard]] nonstd::optional<std::size_t> read(void* data, std::size_t size);
|
||||||
///
|
///
|
||||||
/// [[nodiscard]] std::optional<std::size_t> seek(std::size_t position);
|
/// [[nodiscard]] nonstd::optional<std::size_t> seek(std::size_t position);
|
||||||
///
|
///
|
||||||
/// [[nodiscard]] std::optional<std::size_t> tell();
|
/// [[nodiscard]] nonstd::optional<std::size_t> tell();
|
||||||
///
|
///
|
||||||
/// std::optional<std::size_t> getSize();
|
/// nonstd::optional<std::size_t> getSize();
|
||||||
///
|
///
|
||||||
/// private:
|
/// private:
|
||||||
///
|
///
|
||||||
|
|
|
@ -64,42 +64,42 @@ public:
|
||||||
/// \param data Buffer where to copy the read data
|
/// \param data Buffer where to copy the read data
|
||||||
/// \param size Desired number of bytes to read
|
/// \param size Desired number of bytes to read
|
||||||
///
|
///
|
||||||
/// \return The number of bytes actually read, or `std::nullopt` on error
|
/// \return The number of bytes actually read, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size) override;
|
[[nodiscard]] nonstd::optional<std::size_t> read(void* data, std::size_t size) override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Change the current reading position
|
/// \brief Change the current reading position
|
||||||
///
|
///
|
||||||
/// \param position The position to seek to, from the beginning
|
/// \param position The position to seek to, from the beginning
|
||||||
///
|
///
|
||||||
/// \return The position actually sought to, or `std::nullopt` on error
|
/// \return The position actually sought to, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] std::optional<std::size_t> seek(std::size_t position) override;
|
[[nodiscard]] nonstd::optional<std::size_t> seek(std::size_t position) override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the current reading position in the stream
|
/// \brief Get the current reading position in the stream
|
||||||
///
|
///
|
||||||
/// \return The current position, or `std::nullopt` on error.
|
/// \return The current position, or `nonstd::nullopt` on error.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] std::optional<std::size_t> tell() override;
|
[[nodiscard]] nonstd::optional<std::size_t> tell() override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Return the size of the stream
|
/// \brief Return the size of the stream
|
||||||
///
|
///
|
||||||
/// \return The total number of bytes available in the stream, or `std::nullopt` on error
|
/// \return The total number of bytes available in the stream, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> getSize() override;
|
nonstd::optional<std::size_t> getSize() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
const std::byte* m_data{}; //!< Pointer to the data in memory
|
const unsigned char* m_data{}; //!< Pointer to the data in memory
|
||||||
std::size_t m_size{}; //!< Total size of the data
|
std::size_t m_size{}; //!< Total size of the data
|
||||||
std::size_t m_offset{}; //!< Current reading position
|
std::size_t m_offset{}; //!< Current reading position
|
||||||
};
|
};
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// NOLINTBEGIN(readability-identifier-naming)
|
// NOLINTBEGIN(readability-identifier-naming)
|
||||||
/// Represents an invalid position in the string
|
/// Represents an invalid position in the string
|
||||||
static inline const std::size_t InvalidPos{std::u32string::npos};
|
static const std::size_t InvalidPos{std::u32string::npos};
|
||||||
// NOLINTEND(readability-identifier-naming)
|
// NOLINTEND(readability-identifier-naming)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -279,6 +279,6 @@ constexpr Time& operator%=(Time& left, Time right)
|
||||||
|
|
||||||
// Note: the 'inline' keyword here is technically not required, but VS2019 fails
|
// Note: the 'inline' keyword here is technically not required, but VS2019 fails
|
||||||
// to compile with a bogus "multiple definition" error if not explicitly used.
|
// to compile with a bogus "multiple definition" error if not explicitly used.
|
||||||
inline constexpr Time Time::Zero;
|
constexpr Time Time::Zero;
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
////////////////////////////////////////////////////////////
|
///////i///////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// SFML - Simple and Fast Multimedia Library
|
// SFML - Simple and Fast Multimedia Library
|
||||||
// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org)
|
// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
@ -43,8 +43,6 @@
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
template <typename In, typename Out>
|
template <typename In, typename Out>
|
||||||
Out copyBits(In begin, In end, Out output)
|
Out copyBits(In begin, In end, Out output)
|
||||||
|
@ -53,8 +51,8 @@ Out copyBits(In begin, In end, Out output)
|
||||||
using OutputType = typename Out::container_type::value_type;
|
using OutputType = typename Out::container_type::value_type;
|
||||||
|
|
||||||
static_assert(sizeof(OutputType) >= sizeof(InputType));
|
static_assert(sizeof(OutputType) >= sizeof(InputType));
|
||||||
static_assert(std::is_integral_v<InputType>);
|
// static_assert(std::is_integral_v<InputType>);
|
||||||
static_assert(std::is_integral_v<OutputType>);
|
// static_assert(std::is_integral_v<OutputType>);
|
||||||
|
|
||||||
// The goal is to copy the byte representation of the input into the output type.
|
// The goal is to copy the byte representation of the input into the output type.
|
||||||
// A single static_cast will try to preserve the value as opposed to the byte representation
|
// A single static_cast will try to preserve the value as opposed to the byte representation
|
||||||
|
@ -74,7 +72,6 @@ Out copyBits(In begin, In end, Out output)
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
template <typename In>
|
template <typename In>
|
||||||
In Utf<8>::decode(In begin, In end, char32_t& output, char32_t replacement)
|
In Utf<8>::decode(In begin, In end, char32_t& output, char32_t replacement)
|
||||||
|
@ -174,7 +171,7 @@ Out Utf<8>::encode(char32_t input, Out output, std::uint8_t replacement)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
// Add them to the output
|
// Add them to the output
|
||||||
output = priv::copyBits(bytes.data(), bytes.data() + bytestoWrite, output);
|
output = copyBits(bytes.data(), bytes.data() + bytestoWrite, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
@ -315,7 +312,7 @@ Out Utf<8>::toUtf8(In begin, In end, Out output)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(decltype(*begin)) == sizeof(char));
|
static_assert(sizeof(decltype(*begin)) == sizeof(char));
|
||||||
|
|
||||||
return priv::copyBits(begin, end, output);
|
return copyBits(begin, end, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -500,7 +497,7 @@ Out Utf<16>::fromLatin1(In begin, In end, Out output)
|
||||||
|
|
||||||
// Latin-1 is directly compatible with Unicode encodings,
|
// Latin-1 is directly compatible with Unicode encodings,
|
||||||
// and can thus be treated as (a sub-range of) UTF-32
|
// and can thus be treated as (a sub-range of) UTF-32
|
||||||
return priv::copyBits(begin, end, output);
|
return copyBits(begin, end, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -579,7 +576,7 @@ Out Utf<16>::toUtf16(In begin, In end, Out output)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(decltype(*begin)) == sizeof(char16_t));
|
static_assert(sizeof(decltype(*begin)) == sizeof(char16_t));
|
||||||
|
|
||||||
return priv::copyBits(begin, end, output);
|
return copyBits(begin, end, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -674,7 +671,7 @@ Out Utf<32>::fromLatin1(In begin, In end, Out output)
|
||||||
|
|
||||||
// Latin-1 is directly compatible with Unicode encodings,
|
// Latin-1 is directly compatible with Unicode encodings,
|
||||||
// and can thus be treated as (a sub-range of) UTF-32
|
// and can thus be treated as (a sub-range of) UTF-32
|
||||||
return priv::copyBits(begin, end, output);
|
return copyBits(begin, end, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -753,7 +750,7 @@ Out Utf<32>::toUtf32(In begin, In end, Out output)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(decltype(*begin)) == sizeof(char32_t));
|
static_assert(sizeof(decltype(*begin)) == sizeof(char32_t));
|
||||||
|
|
||||||
return priv::copyBits(begin, end, output);
|
return copyBits(begin, end, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ target_compile_definitions(sfml-network PRIVATE SFML_STATIC)
|
||||||
target_compile_definitions(sfml-network INTERFACE SFML_STATIC)
|
target_compile_definitions(sfml-network INTERFACE SFML_STATIC)
|
||||||
|
|
||||||
# setup dependencies
|
# setup dependencies
|
||||||
target_link_libraries(sfml-network PUBLIC sfml-system)
|
target_link_libraries(sfml-network PUBLIC sfml-system nonstd-lib ghc-filesystem)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(sfml-network PRIVATE ws2_32)
|
target_link_libraries(sfml-network PRIVATE ws2_32)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -122,7 +122,7 @@ Ftp::DirectoryResponse::DirectoryResponse(const Ftp::Response& response) : Ftp::
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
const std::filesystem::path& Ftp::DirectoryResponse::getDirectory() const
|
const ghc::filesystem::path& Ftp::DirectoryResponse::getDirectory() const
|
||||||
{
|
{
|
||||||
return m_directory;
|
return m_directory;
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ Ftp::Response Ftp::deleteDirectory(const std::string& name)
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Ftp::Response Ftp::renameFile(const std::filesystem::path& file, const std::filesystem::path& newName)
|
Ftp::Response Ftp::renameFile(const ghc::filesystem::path& file, const ghc::filesystem::path& newName)
|
||||||
{
|
{
|
||||||
Response response = sendCommand("RNFR", file.string());
|
Response response = sendCommand("RNFR", file.string());
|
||||||
if (response.isOk())
|
if (response.isOk())
|
||||||
|
@ -279,14 +279,14 @@ Ftp::Response Ftp::renameFile(const std::filesystem::path& file, const std::file
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Ftp::Response Ftp::deleteFile(const std::filesystem::path& name)
|
Ftp::Response Ftp::deleteFile(const ghc::filesystem::path& name)
|
||||||
{
|
{
|
||||||
return sendCommand("DELE", name.string());
|
return sendCommand("DELE", name.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Ftp::Response Ftp::download(const std::filesystem::path& remoteFile, const std::filesystem::path& localPath, TransferMode mode)
|
Ftp::Response Ftp::download(const ghc::filesystem::path& remoteFile, const ghc::filesystem::path& localPath, TransferMode mode)
|
||||||
{
|
{
|
||||||
// Open a data channel using the given transfer mode
|
// Open a data channel using the given transfer mode
|
||||||
DataChannel data(*this);
|
DataChannel data(*this);
|
||||||
|
@ -298,7 +298,7 @@ Ftp::Response Ftp::download(const std::filesystem::path& remoteFile, const std::
|
||||||
if (response.isOk())
|
if (response.isOk())
|
||||||
{
|
{
|
||||||
// Create the file and truncate it if necessary
|
// Create the file and truncate it if necessary
|
||||||
const std::filesystem::path filepath = localPath / remoteFile.filename();
|
const ghc::filesystem::path filepath = localPath / remoteFile.filename();
|
||||||
std::ofstream file(filepath, std::ios_base::binary | std::ios_base::trunc);
|
std::ofstream file(filepath, std::ios_base::binary | std::ios_base::trunc);
|
||||||
if (!file)
|
if (!file)
|
||||||
return Response(Response::Status::InvalidFile);
|
return Response(Response::Status::InvalidFile);
|
||||||
|
@ -314,7 +314,7 @@ Ftp::Response Ftp::download(const std::filesystem::path& remoteFile, const std::
|
||||||
|
|
||||||
// If the download was unsuccessful, delete the partial file
|
// If the download was unsuccessful, delete the partial file
|
||||||
if (!response.isOk())
|
if (!response.isOk())
|
||||||
std::filesystem::remove(filepath);
|
ghc::filesystem::remove(filepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,8 +323,8 @@ Ftp::Response Ftp::download(const std::filesystem::path& remoteFile, const std::
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Ftp::Response Ftp::upload(const std::filesystem::path& localFile,
|
Ftp::Response Ftp::upload(const ghc::filesystem::path& localFile,
|
||||||
const std::filesystem::path& remotePath,
|
const ghc::filesystem::path& remotePath,
|
||||||
TransferMode mode,
|
TransferMode mode,
|
||||||
bool append)
|
bool append)
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,9 +123,10 @@ std::string Http::Request::prepare() const
|
||||||
out << "HTTP/" << m_majorVersion << "." << m_minorVersion << "\r\n";
|
out << "HTTP/" << m_majorVersion << "." << m_minorVersion << "\r\n";
|
||||||
|
|
||||||
// Write fields
|
// Write fields
|
||||||
for (const auto& [fieldKey, fieldValue] : m_fields)
|
auto it = m_fields.begin();
|
||||||
|
for (; it != m_fields.end(); it++)
|
||||||
{
|
{
|
||||||
out << fieldKey << ": " << fieldValue << "\r\n";
|
out << it->first << ": " << it->second << "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use an extra \r\n to separate the header from the body
|
// Use an extra \r\n to separate the header from the body
|
||||||
|
@ -148,7 +149,8 @@ bool Http::Request::hasField(const std::string& field) const
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
const std::string& Http::Response::getField(const std::string& field) const
|
const std::string& Http::Response::getField(const std::string& field) const
|
||||||
{
|
{
|
||||||
if (const auto it = m_fields.find(toLower(field)); it != m_fields.end())
|
const auto it = m_fields.find(toLower(field));
|
||||||
|
if (it != m_fields.end())
|
||||||
{
|
{
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,28 +46,27 @@ const IpAddress IpAddress::Broadcast(255, 255, 255, 255);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<IpAddress> IpAddress::resolve(std::string_view address)
|
nonstd::optional<IpAddress> IpAddress::resolve(std::string address)
|
||||||
{
|
{
|
||||||
using namespace std::string_view_literals;
|
|
||||||
|
|
||||||
if (address.empty())
|
if (address.empty())
|
||||||
{
|
{
|
||||||
// Not generating en error message here as resolution failure is a valid outcome.
|
// Not generating en error message here as resolution failure is a valid outcome.
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address == "255.255.255.255"sv)
|
if (address == "255.255.255.255")
|
||||||
{
|
{
|
||||||
// The broadcast address needs to be handled explicitly,
|
// The broadcast address needs to be handled explicitly,
|
||||||
// because it is also the value returned by inet_addr on error
|
// because it is also the value returned by inet_addr on error
|
||||||
return Broadcast;
|
return Broadcast;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address == "0.0.0.0"sv)
|
if (address == "0.0.0.0")
|
||||||
return Any;
|
return Any;
|
||||||
|
|
||||||
// Try to convert the address as a byte representation ("xxx.xxx.xxx.xxx")
|
// Try to convert the address as a byte representation ("xxx.xxx.xxx.xxx")
|
||||||
if (const std::uint32_t ip = inet_addr(address.data()); ip != INADDR_NONE)
|
const std::uint32_t ip = inet_addr(address.data());
|
||||||
|
if (ip != INADDR_NONE)
|
||||||
return IpAddress(ntohl(ip));
|
return IpAddress(ntohl(ip));
|
||||||
|
|
||||||
// Not a valid address, try to convert it as a host name
|
// Not a valid address, try to convert it as a host name
|
||||||
|
@ -87,7 +86,7 @@ std::optional<IpAddress> IpAddress::resolve(std::string_view address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not generating en error message here as resolution failure is a valid outcome.
|
// Not generating en error message here as resolution failure is a valid outcome.
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,7 +121,7 @@ std::uint32_t IpAddress::toInteger() const
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<IpAddress> IpAddress::getLocalAddress()
|
nonstd::optional<IpAddress> IpAddress::getLocalAddress()
|
||||||
{
|
{
|
||||||
// The method here is to connect a UDP socket to a public ip,
|
// The method here is to connect a UDP socket to a public ip,
|
||||||
// and get the local socket address with the getsockname function.
|
// and get the local socket address with the getsockname function.
|
||||||
|
@ -130,36 +129,36 @@ std::optional<IpAddress> IpAddress::getLocalAddress()
|
||||||
|
|
||||||
// Create the socket
|
// Create the socket
|
||||||
const SocketHandle sock = socket(PF_INET, SOCK_DGRAM, 0);
|
const SocketHandle sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
if (sock == priv::SocketImpl::invalidSocket())
|
if (sock == SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
err() << "Failed to retrieve local address (invalid socket)" << std::endl;
|
err() << "Failed to retrieve local address (invalid socket)" << std::endl;
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect the socket to a public ip (here 1.1.1.1) on any
|
// Connect the socket to a public ip (here 1.1.1.1) on any
|
||||||
// port. This will give the local address of the network interface
|
// port. This will give the local address of the network interface
|
||||||
// used for default routing which is usually what we want.
|
// used for default routing which is usually what we want.
|
||||||
sockaddr_in address = priv::SocketImpl::createAddress(0x01010101, 9);
|
sockaddr_in address = SocketImpl::createAddress(0x01010101, 9);
|
||||||
if (connect(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
|
if (connect(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
|
||||||
{
|
{
|
||||||
priv::SocketImpl::close(sock);
|
SocketImpl::close(sock);
|
||||||
|
|
||||||
err() << "Failed to retrieve local address (socket connection failure)" << std::endl;
|
err() << "Failed to retrieve local address (socket connection failure)" << std::endl;
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the local address of the socket connection
|
// Get the local address of the socket connection
|
||||||
priv::SocketImpl::AddrLength size = sizeof(address);
|
SocketImpl::AddrLength size = sizeof(address);
|
||||||
if (getsockname(sock, reinterpret_cast<sockaddr*>(&address), &size) == -1)
|
if (getsockname(sock, reinterpret_cast<sockaddr*>(&address), &size) == -1)
|
||||||
{
|
{
|
||||||
priv::SocketImpl::close(sock);
|
SocketImpl::close(sock);
|
||||||
|
|
||||||
err() << "Failed to retrieve local address (socket local address retrieval failure)" << std::endl;
|
err() << "Failed to retrieve local address (socket local address retrieval failure)" << std::endl;
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the socket
|
// Close the socket
|
||||||
priv::SocketImpl::close(sock);
|
SocketImpl::close(sock);
|
||||||
|
|
||||||
// Finally build the IP address
|
// Finally build the IP address
|
||||||
return IpAddress(ntohl(address.sin_addr.s_addr));
|
return IpAddress(ntohl(address.sin_addr.s_addr));
|
||||||
|
@ -167,7 +166,7 @@ std::optional<IpAddress> IpAddress::getLocalAddress()
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<IpAddress> IpAddress::getPublicAddress(Time timeout)
|
nonstd::optional<IpAddress> IpAddress::getPublicAddress(Time timeout)
|
||||||
{
|
{
|
||||||
// The trick here is more complicated, because the only way
|
// The trick here is more complicated, because the only way
|
||||||
// to get our public IP address is to get it from a distant computer.
|
// to get our public IP address is to get it from a distant computer.
|
||||||
|
@ -187,7 +186,7 @@ std::optional<IpAddress> IpAddress::getPublicAddress(Time timeout)
|
||||||
err() << "Failed to retrieve public address from external IP resolution server (HTTP response status "
|
err() << "Failed to retrieve public address from external IP resolution server (HTTP response status "
|
||||||
<< static_cast<int>(status) << ")" << std::endl;
|
<< static_cast<int>(status) << ")" << std::endl;
|
||||||
|
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,7 +233,7 @@ bool operator>=(IpAddress left, IpAddress right)
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::istream& operator>>(std::istream& stream, std::optional<IpAddress>& address)
|
std::istream& operator>>(std::istream& stream, nonstd::optional<IpAddress>& address)
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
stream >> str;
|
stream >> str;
|
||||||
|
|
|
@ -45,7 +45,7 @@ void Packet::append(const void* data, std::size_t sizeInBytes)
|
||||||
{
|
{
|
||||||
if (data && (sizeInBytes > 0))
|
if (data && (sizeInBytes > 0))
|
||||||
{
|
{
|
||||||
const auto* begin = reinterpret_cast<const std::byte*>(data);
|
const auto* begin = reinterpret_cast<const unsigned char*>(data);
|
||||||
const auto* end = begin + sizeInBytes;
|
const auto* end = begin + sizeInBytes;
|
||||||
m_data.insert(m_data.end(), begin, end);
|
m_data.insert(m_data.end(), begin, end);
|
||||||
}
|
}
|
||||||
|
@ -196,10 +196,10 @@ Packet& Packet::operator>>(std::int64_t& data)
|
||||||
{
|
{
|
||||||
// Since ntohll is not available everywhere, we have to convert
|
// Since ntohll is not available everywhere, we have to convert
|
||||||
// to network byte order (big endian) manually
|
// to network byte order (big endian) manually
|
||||||
std::array<std::byte, sizeof(data)> bytes{};
|
std::array<unsigned char, sizeof(data)> bytes{};
|
||||||
std::memcpy(bytes.data(), &m_data[m_readPos], bytes.size());
|
std::memcpy(bytes.data(), &m_data[m_readPos], bytes.size());
|
||||||
|
|
||||||
data = toInteger<std::int64_t>(bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]);
|
data = toInteger<std::int64_t>(bytes);
|
||||||
|
|
||||||
m_readPos += sizeof(data);
|
m_readPos += sizeof(data);
|
||||||
}
|
}
|
||||||
|
@ -215,10 +215,10 @@ Packet& Packet::operator>>(std::uint64_t& data)
|
||||||
{
|
{
|
||||||
// Since ntohll is not available everywhere, we have to convert
|
// Since ntohll is not available everywhere, we have to convert
|
||||||
// to network byte order (big endian) manually
|
// to network byte order (big endian) manually
|
||||||
std::array<std::byte, sizeof(data)> bytes{};
|
std::array<unsigned char, sizeof(data)> bytes{};
|
||||||
std::memcpy(bytes.data(), &m_data[m_readPos], sizeof(data));
|
std::memcpy(bytes.data(), &m_data[m_readPos], sizeof(data));
|
||||||
|
|
||||||
data = toInteger<std::uint64_t>(bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]);
|
data = toInteger<std::uint64_t>(bytes);
|
||||||
|
|
||||||
m_readPos += sizeof(data);
|
m_readPos += sizeof(data);
|
||||||
}
|
}
|
||||||
|
@ -434,7 +434,7 @@ Packet& Packet::operator<<(std::int64_t data)
|
||||||
// Since htonll is not available everywhere, we have to convert
|
// Since htonll is not available everywhere, we have to convert
|
||||||
// to network byte order (big endian) manually
|
// to network byte order (big endian) manually
|
||||||
|
|
||||||
const std::array toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF),
|
const std::array<std::uint8_t,8> toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF),
|
||||||
static_cast<std::uint8_t>((data >> 48) & 0xFF),
|
static_cast<std::uint8_t>((data >> 48) & 0xFF),
|
||||||
static_cast<std::uint8_t>((data >> 40) & 0xFF),
|
static_cast<std::uint8_t>((data >> 40) & 0xFF),
|
||||||
static_cast<std::uint8_t>((data >> 32) & 0xFF),
|
static_cast<std::uint8_t>((data >> 32) & 0xFF),
|
||||||
|
@ -454,7 +454,7 @@ Packet& Packet::operator<<(std::uint64_t data)
|
||||||
// Since htonll is not available everywhere, we have to convert
|
// Since htonll is not available everywhere, we have to convert
|
||||||
// to network byte order (big endian) manually
|
// to network byte order (big endian) manually
|
||||||
|
|
||||||
const std::array toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF),
|
const std::array<std::uint8_t,8> toWrite = {static_cast<std::uint8_t>((data >> 56) & 0xFF),
|
||||||
static_cast<std::uint8_t>((data >> 48) & 0xFF),
|
static_cast<std::uint8_t>((data >> 48) & 0xFF),
|
||||||
static_cast<std::uint8_t>((data >> 40) & 0xFF),
|
static_cast<std::uint8_t>((data >> 40) & 0xFF),
|
||||||
static_cast<std::uint8_t>((data >> 32) & 0xFF),
|
static_cast<std::uint8_t>((data >> 32) & 0xFF),
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Socket::Socket(Type type) : m_type(type), m_socket(priv::SocketImpl::invalidSocket())
|
Socket::Socket(Type type) : m_type(type), m_socket(SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ Socket::~Socket()
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Socket::Socket(Socket&& socket) noexcept :
|
Socket::Socket(Socket&& socket) noexcept :
|
||||||
m_type(socket.m_type),
|
m_type(socket.m_type),
|
||||||
m_socket(std::exchange(socket.m_socket, priv::SocketImpl::invalidSocket())),
|
m_socket(std::exchange(socket.m_socket, SocketImpl::invalidSocket())),
|
||||||
m_isBlocking(socket.m_isBlocking)
|
m_isBlocking(socket.m_isBlocking)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ Socket& Socket::operator=(Socket&& socket) noexcept
|
||||||
close();
|
close();
|
||||||
|
|
||||||
m_type = socket.m_type;
|
m_type = socket.m_type;
|
||||||
m_socket = std::exchange(socket.m_socket, priv::SocketImpl::invalidSocket());
|
m_socket = std::exchange(socket.m_socket, SocketImpl::invalidSocket());
|
||||||
m_isBlocking = socket.m_isBlocking;
|
m_isBlocking = socket.m_isBlocking;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,8 @@ Socket& Socket::operator=(Socket&& socket) noexcept
|
||||||
void Socket::setBlocking(bool blocking)
|
void Socket::setBlocking(bool blocking)
|
||||||
{
|
{
|
||||||
// Apply if the socket is already created
|
// Apply if the socket is already created
|
||||||
if (m_socket != priv::SocketImpl::invalidSocket())
|
if (m_socket != SocketImpl::invalidSocket())
|
||||||
priv::SocketImpl::setBlocking(m_socket, blocking);
|
SocketImpl::setBlocking(m_socket, blocking);
|
||||||
|
|
||||||
m_isBlocking = blocking;
|
m_isBlocking = blocking;
|
||||||
}
|
}
|
||||||
|
@ -103,11 +103,11 @@ SocketHandle Socket::getNativeHandle() const
|
||||||
void Socket::create()
|
void Socket::create()
|
||||||
{
|
{
|
||||||
// Don't create the socket if it already exists
|
// Don't create the socket if it already exists
|
||||||
if (m_socket == priv::SocketImpl::invalidSocket())
|
if (m_socket == SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
const SocketHandle handle = socket(PF_INET, m_type == Type::Tcp ? SOCK_STREAM : SOCK_DGRAM, 0);
|
const SocketHandle handle = socket(PF_INET, m_type == Type::Tcp ? SOCK_STREAM : SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (handle == priv::SocketImpl::invalidSocket())
|
if (handle == SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
err() << "Failed to create socket" << std::endl;
|
err() << "Failed to create socket" << std::endl;
|
||||||
return;
|
return;
|
||||||
|
@ -122,7 +122,7 @@ void Socket::create()
|
||||||
void Socket::create(SocketHandle handle)
|
void Socket::create(SocketHandle handle)
|
||||||
{
|
{
|
||||||
// Don't create the socket if it already exists
|
// Don't create the socket if it already exists
|
||||||
if (m_socket == priv::SocketImpl::invalidSocket())
|
if (m_socket == SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
// Assign the new handle
|
// Assign the new handle
|
||||||
m_socket = handle;
|
m_socket = handle;
|
||||||
|
@ -165,10 +165,10 @@ void Socket::create(SocketHandle handle)
|
||||||
void Socket::close()
|
void Socket::close()
|
||||||
{
|
{
|
||||||
// Close the socket
|
// Close the socket
|
||||||
if (m_socket != priv::SocketImpl::invalidSocket())
|
if (m_socket != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
priv::SocketImpl::close(m_socket);
|
SocketImpl::close(m_socket);
|
||||||
m_socket = priv::SocketImpl::invalidSocket();
|
m_socket = SocketImpl::invalidSocket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Helper class implementing all the non-portable
|
/// \brief Helper class implementing all the non-portable
|
||||||
|
@ -120,4 +120,4 @@ public:
|
||||||
static Socket::Status getErrorStatus();
|
static Socket::Status getErrorStatus();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -91,7 +91,7 @@ SocketSelector& SocketSelector::operator=(SocketSelector&&) noexcept = default;
|
||||||
void SocketSelector::add(Socket& socket)
|
void SocketSelector::add(Socket& socket)
|
||||||
{
|
{
|
||||||
const SocketHandle handle = socket.getNativeHandle();
|
const SocketHandle handle = socket.getNativeHandle();
|
||||||
if (handle != priv::SocketImpl::invalidSocket())
|
if (handle != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(SFML_SYSTEM_WINDOWS)
|
#if defined(SFML_SYSTEM_WINDOWS)
|
||||||
|
@ -133,7 +133,7 @@ void SocketSelector::add(Socket& socket)
|
||||||
void SocketSelector::remove(Socket& socket)
|
void SocketSelector::remove(Socket& socket)
|
||||||
{
|
{
|
||||||
const SocketHandle handle = socket.getNativeHandle();
|
const SocketHandle handle = socket.getNativeHandle();
|
||||||
if (handle != priv::SocketImpl::invalidSocket())
|
if (handle != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(SFML_SYSTEM_WINDOWS)
|
#if defined(SFML_SYSTEM_WINDOWS)
|
||||||
|
@ -190,7 +190,7 @@ bool SocketSelector::wait(Time timeout)
|
||||||
bool SocketSelector::isReady(Socket& socket) const
|
bool SocketSelector::isReady(Socket& socket) const
|
||||||
{
|
{
|
||||||
const SocketHandle handle = socket.getNativeHandle();
|
const SocketHandle handle = socket.getNativeHandle();
|
||||||
if (handle != priv::SocketImpl::invalidSocket())
|
if (handle != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
|
|
||||||
#if !defined(SFML_SYSTEM_WINDOWS)
|
#if !defined(SFML_SYSTEM_WINDOWS)
|
||||||
|
|
|
@ -45,11 +45,11 @@ TcpListener::TcpListener() : Socket(Type::Tcp)
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
unsigned short TcpListener::getLocalPort() const
|
unsigned short TcpListener::getLocalPort() const
|
||||||
{
|
{
|
||||||
if (getNativeHandle() != priv::SocketImpl::invalidSocket())
|
if (getNativeHandle() != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
// Retrieve information about the local end of the socket
|
// Retrieve information about the local end of the socket
|
||||||
sockaddr_in address{};
|
sockaddr_in address{};
|
||||||
priv::SocketImpl::AddrLength size = sizeof(address);
|
SocketImpl::AddrLength size = sizeof(address);
|
||||||
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
||||||
{
|
{
|
||||||
return ntohs(address.sin_port);
|
return ntohs(address.sin_port);
|
||||||
|
@ -75,7 +75,7 @@ Socket::Status TcpListener::listen(unsigned short port, IpAddress address)
|
||||||
return Status::Error;
|
return Status::Error;
|
||||||
|
|
||||||
// Bind the socket to the specified port
|
// Bind the socket to the specified port
|
||||||
sockaddr_in addr = priv::SocketImpl::createAddress(address.toInteger(), port);
|
sockaddr_in addr = SocketImpl::createAddress(address.toInteger(), port);
|
||||||
if (bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1)
|
if (bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1)
|
||||||
{
|
{
|
||||||
// Not likely to happen, but...
|
// Not likely to happen, but...
|
||||||
|
@ -107,7 +107,7 @@ void TcpListener::close()
|
||||||
Socket::Status TcpListener::accept(TcpSocket& socket)
|
Socket::Status TcpListener::accept(TcpSocket& socket)
|
||||||
{
|
{
|
||||||
// Make sure that we're listening
|
// Make sure that we're listening
|
||||||
if (getNativeHandle() == priv::SocketImpl::invalidSocket())
|
if (getNativeHandle() == SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
err() << "Failed to accept a new connection, the socket is not listening" << std::endl;
|
err() << "Failed to accept a new connection, the socket is not listening" << std::endl;
|
||||||
return Status::Error;
|
return Status::Error;
|
||||||
|
@ -115,12 +115,12 @@ Socket::Status TcpListener::accept(TcpSocket& socket)
|
||||||
|
|
||||||
// Accept a new connection
|
// Accept a new connection
|
||||||
sockaddr_in address{};
|
sockaddr_in address{};
|
||||||
priv::SocketImpl::AddrLength length = sizeof(address);
|
SocketImpl::AddrLength length = sizeof(address);
|
||||||
const SocketHandle remote = ::accept(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &length);
|
const SocketHandle remote = ::accept(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &length);
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
if (remote == priv::SocketImpl::invalidSocket())
|
if (remote == SocketImpl::invalidSocket())
|
||||||
return priv::SocketImpl::getErrorStatus();
|
return SocketImpl::getErrorStatus();
|
||||||
|
|
||||||
// Initialize the new connected socket
|
// Initialize the new connected socket
|
||||||
socket.close();
|
socket.close();
|
||||||
|
|
|
@ -64,11 +64,11 @@ TcpSocket::TcpSocket() : Socket(Type::Tcp)
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
unsigned short TcpSocket::getLocalPort() const
|
unsigned short TcpSocket::getLocalPort() const
|
||||||
{
|
{
|
||||||
if (getNativeHandle() != priv::SocketImpl::invalidSocket())
|
if (getNativeHandle() != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
// Retrieve information about the local end of the socket
|
// Retrieve information about the local end of the socket
|
||||||
sockaddr_in address{};
|
sockaddr_in address{};
|
||||||
priv::SocketImpl::AddrLength size = sizeof(address);
|
SocketImpl::AddrLength size = sizeof(address);
|
||||||
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
||||||
{
|
{
|
||||||
return ntohs(address.sin_port);
|
return ntohs(address.sin_port);
|
||||||
|
@ -81,13 +81,13 @@ unsigned short TcpSocket::getLocalPort() const
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<IpAddress> TcpSocket::getRemoteAddress() const
|
nonstd::optional<IpAddress> TcpSocket::getRemoteAddress() const
|
||||||
{
|
{
|
||||||
if (getNativeHandle() != priv::SocketImpl::invalidSocket())
|
if (getNativeHandle() != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
// Retrieve information about the remote end of the socket
|
// Retrieve information about the remote end of the socket
|
||||||
sockaddr_in address{};
|
sockaddr_in address{};
|
||||||
priv::SocketImpl::AddrLength size = sizeof(address);
|
SocketImpl::AddrLength size = sizeof(address);
|
||||||
if (getpeername(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
if (getpeername(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
||||||
{
|
{
|
||||||
return IpAddress(ntohl(address.sin_addr.s_addr));
|
return IpAddress(ntohl(address.sin_addr.s_addr));
|
||||||
|
@ -95,18 +95,18 @@ std::optional<IpAddress> TcpSocket::getRemoteAddress() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// We failed to retrieve the address
|
// We failed to retrieve the address
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
unsigned short TcpSocket::getRemotePort() const
|
unsigned short TcpSocket::getRemotePort() const
|
||||||
{
|
{
|
||||||
if (getNativeHandle() != priv::SocketImpl::invalidSocket())
|
if (getNativeHandle() != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
// Retrieve information about the remote end of the socket
|
// Retrieve information about the remote end of the socket
|
||||||
sockaddr_in address{};
|
sockaddr_in address{};
|
||||||
priv::SocketImpl::AddrLength size = sizeof(address);
|
SocketImpl::AddrLength size = sizeof(address);
|
||||||
if (getpeername(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
if (getpeername(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
||||||
{
|
{
|
||||||
return ntohs(address.sin_port);
|
return ntohs(address.sin_port);
|
||||||
|
@ -128,7 +128,7 @@ Socket::Status TcpSocket::connect(IpAddress remoteAddress, unsigned short remote
|
||||||
create();
|
create();
|
||||||
|
|
||||||
// Create the remote address
|
// Create the remote address
|
||||||
sockaddr_in address = priv::SocketImpl::createAddress(remoteAddress.toInteger(), remotePort);
|
sockaddr_in address = SocketImpl::createAddress(remoteAddress.toInteger(), remotePort);
|
||||||
|
|
||||||
if (timeout <= Time::Zero)
|
if (timeout <= Time::Zero)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +136,7 @@ Socket::Status TcpSocket::connect(IpAddress remoteAddress, unsigned short remote
|
||||||
|
|
||||||
// Connect the socket
|
// Connect the socket
|
||||||
if (::connect(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
|
if (::connect(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
|
||||||
return priv::SocketImpl::getErrorStatus();
|
return SocketImpl::getErrorStatus();
|
||||||
|
|
||||||
// Connection succeeded
|
// Connection succeeded
|
||||||
return Status::Done;
|
return Status::Done;
|
||||||
|
@ -160,7 +160,7 @@ Socket::Status TcpSocket::connect(IpAddress remoteAddress, unsigned short remote
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the error status
|
// Get the error status
|
||||||
Status status = priv::SocketImpl::getErrorStatus();
|
Status status = SocketImpl::getErrorStatus();
|
||||||
|
|
||||||
// If we were in non-blocking mode, return immediately
|
// If we were in non-blocking mode, return immediately
|
||||||
if (!blocking)
|
if (!blocking)
|
||||||
|
@ -192,13 +192,13 @@ Socket::Status TcpSocket::connect(IpAddress remoteAddress, unsigned short remote
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Connection refused
|
// Connection refused
|
||||||
status = priv::SocketImpl::getErrorStatus();
|
status = SocketImpl::getErrorStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Failed to connect before timeout is over
|
// Failed to connect before timeout is over
|
||||||
status = priv::SocketImpl::getErrorStatus();
|
status = SocketImpl::getErrorStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,8 +223,8 @@ void TcpSocket::disconnect()
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Socket::Status TcpSocket::send(const void* data, std::size_t size)
|
Socket::Status TcpSocket::send(const void* data, std::size_t size)
|
||||||
{
|
{
|
||||||
if (!isBlocking())
|
// if (!isBlocking())
|
||||||
err() << "Warning: Partial sends might not be handled properly." << std::endl;
|
// err() << "Warning: Partial sends might not be handled properly." << std::endl;
|
||||||
|
|
||||||
std::size_t sent = 0;
|
std::size_t sent = 0;
|
||||||
|
|
||||||
|
@ -251,14 +251,14 @@ Socket::Status TcpSocket::send(const void* data, std::size_t size, std::size_t&
|
||||||
// Send a chunk of data
|
// Send a chunk of data
|
||||||
result = static_cast<int>(::send(getNativeHandle(),
|
result = static_cast<int>(::send(getNativeHandle(),
|
||||||
static_cast<const char*>(data) + sent,
|
static_cast<const char*>(data) + sent,
|
||||||
static_cast<priv::SocketImpl::Size>(size - sent),
|
static_cast<SocketImpl::Size>(size - sent),
|
||||||
flags));
|
flags));
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
{
|
{
|
||||||
const Status status = priv::SocketImpl::getErrorStatus();
|
const Status status = SocketImpl::getErrorStatus();
|
||||||
|
|
||||||
if ((status == Status::NotReady) && sent)
|
if ((status == Status::NotReady) && sent)
|
||||||
return Status::Partial;
|
return Status::Partial;
|
||||||
|
@ -288,7 +288,7 @@ Socket::Status TcpSocket::receive(void* data, std::size_t size, std::size_t& rec
|
||||||
#pragma GCC diagnostic ignored "-Wuseless-cast"
|
#pragma GCC diagnostic ignored "-Wuseless-cast"
|
||||||
// Receive a chunk of bytes
|
// Receive a chunk of bytes
|
||||||
const int sizeReceived = static_cast<int>(
|
const int sizeReceived = static_cast<int>(
|
||||||
recv(getNativeHandle(), static_cast<char*>(data), static_cast<priv::SocketImpl::Size>(size), flags));
|
recv(getNativeHandle(), static_cast<char*>(data), static_cast<SocketImpl::Size>(size), flags));
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// Check the number of bytes received
|
// Check the number of bytes received
|
||||||
|
@ -302,7 +302,7 @@ Socket::Status TcpSocket::receive(void* data, std::size_t size, std::size_t& rec
|
||||||
return Socket::Status::Disconnected;
|
return Socket::Status::Disconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
return priv::SocketImpl::getErrorStatus();
|
return SocketImpl::getErrorStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ Socket::Status TcpSocket::send(Packet& packet)
|
||||||
// Send the data block
|
// Send the data block
|
||||||
std::size_t sent = 0;
|
std::size_t sent = 0;
|
||||||
const Status status = send(m_blockToSendBuffer.data() + packet.m_sendPos,
|
const Status status = send(m_blockToSendBuffer.data() + packet.m_sendPos,
|
||||||
static_cast<priv::SocketImpl::Size>(m_blockToSendBuffer.size() - packet.m_sendPos),
|
static_cast<SocketImpl::Size>(m_blockToSendBuffer.size() - packet.m_sendPos),
|
||||||
sent);
|
sent);
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
@ -411,7 +411,7 @@ Socket::Status TcpSocket::receive(Packet& packet)
|
||||||
if (received > 0)
|
if (received > 0)
|
||||||
{
|
{
|
||||||
m_pendingPacket.data.resize(m_pendingPacket.data.size() + received);
|
m_pendingPacket.data.resize(m_pendingPacket.data.size() + received);
|
||||||
std::byte* begin = m_pendingPacket.data.data() + m_pendingPacket.data.size() - received;
|
unsigned char* begin = m_pendingPacket.data.data() + m_pendingPacket.data.size() - received;
|
||||||
std::memcpy(begin, buffer.data(), received);
|
std::memcpy(begin, buffer.data(), received);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,17 +42,18 @@ namespace sf
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
UdpSocket::UdpSocket() : Socket(Type::Udp)
|
UdpSocket::UdpSocket() : Socket(Type::Udp)
|
||||||
{
|
{
|
||||||
|
m_buffer.reserve(MaxDatagramSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
unsigned short UdpSocket::getLocalPort() const
|
unsigned short UdpSocket::getLocalPort() const
|
||||||
{
|
{
|
||||||
if (getNativeHandle() != priv::SocketImpl::invalidSocket())
|
if (getNativeHandle() != SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
// Retrieve information about the local end of the socket
|
// Retrieve information about the local end of the socket
|
||||||
sockaddr_in address{};
|
sockaddr_in address{};
|
||||||
priv::SocketImpl::AddrLength size = sizeof(address);
|
SocketImpl::AddrLength size = sizeof(address);
|
||||||
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
if (getsockname(getNativeHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
|
||||||
{
|
{
|
||||||
return ntohs(address.sin_port);
|
return ntohs(address.sin_port);
|
||||||
|
@ -78,7 +79,7 @@ Socket::Status UdpSocket::bind(unsigned short port, IpAddress address)
|
||||||
return Status::Error;
|
return Status::Error;
|
||||||
|
|
||||||
// Bind the socket
|
// Bind the socket
|
||||||
sockaddr_in addr = priv::SocketImpl::createAddress(address.toInteger(), port);
|
sockaddr_in addr = SocketImpl::createAddress(address.toInteger(), port);
|
||||||
if (::bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1)
|
if (::bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1)
|
||||||
{
|
{
|
||||||
err() << "Failed to bind socket to port " << port << std::endl;
|
err() << "Failed to bind socket to port " << port << std::endl;
|
||||||
|
@ -107,12 +108,12 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, IpAddress rem
|
||||||
if (size > MaxDatagramSize)
|
if (size > MaxDatagramSize)
|
||||||
{
|
{
|
||||||
err() << "Cannot send data over the network "
|
err() << "Cannot send data over the network "
|
||||||
<< "(the number of bytes to send is greater than sf::UdpSocket::MaxDatagramSize)" << std::endl;
|
<< "(the number of bytes to send is greater than UdpSocket::MaxDatagramSize)" << std::endl;
|
||||||
return Status::Error;
|
return Status::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the target address
|
// Build the target address
|
||||||
sockaddr_in address = priv::SocketImpl::createAddress(remoteAddress.toInteger(), remotePort);
|
sockaddr_in address = SocketImpl::createAddress(remoteAddress.toInteger(), remotePort);
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wuseless-cast"
|
#pragma GCC diagnostic ignored "-Wuseless-cast"
|
||||||
|
@ -120,7 +121,7 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, IpAddress rem
|
||||||
const int sent = static_cast<int>(
|
const int sent = static_cast<int>(
|
||||||
sendto(getNativeHandle(),
|
sendto(getNativeHandle(),
|
||||||
static_cast<const char*>(data),
|
static_cast<const char*>(data),
|
||||||
static_cast<priv::SocketImpl::Size>(size),
|
static_cast<SocketImpl::Size>(size),
|
||||||
0,
|
0,
|
||||||
reinterpret_cast<sockaddr*>(&address),
|
reinterpret_cast<sockaddr*>(&address),
|
||||||
sizeof(address)));
|
sizeof(address)));
|
||||||
|
@ -128,7 +129,7 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, IpAddress rem
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
if (sent < 0)
|
if (sent < 0)
|
||||||
return priv::SocketImpl::getErrorStatus();
|
return SocketImpl::getErrorStatus();
|
||||||
|
|
||||||
return Status::Done;
|
return Status::Done;
|
||||||
}
|
}
|
||||||
|
@ -138,12 +139,12 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, IpAddress rem
|
||||||
Socket::Status UdpSocket::receive(void* data,
|
Socket::Status UdpSocket::receive(void* data,
|
||||||
std::size_t size,
|
std::size_t size,
|
||||||
std::size_t& received,
|
std::size_t& received,
|
||||||
std::optional<IpAddress>& remoteAddress,
|
nonstd::optional<IpAddress>& remoteAddress,
|
||||||
unsigned short& remotePort)
|
unsigned short& remotePort)
|
||||||
{
|
{
|
||||||
// First clear the variables to fill
|
// First clear the variables to fill
|
||||||
received = 0;
|
received = 0;
|
||||||
remoteAddress = std::nullopt;
|
remoteAddress = nonstd::nullopt;
|
||||||
remotePort = 0;
|
remotePort = 0;
|
||||||
|
|
||||||
// Check the destination buffer
|
// Check the destination buffer
|
||||||
|
@ -154,16 +155,16 @@ Socket::Status UdpSocket::receive(void* data,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data that will be filled with the other computer's address
|
// Data that will be filled with the other computer's address
|
||||||
sockaddr_in address = priv::SocketImpl::createAddress(INADDR_ANY, 0);
|
sockaddr_in address = SocketImpl::createAddress(INADDR_ANY, 0);
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wuseless-cast"
|
#pragma GCC diagnostic ignored "-Wuseless-cast"
|
||||||
// Receive a chunk of bytes
|
// Receive a chunk of bytes
|
||||||
priv::SocketImpl::AddrLength addressSize = sizeof(address);
|
SocketImpl::AddrLength addressSize = sizeof(address);
|
||||||
const int sizeReceived = static_cast<int>(
|
const int sizeReceived = static_cast<int>(
|
||||||
recvfrom(getNativeHandle(),
|
recvfrom(getNativeHandle(),
|
||||||
static_cast<char*>(data),
|
static_cast<char*>(data),
|
||||||
static_cast<priv::SocketImpl::Size>(size),
|
static_cast<SocketImpl::Size>(size),
|
||||||
0,
|
0,
|
||||||
reinterpret_cast<sockaddr*>(&address),
|
reinterpret_cast<sockaddr*>(&address),
|
||||||
&addressSize));
|
&addressSize));
|
||||||
|
@ -171,7 +172,7 @@ Socket::Status UdpSocket::receive(void* data,
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
if (sizeReceived < 0)
|
if (sizeReceived < 0)
|
||||||
return priv::SocketImpl::getErrorStatus();
|
return SocketImpl::getErrorStatus();
|
||||||
|
|
||||||
// Fill the sender information
|
// Fill the sender information
|
||||||
received = static_cast<std::size_t>(sizeReceived);
|
received = static_cast<std::size_t>(sizeReceived);
|
||||||
|
@ -203,7 +204,7 @@ Socket::Status UdpSocket::send(Packet& packet, IpAddress remoteAddress, unsigned
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Socket::Status UdpSocket::receive(Packet& packet, std::optional<IpAddress>& remoteAddress, unsigned short& remotePort)
|
Socket::Status UdpSocket::receive(Packet& packet, nonstd::optional<IpAddress>& remoteAddress, unsigned short& remotePort)
|
||||||
{
|
{
|
||||||
// See the detailed comment in send(Packet) above.
|
// See the detailed comment in send(Packet) above.
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
sockaddr_in SocketImpl::createAddress(std::uint32_t address, unsigned short port)
|
sockaddr_in SocketImpl::createAddress(std::uint32_t address, unsigned short port)
|
||||||
|
@ -108,4 +108,4 @@ Socket::Status SocketImpl::getErrorStatus()
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct SocketInitializer
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
sockaddr_in SocketImpl::createAddress(std::uint32_t address, unsigned short port)
|
sockaddr_in SocketImpl::createAddress(std::uint32_t address, unsigned short port)
|
||||||
|
@ -107,4 +107,4 @@ Socket::Status SocketImpl::getErrorStatus()
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -49,7 +49,7 @@ std::streambuf::int_type LogcatStream::overflow(std::streambuf::int_type c)
|
||||||
return traits_type::not_eof(c);
|
return traits_type::not_eof(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
|
|
||||||
ActivityStates*& getActivityStatesPtr()
|
ActivityStates*& getActivityStatesPtr()
|
||||||
|
@ -67,8 +67,8 @@ ActivityStates& getActivity()
|
||||||
{
|
{
|
||||||
ActivityStates* const states = getActivityStatesPtr();
|
ActivityStates* const states = getActivityStatesPtr();
|
||||||
assert(states != nullptr &&
|
assert(states != nullptr &&
|
||||||
"Cannot dereference null activity states pointer. Call priv::resetActivity() to initialize it.");
|
"Cannot dereference null activity states pointer. Call resetActivity() to initialize it.");
|
||||||
return *states;
|
return *states;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -54,7 +54,7 @@ private:
|
||||||
std::string m_message;
|
std::string m_message;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
struct ActivityStates
|
struct ActivityStates
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ struct ActivityStates
|
||||||
EGLDisplay display{};
|
EGLDisplay display{};
|
||||||
EglContext* context{};
|
EglContext* context{};
|
||||||
|
|
||||||
std::vector<std::byte> savedState;
|
std::vector<unsigned char> savedState;
|
||||||
|
|
||||||
std::recursive_mutex mutex;
|
std::recursive_mutex mutex;
|
||||||
|
|
||||||
|
@ -100,4 +100,4 @@ SFML_SYSTEM_API void resetActivity(ActivityStates* initializedStates);
|
||||||
|
|
||||||
SFML_SYSTEM_API ActivityStates& getActivity();
|
SFML_SYSTEM_API ActivityStates& getActivity();
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace sf
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
ANativeActivity* getNativeActivity()
|
ANativeActivity* getNativeActivity()
|
||||||
{
|
{
|
||||||
return priv::getActivity().activity;
|
return getActivity().activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool ResourceStream::open(const std::filesystem::path& filename)
|
bool ResourceStream::open(const ghc::filesystem::path& filename)
|
||||||
{
|
{
|
||||||
ActivityStates& states = getActivity();
|
ActivityStates& states = getActivity();
|
||||||
const std::lock_guard lock(states.mutex);
|
const std::lock_guard lock(states.mutex);
|
||||||
|
@ -45,29 +45,29 @@ bool ResourceStream::open(const std::filesystem::path& filename)
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> ResourceStream::read(void* data, std::size_t size)
|
nonstd::optional<std::size_t> ResourceStream::read(void* data, std::size_t size)
|
||||||
{
|
{
|
||||||
assert(m_file && "ResourceStream::read() cannot be called when file is not initialized");
|
assert(m_file && "ResourceStream::read() cannot be called when file is not initialized");
|
||||||
const auto numBytesRead = AAsset_read(m_file.get(), data, size);
|
const auto numBytesRead = AAsset_read(m_file.get(), data, size);
|
||||||
if (numBytesRead < 0)
|
if (numBytesRead < 0)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
return numBytesRead;
|
return numBytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> ResourceStream::seek(std::size_t position)
|
nonstd::optional<std::size_t> ResourceStream::seek(std::size_t position)
|
||||||
{
|
{
|
||||||
assert(m_file && "ResourceStream::seek() cannot be called when file is not initialized");
|
assert(m_file && "ResourceStream::seek() cannot be called when file is not initialized");
|
||||||
const auto newPosition = AAsset_seek(m_file.get(), static_cast<off_t>(position), SEEK_SET);
|
const auto newPosition = AAsset_seek(m_file.get(), static_cast<off_t>(position), SEEK_SET);
|
||||||
if (newPosition < 0)
|
if (newPosition < 0)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
return newPosition;
|
return newPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> ResourceStream::tell()
|
nonstd::optional<std::size_t> ResourceStream::tell()
|
||||||
{
|
{
|
||||||
assert(m_file && "ResourceStream::tell() cannot be called when file is not initialized");
|
assert(m_file && "ResourceStream::tell() cannot be called when file is not initialized");
|
||||||
return getSize().value() - static_cast<std::size_t>(AAsset_getRemainingLength(m_file.get()));
|
return getSize().value() - static_cast<std::size_t>(AAsset_getRemainingLength(m_file.get()));
|
||||||
|
@ -75,7 +75,7 @@ std::optional<std::size_t> ResourceStream::tell()
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> ResourceStream::getSize()
|
nonstd::optional<std::size_t> ResourceStream::getSize()
|
||||||
{
|
{
|
||||||
assert(m_file && "ResourceStream::getSize() cannot be called when file is not initialized");
|
assert(m_file && "ResourceStream::getSize() cannot be called when file is not initialized");
|
||||||
return AAsset_getLength(m_file.get());
|
return AAsset_getLength(m_file.get());
|
||||||
|
@ -88,4 +88,4 @@ void ResourceStream::AAssetDeleter::operator()(AAsset* file)
|
||||||
AAsset_close(file);
|
AAsset_close(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -33,11 +33,11 @@
|
||||||
|
|
||||||
#include <android/asset_manager.h>
|
#include <android/asset_manager.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include "filesystem.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Read from Android asset files
|
/// \brief Read from Android asset files
|
||||||
|
@ -62,7 +62,7 @@ public:
|
||||||
/// \return `true` on success, `false` on error
|
/// \return `true` on success, `false` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
[[nodiscard]] bool open(const std::filesystem::path& filename);
|
[[nodiscard]] bool open(const ghc::filesystem::path& filename);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Read data from the asset
|
/// \brief Read data from the asset
|
||||||
|
@ -70,36 +70,36 @@ public:
|
||||||
/// \param data Buffer where the asset data is copied
|
/// \param data Buffer where the asset data is copied
|
||||||
/// \param size Number of bytes read
|
/// \param size Number of bytes read
|
||||||
///
|
///
|
||||||
/// \return The number of bytes actually read, or `std::nullopt` on error
|
/// \return The number of bytes actually read, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> read(void* data, std::size_t size) override;
|
nonstd::optional<std::size_t> read(void* data, std::size_t size) override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Change the current reading position in the asset file
|
/// \brief Change the current reading position in the asset file
|
||||||
///
|
///
|
||||||
/// \param position The position to seek to, from the beginning
|
/// \param position The position to seek to, from the beginning
|
||||||
///
|
///
|
||||||
/// \return The position actually sought to, or `std::nullopt` on error
|
/// \return The position actually sought to, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> seek(std::size_t position) override;
|
nonstd::optional<std::size_t> seek(std::size_t position) override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get the current reading position in the asset file
|
/// \brief Get the current reading position in the asset file
|
||||||
///
|
///
|
||||||
/// \return The current position, or `std::nullopt` on error.
|
/// \return The current position, or `nonstd::nullopt` on error.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> tell() override;
|
nonstd::optional<std::size_t> tell() override;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Return the size of the asset file
|
/// \brief Return the size of the asset file
|
||||||
///
|
///
|
||||||
/// \return The total number of bytes available in the asset, or `std::nullopt` on error
|
/// \return The total number of bytes available in the asset, or `nonstd::nullopt` on error
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> getSize() override;
|
nonstd::optional<std::size_t> getSize() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -116,4 +116,4 @@ private:
|
||||||
std::unique_ptr<AAsset, AAssetDeleter> m_file; ///< The asset file to read
|
std::unique_ptr<AAsset, AAssetDeleter> m_file; ///< The asset file to read
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -94,3 +94,5 @@ elseif(WIN32)
|
||||||
elseif(ANDROID)
|
elseif(ANDROID)
|
||||||
target_link_libraries(sfml-system PRIVATE android log)
|
target_link_libraries(sfml-system PRIVATE android log)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(sfml-system PRIVATE nonstd-lib ghc-filesystem)
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace sf
|
||||||
Time Clock::getElapsedTime() const
|
Time Clock::getElapsedTime() const
|
||||||
{
|
{
|
||||||
if (isRunning())
|
if (isRunning())
|
||||||
return std::chrono::duration_cast<std::chrono::microseconds>(priv::ClockImpl::now() - m_refPoint);
|
return std::chrono::duration_cast<std::chrono::microseconds>(ClockImpl::now() - m_refPoint);
|
||||||
return std::chrono::duration_cast<std::chrono::microseconds>(m_stopPoint - m_refPoint);
|
return std::chrono::duration_cast<std::chrono::microseconds>(m_stopPoint - m_refPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ Time Clock::getElapsedTime() const
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool Clock::isRunning() const
|
bool Clock::isRunning() const
|
||||||
{
|
{
|
||||||
return m_stopPoint == priv::ClockImpl::time_point();
|
return m_stopPoint == ClockImpl::time_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ void Clock::start()
|
||||||
{
|
{
|
||||||
if (!isRunning())
|
if (!isRunning())
|
||||||
{
|
{
|
||||||
m_refPoint += priv::ClockImpl::now() - m_stopPoint;
|
m_refPoint += ClockImpl::now() - m_stopPoint;
|
||||||
m_stopPoint = {};
|
m_stopPoint = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ void Clock::start()
|
||||||
void Clock::stop()
|
void Clock::stop()
|
||||||
{
|
{
|
||||||
if (isRunning())
|
if (isRunning())
|
||||||
m_stopPoint = priv::ClockImpl::now();
|
m_stopPoint = ClockImpl::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ void Clock::stop()
|
||||||
Time Clock::restart()
|
Time Clock::restart()
|
||||||
{
|
{
|
||||||
const Time elapsed = getElapsedTime();
|
const Time elapsed = getElapsedTime();
|
||||||
m_refPoint = priv::ClockImpl::now();
|
m_refPoint = ClockImpl::now();
|
||||||
m_stopPoint = {};
|
m_stopPoint = {};
|
||||||
return elapsed;
|
return elapsed;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ Time Clock::restart()
|
||||||
Time Clock::reset()
|
Time Clock::reset()
|
||||||
{
|
{
|
||||||
const Time elapsed = getElapsedTime();
|
const Time elapsed = getElapsedTime();
|
||||||
m_refPoint = priv::ClockImpl::now();
|
m_refPoint = ClockImpl::now();
|
||||||
m_stopPoint = m_refPoint;
|
m_stopPoint = m_refPoint;
|
||||||
return elapsed;
|
return elapsed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Fixed-size array container indexed by an enumeration
|
/// \brief Fixed-size array container indexed by an enumeration
|
||||||
|
@ -72,4 +72,4 @@ struct EnumArray : public std::array<Value, Count>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -50,7 +50,7 @@ FileInputStream::FileInputStream() = default;
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
FileInputStream::FileInputStream(const std::filesystem::path& filename)
|
FileInputStream::FileInputStream(const ghc::filesystem::path& filename)
|
||||||
{
|
{
|
||||||
if (!open(filename))
|
if (!open(filename))
|
||||||
throw Exception("Failed to open file input stream");
|
throw Exception("Failed to open file input stream");
|
||||||
|
@ -70,12 +70,12 @@ FileInputStream& FileInputStream::operator=(FileInputStream&&) noexcept = defaul
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool FileInputStream::open(const std::filesystem::path& filename)
|
bool FileInputStream::open(const ghc::filesystem::path& filename)
|
||||||
{
|
{
|
||||||
#ifdef SFML_SYSTEM_ANDROID
|
#ifdef SFML_SYSTEM_ANDROID
|
||||||
if (priv::getActivityStatesPtr() != nullptr)
|
if (getActivityStatesPtr() != nullptr)
|
||||||
{
|
{
|
||||||
m_androidFile = std::make_unique<priv::ResourceStream>();
|
m_androidFile = std::make_unique<ResourceStream>();
|
||||||
if (!m_androidFile->open(filename))
|
if (!m_androidFile->open(filename))
|
||||||
return false;
|
return false;
|
||||||
return m_androidFile->tell().has_value();
|
return m_androidFile->tell().has_value();
|
||||||
|
@ -87,79 +87,79 @@ bool FileInputStream::open(const std::filesystem::path& filename)
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> FileInputStream::read(void* data, std::size_t size)
|
nonstd::optional<std::size_t> FileInputStream::read(void* data, std::size_t size)
|
||||||
{
|
{
|
||||||
#ifdef SFML_SYSTEM_ANDROID
|
#ifdef SFML_SYSTEM_ANDROID
|
||||||
if (priv::getActivityStatesPtr() != nullptr)
|
if (getActivityStatesPtr() != nullptr)
|
||||||
{
|
{
|
||||||
if (!m_androidFile)
|
if (!m_androidFile)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
return m_androidFile->read(data, size);
|
return m_androidFile->read(data, size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!m_file)
|
if (!m_file)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
return std::fread(data, 1, size, m_file.get());
|
return std::fread(data, 1, size, m_file.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> FileInputStream::seek(std::size_t position)
|
nonstd::optional<std::size_t> FileInputStream::seek(std::size_t position)
|
||||||
{
|
{
|
||||||
#ifdef SFML_SYSTEM_ANDROID
|
#ifdef SFML_SYSTEM_ANDROID
|
||||||
if (priv::getActivityStatesPtr() != nullptr)
|
if (getActivityStatesPtr() != nullptr)
|
||||||
{
|
{
|
||||||
if (!m_androidFile)
|
if (!m_androidFile)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
return m_androidFile->seek(position);
|
return m_androidFile->seek(position);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!m_file)
|
if (!m_file)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
if (std::fseek(m_file.get(), static_cast<long>(position), SEEK_SET))
|
if (std::fseek(m_file.get(), static_cast<long>(position), SEEK_SET))
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
|
|
||||||
return tell();
|
return tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> FileInputStream::tell()
|
nonstd::optional<std::size_t> FileInputStream::tell()
|
||||||
{
|
{
|
||||||
#ifdef SFML_SYSTEM_ANDROID
|
#ifdef SFML_SYSTEM_ANDROID
|
||||||
if (priv::getActivityStatesPtr() != nullptr)
|
if (getActivityStatesPtr() != nullptr)
|
||||||
{
|
{
|
||||||
if (!m_androidFile)
|
if (!m_androidFile)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
return m_androidFile->tell();
|
return m_androidFile->tell();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!m_file)
|
if (!m_file)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
const auto position = std::ftell(m_file.get());
|
const auto position = std::ftell(m_file.get());
|
||||||
return position < 0 ? std::nullopt : std::optional<std::size_t>(position);
|
return position < 0 ? nonstd::nullopt : nonstd::optional<std::size_t>(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> FileInputStream::getSize()
|
nonstd::optional<std::size_t> FileInputStream::getSize()
|
||||||
{
|
{
|
||||||
#ifdef SFML_SYSTEM_ANDROID
|
#ifdef SFML_SYSTEM_ANDROID
|
||||||
if (priv::getActivityStatesPtr() != nullptr)
|
if (getActivityStatesPtr() != nullptr)
|
||||||
{
|
{
|
||||||
if (!m_androidFile)
|
if (!m_androidFile)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
return m_androidFile->getSize();
|
return m_androidFile->getSize();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!m_file)
|
if (!m_file)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
const auto position = tell().value();
|
const auto position = tell().value();
|
||||||
std::fseek(m_file.get(), 0, SEEK_END);
|
std::fseek(m_file.get(), 0, SEEK_END);
|
||||||
const std::optional size = tell();
|
const nonstd::optional<size_t> size = tell();
|
||||||
|
|
||||||
if (!seek(position).has_value())
|
if (!seek(position).has_value())
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,17 +36,17 @@ namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
MemoryInputStream::MemoryInputStream(const void* data, std::size_t sizeInBytes) :
|
MemoryInputStream::MemoryInputStream(const void* data, std::size_t sizeInBytes) :
|
||||||
m_data(static_cast<const std::byte*>(data)),
|
m_data(static_cast<const unsigned char*>(data)),
|
||||||
m_size(sizeInBytes)
|
m_size(sizeInBytes)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> MemoryInputStream::read(void* data, std::size_t size)
|
nonstd::optional<std::size_t> MemoryInputStream::read(void* data, std::size_t size)
|
||||||
{
|
{
|
||||||
if (!m_data)
|
if (!m_data)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
|
|
||||||
const std::size_t count = std::min(size, m_size - m_offset);
|
const std::size_t count = std::min(size, m_size - m_offset);
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
|
@ -60,10 +60,10 @@ std::optional<std::size_t> MemoryInputStream::read(void* data, std::size_t size)
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> MemoryInputStream::seek(std::size_t position)
|
nonstd::optional<std::size_t> MemoryInputStream::seek(std::size_t position)
|
||||||
{
|
{
|
||||||
if (!m_data)
|
if (!m_data)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
|
|
||||||
m_offset = position < m_size ? position : m_size;
|
m_offset = position < m_size ? position : m_size;
|
||||||
return m_offset;
|
return m_offset;
|
||||||
|
@ -71,20 +71,20 @@ std::optional<std::size_t> MemoryInputStream::seek(std::size_t position)
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> MemoryInputStream::tell()
|
nonstd::optional<std::size_t> MemoryInputStream::tell()
|
||||||
{
|
{
|
||||||
if (!m_data)
|
if (!m_data)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
|
|
||||||
return m_offset;
|
return m_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::optional<std::size_t> MemoryInputStream::getSize()
|
nonstd::optional<std::size_t> MemoryInputStream::getSize()
|
||||||
{
|
{
|
||||||
if (!m_data)
|
if (!m_data)
|
||||||
return std::nullopt;
|
return nonstd::nullopt;
|
||||||
|
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ void sleep(Time duration)
|
||||||
// as it results in inconsistent sleeping times under MinGW-w64.
|
// as it results in inconsistent sleeping times under MinGW-w64.
|
||||||
|
|
||||||
if (duration >= Time::Zero)
|
if (duration >= Time::Zero)
|
||||||
priv::sleepImpl(duration);
|
sleepImpl(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void sleepImpl(Time time)
|
void sleepImpl(Time time)
|
||||||
|
@ -54,4 +54,4 @@ void sleepImpl(Time time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace sf
|
||||||
class Time;
|
class Time;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Unix implementation of sf::Sleep
|
/// \brief Unix implementation of sf::Sleep
|
||||||
|
@ -45,4 +45,4 @@ namespace sf::priv
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void sleepImpl(Time time);
|
void sleepImpl(Time time);
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/Utils.hpp>
|
#include <SFML/System/Utils.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
@ -41,17 +42,17 @@ std::string toLower(std::string str)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string formatDebugPathInfo(const std::filesystem::path& path)
|
std::string formatDebugPathInfo(const ghc::filesystem::path& path)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
// convert to UTF-8 to handle non-ascii/non-latin1 filenames on windows
|
// convert to UTF-8 to handle non-ascii/non-latin1 filenames on windows
|
||||||
// cast is required to work in C++20 where u8string is char8_t which can't be printed to char stream
|
// cast is required to work in C++20 where u8string is char8_t which can't be printed to char stream
|
||||||
oss << " Provided path: " << reinterpret_cast<const char*>(path.u8string().c_str()) << '\n' //
|
oss << " Provided path: " << reinterpret_cast<const char*>(path.u8string().c_str()) << '\n' //
|
||||||
<< " Absolute path: " << reinterpret_cast<const char*>(std::filesystem::absolute(path).u8string().c_str());
|
<< " Absolute path: " << reinterpret_cast<const char*>(ghc::filesystem::absolute(path).u8string().c_str());
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::FILE* openFile(const std::filesystem::path& filename, std::string_view mode)
|
std::FILE* openFile(const ghc::filesystem::path& filename, std::string mode)
|
||||||
{
|
{
|
||||||
#ifdef SFML_SYSTEM_WINDOWS
|
#ifdef SFML_SYSTEM_WINDOWS
|
||||||
const std::wstring wmode(mode.begin(), mode.end());
|
const std::wstring wmode(mode.begin(), mode.end());
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/Export.hpp>
|
#include <SFML/System/Export.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <array>
|
||||||
|
#include "filesystem.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -40,19 +40,22 @@
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
[[nodiscard]] SFML_SYSTEM_API std::string toLower(std::string str);
|
[[nodiscard]] SFML_SYSTEM_API std::string toLower(std::string str);
|
||||||
[[nodiscard]] SFML_SYSTEM_API std::string formatDebugPathInfo(const std::filesystem::path& path);
|
[[nodiscard]] SFML_SYSTEM_API std::string formatDebugPathInfo(const ghc::filesystem::path& path);
|
||||||
|
|
||||||
// Convert byte sequence into integer
|
// Convert byte sequence into integer
|
||||||
// toInteger<int>(0x12, 0x34, 0x56) == 0x563412
|
// toInteger<int>(0x12, 0x34, 0x56) == 0x563412
|
||||||
template <typename IntegerType, typename... Bytes>
|
template <typename IntegerType>
|
||||||
[[nodiscard]] constexpr IntegerType toInteger(Bytes... byte)
|
[[nodiscard]] constexpr IntegerType toInteger(std::array<unsigned char,8> bytes)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(IntegerType) >= sizeof...(Bytes), "IntegerType not large enough to contain bytes");
|
return ((IntegerType)(bytes[0] << 0)+
|
||||||
|
(IntegerType)(bytes[1] << 8)+
|
||||||
IntegerType integer = 0;
|
(IntegerType)(bytes[2] << 16)+
|
||||||
std::size_t index = 0;
|
(IntegerType)(bytes[3] << 24)+
|
||||||
return ((integer |= static_cast<IntegerType>(static_cast<IntegerType>(byte) << 8 * index++)), ...);
|
(IntegerType)(bytes[4] << 32)+
|
||||||
|
(IntegerType)(bytes[5] << 40)+
|
||||||
|
(IntegerType)(bytes[6] << 48)+
|
||||||
|
(IntegerType)(bytes[7] << 56));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] SFML_SYSTEM_API std::FILE* openFile(const std::filesystem::path& filename, std::string_view mode);
|
[[nodiscard]] SFML_SYSTEM_API std::FILE* openFile(const ghc::filesystem::path& filename, std::string mode);
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace sf
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2<T> Vector2<T>::normalized() const
|
Vector2<T> Vector2<T>::normalized() const
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector2::normalized() is only supported for floating point types");
|
// static_assert(std::is_floating_point_v<T>, "Vector2::normalized() is only supported for floating point types");
|
||||||
|
|
||||||
assert(*this != Vector2<T>() && "Vector2::normalized() cannot normalize a zero vector");
|
assert(*this != Vector2<T>() && "Vector2::normalized() cannot normalize a zero vector");
|
||||||
return (*this) / length();
|
return (*this) / length();
|
||||||
|
@ -47,7 +47,7 @@ Vector2<T> Vector2<T>::normalized() const
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Angle Vector2<T>::angleTo(Vector2<T> rhs) const
|
Angle Vector2<T>::angleTo(Vector2<T> rhs) const
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector2::angleTo() is only supported for floating point types");
|
// static_assert(std::is_floating_point_v<T>, "Vector2::angleTo() is only supported for floating point types");
|
||||||
|
|
||||||
assert(*this != Vector2<T>() && "Vector2::angleTo() cannot calculate angle from a zero vector");
|
assert(*this != Vector2<T>() && "Vector2::angleTo() cannot calculate angle from a zero vector");
|
||||||
assert(rhs != Vector2<T>() && "Vector2::angleTo() cannot calculate angle to a zero vector");
|
assert(rhs != Vector2<T>() && "Vector2::angleTo() cannot calculate angle to a zero vector");
|
||||||
|
@ -59,7 +59,7 @@ Angle Vector2<T>::angleTo(Vector2<T> rhs) const
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Angle Vector2<T>::angle() const
|
Angle Vector2<T>::angle() const
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector2::angle() is only supported for floating point types");
|
//static_assert(std::is_floating_point_v<T>, "Vector2::angle() is only supported for floating point types");
|
||||||
|
|
||||||
assert(*this != Vector2<T>() && "Vector2::angle() cannot calculate angle from a zero vector");
|
assert(*this != Vector2<T>() && "Vector2::angle() cannot calculate angle from a zero vector");
|
||||||
return radians(static_cast<float>(std::atan2(y, x)));
|
return radians(static_cast<float>(std::atan2(y, x)));
|
||||||
|
@ -70,7 +70,7 @@ Angle Vector2<T>::angle() const
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2<T> Vector2<T>::rotatedBy(Angle phi) const
|
Vector2<T> Vector2<T>::rotatedBy(Angle phi) const
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector2::rotatedBy() is only supported for floating point types");
|
// static_assert(std::is_floating_point_v<T>, "Vector2::rotatedBy() is only supported for floating point types");
|
||||||
|
|
||||||
// No zero vector assert, because rotating a zero vector is well-defined (yields always itself)
|
// No zero vector assert, because rotating a zero vector is well-defined (yields always itself)
|
||||||
T cos = std::cos(static_cast<T>(phi.asRadians()));
|
T cos = std::cos(static_cast<T>(phi.asRadians()));
|
||||||
|
@ -85,7 +85,7 @@ Vector2<T> Vector2<T>::rotatedBy(Angle phi) const
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector2<T> Vector2<T>::projectedOnto(Vector2<T> axis) const
|
Vector2<T> Vector2<T>::projectedOnto(Vector2<T> axis) const
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector2::projectedOnto() is only supported for floating point types");
|
// static_assert(std::is_floating_point_v<T>, "Vector2::projectedOnto() is only supported for floating point types");
|
||||||
|
|
||||||
assert(axis != Vector2<T>() && "Vector2::projectedOnto() cannot project onto a zero vector");
|
assert(axis != Vector2<T>() && "Vector2::projectedOnto() cannot project onto a zero vector");
|
||||||
return dot(axis) / axis.lengthSquared() * axis;
|
return dot(axis) / axis.lengthSquared() * axis;
|
||||||
|
@ -98,7 +98,7 @@ Vector2<T>::Vector2(T r, Angle phi) :
|
||||||
x(r * static_cast<T>(std::cos(phi.asRadians()))),
|
x(r * static_cast<T>(std::cos(phi.asRadians()))),
|
||||||
y(r * static_cast<T>(std::sin(phi.asRadians())))
|
y(r * static_cast<T>(std::sin(phi.asRadians())))
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector2::Vector2(T, Angle) is only supported for floating point types");
|
// static_assert(std::is_floating_point_v<T>, "Vector2::Vector2(T, Angle) is only supported for floating point types");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ y(r * static_cast<T>(std::sin(phi.asRadians())))
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Vector2<T>::length() const
|
T Vector2<T>::length() const
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector2::length() is only supported for floating point types");
|
// static_assert(std::is_floating_point_v<T>, "Vector2::length() is only supported for floating point types");
|
||||||
|
|
||||||
// don't use std::hypot because of slow performance
|
// don't use std::hypot because of slow performance
|
||||||
return std::sqrt(x * x + y * y);
|
return std::sqrt(x * x + y * y);
|
||||||
|
@ -119,6 +119,6 @@ T Vector2<T>::length() const
|
||||||
// Explicit template instantiations
|
// Explicit template instantiations
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template class sf::Vector2<float>;
|
//template class sf::Vector2<float>;
|
||||||
template class sf::Vector2<double>;
|
//template class sf::Vector2<double>;
|
||||||
template class sf::Vector2<long double>;
|
//template class sf::Vector2<long double>;
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace sf
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector3<T> Vector3<T>::normalized() const
|
Vector3<T> Vector3<T>::normalized() const
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector3::normalized() is only supported for floating point types");
|
// static_assert(std::is_floating_point_v<T>, "Vector3::normalized() is only supported for floating point types");
|
||||||
|
|
||||||
assert(*this != Vector3<T>() && "Vector3::normalized() cannot normalize a zero vector");
|
assert(*this != Vector3<T>() && "Vector3::normalized() cannot normalize a zero vector");
|
||||||
return (*this) / length();
|
return (*this) / length();
|
||||||
|
@ -47,7 +47,7 @@ Vector3<T> Vector3<T>::normalized() const
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Vector3<T>::length() const
|
T Vector3<T>::length() const
|
||||||
{
|
{
|
||||||
static_assert(std::is_floating_point_v<T>, "Vector3::length() is only supported for floating point types");
|
// static_assert(std::is_floating_point_v<T>, "Vector3::length() is only supported for floating point types");
|
||||||
|
|
||||||
// don't use std::hypot because of slow performance
|
// don't use std::hypot because of slow performance
|
||||||
return std::sqrt(x * x + y * y + z * z);
|
return std::sqrt(x * x + y * y + z * z);
|
||||||
|
@ -60,6 +60,6 @@ T Vector3<T>::length() const
|
||||||
// Explicit template instantiations
|
// Explicit template instantiations
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template class sf::Vector3<float>;
|
//template class sf::Vector3<float>;
|
||||||
template class sf::Vector3<double>;
|
//template class sf::Vector3<double>;
|
||||||
template class sf::Vector3<long double>;
|
//template class sf::Vector3<long double>;
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void sleepImpl(Time time)
|
void sleepImpl(Time time)
|
||||||
|
@ -54,4 +54,4 @@ void sleepImpl(Time time)
|
||||||
timeEndPeriod(periodMin);
|
timeEndPeriod(periodMin);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace sf
|
||||||
class Time;
|
class Time;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf
|
||||||
{
|
{
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -45,4 +45,4 @@ namespace sf::priv
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void sleepImpl(Time time);
|
void sleepImpl(Time time);
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf
|
||||||
|
|
|
@ -52,16 +52,18 @@ case "$1" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Intel builds target 10.10 (Yosemite.)
|
||||||
|
export MACOSX_DEPLOYMENT_TARGET=10.10
|
||||||
|
|
||||||
if [ -n "$APPLE_SILICON" ]; then
|
if [ -n "$APPLE_SILICON" ]; then
|
||||||
if [ -n "$intel_target" ]; then
|
if [ -n "$intel_target" ]; then
|
||||||
target_build_arch='-target x86_64-apple-macos10.15 -march=core2 -mtune=skylake'
|
target_build_arch='-target x86_64-apple-macos10.15 -march=core2 -mtune=skylake'
|
||||||
target_cpu=x86_64
|
target_cpu=x86_64
|
||||||
export MACOSX_DEPLOYMENT_TARGET=10.15 # Catalina
|
|
||||||
else
|
else
|
||||||
export MACOSX_DEPLOYMENT_TARGET=11.0 # Big Sur
|
export MACOSX_DEPLOYMENT_TARGET=11.0 # Big Sur
|
||||||
fi
|
fi
|
||||||
elif [ "$target_cpu" = x86_64 ]; then
|
elif [ "$target_cpu" = x86_64 ]; then
|
||||||
target_build_arch='-m64 -march=core2 -mtune=skylake'
|
target_build_arch="-m64 -march=core2 -mtune=skylake -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Need to use Xcode 9 for 32 bit builds on Mojave and newer.
|
# Need to use Xcode 9 for 32 bit builds on Mojave and newer.
|
||||||
|
@ -80,6 +82,10 @@ elif [ -f /opt/homebrew/bin/brew ]; then
|
||||||
export BREW_PREFIX=$(/opt/homebrew/bin/brew --prefix)
|
export BREW_PREFIX=$(/opt/homebrew/bin/brew --prefix)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -n "$BREW_PREFIX" ]; then
|
||||||
|
"$BREW_PREFIX"/bin/brew unlink gettext >/dev/null 2>&1 || :
|
||||||
|
fi
|
||||||
|
|
||||||
export BUILD_ROOT="${BUILD_ROOT:-$HOME/vbam-build-mac-${target_cpu}}$BUILD_ROOT_SUFFIX"
|
export BUILD_ROOT="${BUILD_ROOT:-$HOME/vbam-build-mac-${target_cpu}}$BUILD_ROOT_SUFFIX"
|
||||||
|
|
||||||
ver_file=$(mktemp)
|
ver_file=$(mktemp)
|
||||||
|
@ -88,7 +94,7 @@ read -r macos_major macos_minor macos_patch < "$ver_file"
|
||||||
rm -f "$ver_file"
|
rm -f "$ver_file"
|
||||||
|
|
||||||
# Find the highest version clang and llvm in Nix or Homebrew.
|
# Find the highest version clang and llvm in Nix or Homebrew.
|
||||||
best_llvm=$(
|
best_llvm_path=$(
|
||||||
(
|
(
|
||||||
for nix_clang in $(find /nix/store -maxdepth 1 -type d -name '*-clang-[0-9]*[0-9]'); do
|
for nix_clang in $(find /nix/store -maxdepth 1 -type d -name '*-clang-[0-9]*[0-9]'); do
|
||||||
llvm_ver=$(echo "$nix_clang" | sed -E 's/.*-([0-9][0-9.]*[0-9])$/\1/')
|
llvm_ver=$(echo "$nix_clang" | sed -E 's/.*-([0-9][0-9.]*[0-9])$/\1/')
|
||||||
|
@ -99,7 +105,7 @@ best_llvm=$(
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
for brew_llvm in $(find "$BREW_PREFIX"/Cellar -maxdepth 1 -type l -name 'llvm*'); do
|
for brew_llvm in $(find "$BREW_PREFIX"/Cellar/llvm -maxdepth 1 -type d 2>/dev/null); do
|
||||||
if [ -x "$brew_llvm/bin/clang++" ]; then
|
if [ -x "$brew_llvm/bin/clang++" ]; then
|
||||||
echo "$brew_llvm $($brew_llvm/bin/clang++ --version | head -1 | awk '{ print $NF }')"
|
echo "$brew_llvm $($brew_llvm/bin/clang++ --version | head -1 | awk '{ print $NF }')"
|
||||||
fi
|
fi
|
||||||
|
@ -107,15 +113,19 @@ best_llvm=$(
|
||||||
) | sort -k2,2 -V -r | head -1 | awk '{ print $1 }'
|
) | sort -k2,2 -V -r | head -1 | awk '{ print $1 }'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Fallback to XCode version.
|
||||||
|
[ -z "$best_llvm_path" ] && best_llvm_path=/usr
|
||||||
|
|
||||||
|
clang_path=${best_llvm_path%%:*}
|
||||||
|
|
||||||
BUILD_ENV=$(cat <<EOF
|
BUILD_ENV=$(cat <<EOF
|
||||||
export MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET
|
export MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET
|
||||||
export COMMAND_MODE=unix2003
|
export COMMAND_MODE=unix2003
|
||||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:"$BREW_PREFIX"/bin
|
export PATH="$best_llvm_path/bin:/usr/bin:/bin:/usr/sbin:/sbin:$BREW_PREFIX/bin"
|
||||||
|
|
||||||
[ -n "$best_llvm" ] && export PATH="$best_llvm/bin:\$PATH"
|
export CC="$clang_path/bin/clang"
|
||||||
|
export CPP="$clang_path/bin/clang -E"
|
||||||
export CC=clang
|
export CXX="$clang_path/bin/clang++"
|
||||||
export CXX=clang++
|
|
||||||
export CPPFLAGS=-DICONV_CONST=
|
export CPPFLAGS=-DICONV_CONST=
|
||||||
export CFLAGS="$target_build_arch -framework Carbon -framework Foundation -framework CoreServices -framework SystemConfiguration -Wno-unused-command-line-argument -DICONV_CONST= -Wl,-no_compact_unwind"
|
export CFLAGS="$target_build_arch -framework Carbon -framework Foundation -framework CoreServices -framework SystemConfiguration -Wno-unused-command-line-argument -DICONV_CONST= -Wl,-no_compact_unwind"
|
||||||
export CXXFLAGS="$target_build_arch -framework Carbon -framework Foundation -framework CoreServices -framework SystemConfiguration -Wno-unused-command-line-argument -DICONV_CONST= -Wl,-no_compact_unwind"
|
export CXXFLAGS="$target_build_arch -framework Carbon -framework Foundation -framework CoreServices -framework SystemConfiguration -Wno-unused-command-line-argument -DICONV_CONST= -Wl,-no_compact_unwind"
|
||||||
|
|
Loading…
Reference in New Issue