From ed486713d01067bb715d4908da7cfc8e63d9b9a4 Mon Sep 17 00:00:00 2001 From: Light Date: Thu, 9 Sep 2021 19:46:02 +0430 Subject: [PATCH] Converted from premake5 to CMake --- .gitmodules | 5 +- CMake/.gitkeep | 0 CMakeLists.txt | 48 + Dependencies/GLAD/CMakeLists.txt | 18 + Dependencies/entt | 1 + Dependencies/entt/build.lua | 49 - Dependencies/entt/entt.cpp | 1 - Dependencies/entt/entt.hpp | 17700 ---------------- Dependencies/stb_image/build.lua | 48 - Dependencies/stb_image/stb_image.c | 7130 ------- Dependencies/stb_image/stb_image.h | 738 - Engine/CMakeLists.txt | 63 + Engine/res/Fonts/OpenSans/LICENSE.txt | 202 + Engine/res/Fonts/OpenSans/OpenSans-Bold.ttf | Bin 0 -> 104120 bytes .../Fonts/OpenSans/OpenSans-BoldItalic.ttf | Bin 0 -> 92628 bytes .../res/Fonts/OpenSans/OpenSans-ExtraBold.ttf | Bin 0 -> 102076 bytes .../OpenSans/OpenSans-ExtraBoldItalic.ttf | Bin 0 -> 135504 bytes Engine/res/Fonts/OpenSans/OpenSans-Italic.ttf | Bin 0 -> 92240 bytes Engine/res/Fonts/OpenSans/OpenSans-Light.ttf | Bin 0 -> 101696 bytes .../Fonts/OpenSans/OpenSans-LightItalic.ttf | Bin 0 -> 92488 bytes .../res/Fonts/OpenSans/OpenSans-Regular.ttf | Bin 0 -> 96932 bytes .../res/Fonts/OpenSans/OpenSans-SemiBold.ttf | Bin 0 -> 100820 bytes .../OpenSans/OpenSans-SemiBoldItalic.ttf | Bin 0 -> 92180 bytes .../TintedTexture/TintedTexture_VS.glsl | 2 +- Engine/src/Engine/Base/Base.h | 3 +- Engine/src/Engine/Core/Application.cpp | 2 +- .../RendererPrograms/QuadRendererProgram.cpp | 2 +- .../TextureRendererProgram.cpp | 2 +- .../TintedTextureRendererProgram.cpp | 7 +- Engine/src/Engine/Input/Input.h | 2 + .../Scene/Components/TransformComponent.h | 14 +- Engine/src/Engine/Scene/Entity.h | 6 +- Engine/src/Engine/Scene/Scene.h | 2 +- .../Engine/UserInterface/UserInterface.cpp | 4 +- .../GraphicsAPI/DirectX/dxUserInterface.cpp | 4 +- .../GraphicsAPI/OpenGL/glUserInterface.cpp | 4 +- Mirror/CMakeLists.txt | 29 + Mirror/res/Textures/awesomeface.png | Bin 76691 -> 81332 bytes Mirror/src/EditorLayer.cpp | 15 +- Mirror/src/EditorLayer.h | 2 + Mirror/src/Panels/SceneHierarchyPanel.cpp | 2 +- 41 files changed, 397 insertions(+), 25708 deletions(-) create mode 100644 CMake/.gitkeep create mode 100644 CMakeLists.txt create mode 100644 Dependencies/GLAD/CMakeLists.txt create mode 160000 Dependencies/entt delete mode 100644 Dependencies/entt/build.lua delete mode 100644 Dependencies/entt/entt.cpp delete mode 100644 Dependencies/entt/entt.hpp delete mode 100644 Dependencies/stb_image/build.lua delete mode 100644 Dependencies/stb_image/stb_image.c delete mode 100644 Dependencies/stb_image/stb_image.h create mode 100644 Engine/CMakeLists.txt create mode 100644 Engine/res/Fonts/OpenSans/LICENSE.txt create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-Bold.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-BoldItalic.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-ExtraBold.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-Italic.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-Light.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-LightItalic.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-Regular.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-SemiBold.ttf create mode 100644 Engine/res/Fonts/OpenSans/OpenSans-SemiBoldItalic.ttf create mode 100644 Mirror/CMakeLists.txt diff --git a/.gitmodules b/.gitmodules index d1c5112..94b76ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,7 +3,7 @@ url = https://github.com/gabime/spdlog [submodule "Dependencies/GLFW"] path = Dependencies/GLFW - url = https://github.com/Light3039/glfw + url = https://github.com/glfw/glfw [submodule "Dependencies/glm"] path = Dependencies/glm url = https://github.com/g-truc/glm @@ -19,3 +19,6 @@ [submodule "Dependencies/spirv-headers"] path = Dependencies/spirv-headers url = https://github.com/KhronosGroup/SPIRV-Headers +[submodule "Dependencies/entt"] + path = Dependencies/entt + url = https://github.com/skypjack/entt diff --git a/CMake/.gitkeep b/CMake/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2e7cafb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.21.2) + +project(Light VERSION 1.0.0) +set(CMAKE_CXX_STANDARD 17) +# target_compile_features(Light PUBLIC cxx_std_17) +# set_property(TARGET Light CXX_STANDARD 17) + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(SANDBOX_DIR ${CMAKE_BINARY_DIR}/../Sandbox/) +set(MIRROR_DIR ${CMAKE_BINARY_DIR}/../Mirror/) +set(ENGINE_DIR ${CMAKE_BINARY_DIR}/../Engine/) +set(DEPENDENCIES_DIR ${CMAKE_BINARY_DIR}/../Dependencies/) + +# SANDBOX +file(GLOB SANDBOX_SRC ABSOLUTE ${SANDBOX_DIR}/src/*.*) +file(GLOB SANDBOX_RES_TEXTURES ABSOLUTE ${SANDBOX_DIR}/res/Textures/*.*) +source_group(src/ FILES ${SANDBOX_SRC}) +source_group(res/Textures FILES ${SANDBOX_RES_TEXTURES}) + +add_executable(Sandbox ${SANDBOX_SRC} ${SANDBOX_RES_TEXTURES}) + +# MIRROR +add_compile_definitions(LIGHT_PLATFORM_WINDOWS) + +# projects +add_subdirectory(${ENGINE_DIR}/) +add_subdirectory(${MIRROR_DIR}/) + +add_subdirectory(${DEPENDENCIES_DIR}GLAD/) +add_subdirectory(${DEPENDENCIES_DIR}GLFW/) +add_subdirectory(${DEPENDENCIES_DIR}spdlog/) +add_subdirectory(${DEPENDENCIES_DIR}glm/) +add_subdirectory(${DEPENDENCIES_DIR}entt/) +add_subdirectory(${DEPENDENCIES_DIR}imgui/) +add_subdirectory(${DEPENDENCIES_DIR}stb_image/) + +target_link_libraries(Engine glad) +target_link_libraries(Engine glfw) +target_link_libraries(Engine spdlog) +target_link_libraries(Engine imgui) +target_link_libraries(Engine stb_image) + +target_link_libraries(imgui glad) +target_link_libraries(imgui glfw) + +target_link_libraries(Mirror Engine) \ No newline at end of file diff --git a/Dependencies/GLAD/CMakeLists.txt b/Dependencies/GLAD/CMakeLists.txt new file mode 100644 index 0000000..419599b --- /dev/null +++ b/Dependencies/GLAD/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.21.2) + +if (CMAKE_COMPILER_IS_GNUCC) + add_compile_options(-w) +endif() +if(MSVC) + add_compile_options(/MP) + add_compile_options(/W0) +endif() + +project(GLAD VERSION 0.1.34 LANGUAGES C) + +file(GLOB_RECURSE GLAD_SOURCES true ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/src/*) +file(GLOB_RECURSE GLAD_HEADERS true ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/include/*) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/) + +add_library(glad STATIC ${GLAD_SOURCES} ${GLAD_HEADERS}) \ No newline at end of file diff --git a/Dependencies/entt b/Dependencies/entt new file mode 160000 index 0000000..59589b6 --- /dev/null +++ b/Dependencies/entt @@ -0,0 +1 @@ +Subproject commit 59589b6a714579fbfac09a802d6bfc87e8bae7dd diff --git a/Dependencies/entt/build.lua b/Dependencies/entt/build.lua deleted file mode 100644 index d02725e..0000000 --- a/Dependencies/entt/build.lua +++ /dev/null @@ -1,49 +0,0 @@ -project "entt" - - -- Output Directories -- - location "%{wks.location}/Dependencies/entt" - - targetdir (target_dir) - objdir (object_dir) - - -- Compiler -- - kind "StaticLib" - language "C++" - cppdialect "C++17" - - -- Project Files --- - files - { - "entt.cpp", - "entt.hpp", - - "%{prj.location}/build.lua", - } - - --- Filters --- - -- windows - filter "system:windows" - systemversion "latest" - staticruntime "On" - - defines - { - "_CRT_SECURE_NO_WARNINGS", - } - - flags { "MultiProcessorCompile" } - - -- debug - filter "configurations:Debug" - runtime "Debug" - symbols "on" - - -- release - filter "configurations:Release" - runtime "Release" - optimize "on" - - -- distribution - filter "configurations:Distribution" - runtime "Release" - optimize "full" diff --git a/Dependencies/entt/entt.cpp b/Dependencies/entt/entt.cpp deleted file mode 100644 index d4a77e7..0000000 --- a/Dependencies/entt/entt.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "entt.hpp" \ No newline at end of file diff --git a/Dependencies/entt/entt.hpp b/Dependencies/entt/entt.hpp deleted file mode 100644 index 1024b5d..0000000 --- a/Dependencies/entt/entt.hpp +++ /dev/null @@ -1,17700 +0,0 @@ -// #include "core/algorithm.hpp" -#ifndef ENTT_CORE_ALGORITHM_HPP -#define ENTT_CORE_ALGORITHM_HPP - - -#include -#include -#include -#include -#include -// #include "utility.hpp" -#ifndef ENTT_CORE_UTILITY_HPP -#define ENTT_CORE_UTILITY_HPP - - -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - - - -namespace entt { - - - /*! @brief Identity function object (waiting for C++20). */ - struct identity { - /** - * @brief Returns its argument unchanged. - * @tparam Type Type of the argument. - * @param value The actual argument. - * @return The submitted value as-is. - */ - template - constexpr Type&& operator()(Type&& value) const ENTT_NOEXCEPT { - return std::forward(value); - } - }; - - - /** - * @brief Constant utility to disambiguate overloaded members of a class. - * @tparam Type Type of the desired overload. - * @tparam Class Type of class to which the member belongs. - * @param member A valid pointer to a member. - * @return Pointer to the member. - */ - template - constexpr auto overload(Type Class::* member) ENTT_NOEXCEPT { return member; } - - - /** - * @brief Constant utility to disambiguate overloaded functions. - * @tparam Func Function type of the desired overload. - * @param func A valid pointer to a function. - * @return Pointer to the function. - */ - template - constexpr auto overload(Func* func) ENTT_NOEXCEPT { return func; } - - - /** - * @brief Helper type for visitors. - * @tparam Func Types of function objects. - */ - template - struct overloaded : Func... { - using Func::operator()...; - }; - - - /** - * @brief Deduction guide. - * @tparam Func Types of function objects. - */ - template - overloaded(Func...)->overloaded; - - - /** - * @brief Basic implementation of a y-combinator. - * @tparam Func Type of a potentially recursive function. - */ - template - struct y_combinator { - /** - * @brief Constructs a y-combinator from a given function. - * @param recursive A potentially recursive function. - */ - y_combinator(Func recursive) : - func{ std::move(recursive) } - {} - - /** - * @brief Invokes a y-combinator and therefore its underlying function. - * @tparam Args Types of arguments to use to invoke the underlying function. - * @param args Parameters to use to invoke the underlying function. - * @return Return value of the underlying function, if any. - */ - template - decltype(auto) operator()(Args &&... args) const { - return func(*this, std::forward(args)...); - } - - /*! @copydoc operator()() */ - template - decltype(auto) operator()(Args &&... args) { - return func(*this, std::forward(args)...); - } - - private: - Func func; - }; - - -} - - -#endif - - - -namespace entt { - - - /** - * @brief Function object to wrap `std::sort` in a class type. - * - * Unfortunately, `std::sort` cannot be passed as template argument to a class - * template or a function template.
- * This class fills the gap by wrapping some flavors of `std::sort` in a - * function object. - */ - struct std_sort { - /** - * @brief Sorts the elements in a range. - * - * Sorts the elements in a range using the given binary comparison function. - * - * @tparam It Type of random access iterator. - * @tparam Compare Type of comparison function object. - * @tparam Args Types of arguments to forward to the sort function. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param compare A valid comparison function object. - * @param args Arguments to forward to the sort function, if any. - */ - template, typename... Args> - void operator()(It first, It last, Compare compare = Compare{}, Args &&... args) const { - std::sort(std::forward(args)..., std::move(first), std::move(last), std::move(compare)); - } - }; - - - /*! @brief Function object for performing insertion sort. */ - struct insertion_sort { - /** - * @brief Sorts the elements in a range. - * - * Sorts the elements in a range using the given binary comparison function. - * - * @tparam It Type of random access iterator. - * @tparam Compare Type of comparison function object. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param compare A valid comparison function object. - */ - template> - void operator()(It first, It last, Compare compare = Compare{}) const { - if (first < last) { - for (auto it = first + 1; it < last; ++it) { - auto value = std::move(*it); - auto pre = it; - - for (; pre > first && compare(value, *(pre - 1)); --pre) { - *pre = std::move(*(pre - 1)); - } - - *pre = std::move(value); - } - } - } - }; - - - /** - * @brief Function object for performing LSD radix sort. - * @tparam Bit Number of bits processed per pass. - * @tparam N Maximum number of bits to sort. - */ - template - struct radix_sort { - static_assert((N% Bit) == 0); - - /** - * @brief Sorts the elements in a range. - * - * Sorts the elements in a range using the given _getter_ to access the - * actual data to be sorted. - * - * This implementation is inspired by the online book - * [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies.html#RadixSort). - * - * @tparam It Type of random access iterator. - * @tparam Getter Type of _getter_ function object. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param getter A valid _getter_ function object. - */ - template - void operator()(It first, It last, Getter getter = Getter{}) const { - if (first < last) { - static constexpr auto mask = (1 << Bit) - 1; - static constexpr auto buckets = 1 << Bit; - static constexpr auto passes = N / Bit; - - using value_type = typename std::iterator_traits::value_type; - std::vector aux(std::distance(first, last)); - - auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) { - std::size_t index[buckets]{}; - std::size_t count[buckets]{}; - - std::for_each(from, to, [&getter, &count, start](const value_type& item) { - ++count[(getter(item) >> start) & mask]; - }); - - std::for_each(std::next(std::begin(index)), std::end(index), [index = std::begin(index), count = std::begin(count)](auto& item) mutable { - item = *(index++) + *(count++); - }); - - std::for_each(from, to, [&getter, &out, &index, start](value_type& item) { - out[index[(getter(item) >> start) & mask]++] = std::move(item); - }); - }; - - for (std::size_t pass = 0; pass < (passes & ~1); pass += 2) { - part(first, last, aux.begin(), pass * Bit); - part(aux.begin(), aux.end(), first, (pass + 1) * Bit); - } - - if constexpr (passes & 1) { - part(first, last, aux.begin(), (passes - 1) * Bit); - std::move(aux.begin(), aux.end(), first); - } - } - } - }; - - -} - - -#endif - -// #include "core/attribute.h" -#ifndef ENTT_CORE_ATTRIBUTE_H -#define ENTT_CORE_ATTRIBUTE_H - - -#ifndef ENTT_EXPORT -# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER -# define ENTT_EXPORT __declspec(dllexport) -# define ENTT_IMPORT __declspec(dllimport) -# define ENTT_HIDDEN -# elif defined __GNUC__ && __GNUC__ >= 4 -# define ENTT_EXPORT __attribute__((visibility("default"))) -# define ENTT_IMPORT __attribute__((visibility("default"))) -# define ENTT_HIDDEN __attribute__((visibility("hidden"))) -# else /* Unsupported compiler */ -# define ENTT_EXPORT -# define ENTT_IMPORT -# define ENTT_HIDDEN -# endif -#endif - - -#ifndef ENTT_API -# if defined ENTT_API_EXPORT -# define ENTT_API ENTT_EXPORT -# elif defined ENTT_API_IMPORT -# define ENTT_API ENTT_IMPORT -# else /* No API */ -# define ENTT_API -# endif -#endif - - -#endif - -// #include "core/family.hpp" -#ifndef ENTT_CORE_FAMILY_HPP -#define ENTT_CORE_FAMILY_HPP - - -// #include "../config/config.h" - -// #include "fwd.hpp" -#ifndef ENTT_CORE_FWD_HPP -#define ENTT_CORE_FWD_HPP - - -// #include "../config/config.h" - - - -namespace entt { - - - /*! @brief Alias declaration for type identifiers. */ - using id_type = ENTT_ID_TYPE; - - -} - - -#endif - - - -namespace entt { - - - /** - * @brief Dynamic identifier generator. - * - * Utility class template that can be used to assign unique identifiers to types - * at runtime. Use different specializations to create separate sets of - * identifiers. - */ - template - class family { - inline static ENTT_MAYBE_ATOMIC(id_type) identifier {}; - - public: - /*! @brief Unsigned integer type. */ - using family_type = id_type; - - /*! @brief Statically generated unique identifier for the given type. */ - template - // at the time I'm writing, clang crashes during compilation if auto is used instead of family_type - inline static const family_type type = identifier++; - }; - - -} - - -#endif - -// #include "core/hashed_string.hpp" -#ifndef ENTT_CORE_HASHED_STRING_HPP -#define ENTT_CORE_HASHED_STRING_HPP - - -#include -#include -// #include "../config/config.h" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - template - struct fnv1a_traits; - - - template<> - struct fnv1a_traits { - using type = std::uint32_t; - static constexpr std::uint32_t offset = 2166136261; - static constexpr std::uint32_t prime = 16777619; - }; - - - template<> - struct fnv1a_traits { - using type = std::uint64_t; - static constexpr std::uint64_t offset = 14695981039346656037ull; - static constexpr std::uint64_t prime = 1099511628211ull; - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Zero overhead unique identifier. - * - * A hashed string is a compile-time tool that allows users to use - * human-readable identifers in the codebase while using their numeric - * counterparts at runtime.
- * Because of that, a hashed string can also be used in constant expressions if - * required. - * - * @tparam Char Character type. - */ - template - class basic_hashed_string { - using traits_type = internal::fnv1a_traits; - - struct const_wrapper { - // non-explicit constructor on purpose - constexpr const_wrapper(const Char* curr) ENTT_NOEXCEPT: str{ curr } {} - const Char* str; - }; - - // Fowler–Noll–Vo hash function v. 1a - the good - static constexpr id_type helper(const Char* curr) ENTT_NOEXCEPT { - auto value = traits_type::offset; - - while (*curr != 0) { - value = (value ^ static_cast(*(curr++))) * traits_type::prime; - } - - return value; - } - - public: - /*! @brief Character type. */ - using value_type = Char; - /*! @brief Unsigned integer type. */ - using hash_type = id_type; - - /** - * @brief Returns directly the numeric representation of a string. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * const auto value = basic_hashed_string::to_value("my.png"); - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - * @return The numeric representation of the string. - */ - template - static constexpr hash_type value(const value_type(&str)[N]) ENTT_NOEXCEPT { - return helper(str); - } - - /** - * @brief Returns directly the numeric representation of a string. - * @param wrapper Helps achieving the purpose by relying on overloading. - * @return The numeric representation of the string. - */ - static hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT { - return helper(wrapper.str); - } - - /** - * @brief Returns directly the numeric representation of a string view. - * @param str Human-readable identifer. - * @param size Length of the string to hash. - * @return The numeric representation of the string. - */ - static hash_type value(const value_type* str, std::size_t size) ENTT_NOEXCEPT { - id_type partial{ traits_type::offset }; - while (size--) { partial = (partial ^ (str++)[0]) * traits_type::prime; } - return partial; - } - - /*! @brief Constructs an empty hashed string. */ - constexpr basic_hashed_string() ENTT_NOEXCEPT - : str{ nullptr }, hash{} - {} - - /** - * @brief Constructs a hashed string from an array of const characters. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * basic_hashed_string hs{"my.png"}; - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param curr Human-readable identifer. - */ - template - constexpr basic_hashed_string(const value_type(&curr)[N]) ENTT_NOEXCEPT - : str{ curr }, hash{ helper(curr) } - {} - - /** - * @brief Explicit constructor on purpose to avoid constructing a hashed - * string directly from a `const value_type *`. - * @param wrapper Helps achieving the purpose by relying on overloading. - */ - explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT - : str{ wrapper.str }, hash{ helper(wrapper.str) } - {} - - /** - * @brief Returns the human-readable representation of a hashed string. - * @return The string used to initialize the instance. - */ - constexpr const value_type* data() const ENTT_NOEXCEPT { - return str; - } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr hash_type value() const ENTT_NOEXCEPT { - return hash; - } - - /*! @copydoc data */ - constexpr operator const value_type* () const ENTT_NOEXCEPT { return data(); } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr operator hash_type() const ENTT_NOEXCEPT { return value(); } - - /** - * @brief Compares two hashed strings. - * @param other Hashed string with which to compare. - * @return True if the two hashed strings are identical, false otherwise. - */ - constexpr bool operator==(const basic_hashed_string& other) const ENTT_NOEXCEPT { - return hash == other.hash; - } - - private: - const value_type* str; - hash_type hash; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the character type of the hashed string directly from a - * human-readable identifer provided to the constructor. - * - * @tparam Char Character type. - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - */ - template - basic_hashed_string(const Char(&str)[N]) ENTT_NOEXCEPT - ->basic_hashed_string; - - - /** - * @brief Compares two hashed strings. - * @tparam Char Character type. - * @param lhs A valid hashed string. - * @param rhs A valid hashed string. - * @return True if the two hashed strings are identical, false otherwise. - */ - template - constexpr bool operator!=(const basic_hashed_string& lhs, const basic_hashed_string& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - /*! @brief Aliases for common character types. */ - using hashed_string = basic_hashed_string; - - - /*! @brief Aliases for common character types. */ - using hashed_wstring = basic_hashed_string; - - -} - - -/** - * @brief User defined literal for hashed strings. - * @param str The literal without its suffix. - * @return A properly initialized hashed string. - */ -constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_string{ str }; -} - - -/** - * @brief User defined literal for hashed wstrings. - * @param str The literal without its suffix. - * @return A properly initialized hashed wstring. - */ -constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_wstring{ str }; -} - - -#endif - -// #include "core/ident.hpp" -#ifndef ENTT_CORE_IDENT_HPP -#define ENTT_CORE_IDENT_HPP - - -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Types identifiers. - * - * Variable template used to generate identifiers at compile-time for the given - * types. Use the `get` member function to know what's the identifier associated - * to the specific type. - * - * @note - * Identifiers are constant expression and can be used in any context where such - * an expression is required. As an example: - * @code{.cpp} - * using id = entt::identifier; - * - * switch(a_type_identifier) { - * case id::type: - * // ... - * break; - * case id::type: - * // ... - * break; - * default: - * // ... - * } - * @endcode - * - * @tparam Types List of types for which to generate identifiers. - */ - template - class identifier { - using tuple_type = std::tuple...>; - - template - static constexpr id_type get(std::index_sequence) { - static_assert(std::disjunction_v...>); - return (0 + ... + (std::is_same_v> ? id_type(Indexes) : id_type{})); - } - - public: - /*! @brief Unsigned integer type. */ - using identifier_type = id_type; - - /*! @brief Statically generated unique identifier for the given type. */ - template - static constexpr identifier_type type = get>(std::index_sequence_for{}); - }; - - -} - - -#endif - -// #include "core/monostate.hpp" -#ifndef ENTT_CORE_MONOSTATE_HPP -#define ENTT_CORE_MONOSTATE_HPP - - -// #include "../config/config.h" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Minimal implementation of the monostate pattern. - * - * A minimal, yet complete configuration system built on top of the monostate - * pattern. Thread safe by design, it works only with basic types like `int`s or - * `bool`s.
- * Multiple types and therefore more than one value can be associated with a - * single key. Because of this, users must pay attention to use the same type - * both during an assignment and when they try to read back their data. - * Otherwise, they can incur in unexpected results. - */ - template - struct monostate { - /** - * @brief Assigns a value of a specific type to a given key. - * @tparam Type Type of the value to assign. - * @param val User data to assign to the given key. - */ - template - void operator=(Type val) const ENTT_NOEXCEPT { - value = val; - } - - /** - * @brief Gets a value of a specific type for a given key. - * @tparam Type Type of the value to get. - * @return Stored value, if any. - */ - template - operator Type() const ENTT_NOEXCEPT { - return value; - } - - private: - template - inline static ENTT_MAYBE_ATOMIC(Type) value {}; - }; - - - /** - * @brief Helper variable template. - * @tparam Value Value used to differentiate between different variables. - */ - template - inline monostate monostate_v = {}; - - -} - - -#endif - -// #include "core/type_info.hpp" -#ifndef ENTT_CORE_TYPE_INFO_HPP -#define ENTT_CORE_TYPE_INFO_HPP - - -// #include "../config/config.h" - -// #include "../core/attribute.h" -#ifndef ENTT_CORE_ATTRIBUTE_H -#define ENTT_CORE_ATTRIBUTE_H - - -#ifndef ENTT_EXPORT -# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER -# define ENTT_EXPORT __declspec(dllexport) -# define ENTT_IMPORT __declspec(dllimport) -# define ENTT_HIDDEN -# elif defined __GNUC__ && __GNUC__ >= 4 -# define ENTT_EXPORT __attribute__((visibility("default"))) -# define ENTT_IMPORT __attribute__((visibility("default"))) -# define ENTT_HIDDEN __attribute__((visibility("hidden"))) -# else /* Unsupported compiler */ -# define ENTT_EXPORT -# define ENTT_IMPORT -# define ENTT_HIDDEN -# endif -#endif - - -#ifndef ENTT_API -# if defined ENTT_API_EXPORT -# define ENTT_API ENTT_EXPORT -# elif defined ENTT_API_IMPORT -# define ENTT_API ENTT_IMPORT -# else /* No API */ -# define ENTT_API -# endif -#endif - - -#endif - -// #include "hashed_string.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - struct ENTT_API type_index { - static id_type next() ENTT_NOEXCEPT { - static ENTT_MAYBE_ATOMIC(id_type) value {}; - return value++; - } - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Type index. - * @tparam Type Type for which to generate a sequential identifier. - */ - template - struct ENTT_API type_index { - /** - * @brief Returns the sequential identifier of a given type. - * @return The sequential identifier of a given type. - */ - static id_type value() ENTT_NOEXCEPT { - static const id_type value = internal::type_index::next(); - return value; - } - }; - - - /** - * @brief Provides the member constant `value` to true if a given type is - * indexable, false otherwise. - * @tparam Type Potentially indexable type. - */ - template - struct has_type_index : std::false_type {}; - - - /*! @brief has_type_index */ - template - struct has_type_index::value())>> : std::true_type {}; - - - /** - * @brief Helper variable template. - * @tparam Type Potentially indexable type. - */ - template - inline constexpr bool has_type_index_v = has_type_index::value; - - - /** - * @brief Type info. - * @tparam Type Type for which to generate information. - */ - template - struct ENTT_API type_info { - /** - * @brief Returns the numeric representation of a given type. - * @return The numeric representation of the given type. - */ -#if defined ENTT_PRETTY_FUNCTION - static ENTT_PRETTY_FUNCTION_CONSTEXPR() id_type id() ENTT_NOEXCEPT { - ENTT_PRETTY_FUNCTION_CONSTEXPR(static const) auto value = entt::hashed_string::value(ENTT_PRETTY_FUNCTION); - return value; - } -#else - static id_type id() ENTT_NOEXCEPT { - return type_index::value(); - } -#endif - }; - - -} - - -#endif - -// #include "core/type_traits.hpp" -#ifndef ENTT_CORE_TYPE_TRAITS_HPP -#define ENTT_CORE_TYPE_TRAITS_HPP - - -#include -#include -#include -// #include "../config/config.h" - -// #include "hashed_string.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Wraps a static constant. - * @tparam Value A static constant. - */ - template - using integral_constant = std::integral_constant; - - - /** - * @brief Alias template to ease the creation of named values. - * @tparam Value A constant value at least convertible to `id_type`. - */ - template - using tag = integral_constant; - - - /** - * @brief Utility class to disambiguate overloaded functions. - * @tparam N Number of choices available. - */ - template - struct choice_t - // Unfortunately, doxygen cannot parse such a construct. - /*! @cond TURN_OFF_DOXYGEN */ - : choice_t - /*! @endcond TURN_OFF_DOXYGEN */ - {}; - - - /*! @copybrief choice_t */ - template<> - struct choice_t<0> {}; - - - /** - * @brief Variable template for the choice trick. - * @tparam N Number of choices available. - */ - template - inline constexpr choice_t choice{}; - - - /*! @brief A class to use to push around lists of types, nothing more. */ - template - struct type_list {}; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_size; - - - /** - * @brief Compile-time number of elements in a type list. - * @tparam Type Types provided by the type list. - */ - template - struct type_list_size> - : std::integral_constant - {}; - - - /** - * @brief Helper variable template. - * @tparam List Type list. - */ - template - inline constexpr auto type_list_size_v = type_list_size::value; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_cat; - - - /*! @brief Concatenates multiple type lists. */ - template<> - struct type_list_cat<> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = type_list<>; - }; - - - /** - * @brief Concatenates multiple type lists. - * @tparam Type Types provided by the first type list. - * @tparam Other Types provided by the second type list. - * @tparam List Other type lists, if any. - */ - template - struct type_list_cat, type_list, List...> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = typename type_list_cat, List...>::type; - }; - - - /** - * @brief Concatenates multiple type lists. - * @tparam Type Types provided by the type list. - */ - template - struct type_list_cat> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = type_list; - }; - - - /** - * @brief Helper type. - * @tparam List Type lists to concatenate. - */ - template - using type_list_cat_t = typename type_list_cat::type; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_unique; - - - /** - * @brief Removes duplicates types from a type list. - * @tparam Type One of the types provided by the given type list. - * @tparam Other The other types provided by the given type list. - */ - template - struct type_list_unique> { - /*! @brief A type list without duplicate types. */ - using type = std::conditional_t< - std::disjunction_v...>, - typename type_list_unique>::type, - type_list_cat_t, typename type_list_unique>::type> - >; - }; - - - /*! @brief Removes duplicates types from a type list. */ - template<> - struct type_list_unique> { - /*! @brief A type list without duplicate types. */ - using type = type_list<>; - }; - - - /** - * @brief Helper type. - * @tparam Type A type list. - */ - template - using type_list_unique_t = typename type_list_unique::type; - - - /** - * @brief Provides the member constant `value` to true if a given type is - * equality comparable, false otherwise. - * @tparam Type Potentially equality comparable type. - */ - template> - struct is_equality_comparable : std::false_type {}; - - - /*! @copydoc is_equality_comparable */ - template - struct is_equality_comparable() == std::declval())>> : std::true_type {}; - - - /** - * @brief Helper variable template. - * @tparam Type Potentially equality comparable type. - */ - template - inline constexpr auto is_equality_comparable_v = is_equality_comparable::value; - - - /** - * @brief Extracts the class of a non-static member object or function. - * @tparam Member A pointer to a non-static member object or function. - */ - template - class member_class { - static_assert(std::is_member_pointer_v); - - template - static Class* clazz(Ret(Class::*)(Args...)); - - template - static Class* clazz(Ret(Class::*)(Args...) const); - - template - static Class* clazz(Type Class::*); - - public: - /*! @brief The class of the given non-static member object or function. */ - using type = std::remove_pointer_t()))>; - }; - - - /** - * @brief Helper type. - * @tparam Member A pointer to a non-static member object or function. - */ - template - using member_class_t = typename member_class::type; - - -} - - -/** - * @brief Defines an enum class to use for opaque identifiers and a dedicate - * `to_integer` function to convert the identifiers to their underlying type. - * @param clazz The name to use for the enum class. - * @param type The underlying type for the enum class. - */ -#define ENTT_OPAQUE_TYPE(clazz, type)\ - enum class clazz: type {};\ - constexpr auto to_integral(const clazz id) ENTT_NOEXCEPT {\ - return static_cast>(id);\ - }\ - static_assert(true) - - -#endif - - // #include "core/utility.hpp" - - // #include "entity/actor.hpp" -#ifndef ENTT_ENTITY_ACTOR_HPP -#define ENTT_ENTITY_ACTOR_HPP - - -#include -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - -// #include "registry.hpp" -#ifndef ENTT_ENTITY_REGISTRY_HPP -#define ENTT_ENTITY_REGISTRY_HPP - - -#include -#include -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/algorithm.hpp" -#ifndef ENTT_CORE_ALGORITHM_HPP -#define ENTT_CORE_ALGORITHM_HPP - - -#include -#include -#include -#include -#include -// #include "utility.hpp" -#ifndef ENTT_CORE_UTILITY_HPP -#define ENTT_CORE_UTILITY_HPP - - -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - - - -namespace entt { - - - /*! @brief Identity function object (waiting for C++20). */ - struct identity { - /** - * @brief Returns its argument unchanged. - * @tparam Type Type of the argument. - * @param value The actual argument. - * @return The submitted value as-is. - */ - template - constexpr Type&& operator()(Type&& value) const ENTT_NOEXCEPT { - return std::forward(value); - } - }; - - - /** - * @brief Constant utility to disambiguate overloaded members of a class. - * @tparam Type Type of the desired overload. - * @tparam Class Type of class to which the member belongs. - * @param member A valid pointer to a member. - * @return Pointer to the member. - */ - template - constexpr auto overload(Type Class::* member) ENTT_NOEXCEPT { return member; } - - - /** - * @brief Constant utility to disambiguate overloaded functions. - * @tparam Func Function type of the desired overload. - * @param func A valid pointer to a function. - * @return Pointer to the function. - */ - template - constexpr auto overload(Func* func) ENTT_NOEXCEPT { return func; } - - - /** - * @brief Helper type for visitors. - * @tparam Func Types of function objects. - */ - template - struct overloaded : Func... { - using Func::operator()...; - }; - - - /** - * @brief Deduction guide. - * @tparam Func Types of function objects. - */ - template - overloaded(Func...)->overloaded; - - - /** - * @brief Basic implementation of a y-combinator. - * @tparam Func Type of a potentially recursive function. - */ - template - struct y_combinator { - /** - * @brief Constructs a y-combinator from a given function. - * @param recursive A potentially recursive function. - */ - y_combinator(Func recursive) : - func{ std::move(recursive) } - {} - - /** - * @brief Invokes a y-combinator and therefore its underlying function. - * @tparam Args Types of arguments to use to invoke the underlying function. - * @param args Parameters to use to invoke the underlying function. - * @return Return value of the underlying function, if any. - */ - template - decltype(auto) operator()(Args &&... args) const { - return func(*this, std::forward(args)...); - } - - /*! @copydoc operator()() */ - template - decltype(auto) operator()(Args &&... args) { - return func(*this, std::forward(args)...); - } - - private: - Func func; - }; - - -} - - -#endif - - - -namespace entt { - - - /** - * @brief Function object to wrap `std::sort` in a class type. - * - * Unfortunately, `std::sort` cannot be passed as template argument to a class - * template or a function template.
- * This class fills the gap by wrapping some flavors of `std::sort` in a - * function object. - */ - struct std_sort { - /** - * @brief Sorts the elements in a range. - * - * Sorts the elements in a range using the given binary comparison function. - * - * @tparam It Type of random access iterator. - * @tparam Compare Type of comparison function object. - * @tparam Args Types of arguments to forward to the sort function. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param compare A valid comparison function object. - * @param args Arguments to forward to the sort function, if any. - */ - template, typename... Args> - void operator()(It first, It last, Compare compare = Compare{}, Args &&... args) const { - std::sort(std::forward(args)..., std::move(first), std::move(last), std::move(compare)); - } - }; - - - /*! @brief Function object for performing insertion sort. */ - struct insertion_sort { - /** - * @brief Sorts the elements in a range. - * - * Sorts the elements in a range using the given binary comparison function. - * - * @tparam It Type of random access iterator. - * @tparam Compare Type of comparison function object. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param compare A valid comparison function object. - */ - template> - void operator()(It first, It last, Compare compare = Compare{}) const { - if (first < last) { - for (auto it = first + 1; it < last; ++it) { - auto value = std::move(*it); - auto pre = it; - - for (; pre > first && compare(value, *(pre - 1)); --pre) { - *pre = std::move(*(pre - 1)); - } - - *pre = std::move(value); - } - } - } - }; - - - /** - * @brief Function object for performing LSD radix sort. - * @tparam Bit Number of bits processed per pass. - * @tparam N Maximum number of bits to sort. - */ - template - struct radix_sort { - static_assert((N% Bit) == 0); - - /** - * @brief Sorts the elements in a range. - * - * Sorts the elements in a range using the given _getter_ to access the - * actual data to be sorted. - * - * This implementation is inspired by the online book - * [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies.html#RadixSort). - * - * @tparam It Type of random access iterator. - * @tparam Getter Type of _getter_ function object. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param getter A valid _getter_ function object. - */ - template - void operator()(It first, It last, Getter getter = Getter{}) const { - if (first < last) { - static constexpr auto mask = (1 << Bit) - 1; - static constexpr auto buckets = 1 << Bit; - static constexpr auto passes = N / Bit; - - using value_type = typename std::iterator_traits::value_type; - std::vector aux(std::distance(first, last)); - - auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) { - std::size_t index[buckets]{}; - std::size_t count[buckets]{}; - - std::for_each(from, to, [&getter, &count, start](const value_type& item) { - ++count[(getter(item) >> start) & mask]; - }); - - std::for_each(std::next(std::begin(index)), std::end(index), [index = std::begin(index), count = std::begin(count)](auto& item) mutable { - item = *(index++) + *(count++); - }); - - std::for_each(from, to, [&getter, &out, &index, start](value_type& item) { - out[index[(getter(item) >> start) & mask]++] = std::move(item); - }); - }; - - for (std::size_t pass = 0; pass < (passes & ~1); pass += 2) { - part(first, last, aux.begin(), pass * Bit); - part(aux.begin(), aux.end(), first, (pass + 1) * Bit); - } - - if constexpr (passes & 1) { - part(first, last, aux.begin(), (passes - 1) * Bit); - std::move(aux.begin(), aux.end(), first); - } - } - } - }; - - -} - - -#endif - -// #include "../core/fwd.hpp" -#ifndef ENTT_CORE_FWD_HPP -#define ENTT_CORE_FWD_HPP - - -// #include "../config/config.h" - - - -namespace entt { - - - /*! @brief Alias declaration for type identifiers. */ - using id_type = ENTT_ID_TYPE; - - -} - - -#endif - -// #include "../core/type_info.hpp" -#ifndef ENTT_CORE_TYPE_INFO_HPP -#define ENTT_CORE_TYPE_INFO_HPP - - -// #include "../config/config.h" - -// #include "../core/attribute.h" -#ifndef ENTT_CORE_ATTRIBUTE_H -#define ENTT_CORE_ATTRIBUTE_H - - -#ifndef ENTT_EXPORT -# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER -# define ENTT_EXPORT __declspec(dllexport) -# define ENTT_IMPORT __declspec(dllimport) -# define ENTT_HIDDEN -# elif defined __GNUC__ && __GNUC__ >= 4 -# define ENTT_EXPORT __attribute__((visibility("default"))) -# define ENTT_IMPORT __attribute__((visibility("default"))) -# define ENTT_HIDDEN __attribute__((visibility("hidden"))) -# else /* Unsupported compiler */ -# define ENTT_EXPORT -# define ENTT_IMPORT -# define ENTT_HIDDEN -# endif -#endif - - -#ifndef ENTT_API -# if defined ENTT_API_EXPORT -# define ENTT_API ENTT_EXPORT -# elif defined ENTT_API_IMPORT -# define ENTT_API ENTT_IMPORT -# else /* No API */ -# define ENTT_API -# endif -#endif - - -#endif - -// #include "hashed_string.hpp" -#ifndef ENTT_CORE_HASHED_STRING_HPP -#define ENTT_CORE_HASHED_STRING_HPP - - -#include -#include -// #include "../config/config.h" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - template - struct fnv1a_traits; - - - template<> - struct fnv1a_traits { - using type = std::uint32_t; - static constexpr std::uint32_t offset = 2166136261; - static constexpr std::uint32_t prime = 16777619; - }; - - - template<> - struct fnv1a_traits { - using type = std::uint64_t; - static constexpr std::uint64_t offset = 14695981039346656037ull; - static constexpr std::uint64_t prime = 1099511628211ull; - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Zero overhead unique identifier. - * - * A hashed string is a compile-time tool that allows users to use - * human-readable identifers in the codebase while using their numeric - * counterparts at runtime.
- * Because of that, a hashed string can also be used in constant expressions if - * required. - * - * @tparam Char Character type. - */ - template - class basic_hashed_string { - using traits_type = internal::fnv1a_traits; - - struct const_wrapper { - // non-explicit constructor on purpose - constexpr const_wrapper(const Char* curr) ENTT_NOEXCEPT: str{ curr } {} - const Char* str; - }; - - // Fowler–Noll–Vo hash function v. 1a - the good - static constexpr id_type helper(const Char* curr) ENTT_NOEXCEPT { - auto value = traits_type::offset; - - while (*curr != 0) { - value = (value ^ static_cast(*(curr++))) * traits_type::prime; - } - - return value; - } - - public: - /*! @brief Character type. */ - using value_type = Char; - /*! @brief Unsigned integer type. */ - using hash_type = id_type; - - /** - * @brief Returns directly the numeric representation of a string. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * const auto value = basic_hashed_string::to_value("my.png"); - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - * @return The numeric representation of the string. - */ - template - static constexpr hash_type value(const value_type(&str)[N]) ENTT_NOEXCEPT { - return helper(str); - } - - /** - * @brief Returns directly the numeric representation of a string. - * @param wrapper Helps achieving the purpose by relying on overloading. - * @return The numeric representation of the string. - */ - static hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT { - return helper(wrapper.str); - } - - /** - * @brief Returns directly the numeric representation of a string view. - * @param str Human-readable identifer. - * @param size Length of the string to hash. - * @return The numeric representation of the string. - */ - static hash_type value(const value_type* str, std::size_t size) ENTT_NOEXCEPT { - id_type partial{ traits_type::offset }; - while (size--) { partial = (partial ^ (str++)[0]) * traits_type::prime; } - return partial; - } - - /*! @brief Constructs an empty hashed string. */ - constexpr basic_hashed_string() ENTT_NOEXCEPT - : str{ nullptr }, hash{} - {} - - /** - * @brief Constructs a hashed string from an array of const characters. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * basic_hashed_string hs{"my.png"}; - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param curr Human-readable identifer. - */ - template - constexpr basic_hashed_string(const value_type(&curr)[N]) ENTT_NOEXCEPT - : str{ curr }, hash{ helper(curr) } - {} - - /** - * @brief Explicit constructor on purpose to avoid constructing a hashed - * string directly from a `const value_type *`. - * @param wrapper Helps achieving the purpose by relying on overloading. - */ - explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT - : str{ wrapper.str }, hash{ helper(wrapper.str) } - {} - - /** - * @brief Returns the human-readable representation of a hashed string. - * @return The string used to initialize the instance. - */ - constexpr const value_type* data() const ENTT_NOEXCEPT { - return str; - } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr hash_type value() const ENTT_NOEXCEPT { - return hash; - } - - /*! @copydoc data */ - constexpr operator const value_type* () const ENTT_NOEXCEPT { return data(); } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr operator hash_type() const ENTT_NOEXCEPT { return value(); } - - /** - * @brief Compares two hashed strings. - * @param other Hashed string with which to compare. - * @return True if the two hashed strings are identical, false otherwise. - */ - constexpr bool operator==(const basic_hashed_string& other) const ENTT_NOEXCEPT { - return hash == other.hash; - } - - private: - const value_type* str; - hash_type hash; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the character type of the hashed string directly from a - * human-readable identifer provided to the constructor. - * - * @tparam Char Character type. - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - */ - template - basic_hashed_string(const Char(&str)[N]) ENTT_NOEXCEPT - ->basic_hashed_string; - - - /** - * @brief Compares two hashed strings. - * @tparam Char Character type. - * @param lhs A valid hashed string. - * @param rhs A valid hashed string. - * @return True if the two hashed strings are identical, false otherwise. - */ - template - constexpr bool operator!=(const basic_hashed_string& lhs, const basic_hashed_string& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - /*! @brief Aliases for common character types. */ - using hashed_string = basic_hashed_string; - - - /*! @brief Aliases for common character types. */ - using hashed_wstring = basic_hashed_string; - - -} - - -/** - * @brief User defined literal for hashed strings. - * @param str The literal without its suffix. - * @return A properly initialized hashed string. - */ -constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_string{ str }; -} - - -/** - * @brief User defined literal for hashed wstrings. - * @param str The literal without its suffix. - * @return A properly initialized hashed wstring. - */ -constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_wstring{ str }; -} - - -#endif - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - struct ENTT_API type_index { - static id_type next() ENTT_NOEXCEPT { - static ENTT_MAYBE_ATOMIC(id_type) value {}; - return value++; - } - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Type index. - * @tparam Type Type for which to generate a sequential identifier. - */ - template - struct ENTT_API type_index { - /** - * @brief Returns the sequential identifier of a given type. - * @return The sequential identifier of a given type. - */ - static id_type value() ENTT_NOEXCEPT { - static const id_type value = internal::type_index::next(); - return value; - } - }; - - - /** - * @brief Provides the member constant `value` to true if a given type is - * indexable, false otherwise. - * @tparam Type Potentially indexable type. - */ - template - struct has_type_index : std::false_type {}; - - - /*! @brief has_type_index */ - template - struct has_type_index::value())>> : std::true_type {}; - - - /** - * @brief Helper variable template. - * @tparam Type Potentially indexable type. - */ - template - inline constexpr bool has_type_index_v = has_type_index::value; - - - /** - * @brief Type info. - * @tparam Type Type for which to generate information. - */ - template - struct ENTT_API type_info { - /** - * @brief Returns the numeric representation of a given type. - * @return The numeric representation of the given type. - */ -#if defined ENTT_PRETTY_FUNCTION - static ENTT_PRETTY_FUNCTION_CONSTEXPR() id_type id() ENTT_NOEXCEPT { - ENTT_PRETTY_FUNCTION_CONSTEXPR(static const) auto value = entt::hashed_string::value(ENTT_PRETTY_FUNCTION); - return value; - } -#else - static id_type id() ENTT_NOEXCEPT { - return type_index::value(); - } -#endif - }; - - -} - - -#endif - -// #include "../core/type_traits.hpp" -#ifndef ENTT_CORE_TYPE_TRAITS_HPP -#define ENTT_CORE_TYPE_TRAITS_HPP - - -#include -#include -#include -// #include "../config/config.h" - -// #include "hashed_string.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Wraps a static constant. - * @tparam Value A static constant. - */ - template - using integral_constant = std::integral_constant; - - - /** - * @brief Alias template to ease the creation of named values. - * @tparam Value A constant value at least convertible to `id_type`. - */ - template - using tag = integral_constant; - - - /** - * @brief Utility class to disambiguate overloaded functions. - * @tparam N Number of choices available. - */ - template - struct choice_t - // Unfortunately, doxygen cannot parse such a construct. - /*! @cond TURN_OFF_DOXYGEN */ - : choice_t - /*! @endcond TURN_OFF_DOXYGEN */ - {}; - - - /*! @copybrief choice_t */ - template<> - struct choice_t<0> {}; - - - /** - * @brief Variable template for the choice trick. - * @tparam N Number of choices available. - */ - template - inline constexpr choice_t choice{}; - - - /*! @brief A class to use to push around lists of types, nothing more. */ - template - struct type_list {}; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_size; - - - /** - * @brief Compile-time number of elements in a type list. - * @tparam Type Types provided by the type list. - */ - template - struct type_list_size> - : std::integral_constant - {}; - - - /** - * @brief Helper variable template. - * @tparam List Type list. - */ - template - inline constexpr auto type_list_size_v = type_list_size::value; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_cat; - - - /*! @brief Concatenates multiple type lists. */ - template<> - struct type_list_cat<> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = type_list<>; - }; - - - /** - * @brief Concatenates multiple type lists. - * @tparam Type Types provided by the first type list. - * @tparam Other Types provided by the second type list. - * @tparam List Other type lists, if any. - */ - template - struct type_list_cat, type_list, List...> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = typename type_list_cat, List...>::type; - }; - - - /** - * @brief Concatenates multiple type lists. - * @tparam Type Types provided by the type list. - */ - template - struct type_list_cat> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = type_list; - }; - - - /** - * @brief Helper type. - * @tparam List Type lists to concatenate. - */ - template - using type_list_cat_t = typename type_list_cat::type; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_unique; - - - /** - * @brief Removes duplicates types from a type list. - * @tparam Type One of the types provided by the given type list. - * @tparam Other The other types provided by the given type list. - */ - template - struct type_list_unique> { - /*! @brief A type list without duplicate types. */ - using type = std::conditional_t< - std::disjunction_v...>, - typename type_list_unique>::type, - type_list_cat_t, typename type_list_unique>::type> - >; - }; - - - /*! @brief Removes duplicates types from a type list. */ - template<> - struct type_list_unique> { - /*! @brief A type list without duplicate types. */ - using type = type_list<>; - }; - - - /** - * @brief Helper type. - * @tparam Type A type list. - */ - template - using type_list_unique_t = typename type_list_unique::type; - - - /** - * @brief Provides the member constant `value` to true if a given type is - * equality comparable, false otherwise. - * @tparam Type Potentially equality comparable type. - */ - template> - struct is_equality_comparable : std::false_type {}; - - - /*! @copydoc is_equality_comparable */ - template - struct is_equality_comparable() == std::declval())>> : std::true_type {}; - - - /** - * @brief Helper variable template. - * @tparam Type Potentially equality comparable type. - */ - template - inline constexpr auto is_equality_comparable_v = is_equality_comparable::value; - - - /** - * @brief Extracts the class of a non-static member object or function. - * @tparam Member A pointer to a non-static member object or function. - */ - template - class member_class { - static_assert(std::is_member_pointer_v); - - template - static Class* clazz(Ret(Class::*)(Args...)); - - template - static Class* clazz(Ret(Class::*)(Args...) const); - - template - static Class* clazz(Type Class::*); - - public: - /*! @brief The class of the given non-static member object or function. */ - using type = std::remove_pointer_t()))>; - }; - - - /** - * @brief Helper type. - * @tparam Member A pointer to a non-static member object or function. - */ - template - using member_class_t = typename member_class::type; - - -} - - -/** - * @brief Defines an enum class to use for opaque identifiers and a dedicate - * `to_integer` function to convert the identifiers to their underlying type. - * @param clazz The name to use for the enum class. - * @param type The underlying type for the enum class. - */ -#define ENTT_OPAQUE_TYPE(clazz, type)\ - enum class clazz: type {};\ - constexpr auto to_integral(const clazz id) ENTT_NOEXCEPT {\ - return static_cast>(id);\ - }\ - static_assert(true) - - -#endif - - // #include "../signal/sigh.hpp" -#ifndef ENTT_SIGNAL_SIGH_HPP -#define ENTT_SIGNAL_SIGH_HPP - - -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - -// #include "delegate.hpp" -#ifndef ENTT_SIGNAL_DELEGATE_HPP -#define ENTT_SIGNAL_DELEGATE_HPP - - -#include -#include -#include -#include -#include -// #include "../config/config.h" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - template - auto function_pointer(Ret(*)(Args...))->Ret(*)(Args...); - - - template - auto function_pointer(Ret(*)(Type, Args...), Other&&)->Ret(*)(Args...); - - - template - auto function_pointer(Ret(Class::*)(Args...), Other &&...)->Ret(*)(Args...); - - - template - auto function_pointer(Ret(Class::*)(Args...) const, Other &&...)->Ret(*)(Args...); - - - template - auto function_pointer(Type Class::*, Other &&...)->Type(*)(); - - - template - using function_pointer_t = decltype(internal::function_pointer(std::declval()...)); - - - template - constexpr auto index_sequence_for(Ret(*)(Args...)) { - return std::index_sequence_for{}; - } - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /*! @brief Used to wrap a function or a member of a specified type. */ - template - struct connect_arg_t {}; - - - /*! @brief Constant of type connect_arg_t used to disambiguate calls. */ - template - inline constexpr connect_arg_t connect_arg{}; - - - /** - * @brief Basic delegate implementation. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error unless the template parameter is a function type. - */ - template - class delegate; - - - /** - * @brief Utility class to use to send around functions and members. - * - * Unmanaged delegate for function pointers and members. Users of this class are - * in charge of disconnecting instances before deleting them. - * - * A delegate can be used as a general purpose invoker without memory overhead - * for free functions possibly with payloads and bound or unbound members. - * - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - */ - template - class delegate { - using proto_fn_type = Ret(const void*, Args...); - - template - auto wrap(std::index_sequence) ENTT_NOEXCEPT { - return [](const void*, Args... args) -> Ret { - const auto arguments = std::forward_as_tuple(std::forward(args)...); - return Ret(std::invoke(Candidate, std::forward>>(std::get(arguments))...)); - }; - } - - template - auto wrap(Type&, std::index_sequence) ENTT_NOEXCEPT { - return [](const void* payload, Args... args) -> Ret { - const auto arguments = std::forward_as_tuple(std::forward(args)...); - Type* curr = static_cast(const_cast, const void*, void*>>(payload)); - return Ret(std::invoke(Candidate, *curr, std::forward>>(std::get(arguments))...)); - }; - } - - template - auto wrap(Type*, std::index_sequence) ENTT_NOEXCEPT { - return [](const void* payload, Args... args) -> Ret { - const auto arguments = std::forward_as_tuple(std::forward(args)...); - Type* curr = static_cast(const_cast, const void*, void*>>(payload)); - return Ret(std::invoke(Candidate, curr, std::forward>>(std::get(arguments))...)); - }; - } - - public: - /*! @brief Function type of the delegate. */ - using function_type = Ret(Args...); - - /*! @brief Default constructor. */ - delegate() ENTT_NOEXCEPT - : fn{ nullptr }, data{ nullptr } - {} - - /** - * @brief Constructs a delegate and connects a free function or an unbound - * member. - * @tparam Candidate Function or member to connect to the delegate. - */ - template - delegate(connect_arg_t) ENTT_NOEXCEPT - : delegate{} - { - connect(); - } - - /** - * @brief Constructs a delegate and connects a free function with payload or - * a bound member. - * @tparam Candidate Function or member to connect to the delegate. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - */ - template - delegate(connect_arg_t, Type&& value_or_instance) ENTT_NOEXCEPT - : delegate{} - { - connect(std::forward(value_or_instance)); - } - - /** - * @brief Connects a free function or an unbound member to a delegate. - * @tparam Candidate Function or member to connect to the delegate. - */ - template - void connect() ENTT_NOEXCEPT { - data = nullptr; - - if constexpr (std::is_invocable_r_v) { - fn = [](const void*, Args... args) -> Ret { - return Ret(std::invoke(Candidate, std::forward(args)...)); - }; - } - else if constexpr (std::is_member_pointer_v) { - fn = wrap(internal::index_sequence_for>>(internal::function_pointer_t{})); - } - else { - fn = wrap(internal::index_sequence_for(internal::function_pointer_t{})); - } - } - - /** - * @brief Connects a free function with payload or a bound member to a - * delegate. - * - * The delegate isn't responsible for the connected object or the payload. - * Users must always guarantee that the lifetime of the instance overcomes - * the one of the delegate.
- * When used to connect a free function with payload, its signature must be - * such that the instance is the first argument before the ones used to - * define the delegate itself. - * - * @tparam Candidate Function or member to connect to the delegate. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid reference that fits the purpose. - */ - template - void connect(Type& value_or_instance) ENTT_NOEXCEPT { - data = &value_or_instance; - - if constexpr (std::is_invocable_r_v) { - fn = [](const void* payload, Args... args) -> Ret { - Type* curr = static_cast(const_cast, const void*, void*>>(payload)); - return Ret(std::invoke(Candidate, *curr, std::forward(args)...)); - }; - } - else { - fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); - } - } - - /** - * @brief Connects a free function with payload or a bound member to a - * delegate. - * - * @sa connect(Type &) - * - * @tparam Candidate Function or member to connect to the delegate. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid pointer that fits the purpose. - */ - template - void connect(Type* value_or_instance) ENTT_NOEXCEPT { - data = value_or_instance; - - if constexpr (std::is_invocable_r_v) { - fn = [](const void* payload, Args... args) -> Ret { - Type* curr = static_cast(const_cast, const void*, void*>>(payload)); - return Ret(std::invoke(Candidate, curr, std::forward(args)...)); - }; - } - else { - fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); - } - } - - /** - * @brief Resets a delegate. - * - * After a reset, a delegate cannot be invoked anymore. - */ - void reset() ENTT_NOEXCEPT { - fn = nullptr; - data = nullptr; - } - - /** - * @brief Returns the instance or the payload linked to a delegate, if any. - * @return An opaque pointer to the underlying data. - */ - const void* instance() const ENTT_NOEXCEPT { - return data; - } - - /** - * @brief Triggers a delegate. - * - * The delegate invokes the underlying function and returns the result. - * - * @warning - * Attempting to trigger an invalid delegate results in undefined - * behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * delegate has not yet been set. - * - * @param args Arguments to use to invoke the underlying function. - * @return The value returned by the underlying function. - */ - Ret operator()(Args... args) const { - ENTT_ASSERT(fn); - return fn(data, std::forward(args)...); - } - - /** - * @brief Checks whether a delegate actually stores a listener. - * @return False if the delegate is empty, true otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - // no need to test also data - return !(fn == nullptr); - } - - /** - * @brief Compares the contents of two delegates. - * @param other Delegate with which to compare. - * @return False if the two contents differ, true otherwise. - */ - bool operator==(const delegate& other) const ENTT_NOEXCEPT { - return fn == other.fn && data == other.data; - } - - private: - proto_fn_type* fn; - const void* data; - }; - - - /** - * @brief Compares the contents of two delegates. - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - * @param lhs A valid delegate object. - * @param rhs A valid delegate object. - * @return True if the two contents differ, false otherwise. - */ - template - bool operator!=(const delegate& lhs, const delegate& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - /** - * @brief Deduction guide. - * @tparam Candidate Function or member to connect to the delegate. - */ - template - delegate(connect_arg_t) ENTT_NOEXCEPT - ->delegate>>; - - - /** - * @brief Deduction guide. - * @tparam Candidate Function or member to connect to the delegate. - * @tparam Type Type of class or type of payload. - */ - template - delegate(connect_arg_t, Type&&) ENTT_NOEXCEPT - ->delegate>>; - - -} - - -#endif - -// #include "fwd.hpp" -#ifndef ENTT_SIGNAL_FWD_HPP -#define ENTT_SIGNAL_FWD_HPP - - -namespace entt { - - - /*! @class delegate */ - template - class delegate; - - /*! @class dispatcher */ - class dispatcher; - - /*! @class emitter */ - template - class emitter; - - /*! @class connection */ - class connection; - - /*! @class scoped_connection */ - struct scoped_connection; - - /*! @class sink */ - template - class sink; - - /*! @class sigh */ - template - class sigh; - - -} - - -#endif - - - -namespace entt { - - - /** - * @brief Sink class. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error unless the template parameter is a function type. - * - * @tparam Function A valid function type. - */ - template - class sink; - - - /** - * @brief Unmanaged signal handler. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error unless the template parameter is a function type. - * - * @tparam Function A valid function type. - */ - template - class sigh; - - - /** - * @brief Unmanaged signal handler. - * - * It works directly with references to classes and pointers to member functions - * as well as pointers to free functions. Users of this class are in charge of - * disconnecting instances before deleting them. - * - * This class serves mainly two purposes: - * - * * Creating signals to use later to notify a bunch of listeners. - * * Collecting results from a set of functions like in a voting system. - * - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - */ - template - class sigh { - /*! @brief A sink is allowed to modify a signal. */ - friend class sink; - - public: - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Sink type. */ - using sink_type = entt::sink; - - /** - * @brief Instance type when it comes to connecting member functions. - * @tparam Class Type of class to which the member function belongs. - */ - template - using instance_type = Class*; - - /** - * @brief Number of listeners connected to the signal. - * @return Number of listeners currently connected. - */ - size_type size() const ENTT_NOEXCEPT { - return calls.size(); - } - - /** - * @brief Returns false if at least a listener is connected to the signal. - * @return True if the signal has no listeners connected, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return calls.empty(); - } - - /** - * @brief Triggers a signal. - * - * All the listeners are notified. Order isn't guaranteed. - * - * @param args Arguments to use to invoke listeners. - */ - void publish(Args... args) const { - for (auto&& call : std::as_const(calls)) { - call(args...); - } - } - - /** - * @brief Collects return values from the listeners. - * - * The collector must expose a call operator with the following properties: - * - * * The return type is either `void` or such that it's convertible to - * `bool`. In the second case, a true value will stop the iteration. - * * The list of parameters is empty if `Ret` is `void`, otherwise it - * contains a single element such that `Ret` is convertible to it. - * - * @tparam Func Type of collector to use, if any. - * @param func A valid function object. - * @param args Arguments to use to invoke listeners. - */ - template - void collect(Func func, Args... args) const { - for (auto&& call : calls) { - if constexpr (std::is_void_v) { - if constexpr (std::is_invocable_r_v) { - call(args...); - if (func()) { break; } - } - else { - call(args...); - func(); - } - } - else { - if constexpr (std::is_invocable_r_v) { - if (func(call(args...))) { break; } - } - else { - func(call(args...)); - } - } - } - } - - private: - std::vector> calls; - }; - - - /** - * @brief Connection class. - * - * Opaque object the aim of which is to allow users to release an already - * estabilished connection without having to keep a reference to the signal or - * the sink that generated it. - */ - class connection { - /*! @brief A sink is allowed to create connection objects. */ - template - friend class sink; - - connection(delegate fn, void* ref) - : disconnect{ fn }, signal{ ref } - {} - - public: - /*! @brief Default constructor. */ - connection() = default; - - /** - * @brief Checks whether a connection is properly initialized. - * @return True if the connection is properly initialized, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return static_cast(disconnect); - } - - /*! @brief Breaks the connection. */ - void release() { - if (disconnect) { - disconnect(signal); - disconnect.reset(); - } - } - - private: - delegate disconnect; - void* signal{}; - }; - - - /** - * @brief Scoped connection class. - * - * Opaque object the aim of which is to allow users to release an already - * estabilished connection without having to keep a reference to the signal or - * the sink that generated it.
- * A scoped connection automatically breaks the link between the two objects - * when it goes out of scope. - */ - struct scoped_connection { - /*! @brief Default constructor. */ - scoped_connection() = default; - - /** - * @brief Constructs a scoped connection from a basic connection. - * @param other A valid connection object. - */ - scoped_connection(const connection& other) - : conn{ other } - {} - - /*! @brief Default copy constructor, deleted on purpose. */ - scoped_connection(const scoped_connection&) = delete; - - /*! @brief Automatically breaks the link on destruction. */ - ~scoped_connection() { - conn.release(); - } - - /** - * @brief Default copy assignment operator, deleted on purpose. - * @return This scoped connection. - */ - scoped_connection& operator=(const scoped_connection&) = delete; - - /** - * @brief Acquires a connection. - * @param other The connection object to acquire. - * @return This scoped connection. - */ - scoped_connection& operator=(connection other) { - conn = std::move(other); - return *this; - } - - /** - * @brief Checks whether a scoped connection is properly initialized. - * @return True if the connection is properly initialized, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return static_cast(conn); - } - - /*! @brief Breaks the connection. */ - void release() { - conn.release(); - } - - private: - connection conn; - }; - - - /** - * @brief Sink class. - * - * A sink is used to connect listeners to signals and to disconnect them.
- * The function type for a listener is the one of the signal to which it - * belongs. - * - * The clear separation between a signal and a sink permits to store the former - * as private data member without exposing the publish functionality to the - * users of the class. - * - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - */ - template - class sink { - using signal_type = sigh; - using difference_type = typename std::iterator_traits::difference_type; - - template - static void release(Type value_or_instance, void* signal) { - sink{ *static_cast(signal) }.disconnect(value_or_instance); - } - - template - static void release(void* signal) { - sink{ *static_cast(signal) }.disconnect(); - } - - public: - /** - * @brief Constructs a sink that is allowed to modify a given signal. - * @param ref A valid reference to a signal object. - */ - sink(sigh& ref) ENTT_NOEXCEPT - : offset{}, - signal{ &ref } - {} - - /** - * @brief Returns false if at least a listener is connected to the sink. - * @return True if the sink has no listeners connected, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return signal->calls.empty(); - } - - /** - * @brief Returns a sink that connects before a given free function or an - * unbound member. - * @tparam Function A valid free function pointer. - * @return A properly initialized sink object. - */ - template - sink before() { - delegate call{}; - call.template connect(); - - const auto& calls = signal->calls; - const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call)); - - sink other{ *this }; - other.offset = std::distance(it, calls.cend()); - return other; - } - - /** - * @brief Returns a sink that connects before a free function with payload - * or a bound member. - * @tparam Candidate Member or free function to look for. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - * @return A properly initialized sink object. - */ - template - sink before(Type&& value_or_instance) { - delegate call{}; - call.template connect(std::forward(value_or_instance)); - - const auto& calls = signal->calls; - const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call)); - - sink other{ *this }; - other.offset = std::distance(it, calls.cend()); - return other; - } - - /** - * @brief Returns a sink that connects before a given instance or specific - * payload. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - * @return A properly initialized sink object. - */ - template - sink before(Type& value_or_instance) { - return before(&value_or_instance); - } - - /** - * @brief Returns a sink that connects before a given instance or specific - * payload. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid pointer that fits the purpose. - * @return A properly initialized sink object. - */ - template - sink before(Type* value_or_instance) { - sink other{ *this }; - - if (value_or_instance) { - const auto& calls = signal->calls; - const auto it = std::find_if(calls.cbegin(), calls.cend(), [value_or_instance](const auto& delegate) { - return delegate.instance() == value_or_instance; - }); - - other.offset = std::distance(it, calls.cend()); - } - - return other; - } - - /** - * @brief Returns a sink that connects before anything else. - * @return A properly initialized sink object. - */ - sink before() { - sink other{ *this }; - other.offset = signal->calls.size(); - return other; - } - - /** - * @brief Connects a free function or an unbound member to a signal. - * - * The signal handler performs checks to avoid multiple connections for the - * same function. - * - * @tparam Candidate Function or member to connect to the signal. - * @return A properly initialized connection object. - */ - template - connection connect() { - disconnect(); - - delegate call{}; - call.template connect(); - signal->calls.insert(signal->calls.end() - offset, std::move(call)); - - delegate conn{}; - conn.template connect<&release>(); - return { std::move(conn), signal }; - } - - /** - * @brief Connects a free function with payload or a bound member to a - * signal. - * - * The signal isn't responsible for the connected object or the payload. - * Users must always guarantee that the lifetime of the instance overcomes - * the one of the signal. On the other side, the signal handler performs - * checks to avoid multiple connections for the same function.
- * When used to connect a free function with payload, its signature must be - * such that the instance is the first argument before the ones used to - * define the signal itself. - * - * @tparam Candidate Function or member to connect to the signal. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - * @return A properly initialized connection object. - */ - template - connection connect(Type&& value_or_instance) { - disconnect(value_or_instance); - - delegate call{}; - call.template connect(value_or_instance); - signal->calls.insert(signal->calls.end() - offset, std::move(call)); - - delegate conn{}; - conn.template connect<&release>(value_or_instance); - return { std::move(conn), signal }; - } - - /** - * @brief Disconnects a free function or an unbound member from a signal. - * @tparam Candidate Function or member to disconnect from the signal. - */ - template - void disconnect() { - auto& calls = signal->calls; - delegate call{}; - call.template connect(); - calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end()); - } - - /** - * @brief Disconnects a free function with payload or a bound member from a - * signal. - * @tparam Candidate Function or member to disconnect from the signal. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - */ - template - void disconnect(Type&& value_or_instance) { - auto& calls = signal->calls; - delegate call{}; - call.template connect(std::forward(value_or_instance)); - calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end()); - } - - /** - * @brief Disconnects free functions with payload or bound members from a - * signal. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - */ - template - void disconnect(Type& value_or_instance) { - disconnect(&value_or_instance); - } - - /** - * @brief Disconnects free functions with payload or bound members from a - * signal. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - */ - template - void disconnect(Type* value_or_instance) { - if (value_or_instance) { - auto& calls = signal->calls; - calls.erase(std::remove_if(calls.begin(), calls.end(), [value_or_instance](const auto& delegate) { - return delegate.instance() == value_or_instance; - }), calls.end()); - } - } - - /*! @brief Disconnects all the listeners from a signal. */ - void disconnect() { - signal->calls.clear(); - } - - private: - difference_type offset; - signal_type* signal; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the function type of a sink directly from the signal it - * refers to. - * - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - */ - template - sink(sigh&) ENTT_NOEXCEPT->sink; - - -} - - -#endif - -// #include "entity.hpp" -#ifndef ENTT_ENTITY_ENTITY_HPP -#define ENTT_ENTITY_ENTITY_HPP - - -#include -#include -// #include "../config/config.h" - -// #include "../core/type_traits.hpp" - -// #include "../core/fwd.hpp" - - - -namespace entt { - - - /** - * @brief Entity traits. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error unless the template parameter is an accepted entity type. - */ - template - struct entt_traits; - - - /** - * @brief Entity traits for a 16 bits entity identifier. - * - * A 16 bits entity identifier guarantees: - * - * * 12 bits for the entity number (up to 4k entities). - * * 4 bit for the version (resets in [0-15]). - */ - template<> - struct entt_traits { - /*! @brief Underlying entity type. */ - using entity_type = std::uint16_t; - /*! @brief Underlying version type. */ - using version_type = std::uint8_t; - /*! @brief Difference type. */ - using difference_type = std::int32_t; - - /*! @brief Mask to use to get the entity number out of an identifier. */ - static constexpr std::uint16_t entity_mask = 0xFFF; - /*! @brief Mask to use to get the version out of an identifier. */ - static constexpr std::uint16_t version_mask = 0xF; - /*! @brief Extent of the entity number within an identifier. */ - static constexpr auto entity_shift = 12; - }; - - - /** - * @brief Entity traits for a 32 bits entity identifier. - * - * A 32 bits entity identifier guarantees: - * - * * 20 bits for the entity number (suitable for almost all the games). - * * 12 bit for the version (resets in [0-4095]). - */ - template<> - struct entt_traits { - /*! @brief Underlying entity type. */ - using entity_type = std::uint32_t; - /*! @brief Underlying version type. */ - using version_type = std::uint16_t; - /*! @brief Difference type. */ - using difference_type = std::int64_t; - - /*! @brief Mask to use to get the entity number out of an identifier. */ - static constexpr std::uint32_t entity_mask = 0xFFFFF; - /*! @brief Mask to use to get the version out of an identifier. */ - static constexpr std::uint32_t version_mask = 0xFFF; - /*! @brief Extent of the entity number within an identifier. */ - static constexpr auto entity_shift = 20; - }; - - - /** - * @brief Entity traits for a 64 bits entity identifier. - * - * A 64 bits entity identifier guarantees: - * - * * 32 bits for the entity number (an indecently large number). - * * 32 bit for the version (an indecently large number). - */ - template<> - struct entt_traits { - /*! @brief Underlying entity type. */ - using entity_type = std::uint64_t; - /*! @brief Underlying version type. */ - using version_type = std::uint32_t; - /*! @brief Difference type. */ - using difference_type = std::int64_t; - - /*! @brief Mask to use to get the entity number out of an identifier. */ - static constexpr std::uint64_t entity_mask = 0xFFFFFFFF; - /*! @brief Mask to use to get the version out of an identifier. */ - static constexpr std::uint64_t version_mask = 0xFFFFFFFF; - /*! @brief Extent of the entity number within an identifier. */ - static constexpr auto entity_shift = 32; - }; - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - class null { - template - using traits_type = entt_traits>; - - public: - template - constexpr operator Entity() const ENTT_NOEXCEPT { - return Entity{ traits_type::entity_mask }; - } - - constexpr bool operator==(null) const ENTT_NOEXCEPT { - return true; - } - - constexpr bool operator!=(null) const ENTT_NOEXCEPT { - return false; - } - - template - constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT { - return (to_integral(entity) & traits_type::entity_mask) == to_integral(static_cast(*this)); - } - - template - constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT { - return !(entity == *this); - } - }; - - - template - constexpr bool operator==(const Entity entity, null other) ENTT_NOEXCEPT { - return other.operator==(entity); - } - - - template - constexpr bool operator!=(const Entity entity, null other) ENTT_NOEXCEPT { - return !(other == entity); - } - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /*! @brief Default entity identifier. */ - ENTT_OPAQUE_TYPE(entity, id_type); - - - /** - * @brief Compile-time constant for null entities. - * - * There exist implicit conversions from this variable to entity identifiers of - * any allowed type. Similarly, there exist comparision operators between the - * null entity and any other entity identifier. - */ - inline constexpr auto null = internal::null{}; - - -} - - -#endif - -// #include "fwd.hpp" -#ifndef ENTT_ENTITY_FWD_HPP -#define ENTT_ENTITY_FWD_HPP - - -// #include "../core/fwd.hpp" - - - -namespace entt { - - - /*! @class basic_registry */ - template - class basic_registry; - - /*! @class basic_view */ - template - class basic_view; - - /*! @class basic_runtime_view */ - template - class basic_runtime_view; - - /*! @class basic_group */ - template - class basic_group; - - /*! @class basic_observer */ - template - class basic_observer; - - /*! @struct basic_actor */ - template - struct basic_actor; - - /*! @class basic_snapshot */ - template - class basic_snapshot; - - /*! @class basic_snapshot_loader */ - template - class basic_snapshot_loader; - - /*! @class basic_continuous_loader */ - template - class basic_continuous_loader; - - /*! @class entity */ - enum class entity : id_type; - - /*! @brief Alias declaration for the most common use case. */ - using registry = basic_registry; - - /*! @brief Alias declaration for the most common use case. */ - using observer = basic_observer; - - /*! @brief Alias declaration for the most common use case. */ - using actor = basic_actor; - - /*! @brief Alias declaration for the most common use case. */ - using snapshot = basic_snapshot; - - /*! @brief Alias declaration for the most common use case. */ - using snapshot_loader = basic_snapshot_loader; - - /*! @brief Alias declaration for the most common use case. */ - using continuous_loader = basic_continuous_loader; - - /** - * @brief Alias declaration for the most common use case. - * @tparam Types Types of components iterated by the view. - */ - template - using view = basic_view; - - /*! @brief Alias declaration for the most common use case. */ - using runtime_view = basic_runtime_view; - - /** - * @brief Alias declaration for the most common use case. - * @tparam Types Types of components iterated by the group. - */ - template - using group = basic_group; - - -} - - -#endif - -// #include "group.hpp" -#ifndef ENTT_ENTITY_GROUP_HPP -#define ENTT_ENTITY_GROUP_HPP - - -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/type_traits.hpp" - -// #include "sparse_set.hpp" -#ifndef ENTT_ENTITY_SPARSE_SET_HPP -#define ENTT_ENTITY_SPARSE_SET_HPP - - -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/algorithm.hpp" - -// #include "entity.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Basic sparse set implementation. - * - * Sparse set or packed array or whatever is the name users give it.
- * Two arrays: an _external_ one and an _internal_ one; a _sparse_ one and a - * _packed_ one; one used for direct access through contiguous memory, the other - * one used to get the data through an extra level of indirection.
- * This is largely used by the registry to offer users the fastest access ever - * to the components. Views and groups in general are almost entirely designed - * around sparse sets. - * - * This type of data structure is widely documented in the literature and on the - * web. This is nothing more than a customized implementation suitable for the - * purpose of the framework. - * - * @note - * There are no guarantees that entities are returned in the insertion order - * when iterate a sparse set. Do not make assumption on the order in any case. - * - * @note - * Internal data structures arrange elements to maximize performance. Because of - * that, there are no guarantees that elements have the expected order when - * iterate directly the internal packed array (see `data` and `size` member - * functions for that). Use `begin` and `end` instead. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - class sparse_set { - static_assert(ENTT_PAGE_SIZE && ((ENTT_PAGE_SIZE& (ENTT_PAGE_SIZE - 1)) == 0)); - static constexpr auto entt_per_page = ENTT_PAGE_SIZE / sizeof(Entity); - - using traits_type = entt_traits>; - using page_type = std::unique_ptr; - - class sparse_set_iterator final { - friend class sparse_set; - - using packed_type = std::vector; - using index_type = typename traits_type::difference_type; - - sparse_set_iterator(const packed_type& ref, const index_type idx) ENTT_NOEXCEPT - : packed{ &ref }, index{ idx } - {} - - public: - using difference_type = index_type; - using value_type = Entity; - using pointer = const value_type*; - using reference = const value_type&; - using iterator_category = std::random_access_iterator_tag; - - sparse_set_iterator() ENTT_NOEXCEPT = default; - - sparse_set_iterator& operator++() ENTT_NOEXCEPT { - return --index, * this; - } - - sparse_set_iterator operator++(int) ENTT_NOEXCEPT { - iterator orig = *this; - return operator++(), orig; - } - - sparse_set_iterator& operator--() ENTT_NOEXCEPT { - return ++index, * this; - } - - sparse_set_iterator operator--(int) ENTT_NOEXCEPT { - sparse_set_iterator orig = *this; - return operator--(), orig; - } - - sparse_set_iterator& operator+=(const difference_type value) ENTT_NOEXCEPT { - index -= value; - return *this; - } - - sparse_set_iterator operator+(const difference_type value) const ENTT_NOEXCEPT { - sparse_set_iterator copy = *this; - return (copy += value); - } - - sparse_set_iterator& operator-=(const difference_type value) ENTT_NOEXCEPT { - return (*this += -value); - } - - sparse_set_iterator operator-(const difference_type value) const ENTT_NOEXCEPT { - return (*this + -value); - } - - difference_type operator-(const sparse_set_iterator& other) const ENTT_NOEXCEPT { - return other.index - index; - } - - reference operator[](const difference_type value) const { - const auto pos = size_type(index - value - 1); - return (*packed)[pos]; - } - - bool operator==(const sparse_set_iterator& other) const ENTT_NOEXCEPT { - return other.index == index; - } - - bool operator!=(const sparse_set_iterator& other) const ENTT_NOEXCEPT { - return !(*this == other); - } - - bool operator<(const sparse_set_iterator& other) const ENTT_NOEXCEPT { - return index > other.index; - } - - bool operator>(const sparse_set_iterator& other) const ENTT_NOEXCEPT { - return index < other.index; - } - - bool operator<=(const sparse_set_iterator& other) const ENTT_NOEXCEPT { - return !(*this > other); - } - - bool operator>=(const sparse_set_iterator& other) const ENTT_NOEXCEPT { - return !(*this < other); - } - - pointer operator->() const { - const auto pos = size_type(index - 1); - return &(*packed)[pos]; - } - - reference operator*() const { - return *operator->(); - } - - private: - const packed_type* packed; - index_type index; - }; - - auto page(const Entity entt) const ENTT_NOEXCEPT { - return std::size_t{ (to_integral(entt) & traits_type::entity_mask) / entt_per_page }; - } - - auto offset(const Entity entt) const ENTT_NOEXCEPT { - return std::size_t{ to_integral(entt) & (entt_per_page - 1) }; - } - - page_type& assure(const std::size_t pos) { - if (!(pos < sparse.size())) { - sparse.resize(pos + 1); - } - - if (!sparse[pos]) { - sparse[pos] = std::make_unique(entt_per_page); - // null is safe in all cases for our purposes - for (auto* first = sparse[pos].get(), *last = first + entt_per_page; first != last; ++first) { - *first = null; - } - } - - return sparse[pos]; - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Random access iterator type. */ - using iterator = sparse_set_iterator; - - /*! @brief Default constructor. */ - sparse_set() = default; - - /*! @brief Default move constructor. */ - sparse_set(sparse_set&&) = default; - - /*! @brief Default destructor. */ - virtual ~sparse_set() = default; - - /*! @brief Default move assignment operator. @return This sparse set. */ - sparse_set& operator=(sparse_set&&) = default; - - /** - * @brief Increases the capacity of a sparse set. - * - * If the new capacity is greater than the current capacity, new storage is - * allocated, otherwise the method does nothing. - * - * @param cap Desired capacity. - */ - void reserve(const size_type cap) { - packed.reserve(cap); - } - - /** - * @brief Returns the number of elements that a sparse set has currently - * allocated space for. - * @return Capacity of the sparse set. - */ - size_type capacity() const ENTT_NOEXCEPT { - return packed.capacity(); - } - - /*! @brief Requests the removal of unused capacity. */ - void shrink_to_fit() { - // conservative approach - if (packed.empty()) { - sparse.clear(); - } - - sparse.shrink_to_fit(); - packed.shrink_to_fit(); - } - - /** - * @brief Returns the extent of a sparse set. - * - * The extent of a sparse set is also the size of the internal sparse array. - * There is no guarantee that the internal packed array has the same size. - * Usually the size of the internal sparse array is equal or greater than - * the one of the internal packed array. - * - * @return Extent of the sparse set. - */ - size_type extent() const ENTT_NOEXCEPT { - return sparse.size() * entt_per_page; - } - - /** - * @brief Returns the number of elements in a sparse set. - * - * The number of elements is also the size of the internal packed array. - * There is no guarantee that the internal sparse array has the same size. - * Usually the size of the internal sparse array is equal or greater than - * the one of the internal packed array. - * - * @return Number of elements. - */ - size_type size() const ENTT_NOEXCEPT { - return packed.size(); - } - - /** - * @brief Checks whether a sparse set is empty. - * @return True if the sparse set is empty, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return packed.empty(); - } - - /** - * @brief Direct access to the internal packed array. - * - * The returned pointer is such that range `[data(), data() + size()]` is - * always a valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order, even though `respect` has been - * previously invoked. Internal data structures arrange elements to maximize - * performance. Accessing them directly gives a performance boost but less - * guarantees. Use `begin` and `end` if you want to iterate the sparse set - * in the expected order. - * - * @return A pointer to the internal packed array. - */ - const entity_type* data() const ENTT_NOEXCEPT { - return packed.data(); - } - - /** - * @brief Returns an iterator to the beginning. - * - * The returned iterator points to the first entity of the internal packed - * array. If the sparse set is empty, the returned iterator will be equal to - * `end()`. - * - * @note - * Random access iterators stay true to the order imposed by a call to - * `respect`. - * - * @return An iterator to the first entity of the internal packed array. - */ - iterator begin() const ENTT_NOEXCEPT { - const typename traits_type::difference_type pos = packed.size(); - return iterator{ packed, pos }; - } - - /** - * @brief Returns an iterator to the end. - * - * The returned iterator points to the element following the last entity in - * the internal packed array. Attempting to dereference the returned - * iterator results in undefined behavior. - * - * @note - * Random access iterators stay true to the order imposed by a call to - * `respect`. - * - * @return An iterator to the element following the last entity of the - * internal packed array. - */ - iterator end() const ENTT_NOEXCEPT { - return iterator{ packed, {} }; - } - - /** - * @brief Finds an entity. - * @param entt A valid entity identifier. - * @return An iterator to the given entity if it's found, past the end - * iterator otherwise. - */ - iterator find(const entity_type entt) const { - return contains(entt) ? --(end() - index(entt)) : end(); - } - - /** - * @brief Checks if a sparse set contains an entity. - * @param entt A valid entity identifier. - * @return True if the sparse set contains the entity, false otherwise. - */ - bool contains(const entity_type entt) const { - const auto curr = page(entt); - // testing against null permits to avoid accessing the packed array - return (curr < sparse.size() && sparse[curr] && sparse[curr][offset(entt)] != null); - } - - /*! @copydoc contains */ - [[deprecated("use ::contains instead")]] - bool has(const entity_type entt) const { - return contains(entt); - } - - /** - * @brief Returns the position of an entity in a sparse set. - * - * @warning - * Attempting to get the position of an entity that doesn't belong to the - * sparse set results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * sparse set doesn't contain the given entity. - * - * @param entt A valid entity identifier. - * @return The position of the entity in the sparse set. - */ - size_type index(const entity_type entt) const { - ENTT_ASSERT(contains(entt)); - return size_type(sparse[page(entt)][offset(entt)]); - } - - /** - * @brief Assigns an entity to a sparse set. - * - * @warning - * Attempting to assign an entity that already belongs to the sparse set - * results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * sparse set already contains the given entity. - * - * @param entt A valid entity identifier. - */ - void emplace(const entity_type entt) { - ENTT_ASSERT(!contains(entt)); - assure(page(entt))[offset(entt)] = entity_type(packed.size()); - packed.push_back(entt); - } - - /*! @copydoc emplace */ - [[deprecated("use ::emplace instead")]] - void construct(const entity_type entt) { - emplace(entt); - } - - /** - * @brief Assigns one or more entities to a sparse set. - * - * @warning - * Attempting to assign an entity that already belongs to the sparse set - * results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * sparse set already contains the given entity. - * - * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - */ - template - void insert(It first, It last) { - auto next = packed.size(); - packed.insert(packed.end(), first, last); - - while (first != last) { - const auto entt = *(first++); - ENTT_ASSERT(!contains(entt)); - assure(page(entt))[offset(entt)] = entity_type(next++); - } - } - - /*! @copydoc insert */ - template - [[deprecated("use ::insert instead")]] - void construct(It first, It last) { - insert(std::move(first), std::move(last)); - } - - /** - * @brief Removes an entity from a sparse set. - * - * @warning - * Attempting to remove an entity that doesn't belong to the sparse set - * results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * sparse set doesn't contain the given entity. - * - * @param entt A valid entity identifier. - */ - void erase(const entity_type entt) { - ENTT_ASSERT(contains(entt)); - const auto curr = page(entt); - const auto pos = offset(entt); - packed[size_type(sparse[curr][pos])] = entity_type(packed.back()); - sparse[page(packed.back())][offset(packed.back())] = sparse[curr][pos]; - sparse[curr][pos] = null; - packed.pop_back(); - } - - /*! @copydoc erase */ - [[deprecated("use ::erase instead")]] - void destroy(const entity_type entt) { - erase(entt); - } - - /** - * @brief Swaps two entities in the internal packed array. - * - * For what it's worth, this function affects both the internal sparse array - * and the internal packed array. Users should not care of that anyway. - * - * @warning - * Attempting to swap entities that don't belong to the sparse set results - * in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * sparse set doesn't contain the given entities. - * - * @param lhs A valid entity identifier. - * @param rhs A valid entity identifier. - */ - virtual void swap(const entity_type lhs, const entity_type rhs) { - auto& from = sparse[page(lhs)][offset(lhs)]; - auto& to = sparse[page(rhs)][offset(rhs)]; - std::swap(packed[size_type(from)], packed[size_type(to)]); - std::swap(from, to); - } - - /** - * @brief Sort elements according to the given comparison function. - * - * Sort the elements so that iterating the range with a couple of iterators - * returns them in the expected order. See `begin` and `end` for more - * details. - * - * The comparison function object must return `true` if the first element - * is _less_ than the second one, `false` otherwise. The signature of the - * comparison function should be equivalent to the following: - * - * @code{.cpp} - * bool(const Entity, const Entity); - * @endcode - * - * Moreover, the comparison function object shall induce a - * _strict weak ordering_ on the values. - * - * The sort function oject must offer a member function template - * `operator()` that accepts three arguments: - * - * * An iterator to the first element of the range to sort. - * * An iterator past the last element of the range to sort. - * * A comparison function to use to compare the elements. - * - * @note - * Attempting to iterate elements using a raw pointer returned by a call to - * `data` gives no guarantees on the order, even though `sort` has been - * invoked. - * - * @tparam Compare Type of comparison function object. - * @tparam Sort Type of sort function object. - * @tparam Args Types of arguments to forward to the sort function object. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param compare A valid comparison function object. - * @param algo A valid sort function object. - * @param args Arguments to forward to the sort function object, if any. - */ - template - void sort(iterator first, iterator last, Compare compare, Sort algo = Sort{}, Args &&... args) { - ENTT_ASSERT(!(last < first)); - ENTT_ASSERT(!(last > end())); - - const auto length = std::distance(first, last); - const auto skip = std::distance(last, end()); - const auto to = packed.rend() - skip; - const auto from = to - length; - - algo(from, to, std::move(compare), std::forward(args)...); - - for (size_type pos = skip, end = skip + length; pos < end; ++pos) { - sparse[page(packed[pos])][offset(packed[pos])] = entity_type(pos); - } - } - - /** - * @brief Sort elements according to the given comparison function. - * - * @sa sort - * - * This function is a slightly slower version of `sort` that invokes the - * caller to indicate which entities are swapped.
- * It's recommended when the caller wants to sort its own data structures to - * align them with the order induced in the sparse set. - * - * The signature of the callback should be equivalent to the following: - * - * @code{.cpp} - * bool(const Entity, const Entity); - * @endcode - * - * @tparam Apply Type of function object to invoke to notify the caller. - * @tparam Compare Type of comparison function object. - * @tparam Sort Type of sort function object. - * @tparam Args Types of arguments to forward to the sort function object. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param apply A valid function object to use as a callback. - * @param compare A valid comparison function object. - * @param algo A valid sort function object. - * @param args Arguments to forward to the sort function object, if any. - */ - template - void arrange(iterator first, iterator last, Apply apply, Compare compare, Sort algo = Sort{}, Args &&... args) { - ENTT_ASSERT(!(last < first)); - ENTT_ASSERT(!(last > end())); - - const auto length = std::distance(first, last); - const auto skip = std::distance(last, end()); - const auto to = packed.rend() - skip; - const auto from = to - length; - - algo(from, to, std::move(compare), std::forward(args)...); - - for (size_type pos = skip, end = skip + length; pos < end; ++pos) { - auto curr = pos; - auto next = index(packed[curr]); - - while (curr != next) { - apply(packed[curr], packed[next]); - sparse[page(packed[curr])][offset(packed[curr])] = entity_type(curr); - - curr = next; - next = index(packed[curr]); - } - } - } - - /** - * @brief Sort entities according to their order in another sparse set. - * - * Entities that are part of both the sparse sets are ordered internally - * according to the order they have in `other`. All the other entities goes - * to the end of the list and there are no guarantees on their order.
- * In other terms, this function can be used to impose the same order on two - * sets by using one of them as a master and the other one as a slave. - * - * Iterating the sparse set with a couple of iterators returns elements in - * the expected order after a call to `respect`. See `begin` and `end` for - * more details. - * - * @note - * Attempting to iterate elements using a raw pointer returned by a call to - * `data` gives no guarantees on the order, even though `respect` has been - * invoked. - * - * @param other The sparse sets that imposes the order of the entities. - */ - void respect(const sparse_set& other) { - const auto to = other.end(); - auto from = other.begin(); - - size_type pos = packed.size() - 1; - - while (pos && from != to) { - if (contains(*from)) { - if (*from != packed[pos]) { - swap(packed[pos], *from); - } - - --pos; - } - - ++from; - } - } - - /** - * @brief Clears a sparse set. - */ - void clear() ENTT_NOEXCEPT { - sparse.clear(); - packed.clear(); - } - - private: - std::vector sparse; - std::vector packed; - }; - - -} - - -#endif - -// #include "storage.hpp" -#ifndef ENTT_ENTITY_STORAGE_HPP -#define ENTT_ENTITY_STORAGE_HPP - - -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/algorithm.hpp" - -// #include "sparse_set.hpp" - -// #include "entity.hpp" - - - -namespace entt { - - - /** - * @brief Basic storage implementation. - * - * This class is a refinement of a sparse set that associates an object to an - * entity. The main purpose of this class is to extend sparse sets to store - * components in a registry. It guarantees fast access both to the elements and - * to the entities. - * - * @note - * Entities and objects have the same order. It's guaranteed both in case of raw - * access (either to entities or objects) and when using random or input access - * iterators. - * - * @note - * Internal data structures arrange elements to maximize performance. Because of - * that, there are no guarantees that elements have the expected order when - * iterate directly the internal packed array (see `raw` and `size` member - * functions for that). Use `begin` and `end` instead. - * - * @warning - * Empty types aren't explicitly instantiated. Therefore, many of the functions - * normally available for non-empty types will not be available for empty ones. - * - * @sa sparse_set - * - * @tparam Entity A valid entity type (see entt_traits for more details). - * @tparam Type Type of objects assigned to the entities. - */ - template> - class storage : public sparse_set { - static_assert(std::is_move_constructible_v); - static_assert(std::is_move_assignable_v); - - using underlying_type = sparse_set; - using traits_type = entt_traits>; - - template - class storage_iterator final { - friend class storage; - - using instance_type = std::conditional_t, std::vector>; - using index_type = typename traits_type::difference_type; - - storage_iterator(instance_type& ref, const index_type idx) ENTT_NOEXCEPT - : instances{ &ref }, index{ idx } - {} - - public: - using difference_type = index_type; - using value_type = Type; - using pointer = std::conditional_t; - using reference = std::conditional_t; - using iterator_category = std::random_access_iterator_tag; - - storage_iterator() ENTT_NOEXCEPT = default; - - storage_iterator& operator++() ENTT_NOEXCEPT { - return --index, * this; - } - - storage_iterator operator++(int) ENTT_NOEXCEPT { - storage_iterator orig = *this; - return operator++(), orig; - } - - storage_iterator& operator--() ENTT_NOEXCEPT { - return ++index, * this; - } - - storage_iterator operator--(int) ENTT_NOEXCEPT { - storage_iterator orig = *this; - return operator--(), orig; - } - - storage_iterator& operator+=(const difference_type value) ENTT_NOEXCEPT { - index -= value; - return *this; - } - - storage_iterator operator+(const difference_type value) const ENTT_NOEXCEPT { - storage_iterator copy = *this; - return (copy += value); - } - - storage_iterator& operator-=(const difference_type value) ENTT_NOEXCEPT { - return (*this += -value); - } - - storage_iterator operator-(const difference_type value) const ENTT_NOEXCEPT { - return (*this + -value); - } - - difference_type operator-(const storage_iterator& other) const ENTT_NOEXCEPT { - return other.index - index; - } - - reference operator[](const difference_type value) const ENTT_NOEXCEPT { - const auto pos = size_type(index - value - 1); - return (*instances)[pos]; - } - - bool operator==(const storage_iterator& other) const ENTT_NOEXCEPT { - return other.index == index; - } - - bool operator!=(const storage_iterator& other) const ENTT_NOEXCEPT { - return !(*this == other); - } - - bool operator<(const storage_iterator& other) const ENTT_NOEXCEPT { - return index > other.index; - } - - bool operator>(const storage_iterator& other) const ENTT_NOEXCEPT { - return index < other.index; - } - - bool operator<=(const storage_iterator& other) const ENTT_NOEXCEPT { - return !(*this > other); - } - - bool operator>=(const storage_iterator& other) const ENTT_NOEXCEPT { - return !(*this < other); - } - - pointer operator->() const ENTT_NOEXCEPT { - const auto pos = size_type(index - 1); - return &(*instances)[pos]; - } - - reference operator*() const ENTT_NOEXCEPT { - return *operator->(); - } - - private: - instance_type* instances; - index_type index; - }; - - public: - /*! @brief Type of the objects associated with the entities. */ - using object_type = Type; - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Random access iterator type. */ - using iterator = storage_iterator; - /*! @brief Constant random access iterator type. */ - using const_iterator = storage_iterator; - - /** - * @brief Increases the capacity of a storage. - * - * If the new capacity is greater than the current capacity, new storage is - * allocated, otherwise the method does nothing. - * - * @param cap Desired capacity. - */ - void reserve(const size_type cap) { - underlying_type::reserve(cap); - instances.reserve(cap); - } - - /*! @brief Requests the removal of unused capacity. */ - void shrink_to_fit() { - underlying_type::shrink_to_fit(); - instances.shrink_to_fit(); - } - - /** - * @brief Direct access to the array of objects. - * - * The returned pointer is such that range `[raw(), raw() + size()]` is - * always a valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order, even though either `sort` or - * `respect` has been previously invoked. Internal data structures arrange - * elements to maximize performance. Accessing them directly gives a - * performance boost but less guarantees. Use `begin` and `end` if you want - * to iterate the storage in the expected order. - * - * @return A pointer to the array of objects. - */ - const object_type* raw() const ENTT_NOEXCEPT { - return instances.data(); - } - - /*! @copydoc raw */ - object_type* raw() ENTT_NOEXCEPT { - return const_cast(std::as_const(*this).raw()); - } - - /** - * @brief Returns an iterator to the beginning. - * - * The returned iterator points to the first instance of the given type. If - * the storage is empty, the returned iterator will be equal to `end()`. - * - * @note - * Random access iterators stay true to the order imposed by a call to - * either `sort` or `respect`. - * - * @return An iterator to the first instance of the given type. - */ - const_iterator cbegin() const ENTT_NOEXCEPT { - const typename traits_type::difference_type pos = underlying_type::size(); - return const_iterator{ instances, pos }; - } - - /*! @copydoc cbegin */ - const_iterator begin() const ENTT_NOEXCEPT { - return cbegin(); - } - - /*! @copydoc begin */ - iterator begin() ENTT_NOEXCEPT { - const typename traits_type::difference_type pos = underlying_type::size(); - return iterator{ instances, pos }; - } - - /** - * @brief Returns an iterator to the end. - * - * The returned iterator points to the element following the last instance - * of the given type. Attempting to dereference the returned iterator - * results in undefined behavior. - * - * @note - * Random access iterators stay true to the order imposed by a call to - * either `sort` or `respect`. - * - * @return An iterator to the element following the last instance of the - * given type. - */ - const_iterator cend() const ENTT_NOEXCEPT { - return const_iterator{ instances, {} }; - } - - /*! @copydoc cend */ - const_iterator end() const ENTT_NOEXCEPT { - return cend(); - } - - /*! @copydoc end */ - iterator end() ENTT_NOEXCEPT { - return iterator{ instances, {} }; - } - - /** - * @brief Returns the object associated with an entity. - * - * @warning - * Attempting to use an entity that doesn't belong to the storage results in - * undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * storage doesn't contain the given entity. - * - * @param entt A valid entity identifier. - * @return The object associated with the entity. - */ - const object_type& get(const entity_type entt) const { - return instances[underlying_type::index(entt)]; - } - - /*! @copydoc get */ - object_type& get(const entity_type entt) { - return const_cast(std::as_const(*this).get(entt)); - } - - /** - * @brief Returns a pointer to the object associated with an entity, if any. - * @param entt A valid entity identifier. - * @return The object associated with the entity, if any. - */ - const object_type* try_get(const entity_type entt) const { - return underlying_type::contains(entt) ? (instances.data() + underlying_type::index(entt)) : nullptr; - } - - /*! @copydoc try_get */ - object_type* try_get(const entity_type entt) { - return const_cast(std::as_const(*this).try_get(entt)); - } - - /** - * @brief Assigns an entity to a storage and constructs its object. - * - * This version accept both types that can be constructed in place directly - * and types like aggregates that do not work well with a placement new as - * performed usually under the hood during an _emplace back_. - * - * @warning - * Attempting to use an entity that already belongs to the storage results - * in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * storage already contains the given entity. - * - * @tparam Args Types of arguments to use to construct the object. - * @param entt A valid entity identifier. - * @param args Parameters to use to construct an object for the entity. - */ - template - void emplace(const entity_type entt, Args &&... args) { - if constexpr (std::is_aggregate_v) { - instances.push_back(Type{ std::forward(args)... }); - } - else { - instances.emplace_back(std::forward(args)...); - } - - // entity goes after component in case constructor throws - underlying_type::emplace(entt); - } - - /*! @copydoc emplace */ - template - [[deprecated("use ::emplace instead")]] - void construct(const entity_type entt, Args &&... args) { - emplace(entt, std::forward(args)...); - } - - /** - * @brief Assigns one or more entities to a storage and constructs their - * objects from a given instance. - * - * @warning - * Attempting to assign an entity that already belongs to the storage - * results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * storage already contains the given entity. - * - * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - * @param value An instance of the object to construct. - */ - template - void insert(It first, It last, const object_type& value = {}) { - instances.insert(instances.end(), std::distance(first, last), value); - // entities go after components in case constructors throw - underlying_type::insert(first, last); - } - - /*! @copydoc insert */ - template - [[deprecated("use ::insert instead")]] - std::enable_if_t::value_type, entity_type>, void> - construct(It first, It last, const object_type& value = {}) { - insert(std::move(first), std::move(last), value); - } - - /** - * @brief Assigns one or more entities to a storage and constructs their - * objects from a given range. - * - * @sa construct - * - * @tparam EIt Type of input iterator. - * @tparam CIt Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - * @param from An iterator to the first element of the range of objects. - * @param to An iterator past the last element of the range of objects. - */ - template - void insert(EIt first, EIt last, CIt from, CIt to) { - instances.insert(instances.end(), from, to); - // entities go after components in case constructors throw - underlying_type::insert(first, last); - } - - /*! @copydoc insert */ - template - [[deprecated("use ::insert instead")]] - std::enable_if_t::value_type, entity_type>, void> - construct(EIt first, EIt last, CIt value) { - insert(std::move(first), std::move(last), std::move(value)); - } - - /** - * @brief Removes an entity from a storage and destroys its object. - * - * @warning - * Attempting to use an entity that doesn't belong to the storage results in - * undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * storage doesn't contain the given entity. - * - * @param entt A valid entity identifier. - */ - void erase(const entity_type entt) { - auto other = std::move(instances.back()); - instances[underlying_type::index(entt)] = std::move(other); - instances.pop_back(); - underlying_type::erase(entt); - } - - /*! @copydoc erase */ - [[deprecated("use ::erase instead")]] - void destroy(const entity_type entt) { - erase(entt); - } - - /** - * @brief Swaps entities and objects in the internal packed arrays. - * - * @warning - * Attempting to swap entities that don't belong to the sparse set results - * in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * sparse set doesn't contain the given entities. - * - * @param lhs A valid entity identifier. - * @param rhs A valid entity identifier. - */ - void swap(const entity_type lhs, const entity_type rhs) override { - std::swap(instances[underlying_type::index(lhs)], instances[underlying_type::index(rhs)]); - underlying_type::swap(lhs, rhs); - } - - /** - * @brief Sort elements according to the given comparison function. - * - * Sort the elements so that iterating the range with a couple of iterators - * returns them in the expected order. See `begin` and `end` for more - * details. - * - * The comparison function object must return `true` if the first element - * is _less_ than the second one, `false` otherwise. The signature of the - * comparison function should be equivalent to one of the following: - * - * @code{.cpp} - * bool(const Entity, const Entity); - * bool(const Type &, const Type &); - * @endcode - * - * Moreover, the comparison function object shall induce a - * _strict weak ordering_ on the values. - * - * The sort function oject must offer a member function template - * `operator()` that accepts three arguments: - * - * * An iterator to the first element of the range to sort. - * * An iterator past the last element of the range to sort. - * * A comparison function to use to compare the elements. - * - * @note - * Attempting to iterate elements using a raw pointer returned by a call to - * either `data` or `raw` gives no guarantees on the order, even though - * `sort` has been invoked. - * - * @warning - * Empty types are never instantiated. Therefore, only comparison function - * objects that require to return entities rather than components are - * accepted. - * - * @tparam Compare Type of comparison function object. - * @tparam Sort Type of sort function object. - * @tparam Args Types of arguments to forward to the sort function object. - * @param first An iterator to the first element of the range to sort. - * @param last An iterator past the last element of the range to sort. - * @param compare A valid comparison function object. - * @param algo A valid sort function object. - * @param args Arguments to forward to the sort function object, if any. - */ - template - void sort(iterator first, iterator last, Compare compare, Sort algo = Sort{}, Args &&... args) { - ENTT_ASSERT(!(last < first)); - ENTT_ASSERT(!(last > end())); - - const auto from = underlying_type::begin() + std::distance(begin(), first); - const auto to = from + std::distance(first, last); - - const auto apply = [this](const auto lhs, const auto rhs) { - std::swap(instances[underlying_type::index(lhs)], instances[underlying_type::index(rhs)]); - }; - - if constexpr (std::is_invocable_v) { - underlying_type::arrange(from, to, std::move(apply), [this, compare = std::move(compare)](const auto lhs, const auto rhs) { - return compare(std::as_const(instances[underlying_type::index(lhs)]), std::as_const(instances[underlying_type::index(rhs)])); - }, std::move(algo), std::forward(args)...); - } - else { - underlying_type::arrange(from, to, std::move(apply), std::move(compare), std::move(algo), std::forward(args)...); - } - } - - /*! @brief Clears a storage. */ - void clear() { - underlying_type::clear(); - instances.clear(); - } - - private: - std::vector instances; - }; - - - /*! @copydoc storage */ - template - class storage> : public sparse_set { - using traits_type = entt_traits>; - using underlying_type = sparse_set; - - public: - /*! @brief Type of the objects associated with the entities. */ - using object_type = Type; - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - - /** - * @brief Assigns an entity to a storage and constructs its object. - * - * @warning - * Attempting to use an entity that already belongs to the storage results - * in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * storage already contains the given entity. - * - * @tparam Args Types of arguments to use to construct the object. - * @param entt A valid entity identifier. - * @param args Parameters to use to construct an object for the entity. - */ - template - void emplace(const entity_type entt, Args &&... args) { - [[maybe_unused]] object_type instance{ std::forward(args)... }; - underlying_type::emplace(entt); - } - - /*! @copydoc emplace */ - template - [[deprecated("use ::emplace instead")]] - void construct(const entity_type entt, Args &&... args) { - emplace(entt, std::forward(args)...); - } - - /** - * @brief Assigns one or more entities to a storage. - * - * @warning - * Attempting to assign an entity that already belongs to the storage - * results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * storage already contains the given entity. - * - * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - */ - template - void insert(It first, It last, const object_type & = {}) { - underlying_type::insert(first, last); - } - - /** - * @copydoc insert - * @param value An instance of the object to construct. - */ - template - [[deprecated("use ::insert instead")]] - std::enable_if_t::value_type, entity_type>, void> - construct(It first, It last, const object_type& value = {}) { - insert(std::move(first), std::move(last), value); - } - }; - - -} - - -#endif - -// #include "utility.hpp" -#ifndef ENTT_ENTITY_UTILITY_HPP -#define ENTT_ENTITY_UTILITY_HPP - - -// #include "../core/type_traits.hpp" - - - -namespace entt { - - - /** - * @brief Alias for exclusion lists. - * @tparam Type List of types. - */ - template - struct exclude_t : type_list {}; - - - /** - * @brief Variable template for exclusion lists. - * @tparam Type List of types. - */ - template - inline constexpr exclude_t exclude{}; - - - /** - * @brief Alias for lists of observed components. - * @tparam Type List of types. - */ - template - struct get_t : type_list {}; - - - /** - * @brief Variable template for lists of observed components. - * @tparam Type List of types. - */ - template - inline constexpr get_t get{}; - - -} - - -#endif - -// #include "entity.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Group. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error, but for a few reasonable cases. - */ - template - class basic_group; - - - /** - * @brief Non-owning group. - * - * A non-owning group returns all entities and only the entities that have at - * least the given components. Moreover, it's guaranteed that the entity list - * is tightly packed in memory for fast iterations. - * - * @b Important - * - * Iterators aren't invalidated if: - * - * * New instances of the given components are created and assigned to entities. - * * The entity currently pointed is modified (as an example, if one of the - * given components is removed from the entity to which the iterator points). - * * The entity currently pointed is destroyed. - * - * In all other cases, modifying the pools iterated by the group in any way - * invalidates all the iterators and using them results in undefined behavior. - * - * @note - * Groups share references to the underlying data structures of the registry - * that generated them. Therefore any change to the entities and to the - * components made by means of the registry are immediately reflected by all the - * groups.
- * Moreover, sorting a non-owning group affects all the instances of the same - * group (it means that users don't have to call `sort` on each instance to sort - * all of them because they _share_ entities and components). - * - * @warning - * Lifetime of a group must not overcome that of the registry that generated it. - * In any other case, attempting to use a group results in undefined behavior. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - * @tparam Exclude Types of components used to filter the group. - * @tparam Get Type of components observed by the group. - */ - template - class basic_group, get_t> { - /*! @brief A registry is allowed to create groups. */ - friend class basic_registry; - - template - using pool_type = std::conditional_t, const storage>, storage>; - - // we could use pool_type &..., but vs complains about it and refuses to compile for unknown reasons (most likely a bug) - basic_group(sparse_set& ref, storage> &... gpool) ENTT_NOEXCEPT - : handler{ &ref }, - pools{ &gpool... } - {} - - template - void traverse(Func func, type_list) const { - for (const auto entt : *handler) { - if constexpr (std::is_invocable_v < Func, decltype(get({}))... > ) { - func(std::get*>(pools)->get(entt)...); - } - else { - func(entt, std::get*>(pools)->get(entt)...); - } - } - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Input iterator type. */ - using iterator = typename sparse_set::iterator; - - /** - * @brief Returns the number of existing components of the given type. - * @tparam Component Type of component of which to return the size. - * @return Number of existing components of the given type. - */ - template - size_type size() const ENTT_NOEXCEPT { - return std::get*>(pools)->size(); - } - - /** - * @brief Returns the number of entities that have the given components. - * @return Number of entities that have the given components. - */ - size_type size() const ENTT_NOEXCEPT { - return handler->size(); - } - - /** - * @brief Returns the number of elements that a group has currently - * allocated space for. - * @return Capacity of the group. - */ - size_type capacity() const ENTT_NOEXCEPT { - return handler->capacity(); - } - - /*! @brief Requests the removal of unused capacity. */ - void shrink_to_fit() { - handler->shrink_to_fit(); - } - - /** - * @brief Checks whether a group or some pools are empty. - * @tparam Component Types of components in which one is interested. - * @return True if the group or the pools are empty, false otherwise. - */ - template - bool empty() const ENTT_NOEXCEPT { - if constexpr (sizeof...(Component) == 0) { - return handler->empty(); - } - else { - return (std::get*>(pools)->empty() && ...); - } - } - - /** - * @brief Direct access to the list of components of a given pool. - * - * The returned pointer is such that range - * `[raw(), raw() + size()]` is always a - * valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order of the components. Use `begin` and - * `end` if you want to iterate the group in the expected order. - * - * @tparam Component Type of component in which one is interested. - * @return A pointer to the array of components. - */ - template - Component* raw() const ENTT_NOEXCEPT { - return std::get*>(pools)->raw(); - } - - /** - * @brief Direct access to the list of entities of a given pool. - * - * The returned pointer is such that range - * `[data(), data() + size()]` is always a - * valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order of the entities. Use `begin` and - * `end` if you want to iterate the group in the expected order. - * - * @tparam Component Type of component in which one is interested. - * @return A pointer to the array of entities. - */ - template - const entity_type* data() const ENTT_NOEXCEPT { - return std::get*>(pools)->data(); - } - - /** - * @brief Direct access to the list of entities. - * - * The returned pointer is such that range `[data(), data() + size()]` is - * always a valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order of the entities. Use `begin` and - * `end` if you want to iterate the group in the expected order. - * - * @return A pointer to the array of entities. - */ - const entity_type* data() const ENTT_NOEXCEPT { - return handler->data(); - } - - /** - * @brief Returns an iterator to the first entity that has the given - * components. - * - * The returned iterator points to the first entity that has the given - * components. If the group is empty, the returned iterator will be equal to - * `end()`. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the first entity that has the given components. - */ - iterator begin() const ENTT_NOEXCEPT { - return handler->begin(); - } - - /** - * @brief Returns an iterator that is past the last entity that has the - * given components. - * - * The returned iterator points to the entity following the last entity that - * has the given components. Attempting to dereference the returned iterator - * results in undefined behavior. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the entity following the last entity that has the - * given components. - */ - iterator end() const ENTT_NOEXCEPT { - return handler->end(); - } - - /** - * @brief Returns the first entity that has the given components, if any. - * @return The first entity that has the given components if one exists, the - * null entity otherwise. - */ - entity_type front() const { - const auto it = begin(); - return it != end() ? *it : null; - } - - /** - * @brief Returns the last entity that has the given components, if any. - * @return The last entity that has the given components if one exists, the - * null entity otherwise. - */ - entity_type back() const { - const auto it = std::make_reverse_iterator(end()); - return it != std::make_reverse_iterator(begin()) ? *it : null; - } - - /** - * @brief Finds an entity. - * @param entt A valid entity identifier. - * @return An iterator to the given entity if it's found, past the end - * iterator otherwise. - */ - iterator find(const entity_type entt) const { - const auto it = handler->find(entt); - return it != end() && *it == entt ? it : end(); - } - - /** - * @brief Returns the identifier that occupies the given position. - * @param pos Position of the element to return. - * @return The identifier that occupies the given position. - */ - entity_type operator[](const size_type pos) const { - return begin()[pos]; - } - - /** - * @brief Checks if a group contains an entity. - * @param entt A valid entity identifier. - * @return True if the group contains the given entity, false otherwise. - */ - bool contains(const entity_type entt) const { - return handler->contains(entt); - } - - /** - * @brief Returns the components assigned to the given entity. - * - * Prefer this function instead of `registry::get` during iterations. It has - * far better performance than its counterpart. - * - * @warning - * Attempting to use an invalid component type results in a compilation - * error. Attempting to use an entity that doesn't belong to the group - * results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * group doesn't contain the given entity. - * - * @tparam Component Types of components to get. - * @param entt A valid entity identifier. - * @return The components assigned to the entity. - */ - template - decltype(auto) get([[maybe_unused]] const entity_type entt) const { - ENTT_ASSERT(contains(entt)); - - if constexpr (sizeof...(Component) == 1) { - return (std::get*>(pools)->get(entt), ...); - } - else { - return std::tuple({}))... > {get(entt)...}; - } - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The function object is invoked for each entity. It is provided with the - * entity itself and a set of references to non-empty components. The - * _constness_ of the components is as requested.
- * The signature of the function must be equivalent to one of the following - * forms: - * - * @code{.cpp} - * void(const entity_type, Type &...); - * void(Type &...); - * @endcode - * - * @note - * Empty types aren't explicitly instantiated and therefore they are never - * returned during iterations. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - using get_type_list = type_list_cat_t, type_list>...>; - traverse(std::move(func), get_type_list{}); - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The function object is invoked for each entity. It is provided with the - * entity itself and a set of references to non-empty components. The - * _constness_ of the components is as requested.
- * The signature of the function must be equivalent to one of the following - * forms: - * - * @code{.cpp} - * void(const entity_type, Type &...); - * void(Type &...); - * @endcode - * - * @note - * Empty types aren't explicitly instantiated and therefore they are never - * returned during iterations. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - [[deprecated("use ::each instead")]] - void less(Func func) const { - each(std::move(func)); - } - - /** - * @brief Sort a group according to the given comparison function. - * - * Sort the group so that iterating it with a couple of iterators returns - * entities and components in the expected order. See `begin` and `end` for - * more details. - * - * The comparison function object must return `true` if the first element - * is _less_ than the second one, `false` otherwise. The signature of the - * comparison function should be equivalent to one of the following: - * - * @code{.cpp} - * bool(std::tuple, std::tuple); - * bool(const Component &..., const Component &...); - * bool(const Entity, const Entity); - * @endcode - * - * Where `Component` are such that they are iterated by the group.
- * Moreover, the comparison function object shall induce a - * _strict weak ordering_ on the values. - * - * The sort function oject must offer a member function template - * `operator()` that accepts three arguments: - * - * * An iterator to the first element of the range to sort. - * * An iterator past the last element of the range to sort. - * * A comparison function to use to compare the elements. - * - * @note - * Attempting to iterate elements using a raw pointer returned by a call to - * either `data` or `raw` gives no guarantees on the order, even though - * `sort` has been invoked. - * - * @tparam Component Optional types of components to compare. - * @tparam Compare Type of comparison function object. - * @tparam Sort Type of sort function object. - * @tparam Args Types of arguments to forward to the sort function object. - * @param compare A valid comparison function object. - * @param algo A valid sort function object. - * @param args Arguments to forward to the sort function object, if any. - */ - template - void sort(Compare compare, Sort algo = Sort{}, Args &&... args) { - if constexpr (sizeof...(Component) == 0) { - static_assert(std::is_invocable_v); - handler->sort(handler->begin(), handler->end(), std::move(compare), std::move(algo), std::forward(args)...); - } - else if constexpr (sizeof...(Component) == 1) { - handler->sort(handler->begin(), handler->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) { - return compare((std::get*>(pools)->get(lhs), ...), (std::get*>(pools)->get(rhs), ...)); - }, std::move(algo), std::forward(args)...); - } - else { - handler->sort(handler->begin(), handler->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) { - return compare(std::tuple({}))... > {std::get*>(pools)->get(lhs)...}, std::tuple({}))... > {std::get*>(pools)->get(rhs)...}); - }, std::move(algo), std::forward(args)...); - } - } - - /** - * @brief Sort the shared pool of entities according to the given component. - * - * Non-owning groups of the same type share with the registry a pool of - * entities with its own order that doesn't depend on the order of any pool - * of components. Users can order the underlying data structure so that it - * respects the order of the pool of the given component. - * - * @note - * The shared pool of entities and thus its order is affected by the changes - * to each and every pool that it tracks. Therefore changes to those pools - * can quickly ruin the order imposed to the pool of entities shared between - * the non-owning groups. - * - * @tparam Component Type of component to use to impose the order. - */ - template - void sort() const { - handler->respect(*std::get*>(pools)); - } - - private: - sparse_set* handler; - const std::tuple *...> pools; - }; - - - /** - * @brief Owning group. - * - * Owning groups return all entities and only the entities that have at least - * the given components. Moreover: - * - * * It's guaranteed that the entity list is tightly packed in memory for fast - * iterations. - * * It's guaranteed that the lists of owned components are tightly packed in - * memory for even faster iterations and to allow direct access. - * * They stay true to the order of the owned components and all instances have - * the same order in memory. - * - * The more types of components are owned by a group, the faster it is to - * iterate them. - * - * @b Important - * - * Iterators aren't invalidated if: - * - * * New instances of the given components are created and assigned to entities. - * * The entity currently pointed is modified (as an example, if one of the - * given components is removed from the entity to which the iterator points). - * * The entity currently pointed is destroyed. - * - * In all other cases, modifying the pools iterated by the group in any way - * invalidates all the iterators and using them results in undefined behavior. - * - * @note - * Groups share references to the underlying data structures of the registry - * that generated them. Therefore any change to the entities and to the - * components made by means of the registry are immediately reflected by all the - * groups. - * Moreover, sorting an owning group affects all the instance of the same group - * (it means that users don't have to call `sort` on each instance to sort all - * of them because they share the underlying data structure). - * - * @warning - * Lifetime of a group must not overcome that of the registry that generated it. - * In any other case, attempting to use a group results in undefined behavior. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - * @tparam Exclude Types of components used to filter the group. - * @tparam Get Types of components observed by the group. - * @tparam Owned Types of components owned by the group. - */ - template - class basic_group, get_t, Owned...> { - /*! @brief A registry is allowed to create groups. */ - friend class basic_registry; - - template - using pool_type = std::conditional_t, const storage>, storage>; - - template - using component_iterator = decltype(std::declval>().begin()); - - // we could use pool_type &..., but vs complains about it and refuses to compile for unknown reasons (most likely a bug) - basic_group(const std::size_t& ref, const std::size_t& extent, storage> &... opool, storage> &... gpool) ENTT_NOEXCEPT - : pools{ &opool..., &gpool... }, - length{ &extent }, - super{ &ref } - {} - - template - void traverse(Func func, type_list, type_list) const { - [[maybe_unused]] auto it = std::make_tuple((std::get*>(pools)->end() - *length)...); - [[maybe_unused]] auto data = std::get<0>(pools)->sparse_set::end() - *length; - - for (auto next = *length; next; --next) { - if constexpr (std::is_invocable_v < Func, decltype(get({}))..., decltype(get({}))... > ) { - if constexpr (sizeof...(Weak) == 0) { - func(*(std::get>(it)++)...); - } - else { - const auto entt = *(data++); - func(*(std::get>(it)++)..., std::get*>(pools)->get(entt)...); - } - } - else { - const auto entt = *(data++); - func(entt, *(std::get>(it)++)..., std::get*>(pools)->get(entt)...); - } - } - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Input iterator type. */ - using iterator = typename sparse_set::iterator; - - /** - * @brief Returns the number of existing components of the given type. - * @tparam Component Type of component of which to return the size. - * @return Number of existing components of the given type. - */ - template - size_type size() const ENTT_NOEXCEPT { - return std::get*>(pools)->size(); - } - - /** - * @brief Returns the number of entities that have the given components. - * @return Number of entities that have the given components. - */ - size_type size() const ENTT_NOEXCEPT { - return *length; - } - - /** - * @brief Checks whether a group or some pools are empty. - * @tparam Component Types of components in which one is interested. - * @return True if the group or the pools are empty, false otherwise. - */ - template - bool empty() const ENTT_NOEXCEPT { - if constexpr (sizeof...(Component) == 0) { - return !*length; - } - else { - return (std::get*>(pools)->empty() && ...); - } - } - - /** - * @brief Direct access to the list of components of a given pool. - * - * The returned pointer is such that range - * `[raw(), raw() + size()]` is always a - * valid range, even if the container is empty.
- * Moreover, in case the group owns the given component, the range - * `[raw(), raw() + size()]` is such that it contains - * the instances that are part of the group itself. - * - * @note - * There are no guarantees on the order of the components. Use `begin` and - * `end` if you want to iterate the group in the expected order. - * - * @tparam Component Type of component in which one is interested. - * @return A pointer to the array of components. - */ - template - Component* raw() const ENTT_NOEXCEPT { - return std::get*>(pools)->raw(); - } - - /** - * @brief Direct access to the list of entities of a given pool. - * - * The returned pointer is such that range - * `[data(), data() + size()]` is always a - * valid range, even if the container is empty.
- * Moreover, in case the group owns the given component, the range - * `[data(), data() + size()]` is such that it - * contains the entities that are part of the group itself. - * - * @note - * There are no guarantees on the order of the entities. Use `begin` and - * `end` if you want to iterate the group in the expected order. - * - * @tparam Component Type of component in which one is interested. - * @return A pointer to the array of entities. - */ - template - const entity_type* data() const ENTT_NOEXCEPT { - return std::get*>(pools)->data(); - } - - /** - * @brief Direct access to the list of entities. - * - * The returned pointer is such that range `[data(), data() + size()]` is - * always a valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order of the entities. Use `begin` and - * `end` if you want to iterate the group in the expected order. - * - * @return A pointer to the array of entities. - */ - const entity_type* data() const ENTT_NOEXCEPT { - return std::get<0>(pools)->data(); - } - - /** - * @brief Returns an iterator to the first entity that has the given - * components. - * - * The returned iterator points to the first entity that has the given - * components. If the group is empty, the returned iterator will be equal to - * `end()`. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the first entity that has the given components. - */ - iterator begin() const ENTT_NOEXCEPT { - return std::get<0>(pools)->sparse_set::end() - *length; - } - - /** - * @brief Returns an iterator that is past the last entity that has the - * given components. - * - * The returned iterator points to the entity following the last entity that - * has the given components. Attempting to dereference the returned iterator - * results in undefined behavior. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the entity following the last entity that has the - * given components. - */ - iterator end() const ENTT_NOEXCEPT { - return std::get<0>(pools)->sparse_set::end(); - } - - /** - * @brief Returns the first entity that has the given components, if any. - * @return The first entity that has the given components if one exists, the - * null entity otherwise. - */ - entity_type front() const { - const auto it = begin(); - return it != end() ? *it : null; - } - - /** - * @brief Returns the last entity that has the given components, if any. - * @return The last entity that has the given components if one exists, the - * null entity otherwise. - */ - entity_type back() const { - const auto it = std::make_reverse_iterator(end()); - return it != std::make_reverse_iterator(begin()) ? *it : null; - } - - /** - * @brief Finds an entity. - * @param entt A valid entity identifier. - * @return An iterator to the given entity if it's found, past the end - * iterator otherwise. - */ - iterator find(const entity_type entt) const { - const auto it = std::get<0>(pools)->find(entt); - return it != end() && it >= begin() && *it == entt ? it : end(); - } - - /** - * @brief Returns the identifier that occupies the given position. - * @param pos Position of the element to return. - * @return The identifier that occupies the given position. - */ - entity_type operator[](const size_type pos) const { - return begin()[pos]; - } - - /** - * @brief Checks if a group contains an entity. - * @param entt A valid entity identifier. - * @return True if the group contains the given entity, false otherwise. - */ - bool contains(const entity_type entt) const { - return std::get<0>(pools)->contains(entt) && (std::get<0>(pools)->index(entt) < (*length)); - } - - /** - * @brief Returns the components assigned to the given entity. - * - * Prefer this function instead of `registry::get` during iterations. It has - * far better performance than its counterpart. - * - * @warning - * Attempting to use an invalid component type results in a compilation - * error. Attempting to use an entity that doesn't belong to the group - * results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * group doesn't contain the given entity. - * - * @tparam Component Types of components to get. - * @param entt A valid entity identifier. - * @return The components assigned to the entity. - */ - template - decltype(auto) get([[maybe_unused]] const entity_type entt) const { - ENTT_ASSERT(contains(entt)); - - if constexpr (sizeof...(Component) == 1) { - return (std::get*>(pools)->get(entt), ...); - } - else { - return std::tuple({}))... > {get(entt)...}; - } - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The function object is invoked for each entity. It is provided with the - * entity itself and a set of references to non-empty components. The - * _constness_ of the components is as requested.
- * The signature of the function must be equivalent to one of the following - * forms: - * - * @code{.cpp} - * void(const entity_type, Type &...); - * void(Type &...); - * @endcode - * - * @note - * Empty types aren't explicitly instantiated and therefore they are never - * returned during iterations. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - using owned_type_list = type_list_cat_t, type_list>...>; - using get_type_list = type_list_cat_t, type_list>...>; - traverse(std::move(func), owned_type_list{}, get_type_list{}); - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The function object is invoked for each entity. It is provided with the - * entity itself and a set of references to non-empty components. The - * _constness_ of the components is as requested.
- * The signature of the function must be equivalent to one of the following - * forms: - * - * @code{.cpp} - * void(const entity_type, Type &...); - * void(Type &...); - * @endcode - * - * @note - * Empty types aren't explicitly instantiated and therefore they are never - * returned during iterations. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - [[deprecated("use ::each instead")]] - void less(Func func) const { - each(std::move(func)); - } - - /** - * @brief Checks whether the group can be sorted. - * @return True if the group can be sorted, false otherwise. - */ - bool sortable() const ENTT_NOEXCEPT { - constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude); - return *super == size; - } - - /** - * @brief Sort a group according to the given comparison function. - * - * Sort the group so that iterating it with a couple of iterators returns - * entities and components in the expected order. See `begin` and `end` for - * more details. - * - * The comparison function object must return `true` if the first element - * is _less_ than the second one, `false` otherwise. The signature of the - * comparison function should be equivalent to one of the following: - * - * @code{.cpp} - * bool(std::tuple, std::tuple); - * bool(const Component &, const Component &); - * bool(const Entity, const Entity); - * @endcode - * - * Where `Component` are either owned types or not but still such that they - * are iterated by the group.
- * Moreover, the comparison function object shall induce a - * _strict weak ordering_ on the values. - * - * The sort function oject must offer a member function template - * `operator()` that accepts three arguments: - * - * * An iterator to the first element of the range to sort. - * * An iterator past the last element of the range to sort. - * * A comparison function to use to compare the elements. - * - * @note - * Attempting to iterate elements using a raw pointer returned by a call to - * either `data` or `raw` gives no guarantees on the order, even though - * `sort` has been invoked. - * - * @tparam Component Optional types of components to compare. - * @tparam Compare Type of comparison function object. - * @tparam Sort Type of sort function object. - * @tparam Args Types of arguments to forward to the sort function object. - * @param compare A valid comparison function object. - * @param algo A valid sort function object. - * @param args Arguments to forward to the sort function object, if any. - */ - template - void sort(Compare compare, Sort algo = Sort{}, Args &&... args) { - ENTT_ASSERT(sortable()); - auto* cpool = std::get<0>(pools); - - if constexpr (sizeof...(Component) == 0) { - static_assert(std::is_invocable_v); - cpool->sort(cpool->end() - *length, cpool->end(), std::move(compare), std::move(algo), std::forward(args)...); - } - else if constexpr (sizeof...(Component) == 1) { - cpool->sort(cpool->end() - *length, cpool->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) { - return compare((std::get*>(pools)->get(lhs), ...), (std::get*>(pools)->get(rhs), ...)); - }, std::move(algo), std::forward(args)...); - } - else { - cpool->sort(cpool->end() - *length, cpool->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) { - return compare(std::tuple({}))... > {std::get*>(pools)->get(lhs)...}, std::tuple({}))... > {std::get*>(pools)->get(rhs)...}); - }, std::move(algo), std::forward(args)...); - } - - [this](auto* head, auto *... other) { - for (auto next = *length; next; --next) { - const auto pos = next - 1; - [[maybe_unused]] const auto entt = head->data()[pos]; - (other->swap(other->data()[pos], entt), ...); - } - }(std::get*>(pools)...); - } - - private: - const std::tuple *..., pool_type *...> pools; - const size_type* length; - const size_type* super; - }; - - -} - - -#endif - -// #include "runtime_view.hpp" -#ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP -#define ENTT_ENTITY_RUNTIME_VIEW_HPP - - -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "sparse_set.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Runtime view. - * - * Runtime views iterate over those entities that have at least all the given - * components in their bags. During initialization, a runtime view looks at the - * number of entities available for each component and picks up a reference to - * the smallest set of candidate entities in order to get a performance boost - * when iterate.
- * Order of elements during iterations are highly dependent on the order of the - * underlying data structures. See sparse_set and its specializations for more - * details. - * - * @b Important - * - * Iterators aren't invalidated if: - * - * * New instances of the given components are created and assigned to entities. - * * The entity currently pointed is modified (as an example, if one of the - * given components is removed from the entity to which the iterator points). - * * The entity currently pointed is destroyed. - * - * In all the other cases, modifying the pools of the given components in any - * way invalidates all the iterators and using them results in undefined - * behavior. - * - * @note - * Views share references to the underlying data structures of the registry that - * generated them. Therefore any change to the entities and to the components - * made by means of the registry are immediately reflected by the views, unless - * a pool was missing when the view was built (in this case, the view won't - * have a valid reference and won't be updated accordingly). - * - * @warning - * Lifetime of a view must not overcome that of the registry that generated it. - * In any other case, attempting to use a view results in undefined behavior. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - class basic_runtime_view { - /*! @brief A registry is allowed to create views. */ - friend class basic_registry; - - using underlying_iterator = typename sparse_set::iterator; - - class view_iterator final { - friend class basic_runtime_view; - - using direct_type = std::vector*>; - - view_iterator(const direct_type& all, underlying_iterator curr) ENTT_NOEXCEPT - : pools{ &all }, - it{ curr } - { - if (it != (*pools)[0]->end() && !valid()) { - ++(*this); - } - } - - bool valid() const { - return std::all_of(pools->begin()++, pools->end(), [entt = *it](const auto* curr) { - return curr->contains(entt); - }); - } - - public: - using difference_type = typename underlying_iterator::difference_type; - using value_type = typename underlying_iterator::value_type; - using pointer = typename underlying_iterator::pointer; - using reference = typename underlying_iterator::reference; - using iterator_category = std::bidirectional_iterator_tag; - - view_iterator() ENTT_NOEXCEPT = default; - - view_iterator& operator++() { - while (++it != (*pools)[0]->end() && !valid()); - return *this; - } - - view_iterator operator++(int) { - view_iterator orig = *this; - return operator++(), orig; - } - - view_iterator& operator--() ENTT_NOEXCEPT { - while (--it != (*pools)[0]->begin() && !valid()); - return *this; - } - - view_iterator operator--(int) ENTT_NOEXCEPT { - view_iterator orig = *this; - return operator--(), orig; - } - - bool operator==(const view_iterator& other) const ENTT_NOEXCEPT { - return other.it == it; - } - - bool operator!=(const view_iterator& other) const ENTT_NOEXCEPT { - return !(*this == other); - } - - pointer operator->() const { - return it.operator->(); - } - - reference operator*() const { - return *operator->(); - } - - private: - const direct_type* pools; - underlying_iterator it; - }; - - basic_runtime_view(std::vector*> others) ENTT_NOEXCEPT - : pools{ std::move(others) } - { - const auto it = std::min_element(pools.begin(), pools.end(), [](const auto* lhs, const auto* rhs) { - return (!lhs && rhs) || (lhs && rhs && lhs->size() < rhs->size()); - }); - - // brings the best candidate (if any) on front of the vector - std::rotate(pools.begin(), it, pools.end()); - } - - bool valid() const { - return !pools.empty() && pools.front(); - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Input iterator type. */ - using iterator = view_iterator; - - /** - * @brief Estimates the number of entities that have the given components. - * @return Estimated number of entities that have the given components. - */ - size_type size() const { - return valid() ? pools.front()->size() : size_type{}; - } - - /** - * @brief Checks if the view is definitely empty. - * @return True if the view is definitely empty, false otherwise. - */ - bool empty() const { - return !valid() || pools.front()->empty(); - } - - /** - * @brief Returns an iterator to the first entity that has the given - * components. - * - * The returned iterator points to the first entity that has the given - * components. If the view is empty, the returned iterator will be equal to - * `end()`. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the first entity that has the given components. - */ - iterator begin() const { - iterator it{}; - - if (valid()) { - it = { pools, pools[0]->begin() }; - } - - return it; - } - - /** - * @brief Returns an iterator that is past the last entity that has the - * given components. - * - * The returned iterator points to the entity following the last entity that - * has the given components. Attempting to dereference the returned iterator - * results in undefined behavior. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the entity following the last entity that has the - * given components. - */ - iterator end() const { - iterator it{}; - - if (valid()) { - it = { pools, pools[0]->end() }; - } - - return it; - } - - /** - * @brief Checks if a view contains an entity. - * @param entt A valid entity identifier. - * @return True if the view contains the given entity, false otherwise. - */ - bool contains(const entity_type entt) const { - return valid() && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto* view) { - return view->find(entt) != view->end(); - }); - } - - /** - * @brief Iterates entities and applies the given function object to them. - * - * The function object is invoked for each entity. It is provided only with - * the entity itself. To get the components, users can use the registry with - * which the view was built.
- * The signature of the function should be equivalent to the following: - * - * @code{.cpp} - * void(const entity_type); - * @endcode - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - for (const auto entity : *this) { - func(entity); - } - } - - private: - std::vector*> pools; - }; - - -} - - -#endif - -// #include "snapshot.hpp" -#ifndef ENTT_ENTITY_SNAPSHOT_HPP -#define ENTT_ENTITY_SNAPSHOT_HPP - - -#include -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "entity.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Utility class to create snapshots from a registry. - * - * A _snapshot_ can be either a dump of the entire registry or a narrower - * selection of components of interest.
- * This type can be used in both cases if provided with a correctly configured - * output archive. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - class basic_snapshot { - /*! @brief A registry is allowed to create snapshots. */ - friend class basic_registry; - - using traits_type = entt_traits>; - - template - void get(Archive& archive, std::size_t sz, It first, It last) const { - archive(typename traits_type::entity_type(sz)); - - while (first != last) { - const auto entt = *(first++); - - if (reg->template has(entt)) { - if constexpr (std::is_empty_v) { - archive(entt); - } - else { - archive(entt, reg->template get(entt)); - } - } - } - } - - template - void component(Archive& archive, It first, It last, std::index_sequence) const { - std::array size{}; - auto begin = first; - - while (begin != last) { - const auto entt = *(begin++); - ((reg->template has(entt) ? ++size[Indexes] : size[Indexes]), ...); - } - - (get(archive, size[Indexes], first, last), ...); - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - - /** - * @brief Constructs an instance that is bound to a given registry. - * @param source A valid reference to a registry. - */ - basic_snapshot(const basic_registry& source) ENTT_NOEXCEPT - : reg{ &source } - {} - - /*! @brief Default move constructor. */ - basic_snapshot(basic_snapshot&&) = default; - - /*! @brief Default move assignment operator. @return This snapshot. */ - basic_snapshot& operator=(basic_snapshot&&) = default; - - /** - * @brief Puts aside all the entities from the underlying registry. - * - * Entities are serialized along with their versions. Destroyed entities are - * taken in consideration as well by this function. - * - * @tparam Archive Type of output archive. - * @param archive A valid reference to an output archive. - * @return An object of this type to continue creating the snapshot. - */ - template - const basic_snapshot& entities(Archive& archive) const { - const auto sz = reg->size(); - auto first = reg->data(); - const auto last = first + sz; - - archive(typename traits_type::entity_type(sz)); - - while (first != last) { - archive(*(first++)); - } - - return *this; - } - - /** - * @brief Deprecated function. Currently, it does nothing. - * @tparam Archive Type of output archive. - * @return An object of this type to continue creating the snapshot. - */ - template - [[deprecated("use ::entities instead, it exports now also destroyed entities")]] - const basic_snapshot& destroyed(Archive&) const { return *this; } - - /** - * @brief Puts aside the given components. - * - * Each instance is serialized together with the entity to which it belongs. - * Entities are serialized along with their versions. - * - * @tparam Component Types of components to serialize. - * @tparam Archive Type of output archive. - * @param archive A valid reference to an output archive. - * @return An object of this type to continue creating the snapshot. - */ - template - const basic_snapshot& component(Archive& archive) const { - (component(archive, reg->template data(), reg->template data() + reg->template size()), ...); - return *this; - } - - /** - * @brief Puts aside the given components for the entities in a range. - * - * Each instance is serialized together with the entity to which it belongs. - * Entities are serialized along with their versions. - * - * @tparam Component Types of components to serialize. - * @tparam Archive Type of output archive. - * @tparam It Type of input iterator. - * @param archive A valid reference to an output archive. - * @param first An iterator to the first element of the range to serialize. - * @param last An iterator past the last element of the range to serialize. - * @return An object of this type to continue creating the snapshot. - */ - template - const basic_snapshot& component(Archive& archive, It first, It last) const { - component(archive, first, last, std::index_sequence_for{}); - return *this; - } - - private: - const basic_registry* reg; - }; - - - /** - * @brief Utility class to restore a snapshot as a whole. - * - * A snapshot loader requires that the destination registry be empty and loads - * all the data at once while keeping intact the identifiers that the entities - * originally had.
- * An example of use is the implementation of a save/restore utility. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - class basic_snapshot_loader { - /*! @brief A registry is allowed to create snapshot loaders. */ - friend class basic_registry; - - using traits_type = entt_traits>; - - template - void assign(Archive& archive, Args... args) const { - typename traits_type::entity_type length{}; - archive(length); - - while (length--) { - entity_type entt{}; - - if constexpr (std::is_empty_v) { - archive(entt); - const auto entity = reg->valid(entt) ? entt : reg->create(entt); - ENTT_ASSERT(entity == entt); - reg->template emplace(args..., entt); - } - else { - Type instance{}; - archive(entt, instance); - const auto entity = reg->valid(entt) ? entt : reg->create(entt); - ENTT_ASSERT(entity == entt); - reg->template emplace(args..., entt, std::as_const(instance)); - } - } - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - - /** - * @brief Constructs an instance that is bound to a given registry. - * @param source A valid reference to a registry. - */ - basic_snapshot_loader(basic_registry& source) ENTT_NOEXCEPT - : reg{ &source } - { - // restoring a snapshot as a whole requires a clean registry - ENTT_ASSERT(reg->empty()); - } - - /*! @brief Default move constructor. */ - basic_snapshot_loader(basic_snapshot_loader&&) = default; - - /*! @brief Default move assignment operator. @return This loader. */ - basic_snapshot_loader& operator=(basic_snapshot_loader&&) = default; - - /** - * @brief Restores entities that were in use during serialization. - * - * This function restores the entities that were in use during serialization - * and gives them the versions they originally had. - * - * @tparam Archive Type of input archive. - * @param archive A valid reference to an input archive. - * @return A valid loader to continue restoring data. - */ - template - const basic_snapshot_loader& entities(Archive& archive) const { - typename traits_type::entity_type length{}; - - archive(length); - std::vector all(length); - - for (decltype(length) pos{}; pos < length; ++pos) { - archive(all[pos]); - } - - reg->assign(all.cbegin(), all.cend()); - - return *this; - } - - /** - * @brief Deprecated function. Currently, it does nothing. - * @tparam Archive Type of input archive. - * @return A valid loader to continue restoring data. - */ - template - [[deprecated("use ::entities instead, it imports now also destroyed entities")]] - const basic_snapshot_loader& destroyed(Archive&) const { return *this; } - - /** - * @brief Restores components and assigns them to the right entities. - * - * The template parameter list must be exactly the same used during - * serialization. In the event that the entity to which the component is - * assigned doesn't exist yet, the loader will take care to create it with - * the version it originally had. - * - * @tparam Component Types of components to restore. - * @tparam Archive Type of input archive. - * @param archive A valid reference to an input archive. - * @return A valid loader to continue restoring data. - */ - template - const basic_snapshot_loader& component(Archive& archive) const { - (assign(archive), ...); - return *this; - } - - /** - * @brief Destroys those entities that have no components. - * - * In case all the entities were serialized but only part of the components - * was saved, it could happen that some of the entities have no components - * once restored.
- * This functions helps to identify and destroy those entities. - * - * @return A valid loader to continue restoring data. - */ - const basic_snapshot_loader& orphans() const { - reg->orphans([this](const auto entt) { - reg->destroy(entt); - }); - - return *this; - } - - private: - basic_registry* reg; - }; - - - /** - * @brief Utility class for _continuous loading_. - * - * A _continuous loader_ is designed to load data from a source registry to a - * (possibly) non-empty destination. The loader can accommodate in a registry - * more than one snapshot in a sort of _continuous loading_ that updates the - * destination one step at a time.
- * Identifiers that entities originally had are not transferred to the target. - * Instead, the loader maps remote identifiers to local ones while restoring a - * snapshot.
- * An example of use is the implementation of a client-server applications with - * the requirement of transferring somehow parts of the representation side to - * side. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - class basic_continuous_loader { - using traits_type = entt_traits>; - - void destroy(Entity entt) { - const auto it = remloc.find(entt); - - if (it == remloc.cend()) { - const auto local = reg->create(); - remloc.emplace(entt, std::make_pair(local, true)); - reg->destroy(local); - } - } - - void restore(Entity entt) { - const auto it = remloc.find(entt); - - if (it == remloc.cend()) { - const auto local = reg->create(); - remloc.emplace(entt, std::make_pair(local, true)); - } - else { - remloc[entt].first = reg->valid(remloc[entt].first) ? remloc[entt].first : reg->create(); - // set the dirty flag - remloc[entt].second = true; - } - } - - template - auto update(int, Container& container) - -> decltype(typename Container::mapped_type{}, void()) { - // map like container - Container other; - - for (auto&& pair : container) { - using first_type = std::remove_const_t::first_type>; - using second_type = typename std::decay_t::second_type; - - if constexpr (std::is_same_v && std::is_same_v) { - other.emplace(map(pair.first), map(pair.second)); - } - else if constexpr (std::is_same_v) { - other.emplace(map(pair.first), std::move(pair.second)); - } - else { - static_assert(std::is_same_v); - other.emplace(std::move(pair.first), map(pair.second)); - } - } - - std::swap(container, other); - } - - template - auto update(char, Container& container) - -> decltype(typename Container::value_type{}, void()) { - // vector like container - static_assert(std::is_same_v); - - for (auto&& entt : container) { - entt = map(entt); - } - } - - template - void update([[maybe_unused]] Other& instance, [[maybe_unused]] Member Type::* member) { - if constexpr (!std::is_same_v) { - return; - } - else if constexpr (std::is_same_v) { - instance.*member = map(instance.*member); - } - else { - // maybe a container? let's try... - update(0, instance.*member); - } - } - - template - void remove_if_exists() { - for (auto&& ref : remloc) { - const auto local = ref.second.first; - - if (reg->valid(local)) { - reg->template remove_if_exists(local); - } - } - } - - template - void assign(Archive& archive, [[maybe_unused]] Member Type:: *... member) { - typename traits_type::entity_type length{}; - archive(length); - - while (length--) { - entity_type entt{}; - - if constexpr (std::is_empty_v) { - archive(entt); - restore(entt); - reg->template emplace_or_replace(map(entt)); - } - else { - Other instance{}; - archive(entt, instance); - (update(instance, member), ...); - restore(entt); - reg->template emplace_or_replace(map(entt), std::as_const(instance)); - } - } - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - - /** - * @brief Constructs an instance that is bound to a given registry. - * @param source A valid reference to a registry. - */ - basic_continuous_loader(basic_registry& source) ENTT_NOEXCEPT - : reg{ &source } - {} - - /*! @brief Default move constructor. */ - basic_continuous_loader(basic_continuous_loader&&) = default; - - /*! @brief Default move assignment operator. @return This loader. */ - basic_continuous_loader& operator=(basic_continuous_loader&&) = default; - - /** - * @brief Restores entities that were in use during serialization. - * - * This function restores the entities that were in use during serialization - * and creates local counterparts for them if required. - * - * @tparam Archive Type of input archive. - * @param archive A valid reference to an input archive. - * @return A non-const reference to this loader. - */ - template - basic_continuous_loader& entities(Archive& archive) { - typename traits_type::entity_type length{}; - entity_type entt{}; - - archive(length); - - for (decltype(length) pos{}; pos < length; ++pos) { - archive(entt); - - if (const auto entity = (to_integral(entt) & traits_type::entity_mask); entity == pos) { - restore(entt); - } - else { - destroy(entt); - } - } - - return *this; - } - - /** - * @brief Deprecated function. Currently, it does nothing. - * @tparam Archive Type of input archive. - * @return A non-const reference to this loader. - */ - template - [[deprecated("use ::entities instead, it imports now also destroyed entities")]] - basic_continuous_loader& destroyed(Archive&) { return *this; } - - /** - * @brief Restores components and assigns them to the right entities. - * - * The template parameter list must be exactly the same used during - * serialization. In the event that the entity to which the component is - * assigned doesn't exist yet, the loader will take care to create a local - * counterpart for it.
- * Members can be either data members of type entity_type or containers of - * entities. In both cases, the loader will visit them and update the - * entities by replacing each one with its local counterpart. - * - * @tparam Component Type of component to restore. - * @tparam Archive Type of input archive. - * @tparam Type Types of components to update with local counterparts. - * @tparam Member Types of members to update with their local counterparts. - * @param archive A valid reference to an input archive. - * @param member Members to update with their local counterparts. - * @return A non-const reference to this loader. - */ - template - basic_continuous_loader& component(Archive& archive, Member Type:: *... member) { - (remove_if_exists(), ...); - (assign(archive, member...), ...); - return *this; - } - - /** - * @brief Helps to purge entities that no longer have a conterpart. - * - * Users should invoke this member function after restoring each snapshot, - * unless they know exactly what they are doing. - * - * @return A non-const reference to this loader. - */ - basic_continuous_loader& shrink() { - auto it = remloc.begin(); - - while (it != remloc.cend()) { - const auto local = it->second.first; - bool& dirty = it->second.second; - - if (dirty) { - dirty = false; - ++it; - } - else { - if (reg->valid(local)) { - reg->destroy(local); - } - - it = remloc.erase(it); - } - } - - return *this; - } - - /** - * @brief Destroys those entities that have no components. - * - * In case all the entities were serialized but only part of the components - * was saved, it could happen that some of the entities have no components - * once restored.
- * This functions helps to identify and destroy those entities. - * - * @return A non-const reference to this loader. - */ - basic_continuous_loader& orphans() { - reg->orphans([this](const auto entt) { - reg->destroy(entt); - }); - - return *this; - } - - /** - * @brief Tests if a loader knows about a given entity. - * @param entt An entity identifier. - * @return True if `entity` is managed by the loader, false otherwise. - */ - bool contains(entity_type entt) const ENTT_NOEXCEPT { - return (remloc.find(entt) != remloc.cend()); - } - - /*! @copydoc contains */ - [[deprecated("use ::contains instead")]] - bool has(entity_type entt) const ENTT_NOEXCEPT { - return contains(entt); - } - - /** - * @brief Returns the identifier to which an entity refers. - * @param entt An entity identifier. - * @return The local identifier if any, the null entity otherwise. - */ - entity_type map(entity_type entt) const ENTT_NOEXCEPT { - const auto it = remloc.find(entt); - entity_type other = null; - - if (it != remloc.cend()) { - other = it->second.first; - } - - return other; - } - - private: - std::unordered_map> remloc; - basic_registry* reg; - }; - - -} - - -#endif - -// #include "sparse_set.hpp" - -// #include "storage.hpp" - -// #include "utility.hpp" - -// #include "view.hpp" -#ifndef ENTT_ENTITY_VIEW_HPP -#define ENTT_ENTITY_VIEW_HPP - - -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/type_traits.hpp" - -// #include "sparse_set.hpp" - -// #include "storage.hpp" - -// #include "utility.hpp" - -// #include "entity.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief View. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error, but for a few reasonable cases. - */ - template - class basic_view; - - - /** - * @brief Multi component view. - * - * Multi component views iterate over those entities that have at least all the - * given components in their bags. During initialization, a multi component view - * looks at the number of entities available for each component and uses the - * smallest set in order to get a performance boost when iterate. - * - * @b Important - * - * Iterators aren't invalidated if: - * - * * New instances of the given components are created and assigned to entities. - * * The entity currently pointed is modified (as an example, if one of the - * given components is removed from the entity to which the iterator points). - * * The entity currently pointed is destroyed. - * - * In all other cases, modifying the pools iterated by the view in any way - * invalidates all the iterators and using them results in undefined behavior. - * - * @note - * Views share references to the underlying data structures of the registry that - * generated them. Therefore any change to the entities and to the components - * made by means of the registry are immediately reflected by views. - * - * @warning - * Lifetime of a view must not overcome that of the registry that generated it. - * In any other case, attempting to use a view results in undefined behavior. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - * @tparam Exclude Types of components used to filter the view. - * @tparam Component Types of components iterated by the view. - */ - template - class basic_view, Component...> { - /*! @brief A registry is allowed to create views. */ - friend class basic_registry; - - template - using pool_type = std::conditional_t, const storage>, storage>; - - template - using component_iterator = decltype(std::declval>().begin()); - - using underlying_iterator = typename sparse_set::iterator; - using unchecked_type = std::array*, (sizeof...(Component) - 1)>; - using filter_type = std::array*, sizeof...(Exclude)>; - - class view_iterator final { - friend class basic_view, Component...>; - - view_iterator(const sparse_set& candidate, unchecked_type other, filter_type ignore, underlying_iterator curr) ENTT_NOEXCEPT - : view{ &candidate }, - unchecked{ other }, - filter{ ignore }, - it{ curr } - { - if (it != view->end() && !valid()) { - ++(*this); - } - } - - bool valid() const { - return std::all_of(unchecked.cbegin(), unchecked.cend(), [entt = *it](const sparse_set* curr) { return curr->contains(entt); }) - && std::none_of(filter.cbegin(), filter.cend(), [entt = *it](const sparse_set* curr) { return curr->contains(entt); }); - } - - public: - using difference_type = typename underlying_iterator::difference_type; - using value_type = typename underlying_iterator::value_type; - using pointer = typename underlying_iterator::pointer; - using reference = typename underlying_iterator::reference; - using iterator_category = std::bidirectional_iterator_tag; - - view_iterator() ENTT_NOEXCEPT = default; - - view_iterator& operator++() { - while (++it != view->end() && !valid()); - return *this; - } - - view_iterator operator++(int) { - view_iterator orig = *this; - return operator++(), orig; - } - - view_iterator& operator--() ENTT_NOEXCEPT { - while (--it != view->begin() && !valid()); - return *this; - } - - view_iterator operator--(int) ENTT_NOEXCEPT { - view_iterator orig = *this; - return operator--(), orig; - } - - bool operator==(const view_iterator& other) const ENTT_NOEXCEPT { - return other.it == it; - } - - bool operator!=(const view_iterator& other) const ENTT_NOEXCEPT { - return !(*this == other); - } - - pointer operator->() const { - return it.operator->(); - } - - reference operator*() const { - return *operator->(); - } - - private: - const sparse_set* view; - unchecked_type unchecked; - filter_type filter; - underlying_iterator it; - }; - - // we could use pool_type &..., but vs complains about it and refuses to compile for unknown reasons (likely a bug) - basic_view(storage> &... component, storage> &... epool) ENTT_NOEXCEPT - : pools{ &component..., &epool... } - {} - - const sparse_set& candidate() const ENTT_NOEXCEPT { - return *std::min({ static_cast *>(std::get*>(pools))... }, [](const auto* lhs, const auto* rhs) { - return lhs->size() < rhs->size(); - }); - } - - unchecked_type unchecked(const sparse_set& view) const { - std::size_t pos{}; - unchecked_type other{}; - ((std::get*>(pools) == &view ? nullptr : (other[pos++] = std::get*>(pools))), ...); - return other; - } - - template - decltype(auto) get([[maybe_unused]] component_iterator it, [[maybe_unused]] pool_type* cpool, [[maybe_unused]] const Entity entt) const { - if constexpr (std::is_same_v) { - return *it; - } - else { - return cpool->get(entt); - } - } - - template - void traverse(Func func, type_list) const { - if constexpr (std::disjunction_v...>) { - auto it = std::get*>(pools)->begin(); - - for (const auto entt : static_cast&>(*std::get*>(pools))) { - auto curr = it++; - - if (((std::is_same_v || std::get *>(pools)->contains(entt)) && ...) && (!std::get *>(pools)->contains(entt) && ...)) { - if constexpr (std::is_invocable_v < Func, decltype(get({}))... > ) { - func(get(curr, std::get*>(pools), entt)...); - } - else { - func(entt, get(curr, std::get*>(pools), entt)...); - } - } - } - } - else { - for (const auto entt : static_cast&>(*std::get*>(pools))) { - if (((std::is_same_v || std::get *>(pools)->contains(entt)) && ...) && (!std::get *>(pools)->contains(entt) && ...)) { - if constexpr (std::is_invocable_v < Func, decltype(get({}))... > ) { - func(std::get*>(pools)->get(entt)...); - } - else { - func(entt, std::get*>(pools)->get(entt)...); - } - } - } - } - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Input iterator type. */ - using iterator = view_iterator; - - /** - * @brief Returns the number of existing components of the given type. - * - * This isn't the number of entities iterated by the view. - * - * @tparam Comp Type of component of which to return the size. - * @return Number of existing components of the given type. - */ - template - size_type size() const ENTT_NOEXCEPT { - return std::get*>(pools)->size(); - } - - /** - * @brief Estimates the number of entities iterated by the view. - * @return Estimated number of entities iterated by the view. - */ - size_type size() const ENTT_NOEXCEPT { - return std::min({ std::get*>(pools)->size()... }); - } - - /** - * @brief Checks whether a view or some pools are empty. - * - * The view is definitely empty if one of the pools it uses is empty. In all - * other cases, the view may be empty and not return entities even if this - * function returns false. - * - * @tparam Comp Types of components in which one is interested. - * @return True if the view or the pools are empty, false otherwise. - */ - template - bool empty() const ENTT_NOEXCEPT { - if constexpr (sizeof...(Comp) == 0) { - return (std::get*>(pools)->empty() || ...); - } - else { - return (std::get*>(pools)->empty() && ...); - } - } - - /** - * @brief Direct access to the list of components of a given pool. - * - * The returned pointer is such that range - * `[raw(), raw() + size()]` is always a valid range, even - * if the container is empty. - * - * @note - * There are no guarantees on the order of the components. Use `begin` and - * `end` if you want to iterate the view in the expected order. - * - * @tparam Comp Type of component in which one is interested. - * @return A pointer to the array of components. - */ - template - Comp* raw() const ENTT_NOEXCEPT { - return std::get*>(pools)->raw(); - } - - /** - * @brief Direct access to the list of entities of a given pool. - * - * The returned pointer is such that range - * `[data(), data() + size()]` is always a valid range, - * even if the container is empty. - * - * @note - * There are no guarantees on the order of the entities. Use `begin` and - * `end` if you want to iterate the view in the expected order. - * - * @tparam Comp Type of component in which one is interested. - * @return A pointer to the array of entities. - */ - template - const entity_type* data() const ENTT_NOEXCEPT { - return std::get*>(pools)->data(); - } - - /** - * @brief Returns an iterator to the first entity that has the given - * components. - * - * The returned iterator points to the first entity that has the given - * components. If the view is empty, the returned iterator will be equal to - * `end()`. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the first entity that has the given components. - */ - iterator begin() const { - const auto& view = candidate(); - const filter_type ignore{ std::get*>(pools)... }; - return iterator{ view, unchecked(view), ignore, view.begin() }; - } - - /** - * @brief Returns an iterator that is past the last entity that has the - * given components. - * - * The returned iterator points to the entity following the last entity that - * has the given components. Attempting to dereference the returned iterator - * results in undefined behavior. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the entity following the last entity that has the - * given components. - */ - iterator end() const { - const auto& view = candidate(); - const filter_type ignore{ std::get*>(pools)... }; - return iterator{ view, unchecked(view), ignore, view.end() }; - } - - /** - * @brief Returns the first entity that has the given components, if any. - * @return The first entity that has the given components if one exists, the - * null entity otherwise. - */ - entity_type front() const { - const auto it = begin(); - return it != end() ? *it : null; - } - - /** - * @brief Returns the last entity that has the given components, if any. - * @return The last entity that has the given components if one exists, the - * null entity otherwise. - */ - entity_type back() const { - const auto it = std::make_reverse_iterator(end()); - return it != std::make_reverse_iterator(begin()) ? *it : null; - } - - /** - * @brief Finds an entity. - * @param entt A valid entity identifier. - * @return An iterator to the given entity if it's found, past the end - * iterator otherwise. - */ - iterator find(const entity_type entt) const { - const auto& view = candidate(); - const filter_type ignore{ std::get*>(pools)... }; - iterator it{ view, unchecked(view), ignore, view.find(entt) }; - return (it != end() && *it == entt) ? it : end(); - } - - /** - * @brief Checks if a view contains an entity. - * @param entt A valid entity identifier. - * @return True if the view contains the given entity, false otherwise. - */ - bool contains(const entity_type entt) const { - return (std::get*>(pools)->contains(entt) && ...) - && (!std::get*>(pools)->contains(entt) && ...); - } - - /** - * @brief Returns the components assigned to the given entity. - * - * Prefer this function instead of `registry::get` during iterations. It has - * far better performance than its counterpart. - * - * @warning - * Attempting to use an invalid component type results in a compilation - * error. Attempting to use an entity that doesn't belong to the view - * results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * view doesn't contain the given entity. - * - * @tparam Comp Types of components to get. - * @param entt A valid entity identifier. - * @return The components assigned to the entity. - */ - template - decltype(auto) get([[maybe_unused]] const entity_type entt) const { - ENTT_ASSERT(contains(entt)); - - if constexpr (sizeof...(Comp) == 0) { - static_assert(sizeof...(Component) == 1); - return (std::get*>(pools)->get(entt), ...); - } - else if constexpr (sizeof...(Comp) == 1) { - return (std::get*>(pools)->get(entt), ...); - } - else { - return std::tuple({}))... > {get(entt)...}; - } - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The function object is invoked for each entity. It is provided with the - * entity itself and a set of references to non-empty components. The - * _constness_ of the components is as requested.
- * The signature of the function must be equivalent to one of the following - * forms: - * - * @code{.cpp} - * void(const entity_type, Type &...); - * void(Type &...); - * @endcode - * - * @note - * Empty types aren't explicitly instantiated and therefore they are never - * returned during iterations. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - const auto& view = candidate(); - ((std::get*>(pools) == &view ? each(std::move(func)) : void()), ...); - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The pool of the suggested component is used to lead the iterations. The - * returned entities will therefore respect the order of the pool associated - * with that type.
- * It is no longer guaranteed that the performance is the best possible, but - * there will be greater control over the order of iteration. - * - * @sa each - * - * @tparam Comp Type of component to use to enforce the iteration order. - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - using non_empty_type = type_list_cat_t, type_list>...>; - traverse(std::move(func), non_empty_type{}); - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The function object is invoked for each entity. It is provided with the - * entity itself and a set of references to non-empty components. The - * _constness_ of the components is as requested.
- * The signature of the function must be equivalent to one of the following - * forms: - * - * @code{.cpp} - * void(const entity_type, Type &...); - * void(Type &...); - * @endcode - * - * @note - * Empty types aren't explicitly instantiated and therefore they are never - * returned during iterations. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - [[deprecated("use ::each instead")]] - void less(Func func) const { - each(std::move(func)); - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The pool of the suggested component is used to lead the iterations. The - * returned entities will therefore respect the order of the pool associated - * with that type.
- * It is no longer guaranteed that the performance is the best possible, but - * there will be greater control over the order of iteration. - * - * @sa less - * - * @tparam Comp Type of component to use to enforce the iteration order. - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - [[deprecated("use ::each instead")]] - void less(Func func) const { - each(std::move(func)); - } - - private: - const std::tuple *..., pool_type *...> pools; - }; - - - /** - * @brief Single component view specialization. - * - * Single component views are specialized in order to get a boost in terms of - * performance. This kind of views can access the underlying data structure - * directly and avoid superfluous checks. - * - * @b Important - * - * Iterators aren't invalidated if: - * - * * New instances of the given component are created and assigned to entities. - * * The entity currently pointed is modified (as an example, the given - * component is removed from the entity to which the iterator points). - * * The entity currently pointed is destroyed. - * - * In all other cases, modifying the pool iterated by the view in any way - * invalidates all the iterators and using them results in undefined behavior. - * - * @note - * Views share a reference to the underlying data structure of the registry that - * generated them. Therefore any change to the entities and to the components - * made by means of the registry are immediately reflected by views. - * - * @warning - * Lifetime of a view must not overcome that of the registry that generated it. - * In any other case, attempting to use a view results in undefined behavior. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - * @tparam Component Type of component iterated by the view. - */ - template - class basic_view, Component> { - /*! @brief A registry is allowed to create views. */ - friend class basic_registry; - - using pool_type = std::conditional_t, const storage>, storage>; - - basic_view(pool_type& ref) ENTT_NOEXCEPT - : pool{ &ref } - {} - - public: - /*! @brief Type of component iterated by the view. */ - using raw_type = Component; - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Input iterator type. */ - using iterator = typename sparse_set::iterator; - - /** - * @brief Returns the number of entities that have the given component. - * @return Number of entities that have the given component. - */ - size_type size() const ENTT_NOEXCEPT { - return pool->size(); - } - - /** - * @brief Checks whether a view is empty. - * @return True if the view is empty, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return pool->empty(); - } - - /** - * @brief Direct access to the list of components. - * - * The returned pointer is such that range `[raw(), raw() + size()]` is - * always a valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order of the components. Use `begin` and - * `end` if you want to iterate the view in the expected order. - * - * @return A pointer to the array of components. - */ - raw_type* raw() const ENTT_NOEXCEPT { - return pool->raw(); - } - - /** - * @brief Direct access to the list of entities. - * - * The returned pointer is such that range `[data(), data() + size()]` is - * always a valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order of the entities. Use `begin` and - * `end` if you want to iterate the view in the expected order. - * - * @return A pointer to the array of entities. - */ - const entity_type* data() const ENTT_NOEXCEPT { - return pool->data(); - } - - /** - * @brief Returns an iterator to the first entity that has the given - * component. - * - * The returned iterator points to the first entity that has the given - * component. If the view is empty, the returned iterator will be equal to - * `end()`. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the first entity that has the given component. - */ - iterator begin() const ENTT_NOEXCEPT { - return pool->sparse_set::begin(); - } - - /** - * @brief Returns an iterator that is past the last entity that has the - * given component. - * - * The returned iterator points to the entity following the last entity that - * has the given component. Attempting to dereference the returned iterator - * results in undefined behavior. - * - * @note - * Input iterators stay true to the order imposed to the underlying data - * structures. - * - * @return An iterator to the entity following the last entity that has the - * given component. - */ - iterator end() const ENTT_NOEXCEPT { - return pool->sparse_set::end(); - } - - /** - * @brief Returns the first entity that has the given component, if any. - * @return The first entity that has the given component if one exists, the - * null entity otherwise. - */ - entity_type front() const { - const auto it = begin(); - return it != end() ? *it : null; - } - - /** - * @brief Returns the last entity that has the given component, if any. - * @return The last entity that has the given component if one exists, the - * null entity otherwise. - */ - entity_type back() const { - const auto it = std::make_reverse_iterator(end()); - return it != std::make_reverse_iterator(begin()) ? *it : null; - } - - /** - * @brief Finds an entity. - * @param entt A valid entity identifier. - * @return An iterator to the given entity if it's found, past the end - * iterator otherwise. - */ - iterator find(const entity_type entt) const { - const auto it = pool->find(entt); - return it != end() && *it == entt ? it : end(); - } - - /** - * @brief Returns the identifier that occupies the given position. - * @param pos Position of the element to return. - * @return The identifier that occupies the given position. - */ - entity_type operator[](const size_type pos) const { - return begin()[pos]; - } - - /** - * @brief Checks if a view contains an entity. - * @param entt A valid entity identifier. - * @return True if the view contains the given entity, false otherwise. - */ - bool contains(const entity_type entt) const { - return pool->contains(entt); - } - - /** - * @brief Returns the component assigned to the given entity. - * - * Prefer this function instead of `registry::get` during iterations. It has - * far better performance than its counterpart. - * - * @warning - * Attempting to use an entity that doesn't belong to the view results in - * undefined behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * view doesn't contain the given entity. - * - * @param entt A valid entity identifier. - * @return The component assigned to the entity. - */ - template - decltype(auto) get(const entity_type entt) const { - static_assert(std::is_same_v); - ENTT_ASSERT(contains(entt)); - return pool->get(entt); - } - - /** - * @brief Iterates entities and components and applies the given function - * object to them. - * - * The function object is invoked for each entity. It is provided with the - * entity itself and a reference to the component if it's a non-empty one. - * The _constness_ of the component is as requested.
- * The signature of the function must be equivalent to one of the following - * forms: - * - * @code{.cpp} - * void(const entity_type, Component &); - * void(Component &); - * @endcode - * - * @note - * Empty types aren't explicitly instantiated and therefore they are never - * returned during iterations. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - if constexpr (ENTT_IS_EMPTY(Component)) { - if constexpr (std::is_invocable_v) { - for (auto pos = pool->size(); pos; --pos) { - func(); - } - } - else { - for (const auto entt : *this) { - func(entt); - } - } - } - else { - if constexpr (std::is_invocable_v < Func, decltype(get({})) > ) { - for (auto&& component : *pool) { - func(component); - } - } - else { - auto raw = pool->begin(); - - for (const auto entt : *this) { - func(entt, *(raw++)); - } - } - } - } - - /*! @copydoc each */ - template - [[deprecated("use ::each instead")]] - void less(Func func) const { - each(std::move(func)); - } - - private: - pool_type* pool; - }; - - -} - - -#endif - - - -namespace entt { - - - /** - * @brief Fast and reliable entity-component system. - * - * The registry is the core class of the entity-component framework.
- * It stores entities and arranges pools of components on a per request basis. - * By means of a registry, users can manage entities and components, then create - * views or groups to iterate them. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - class basic_registry { - using traits_type = entt_traits>; - - template - struct pool_handler final : storage { - static_assert(std::is_same_v>); - std::size_t super{}; - - auto on_construct() ENTT_NOEXCEPT { - return sink{ construction }; - } - - auto on_update() ENTT_NOEXCEPT { - return sink{ update }; - } - - auto on_destroy() ENTT_NOEXCEPT { - return sink{ destruction }; - } - - template - decltype(auto) emplace(basic_registry& owner, const Entity entt, Args &&... args) { - storage::emplace(entt, std::forward(args)...); - construction.publish(owner, entt); - - if constexpr (!ENTT_IS_EMPTY(Component)) { - return this->get(entt); - } - } - - template - void insert(basic_registry& owner, It first, It last, Args &&... args) { - storage::insert(first, last, std::forward(args)...); - - if (!construction.empty()) { - while (first != last) { construction.publish(owner, *(first++)); } - } - } - - void remove(basic_registry& owner, const Entity entt) { - destruction.publish(owner, entt); - this->erase(entt); - } - - template - void remove(basic_registry& owner, It first, It last) { - if (std::distance(first, last) == std::distance(this->begin(), this->end())) { - if (!destruction.empty()) { - while (first != last) { destruction.publish(owner, *(first++)); } - } - - this->clear(); - } - else { - while (first != last) { this->remove(owner, *(first++)); } - } - } - - template - decltype(auto) patch(basic_registry& owner, const Entity entt, Func &&... func) { - (std::forward(func)(this->get(entt)), ...); - update.publish(owner, entt); - - if constexpr (!ENTT_IS_EMPTY(Component)) { - return this->get(entt); - } - } - - decltype(auto) replace(basic_registry& owner, const Entity entt, [[maybe_unused]] Component component) { - if constexpr (ENTT_IS_EMPTY(Component)) { - return patch(owner, entt); - } - else { - return patch(owner, entt, [&component](auto&& curr) { curr = std::move(component); }); - } - } - - private: - sigh construction{}; - sigh destruction{}; - sigh update{}; - }; - - struct pool_data { - id_type type_id{}; - std::unique_ptr> pool{}; - void(*remove)(sparse_set&, basic_registry&, const Entity) {}; - }; - - template - struct group_handler; - - template - struct group_handler, get_t, Owned...> { - static_assert(std::conjunction_v>..., std::is_same>..., std::is_same>...>); - std::conditional_t, std::size_t> current{}; - - template - void maybe_valid_if(basic_registry& owner, const Entity entt) { - static_assert(std::disjunction_v>..., std::is_same>..., std::is_same>...>); - [[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.assure()...); - - const auto is_valid = ((std::is_same_v || std::get&>(cpools).contains(entt)) && ...) - && ((std::is_same_v || owner.assure().contains(entt)) && ...) - && ((std::is_same_v || !owner.assure().contains(entt)) && ...); - - if constexpr (sizeof...(Owned) == 0) { - if (is_valid && !current.contains(entt)) { - current.emplace(entt); - } - } - else { - if (is_valid && !(std::get<0>(cpools).index(entt) < current)) { - const auto pos = current++; - (std::get&>(cpools).swap(std::get&>(cpools).data()[pos], entt), ...); - } - } - } - - void discard_if([[maybe_unused]] basic_registry& owner, const Entity entt) { - if constexpr (sizeof...(Owned) == 0) { - if (current.contains(entt)) { - current.erase(entt); - } - } - else { - if (const auto cpools = std::forward_as_tuple(owner.assure()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) { - const auto pos = --current; - (std::get&>(cpools).swap(std::get&>(cpools).data()[pos], entt), ...); - } - } - } - }; - - struct group_data { - std::size_t size; - std::unique_ptr group; - bool (*owned)(const id_type) ENTT_NOEXCEPT; - bool (*get)(const id_type) ENTT_NOEXCEPT; - bool (*exclude)(const id_type) ENTT_NOEXCEPT; - }; - - struct variable_data { - id_type type_id; - std::unique_ptr value; - }; - - template - const pool_handler& assure() const { - static_assert(std::is_same_v>); - - if constexpr (has_type_index_v) { - const auto index = type_index::value(); - - if (!(index < pools.size())) { - pools.resize(index + 1); - } - - if (auto&& pdata = pools[index]; !pdata.pool) { - pdata.type_id = type_info::id(); - pdata.pool.reset(new pool_handler()); - pdata.remove = [](sparse_set& cpool, basic_registry& owner, const entity_type entt) { - static_cast&>(cpool).remove(owner, entt); - }; - } - - return static_cast &>(*pools[index].pool); - } - else { - sparse_set* candidate{ nullptr }; - - if (auto it = std::find_if(pools.begin(), pools.end(), [id = type_info::id()](const auto& pdata) { return id == pdata.type_id; }); it == pools.cend()) { - candidate = pools.emplace_back(pool_data{ - type_info::id(), - std::unique_ptr>{new pool_handler()}, - [](sparse_set& cpool, basic_registry& owner, const entity_type entt) { - static_cast&>(cpool).remove(owner, entt); - } - }).pool.get(); - } - else { - candidate = it->pool.get(); - } - - return static_cast &>(*candidate); - } - } - - template - pool_handler& assure() { - return const_cast &>(std::as_const(*this).template assure()); - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Underlying version type. */ - using version_type = typename traits_type::version_type; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - - /*! @brief Default constructor. */ - basic_registry() = default; - - /*! @brief Default move constructor. */ - basic_registry(basic_registry&&) = default; - - /*! @brief Default move assignment operator. @return This registry. */ - basic_registry& operator=(basic_registry&&) = default; - - /** - * @brief Prepares a pool for the given type if required. - * @tparam Component Type of component for which to prepare a pool. - */ - template - void prepare() { - assure(); - } - - /** - * @brief Returns the number of existing components of the given type. - * @tparam Component Type of component of which to return the size. - * @return Number of existing components of the given type. - */ - template - size_type size() const { - return assure().size(); - } - - /** - * @brief Returns the number of entities created so far. - * @return Number of entities created so far. - */ - size_type size() const ENTT_NOEXCEPT { - return entities.size(); - } - - /** - * @brief Returns the number of entities still in use. - * @return Number of entities still in use. - */ - size_type alive() const { - auto sz = entities.size(); - auto curr = destroyed; - - for (; curr != null; --sz) { - curr = entities[to_integral(curr) & traits_type::entity_mask]; - } - - return sz; - } - - /** - * @brief Increases the capacity of the registry or of the pools for the - * given components. - * - * If no components are specified, the capacity of the registry is - * increased, that is the number of entities it contains. Otherwise the - * capacity of the pools for the given components is increased.
- * In both cases, if the new capacity is greater than the current capacity, - * new storage is allocated, otherwise the method does nothing. - * - * @tparam Component Types of components for which to reserve storage. - * @param cap Desired capacity. - */ - template - void reserve(const size_type cap) { - if constexpr (sizeof...(Component) == 0) { - entities.reserve(cap); - } - else { - (assure().reserve(cap), ...); - } - } - - /** - * @brief Returns the capacity of the pool for the given component. - * @tparam Component Type of component in which one is interested. - * @return Capacity of the pool of the given component. - */ - template - size_type capacity() const { - return assure().capacity(); - } - - /** - * @brief Returns the number of entities that a registry has currently - * allocated space for. - * @return Capacity of the registry. - */ - size_type capacity() const ENTT_NOEXCEPT { - return entities.capacity(); - } - - /** - * @brief Requests the removal of unused capacity for the given components. - * @tparam Component Types of components for which to reclaim unused - * capacity. - */ - template - void shrink_to_fit() { - (assure().shrink_to_fit(), ...); - } - - /** - * @brief Checks whether the registry or the pools of the given components - * are empty. - * - * A registry is considered empty when it doesn't contain entities that are - * still in use. - * - * @tparam Component Types of components in which one is interested. - * @return True if the registry or the pools of the given components are - * empty, false otherwise. - */ - template - bool empty() const { - if constexpr (sizeof...(Component) == 0) { - return !alive(); - } - else { - return (assure().empty() && ...); - } - } - - /** - * @brief Direct access to the list of components of a given pool. - * - * The returned pointer is such that range - * `[raw(), raw() + size()]` is always a - * valid range, even if the container is empty. - * - * There are no guarantees on the order of the components. Use a view if you - * want to iterate entities and components in the expected order. - * - * @note - * Empty components aren't explicitly instantiated. Therefore, this function - * isn't available for them. A compilation error will occur if invoked. - * - * @tparam Component Type of component in which one is interested. - * @return A pointer to the array of components of the given type. - */ - template - const Component* raw() const { - return assure().raw(); - } - - /*! @copydoc raw */ - template - Component* raw() { - return const_cast(std::as_const(*this).template raw()); - } - - /** - * @brief Direct access to the list of entities of a given pool. - * - * The returned pointer is such that range - * `[data(), data() + size()]` is always a - * valid range, even if the container is empty. - * - * There are no guarantees on the order of the entities. Use a view if you - * want to iterate entities and components in the expected order. - * - * @tparam Component Type of component in which one is interested. - * @return A pointer to the array of entities. - */ - template - const entity_type* data() const { - return assure().data(); - } - - /** - * @brief Direct access to the list of entities of a registry. - * - * The returned pointer is such that range `[data(), data() + size()]` is - * always a valid range, even if the container is empty. - * - * @warning - * This list contains both valid and destroyed entities and isn't suitable - * for direct use. - * - * @return A pointer to the array of entities. - */ - const entity_type* data() const ENTT_NOEXCEPT { - return entities.data(); - } - - /** - * @brief Checks if an entity identifier refers to a valid entity. - * @param entity An entity identifier, either valid or not. - * @return True if the identifier is valid, false otherwise. - */ - bool valid(const entity_type entity) const { - const auto pos = size_type(to_integral(entity) & traits_type::entity_mask); - return (pos < entities.size() && entities[pos] == entity); - } - - /** - * @brief Returns the entity identifier without the version. - * @param entity An entity identifier, either valid or not. - * @return The entity identifier without the version. - */ - static entity_type entity(const entity_type entity) ENTT_NOEXCEPT { - return entity_type{ to_integral(entity) & traits_type::entity_mask }; - } - - /** - * @brief Returns the version stored along with an entity identifier. - * @param entity An entity identifier, either valid or not. - * @return The version stored along with the given entity identifier. - */ - static version_type version(const entity_type entity) ENTT_NOEXCEPT { - return version_type(to_integral(entity) >> traits_type::entity_shift); - } - - /** - * @brief Returns the actual version for an entity identifier. - * - * @warning - * Attempting to use an entity that doesn't belong to the registry results - * in undefined behavior. An entity belongs to the registry even if it has - * been previously destroyed and/or recycled.
- * An assertion will abort the execution at runtime in debug mode if the - * registry doesn't own the given entity. - * - * @param entity A valid entity identifier. - * @return Actual version for the given entity identifier. - */ - version_type current(const entity_type entity) const { - const auto pos = size_type(to_integral(entity) & traits_type::entity_mask); - ENTT_ASSERT(pos < entities.size()); - return version_type(to_integral(entities[pos]) >> traits_type::entity_shift); - } - - /** - * @brief Creates a new entity and returns it. - * - * There are two kinds of possible entity identifiers: - * - * * Newly created ones in case no entities have been previously destroyed. - * * Recycled ones with updated versions. - * - * @return A valid entity identifier. - */ - entity_type create() { - entity_type entt; - - if (destroyed == null) { - entt = entities.emplace_back(entity_type(entities.size())); - // traits_type::entity_mask is reserved to allow for null identifiers - ENTT_ASSERT(to_integral(entt) < traits_type::entity_mask); - } - else { - const auto curr = to_integral(destroyed); - const auto version = to_integral(entities[curr]) & (traits_type::version_mask << traits_type::entity_shift); - destroyed = entity_type{ to_integral(entities[curr]) & traits_type::entity_mask }; - entt = entities[curr] = entity_type{ curr | version }; - } - - return entt; - } - - /** - * @brief Creates a new entity and returns it. - * - * @sa create - * - * If the requested entity isn't in use, the suggested identifier is created - * and returned. Otherwise, a new one will be generated for this purpose. - * - * @param hint A desired entity identifier. - * @return A valid entity identifier. - */ - entity_type create(const entity_type hint) { - ENTT_ASSERT(hint != null); - entity_type entt; - - if (const auto req = (to_integral(hint) & traits_type::entity_mask); !(req < entities.size())) { - entities.reserve(req + 1); - - for (auto pos = entities.size(); pos < req; ++pos) { - entities.emplace_back(destroyed); - destroyed = entity_type(pos); - } - - entt = entities.emplace_back(hint); - } - else if (const auto curr = (to_integral(entities[req]) & traits_type::entity_mask); req == curr) { - entt = create(); - } - else { - auto* it = &destroyed; - for (; (to_integral(*it) & traits_type::entity_mask) != req; it = &entities[to_integral(*it) & traits_type::entity_mask]); - *it = entity_type{ curr | (to_integral(*it) & (traits_type::version_mask << traits_type::entity_shift)) }; - entt = entities[req] = hint; - } - - return entt; - } - - /** - * @brief Assigns each element in a range an entity. - * - * @sa create - * - * @tparam It Type of forward iterator. - * @param first An iterator to the first element of the range to generate. - * @param last An iterator past the last element of the range to generate. - */ - template - void create(It first, It last) { - std::generate(first, last, [this]() { return create(); }); - } - - /** - * @brief Assigns entities to an empty registry. - * - * This function is intended for use in conjunction with `raw`.
- * Don't try to inject ranges of randomly generated entities. There is no - * guarantee that a registry will continue to work properly in this case. - * - * @warning - * An assertion will abort the execution at runtime in debug mode if all - * pools aren't empty. - * - * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - */ - template - void assign(It first, It last) { - ENTT_ASSERT(std::all_of(pools.cbegin(), pools.cend(), [](auto&& pdata) { return !pdata.pool || pdata.pool->empty(); })); - entities.assign(first, last); - destroyed = null; - - for (std::size_t pos{}, end = entities.size(); pos < end; ++pos) { - if ((to_integral(entities[pos]) & traits_type::entity_mask) != pos) { - const auto version = to_integral(entities[pos]) & (traits_type::version_mask << traits_type::entity_shift); - entities[pos] = entity_type{ to_integral(destroyed) | version }; - destroyed = entity_type(pos); - } - } - } - - /** - * @brief Destroys an entity. - * - * When an entity is destroyed, its version is updated and the identifier - * can be recycled at any time. - * - * @sa remove_all - * - * @param entity A valid entity identifier. - */ - void destroy(const entity_type entity) { - destroy(entity, (to_integral(entity) >> traits_type::entity_shift) + 1); - } - - /** - * @brief Destroys an entity. - * - * If the entity isn't already destroyed, the suggested version is used - * instead of the implicitly generated one. - * - * @sa remove_all - * - * @param entity A valid entity identifier. - * @param version A desired version upon destruction. - */ - void destroy(const entity_type entity, const version_type version) { - remove_all(entity); - // lengthens the implicit list of destroyed entities - const auto entt = to_integral(entity) & traits_type::entity_mask; - entities[entt] = entity_type{ to_integral(destroyed) | (version << traits_type::entity_shift) }; - destroyed = entity_type{ entt }; - } - - /** - * @brief Destroys all the entities in a range. - * - * @sa destroy - * - * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - */ - template - void destroy(It first, It last) { - while (first != last) { destroy(*(first++)); } - } - - /** - * @brief Assigns the given component to an entity. - * - * A new instance of the given component is created and initialized with the - * arguments provided (the component must have a proper constructor or be of - * aggregate type). Then the component is assigned to the given entity. - * - * @warning - * Attempting to use an invalid entity or to assign a component to an entity - * that already owns it results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity or if the entity already owns an instance of the given - * component. - * - * @tparam Component Type of component to create. - * @tparam Args Types of arguments to use to construct the component. - * @param entity A valid entity identifier. - * @param args Parameters to use to initialize the component. - * @return A reference to the newly created component. - */ - template - decltype(auto) emplace(const entity_type entity, Args &&... args) { - ENTT_ASSERT(valid(entity)); - return assure().emplace(*this, entity, std::forward(args)...); - } - - /*! @copydoc emplace */ - template - [[deprecated("use ::emplace instead")]] - decltype(auto) assign(const entity_type entity, Args &&... args) { - return emplace(entity, std::forward(args)...); - } - - /** - * @brief Assigns each entity in a range the given component. - * - * @sa emplace - * - * @tparam Component Type of component to create. - * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - * @param value An instance of the component to assign. - */ - template - void insert(It first, It last, const Component& value = {}) { - ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); })); - assure().insert(*this, first, last, value); - } - - /*! @copydoc insert */ - template - [[deprecated("use ::insert instead")]] - std::enable_if_t::value_type, entity_type>, void> - assign(It first, It last, const Component& value = {}) { - return insert(std::move(first), std::move(last), value); - } - - /** - * @brief Assigns each entity in a range the given components. - * - * @sa emplace - * - * @tparam Component Type of component to create. - * @tparam EIt Type of input iterator. - * @tparam CIt Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - * @param from An iterator to the first element of the range of components. - * @param to An iterator past the last element of the range of components. - */ - template - void insert(EIt first, EIt last, CIt from, CIt to) { - static_assert(std::is_constructible_v::value_type>); - ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); })); - assure().insert(*this, first, last, from, to); - } - - /*! @copydoc insert */ - template - [[deprecated("use ::insert instead")]] - std::enable_if_t::value_type, entity_type>, void> - assign(EIt first, EIt last, CIt value) { - return insert(std::move(first), std::move(last), value, value + std::distance(first, last)); - } - - /** - * @brief Assigns or replaces the given component for an entity. - * - * Equivalent to the following snippet (pseudocode): - * - * @code{.cpp} - * auto &component = registry.has(entity) ? registry.replace(entity, args...) : registry.emplace(entity, args...); - * @endcode - * - * Prefer this function anyway because it has slightly better performance. - * - * @warning - * Attempting to use an invalid entity results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity. - * - * @tparam Component Type of component to assign or replace. - * @tparam Args Types of arguments to use to construct the component. - * @param entity A valid entity identifier. - * @param args Parameters to use to initialize the component. - * @return A reference to the newly created component. - */ - template - decltype(auto) emplace_or_replace(const entity_type entity, Args &&... args) { - ENTT_ASSERT(valid(entity)); - auto& cpool = assure(); - - return cpool.contains(entity) - ? cpool.replace(*this, entity, Component{ std::forward(args)... }) - : cpool.emplace(*this, entity, std::forward(args)...); - } - - /*! @copydoc emplace_or_replace */ - template - [[deprecated("use ::emplace_or_replace instead")]] - decltype(auto) assign_or_replace(const entity_type entity, Args &&... args) { - return emplace_or_replace(entity, std::forward(args)...); - } - - /** - * @brief Patches the given component for an entity. - * - * The signature of the functions should be equivalent to the following: - * - * @code{.cpp} - * void(Component &); - * @endcode - * - * @note - * Empty types aren't explicitly instantiated and therefore they are never - * returned. However, this function can be used to trigger an update signal - * for them. - * - * @warning - * Attempting to use an invalid entity or to patch a component of an entity - * that doesn't own it results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity or if the entity doesn't own an instance of the given - * component. - * - * @tparam Component Type of component to patch. - * @tparam Func Types of the function objects to invoke. - * @param entity A valid entity identifier. - * @param func Valid function objects. - * @return A reference to the patched component. - */ - template - decltype(auto) patch(const entity_type entity, Func &&... func) { - ENTT_ASSERT(valid(entity)); - return assure().patch(*this, entity, std::forward(func)...); - } - - /*! @copydoc patch */ - template - [[deprecated("use registry::patch instead")]] - auto replace(const entity_type entity, Func &&... func) - -> decltype((func(std::declval()), ...), assign(entity)) { - return patch(entity, std::forward(func)...); - } - - /** - * @brief Replaces the given component for an entity. - * - * A new instance of the given component is created and initialized with the - * arguments provided (the component must have a proper constructor or be of - * aggregate type). Then the component is assigned to the given entity. - * - * @warning - * Attempting to use an invalid entity or to replace a component of an - * entity that doesn't own it results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity or if the entity doesn't own an instance of the given - * component. - * - * @tparam Component Type of component to replace. - * @tparam Args Types of arguments to use to construct the component. - * @param entity A valid entity identifier. - * @param args Parameters to use to initialize the component. - * @return A reference to the component being replaced. - */ - template - auto replace(const entity_type entity, Args &&... args) - -> decltype(std::enable_if_t(), Component{ std::forward(args)... }, assure().get(entity)) { - return assure().replace(*this, entity, Component{ std::forward(args)... }); - } - - /** - * @brief Removes the given components from an entity. - * - * @warning - * Attempting to use an invalid entity or to remove a component from an - * entity that doesn't own it results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity or if the entity doesn't own an instance of the given - * component. - * - * @tparam Component Types of components to remove. - * @param entity A valid entity identifier. - */ - template - void remove(const entity_type entity) { - ENTT_ASSERT(valid(entity)); - (assure().remove(*this, entity), ...); - } - - /** - * @brief Removes the given components from all the entities in a range. - * - * @see remove - * - * @tparam Component Types of components to remove. - * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range of entities. - * @param last An iterator past the last element of the range of entities. - */ - template - void remove(It first, It last) { - ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); })); - (assure().remove(*this, first, last), ...); - } - - /** - * @brief Removes the given components from an entity. - * - * Equivalent to the following snippet (pseudocode): - * - * @code{.cpp} - * if(registry.has(entity)) { registry.remove(entity) } - * @endcode - * - * Prefer this function anyway because it has slightly better performance. - * - * @warning - * Attempting to use an invalid entity results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity. - * - * @tparam Component Types of components to remove. - * @param entity A valid entity identifier. - */ - template - void remove_if_exists(const entity_type entity) { - ENTT_ASSERT(valid(entity)); - - ([this, entity](auto&& cpool) { - if (cpool.contains(entity)) { - cpool.remove(*this, entity); - } - }(assure()), ...); - } - - /** - * @brief Removes all the components from an entity and makes it orphaned. - * - * @warning - * In case there are listeners that observe the destruction of components - * and assign other components to the entity in their bodies, the result of - * invoking this function may not be as expected. In the worst case, it - * could lead to undefined behavior. An assertion will abort the execution - * at runtime in debug mode if a violation is detected. - * - * @warning - * Attempting to use an invalid entity results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity. - * - * @param entity A valid entity identifier. - */ - void remove_all(const entity_type entity) { - ENTT_ASSERT(valid(entity)); - - for (auto pos = pools.size(); pos; --pos) { - if (auto& pdata = pools[pos - 1]; pdata.pool && pdata.pool->contains(entity)) { - pdata.remove(*pdata.pool, *this, entity); - } - } - } - - /** - * @brief Checks if an entity has all the given components. - * - * @warning - * Attempting to use an invalid entity results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity. - * - * @tparam Component Components for which to perform the check. - * @param entity A valid entity identifier. - * @return True if the entity has all the components, false otherwise. - */ - template - bool has(const entity_type entity) const { - ENTT_ASSERT(valid(entity)); - return (assure().contains(entity) && ...); - } - - /** - * @brief Checks if an entity has at least one of the given components. - * - * @warning - * Attempting to use an invalid entity results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity. - * - * @tparam Component Components for which to perform the check. - * @param entity A valid entity identifier. - * @return True if the entity has at least one of the given components, - * false otherwise. - */ - template - bool any(const entity_type entity) const { - ENTT_ASSERT(valid(entity)); - return (assure().contains(entity) || ...); - } - - /** - * @brief Returns references to the given components for an entity. - * - * @warning - * Attempting to use an invalid entity or to get a component from an entity - * that doesn't own it results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity or if the entity doesn't own an instance of the given - * component. - * - * @tparam Component Types of components to get. - * @param entity A valid entity identifier. - * @return References to the components owned by the entity. - */ - template - decltype(auto) get([[maybe_unused]] const entity_type entity) const { - ENTT_ASSERT(valid(entity)); - - if constexpr (sizeof...(Component) == 1) { - return (assure().get(entity), ...); - } - else { - return std::forward_as_tuple(get(entity)...); - } - } - - /*! @copydoc get */ - template - decltype(auto) get([[maybe_unused]] const entity_type entity) { - ENTT_ASSERT(valid(entity)); - - if constexpr (sizeof...(Component) == 1) { - return (assure().get(entity), ...); - } - else { - return std::forward_as_tuple(get(entity)...); - } - } - - /** - * @brief Returns a reference to the given component for an entity. - * - * In case the entity doesn't own the component, the parameters provided are - * used to construct it.
- * Equivalent to the following snippet (pseudocode): - * - * @code{.cpp} - * auto &component = registry.has(entity) ? registry.get(entity) : registry.emplace(entity, args...); - * @endcode - * - * Prefer this function anyway because it has slightly better performance. - * - * @warning - * Attempting to use an invalid entity results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity. - * - * @tparam Component Type of component to get. - * @tparam Args Types of arguments to use to construct the component. - * @param entity A valid entity identifier. - * @param args Parameters to use to initialize the component. - * @return Reference to the component owned by the entity. - */ - template - decltype(auto) get_or_emplace(const entity_type entity, Args &&... args) { - ENTT_ASSERT(valid(entity)); - auto& cpool = assure(); - return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(*this, entity, std::forward(args)...); - } - - /*! @copydoc get_or_emplace */ - template - [[deprecated("use ::get_or_emplace instead")]] - decltype(auto) get_or_assign(const entity_type entity, Args &&... args) { - return get_or_emplace(entity, std::forward(args)...); - } - - /** - * @brief Returns pointers to the given components for an entity. - * - * @warning - * Attempting to use an invalid entity results in undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid entity. - * - * @tparam Component Types of components to get. - * @param entity A valid entity identifier. - * @return Pointers to the components owned by the entity. - */ - template - auto try_get([[maybe_unused]] const entity_type entity) const { - ENTT_ASSERT(valid(entity)); - - if constexpr (sizeof...(Component) == 1) { - return (assure().try_get(entity), ...); - } - else { - return std::make_tuple(try_get(entity)...); - } - } - - /*! @copydoc try_get */ - template - auto try_get([[maybe_unused]] const entity_type entity) { - ENTT_ASSERT(valid(entity)); - - if constexpr (sizeof...(Component) == 1) { - return (assure().try_get(entity), ...); - } - else { - return std::make_tuple(try_get(entity)...); - } - } - - /** - * @brief Clears a whole registry or the pools for the given components. - * @tparam Component Types of components to remove from their entities. - */ - template - void clear() { - if constexpr (sizeof...(Component) == 0) { - // useless this-> used to suppress a warning with clang - each([this](const auto entity) { this->destroy(entity); }); - } - else { - ([this](auto&& cpool) { - cpool.remove(*this, cpool.sparse_set::begin(), cpool.sparse_set::end()); - }(assure()), ...); - } - } - - /** - * @brief Iterates all the entities that are still in use. - * - * The function object is invoked for each entity that is still in use.
- * The signature of the function should be equivalent to the following: - * - * @code{.cpp} - * void(const Entity); - * @endcode - * - * This function is fairly slow and should not be used frequently. However, - * it's useful for iterating all the entities still in use, regardless of - * their components. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - static_assert(std::is_invocable_v); - - if (destroyed == null) { - for (auto pos = entities.size(); pos; --pos) { - func(entities[pos - 1]); - } - } - else { - for (auto pos = entities.size(); pos; --pos) { - if (const auto entt = entities[pos - 1]; (to_integral(entt) & traits_type::entity_mask) == (pos - 1)) { - func(entt); - } - } - } - } - - /** - * @brief Checks if an entity has components assigned. - * @param entity A valid entity identifier. - * @return True if the entity has no components assigned, false otherwise. - */ - bool orphan(const entity_type entity) const { - ENTT_ASSERT(valid(entity)); - return std::none_of(pools.cbegin(), pools.cend(), [entity](auto&& pdata) { return pdata.pool && pdata.pool->contains(entity); }); - } - - /** - * @brief Iterates orphans and applies them the given function object. - * - * The function object is invoked for each entity that is still in use and - * has no components assigned.
- * The signature of the function should be equivalent to the following: - * - * @code{.cpp} - * void(const Entity); - * @endcode - * - * This function can be very slow and should not be used frequently. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void orphans(Func func) const { - static_assert(std::is_invocable_v); - - each([this, &func](const auto entity) { - if (orphan(entity)) { - func(entity); - } - }); - } - - /** - * @brief Returns a sink object for the given component. - * - * A sink is an opaque object used to connect listeners to components.
- * The sink returned by this function can be used to receive notifications - * whenever a new instance of the given component is created and assigned to - * an entity. - * - * The function type for a listener is equivalent to: - * - * @code{.cpp} - * void(registry &, Entity); - * @endcode - * - * Listeners are invoked **after** the component has been assigned to the - * entity. - * - * @sa sink - * - * @tparam Component Type of component of which to get the sink. - * @return A temporary sink object. - */ - template - auto on_construct() { - return assure().on_construct(); - } - - /** - * @brief Returns a sink object for the given component. - * - * A sink is an opaque object used to connect listeners to components.
- * The sink returned by this function can be used to receive notifications - * whenever an instance of the given component is explicitly updated. - * - * The function type for a listener is equivalent to: - * - * @code{.cpp} - * void(registry &, Entity); - * @endcode - * - * Listeners are invoked **after** the component has been updated. - * - * @sa sink - * - * @tparam Component Type of component of which to get the sink. - * @return A temporary sink object. - */ - template - auto on_update() { - return assure().on_update(); - } - - /*! @copydoc on_update */ - template - [[deprecated("use registry::on_update instead")]] - auto on_replace() { - return on_update(); - } - - /** - * @brief Returns a sink object for the given component. - * - * A sink is an opaque object used to connect listeners to components.
- * The sink returned by this function can be used to receive notifications - * whenever an instance of the given component is removed from an entity and - * thus destroyed. - * - * The function type for a listener is equivalent to: - * - * @code{.cpp} - * void(registry &, Entity); - * @endcode - * - * Listeners are invoked **before** the component has been removed from the - * entity. - * - * @sa sink - * - * @tparam Component Type of component of which to get the sink. - * @return A temporary sink object. - */ - template - auto on_destroy() { - return assure().on_destroy(); - } - - /** - * @brief Sorts the pool of entities for the given component. - * - * The order of the elements in a pool is highly affected by assignments - * of components to entities and deletions. Components are arranged to - * maximize the performance during iterations and users should not make any - * assumption on the order.
- * This function can be used to impose an order to the elements in the pool - * of the given component. The order is kept valid until a component of the - * given type is assigned or removed from an entity. - * - * The comparison function object must return `true` if the first element - * is _less_ than the second one, `false` otherwise. The signature of the - * comparison function should be equivalent to one of the following: - * - * @code{.cpp} - * bool(const Entity, const Entity); - * bool(const Component &, const Component &); - * @endcode - * - * Moreover, the comparison function object shall induce a - * _strict weak ordering_ on the values. - * - * The sort function oject must offer a member function template - * `operator()` that accepts three arguments: - * - * * An iterator to the first element of the range to sort. - * * An iterator past the last element of the range to sort. - * * A comparison function to use to compare the elements. - * - * The comparison funtion object received by the sort function object hasn't - * necessarily the type of the one passed along with the other parameters to - * this member function. - * - * @warning - * Pools of components owned by a group cannot be sorted.
- * An assertion will abort the execution at runtime in debug mode in case - * the pool is owned by a group. - * - * @tparam Component Type of components to sort. - * @tparam Compare Type of comparison function object. - * @tparam Sort Type of sort function object. - * @tparam Args Types of arguments to forward to the sort function object. - * @param compare A valid comparison function object. - * @param algo A valid sort function object. - * @param args Arguments to forward to the sort function object, if any. - */ - template - void sort(Compare compare, Sort algo = Sort{}, Args &&... args) { - auto& cpool = assure(); - ENTT_ASSERT(!cpool.super); - cpool.sort(cpool.begin(), cpool.end(), std::move(compare), std::move(algo), std::forward(args)...); - } - - /** - * @brief Sorts two pools of components in the same way. - * - * The order of the elements in a pool is highly affected by assignments - * of components to entities and deletions. Components are arranged to - * maximize the performance during iterations and users should not make any - * assumption on the order. - * - * It happens that different pools of components must be sorted the same way - * because of runtime and/or performance constraints. This function can be - * used to order a pool of components according to the order between the - * entities in another pool of components. - * - * @b How @b it @b works - * - * Being `A` and `B` the two sets where `B` is the master (the one the order - * of which rules) and `A` is the slave (the one to sort), after a call to - * this function an iterator for `A` will return the entities according to - * the following rules: - * - * * All the entities in `A` that are also in `B` are returned first - * according to the order they have in `B`. - * * All the entities in `A` that are not in `B` are returned in no - * particular order after all the other entities. - * - * Any subsequent change to `B` won't affect the order in `A`. - * - * @warning - * Pools of components owned by a group cannot be sorted.
- * An assertion will abort the execution at runtime in debug mode in case - * the pool is owned by a group. - * - * @tparam To Type of components to sort. - * @tparam From Type of components to use to sort. - */ - template - void sort() { - auto& cpool = assure(); - ENTT_ASSERT(!cpool.super); - cpool.respect(assure()); - } - - /** - * @brief Returns a view for the given components. - * - * This kind of objects are created on the fly and share with the registry - * its internal data structures.
- * Feel free to discard a view after the use. Creating and destroying a view - * is an incredibly cheap operation because they do not require any type of - * initialization.
- * As a rule of thumb, storing a view should never be an option. - * - * Views do their best to iterate the smallest set of candidate entities. - * In particular: - * - * * Single component views are incredibly fast and iterate a packed array - * of entities, all of which has the given component. - * * Multi component views look at the number of entities available for each - * component and pick up a reference to the smallest set of candidates to - * test for the given components. - * - * Views in no way affect the functionalities of the registry nor those of - * the underlying pools. - * - * @note - * Multi component views are pretty fast. However their performance tend to - * degenerate when the number of components to iterate grows up and the most - * of the entities have all the given components.
- * To get a performance boost, consider using a group instead. - * - * @tparam Component Type of components used to construct the view. - * @tparam Exclude Types of components used to filter the view. - * @return A newly created view. - */ - template - entt::basic_view, Component...> view(exclude_t = {}) { - static_assert(sizeof...(Component) > 0); - return { assure>()..., assure()... }; - } - - /*! @copydoc view */ - template - entt::basic_view, Component...> view(exclude_t = {}) const { - static_assert(std::conjunction_v...>); - return const_cast(this)->view(exclude); - } - - /** - * @brief Checks whether the given components belong to any group. - * @tparam Component Types of components in which one is interested. - * @return True if the pools of the given components are sortable, false - * otherwise. - */ - template - bool sortable() const { - return !(assure().super || ...); - } - - /** - * @brief Returns a group for the given components. - * - * This kind of objects are created on the fly and share with the registry - * its internal data structures.
- * Feel free to discard a group after the use. Creating and destroying a - * group is an incredibly cheap operation because they do not require any - * type of initialization, but for the first time they are requested.
- * As a rule of thumb, storing a group should never be an option. - * - * Groups support exclusion lists and can own types of components. The more - * types are owned by a group, the faster it is to iterate entities and - * components.
- * However, groups also affect some features of the registry such as the - * creation and destruction of components, which will consequently be - * slightly slower (nothing that can be noticed in most cases). - * - * @note - * Pools of components that are owned by a group cannot be sorted anymore. - * The group takes the ownership of the pools and arrange components so as - * to iterate them as fast as possible. - * - * @tparam Owned Types of components owned by the group. - * @tparam Get Types of components observed by the group. - * @tparam Exclude Types of components used to filter the group. - * @return A newly created group. - */ - template - entt::basic_group, get_t, Owned...> group(get_t, exclude_t = {}) { - static_assert(sizeof...(Owned) + sizeof...(Get) > 0); - static_assert(sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) > 1); - - using handler_type = group_handler, get_t...>, std::decay_t...>; - - const auto cpools = std::forward_as_tuple(assure>()..., assure>()...); - constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude); - handler_type* handler = nullptr; - - if (auto it = std::find_if(groups.cbegin(), groups.cend(), [size](const auto& gdata) { - return gdata.size == size - && (gdata.owned(type_info>::id()) && ...) - && (gdata.get(type_info>::id()) && ...) - && (gdata.exclude(type_info::id()) && ...); - }); it != groups.cend()) - { - handler = static_cast(it->group.get()); - } - - if (!handler) { - group_data candidate = { - size, - { new handler_type{}, [](void* instance) { delete static_cast(instance); } }, - []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info>::id()) || ...); }, - []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info>::id()) || ...); }, - []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info::id()) || ...); }, - }; - - handler = static_cast(candidate.group.get()); - - const void* maybe_valid_if = nullptr; - const void* discard_if = nullptr; - - if constexpr (sizeof...(Owned) == 0) { - groups.push_back(std::move(candidate)); - } - else { - ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [size](const auto& gdata) { - const auto overlapping = (0u + ... + gdata.owned(type_info>::id())); - const auto sz = overlapping + (0u + ... + gdata.get(type_info>::id())) + (0u + ... + gdata.exclude(type_info::id())); - return !overlapping || ((sz == size) || (sz == gdata.size)); - })); - - const auto next = std::find_if_not(groups.cbegin(), groups.cend(), [size](const auto& gdata) { - return !(0u + ... + gdata.owned(type_info>::id())) || (size > (gdata.size)); - }); - - const auto prev = std::find_if(std::make_reverse_iterator(next), groups.crend(), [](const auto& gdata) { - return (0u + ... + gdata.owned(type_info>::id())); - }); - - maybe_valid_if = (next == groups.cend() ? maybe_valid_if : next->group.get()); - discard_if = (prev == groups.crend() ? discard_if : prev->group.get()); - groups.insert(next, std::move(candidate)); - } - - ((std::get>&>(cpools).super = std::max(std::get>&>(cpools).super, size)), ...); - - (on_construct>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if>>(*handler), ...); - (on_construct>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if>>(*handler), ...); - (on_destroy().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if>(*handler), ...); - - (on_destroy>().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...); - (on_destroy>().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...); - (on_construct().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...); - - if constexpr (sizeof...(Owned) == 0) { - for (const auto entity : view(entt::exclude)) { - handler->current.emplace(entity); - } - } - else { - // we cannot iterate backwards because we want to leave behind valid entities in case of owned types - for (auto* first = std::get<0>(cpools).data(), *last = first + std::get<0>(cpools).size(); first != last; ++first) { - handler->template maybe_valid_if...>>>(*this, *first); - } - } - } - - if constexpr (sizeof...(Owned) == 0) { - return { handler->current, std::get>&>(cpools)... }; - } - else { - return { std::get<0>(cpools).super, handler->current, std::get>&>(cpools)... , std::get>&>(cpools)... }; - } - } - - /** - * @brief Returns a group for the given components. - * - * @sa group - * - * @tparam Owned Types of components owned by the group. - * @tparam Get Types of components observed by the group. - * @tparam Exclude Types of components used to filter the group. - * @return A newly created group. - */ - template - entt::basic_group, get_t, Owned...> group(get_t, exclude_t = {}) const { - static_assert(std::conjunction_v..., std::is_const...>); - return const_cast(this)->group(entt::get, exclude); - } - - /** - * @brief Returns a group for the given components. - * - * @sa group - * - * @tparam Owned Types of components owned by the group. - * @tparam Exclude Types of components used to filter the group. - * @return A newly created group. - */ - template - entt::basic_group, get_t<>, Owned...> group(exclude_t = {}) { - return group(entt::get<>, exclude); - } - - /** - * @brief Returns a group for the given components. - * - * @sa group - * - * @tparam Owned Types of components owned by the group. - * @tparam Exclude Types of components used to filter the group. - * @return A newly created group. - */ - template - entt::basic_group, get_t<>, Owned...> group(exclude_t = {}) const { - static_assert(std::conjunction_v...>); - return const_cast(this)->group(exclude); - } - - /** - * @brief Returns a runtime view for the given components. - * - * This kind of objects are created on the fly and share with the registry - * its internal data structures.
- * Users should throw away the view after use. Fortunately, creating and - * destroying a runtime view is an incredibly cheap operation because they - * do not require any type of initialization.
- * As a rule of thumb, storing a view should never be an option. - * - * Runtime views are to be used when users want to construct a view from - * some external inputs and don't know at compile-time what are the required - * components.
- * This is particularly well suited to plugin systems and mods in general. - * - * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range of components. - * @param last An iterator past the last element of the range of components. - * @return A newly created runtime view. - */ - template - entt::basic_runtime_view runtime_view(It first, It last) const { - std::vector*> selected(std::distance(first, last)); - - std::transform(first, last, selected.begin(), [this](const auto ctype) { - const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto&& pdata) { return pdata.pool && pdata.type_id == ctype; }); - return it == pools.cend() ? nullptr : it->pool.get(); - }); - - return { std::move(selected) }; - } - - /** - * @brief Returns a temporary object to use to create snapshots. - * - * A snapshot is either a full or a partial dump of a registry.
- * It can be used to save and restore its internal state or to keep two or - * more instances of this class in sync, as an example in a client-server - * architecture. - * - * @return A temporary object to use to take snasphosts. - */ - [[deprecated("basic_snapshot has now a constructor that accepts a reference to a registry")]] - entt::basic_snapshot snapshot() const { - return { *this }; - } - - /** - * @brief Returns a temporary object to use to load snapshots. - * - * A snapshot is either a full or a partial dump of a registry.
- * It can be used to save and restore its internal state or to keep two or - * more instances of this class in sync, as an example in a client-server - * architecture. - * - * @note - * The loader returned by this function requires that the registry be empty. - * In case it isn't, all the data will be automatically deleted before to - * return. - * - * @return A temporary object to use to load snasphosts. - */ - [[deprecated("basic_snapshot_loader has now a constructor that accepts a reference to a registry")]] - basic_snapshot_loader loader() { - return { *this }; - } - - /** - * @brief Visits an entity and returns the types for its components. - * - * The signature of the function should be equivalent to the following: - * - * @code{.cpp} - * void(const id_type); - * @endcode - * - * Returned identifiers are those of the components owned by the entity. - * - * @sa type_info - * - * @warning - * It's not specified whether a component attached to or removed from the - * given entity during the visit is returned or not to the caller. - * - * @tparam Func Type of the function object to invoke. - * @param entity A valid entity identifier. - * @param func A valid function object. - */ - template - void visit(entity_type entity, Func func) const { - for (auto pos = pools.size(); pos; --pos) { - if (const auto& pdata = pools[pos - 1]; pdata.pool && pdata.pool->contains(entity)) { - func(pdata.type_id); - } - } - } - - /** - * @brief Visits a registry and returns the types for its components. - * - * The signature of the function should be equivalent to the following: - * - * @code{.cpp} - * void(const id_type); - * @endcode - * - * Returned identifiers are those of the components managed by the registry. - * - * @sa type_info - * - * @warning - * It's not specified whether a component for which a pool is created during - * the visit is returned or not to the caller. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void visit(Func func) const { - for (auto pos = pools.size(); pos; --pos) { - if (const auto& pdata = pools[pos - 1]; pdata.pool) { - func(pdata.type_id); - } - } - } - - /** - * @brief Binds an object to the context of the registry. - * - * If the value already exists it is overwritten, otherwise a new instance - * of the given type is created and initialized with the arguments provided. - * - * @tparam Type Type of object to set. - * @tparam Args Types of arguments to use to construct the object. - * @param args Parameters to use to initialize the value. - * @return A reference to the newly created object. - */ - template - Type& set(Args &&... args) { - unset(); - vars.push_back(variable_data{ type_info::id(), { new Type{std::forward(args)...}, [](void* instance) { delete static_cast(instance); } } }); - return *static_cast(vars.back().value.get()); - } - - /** - * @brief Unsets a context variable if it exists. - * @tparam Type Type of object to set. - */ - template - void unset() { - vars.erase(std::remove_if(vars.begin(), vars.end(), [](auto&& var) { - return var.type_id == type_info::id(); - }), vars.end()); - } - - /** - * @brief Binds an object to the context of the registry. - * - * In case the context doesn't contain the given object, the parameters - * provided are used to construct it. - * - * @tparam Type Type of object to set. - * @tparam Args Types of arguments to use to construct the object. - * @param args Parameters to use to initialize the object. - * @return A reference to the object in the context of the registry. - */ - template - Type& ctx_or_set(Args &&... args) { - auto* value = try_ctx(); - return value ? *value : set(std::forward(args)...); - } - - /** - * @brief Returns a pointer to an object in the context of the registry. - * @tparam Type Type of object to get. - * @return A pointer to the object if it exists in the context of the - * registry, a null pointer otherwise. - */ - template - const Type* try_ctx() const { - auto it = std::find_if(vars.cbegin(), vars.cend(), [](auto&& var) { return var.type_id == type_info::id(); }); - return it == vars.cend() ? nullptr : static_cast(it->value.get()); - } - - /*! @copydoc try_ctx */ - template - Type* try_ctx() { - return const_cast(std::as_const(*this).template try_ctx()); - } - - /** - * @brief Returns a reference to an object in the context of the registry. - * - * @warning - * Attempting to get a context variable that doesn't exist results in - * undefined behavior.
- * An assertion will abort the execution at runtime in debug mode in case of - * invalid requests. - * - * @tparam Type Type of object to get. - * @return A valid reference to the object in the context of the registry. - */ - template - const Type& ctx() const { - const auto* instance = try_ctx(); - ENTT_ASSERT(instance); - return *instance; - } - - /*! @copydoc ctx */ - template - Type& ctx() { - return const_cast(std::as_const(*this).template ctx()); - } - - /** - * @brief Visits a registry and returns the types for its context variables. - * - * The signature of the function should be equivalent to the following: - * - * @code{.cpp} - * void(const id_type); - * @endcode - * - * Returned identifiers are those of the context variables currently set. - * - * @sa type_info - * - * @warning - * It's not specified whether a context variable created during the visit is - * returned or not to the caller. - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void ctx(Func func) const { - for (auto pos = vars.size(); pos; --pos) { - func(vars[pos - 1].type_id); - } - } - - private: - std::vector groups{}; - mutable std::vector pools{}; - std::vector entities{}; - std::vector vars{}; - entity_type destroyed{ null }; - }; - - -} - - -#endif - -// #include "entity.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Dedicated to those who aren't confident with the - * entity-component-system architecture. - * - * Tiny wrapper around a registry, for all those users that aren't confident - * with entity-component-system architecture and prefer to iterate objects - * directly. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - struct basic_actor { - /*! @brief Type of registry used internally. */ - using registry_type = basic_registry; - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - - basic_actor() ENTT_NOEXCEPT - : entt{ entt::null }, reg{ nullptr } - {} - - /** - * @brief Move constructor. - * - * After actor move construction, instances that have been moved from are - * placed in a valid but unspecified state. It's highly discouraged to - * continue using them. - * - * @param other The instance to move from. - */ - basic_actor(basic_actor&& other) ENTT_NOEXCEPT - : entt{ other.entt }, reg{ other.reg } - { - other.entt = null; - } - - /** - * @brief Constructs an actor from a given registry. - * @param ref An instance of the registry class. - */ - explicit basic_actor(registry_type& ref) - : entt{ ref.create() }, reg{ &ref } - {} - - /** - * @brief Constructs an actor from a given entity. - * @param entity A valid entity identifier. - * @param ref An instance of the registry class. - */ - explicit basic_actor(entity_type entity, registry_type& ref) ENTT_NOEXCEPT - : entt{ entity }, reg{ &ref } - { - ENTT_ASSERT(ref.valid(entity)); - } - - /*! @brief Default destructor. */ - virtual ~basic_actor() { - if (*this) { - reg->destroy(entt); - } - } - - /** - * @brief Move assignment operator. - * - * After actor move assignment, instances that have been moved from are - * placed in a valid but unspecified state. It's highly discouraged to - * continue using them. - * - * @param other The instance to move from. - * @return This actor. - */ - basic_actor& operator=(basic_actor&& other) ENTT_NOEXCEPT { - if (this != &other) { - auto tmp{ std::move(other) }; - std::swap(reg, tmp.reg); - std::swap(entt, tmp.entt); - } - - return *this; - } - - /** - * @brief Assigns the given component to an actor. - * - * A new instance of the given component is created and initialized with the - * arguments provided (the component must have a proper constructor or be of - * aggregate type). Then the component is assigned to the actor.
- * In case the actor already has a component of the given type, it's - * replaced with the new one. - * - * @tparam Component Type of the component to create. - * @tparam Args Types of arguments to use to construct the component. - * @param args Parameters to use to initialize the component. - * @return A reference to the newly created component. - */ - template - decltype(auto) assign(Args &&... args) { - return reg->template emplace_or_replace(entt, std::forward(args)...); - } - - /** - * @brief Removes the given component from an actor. - * @tparam Component Type of the component to remove. - */ - template - void remove() { - reg->template remove(entt); - } - - /** - * @brief Checks if an actor has the given components. - * @tparam Component Components for which to perform the check. - * @return True if the actor has all the components, false otherwise. - */ - template - bool has() const { - return reg->template has(entt); - } - - /** - * @brief Returns references to the given components for an actor. - * @tparam Component Types of components to get. - * @return References to the components owned by the actor. - */ - template - decltype(auto) get() const { - return std::as_const(*reg).template get(entt); - } - - /*! @copydoc get */ - template - decltype(auto) get() { - return reg->template get(entt); - } - - /** - * @brief Returns pointers to the given components for an actor. - * @tparam Component Types of components to get. - * @return Pointers to the components owned by the actor. - */ - template - auto try_get() const { - return std::as_const(*reg).template try_get(entt); - } - - /*! @copydoc try_get */ - template - auto try_get() { - return reg->template try_get(entt); - } - - /** - * @brief Returns a reference to the underlying registry. - * @return A reference to the underlying registry. - */ - const registry_type& backend() const ENTT_NOEXCEPT { - return *reg; - } - - /*! @copydoc backend */ - registry_type& backend() ENTT_NOEXCEPT { - return const_cast(std::as_const(*this).backend()); - } - - /** - * @brief Returns the entity associated with an actor. - * @return The entity associated with the actor. - */ - entity_type entity() const ENTT_NOEXCEPT { - return entt; - } - - /** - * @brief Checks if an actor refers to a valid entity or not. - * @return True if the actor refers to a valid entity, false otherwise. - */ - explicit operator bool() const { - return reg && reg->valid(entt); - } - - private: - entity_type entt; - registry_type* reg; - }; - - -} - - -#endif - -// #include "entity/entity.hpp" - -// #include "entity/group.hpp" - -// #include "entity/helper.hpp" -#ifndef ENTT_ENTITY_HELPER_HPP -#define ENTT_ENTITY_HELPER_HPP - - -#include -// #include "../config/config.h" - -// #include "../core/type_traits.hpp" - -// #include "../signal/delegate.hpp" - -// #include "registry.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Converts a registry to a view. - * @tparam Const Constness of the accepted registry. - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - struct as_view { - /*! @brief Type of registry to convert. */ - using registry_type = std::conditional_t, entt::basic_registry>; - - /** - * @brief Constructs a converter for a given registry. - * @param source A valid reference to a registry. - */ - as_view(registry_type& source) ENTT_NOEXCEPT: reg{ source } {} - - /** - * @brief Conversion function from a registry to a view. - * @tparam Exclude Types of components used to filter the view. - * @tparam Component Type of components used to construct the view. - * @return A newly created view. - */ - template - operator entt::basic_view() const { - return reg.template view(Exclude{}); - } - - private: - registry_type& reg; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the constness of a registry directly from the instance - * provided to the constructor. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - as_view(basic_registry&) ENTT_NOEXCEPT->as_view; - - - /*! @copydoc as_view */ - template - as_view(const basic_registry&) ENTT_NOEXCEPT->as_view; - - - /** - * @brief Converts a registry to a group. - * @tparam Const Constness of the accepted registry. - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - struct as_group { - /*! @brief Type of registry to convert. */ - using registry_type = std::conditional_t, entt::basic_registry>; - - /** - * @brief Constructs a converter for a given registry. - * @param source A valid reference to a registry. - */ - as_group(registry_type& source) ENTT_NOEXCEPT: reg{ source } {} - - /** - * @brief Conversion function from a registry to a group. - * @tparam Exclude Types of components used to filter the group. - * @tparam Get Types of components observed by the group. - * @tparam Owned Types of components owned by the group. - * @return A newly created group. - */ - template - operator entt::basic_group() const { - return reg.template group(Get{}, Exclude{}); - } - - private: - registry_type& reg; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the constness of a registry directly from the instance - * provided to the constructor. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - as_group(basic_registry&) ENTT_NOEXCEPT->as_group; - - - /*! @copydoc as_group */ - template - as_group(const basic_registry&) ENTT_NOEXCEPT->as_group; - - - - /** - * @brief Helper to create a listener that directly invokes a member function. - * @tparam Member Member function to invoke on a component of the given type. - * @tparam Entity A valid entity type (see entt_traits for more details). - * @param reg A registry that contains the given entity and its components. - * @param entt Entity from which to get the component. - */ - template - void invoke(basic_registry& reg, const Entity entt) { - static_assert(std::is_member_function_pointer_v); - delegate&, const Entity)> func; - func.template connect(reg.template get>(entt)); - func(reg, entt); - } - - -} - - -#endif - -// #include "entity/observer.hpp" -#ifndef ENTT_ENTITY_OBSERVER_HPP -#define ENTT_ENTITY_OBSERVER_HPP - - -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/type_traits.hpp" - -// #include "registry.hpp" - -// #include "storage.hpp" - -// #include "utility.hpp" - -// #include "entity.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /*! @brief Grouping matcher. */ - template - struct matcher {}; - - - /** - * @brief Collector. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error, but for a few reasonable cases. - */ - template - struct basic_collector; - - - /** - * @brief Collector. - * - * A collector contains a set of rules (literally, matchers) to use to track - * entities.
- * Its main purpose is to generate a descriptor that allows an observer to know - * how to connect to a registry. - */ - template<> - struct basic_collector<> { - /** - * @brief Adds a grouping matcher to the collector. - * @tparam AllOf Types of components tracked by the matcher. - * @tparam NoneOf Types of components used to filter out entities. - * @return The updated collector. - */ - template - static constexpr auto group(exclude_t = {}) ENTT_NOEXCEPT { - return basic_collector, type_list<>, type_list, AllOf...>>{}; - } - - /** - * @brief Adds an observing matcher to the collector. - * @tparam AnyOf Type of component for which changes should be detected. - * @return The updated collector. - */ - template - static constexpr auto update() ENTT_NOEXCEPT { - return basic_collector, type_list<>, AnyOf>>{}; - } - - /*! @copydoc update */ - template - [[deprecated("use ::update instead")]] - static constexpr auto replace() ENTT_NOEXCEPT { - return update(); - } - }; - - /** - * @brief Collector. - * @copydetails basic_collector<> - * @tparam Reject Untracked types used to filter out entities. - * @tparam Require Untracked types required by the matcher. - * @tparam Rule Specific details of the current matcher. - * @tparam Other Other matchers. - */ - template - struct basic_collector, type_list, Rule...>, Other...> { - /*! @brief Current matcher. */ - using current_type = matcher, type_list, Rule...>; - - /** - * @brief Adds a grouping matcher to the collector. - * @tparam AllOf Types of components tracked by the matcher. - * @tparam NoneOf Types of components used to filter out entities. - * @return The updated collector. - */ - template - static constexpr auto group(exclude_t = {}) ENTT_NOEXCEPT { - return basic_collector, type_list<>, type_list, AllOf...>, current_type, Other...>{}; - } - - /** - * @brief Adds an observing matcher to the collector. - * @tparam AnyOf Type of component for which changes should be detected. - * @return The updated collector. - */ - template - static constexpr auto update() ENTT_NOEXCEPT { - return basic_collector, type_list<>, AnyOf>, current_type, Other...>{}; - } - - /*! @copydoc update */ - template - [[deprecated("use ::update instead")]] - static constexpr auto replace() ENTT_NOEXCEPT { - return update(); - } - - - /** - * @brief Updates the filter of the last added matcher. - * @tparam AllOf Types of components required by the matcher. - * @tparam NoneOf Types of components used to filter out entities. - * @return The updated collector. - */ - template - static constexpr auto where(exclude_t = {}) ENTT_NOEXCEPT { - using extended_type = matcher, type_list, Rule...>; - return basic_collector{}; - } - }; - - - /*! @brief Variable template used to ease the definition of collectors. */ - inline constexpr basic_collector<> collector{}; - - - /** - * @brief Observer. - * - * An observer returns all the entities and only the entities that fit the - * requirements of at least one matcher. Moreover, it's guaranteed that the - * entity list is tightly packed in memory for fast iterations.
- * In general, observers don't stay true to the order of any set of components. - * - * Observers work mainly with two types of matchers, provided through a - * collector: - * - * * Observing matcher: an observer will return at least all the living entities - * for which one or more of the given components have been updated and not yet - * destroyed. - * * Grouping matcher: an observer will return at least all the living entities - * that would have entered the given group if it existed and that would have - * not yet left it. - * - * If an entity respects the requirements of multiple matchers, it will be - * returned once and only once by the observer in any case. - * - * Matchers support also filtering by means of a _where_ clause that accepts - * both a list of types and an exclusion list.
- * Whenever a matcher finds that an entity matches its requirements, the - * condition of the filter is verified before to register the entity itself. - * Moreover, a registered entity isn't returned by the observer if the condition - * set by the filter is broken in the meantime. - * - * @b Important - * - * Iterators aren't invalidated if: - * - * * New instances of the given components are created and assigned to entities. - * * The entity currently pointed is modified (as an example, if one of the - * given components is removed from the entity to which the iterator points). - * * The entity currently pointed is destroyed. - * - * In all the other cases, modifying the pools of the given components in any - * way invalidates all the iterators and using them results in undefined - * behavior. - * - * @warning - * Lifetime of an observer doesn't necessarily have to overcome that of the - * registry to which it is connected. However, the observer must be disconnected - * from the registry before being destroyed to avoid crashes due to dangling - * pointers. - * - * @tparam Entity A valid entity type (see entt_traits for more details). - */ - template - class basic_observer { - using payload_type = std::uint32_t; - - template - struct matcher_handler; - - template - struct matcher_handler, type_list, AnyOf>> { - template - static void maybe_valid_if(basic_observer& obs, const basic_registry& reg, const Entity entt) { - if (reg.template has(entt) && !reg.template any(entt)) { - if (auto* comp = obs.view.try_get(entt); !comp) { - obs.view.emplace(entt); - } - - obs.view.get(entt) |= (1 << Index); - } - } - - template - static void discard_if(basic_observer& obs, const basic_registry&, const Entity entt) { - if (auto* value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) { - obs.view.erase(entt); - } - } - - template - static void connect(basic_observer& obs, basic_registry& reg) { - (reg.template on_destroy().template connect<&discard_if>(obs), ...); - (reg.template on_construct().template connect<&discard_if>(obs), ...); - reg.template on_update().template connect<&maybe_valid_if>(obs); - reg.template on_destroy().template connect<&discard_if>(obs); - } - - static void disconnect(basic_observer& obs, basic_registry& reg) { - (reg.template on_destroy().disconnect(obs), ...); - (reg.template on_construct().disconnect(obs), ...); - reg.template on_update().disconnect(obs); - reg.template on_destroy().disconnect(obs); - } - }; - - template - struct matcher_handler, type_list, type_list, AllOf...>> { - template - static void maybe_valid_if(basic_observer& obs, const basic_registry& reg, const Entity entt) { - if (reg.template has(entt) && !reg.template any(entt)) { - if (auto* comp = obs.view.try_get(entt); !comp) { - obs.view.emplace(entt); - } - - obs.view.get(entt) |= (1 << Index); - } - } - - template - static void discard_if(basic_observer& obs, const basic_registry&, const Entity entt) { - if (auto* value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) { - obs.view.erase(entt); - } - } - - template - static void connect(basic_observer& obs, basic_registry& reg) { - (reg.template on_destroy().template connect<&discard_if>(obs), ...); - (reg.template on_construct().template connect<&discard_if>(obs), ...); - (reg.template on_construct().template connect<&maybe_valid_if>(obs), ...); - (reg.template on_destroy().template connect<&maybe_valid_if>(obs), ...); - (reg.template on_destroy().template connect<&discard_if>(obs), ...); - (reg.template on_construct().template connect<&discard_if>(obs), ...); - } - - static void disconnect(basic_observer& obs, basic_registry& reg) { - (reg.template on_destroy().disconnect(obs), ...); - (reg.template on_construct().disconnect(obs), ...); - (reg.template on_construct().disconnect(obs), ...); - (reg.template on_destroy().disconnect(obs), ...); - (reg.template on_destroy().disconnect(obs), ...); - (reg.template on_construct().disconnect(obs), ...); - } - }; - - template - static void disconnect(basic_observer& obs, basic_registry& reg) { - (matcher_handler::disconnect(obs, reg), ...); - } - - template - void connect(basic_registry& reg, std::index_sequence) { - static_assert(sizeof...(Matcher) < std::numeric_limits::digits); - (matcher_handler::template connect(*this, reg), ...); - release = &basic_observer::disconnect; - } - - public: - /*! @brief Underlying entity identifier. */ - using entity_type = Entity; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Input iterator type. */ - using iterator = typename sparse_set::iterator; - - /*! @brief Default constructor. */ - basic_observer() - : target{}, release{}, view{} - {} - - /*! @brief Default copy constructor, deleted on purpose. */ - basic_observer(const basic_observer&) = delete; - /*! @brief Default move constructor, deleted on purpose. */ - basic_observer(basic_observer&&) = delete; - - /** - * @brief Creates an observer and connects it to a given registry. - * @tparam Matcher Types of matchers to use to initialize the observer. - * @param reg A valid reference to a registry. - */ - template - basic_observer(basic_registry& reg, basic_collector) - : target{ ® }, - release{}, - view{} - { - connect(reg, std::index_sequence_for{}); - } - - /*! @brief Default destructor. */ - ~basic_observer() = default; - - /** - * @brief Default copy assignment operator, deleted on purpose. - * @return This observer. - */ - basic_observer& operator=(const basic_observer&) = delete; - - /** - * @brief Default move assignment operator, deleted on purpose. - * @return This observer. - */ - basic_observer& operator=(basic_observer&&) = delete; - - /** - * @brief Connects an observer to a given registry. - * @tparam Matcher Types of matchers to use to initialize the observer. - * @param reg A valid reference to a registry. - */ - template - void connect(basic_registry& reg, basic_collector) { - disconnect(); - connect(reg, std::index_sequence_for{}); - target = ® - view.clear(); - } - - /*! @brief Disconnects an observer from the registry it keeps track of. */ - void disconnect() { - if (release) { - release(*this, *target); - release = nullptr; - } - } - - /** - * @brief Returns the number of elements in an observer. - * @return Number of elements. - */ - size_type size() const ENTT_NOEXCEPT { - return view.size(); - } - - /** - * @brief Checks whether an observer is empty. - * @return True if the observer is empty, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return view.empty(); - } - - /** - * @brief Direct access to the list of entities of the observer. - * - * The returned pointer is such that range `[data(), data() + size()]` is - * always a valid range, even if the container is empty. - * - * @note - * There are no guarantees on the order of the entities. Use `begin` and - * `end` if you want to iterate the observer in the expected order. - * - * @return A pointer to the array of entities. - */ - const entity_type* data() const ENTT_NOEXCEPT { - return view.data(); - } - - /** - * @brief Returns an iterator to the first entity of the observer. - * - * The returned iterator points to the first entity of the observer. If the - * container is empty, the returned iterator will be equal to `end()`. - * - * @return An iterator to the first entity of the observer. - */ - iterator begin() const ENTT_NOEXCEPT { - return view.sparse_set::begin(); - } - - /** - * @brief Returns an iterator that is past the last entity of the observer. - * - * The returned iterator points to the entity following the last entity of - * the observer. Attempting to dereference the returned iterator results in - * undefined behavior. - * - * @return An iterator to the entity following the last entity of the - * observer. - */ - iterator end() const ENTT_NOEXCEPT { - return view.sparse_set::end(); - } - - /*! @brief Clears the underlying container. */ - void clear() ENTT_NOEXCEPT { - view.clear(); - } - - /** - * @brief Iterates entities and applies the given function object to them. - * - * The function object is invoked for each entity.
- * The signature of the function must be equivalent to the following form: - * - * @code{.cpp} - * void(const entity_type); - * @endcode - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - static_assert(std::is_invocable_v); - - for (const auto entity : *this) { - func(entity); - } - } - - /** - * @brief Iterates entities and applies the given function object to them, - * then clears the observer. - * - * @sa each - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) { - std::as_const(*this).each(std::move(func)); - clear(); - } - - private: - basic_registry* target; - void(*release)(basic_observer&, basic_registry&); - storage view; - }; - - -} - - -#endif - -// #include "entity/registry.hpp" - -// #include "entity/runtime_view.hpp" - -// #include "entity/snapshot.hpp" - -// #include "entity/sparse_set.hpp" - -// #include "entity/storage.hpp" - -// #include "entity/utility.hpp" - -// #include "entity/view.hpp" - -// #include "locator/locator.hpp" -#ifndef ENTT_LOCATOR_LOCATOR_HPP -#define ENTT_LOCATOR_LOCATOR_HPP - - -#include -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - - - -namespace entt { - - - /** - * @brief Service locator, nothing more. - * - * A service locator can be used to do what it promises: locate services.
- * Usually service locators are tightly bound to the services they expose and - * thus it's hard to define a general purpose class to do that. This template - * based implementation tries to fill the gap and to get rid of the burden of - * defining a different specific locator for each application. - * - * @tparam Service Type of service managed by the locator. - */ - template - struct service_locator { - /*! @brief Type of service offered. */ - using service_type = Service; - - /*! @brief Default constructor, deleted on purpose. */ - service_locator() = delete; - /*! @brief Default destructor, deleted on purpose. */ - ~service_locator() = delete; - - /** - * @brief Tests if a valid service implementation is set. - * @return True if the service is set, false otherwise. - */ - static bool empty() ENTT_NOEXCEPT { - return !static_cast(service); - } - - /** - * @brief Returns a weak pointer to a service implementation, if any. - * - * Clients of a service shouldn't retain references to it. The recommended - * way is to retrieve the service implementation currently set each and - * every time the need of using it arises. Otherwise users can incur in - * unexpected behaviors. - * - * @return A reference to the service implementation currently set, if any. - */ - static std::weak_ptr get() ENTT_NOEXCEPT { - return service; - } - - /** - * @brief Returns a weak reference to a service implementation, if any. - * - * Clients of a service shouldn't retain references to it. The recommended - * way is to retrieve the service implementation currently set each and - * every time the need of using it arises. Otherwise users can incur in - * unexpected behaviors. - * - * @warning - * In case no service implementation has been set, a call to this function - * results in undefined behavior. - * - * @return A reference to the service implementation currently set, if any. - */ - static Service& ref() ENTT_NOEXCEPT { - return *service; - } - - /** - * @brief Sets or replaces a service. - * @tparam Impl Type of the new service to use. - * @tparam Args Types of arguments to use to construct the service. - * @param args Parameters to use to construct the service. - */ - template - static void set(Args &&... args) { - service = std::make_shared(std::forward(args)...); - } - - /** - * @brief Sets or replaces a service. - * @param ptr Service to use to replace the current one. - */ - static void set(std::shared_ptr ptr) { - ENTT_ASSERT(static_cast(ptr)); - service = std::move(ptr); - } - - /** - * @brief Resets a service. - * - * The service is no longer valid after a reset. - */ - static void reset() { - service.reset(); - } - - private: - inline static std::shared_ptr service = nullptr; - }; - - -} - - -#endif - -// #include "meta/factory.hpp" -#ifndef ENTT_META_FACTORY_HPP -#define ENTT_META_FACTORY_HPP - - -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - -// #include "../core/fwd.hpp" -#ifndef ENTT_CORE_FWD_HPP -#define ENTT_CORE_FWD_HPP - - -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - - - -namespace entt { - - - /*! @brief Alias declaration for type identifiers. */ - using id_type = ENTT_ID_TYPE; - - -} - - -#endif - -// #include "../core/type_info.hpp" -#ifndef ENTT_CORE_TYPE_INFO_HPP -#define ENTT_CORE_TYPE_INFO_HPP - - -// #include "../config/config.h" - -// #include "../core/attribute.h" -#ifndef ENTT_CORE_ATTRIBUTE_H -#define ENTT_CORE_ATTRIBUTE_H - - -#ifndef ENTT_EXPORT -# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER -# define ENTT_EXPORT __declspec(dllexport) -# define ENTT_IMPORT __declspec(dllimport) -# define ENTT_HIDDEN -# elif defined __GNUC__ && __GNUC__ >= 4 -# define ENTT_EXPORT __attribute__((visibility("default"))) -# define ENTT_IMPORT __attribute__((visibility("default"))) -# define ENTT_HIDDEN __attribute__((visibility("hidden"))) -# else /* Unsupported compiler */ -# define ENTT_EXPORT -# define ENTT_IMPORT -# define ENTT_HIDDEN -# endif -#endif - - -#ifndef ENTT_API -# if defined ENTT_API_EXPORT -# define ENTT_API ENTT_EXPORT -# elif defined ENTT_API_IMPORT -# define ENTT_API ENTT_IMPORT -# else /* No API */ -# define ENTT_API -# endif -#endif - - -#endif - -// #include "hashed_string.hpp" -#ifndef ENTT_CORE_HASHED_STRING_HPP -#define ENTT_CORE_HASHED_STRING_HPP - - -#include -#include -// #include "../config/config.h" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - template - struct fnv1a_traits; - - - template<> - struct fnv1a_traits { - using type = std::uint32_t; - static constexpr std::uint32_t offset = 2166136261; - static constexpr std::uint32_t prime = 16777619; - }; - - - template<> - struct fnv1a_traits { - using type = std::uint64_t; - static constexpr std::uint64_t offset = 14695981039346656037ull; - static constexpr std::uint64_t prime = 1099511628211ull; - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Zero overhead unique identifier. - * - * A hashed string is a compile-time tool that allows users to use - * human-readable identifers in the codebase while using their numeric - * counterparts at runtime.
- * Because of that, a hashed string can also be used in constant expressions if - * required. - * - * @tparam Char Character type. - */ - template - class basic_hashed_string { - using traits_type = internal::fnv1a_traits; - - struct const_wrapper { - // non-explicit constructor on purpose - constexpr const_wrapper(const Char* curr) ENTT_NOEXCEPT: str{ curr } {} - const Char* str; - }; - - // Fowler–Noll–Vo hash function v. 1a - the good - static constexpr id_type helper(const Char* curr) ENTT_NOEXCEPT { - auto value = traits_type::offset; - - while (*curr != 0) { - value = (value ^ static_cast(*(curr++))) * traits_type::prime; - } - - return value; - } - - public: - /*! @brief Character type. */ - using value_type = Char; - /*! @brief Unsigned integer type. */ - using hash_type = id_type; - - /** - * @brief Returns directly the numeric representation of a string. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * const auto value = basic_hashed_string::to_value("my.png"); - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - * @return The numeric representation of the string. - */ - template - static constexpr hash_type value(const value_type(&str)[N]) ENTT_NOEXCEPT { - return helper(str); - } - - /** - * @brief Returns directly the numeric representation of a string. - * @param wrapper Helps achieving the purpose by relying on overloading. - * @return The numeric representation of the string. - */ - static hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT { - return helper(wrapper.str); - } - - /** - * @brief Returns directly the numeric representation of a string view. - * @param str Human-readable identifer. - * @param size Length of the string to hash. - * @return The numeric representation of the string. - */ - static hash_type value(const value_type* str, std::size_t size) ENTT_NOEXCEPT { - id_type partial{ traits_type::offset }; - while (size--) { partial = (partial ^ (str++)[0]) * traits_type::prime; } - return partial; - } - - /*! @brief Constructs an empty hashed string. */ - constexpr basic_hashed_string() ENTT_NOEXCEPT - : str{ nullptr }, hash{} - {} - - /** - * @brief Constructs a hashed string from an array of const characters. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * basic_hashed_string hs{"my.png"}; - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param curr Human-readable identifer. - */ - template - constexpr basic_hashed_string(const value_type(&curr)[N]) ENTT_NOEXCEPT - : str{ curr }, hash{ helper(curr) } - {} - - /** - * @brief Explicit constructor on purpose to avoid constructing a hashed - * string directly from a `const value_type *`. - * @param wrapper Helps achieving the purpose by relying on overloading. - */ - explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT - : str{ wrapper.str }, hash{ helper(wrapper.str) } - {} - - /** - * @brief Returns the human-readable representation of a hashed string. - * @return The string used to initialize the instance. - */ - constexpr const value_type* data() const ENTT_NOEXCEPT { - return str; - } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr hash_type value() const ENTT_NOEXCEPT { - return hash; - } - - /*! @copydoc data */ - constexpr operator const value_type* () const ENTT_NOEXCEPT { return data(); } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr operator hash_type() const ENTT_NOEXCEPT { return value(); } - - /** - * @brief Compares two hashed strings. - * @param other Hashed string with which to compare. - * @return True if the two hashed strings are identical, false otherwise. - */ - constexpr bool operator==(const basic_hashed_string& other) const ENTT_NOEXCEPT { - return hash == other.hash; - } - - private: - const value_type* str; - hash_type hash; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the character type of the hashed string directly from a - * human-readable identifer provided to the constructor. - * - * @tparam Char Character type. - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - */ - template - basic_hashed_string(const Char(&str)[N]) ENTT_NOEXCEPT - ->basic_hashed_string; - - - /** - * @brief Compares two hashed strings. - * @tparam Char Character type. - * @param lhs A valid hashed string. - * @param rhs A valid hashed string. - * @return True if the two hashed strings are identical, false otherwise. - */ - template - constexpr bool operator!=(const basic_hashed_string& lhs, const basic_hashed_string& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - /*! @brief Aliases for common character types. */ - using hashed_string = basic_hashed_string; - - - /*! @brief Aliases for common character types. */ - using hashed_wstring = basic_hashed_string; - - -} - - -/** - * @brief User defined literal for hashed strings. - * @param str The literal without its suffix. - * @return A properly initialized hashed string. - */ -constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_string{ str }; -} - - -/** - * @brief User defined literal for hashed wstrings. - * @param str The literal without its suffix. - * @return A properly initialized hashed wstring. - */ -constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_wstring{ str }; -} - - -#endif - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - struct ENTT_API type_index { - static id_type next() ENTT_NOEXCEPT { - static ENTT_MAYBE_ATOMIC(id_type) value {}; - return value++; - } - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Type index. - * @tparam Type Type for which to generate a sequential identifier. - */ - template - struct ENTT_API type_index { - /** - * @brief Returns the sequential identifier of a given type. - * @return The sequential identifier of a given type. - */ - static id_type value() ENTT_NOEXCEPT { - static const id_type value = internal::type_index::next(); - return value; - } - }; - - - /** - * @brief Provides the member constant `value` to true if a given type is - * indexable, false otherwise. - * @tparam Type Potentially indexable type. - */ - template - struct has_type_index : std::false_type {}; - - - /*! @brief has_type_index */ - template - struct has_type_index::value())>> : std::true_type {}; - - - /** - * @brief Helper variable template. - * @tparam Type Potentially indexable type. - */ - template - inline constexpr bool has_type_index_v = has_type_index::value; - - - /** - * @brief Type info. - * @tparam Type Type for which to generate information. - */ - template - struct ENTT_API type_info { - /** - * @brief Returns the numeric representation of a given type. - * @return The numeric representation of the given type. - */ -#if defined ENTT_PRETTY_FUNCTION - static ENTT_PRETTY_FUNCTION_CONSTEXPR() id_type id() ENTT_NOEXCEPT { - ENTT_PRETTY_FUNCTION_CONSTEXPR(static const) auto value = entt::hashed_string::value(ENTT_PRETTY_FUNCTION); - return value; - } -#else - static id_type id() ENTT_NOEXCEPT { - return type_index::value(); - } -#endif - }; - - -} - - -#endif - -// #include "../core/type_traits.hpp" -#ifndef ENTT_CORE_TYPE_TRAITS_HPP -#define ENTT_CORE_TYPE_TRAITS_HPP - - -#include -#include -#include -// #include "../config/config.h" - -// #include "hashed_string.hpp" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Wraps a static constant. - * @tparam Value A static constant. - */ - template - using integral_constant = std::integral_constant; - - - /** - * @brief Alias template to ease the creation of named values. - * @tparam Value A constant value at least convertible to `id_type`. - */ - template - using tag = integral_constant; - - - /** - * @brief Utility class to disambiguate overloaded functions. - * @tparam N Number of choices available. - */ - template - struct choice_t - // Unfortunately, doxygen cannot parse such a construct. - /*! @cond TURN_OFF_DOXYGEN */ - : choice_t - /*! @endcond TURN_OFF_DOXYGEN */ - {}; - - - /*! @copybrief choice_t */ - template<> - struct choice_t<0> {}; - - - /** - * @brief Variable template for the choice trick. - * @tparam N Number of choices available. - */ - template - inline constexpr choice_t choice{}; - - - /*! @brief A class to use to push around lists of types, nothing more. */ - template - struct type_list {}; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_size; - - - /** - * @brief Compile-time number of elements in a type list. - * @tparam Type Types provided by the type list. - */ - template - struct type_list_size> - : std::integral_constant - {}; - - - /** - * @brief Helper variable template. - * @tparam List Type list. - */ - template - inline constexpr auto type_list_size_v = type_list_size::value; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_cat; - - - /*! @brief Concatenates multiple type lists. */ - template<> - struct type_list_cat<> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = type_list<>; - }; - - - /** - * @brief Concatenates multiple type lists. - * @tparam Type Types provided by the first type list. - * @tparam Other Types provided by the second type list. - * @tparam List Other type lists, if any. - */ - template - struct type_list_cat, type_list, List...> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = typename type_list_cat, List...>::type; - }; - - - /** - * @brief Concatenates multiple type lists. - * @tparam Type Types provided by the type list. - */ - template - struct type_list_cat> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = type_list; - }; - - - /** - * @brief Helper type. - * @tparam List Type lists to concatenate. - */ - template - using type_list_cat_t = typename type_list_cat::type; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_unique; - - - /** - * @brief Removes duplicates types from a type list. - * @tparam Type One of the types provided by the given type list. - * @tparam Other The other types provided by the given type list. - */ - template - struct type_list_unique> { - /*! @brief A type list without duplicate types. */ - using type = std::conditional_t< - std::disjunction_v...>, - typename type_list_unique>::type, - type_list_cat_t, typename type_list_unique>::type> - >; - }; - - - /*! @brief Removes duplicates types from a type list. */ - template<> - struct type_list_unique> { - /*! @brief A type list without duplicate types. */ - using type = type_list<>; - }; - - - /** - * @brief Helper type. - * @tparam Type A type list. - */ - template - using type_list_unique_t = typename type_list_unique::type; - - - /** - * @brief Provides the member constant `value` to true if a given type is - * equality comparable, false otherwise. - * @tparam Type Potentially equality comparable type. - */ - template> - struct is_equality_comparable : std::false_type {}; - - - /*! @copydoc is_equality_comparable */ - template - struct is_equality_comparable() == std::declval())>> : std::true_type {}; - - - /** - * @brief Helper variable template. - * @tparam Type Potentially equality comparable type. - */ - template - inline constexpr auto is_equality_comparable_v = is_equality_comparable::value; - - - /** - * @brief Extracts the class of a non-static member object or function. - * @tparam Member A pointer to a non-static member object or function. - */ - template - class member_class { - static_assert(std::is_member_pointer_v); - - template - static Class* clazz(Ret(Class::*)(Args...)); - - template - static Class* clazz(Ret(Class::*)(Args...) const); - - template - static Class* clazz(Type Class::*); - - public: - /*! @brief The class of the given non-static member object or function. */ - using type = std::remove_pointer_t()))>; - }; - - - /** - * @brief Helper type. - * @tparam Member A pointer to a non-static member object or function. - */ - template - using member_class_t = typename member_class::type; - - -} - - -/** - * @brief Defines an enum class to use for opaque identifiers and a dedicate - * `to_integer` function to convert the identifiers to their underlying type. - * @param clazz The name to use for the enum class. - * @param type The underlying type for the enum class. - */ -#define ENTT_OPAQUE_TYPE(clazz, type)\ - enum class clazz: type {};\ - constexpr auto to_integral(const clazz id) ENTT_NOEXCEPT {\ - return static_cast>(id);\ - }\ - static_assert(true) - - -#endif - - // #include "../core/utility.hpp" -#ifndef ENTT_CORE_UTILITY_HPP -#define ENTT_CORE_UTILITY_HPP - - -#include -// #include "../config/config.h" - - - -namespace entt { - - - /*! @brief Identity function object (waiting for C++20). */ - struct identity { - /** - * @brief Returns its argument unchanged. - * @tparam Type Type of the argument. - * @param value The actual argument. - * @return The submitted value as-is. - */ - template - constexpr Type&& operator()(Type&& value) const ENTT_NOEXCEPT { - return std::forward(value); - } - }; - - - /** - * @brief Constant utility to disambiguate overloaded members of a class. - * @tparam Type Type of the desired overload. - * @tparam Class Type of class to which the member belongs. - * @param member A valid pointer to a member. - * @return Pointer to the member. - */ - template - constexpr auto overload(Type Class::* member) ENTT_NOEXCEPT { return member; } - - - /** - * @brief Constant utility to disambiguate overloaded functions. - * @tparam Func Function type of the desired overload. - * @param func A valid pointer to a function. - * @return Pointer to the function. - */ - template - constexpr auto overload(Func* func) ENTT_NOEXCEPT { return func; } - - - /** - * @brief Helper type for visitors. - * @tparam Func Types of function objects. - */ - template - struct overloaded : Func... { - using Func::operator()...; - }; - - - /** - * @brief Deduction guide. - * @tparam Func Types of function objects. - */ - template - overloaded(Func...)->overloaded; - - - /** - * @brief Basic implementation of a y-combinator. - * @tparam Func Type of a potentially recursive function. - */ - template - struct y_combinator { - /** - * @brief Constructs a y-combinator from a given function. - * @param recursive A potentially recursive function. - */ - y_combinator(Func recursive) : - func{ std::move(recursive) } - {} - - /** - * @brief Invokes a y-combinator and therefore its underlying function. - * @tparam Args Types of arguments to use to invoke the underlying function. - * @param args Parameters to use to invoke the underlying function. - * @return Return value of the underlying function, if any. - */ - template - decltype(auto) operator()(Args &&... args) const { - return func(*this, std::forward(args)...); - } - - /*! @copydoc operator()() */ - template - decltype(auto) operator()(Args &&... args) { - return func(*this, std::forward(args)...); - } - - private: - Func func; - }; - - -} - - -#endif - -// #include "meta.hpp" -#ifndef ENTT_META_META_HPP -#define ENTT_META_META_HPP - - -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/fwd.hpp" - -// #include "../core/type_info.hpp" - -// #include "../core/type_traits.hpp" - - - -namespace entt { - - - class meta_any; - class meta_type; - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - struct meta_type_node; - - - struct meta_prop_node { - meta_prop_node* next; - meta_any(* const key)(); - meta_any(* const value)(); - }; - - - struct meta_base_node { - meta_type_node* const parent; - meta_base_node* next; - meta_type_node* (* const type)() ENTT_NOEXCEPT; - void* (* const cast)(void*) ENTT_NOEXCEPT; - }; - - - struct meta_conv_node { - meta_type_node* const parent; - meta_conv_node* next; - meta_type_node* (* const type)() ENTT_NOEXCEPT; - meta_any(* const conv)(const void*); - }; - - - struct meta_ctor_node { - using size_type = std::size_t; - meta_type_node* const parent; - meta_ctor_node* next; - meta_prop_node* prop; - const size_type size; - meta_type_node* (* const arg)(size_type) ENTT_NOEXCEPT; - meta_any(* const invoke)(meta_any* const); - }; - - - struct meta_dtor_node { - meta_type_node* const parent; - void(* const invoke)(void*); - }; - - - struct meta_data_node { - id_type id; - meta_type_node* const parent; - meta_data_node* next; - meta_prop_node* prop; - const bool is_const; - const bool is_static; - meta_type_node* (* const type)() ENTT_NOEXCEPT; - bool(* const set)(meta_any, meta_any, meta_any); - meta_any(* const get)(meta_any, meta_any); - }; - - - struct meta_func_node { - using size_type = std::size_t; - id_type id; - meta_type_node* const parent; - meta_func_node* next; - meta_prop_node* prop; - const size_type size; - const bool is_const; - const bool is_static; - meta_type_node* (* const ret)() ENTT_NOEXCEPT; - meta_type_node* (* const arg)(size_type) ENTT_NOEXCEPT; - meta_any(* const invoke)(meta_any, meta_any*); - }; - - - struct meta_type_node { - using size_type = std::size_t; - const id_type type_id; - id_type id; - meta_type_node* next; - meta_prop_node* prop; - const bool is_void; - const bool is_integral; - const bool is_floating_point; - const bool is_array; - const bool is_enum; - const bool is_union; - const bool is_class; - const bool is_pointer; - const bool is_function_pointer; - const bool is_member_object_pointer; - const bool is_member_function_pointer; - const size_type extent; - bool(* const compare)(const void*, const void*); - meta_type_node* (* const remove_pointer)() ENTT_NOEXCEPT; - meta_type_node* (* const remove_extent)() ENTT_NOEXCEPT; - meta_base_node* base{ nullptr }; - meta_conv_node* conv{ nullptr }; - meta_ctor_node* ctor{ nullptr }; - meta_dtor_node* dtor{ nullptr }; - meta_data_node* data{ nullptr }; - meta_func_node* func{ nullptr }; - }; - - - template - void visit(Op& op, Node* node) { - while (node) { - op(Type{ node }); - node = node->next; - } - } - - - template - void visit(Op& op, const internal::meta_type_node* node) { - if (node) { - internal::visit(op, node->*Member); - auto* next = node->base; - - while (next) { - visit(op, next->type()); - next = next->next; - } - } - } - - - template - auto find_if(const Op& op, Node* node) { - while (node && !op(node)) { - node = node->next; - } - - return node; - } - - - template - auto find_if(const Op& op, const meta_type_node* node) - -> decltype(find_if(op, node->*Member)) { - decltype(find_if(op, node->*Member)) ret = nullptr; - - if (node) { - ret = find_if(op, node->*Member); - auto* next = node->base; - - while (next && !ret) { - ret = find_if(op, next->type()); - next = next->next; - } - } - - return ret; - } - - - template - bool compare(const void* lhs, const void* rhs) { - if constexpr (!std::is_function_v && is_equality_comparable_v) { - return *static_cast(lhs) == *static_cast(rhs); - } - else { - return lhs == rhs; - } - } - - - struct ENTT_API meta_context { - inline static meta_type_node* local = nullptr; - inline static meta_type_node** global = &local; - - static void detach(const meta_type_node* node) ENTT_NOEXCEPT { - auto** it = global; - - while (*it && *it != node) { - it = &(*it)->next; - } - - if (*it) { - *it = (*it)->next; - } - } - }; - - - template - struct ENTT_API meta_node { - static_assert(std::is_same_v>>); - - static meta_type_node* resolve() ENTT_NOEXCEPT { - static meta_type_node node{ - type_info::id(), - {}, - nullptr, - nullptr, - std::is_void_v, - std::is_integral_v, - std::is_floating_point_v, - std::is_array_v, - std::is_enum_v, - std::is_union_v, - std::is_class_v, - std::is_pointer_v, - std::is_pointer_v && std::is_function_v>, - std::is_member_object_pointer_v, - std::is_member_function_pointer_v, - std::extent_v, - &compare, // workaround for an issue with VS2017 - &meta_node>>::resolve, - &meta_node>>::resolve - }; - - return &node; - } - }; - - - template - struct meta_info : meta_node>...> {}; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /*! @brief Opaque container for a meta context. */ - struct meta_ctx { - /** - * @brief Binds the meta system to the given context. - * @param other A valid context to which to bind. - */ - static void bind(meta_ctx other) ENTT_NOEXCEPT { - internal::meta_context::global = other.ctx; - } - - private: - internal::meta_type_node** ctx{ &internal::meta_context::local }; - }; - - - /** - * @brief Opaque container for values of any type. - * - * This class uses a technique called small buffer optimization (SBO) to get rid - * of memory allocations if possible. This should improve overall performance. - */ - class meta_any { - using storage_type = std::aligned_storage_t; - using copy_fn_type = void(meta_any&, const meta_any&); - using steal_fn_type = void(meta_any&, meta_any&); - using destroy_fn_type = void(meta_any&); - - template> - struct type_traits { - template - static void instance(meta_any& any, Args &&... args) { - any.instance = new Type{ std::forward(args)... }; - new (&any.storage) Type* { static_cast(any.instance) }; - } - - static void destroy(meta_any& any) { - const auto* const node = internal::meta_info::resolve(); - if (node->dtor) { node->dtor->invoke(any.instance); } - delete static_cast(any.instance); - } - - static void copy(meta_any& to, const meta_any& from) { - auto* instance = new Type{ *static_cast(from.instance) }; - new (&to.storage) Type* { instance }; - to.instance = instance; - } - - static void steal(meta_any& to, meta_any& from) { - new (&to.storage) Type* { static_cast(from.instance) }; - to.instance = from.instance; - } - }; - - template - struct type_traits>> { - template - static void instance(meta_any& any, Args &&... args) { - any.instance = new (&any.storage) Type{ std::forward(args)... }; - } - - static void destroy(meta_any& any) { - const auto* const node = internal::meta_info::resolve(); - if (node->dtor) { node->dtor->invoke(any.instance); } - static_cast(any.instance)->~Type(); - } - - static void copy(meta_any& to, const meta_any& from) { - to.instance = new (&to.storage) Type{ *static_cast(from.instance) }; - } - - static void steal(meta_any& to, meta_any& from) { - to.instance = new (&to.storage) Type{ std::move(*static_cast(from.instance)) }; - destroy(from); - } - }; - - meta_any(const internal::meta_type_node* curr, void* ref) ENTT_NOEXCEPT - : meta_any{} - { - node = curr; - instance = ref; - } - - public: - /*! @brief Default constructor. */ - meta_any() ENTT_NOEXCEPT - : storage{}, - instance{}, - node{}, - destroy_fn{}, - copy_fn{}, - steal_fn{} - {} - - /** - * @brief Constructs a meta any by directly initializing the new object. - * @tparam Type Type of object to use to initialize the container. - * @tparam Args Types of arguments to use to construct the new instance. - * @param args Parameters to use to construct the instance. - */ - template - explicit meta_any(std::in_place_type_t, [[maybe_unused]] Args &&... args) - : meta_any{} - { - node = internal::meta_info::resolve(); - - if constexpr (!std::is_void_v) { - using traits_type = type_traits>>; - traits_type::instance(*this, std::forward(args)...); - destroy_fn = &traits_type::destroy; - copy_fn = &traits_type::copy; - steal_fn = &traits_type::steal; - } - } - - /** - * @brief Constructs a meta any that holds an unmanaged object. - * @tparam Type Type of object to use to initialize the container. - * @param value An instance of an object to use to initialize the container. - */ - template - meta_any(std::reference_wrapper value) - : meta_any{ internal::meta_info::resolve(), &value.get() } - {} - - /** - * @brief Constructs a meta any from a given value. - * @tparam Type Type of object to use to initialize the container. - * @param value An instance of an object to use to initialize the container. - */ - template>, meta_any>>> - meta_any(Type&& value) - : meta_any{ std::in_place_type>>, std::forward(value) } - {} - - /** - * @brief Copy constructor. - * @param other The instance to copy from. - */ - meta_any(const meta_any& other) - : meta_any{} - { - node = other.node; - (other.copy_fn ? other.copy_fn : [](meta_any& to, const meta_any& from) { to.instance = from.instance; })(*this, other); - destroy_fn = other.destroy_fn; - copy_fn = other.copy_fn; - steal_fn = other.steal_fn; - } - - /** - * @brief Move constructor. - * - * After move construction, instances that have been moved from are placed - * in a valid but unspecified state. - * - * @param other The instance to move from. - */ - meta_any(meta_any&& other) - : meta_any{} - { - swap(*this, other); - } - - /*! @brief Frees the internal storage, whatever it means. */ - ~meta_any() { - if (destroy_fn) { - destroy_fn(*this); - } - } - - /** - * @brief Assignment operator. - * @tparam Type Type of object to use to initialize the container. - * @param value An instance of an object to use to initialize the container. - * @return This meta any object. - */ - template - meta_any& operator=(Type&& value) { - return (*this = meta_any{ std::forward(value) }); - } - - /** - * @brief Assignment operator. - * @param other The instance to assign from. - * @return This meta any object. - */ - meta_any& operator=(meta_any other) { - swap(other, *this); - return *this; - } - - /** - * @brief Returns the meta type of the underlying object. - * @return The meta type of the underlying object, if any. - */ - inline meta_type type() const ENTT_NOEXCEPT; - - /** - * @brief Returns an opaque pointer to the contained instance. - * @return An opaque pointer the contained instance, if any. - */ - const void* data() const ENTT_NOEXCEPT { - return instance; - } - - /*! @copydoc data */ - void* data() ENTT_NOEXCEPT { - return const_cast(std::as_const(*this).data()); - } - - /** - * @brief Tries to cast an instance to a given type. - * @tparam Type Type to which to cast the instance. - * @return A (possibly null) pointer to the contained instance. - */ - template - const Type* try_cast() const { - void* ret = nullptr; - - if (const auto type_id = internal::meta_info::resolve()->type_id; node && node->type_id == type_id) { - ret = instance; - } - else if (const auto* base = internal::find_if<&internal::meta_type_node::base>([type_id](const auto* curr) { return curr->type()->type_id == type_id; }, node); base) { - ret = base->cast(instance); - } - - return static_cast(ret); - } - - /*! @copydoc try_cast */ - template - Type* try_cast() { - return const_cast(std::as_const(*this).try_cast()); - } - - /** - * @brief Tries to cast an instance to a given type. - * - * The type of the instance must be such that the cast is possible. - * - * @warning - * Attempting to perform a cast that isn't viable results in undefined - * behavior.
- * An assertion will abort the execution at runtime in debug mode in case - * the cast is not feasible. - * - * @tparam Type Type to which to cast the instance. - * @return A reference to the contained instance. - */ - template - const Type& cast() const { - auto* const actual = try_cast(); - ENTT_ASSERT(actual); - return *actual; - } - - /*! @copydoc cast */ - template - Type& cast() { - return const_cast(std::as_const(*this).cast()); - } - - /** - * @brief Tries to convert an instance to a given type and returns it. - * @tparam Type Type to which to convert the instance. - * @return A valid meta any object if the conversion is possible, an invalid - * one otherwise. - */ - template - meta_any convert() const { - meta_any any{}; - - if (const auto type_id = internal::meta_info::resolve()->type_id; node && node->type_id == type_id) { - any = *this; - } - else if (const auto* const conv = internal::find_if<&internal::meta_type_node::conv>([type_id](const auto* curr) { return curr->type()->type_id == type_id; }, node); conv) { - any = conv->conv(instance); - } - - return any; - } - - /** - * @brief Tries to convert an instance to a given type. - * @tparam Type Type to which to convert the instance. - * @return True if the conversion is possible, false otherwise. - */ - template - bool convert() { - bool valid = (node && node->type_id == internal::meta_info::resolve()->type_id); - - if (!valid) { - if (auto any = std::as_const(*this).convert(); any) { - swap(any, *this); - valid = true; - } - } - - return valid; - } - - /** - * @brief Replaces the contained object by initializing a new instance - * directly. - * @tparam Type Type of object to use to initialize the container. - * @tparam Args Types of arguments to use to construct the new instance. - * @param args Parameters to use to construct the instance. - */ - template - void emplace(Args &&... args) { - *this = meta_any{ std::in_place_type_t{}, std::forward(args)... }; - } - - /** - * @brief Aliasing constructor. - * @return A meta any that shares a reference to an unmanaged object. - */ - meta_any ref() const ENTT_NOEXCEPT { - return meta_any{ node, instance }; - } - - /** - * @brief Indirection operator for aliasing construction. - * @return A meta any that shares a reference to an unmanaged object. - */ - meta_any operator *() const ENTT_NOEXCEPT { - return ref(); - } - - /** - * @brief Returns false if a container is empty, true otherwise. - * @return False if the container is empty, true otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return !(node == nullptr); - } - - /** - * @brief Checks if two containers differ in their content. - * @param other Container with which to compare. - * @return False if the two containers differ in their content, true - * otherwise. - */ - bool operator==(const meta_any& other) const { - return (!node && !other.node) || (node && other.node && node->type_id == other.node->type_id && node->compare(instance, other.instance)); - } - - /** - * @brief Swaps two meta any objects. - * @param lhs A valid meta any object. - * @param rhs A valid meta any object. - */ - friend void swap(meta_any& lhs, meta_any& rhs) { - if (lhs.steal_fn && rhs.steal_fn) { - meta_any buffer{}; - lhs.steal_fn(buffer, lhs); - rhs.steal_fn(lhs, rhs); - lhs.steal_fn(rhs, buffer); - } - else if (lhs.steal_fn) { - lhs.steal_fn(rhs, lhs); - } - else if (rhs.steal_fn) { - rhs.steal_fn(lhs, rhs); - } - else { - std::swap(lhs.instance, rhs.instance); - } - - std::swap(lhs.node, rhs.node); - std::swap(lhs.destroy_fn, rhs.destroy_fn); - std::swap(lhs.copy_fn, rhs.copy_fn); - std::swap(lhs.steal_fn, rhs.steal_fn); - } - - private: - storage_type storage; - void* instance; - const internal::meta_type_node* node; - destroy_fn_type* destroy_fn; - copy_fn_type* copy_fn; - steal_fn_type* steal_fn; - }; - - - /** - * @brief Opaque pointers to instances of any type. - * - * A handle doesn't perform copies and isn't responsible for the contained - * object. It doesn't prolong the lifetime of the pointed instance.
- * Handles are used to generate meta references to actual objects when needed. - */ - struct meta_handle { - /*! @brief Default constructor. */ - meta_handle() - : any{} - {} - - /** - * @brief Creates a handle that points to an unmanaged object. - * @tparam Type Type of object to use to initialize the container. - * @param value An instance of an object to use to initialize the container. - */ - template - meta_handle(Type&& value) ENTT_NOEXCEPT - : meta_handle{} - { - if constexpr (std::is_same_v>, meta_any>) { - any = *value; - } - else { - static_assert(std::is_lvalue_reference_v); - any = std::ref(value); - } - } - - /*! @copydoc meta_any::operator* */ - meta_any operator *() const { - return any; - } - - private: - meta_any any; - }; - - - /** - * @brief Checks if two containers differ in their content. - * @param lhs A meta any object, either empty or not. - * @param rhs A meta any object, either empty or not. - * @return True if the two containers differ in their content, false otherwise. - */ - inline bool operator!=(const meta_any& lhs, const meta_any& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - /*! @brief Opaque container for meta properties of any type. */ - struct meta_prop { - /** - * @brief Constructs an instance from a given node. - * @param curr The underlying node with which to construct the instance. - */ - meta_prop(const internal::meta_prop_node* curr = nullptr) ENTT_NOEXCEPT - : node{ curr } - {} - - /** - * @brief Returns the stored key. - * @return A meta any containing the key stored with the given property. - */ - meta_any key() const { - return node->key(); - } - - /** - * @brief Returns the stored value. - * @return A meta any containing the value stored with the given property. - */ - meta_any value() const { - return node->value(); - } - - /** - * @brief Returns true if a meta object is valid, false otherwise. - * @return True if the meta object is valid, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return !(node == nullptr); - } - - private: - const internal::meta_prop_node* node; - }; - - - /*! @brief Opaque container for meta base classes. */ - struct meta_base { - /*! @copydoc meta_prop::meta_prop */ - meta_base(const internal::meta_base_node* curr = nullptr) ENTT_NOEXCEPT - : node{ curr } - {} - - /** - * @brief Returns the meta type to which a meta object belongs. - * @return The meta type to which the meta object belongs. - */ - inline meta_type parent() const ENTT_NOEXCEPT; - - /*! @copydoc meta_any::type */ - inline meta_type type() const ENTT_NOEXCEPT; - - /** - * @brief Casts an instance from a parent type to a base type. - * @param instance The instance to cast. - * @return An opaque pointer to the base type. - */ - void* cast(void* instance) const ENTT_NOEXCEPT { - return node->cast(instance); - } - - /** - * @brief Returns true if a meta object is valid, false otherwise. - * @return True if the meta object is valid, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return !(node == nullptr); - } - - private: - const internal::meta_base_node* node; - }; - - - /*! @brief Opaque container for meta conversion functions. */ - struct meta_conv { - /*! @copydoc meta_prop::meta_prop */ - meta_conv(const internal::meta_conv_node* curr = nullptr) ENTT_NOEXCEPT - : node{ curr } - {} - - /*! @copydoc meta_base::parent */ - inline meta_type parent() const ENTT_NOEXCEPT; - - /*! @copydoc meta_any::type */ - inline meta_type type() const ENTT_NOEXCEPT; - - /** - * @brief Converts an instance to a given type. - * @param instance The instance to convert. - * @return An opaque pointer to the instance to convert. - */ - meta_any convert(const void* instance) const { - return node->conv(instance); - } - - /** - * @brief Returns true if a meta object is valid, false otherwise. - * @return True if the meta object is valid, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return !(node == nullptr); - } - - private: - const internal::meta_conv_node* node; - }; - - - /*! @brief Opaque container for meta constructors. */ - struct meta_ctor { - /*! @brief Unsigned integer type. */ - using size_type = typename internal::meta_ctor_node::size_type; - - /*! @copydoc meta_prop::meta_prop */ - meta_ctor(const internal::meta_ctor_node* curr = nullptr) ENTT_NOEXCEPT - : node{ curr } - {} - - /*! @copydoc meta_base::parent */ - inline meta_type parent() const ENTT_NOEXCEPT; - - /** - * @brief Returns the number of arguments accepted by a meta constructor. - * @return The number of arguments accepted by the meta constructor. - */ - size_type size() const ENTT_NOEXCEPT { - return node->size; - } - - /** - * @brief Returns the meta type of the i-th argument of a meta constructor. - * @param index The index of the argument of which to return the meta type. - * @return The meta type of the i-th argument of a meta constructor, if any. - */ - meta_type arg(size_type index) const ENTT_NOEXCEPT; - - /** - * @brief Creates an instance of the underlying type, if possible. - * - * To create a valid instance, the parameters must be such that a cast or - * conversion to the required types is possible. Otherwise, an empty and - * thus invalid container is returned. - * - * @tparam Args Types of arguments to use to construct the instance. - * @param args Parameters to use to construct the instance. - * @return A meta any containing the new instance, if any. - */ - template - meta_any invoke([[maybe_unused]] Args &&... args) const { - if constexpr (sizeof...(Args) == 0) { - return sizeof...(Args) == size() ? node->invoke(nullptr) : meta_any{}; - } - else { - meta_any arguments[]{ std::forward(args)... }; - return sizeof...(Args) == size() ? node->invoke(arguments) : meta_any{}; - } - } - - /** - * @brief Iterates all the properties assigned to a meta constructor. - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - std::enable_if_t, void> - prop(Op op) const { - internal::visit(op, node->prop); - } - - /** - * @brief Returns the property associated with a given key. - * @param key The key to use to search for a property. - * @return The property associated with the given key, if any. - */ - meta_prop prop(meta_any key) const { - return internal::find_if([key = std::move(key)](const auto* curr) { - return curr->key() == key; - }, node->prop); - } - - /** - * @brief Returns true if a meta object is valid, false otherwise. - * @return True if the meta object is valid, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return !(node == nullptr); - } - - private: - const internal::meta_ctor_node* node; - }; - - - /*! @brief Opaque container for meta data. */ - struct meta_data { - /*! @copydoc meta_prop::meta_prop */ - meta_data(const internal::meta_data_node* curr = nullptr) ENTT_NOEXCEPT - : node{ curr } - {} - - /*! @copydoc meta_type::id */ - id_type id() const ENTT_NOEXCEPT { - return node->id; - } - - /*! @copydoc id */ - [[deprecated("use ::id instead")]] - id_type alias() const ENTT_NOEXCEPT { - return id(); - } - - /*! @copydoc meta_base::parent */ - inline meta_type parent() const ENTT_NOEXCEPT; - - /** - * @brief Indicates whether a given meta data is constant or not. - * @return True if the meta data is constant, false otherwise. - */ - bool is_const() const ENTT_NOEXCEPT { - return node->is_const; - } - - /** - * @brief Indicates whether a given meta data is static or not. - * @return True if the meta data is static, false otherwise. - */ - bool is_static() const ENTT_NOEXCEPT { - return node->is_static; - } - - /*! @copydoc meta_any::type */ - inline meta_type type() const ENTT_NOEXCEPT; - - /** - * @brief Sets the value of the variable enclosed by a given meta type. - * - * It must be possible to cast the instance to the parent type of the meta - * data. Otherwise, invoking the setter results in an undefined - * behavior.
- * The type of the value must be such that a cast or conversion to the type - * of the variable is possible. Otherwise, invoking the setter does nothing. - * - * @tparam Type Type of value to assign. - * @param instance An opaque instance of the underlying type. - * @param value Parameter to use to set the underlying variable. - * @return True in case of success, false otherwise. - */ - template - bool set(meta_handle instance, Type&& value) const { - return node->set(*instance, {}, std::forward(value)); - } - - /** - * @brief Sets the i-th element of an array enclosed by a given meta type. - * - * It must be possible to cast the instance to the parent type of the meta - * data. Otherwise, invoking the setter results in an undefined - * behavior.
- * The type of the value must be such that a cast or conversion to the array - * type is possible. Otherwise, invoking the setter does nothing. - * - * @tparam Type Type of value to assign. - * @param instance An opaque instance of the underlying type. - * @param index Position of the underlying element to set. - * @param value Parameter to use to set the underlying element. - * @return True in case of success, false otherwise. - */ - template - bool set(meta_handle instance, std::size_t index, Type&& value) const { - ENTT_ASSERT(index < node->type()->extent); - return node->set(*instance, index, std::forward(value)); - } - - /** - * @brief Gets the value of the variable enclosed by a given meta type. - * - * It must be possible to cast the instance to the parent type of the meta - * data. Otherwise, invoking the getter results in an undefined behavior. - * - * @param instance An opaque instance of the underlying type. - * @return A meta any containing the value of the underlying variable. - */ - meta_any get(meta_handle instance) const { - return node->get(*instance, {}); - } - - /** - * @brief Gets the i-th element of an array enclosed by a given meta type. - * - * It must be possible to cast the instance to the parent type of the meta - * data. Otherwise, invoking the getter results in an undefined behavior. - * - * @param instance An opaque instance of the underlying type. - * @param index Position of the underlying element to get. - * @return A meta any containing the value of the underlying element. - */ - meta_any get(meta_handle instance, std::size_t index) const { - ENTT_ASSERT(index < node->type()->extent); - return node->get(*instance, index); - } - - /** - * @brief Iterates all the properties assigned to a meta data. - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - std::enable_if_t, void> - prop(Op op) const { - internal::visit(op, node->prop); - } - - /** - * @brief Returns the property associated with a given key. - * @param key The key to use to search for a property. - * @return The property associated with the given key, if any. - */ - meta_prop prop(meta_any key) const { - return internal::find_if([key = std::move(key)](const auto* curr) { - return curr->key() == key; - }, node->prop); - } - - /** - * @brief Returns true if a meta object is valid, false otherwise. - * @return True if the meta object is valid, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return !(node == nullptr); - } - - private: - const internal::meta_data_node* node; - }; - - - /*! @brief Opaque container for meta functions. */ - struct meta_func { - /*! @brief Unsigned integer type. */ - using size_type = typename internal::meta_func_node::size_type; - - /*! @copydoc meta_prop::meta_prop */ - meta_func(const internal::meta_func_node* curr = nullptr) ENTT_NOEXCEPT - : node{ curr } - {} - - /*! @copydoc meta_type::id */ - id_type id() const ENTT_NOEXCEPT { - return node->id; - } - - /*! @copydoc id */ - [[deprecated("use ::id instead")]] - id_type alias() const ENTT_NOEXCEPT { - return id(); - } - - /*! @copydoc meta_base::parent */ - inline meta_type parent() const ENTT_NOEXCEPT; - - /** - * @brief Returns the number of arguments accepted by a meta function. - * @return The number of arguments accepted by the meta function. - */ - size_type size() const ENTT_NOEXCEPT { - return node->size; - } - - /** - * @brief Indicates whether a given meta function is constant or not. - * @return True if the meta function is constant, false otherwise. - */ - bool is_const() const ENTT_NOEXCEPT { - return node->is_const; - } - - /** - * @brief Indicates whether a given meta function is static or not. - * @return True if the meta function is static, false otherwise. - */ - bool is_static() const ENTT_NOEXCEPT { - return node->is_static; - } - - /** - * @brief Returns the meta type of the return type of a meta function. - * @return The meta type of the return type of the meta function. - */ - inline meta_type ret() const ENTT_NOEXCEPT; - - /** - * @brief Returns the meta type of the i-th argument of a meta function. - * @param index The index of the argument of which to return the meta type. - * @return The meta type of the i-th argument of a meta function, if any. - */ - inline meta_type arg(size_type index) const ENTT_NOEXCEPT; - - /** - * @brief Invokes the underlying function, if possible. - * - * To invoke a meta function, the parameters must be such that a cast or - * conversion to the required types is possible. Otherwise, an empty and - * thus invalid container is returned.
- * It must be possible to cast the instance to the parent type of the meta - * function. Otherwise, invoking the underlying function results in an - * undefined behavior. - * - * @tparam Args Types of arguments to use to invoke the function. - * @param instance An opaque instance of the underlying type. - * @param args Parameters to use to invoke the function. - * @return A meta any containing the returned value, if any. - */ - template - meta_any invoke(meta_handle instance, Args &&... args) const { - meta_any arguments[]{ *instance, std::forward(args)... }; - return sizeof...(Args) == size() ? node->invoke(arguments[0], &arguments[sizeof...(Args) != 0]) : meta_any{}; - } - - /** - * @brief Iterates all the properties assigned to a meta function. - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - std::enable_if_t, void> - prop(Op op) const { - internal::visit(op, node->prop); - } - - /** - * @brief Returns the property associated with a given key. - * @param key The key to use to search for a property. - * @return The property associated with the given key, if any. - */ - meta_prop prop(meta_any key) const { - return internal::find_if([key = std::move(key)](const auto* curr) { - return curr->key() == key; - }, node->prop); - } - - /** - * @brief Returns true if a meta object is valid, false otherwise. - * @return True if the meta object is valid, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return !(node == nullptr); - } - - private: - const internal::meta_func_node* node; - }; - - - /*! @brief Opaque container for meta types. */ - class meta_type { - template - auto ctor(std::index_sequence) const { - return internal::find_if([](const auto* candidate) { - return candidate->size == sizeof...(Args) && ([](auto* from, auto* to) { - return (from->type_id == to->type_id) - || internal::find_if<&internal::meta_type_node::base>([to](const auto* curr) { return curr->type()->type_id == to->type_id; }, from) - || internal::find_if<&internal::meta_type_node::conv>([to](const auto* curr) { return curr->type()->type_id == to->type_id; }, from); - }(internal::meta_info::resolve(), candidate->arg(Indexes)) && ...); - }, node->ctor); - } - - public: - /*! @brief Unsigned integer type. */ - using size_type = typename internal::meta_type_node::size_type; - - /*! @copydoc meta_prop::meta_prop */ - meta_type(const internal::meta_type_node* curr = nullptr) ENTT_NOEXCEPT - : node{ curr } - {} - - /** - * @brief Returns the type id of the underlying type. - * @return The type id of the underlying type. - */ - id_type type_id() const ENTT_NOEXCEPT { - return node->type_id; - } - - /** - * @brief Returns the identifier assigned to a given meta object. - * @return The identifier assigned to the meta object. - */ - id_type id() const ENTT_NOEXCEPT { - return node->id; - } - - /*! @copydoc id */ - [[deprecated("use ::id instead")]] - id_type alias() const ENTT_NOEXCEPT { - return id(); - } - - /** - * @brief Indicates whether a given meta type refers to void or not. - * @return True if the underlying type is void, false otherwise. - */ - bool is_void() const ENTT_NOEXCEPT { - return node->is_void; - } - - /** - * @brief Indicates whether a given meta type refers to an integral type or - * not. - * @return True if the underlying type is an integral type, false otherwise. - */ - bool is_integral() const ENTT_NOEXCEPT { - return node->is_integral; - } - - /** - * @brief Indicates whether a given meta type refers to a floating-point - * type or not. - * @return True if the underlying type is a floating-point type, false - * otherwise. - */ - bool is_floating_point() const ENTT_NOEXCEPT { - return node->is_floating_point; - } - - /** - * @brief Indicates whether a given meta type refers to an array type or - * not. - * @return True if the underlying type is an array type, false otherwise. - */ - bool is_array() const ENTT_NOEXCEPT { - return node->is_array; - } - - /** - * @brief Indicates whether a given meta type refers to an enum or not. - * @return True if the underlying type is an enum, false otherwise. - */ - bool is_enum() const ENTT_NOEXCEPT { - return node->is_enum; - } - - /** - * @brief Indicates whether a given meta type refers to an union or not. - * @return True if the underlying type is an union, false otherwise. - */ - bool is_union() const ENTT_NOEXCEPT { - return node->is_union; - } - - /** - * @brief Indicates whether a given meta type refers to a class or not. - * @return True if the underlying type is a class, false otherwise. - */ - bool is_class() const ENTT_NOEXCEPT { - return node->is_class; - } - - /** - * @brief Indicates whether a given meta type refers to a pointer or not. - * @return True if the underlying type is a pointer, false otherwise. - */ - bool is_pointer() const ENTT_NOEXCEPT { - return node->is_pointer; - } - - /** - * @brief Indicates whether a given meta type refers to a function pointer - * or not. - * @return True if the underlying type is a function pointer, false - * otherwise. - */ - bool is_function_pointer() const ENTT_NOEXCEPT { - return node->is_function_pointer; - } - - /** - * @brief Indicates whether a given meta type refers to a pointer to data - * member or not. - * @return True if the underlying type is a pointer to data member, false - * otherwise. - */ - bool is_member_object_pointer() const ENTT_NOEXCEPT { - return node->is_member_object_pointer; - } - - /** - * @brief Indicates whether a given meta type refers to a pointer to member - * function or not. - * @return True if the underlying type is a pointer to member function, - * false otherwise. - */ - bool is_member_function_pointer() const ENTT_NOEXCEPT { - return node->is_member_function_pointer; - } - - /** - * @brief If a given meta type refers to an array type, provides the number - * of elements of the array. - * @return The number of elements of the array if the underlying type is an - * array type, 0 otherwise. - */ - size_type extent() const ENTT_NOEXCEPT { - return node->extent; - } - - /** - * @brief Provides the meta type for which the pointer is defined. - * @return The meta type for which the pointer is defined or this meta type - * if it doesn't refer to a pointer type. - */ - meta_type remove_pointer() const ENTT_NOEXCEPT { - return node->remove_pointer(); - } - - /** - * @brief Provides the meta type for which the array is defined. - * @return The meta type for which the array is defined or this meta type - * if it doesn't refer to an array type. - */ - meta_type remove_extent() const ENTT_NOEXCEPT { - return node->remove_extent(); - } - - /** - * @brief Iterates all the meta bases of a meta type. - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - std::enable_if_t, void> - base(Op op) const { - internal::visit<&internal::meta_type_node::base, meta_base>(op, node); - } - - /** - * @brief Returns the meta base associated with a given identifier. - * @param id Unique identifier. - * @return The meta base associated with the given identifier, if any. - */ - meta_base base(const id_type id) const { - return internal::find_if<&internal::meta_type_node::base>([id](const auto* curr) { - return curr->type()->id == id; - }, node); - } - - /** - * @brief Iterates all the meta conversion functions of a meta type. - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - void conv(Op op) const { - internal::visit<&internal::meta_type_node::conv, meta_conv>(op, node); - } - - /** - * @brief Returns the meta conversion function associated with a given type. - * @tparam Type The type to use to search for a meta conversion function. - * @return The meta conversion function associated with the given type, if - * any. - */ - template - meta_conv conv() const { - return internal::find_if<&internal::meta_type_node::conv>([type_id = internal::meta_info::resolve()->type_id](const auto* curr) { - return curr->type()->type_id == type_id; - }, node); - } - - /** - * @brief Iterates all the meta constructors of a meta type. - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - void ctor(Op op) const { - internal::visit(op, node->ctor); - } - - /** - * @brief Returns the meta constructor that accepts a given list of types of - * arguments. - * @return The requested meta constructor, if any. - */ - template - meta_ctor ctor() const { - return ctor(std::index_sequence_for{}); - } - - /** - * @brief Iterates all the meta data of a meta type. - * - * The meta data of the base classes will also be returned, if any. - * - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - std::enable_if_t, void> - data(Op op) const { - internal::visit<&internal::meta_type_node::data, meta_data>(op, node); - } - - /** - * @brief Returns the meta data associated with a given identifier. - * - * The meta data of the base classes will also be visited, if any. - * - * @param id Unique identifier. - * @return The meta data associated with the given identifier, if any. - */ - meta_data data(const id_type id) const { - return internal::find_if<&internal::meta_type_node::data>([id](const auto* curr) { - return curr->id == id; - }, node); - } - - /** - * @brief Iterates all the meta functions of a meta type. - * - * The meta functions of the base classes will also be returned, if any. - * - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - std::enable_if_t, void> - func(Op op) const { - internal::visit<&internal::meta_type_node::func, meta_func>(op, node); - } - - /** - * @brief Returns the meta function associated with a given identifier. - * - * The meta functions of the base classes will also be visited, if any. - * - * @param id Unique identifier. - * @return The meta function associated with the given identifier, if any. - */ - meta_func func(const id_type id) const { - return internal::find_if<&internal::meta_type_node::func>([id](const auto* curr) { - return curr->id == id; - }, node); - } - - /** - * @brief Creates an instance of the underlying type, if possible. - * - * To create a valid instance, the parameters must be such that a cast or - * conversion to the required types is possible. Otherwise, an empty and - * thus invalid container is returned. - * - * @tparam Args Types of arguments to use to construct the instance. - * @param args Parameters to use to construct the instance. - * @return A meta any containing the new instance, if any. - */ - template - meta_any construct(Args &&... args) const { - auto construct_if = [this](meta_any* params) { - meta_any any{}; - - internal::find_if<&internal::meta_type_node::ctor>([params, &any](const auto* curr) { - return (curr->size == sizeof...(args)) && (any = curr->invoke(params)); - }, node); - - return any; - }; - - if constexpr (sizeof...(Args) == 0) { - return construct_if(nullptr); - } - else { - meta_any arguments[]{ std::forward(args)... }; - return construct_if(arguments); - } - } - - /** - * @brief Iterates all the properties assigned to a meta type. - * - * The properties of the base classes will also be returned, if any. - * - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - std::enable_if_t, void> - prop(Op op) const { - internal::visit<&internal::meta_type_node::prop, meta_prop>(op, node); - } - - /** - * @brief Returns the property associated with a given key. - * - * The properties of the base classes will also be visited, if any. - * - * @param key The key to use to search for a property. - * @return The property associated with the given key, if any. - */ - meta_prop prop(meta_any key) const { - return internal::find_if<&internal::meta_type_node::prop>([key = std::move(key)](const auto* curr) { - return curr->key() == key; - }, node); - } - - /** - * @brief Returns true if a meta object is valid, false otherwise. - * @return True if the meta object is valid, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return !(node == nullptr); - } - - /** - * @brief Checks if two meta objects refer to the same type. - * @param other The meta object with which to compare. - * @return True if the two meta objects refer to the same type, false - * otherwise. - */ - bool operator==(const meta_type& other) const ENTT_NOEXCEPT { - return (!node && !other.node) || (node && other.node && node->type_id == other.node->type_id); - } - - /*! @brief Removes a meta object from the list of searchable types. */ - void detach() ENTT_NOEXCEPT { - internal::meta_context::detach(node); - } - - private: - const internal::meta_type_node* node; - }; - - - /** - * @brief Checks if two meta objects refer to the same type. - * @param lhs A meta object, either valid or not. - * @param rhs A meta object, either valid or not. - * @return False if the two meta objects refer to the same node, true otherwise. - */ - inline bool operator!=(const meta_type& lhs, const meta_type& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - inline meta_type meta_any::type() const ENTT_NOEXCEPT { - return node; - } - - - inline meta_type meta_base::parent() const ENTT_NOEXCEPT { - return node->parent; - } - - - inline meta_type meta_base::type() const ENTT_NOEXCEPT { - return node->type(); - } - - - inline meta_type meta_conv::parent() const ENTT_NOEXCEPT { - return node->parent; - } - - - inline meta_type meta_conv::type() const ENTT_NOEXCEPT { - return node->type(); - } - - - inline meta_type meta_ctor::parent() const ENTT_NOEXCEPT { - return node->parent; - } - - - inline meta_type meta_ctor::arg(size_type index) const ENTT_NOEXCEPT { - return index < size() ? node->arg(index) : nullptr; - } - - - inline meta_type meta_data::parent() const ENTT_NOEXCEPT { - return node->parent; - } - - - inline meta_type meta_data::type() const ENTT_NOEXCEPT { - return node->type(); - } - - - inline meta_type meta_func::parent() const ENTT_NOEXCEPT { - return node->parent; - } - - - inline meta_type meta_func::ret() const ENTT_NOEXCEPT { - return node->ret(); - } - - - inline meta_type meta_func::arg(size_type index) const ENTT_NOEXCEPT { - return index < size() ? node->arg(index) : nullptr; - } - - -} - - -#endif - -// #include "policy.hpp" -#ifndef ENTT_META_POLICY_HPP -#define ENTT_META_POLICY_HPP - - -namespace entt { - - - /*! @brief Empty class type used to request the _as ref_ policy. */ - struct as_ref_t {}; - - - /*! @brief Disambiguation tag. */ - inline constexpr as_ref_t as_ref; - - - /*! @copydoc as_ref_t */ - using as_alias_t [[deprecated("use as_ref_t instead")]] = as_ref_t; - - - /*! @copydoc as_ref */ - [[deprecated("use as_ref instead")]] - inline constexpr as_ref_t as_alias; - - - /*! @brief Empty class type used to request the _as-is_ policy. */ - struct as_is_t {}; - - - /*! @brief Empty class type used to request the _as void_ policy. */ - struct as_void_t {}; - - -} - - -#endif - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - template - struct meta_function_helper; - - - template - struct meta_function_helper { - using return_type = std::remove_cv_t>; - using args_type = std::tuple>...>; - - static constexpr std::index_sequence_for index_sequence{}; - static constexpr auto is_const = false; - - static auto arg(typename internal::meta_func_node::size_type index) ENTT_NOEXCEPT { - return std::array{ {meta_info::resolve()...}} [index] ; - } - }; - - - template - struct meta_function_helper : meta_function_helper { - static constexpr auto is_const = true; - }; - - - template - constexpr meta_function_helper - to_meta_function_helper(Ret(Class::*)(Args...)); - - - template - constexpr meta_function_helper - to_meta_function_helper(Ret(Class::*)(Args...) const); - - - template - constexpr meta_function_helper - to_meta_function_helper(Ret(*)(Args...)); - - - constexpr void to_meta_function_helper(...); - - - template - using meta_function_helper_t = decltype(to_meta_function_helper(std::declval())); - - - template - meta_any construct(meta_any* const args, std::index_sequence) { - [[maybe_unused]] auto direct = std::make_tuple((args + Indexes)->try_cast()...); - meta_any any{}; - - if (((std::get(direct) || (args + Indexes)->convert()) && ...)) { - any = Type{ (std::get(direct) ? *std::get(direct) : (args + Indexes)->cast())... }; - } - - return any; - } - - - template - bool setter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any index, [[maybe_unused]] meta_any value) { - bool accepted = false; - - if constexpr (!Const) { - if constexpr (std::is_function_v>> || std::is_member_function_pointer_v) { - using helper_type = meta_function_helper_t; - using data_type = std::tuple_element_t, typename helper_type::args_type>; - static_assert(std::is_invocable_v); - auto* const clazz = instance.try_cast(); - auto* const direct = value.try_cast(); - - if (clazz && (direct || value.convert())) { - std::invoke(Data, *clazz, direct ? *direct : value.cast()); - accepted = true; - } - } - else if constexpr (std::is_member_object_pointer_v) { - using data_type = std::remove_cv_t().*Data)>>; - static_assert(std::is_invocable_v); - auto* const clazz = instance.try_cast(); - - if constexpr (std::is_array_v) { - using underlying_type = std::remove_extent_t; - auto* const direct = value.try_cast(); - auto* const idx = index.try_cast(); - - if (clazz && idx && (direct || value.convert())) { - std::invoke(Data, clazz)[*idx] = direct ? *direct : value.cast(); - accepted = true; - } - } - else { - auto* const direct = value.try_cast(); - - if (clazz && (direct || value.convert())) { - std::invoke(Data, clazz) = (direct ? *direct : value.cast()); - accepted = true; - } - } - } - else { - static_assert(std::is_pointer_v); - using data_type = std::remove_cv_t>; - - if constexpr (std::is_array_v) { - using underlying_type = std::remove_extent_t; - auto* const direct = value.try_cast(); - auto* const idx = index.try_cast(); - - if (idx && (direct || value.convert())) { - (*Data)[*idx] = (direct ? *direct : value.cast()); - accepted = true; - } - } - else { - auto* const direct = value.try_cast(); - - if (direct || value.convert()) { - *Data = (direct ? *direct : value.cast()); - accepted = true; - } - } - } - } - - return accepted; - } - - - template - meta_any getter([[maybe_unused]] meta_any instance, [[maybe_unused]] meta_any index) { - auto dispatch = [](auto&& value) { - if constexpr (std::is_same_v) { - return meta_any{ std::in_place_type, std::forward(value) }; - } - else if constexpr (std::is_same_v) { - return meta_any{ std::ref(std::forward(value)) }; - } - else { - static_assert(std::is_same_v); - return meta_any{ std::forward(value) }; - } - }; - - if constexpr (std::is_function_v>> || std::is_member_function_pointer_v) { - static_assert(std::is_invocable_v); - auto* const clazz = instance.try_cast(); - return clazz ? dispatch(std::invoke(Data, *clazz)) : meta_any{}; - } - else if constexpr (std::is_member_object_pointer_v) { - using data_type = std::remove_cv_t().*Data)>>; - static_assert(std::is_invocable_v); - auto* const clazz = instance.try_cast(); - - if constexpr (std::is_array_v) { - auto* const idx = index.try_cast(); - return (clazz && idx) ? dispatch(std::invoke(Data, clazz)[*idx]) : meta_any{}; - } - else { - return clazz ? dispatch(std::invoke(Data, clazz)) : meta_any{}; - } - } - else { - static_assert(std::is_pointer_v>); - - if constexpr (std::is_array_v>) { - auto* const idx = index.try_cast(); - return idx ? dispatch((*Data)[*idx]) : meta_any{}; - } - else { - return dispatch(*Data); - } - } - } - - - template - meta_any invoke([[maybe_unused]] meta_any instance, meta_any* args, std::index_sequence) { - using helper_type = meta_function_helper_t; - - auto dispatch = [](auto *... params) { - if constexpr (std::is_void_v || std::is_same_v) { - std::invoke(Candidate, *params...); - return meta_any{ std::in_place_type }; - } - else if constexpr (std::is_same_v) { - return meta_any{ std::ref(std::invoke(Candidate, *params...)) }; - } - else { - static_assert(std::is_same_v); - return meta_any{ std::invoke(Candidate, *params...) }; - } - }; - - [[maybe_unused]] const auto direct = std::make_tuple([](meta_any* any, auto* value) { - using arg_type = std::remove_reference_t; - - if (!value && any->convert()) { - value = any->try_cast(); - } - - return value; - }(args + Indexes, (args + Indexes)->try_cast>())...); - - if constexpr (std::is_function_v>>) { - return (std::get(direct) && ...) ? dispatch(std::get(direct)...) : meta_any{}; - } - else { - auto* const clazz = instance.try_cast(); - return (clazz && (std::get(direct) && ...)) ? dispatch(clazz, std::get(direct)...) : meta_any{}; - } - } - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Meta factory to be used for reflection purposes. - * - * The meta factory is an utility class used to reflect types, data members and - * functions of all sorts. This class ensures that the underlying web of types - * is built correctly and performs some checks in debug mode to ensure that - * there are no subtle errors at runtime. - */ - template - class meta_factory; - - - /** - * @brief Extended meta factory to be used for reflection purposes. - * @tparam Type Reflected type for which the factory was created. - * @tparam Spec Property specialization pack used to disambiguate overloads. - */ - template - class meta_factory : public meta_factory { - bool exists(const meta_any& key, const internal::meta_prop_node* node) ENTT_NOEXCEPT { - return node && (node->key() == key || exists(key, node->next)); - } - - template - void unpack(std::index_sequence, std::tuple property, Other &&... other) { - unroll(choice<3>, std::move(std::get(property))..., std::forward(other)...); - } - - template - void unroll(choice_t<3>, std::tuple property, Other &&... other) { - unpack(std::index_sequence_for{}, std::move(property), std::forward(other)...); - } - - template - void unroll(choice_t<2>, std::pair property, Other &&... other) { - assign(std::move(property.first), std::move(property.second)); - unroll(choice<3>, std::forward(other)...); - } - - template - std::enable_if_t> - unroll(choice_t<1>, Property&& property, Other &&... other) { - assign(std::forward(property)); - unroll(choice<3>, std::forward(other)...); - } - - template - void unroll(choice_t<0>, Func&& invocable, Other &&... other) { - unroll(choice<3>, std::forward(invocable)(), std::forward(other)...); - } - - template - void unroll(choice_t<0>) {} - - template - void assign(Key&& key, Value &&... value) { - static const auto property{ std::make_tuple(std::forward(key), std::forward(value)...) }; - - static internal::meta_prop_node node{ - nullptr, - []() -> meta_any { - return std::get<0>(property); - }, - []() -> meta_any { - if constexpr (sizeof...(Value) == 0) { - return {}; - } - else { - return std::get<1>(property); - } -} - }; - - ENTT_ASSERT(!exists(node.key(), *curr)); - node.next = *curr; - *curr = &node; - } - - public: - /** - * @brief Constructs an extended factory from a given node. - * @param target The underlying node to which to assign the properties. - */ - meta_factory(entt::internal::meta_prop_node** target) ENTT_NOEXCEPT - : curr{ target } - {} - - /** - * @brief Assigns a property to the last meta object created. - * - * Both the key and the value (if any) must be at least copy constructible. - * - * @tparam PropertyOrKey Type of the property or property key. - * @tparam Value Optional type of the property value. - * @param property_or_key Property or property key. - * @param value Optional property value. - * @return A meta factory for the parent type. - */ - template - auto prop(PropertyOrKey&& property_or_key, Value &&... value)&& { - if constexpr (sizeof...(Value) == 0) { - unroll(choice<3>, std::forward(property_or_key)); - } - else { - assign(std::forward(property_or_key), std::forward(value)...); - } - - return meta_factory{curr}; - } - - /** - * @brief Assigns properties to the last meta object created. - * - * Both the keys and the values (if any) must be at least copy - * constructible. - * - * @tparam Property Types of the properties. - * @param property Properties to assign to the last meta object created. - * @return A meta factory for the parent type. - */ - template - auto props(Property... property)&& { - unroll(choice<3>, std::forward(property)...); - return meta_factory{curr}; - } - - private: - entt::internal::meta_prop_node** curr; - }; - - - /** - * @brief Basic meta factory to be used for reflection purposes. - * @tparam Type Reflected type for which the factory was created. - */ - template - class meta_factory { - template - bool exists(const Node* candidate, const Node* node) ENTT_NOEXCEPT { - return node && (node == candidate || exists(candidate, node->next)); - } - - template - bool exists(const id_type id, const Node* node) ENTT_NOEXCEPT { - return node && (node->id == id || exists(id, node->next)); - } - - public: - /** - * @brief Makes a meta type _searchable_. - * @param id Optional unique identifier. - * @return An extended meta factory for the given type. - */ - auto type(const id_type id = type_info::id()) { - auto* const node = internal::meta_info::resolve(); - - ENTT_ASSERT(!exists(id, *internal::meta_context::global)); - ENTT_ASSERT(!exists(node, *internal::meta_context::global)); - node->id = id; - node->next = *internal::meta_context::global; - *internal::meta_context::global = node; - - return meta_factory{&node->prop}; - } - - /*! @copydoc type */ - [[deprecated("use ::type instead")]] - auto alias(const id_type id) ENTT_NOEXCEPT { - return type(id); - } - - /** - * @brief Assigns a meta base to a meta type. - * - * A reflected base class must be a real base class of the reflected type. - * - * @tparam Base Type of the base class to assign to the meta type. - * @return A meta factory for the parent type. - */ - template - auto base() ENTT_NOEXCEPT { - static_assert(std::is_base_of_v); - auto* const type = internal::meta_info::resolve(); - - static internal::meta_base_node node{ - type, - nullptr, - &internal::meta_info::resolve, - [](void* instance) ENTT_NOEXCEPT -> void* { - return static_cast(static_cast(instance)); - } - }; - - ENTT_ASSERT(!exists(&node, type->base)); - node.next = type->base; - type->base = &node; - - return meta_factory{}; - } - - /** - * @brief Assigns a meta conversion function to a meta type. - * - * The given type must be such that an instance of the reflected type can be - * converted to it. - * - * @tparam To Type of the conversion function to assign to the meta type. - * @return A meta factory for the parent type. - */ - template - auto conv() ENTT_NOEXCEPT { - static_assert(std::is_convertible_v); - auto* const type = internal::meta_info::resolve(); - - static internal::meta_conv_node node{ - type, - nullptr, - &internal::meta_info::resolve, - [](const void* instance) -> meta_any { - return static_cast(*static_cast(instance)); - } - }; - - ENTT_ASSERT(!exists(&node, type->conv)); - node.next = type->conv; - type->conv = &node; - - return meta_factory{}; - } - - /** - * @brief Assigns a meta conversion function to a meta type. - * - * Conversion functions can be either free functions or member - * functions.
- * In case of free functions, they must accept a const reference to an - * instance of the parent type as an argument. In case of member functions, - * they should have no arguments at all. - * - * @tparam Candidate The actual function to use for the conversion. - * @return A meta factory for the parent type. - */ - template - auto conv() ENTT_NOEXCEPT { - using conv_type = std::invoke_result_t; - auto* const type = internal::meta_info::resolve(); - - static internal::meta_conv_node node{ - type, - nullptr, - &internal::meta_info::resolve, - [](const void* instance) -> meta_any { - return std::invoke(Candidate, *static_cast(instance)); - } - }; - - ENTT_ASSERT(!exists(&node, type->conv)); - node.next = type->conv; - type->conv = &node; - - return meta_factory{}; - } - - /** - * @brief Assigns a meta constructor to a meta type. - * - * Free functions can be assigned to meta types in the role of constructors. - * All that is required is that they return an instance of the underlying - * type.
- * From a client's point of view, nothing changes if a constructor of a meta - * type is a built-in one or a free function. - * - * @tparam Func The actual function to use as a constructor. - * @tparam Policy Optional policy (no policy set by default). - * @return An extended meta factory for the parent type. - */ - template - auto ctor() ENTT_NOEXCEPT { - using helper_type = internal::meta_function_helper_t; - static_assert(std::is_same_v); - auto* const type = internal::meta_info::resolve(); - - static internal::meta_ctor_node node{ - type, - nullptr, - nullptr, - helper_type::index_sequence.size(), - &helper_type::arg, - [](meta_any* const any) { - return internal::invoke({}, any, helper_type::index_sequence); - } - }; - - ENTT_ASSERT(!exists(&node, type->ctor)); - node.next = type->ctor; - type->ctor = &node; - - return meta_factory>{&node.prop}; - } - - /** - * @brief Assigns a meta constructor to a meta type. - * - * A meta constructor is uniquely identified by the types of its arguments - * and is such that there exists an actual constructor of the underlying - * type that can be invoked with parameters whose types are those given. - * - * @tparam Args Types of arguments to use to construct an instance. - * @return An extended meta factory for the parent type. - */ - template - auto ctor() ENTT_NOEXCEPT { - using helper_type = internal::meta_function_helper_t; - auto* const type = internal::meta_info::resolve(); - - static internal::meta_ctor_node node{ - type, - nullptr, - nullptr, - helper_type::index_sequence.size(), - &helper_type::arg, - [](meta_any* const any) { - return internal::construct>...>(any, helper_type::index_sequence); - } - }; - - ENTT_ASSERT(!exists(&node, type->ctor)); - node.next = type->ctor; - type->ctor = &node; - - return meta_factory{&node.prop}; - } - - /** - * @brief Assigns a meta destructor to a meta type. - * - * Free functions can be assigned to meta types in the role of destructors. - * The signature of the function should identical to the following: - * - * @code{.cpp} - * void(Type &); - * @endcode - * - * The purpose is to give users the ability to free up resources that - * require special treatment before an object is actually destroyed. - * - * @tparam Func The actual function to use as a destructor. - * @return A meta factory for the parent type. - */ - template - auto dtor() ENTT_NOEXCEPT { - static_assert(std::is_invocable_v); - auto* const type = internal::meta_info::resolve(); - - static internal::meta_dtor_node node{ - type, - [](void* instance) { - if (instance) { - std::invoke(Func, *static_cast(instance)); - } - } - }; - - ENTT_ASSERT(!type->dtor); - type->dtor = &node; - - return meta_factory{}; - } - - /** - * @brief Assigns a meta data to a meta type. - * - * Both data members and static and global variables, as well as constants - * of any kind, can be assigned to a meta type.
- * From a client's point of view, all the variables associated with the - * reflected object will appear as if they were part of the type itself. - * - * @tparam Data The actual variable to attach to the meta type. - * @tparam Policy Optional policy (no policy set by default). - * @param id Unique identifier. - * @return An extended meta factory for the parent type. - */ - template - auto data(const id_type id) ENTT_NOEXCEPT { - auto* const type = internal::meta_info::resolve(); - internal::meta_data_node* curr = nullptr; - - if constexpr (std::is_same_v) { - static_assert(std::is_same_v); - - static internal::meta_data_node node{ - {}, - type, - nullptr, - nullptr, - true, - true, - &internal::meta_info::resolve, - [](meta_any, meta_any, meta_any) { return false; }, - [](meta_any, meta_any) -> meta_any { return Data; } - }; - - curr = &node; - } - else if constexpr (std::is_member_object_pointer_v) { - using data_type = std::remove_reference_t().*Data)>; - - static internal::meta_data_node node{ - {}, - type, - nullptr, - nullptr, - std::is_const_v, - !std::is_member_object_pointer_v, - &internal::meta_info::resolve, - &internal::setter, Type, Data>, - &internal::getter - }; - - curr = &node; - } - else { - static_assert(std::is_pointer_v>); - using data_type = std::remove_pointer_t>; - - static internal::meta_data_node node{ - {}, - type, - nullptr, - nullptr, - std::is_const_v, - !std::is_member_object_pointer_v, - &internal::meta_info::resolve, - &internal::setter, Type, Data>, - &internal::getter - }; - - curr = &node; - } - - ENTT_ASSERT(!exists(id, type->data)); - ENTT_ASSERT(!exists(curr, type->data)); - curr->id = id; - curr->next = type->data; - type->data = curr; - - return meta_factory>{&curr->prop}; - } - - /** - * @brief Assigns a meta data to a meta type by means of its setter and - * getter. - * - * Setters and getters can be either free functions, member functions or a - * mix of them.
- * In case of free functions, setters and getters must accept a reference to - * an instance of the parent type as their first argument. A setter has then - * an extra argument of a type convertible to that of the parameter to - * set.
- * In case of member functions, getters have no arguments at all, while - * setters has an argument of a type convertible to that of the parameter to - * set. - * - * @tparam Setter The actual function to use as a setter. - * @tparam Getter The actual function to use as a getter. - * @tparam Policy Optional policy (no policy set by default). - * @param id Unique identifier. - * @return An extended meta factory for the parent type. - */ - template - auto data(const id_type id) ENTT_NOEXCEPT { - using underlying_type = std::invoke_result_t; - static_assert(std::is_invocable_v); - auto* const type = internal::meta_info::resolve(); - - static internal::meta_data_node node{ - {}, - type, - nullptr, - nullptr, - false, - false, - &internal::meta_info::resolve, - &internal::setter, - &internal::getter - }; - - ENTT_ASSERT(!exists(id, type->data)); - ENTT_ASSERT(!exists(&node, type->data)); - node.id = id; - node.next = type->data; - type->data = &node; - - return meta_factory, std::integral_constant>{&node.prop}; - } - - /** - * @brief Assigns a meta funcion to a meta type. - * - * Both member functions and free functions can be assigned to a meta - * type.
- * From a client's point of view, all the functions associated with the - * reflected object will appear as if they were part of the type itself. - * - * @tparam Candidate The actual function to attach to the meta type. - * @tparam Policy Optional policy (no policy set by default). - * @param id Unique identifier. - * @return An extended meta factory for the parent type. - */ - template - auto func(const id_type id) ENTT_NOEXCEPT { - using helper_type = internal::meta_function_helper_t; - auto* const type = internal::meta_info::resolve(); - - static internal::meta_func_node node{ - {}, - type, - nullptr, - nullptr, - helper_type::index_sequence.size(), - helper_type::is_const, - !std::is_member_function_pointer_v, - &internal::meta_info, void, typename helper_type::return_type>>::resolve, - &helper_type::arg, - [](meta_any instance, meta_any* args) { - return internal::invoke(std::move(instance), args, helper_type::index_sequence); - } - }; - - ENTT_ASSERT(!exists(id, type->func)); - ENTT_ASSERT(!exists(&node, type->func)); - node.id = id; - node.next = type->func; - type->func = &node; - - return meta_factory>{&node.prop}; - } - - /** - * @brief Resets a meta type and all its parts. - * - * This function resets a meta type and all its data members, member - * functions and properties, as well as its constructors, destructors and - * conversion functions if any.
- * Base classes aren't reset but the link between the two types is removed. - * - * @return An extended meta factory for the given type. - */ - auto reset() ENTT_NOEXCEPT { - auto* const node = internal::meta_info::resolve(); - - internal::meta_context::detach(node); - - const auto unregister_all = y_combinator{ - [](auto&& self, auto** curr, auto... member) { - while (*curr) { - auto* prev = *curr; - (self(&(prev->*member)), ...); - *curr = prev->next; - prev->next = nullptr; - } - } - }; - - unregister_all(&node->prop); - unregister_all(&node->base); - unregister_all(&node->conv); - unregister_all(&node->ctor, &internal::meta_ctor_node::prop); - unregister_all(&node->data, &internal::meta_data_node::prop); - unregister_all(&node->func, &internal::meta_func_node::prop); - - node->id = {}; - node->next = nullptr; - node->dtor = nullptr; - - return meta_factory{&node->prop}; - } - }; - - - /** - * @brief Utility function to use for reflection. - * - * This is the point from which everything starts.
- * By invoking this function with a type that is not yet reflected, a meta type - * is created to which it will be possible to attach meta objects through a - * dedicated factory. - * - * @tparam Type Type to reflect. - * @return An meta factory for the given type. - */ - template - inline meta_factory meta() ENTT_NOEXCEPT { - auto* const node = internal::meta_info::resolve(); - // extended meta factory to allow assigning properties to opaque meta types - return meta_factory{&node->prop}; - } - - -} - - -#endif - -// #include "meta/meta.hpp" - -// #include "meta/resolve.hpp" -#ifndef ENTT_META_RESOLVE_HPP -#define ENTT_META_RESOLVE_HPP - - -#include -// #include "meta.hpp" - - - -namespace entt { - - - /** - * @brief Returns the meta type associated with a given type. - * @tparam Type Type to use to search for a meta type. - * @return The meta type associated with the given type, if any. - */ - template - inline meta_type resolve() ENTT_NOEXCEPT { - return internal::meta_info::resolve(); - } - - - /** - * @brief Returns the first meta type that satisfies specific criteria, if any. - * @tparam Func Type of the unary predicate to use to test the meta types. - * @param func Unary predicate which returns true for the required element. - * @return The first meta type satisfying the condition, if any. - */ - template - inline meta_type resolve_if(Func func) ENTT_NOEXCEPT { - return internal::find_if([&func](const auto* curr) { - return func(meta_type{ curr }); - }, *internal::meta_context::global); - } - - - /** - * @brief Returns the meta type associated with a given identifier, if any. - * @param id Unique identifier. - * @return The meta type associated with the given identifier, if any. - */ - inline meta_type resolve_id(const id_type id) ENTT_NOEXCEPT { - return resolve_if([id](const auto type) { return type.id() == id; }); - } - - - /** - * @brief Returns the meta type associated with a given type id, if any. - * @param id Unique identifier. - * @return The meta type associated with the given type id, if any. - */ - inline meta_type resolve_type(const id_type id) ENTT_NOEXCEPT { - return resolve_if([id](const auto type) { return type.type_id() == id; }); - } - - - /*! @copydoc resolve_id */ - [[deprecated("use entt::resolve_id instead")]] - inline meta_type resolve(const id_type id) ENTT_NOEXCEPT { - return resolve_id(id); - } - - - /** - * @brief Iterates all the reflected types. - * @tparam Op Type of the function object to invoke. - * @param op A valid function object. - */ - template - inline std::enable_if_t, void> - resolve(Op op) { - internal::visit(op, *internal::meta_context::global); - } - - -} - - -#endif - -// #include "meta/policy.hpp" - -// #include "process/process.hpp" -#ifndef ENTT_PROCESS_PROCESS_HPP -#define ENTT_PROCESS_PROCESS_HPP - - -#include -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - -// #include "../core/type_traits.hpp" -#ifndef ENTT_CORE_TYPE_TRAITS_HPP -#define ENTT_CORE_TYPE_TRAITS_HPP - - -#include -#include -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - -// #include "hashed_string.hpp" -#ifndef ENTT_CORE_HASHED_STRING_HPP -#define ENTT_CORE_HASHED_STRING_HPP - - -#include -#include -// #include "../config/config.h" - -// #include "fwd.hpp" -#ifndef ENTT_CORE_FWD_HPP -#define ENTT_CORE_FWD_HPP - - -// #include "../config/config.h" - - - -namespace entt { - - - /*! @brief Alias declaration for type identifiers. */ - using id_type = ENTT_ID_TYPE; - - -} - - -#endif - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - template - struct fnv1a_traits; - - - template<> - struct fnv1a_traits { - using type = std::uint32_t; - static constexpr std::uint32_t offset = 2166136261; - static constexpr std::uint32_t prime = 16777619; - }; - - - template<> - struct fnv1a_traits { - using type = std::uint64_t; - static constexpr std::uint64_t offset = 14695981039346656037ull; - static constexpr std::uint64_t prime = 1099511628211ull; - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Zero overhead unique identifier. - * - * A hashed string is a compile-time tool that allows users to use - * human-readable identifers in the codebase while using their numeric - * counterparts at runtime.
- * Because of that, a hashed string can also be used in constant expressions if - * required. - * - * @tparam Char Character type. - */ - template - class basic_hashed_string { - using traits_type = internal::fnv1a_traits; - - struct const_wrapper { - // non-explicit constructor on purpose - constexpr const_wrapper(const Char* curr) ENTT_NOEXCEPT: str{ curr } {} - const Char* str; - }; - - // Fowler-Noll-Vo hash function v. 1a - the good - static constexpr id_type helper(const Char* curr) ENTT_NOEXCEPT { - auto value = traits_type::offset; - - while (*curr != 0) { - value = (value ^ static_cast(*(curr++))) * traits_type::prime; - } - - return value; - } - - public: - /*! @brief Character type. */ - using value_type = Char; - /*! @brief Unsigned integer type. */ - using hash_type = id_type; - - /** - * @brief Returns directly the numeric representation of a string. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * const auto value = basic_hashed_string::to_value("my.png"); - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - * @return The numeric representation of the string. - */ - template - static constexpr hash_type value(const value_type(&str)[N]) ENTT_NOEXCEPT { - return helper(str); - } - - /** - * @brief Returns directly the numeric representation of a string. - * @param wrapper Helps achieving the purpose by relying on overloading. - * @return The numeric representation of the string. - */ - static hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT { - return helper(wrapper.str); - } - - /** - * @brief Returns directly the numeric representation of a string view. - * @param str Human-readable identifer. - * @param size Length of the string to hash. - * @return The numeric representation of the string. - */ - static hash_type value(const value_type* str, std::size_t size) ENTT_NOEXCEPT { - id_type partial{ traits_type::offset }; - while (size--) { partial = (partial ^ (str++)[0]) * traits_type::prime; } - return partial; - } - - /*! @brief Constructs an empty hashed string. */ - constexpr basic_hashed_string() ENTT_NOEXCEPT - : str{ nullptr }, hash{} - {} - - /** - * @brief Constructs a hashed string from an array of const characters. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * basic_hashed_string hs{"my.png"}; - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param curr Human-readable identifer. - */ - template - constexpr basic_hashed_string(const value_type(&curr)[N]) ENTT_NOEXCEPT - : str{ curr }, hash{ helper(curr) } - {} - - /** - * @brief Explicit constructor on purpose to avoid constructing a hashed - * string directly from a `const value_type *`. - * @param wrapper Helps achieving the purpose by relying on overloading. - */ - explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT - : str{ wrapper.str }, hash{ helper(wrapper.str) } - {} - - /** - * @brief Returns the human-readable representation of a hashed string. - * @return The string used to initialize the instance. - */ - constexpr const value_type* data() const ENTT_NOEXCEPT { - return str; - } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr hash_type value() const ENTT_NOEXCEPT { - return hash; - } - - /*! @copydoc data */ - constexpr operator const value_type* () const ENTT_NOEXCEPT { return data(); } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr operator hash_type() const ENTT_NOEXCEPT { return value(); } - - /** - * @brief Compares two hashed strings. - * @param other Hashed string with which to compare. - * @return True if the two hashed strings are identical, false otherwise. - */ - constexpr bool operator==(const basic_hashed_string& other) const ENTT_NOEXCEPT { - return hash == other.hash; - } - - private: - const value_type* str; - hash_type hash; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the character type of the hashed string directly from a - * human-readable identifer provided to the constructor. - * - * @tparam Char Character type. - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - */ - template - basic_hashed_string(const Char(&str)[N]) ENTT_NOEXCEPT - ->basic_hashed_string; - - - /** - * @brief Compares two hashed strings. - * @tparam Char Character type. - * @param lhs A valid hashed string. - * @param rhs A valid hashed string. - * @return True if the two hashed strings are identical, false otherwise. - */ - template - constexpr bool operator!=(const basic_hashed_string& lhs, const basic_hashed_string& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - /*! @brief Aliases for common character types. */ - using hashed_string = basic_hashed_string; - - - /*! @brief Aliases for common character types. */ - using hashed_wstring = basic_hashed_string; - - -} - - -/** - * @brief User defined literal for hashed strings. - * @param str The literal without its suffix. - * @return A properly initialized hashed string. - */ -constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_string{ str }; -} - - -/** - * @brief User defined literal for hashed wstrings. - * @param str The literal without its suffix. - * @return A properly initialized hashed wstring. - */ -constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_wstring{ str }; -} - - -#endif - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Wraps a static constant. - * @tparam Value A static constant. - */ - template - using integral_constant = std::integral_constant; - - - /** - * @brief Alias template to ease the creation of named values. - * @tparam Value A constant value at least convertible to `id_type`. - */ - template - using tag = integral_constant; - - - /** - * @brief Utility class to disambiguate overloaded functions. - * @tparam N Number of choices available. - */ - template - struct choice_t - // Unfortunately, doxygen cannot parse such a construct. - /*! @cond TURN_OFF_DOXYGEN */ - : choice_t - /*! @endcond TURN_OFF_DOXYGEN */ - {}; - - - /*! @copybrief choice_t */ - template<> - struct choice_t<0> {}; - - - /** - * @brief Variable template for the choice trick. - * @tparam N Number of choices available. - */ - template - inline constexpr choice_t choice{}; - - - /*! @brief A class to use to push around lists of types, nothing more. */ - template - struct type_list {}; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_size; - - - /** - * @brief Compile-time number of elements in a type list. - * @tparam Type Types provided by the type list. - */ - template - struct type_list_size> - : std::integral_constant - {}; - - - /** - * @brief Helper variable template. - * @tparam List Type list. - */ - template - inline constexpr auto type_list_size_v = type_list_size::value; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_cat; - - - /*! @brief Concatenates multiple type lists. */ - template<> - struct type_list_cat<> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = type_list<>; - }; - - - /** - * @brief Concatenates multiple type lists. - * @tparam Type Types provided by the first type list. - * @tparam Other Types provided by the second type list. - * @tparam List Other type lists, if any. - */ - template - struct type_list_cat, type_list, List...> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = typename type_list_cat, List...>::type; - }; - - - /** - * @brief Concatenates multiple type lists. - * @tparam Type Types provided by the type list. - */ - template - struct type_list_cat> { - /*! @brief A type list composed by the types of all the type lists. */ - using type = type_list; - }; - - - /** - * @brief Helper type. - * @tparam List Type lists to concatenate. - */ - template - using type_list_cat_t = typename type_list_cat::type; - - - /*! @brief Primary template isn't defined on purpose. */ - template - struct type_list_unique; - - - /** - * @brief Removes duplicates types from a type list. - * @tparam Type One of the types provided by the given type list. - * @tparam Other The other types provided by the given type list. - */ - template - struct type_list_unique> { - /*! @brief A type list without duplicate types. */ - using type = std::conditional_t< - std::disjunction_v...>, - typename type_list_unique>::type, - type_list_cat_t, typename type_list_unique>::type> - >; - }; - - - /*! @brief Removes duplicates types from a type list. */ - template<> - struct type_list_unique> { - /*! @brief A type list without duplicate types. */ - using type = type_list<>; - }; - - - /** - * @brief Helper type. - * @tparam Type A type list. - */ - template - using type_list_unique_t = typename type_list_unique::type; - - - /** - * @brief Provides the member constant `value` to true if a given type is - * equality comparable, false otherwise. - * @tparam Type Potentially equality comparable type. - */ - template> - struct is_equality_comparable : std::false_type {}; - - - /*! @copydoc is_equality_comparable */ - template - struct is_equality_comparable() == std::declval())>> : std::true_type {}; - - - /** - * @brief Helper variable template. - * @tparam Type Potentially equality comparable type. - */ - template - inline constexpr auto is_equality_comparable_v = is_equality_comparable::value; - - - /** - * @brief Extracts the class of a non-static member object or function. - * @tparam Member A pointer to a non-static member object or function. - */ - template - class member_class { - static_assert(std::is_member_pointer_v); - - template - static Class* clazz(Ret(Class::*)(Args...)); - - template - static Class* clazz(Ret(Class::*)(Args...) const); - - template - static Class* clazz(Type Class::*); - - public: - /*! @brief The class of the given non-static member object or function. */ - using type = std::remove_pointer_t()))>; - }; - - - /** - * @brief Helper type. - * @tparam Member A pointer to a non-static member object or function. - */ - template - using member_class_t = typename member_class::type; - - -} - - -/** - * @brief Defines an enum class to use for opaque identifiers and a dedicate - * `to_integer` function to convert the identifiers to their underlying type. - * @param clazz The name to use for the enum class. - * @param type The underlying type for the enum class. - */ -#define ENTT_OPAQUE_TYPE(clazz, type)\ - enum class clazz: type {};\ - constexpr auto to_integral(const clazz id) ENTT_NOEXCEPT {\ - return static_cast>(id);\ - }\ - static_assert(true) - - -#endif - - - -namespace entt { - - - /** - * @brief Base class for processes. - * - * This class stays true to the CRTP idiom. Derived classes must specify what's - * the intended type for elapsed times.
- * A process should expose publicly the following member functions whether - * required: - * - * * @code{.cpp} - * void update(Delta, void *); - * @endcode - * - * It's invoked once per tick until a process is explicitly aborted or it - * terminates either with or without errors. Even though it's not mandatory to - * declare this member function, as a rule of thumb each process should at - * least define it to work properly. The `void *` parameter is an opaque - * pointer to user data (if any) forwarded directly to the process during an - * update. - * - * * @code{.cpp} - * void init(); - * @endcode - * - * It's invoked when the process joins the running queue of a scheduler. This - * happens as soon as it's attached to the scheduler if the process is a top - * level one, otherwise when it replaces its parent if the process is a - * continuation. - * - * * @code{.cpp} - * void succeeded(); - * @endcode - * - * It's invoked in case of success, immediately after an update and during the - * same tick. - * - * * @code{.cpp} - * void failed(); - * @endcode - * - * It's invoked in case of errors, immediately after an update and during the - * same tick. - * - * * @code{.cpp} - * void aborted(); - * @endcode - * - * It's invoked only if a process is explicitly aborted. There is no guarantee - * that it executes in the same tick, this depends solely on whether the - * process is aborted immediately or not. - * - * Derived classes can change the internal state of a process by invoking the - * `succeed` and `fail` protected member functions and even pause or unpause the - * process itself. - * - * @sa scheduler - * - * @tparam Derived Actual type of process that extends the class template. - * @tparam Delta Type to use to provide elapsed time. - */ - template - class process { - enum class state : unsigned int { - UNINITIALIZED = 0, - RUNNING, - PAUSED, - SUCCEEDED, - FAILED, - ABORTED, - FINISHED - }; - - template - auto next(integral_constant) - -> decltype(std::declval().init()) { - static_cast(this)->init(); - } - - template - auto next(integral_constant, Delta delta, void* data) - -> decltype(std::declval().update(delta, data)) { - static_cast(this)->update(delta, data); - } - - template - auto next(integral_constant) - -> decltype(std::declval().succeeded()) { - static_cast(this)->succeeded(); - } - - template - auto next(integral_constant) - -> decltype(std::declval().failed()) { - static_cast(this)->failed(); - } - - template - auto next(integral_constant) - -> decltype(std::declval().aborted()) { - static_cast(this)->aborted(); - } - - void next(...) const ENTT_NOEXCEPT {} - - protected: - /** - * @brief Terminates a process with success if it's still alive. - * - * The function is idempotent and it does nothing if the process isn't - * alive. - */ - void succeed() ENTT_NOEXCEPT { - if (alive()) { - current = state::SUCCEEDED; - } - } - - /** - * @brief Terminates a process with errors if it's still alive. - * - * The function is idempotent and it does nothing if the process isn't - * alive. - */ - void fail() ENTT_NOEXCEPT { - if (alive()) { - current = state::FAILED; - } - } - - /** - * @brief Stops a process if it's in a running state. - * - * The function is idempotent and it does nothing if the process isn't - * running. - */ - void pause() ENTT_NOEXCEPT { - if (current == state::RUNNING) { - current = state::PAUSED; - } - } - - /** - * @brief Restarts a process if it's paused. - * - * The function is idempotent and it does nothing if the process isn't - * paused. - */ - void unpause() ENTT_NOEXCEPT { - if (current == state::PAUSED) { - current = state::RUNNING; - } - } - - public: - /*! @brief Type used to provide elapsed time. */ - using delta_type = Delta; - - /*! @brief Default destructor. */ - virtual ~process() { - static_assert(std::is_base_of_v); - } - - /** - * @brief Aborts a process if it's still alive. - * - * The function is idempotent and it does nothing if the process isn't - * alive. - * - * @param immediately Requests an immediate operation. - */ - void abort(const bool immediately = false) { - if (alive()) { - current = state::ABORTED; - - if (immediately) { - tick({}); - } - } - } - - /** - * @brief Returns true if a process is either running or paused. - * @return True if the process is still alive, false otherwise. - */ - bool alive() const ENTT_NOEXCEPT { - return current == state::RUNNING || current == state::PAUSED; - } - - /** - * @brief Returns true if a process is already terminated. - * @return True if the process is terminated, false otherwise. - */ - bool dead() const ENTT_NOEXCEPT { - return current == state::FINISHED; - } - - /** - * @brief Returns true if a process is currently paused. - * @return True if the process is paused, false otherwise. - */ - bool paused() const ENTT_NOEXCEPT { - return current == state::PAUSED; - } - - /** - * @brief Returns true if a process terminated with errors. - * @return True if the process terminated with errors, false otherwise. - */ - bool rejected() const ENTT_NOEXCEPT { - return stopped; - } - - /** - * @brief Updates a process and its internal state if required. - * @param delta Elapsed time. - * @param data Optional data. - */ - void tick(const Delta delta, void* data = nullptr) { - switch (current) { - case state::UNINITIALIZED: - next(integral_constant{}); - current = state::RUNNING; - break; - case state::RUNNING: - next(integral_constant{}, delta, data); - break; - default: - // suppress warnings - break; - } - - // if it's dead, it must be notified and removed immediately - switch (current) { - case state::SUCCEEDED: - next(integral_constant{}); - current = state::FINISHED; - break; - case state::FAILED: - next(integral_constant{}); - current = state::FINISHED; - stopped = true; - break; - case state::ABORTED: - next(integral_constant{}); - current = state::FINISHED; - stopped = true; - break; - default: - // suppress warnings - break; - } - } - - private: - state current{ state::UNINITIALIZED }; - bool stopped{ false }; - }; - - - /** - * @brief Adaptor for lambdas and functors to turn them into processes. - * - * Lambdas and functors can't be used directly with a scheduler for they are not - * properly defined processes with managed life cycles.
- * This class helps in filling the gap and turning lambdas and functors into - * full featured processes usable by a scheduler. - * - * The signature of the function call operator should be equivalent to the - * following: - * - * @code{.cpp} - * void(Delta delta, void *data, auto succeed, auto fail); - * @endcode - * - * Where: - * - * * `delta` is the elapsed time. - * * `data` is an opaque pointer to user data if any, `nullptr` otherwise. - * * `succeed` is a function to call when a process terminates with success. - * * `fail` is a function to call when a process terminates with errors. - * - * The signature of the function call operator of both `succeed` and `fail` - * is equivalent to the following: - * - * @code{.cpp} - * void(); - * @endcode - * - * Usually users shouldn't worry about creating adaptors. A scheduler will - * create them internally each and avery time a lambda or a functor is used as - * a process. - * - * @sa process - * @sa scheduler - * - * @tparam Func Actual type of process. - * @tparam Delta Type to use to provide elapsed time. - */ - template - struct process_adaptor : process, Delta>, private Func { - /** - * @brief Constructs a process adaptor from a lambda or a functor. - * @tparam Args Types of arguments to use to initialize the actual process. - * @param args Parameters to use to initialize the actual process. - */ - template - process_adaptor(Args &&... args) - : Func{ std::forward(args)... } - {} - - /** - * @brief Updates a process and its internal state if required. - * @param delta Elapsed time. - * @param data Optional data. - */ - void update(const Delta delta, void* data) { - Func::operator()(delta, data, [this]() { this->succeed(); }, [this]() { this->fail(); }); - } - }; - - -} - - -#endif - -// #include "process/scheduler.hpp" -#ifndef ENTT_PROCESS_SCHEDULER_HPP -#define ENTT_PROCESS_SCHEDULER_HPP - - -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "process.hpp" - - - -namespace entt { - - - /** - * @brief Cooperative scheduler for processes. - * - * A cooperative scheduler runs processes and helps managing their life cycles. - * - * Each process is invoked once per tick. If a process terminates, it's - * removed automatically from the scheduler and it's never invoked again.
- * A process can also have a child. In this case, the process is replaced with - * its child when it terminates if it returns with success. In case of errors, - * both the process and its child are discarded. - * - * Example of use (pseudocode): - * - * @code{.cpp} - * scheduler.attach([](auto delta, void *, auto succeed, auto fail) { - * // code - * }).then(arguments...); - * @endcode - * - * In order to invoke all scheduled processes, call the `update` member function - * passing it the elapsed time to forward to the tasks. - * - * @sa process - * - * @tparam Delta Type to use to provide elapsed time. - */ - template - class scheduler { - struct process_handler { - using instance_type = std::unique_ptr; - using update_fn_type = bool(process_handler&, Delta, void*); - using abort_fn_type = void(process_handler&, bool); - using next_type = std::unique_ptr; - - instance_type instance; - update_fn_type* update; - abort_fn_type* abort; - next_type next; - }; - - struct continuation { - continuation(process_handler* ref) - : handler{ ref } - { - ENTT_ASSERT(handler); - } - - template - continuation then(Args &&... args) { - static_assert(std::is_base_of_v, Proc>); - auto proc = typename process_handler::instance_type{ new Proc{std::forward(args)...}, &scheduler::deleter }; - handler->next.reset(new process_handler{ std::move(proc), &scheduler::update, &scheduler::abort, nullptr }); - handler = handler->next.get(); - return *this; - } - - template - continuation then(Func&& func) { - return then, Delta>>(std::forward(func)); - } - - private: - process_handler* handler; - }; - - template - static bool update(process_handler& handler, const Delta delta, void* data) { - auto* process = static_cast(handler.instance.get()); - process->tick(delta, data); - - auto dead = process->dead(); - - if (dead) { - if (handler.next && !process->rejected()) { - handler = std::move(*handler.next); - // forces the process to exit the uninitialized state - dead = handler.update(handler, {}, nullptr); - } - else { - handler.instance.reset(); - } - } - - return dead; - } - - template - static void abort(process_handler& handler, const bool immediately) { - static_cast(handler.instance.get())->abort(immediately); - } - - template - static void deleter(void* proc) { - delete static_cast(proc); - } - - public: - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - - /*! @brief Default constructor. */ - scheduler() = default; - - /*! @brief Default move constructor. */ - scheduler(scheduler&&) = default; - - /*! @brief Default move assignment operator. @return This scheduler. */ - scheduler& operator=(scheduler&&) = default; - - /** - * @brief Number of processes currently scheduled. - * @return Number of processes currently scheduled. - */ - size_type size() const ENTT_NOEXCEPT { - return handlers.size(); - } - - /** - * @brief Returns true if at least a process is currently scheduled. - * @return True if there are scheduled processes, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return handlers.empty(); - } - - /** - * @brief Discards all scheduled processes. - * - * Processes aren't aborted. They are discarded along with their children - * and never executed again. - */ - void clear() { - handlers.clear(); - } - - /** - * @brief Schedules a process for the next tick. - * - * Returned value is an opaque object that can be used to attach a child to - * the given process. The child is automatically scheduled when the process - * terminates and only if the process returns with success. - * - * Example of use (pseudocode): - * - * @code{.cpp} - * // schedules a task in the form of a process class - * scheduler.attach(arguments...) - * // appends a child in the form of a lambda function - * .then([](auto delta, void *, auto succeed, auto fail) { - * // code - * }) - * // appends a child in the form of another process class - * .then(); - * @endcode - * - * @tparam Proc Type of process to schedule. - * @tparam Args Types of arguments to use to initialize the process. - * @param args Parameters to use to initialize the process. - * @return An opaque object to use to concatenate processes. - */ - template - auto attach(Args &&... args) { - static_assert(std::is_base_of_v, Proc>); - auto proc = typename process_handler::instance_type{ new Proc{std::forward(args)...}, &scheduler::deleter }; - process_handler handler{ std::move(proc), &scheduler::update, &scheduler::abort, nullptr }; - // forces the process to exit the uninitialized state - handler.update(handler, {}, nullptr); - return continuation{ &handlers.emplace_back(std::move(handler)) }; - } - - /** - * @brief Schedules a process for the next tick. - * - * A process can be either a lambda or a functor. The scheduler wraps both - * of them in a process adaptor internally.
- * The signature of the function call operator should be equivalent to the - * following: - * - * @code{.cpp} - * void(Delta delta, void *data, auto succeed, auto fail); - * @endcode - * - * Where: - * - * * `delta` is the elapsed time. - * * `data` is an opaque pointer to user data if any, `nullptr` otherwise. - * * `succeed` is a function to call when a process terminates with success. - * * `fail` is a function to call when a process terminates with errors. - * - * The signature of the function call operator of both `succeed` and `fail` - * is equivalent to the following: - * - * @code{.cpp} - * void(); - * @endcode - * - * Returned value is an opaque object that can be used to attach a child to - * the given process. The child is automatically scheduled when the process - * terminates and only if the process returns with success. - * - * Example of use (pseudocode): - * - * @code{.cpp} - * // schedules a task in the form of a lambda function - * scheduler.attach([](auto delta, void *, auto succeed, auto fail) { - * // code - * }) - * // appends a child in the form of another lambda function - * .then([](auto delta, void *, auto succeed, auto fail) { - * // code - * }) - * // appends a child in the form of a process class - * .then(arguments...); - * @endcode - * - * @sa process_adaptor - * - * @tparam Func Type of process to schedule. - * @param func Either a lambda or a functor to use as a process. - * @return An opaque object to use to concatenate processes. - */ - template - auto attach(Func&& func) { - using Proc = process_adaptor, Delta>; - return attach(std::forward(func)); - } - - /** - * @brief Updates all scheduled processes. - * - * All scheduled processes are executed in no specific order.
- * If a process terminates with success, it's replaced with its child, if - * any. Otherwise, if a process terminates with an error, it's removed along - * with its child. - * - * @param delta Elapsed time. - * @param data Optional data. - */ - void update(const Delta delta, void* data = nullptr) { - bool clean = false; - - for (auto pos = handlers.size(); pos; --pos) { - auto& handler = handlers[pos - 1]; - const bool dead = handler.update(handler, delta, data); - clean = clean || dead; - } - - if (clean) { - handlers.erase(std::remove_if(handlers.begin(), handlers.end(), [](auto& handler) { - return !handler.instance; - }), handlers.end()); - } - } - - /** - * @brief Aborts all scheduled processes. - * - * Unless an immediate operation is requested, the abort is scheduled for - * the next tick. Processes won't be executed anymore in any case.
- * Once a process is fully aborted and thus finished, it's discarded along - * with its child, if any. - * - * @param immediately Requests an immediate operation. - */ - void abort(const bool immediately = false) { - decltype(handlers) exec; - exec.swap(handlers); - - for (auto&& handler : exec) { - handler.abort(handler, immediately); - } - - std::move(handlers.begin(), handlers.end(), std::back_inserter(exec)); - handlers.swap(exec); - } - - private: - std::vector handlers{}; - }; - - -} - - -#endif - -// #include "resource/cache.hpp" -#ifndef ENTT_RESOURCE_CACHE_HPP -#define ENTT_RESOURCE_CACHE_HPP - - -#include -#include -#include -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - -// #include "../core/fwd.hpp" -#ifndef ENTT_CORE_FWD_HPP -#define ENTT_CORE_FWD_HPP - - -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - - - -namespace entt { - - - /*! @brief Alias declaration for type identifiers. */ - using id_type = ENTT_ID_TYPE; - - -} - - -#endif - -// #include "handle.hpp" -#ifndef ENTT_RESOURCE_HANDLE_HPP -#define ENTT_RESOURCE_HANDLE_HPP - - -#include -#include -// #include "../config/config.h" - -// #include "fwd.hpp" -#ifndef ENTT_RESOURCE_FWD_HPP -#define ENTT_RESOURCE_FWD_HPP - - -namespace entt { - - - /*! @struct cache */ - template - struct cache; - - /*! @class handle */ - template - class handle; - - /*! @class loader */ - template - class loader; - - -} - - -#endif - - - -namespace entt { - - - /** - * @brief Shared resource handle. - * - * A shared resource handle is a small class that wraps a resource and keeps it - * alive even if it's deleted from the cache. It can be either copied or - * moved. A handle shares a reference to the same resource with all the other - * handles constructed for the same identifier.
- * As a rule of thumb, resources should never be copied nor moved. Handles are - * the way to go to keep references to them. - * - * @tparam Resource Type of resource managed by a handle. - */ - template - class handle { - /*! @brief Resource handles are friends of their caches. */ - friend struct cache; - - handle(std::shared_ptr res) ENTT_NOEXCEPT - : resource{ std::move(res) } - {} - - public: - /*! @brief Default constructor. */ - handle() ENTT_NOEXCEPT = default; - - /** - * @brief Gets a reference to the managed resource. - * - * @warning - * The behavior is undefined if the handle doesn't contain a resource.
- * An assertion will abort the execution at runtime in debug mode if the - * handle is empty. - * - * @return A reference to the managed resource. - */ - const Resource& get() const ENTT_NOEXCEPT { - ENTT_ASSERT(static_cast(resource)); - return *resource; - } - - /*! @copydoc get */ - Resource& get() ENTT_NOEXCEPT { - return const_cast(std::as_const(*this).get()); - } - - /*! @copydoc get */ - operator const Resource& () const ENTT_NOEXCEPT { return get(); } - - /*! @copydoc get */ - operator Resource& () ENTT_NOEXCEPT { return get(); } - - /*! @copydoc get */ - const Resource& operator *() const ENTT_NOEXCEPT { return get(); } - - /*! @copydoc get */ - Resource& operator *() ENTT_NOEXCEPT { return get(); } - - /** - * @brief Gets a pointer to the managed resource. - * - * @warning - * The behavior is undefined if the handle doesn't contain a resource.
- * An assertion will abort the execution at runtime in debug mode if the - * handle is empty. - * - * @return A pointer to the managed resource or `nullptr` if the handle - * contains no resource at all. - */ - const Resource* operator->() const ENTT_NOEXCEPT { - ENTT_ASSERT(static_cast(resource)); - return resource.get(); - } - - /*! @copydoc operator-> */ - Resource* operator->() ENTT_NOEXCEPT { - return const_cast(std::as_const(*this).operator->()); - } - - /** - * @brief Returns true if a handle contains a resource, false otherwise. - * @return True if the handle contains a resource, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return static_cast(resource); - } - - private: - std::shared_ptr resource; - }; - - -} - - -#endif - -// #include "loader.hpp" -#ifndef ENTT_RESOURCE_LOADER_HPP -#define ENTT_RESOURCE_LOADER_HPP - - -#include -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Base class for resource loaders. - * - * Resource loaders must inherit from this class and stay true to the CRTP - * idiom. Moreover, a resource loader must expose a public, const member - * function named `load` that accepts a variable number of arguments and returns - * a shared pointer to the resource just created.
- * As an example: - * - * @code{.cpp} - * struct my_resource {}; - * - * struct my_loader: entt::loader { - * std::shared_ptr load(int) const { - * // use the integer value somehow - * return std::make_shared(); - * } - * }; - * @endcode - * - * In general, resource loaders should not have a state or retain data of any - * type. They should let the cache manage their resources instead. - * - * @note - * Base class and CRTP idiom aren't strictly required with the current - * implementation. One could argue that a cache can easily work with loaders of - * any type. However, future changes won't be breaking ones by forcing the use - * of a base class today and that's why the model is already in its place. - * - * @tparam Loader Type of the derived class. - * @tparam Resource Type of resource for which to use the loader. - */ - template - class loader { - /*! @brief Resource loaders are friends of their caches. */ - friend struct cache; - - /** - * @brief Loads the resource and returns it. - * @tparam Args Types of arguments for the loader. - * @param args Arguments for the loader. - * @return The resource just loaded or an empty pointer in case of errors. - */ - template - std::shared_ptr get(Args &&... args) const { - return static_cast(this)->load(std::forward(args)...); - } - }; - - -} - - -#endif - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @brief Simple cache for resources of a given type. - * - * Minimal implementation of a cache for resources of a given type. It doesn't - * offer much functionalities but it's suitable for small or medium sized - * applications and can be freely inherited to add targeted functionalities for - * large sized applications. - * - * @tparam Resource Type of resources managed by a cache. - */ - template - struct cache { - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Type of resources managed by a cache. */ - using resource_type = Resource; - - /*! @brief Default constructor. */ - cache() = default; - - /*! @brief Default move constructor. */ - cache(cache&&) = default; - - /*! @brief Default move assignment operator. @return This cache. */ - cache& operator=(cache&&) = default; - - /** - * @brief Number of resources managed by a cache. - * @return Number of resources currently stored. - */ - size_type size() const ENTT_NOEXCEPT { - return resources.size(); - } - - /** - * @brief Returns true if a cache contains no resources, false otherwise. - * @return True if the cache contains no resources, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return resources.empty(); - } - - /** - * @brief Clears a cache and discards all its resources. - * - * Handles are not invalidated and the memory used by a resource isn't - * freed as long as at least a handle keeps the resource itself alive. - */ - void clear() ENTT_NOEXCEPT { - resources.clear(); - } - - /** - * @brief Loads the resource that corresponds to a given identifier. - * - * In case an identifier isn't already present in the cache, it loads its - * resource and stores it aside for future uses. Arguments are forwarded - * directly to the loader in order to construct properly the requested - * resource. - * - * @note - * If the identifier is already present in the cache, this function does - * nothing and the arguments are simply discarded. - * - * @warning - * If the resource cannot be loaded correctly, the returned handle will be - * invalid and any use of it will result in undefined behavior. - * - * @tparam Loader Type of loader to use to load the resource if required. - * @tparam Args Types of arguments to use to load the resource if required. - * @param id Unique resource identifier. - * @param args Arguments to use to load the resource if required. - * @return A handle for the given resource. - */ - template - entt::handle load(const id_type id, Args &&... args) { - static_assert(std::is_base_of_v, Loader>); - entt::handle resource{}; - - if (auto it = resources.find(id); it == resources.cend()) { - if (auto instance = Loader{}.get(std::forward(args)...); instance) { - resources[id] = instance; - resource = std::move(instance); - } - } - else { - resource = it->second; - } - - return resource; - } - - /** - * @brief Reloads a resource or loads it for the first time if not present. - * - * Equivalent to the following snippet (pseudocode): - * - * @code{.cpp} - * cache.discard(id); - * cache.load(id, args...); - * @endcode - * - * Arguments are forwarded directly to the loader in order to construct - * properly the requested resource. - * - * @warning - * If the resource cannot be loaded correctly, the returned handle will be - * invalid and any use of it will result in undefined behavior. - * - * @tparam Loader Type of loader to use to load the resource. - * @tparam Args Types of arguments to use to load the resource. - * @param id Unique resource identifier. - * @param args Arguments to use to load the resource. - * @return A handle for the given resource. - */ - template - entt::handle reload(const id_type id, Args &&... args) { - return (discard(id), load(id, std::forward(args)...)); - } - - /** - * @brief Creates a temporary handle for a resource. - * - * Arguments are forwarded directly to the loader in order to construct - * properly the requested resource. The handle isn't stored aside and the - * cache isn't in charge of the lifetime of the resource itself. - * - * @tparam Loader Type of loader to use to load the resource. - * @tparam Args Types of arguments to use to load the resource. - * @param args Arguments to use to load the resource. - * @return A handle for the given resource. - */ - template - entt::handle temp(Args &&... args) const { - return { Loader{}.get(std::forward(args)...) }; - } - - /** - * @brief Creates a handle for a given resource identifier. - * - * A resource handle can be in a either valid or invalid state. In other - * terms, a resource handle is properly initialized with a resource if the - * cache contains the resource itself. Otherwise the returned handle is - * uninitialized and accessing it results in undefined behavior. - * - * @sa handle - * - * @param id Unique resource identifier. - * @return A handle for the given resource. - */ - entt::handle handle(const id_type id) const { - auto it = resources.find(id); - return { it == resources.end() ? nullptr : it->second }; - } - - /** - * @brief Checks if a cache contains a given identifier. - * @param id Unique resource identifier. - * @return True if the cache contains the resource, false otherwise. - */ - bool contains(const id_type id) const { - return (resources.find(id) != resources.cend()); - } - - /** - * @brief Discards the resource that corresponds to a given identifier. - * - * Handles are not invalidated and the memory used by the resource isn't - * freed as long as at least a handle keeps the resource itself alive. - * - * @param id Unique resource identifier. - */ - void discard(const id_type id) { - if (auto it = resources.find(id); it != resources.end()) { - resources.erase(it); - } - } - - /** - * @brief Iterates all resources. - * - * The function object is invoked for each element. It is provided with - * either the resource identifier, the resource handle or both of them.
- * The signature of the function must be equivalent to one of the following - * forms: - * - * @code{.cpp} - * void(const id_type); - * void(handle); - * void(const id_type, handle); - * @endcode - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - auto begin = resources.begin(); - auto end = resources.end(); - - while (begin != end) { - auto curr = begin++; - - if constexpr (std::is_invocable_v) { - func(curr->first); - } - else if constexpr (std::is_invocable_v>) { - func(entt::handle{ curr->second }); - } - else { - func(curr->first, entt::handle{ curr->second }); - } - } - } - - private: - std::unordered_map> resources; - }; - - -} - - -#endif - -// #include "resource/handle.hpp" - -// #include "resource/loader.hpp" - -// #include "signal/delegate.hpp" -#ifndef ENTT_SIGNAL_DELEGATE_HPP -#define ENTT_SIGNAL_DELEGATE_HPP - - -#include -#include -#include -#include -#include -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - template - auto function_pointer(Ret(*)(Args...))->Ret(*)(Args...); - - - template - auto function_pointer(Ret(*)(Type, Args...), Other&&)->Ret(*)(Args...); - - - template - auto function_pointer(Ret(Class::*)(Args...), Other &&...)->Ret(*)(Args...); - - - template - auto function_pointer(Ret(Class::*)(Args...) const, Other &&...)->Ret(*)(Args...); - - - template - auto function_pointer(Type Class::*, Other &&...)->Type(*)(); - - - template - using function_pointer_t = decltype(internal::function_pointer(std::declval()...)); - - - template - constexpr auto index_sequence_for(Ret(*)(Args...)) { - return std::index_sequence_for{}; - } - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /*! @brief Used to wrap a function or a member of a specified type. */ - template - struct connect_arg_t {}; - - - /*! @brief Constant of type connect_arg_t used to disambiguate calls. */ - template - inline constexpr connect_arg_t connect_arg{}; - - - /** - * @brief Basic delegate implementation. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error unless the template parameter is a function type. - */ - template - class delegate; - - - /** - * @brief Utility class to use to send around functions and members. - * - * Unmanaged delegate for function pointers and members. Users of this class are - * in charge of disconnecting instances before deleting them. - * - * A delegate can be used as a general purpose invoker without memory overhead - * for free functions possibly with payloads and bound or unbound members. - * - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - */ - template - class delegate { - using proto_fn_type = Ret(const void*, Args...); - - template - auto wrap(std::index_sequence) ENTT_NOEXCEPT { - return [](const void*, Args... args) -> Ret { - const auto arguments = std::forward_as_tuple(std::forward(args)...); - return Ret(std::invoke(Candidate, std::forward>>(std::get(arguments))...)); - }; - } - - template - auto wrap(Type&, std::index_sequence) ENTT_NOEXCEPT { - return [](const void* payload, Args... args) -> Ret { - const auto arguments = std::forward_as_tuple(std::forward(args)...); - Type* curr = static_cast(const_cast, const void*, void*>>(payload)); - return Ret(std::invoke(Candidate, *curr, std::forward>>(std::get(arguments))...)); - }; - } - - template - auto wrap(Type*, std::index_sequence) ENTT_NOEXCEPT { - return [](const void* payload, Args... args) -> Ret { - const auto arguments = std::forward_as_tuple(std::forward(args)...); - Type* curr = static_cast(const_cast, const void*, void*>>(payload)); - return Ret(std::invoke(Candidate, curr, std::forward>>(std::get(arguments))...)); - }; - } - - public: - /*! @brief Function type of the delegate. */ - using function_type = Ret(Args...); - - /*! @brief Default constructor. */ - delegate() ENTT_NOEXCEPT - : fn{ nullptr }, data{ nullptr } - {} - - /** - * @brief Constructs a delegate and connects a free function or an unbound - * member. - * @tparam Candidate Function or member to connect to the delegate. - */ - template - delegate(connect_arg_t) ENTT_NOEXCEPT - : delegate{} - { - connect(); - } - - /** - * @brief Constructs a delegate and connects a free function with payload or - * a bound member. - * @tparam Candidate Function or member to connect to the delegate. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - */ - template - delegate(connect_arg_t, Type&& value_or_instance) ENTT_NOEXCEPT - : delegate{} - { - connect(std::forward(value_or_instance)); - } - - /** - * @brief Connects a free function or an unbound member to a delegate. - * @tparam Candidate Function or member to connect to the delegate. - */ - template - void connect() ENTT_NOEXCEPT { - data = nullptr; - - if constexpr (std::is_invocable_r_v) { - fn = [](const void*, Args... args) -> Ret { - return Ret(std::invoke(Candidate, std::forward(args)...)); - }; - } - else if constexpr (std::is_member_pointer_v) { - fn = wrap(internal::index_sequence_for>>(internal::function_pointer_t{})); - } - else { - fn = wrap(internal::index_sequence_for(internal::function_pointer_t{})); - } - } - - /** - * @brief Connects a free function with payload or a bound member to a - * delegate. - * - * The delegate isn't responsible for the connected object or the payload. - * Users must always guarantee that the lifetime of the instance overcomes - * the one of the delegate.
- * When used to connect a free function with payload, its signature must be - * such that the instance is the first argument before the ones used to - * define the delegate itself. - * - * @tparam Candidate Function or member to connect to the delegate. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid reference that fits the purpose. - */ - template - void connect(Type& value_or_instance) ENTT_NOEXCEPT { - data = &value_or_instance; - - if constexpr (std::is_invocable_r_v) { - fn = [](const void* payload, Args... args) -> Ret { - Type* curr = static_cast(const_cast, const void*, void*>>(payload)); - return Ret(std::invoke(Candidate, *curr, std::forward(args)...)); - }; - } - else { - fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); - } - } - - /** - * @brief Connects a free function with payload or a bound member to a - * delegate. - * - * @sa connect(Type &) - * - * @tparam Candidate Function or member to connect to the delegate. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid pointer that fits the purpose. - */ - template - void connect(Type* value_or_instance) ENTT_NOEXCEPT { - data = value_or_instance; - - if constexpr (std::is_invocable_r_v) { - fn = [](const void* payload, Args... args) -> Ret { - Type* curr = static_cast(const_cast, const void*, void*>>(payload)); - return Ret(std::invoke(Candidate, curr, std::forward(args)...)); - }; - } - else { - fn = wrap(value_or_instance, internal::index_sequence_for(internal::function_pointer_t{})); - } - } - - /** - * @brief Resets a delegate. - * - * After a reset, a delegate cannot be invoked anymore. - */ - void reset() ENTT_NOEXCEPT { - fn = nullptr; - data = nullptr; - } - - /** - * @brief Returns the instance or the payload linked to a delegate, if any. - * @return An opaque pointer to the underlying data. - */ - const void* instance() const ENTT_NOEXCEPT { - return data; - } - - /** - * @brief Triggers a delegate. - * - * The delegate invokes the underlying function and returns the result. - * - * @warning - * Attempting to trigger an invalid delegate results in undefined - * behavior.
- * An assertion will abort the execution at runtime in debug mode if the - * delegate has not yet been set. - * - * @param args Arguments to use to invoke the underlying function. - * @return The value returned by the underlying function. - */ - Ret operator()(Args... args) const { - ENTT_ASSERT(fn); - return fn(data, std::forward(args)...); - } - - /** - * @brief Checks whether a delegate actually stores a listener. - * @return False if the delegate is empty, true otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - // no need to test also data - return !(fn == nullptr); - } - - /** - * @brief Compares the contents of two delegates. - * @param other Delegate with which to compare. - * @return False if the two contents differ, true otherwise. - */ - bool operator==(const delegate& other) const ENTT_NOEXCEPT { - return fn == other.fn && data == other.data; - } - - private: - proto_fn_type* fn; - const void* data; - }; - - - /** - * @brief Compares the contents of two delegates. - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - * @param lhs A valid delegate object. - * @param rhs A valid delegate object. - * @return True if the two contents differ, false otherwise. - */ - template - bool operator!=(const delegate& lhs, const delegate& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - /** - * @brief Deduction guide. - * @tparam Candidate Function or member to connect to the delegate. - */ - template - delegate(connect_arg_t) ENTT_NOEXCEPT - ->delegate>>; - - - /** - * @brief Deduction guide. - * @tparam Candidate Function or member to connect to the delegate. - * @tparam Type Type of class or type of payload. - */ - template - delegate(connect_arg_t, Type&&) ENTT_NOEXCEPT - ->delegate>>; - - -} - - -#endif - -// #include "signal/dispatcher.hpp" -#ifndef ENTT_SIGNAL_DISPATCHER_HPP -#define ENTT_SIGNAL_DISPATCHER_HPP - - -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/fwd.hpp" -#ifndef ENTT_CORE_FWD_HPP -#define ENTT_CORE_FWD_HPP - - -// #include "../config/config.h" -#ifndef ENTT_CONFIG_CONFIG_H -#define ENTT_CONFIG_CONFIG_H - - -#ifndef ENTT_NOEXCEPT -# define ENTT_NOEXCEPT noexcept -#endif - - -#ifndef ENTT_HS_SUFFIX -# define ENTT_HS_SUFFIX _hs -#endif - - -#ifndef ENTT_HWS_SUFFIX -# define ENTT_HWS_SUFFIX _hws -#endif - - -#ifndef ENTT_USE_ATOMIC -# define ENTT_MAYBE_ATOMIC(Type) Type -#else -# include -# define ENTT_MAYBE_ATOMIC(Type) std::atomic -#endif - - -#ifndef ENTT_ID_TYPE -# include -# define ENTT_ID_TYPE std::uint32_t -#endif - - -#ifndef ENTT_PAGE_SIZE -# define ENTT_PAGE_SIZE 32768 -#endif - - -#ifndef ENTT_ASSERT -# include -# define ENTT_ASSERT(condition) assert(condition) -#endif - - -#ifndef ENTT_NO_ETO -# include -# define ENTT_IS_EMPTY(Type) std::is_empty_v -#else -# include -# // sfinae-friendly definition -# define ENTT_IS_EMPTY(Type) (false && std::is_empty_v) -#endif - - -#ifndef ENTT_STANDARD_CPP -# if defined _MSC_VER -# define ENTT_PRETTY_FUNCTION __FUNCSIG__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __clang__ || (defined __GNUC__ && __GNUC__ > 8) -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) constexpr -# elif defined __GNUC__ -# define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__ -# define ENTT_PRETTY_FUNCTION_CONSTEXPR(...) __VA_ARGS__ -# endif -#endif - - -#endif - - - -namespace entt { - - - /*! @brief Alias declaration for type identifiers. */ - using id_type = ENTT_ID_TYPE; - - -} - - -#endif - -// #include "../core/type_info.hpp" -#ifndef ENTT_CORE_TYPE_INFO_HPP -#define ENTT_CORE_TYPE_INFO_HPP - - -// #include "../config/config.h" - -// #include "../core/attribute.h" -#ifndef ENTT_CORE_ATTRIBUTE_H -#define ENTT_CORE_ATTRIBUTE_H - - -#ifndef ENTT_EXPORT -# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER -# define ENTT_EXPORT __declspec(dllexport) -# define ENTT_IMPORT __declspec(dllimport) -# define ENTT_HIDDEN -# elif defined __GNUC__ && __GNUC__ >= 4 -# define ENTT_EXPORT __attribute__((visibility("default"))) -# define ENTT_IMPORT __attribute__((visibility("default"))) -# define ENTT_HIDDEN __attribute__((visibility("hidden"))) -# else /* Unsupported compiler */ -# define ENTT_EXPORT -# define ENTT_IMPORT -# define ENTT_HIDDEN -# endif -#endif - - -#ifndef ENTT_API -# if defined ENTT_API_EXPORT -# define ENTT_API ENTT_EXPORT -# elif defined ENTT_API_IMPORT -# define ENTT_API ENTT_IMPORT -# else /* No API */ -# define ENTT_API -# endif -#endif - - -#endif - -// #include "hashed_string.hpp" -#ifndef ENTT_CORE_HASHED_STRING_HPP -#define ENTT_CORE_HASHED_STRING_HPP - - -#include -#include -// #include "../config/config.h" - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - template - struct fnv1a_traits; - - - template<> - struct fnv1a_traits { - using type = std::uint32_t; - static constexpr std::uint32_t offset = 2166136261; - static constexpr std::uint32_t prime = 16777619; - }; - - - template<> - struct fnv1a_traits { - using type = std::uint64_t; - static constexpr std::uint64_t offset = 14695981039346656037ull; - static constexpr std::uint64_t prime = 1099511628211ull; - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Zero overhead unique identifier. - * - * A hashed string is a compile-time tool that allows users to use - * human-readable identifers in the codebase while using their numeric - * counterparts at runtime.
- * Because of that, a hashed string can also be used in constant expressions if - * required. - * - * @tparam Char Character type. - */ - template - class basic_hashed_string { - using traits_type = internal::fnv1a_traits; - - struct const_wrapper { - // non-explicit constructor on purpose - constexpr const_wrapper(const Char* curr) ENTT_NOEXCEPT: str{ curr } {} - const Char* str; - }; - - // Fowler-Noll-Vo hash function v. 1a - the good - static constexpr id_type helper(const Char* curr) ENTT_NOEXCEPT { - auto value = traits_type::offset; - - while (*curr != 0) { - value = (value ^ static_cast(*(curr++))) * traits_type::prime; - } - - return value; - } - - public: - /*! @brief Character type. */ - using value_type = Char; - /*! @brief Unsigned integer type. */ - using hash_type = id_type; - - /** - * @brief Returns directly the numeric representation of a string. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * const auto value = basic_hashed_string::to_value("my.png"); - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - * @return The numeric representation of the string. - */ - template - static constexpr hash_type value(const value_type(&str)[N]) ENTT_NOEXCEPT { - return helper(str); - } - - /** - * @brief Returns directly the numeric representation of a string. - * @param wrapper Helps achieving the purpose by relying on overloading. - * @return The numeric representation of the string. - */ - static hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT { - return helper(wrapper.str); - } - - /** - * @brief Returns directly the numeric representation of a string view. - * @param str Human-readable identifer. - * @param size Length of the string to hash. - * @return The numeric representation of the string. - */ - static hash_type value(const value_type* str, std::size_t size) ENTT_NOEXCEPT { - id_type partial{ traits_type::offset }; - while (size--) { partial = (partial ^ (str++)[0]) * traits_type::prime; } - return partial; - } - - /*! @brief Constructs an empty hashed string. */ - constexpr basic_hashed_string() ENTT_NOEXCEPT - : str{ nullptr }, hash{} - {} - - /** - * @brief Constructs a hashed string from an array of const characters. - * - * Forcing template resolution avoids implicit conversions. An - * human-readable identifier can be anything but a plain, old bunch of - * characters.
- * Example of use: - * @code{.cpp} - * basic_hashed_string hs{"my.png"}; - * @endcode - * - * @tparam N Number of characters of the identifier. - * @param curr Human-readable identifer. - */ - template - constexpr basic_hashed_string(const value_type(&curr)[N]) ENTT_NOEXCEPT - : str{ curr }, hash{ helper(curr) } - {} - - /** - * @brief Explicit constructor on purpose to avoid constructing a hashed - * string directly from a `const value_type *`. - * @param wrapper Helps achieving the purpose by relying on overloading. - */ - explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT - : str{ wrapper.str }, hash{ helper(wrapper.str) } - {} - - /** - * @brief Returns the human-readable representation of a hashed string. - * @return The string used to initialize the instance. - */ - constexpr const value_type* data() const ENTT_NOEXCEPT { - return str; - } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr hash_type value() const ENTT_NOEXCEPT { - return hash; - } - - /*! @copydoc data */ - constexpr operator const value_type* () const ENTT_NOEXCEPT { return data(); } - - /** - * @brief Returns the numeric representation of a hashed string. - * @return The numeric representation of the instance. - */ - constexpr operator hash_type() const ENTT_NOEXCEPT { return value(); } - - /** - * @brief Compares two hashed strings. - * @param other Hashed string with which to compare. - * @return True if the two hashed strings are identical, false otherwise. - */ - constexpr bool operator==(const basic_hashed_string& other) const ENTT_NOEXCEPT { - return hash == other.hash; - } - - private: - const value_type* str; - hash_type hash; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the character type of the hashed string directly from a - * human-readable identifer provided to the constructor. - * - * @tparam Char Character type. - * @tparam N Number of characters of the identifier. - * @param str Human-readable identifer. - */ - template - basic_hashed_string(const Char(&str)[N]) ENTT_NOEXCEPT - ->basic_hashed_string; - - - /** - * @brief Compares two hashed strings. - * @tparam Char Character type. - * @param lhs A valid hashed string. - * @param rhs A valid hashed string. - * @return True if the two hashed strings are identical, false otherwise. - */ - template - constexpr bool operator!=(const basic_hashed_string& lhs, const basic_hashed_string& rhs) ENTT_NOEXCEPT { - return !(lhs == rhs); - } - - - /*! @brief Aliases for common character types. */ - using hashed_string = basic_hashed_string; - - - /*! @brief Aliases for common character types. */ - using hashed_wstring = basic_hashed_string; - - -} - - -/** - * @brief User defined literal for hashed strings. - * @param str The literal without its suffix. - * @return A properly initialized hashed string. - */ -constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_string{ str }; -} - - -/** - * @brief User defined literal for hashed wstrings. - * @param str The literal without its suffix. - * @return A properly initialized hashed wstring. - */ -constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t* str, std::size_t) ENTT_NOEXCEPT { - return entt::hashed_wstring{ str }; -} - - -#endif - -// #include "fwd.hpp" - - - -namespace entt { - - - /** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - - - namespace internal { - - - struct ENTT_API type_index { - static id_type next() ENTT_NOEXCEPT { - static ENTT_MAYBE_ATOMIC(id_type) value {}; - return value++; - } - }; - - - } - - - /** - * Internal details not to be documented. - * @endcond TURN_OFF_DOXYGEN - */ - - - /** - * @brief Type index. - * @tparam Type Type for which to generate a sequential identifier. - */ - template - struct ENTT_API type_index { - /** - * @brief Returns the sequential identifier of a given type. - * @return The sequential identifier of a given type. - */ - static id_type value() ENTT_NOEXCEPT { - static const id_type value = internal::type_index::next(); - return value; - } - }; - - - /** - * @brief Provides the member constant `value` to true if a given type is - * indexable, false otherwise. - * @tparam Type Potentially indexable type. - */ - template - struct has_type_index : std::false_type {}; - - - /*! @brief has_type_index */ - template - struct has_type_index::value())>> : std::true_type {}; - - - /** - * @brief Helper variable template. - * @tparam Type Potentially indexable type. - */ - template - inline constexpr bool has_type_index_v = has_type_index::value; - - - /** - * @brief Type info. - * @tparam Type Type for which to generate information. - */ - template - struct ENTT_API type_info { - /** - * @brief Returns the numeric representation of a given type. - * @return The numeric representation of the given type. - */ -#if defined ENTT_PRETTY_FUNCTION - static ENTT_PRETTY_FUNCTION_CONSTEXPR() id_type id() ENTT_NOEXCEPT { - ENTT_PRETTY_FUNCTION_CONSTEXPR(static const) auto value = entt::hashed_string::value(ENTT_PRETTY_FUNCTION); - return value; - } -#else - static id_type id() ENTT_NOEXCEPT { - return type_index::value(); - } -#endif - }; - - -} - - -#endif - -// #include "sigh.hpp" -#ifndef ENTT_SIGNAL_SIGH_HPP -#define ENTT_SIGNAL_SIGH_HPP - - -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "delegate.hpp" - -// #include "fwd.hpp" -#ifndef ENTT_SIGNAL_FWD_HPP -#define ENTT_SIGNAL_FWD_HPP - - -namespace entt { - - - /*! @class delegate */ - template - class delegate; - - /*! @class dispatcher */ - class dispatcher; - - /*! @class emitter */ - template - class emitter; - - /*! @class connection */ - class connection; - - /*! @class scoped_connection */ - struct scoped_connection; - - /*! @class sink */ - template - class sink; - - /*! @class sigh */ - template - class sigh; - - -} - - -#endif - - - -namespace entt { - - - /** - * @brief Sink class. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error unless the template parameter is a function type. - * - * @tparam Function A valid function type. - */ - template - class sink; - - - /** - * @brief Unmanaged signal handler. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error unless the template parameter is a function type. - * - * @tparam Function A valid function type. - */ - template - class sigh; - - - /** - * @brief Unmanaged signal handler. - * - * It works directly with references to classes and pointers to member functions - * as well as pointers to free functions. Users of this class are in charge of - * disconnecting instances before deleting them. - * - * This class serves mainly two purposes: - * - * * Creating signals to use later to notify a bunch of listeners. - * * Collecting results from a set of functions like in a voting system. - * - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - */ - template - class sigh { - /*! @brief A sink is allowed to modify a signal. */ - friend class sink; - - public: - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Sink type. */ - using sink_type = entt::sink; - - /** - * @brief Instance type when it comes to connecting member functions. - * @tparam Class Type of class to which the member function belongs. - */ - template - using instance_type = Class*; - - /** - * @brief Number of listeners connected to the signal. - * @return Number of listeners currently connected. - */ - size_type size() const ENTT_NOEXCEPT { - return calls.size(); - } - - /** - * @brief Returns false if at least a listener is connected to the signal. - * @return True if the signal has no listeners connected, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return calls.empty(); - } - - /** - * @brief Triggers a signal. - * - * All the listeners are notified. Order isn't guaranteed. - * - * @param args Arguments to use to invoke listeners. - */ - void publish(Args... args) const { - for (auto&& call : std::as_const(calls)) { - call(args...); - } - } - - /** - * @brief Collects return values from the listeners. - * - * The collector must expose a call operator with the following properties: - * - * * The return type is either `void` or such that it's convertible to - * `bool`. In the second case, a true value will stop the iteration. - * * The list of parameters is empty if `Ret` is `void`, otherwise it - * contains a single element such that `Ret` is convertible to it. - * - * @tparam Func Type of collector to use, if any. - * @param func A valid function object. - * @param args Arguments to use to invoke listeners. - */ - template - void collect(Func func, Args... args) const { - for (auto&& call : calls) { - if constexpr (std::is_void_v) { - if constexpr (std::is_invocable_r_v) { - call(args...); - if (func()) { break; } - } - else { - call(args...); - func(); - } - } - else { - if constexpr (std::is_invocable_r_v) { - if (func(call(args...))) { break; } - } - else { - func(call(args...)); - } - } - } - } - - private: - std::vector> calls; - }; - - - /** - * @brief Connection class. - * - * Opaque object the aim of which is to allow users to release an already - * estabilished connection without having to keep a reference to the signal or - * the sink that generated it. - */ - class connection { - /*! @brief A sink is allowed to create connection objects. */ - template - friend class sink; - - connection(delegate fn, void* ref) - : disconnect{ fn }, signal{ ref } - {} - - public: - /*! @brief Default constructor. */ - connection() = default; - - /** - * @brief Checks whether a connection is properly initialized. - * @return True if the connection is properly initialized, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return static_cast(disconnect); - } - - /*! @brief Breaks the connection. */ - void release() { - if (disconnect) { - disconnect(signal); - disconnect.reset(); - } - } - - private: - delegate disconnect; - void* signal{}; - }; - - - /** - * @brief Scoped connection class. - * - * Opaque object the aim of which is to allow users to release an already - * estabilished connection without having to keep a reference to the signal or - * the sink that generated it.
- * A scoped connection automatically breaks the link between the two objects - * when it goes out of scope. - */ - struct scoped_connection { - /*! @brief Default constructor. */ - scoped_connection() = default; - - /** - * @brief Constructs a scoped connection from a basic connection. - * @param other A valid connection object. - */ - scoped_connection(const connection& other) - : conn{ other } - {} - - /*! @brief Default copy constructor, deleted on purpose. */ - scoped_connection(const scoped_connection&) = delete; - - /*! @brief Automatically breaks the link on destruction. */ - ~scoped_connection() { - conn.release(); - } - - /** - * @brief Default copy assignment operator, deleted on purpose. - * @return This scoped connection. - */ - scoped_connection& operator=(const scoped_connection&) = delete; - - /** - * @brief Acquires a connection. - * @param other The connection object to acquire. - * @return This scoped connection. - */ - scoped_connection& operator=(connection other) { - conn = std::move(other); - return *this; - } - - /** - * @brief Checks whether a scoped connection is properly initialized. - * @return True if the connection is properly initialized, false otherwise. - */ - explicit operator bool() const ENTT_NOEXCEPT { - return static_cast(conn); - } - - /*! @brief Breaks the connection. */ - void release() { - conn.release(); - } - - private: - connection conn; - }; - - - /** - * @brief Sink class. - * - * A sink is used to connect listeners to signals and to disconnect them.
- * The function type for a listener is the one of the signal to which it - * belongs. - * - * The clear separation between a signal and a sink permits to store the former - * as private data member without exposing the publish functionality to the - * users of the class. - * - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - */ - template - class sink { - using signal_type = sigh; - using difference_type = typename std::iterator_traits::difference_type; - - template - static void release(Type value_or_instance, void* signal) { - sink{ *static_cast(signal) }.disconnect(value_or_instance); - } - - template - static void release(void* signal) { - sink{ *static_cast(signal) }.disconnect(); - } - - public: - /** - * @brief Constructs a sink that is allowed to modify a given signal. - * @param ref A valid reference to a signal object. - */ - sink(sigh& ref) ENTT_NOEXCEPT - : offset{}, - signal{ &ref } - {} - - /** - * @brief Returns false if at least a listener is connected to the sink. - * @return True if the sink has no listeners connected, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return signal->calls.empty(); - } - - /** - * @brief Returns a sink that connects before a given free function or an - * unbound member. - * @tparam Function A valid free function pointer. - * @return A properly initialized sink object. - */ - template - sink before() { - delegate call{}; - call.template connect(); - - const auto& calls = signal->calls; - const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call)); - - sink other{ *this }; - other.offset = std::distance(it, calls.cend()); - return other; - } - - /** - * @brief Returns a sink that connects before a free function with payload - * or a bound member. - * @tparam Candidate Member or free function to look for. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - * @return A properly initialized sink object. - */ - template - sink before(Type&& value_or_instance) { - delegate call{}; - call.template connect(std::forward(value_or_instance)); - - const auto& calls = signal->calls; - const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call)); - - sink other{ *this }; - other.offset = std::distance(it, calls.cend()); - return other; - } - - /** - * @brief Returns a sink that connects before a given instance or specific - * payload. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - * @return A properly initialized sink object. - */ - template - sink before(Type& value_or_instance) { - return before(&value_or_instance); - } - - /** - * @brief Returns a sink that connects before a given instance or specific - * payload. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid pointer that fits the purpose. - * @return A properly initialized sink object. - */ - template - sink before(Type* value_or_instance) { - sink other{ *this }; - - if (value_or_instance) { - const auto& calls = signal->calls; - const auto it = std::find_if(calls.cbegin(), calls.cend(), [value_or_instance](const auto& delegate) { - return delegate.instance() == value_or_instance; - }); - - other.offset = std::distance(it, calls.cend()); - } - - return other; - } - - /** - * @brief Returns a sink that connects before anything else. - * @return A properly initialized sink object. - */ - sink before() { - sink other{ *this }; - other.offset = signal->calls.size(); - return other; - } - - /** - * @brief Connects a free function or an unbound member to a signal. - * - * The signal handler performs checks to avoid multiple connections for the - * same function. - * - * @tparam Candidate Function or member to connect to the signal. - * @return A properly initialized connection object. - */ - template - connection connect() { - disconnect(); - - delegate call{}; - call.template connect(); - signal->calls.insert(signal->calls.end() - offset, std::move(call)); - - delegate conn{}; - conn.template connect<&release>(); - return { std::move(conn), signal }; - } - - /** - * @brief Connects a free function with payload or a bound member to a - * signal. - * - * The signal isn't responsible for the connected object or the payload. - * Users must always guarantee that the lifetime of the instance overcomes - * the one of the signal. On the other side, the signal handler performs - * checks to avoid multiple connections for the same function.
- * When used to connect a free function with payload, its signature must be - * such that the instance is the first argument before the ones used to - * define the signal itself. - * - * @tparam Candidate Function or member to connect to the signal. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - * @return A properly initialized connection object. - */ - template - connection connect(Type&& value_or_instance) { - disconnect(value_or_instance); - - delegate call{}; - call.template connect(value_or_instance); - signal->calls.insert(signal->calls.end() - offset, std::move(call)); - - delegate conn{}; - conn.template connect<&release>(value_or_instance); - return { std::move(conn), signal }; - } - - /** - * @brief Disconnects a free function or an unbound member from a signal. - * @tparam Candidate Function or member to disconnect from the signal. - */ - template - void disconnect() { - auto& calls = signal->calls; - delegate call{}; - call.template connect(); - calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end()); - } - - /** - * @brief Disconnects a free function with payload or a bound member from a - * signal. - * @tparam Candidate Function or member to disconnect from the signal. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - */ - template - void disconnect(Type&& value_or_instance) { - auto& calls = signal->calls; - delegate call{}; - call.template connect(std::forward(value_or_instance)); - calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end()); - } - - /** - * @brief Disconnects free functions with payload or bound members from a - * signal. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - */ - template - void disconnect(Type& value_or_instance) { - disconnect(&value_or_instance); - } - - /** - * @brief Disconnects free functions with payload or bound members from a - * signal. - * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid object that fits the purpose. - */ - template - void disconnect(Type* value_or_instance) { - if (value_or_instance) { - auto& calls = signal->calls; - calls.erase(std::remove_if(calls.begin(), calls.end(), [value_or_instance](const auto& delegate) { - return delegate.instance() == value_or_instance; - }), calls.end()); - } - } - - /*! @brief Disconnects all the listeners from a signal. */ - void disconnect() { - signal->calls.clear(); - } - - private: - difference_type offset; - signal_type* signal; - }; - - - /** - * @brief Deduction guide. - * - * It allows to deduce the function type of a sink directly from the signal it - * refers to. - * - * @tparam Ret Return type of a function type. - * @tparam Args Types of arguments of a function type. - */ - template - sink(sigh&) ENTT_NOEXCEPT->sink; - - -} - - -#endif - - - -namespace entt { - - - /** - * @brief Basic dispatcher implementation. - * - * A dispatcher can be used either to trigger an immediate event or to enqueue - * events to be published all together once per tick.
- * Listeners are provided in the form of member functions. For each event of - * type `Event`, listeners are such that they can be invoked with an argument of - * type `const Event &`, no matter what the return type is. - * - * The dispatcher creates instances of the `sigh` class internally. Refer to the - * documentation of the latter for more details. - */ - class dispatcher { - struct basic_pool { - virtual ~basic_pool() = default; - virtual void publish() = 0; - virtual void clear() ENTT_NOEXCEPT = 0; - virtual id_type type_id() const ENTT_NOEXCEPT = 0; - }; - - template - struct pool_handler final : basic_pool { - using signal_type = sigh; - using sink_type = typename signal_type::sink_type; - - void publish() override { - const auto length = events.size(); - - for (std::size_t pos{}; pos < length; ++pos) { - signal.publish(events[pos]); - } - - events.erase(events.cbegin(), events.cbegin() + length); - } - - void clear() ENTT_NOEXCEPT override { - events.clear(); - } - - sink_type sink() ENTT_NOEXCEPT { - return entt::sink{ signal }; - } - - template - void trigger(Args &&... args) { - signal.publish(Event{ std::forward(args)... }); - } - - template - void enqueue(Args &&... args) { - events.emplace_back(std::forward(args)...); - } - - id_type type_id() const ENTT_NOEXCEPT override { - return type_info::id(); - } - - private: - signal_type signal{}; - std::vector events; - }; - - template - pool_handler& assure() { - static_assert(std::is_same_v>); - - if constexpr (has_type_index_v) { - const auto index = type_index::value(); - - if (!(index < pools.size())) { - pools.resize(index + 1); - } - - if (!pools[index]) { - pools[index].reset(new pool_handler{}); - } - - return static_cast &>(*pools[index]); - } - else { - auto it = std::find_if(pools.begin(), pools.end(), [id = type_info::id()](const auto& cpool) { return id == cpool->type_id(); }); - return static_cast &>(it == pools.cend() ? *pools.emplace_back(new pool_handler{}) : **it); - } - } - - public: - /** - * @brief Returns a sink object for the given event. - * - * A sink is an opaque object used to connect listeners to events. - * - * The function type for a listener is: - * @code{.cpp} - * void(const Event &); - * @endcode - * - * The order of invocation of the listeners isn't guaranteed. - * - * @sa sink - * - * @tparam Event Type of event of which to get the sink. - * @return A temporary sink object. - */ - template - auto sink() { - return assure().sink(); - } - - /** - * @brief Triggers an immediate event of the given type. - * - * All the listeners registered for the given type are immediately notified. - * The event is discarded after the execution. - * - * @tparam Event Type of event to trigger. - * @tparam Args Types of arguments to use to construct the event. - * @param args Arguments to use to construct the event. - */ - template - void trigger(Args &&... args) { - assure().trigger(std::forward(args)...); - } - - /** - * @brief Triggers an immediate event of the given type. - * - * All the listeners registered for the given type are immediately notified. - * The event is discarded after the execution. - * - * @tparam Event Type of event to trigger. - * @param event An instance of the given type of event. - */ - template - void trigger(Event&& event) { - assure>().trigger(std::forward(event)); - } - - /** - * @brief Enqueues an event of the given type. - * - * An event of the given type is queued. No listener is invoked. Use the - * `update` member function to notify listeners when ready. - * - * @tparam Event Type of event to enqueue. - * @tparam Args Types of arguments to use to construct the event. - * @param args Arguments to use to construct the event. - */ - template - void enqueue(Args &&... args) { - assure().enqueue(std::forward(args)...); - } - - /** - * @brief Enqueues an event of the given type. - * - * An event of the given type is queued. No listener is invoked. Use the - * `update` member function to notify listeners when ready. - * - * @tparam Event Type of event to enqueue. - * @param event An instance of the given type of event. - */ - template - void enqueue(Event&& event) { - assure>().enqueue(std::forward(event)); - } - - /** - * @brief Discards all the events queued so far. - * - * If no types are provided, the dispatcher will clear all the existing - * pools. - * - * @tparam Event Type of events to discard. - */ - template - void clear() { - if constexpr (sizeof...(Event) == 0) { - for (auto&& cpool : pools) { - if (cpool) { - cpool->clear(); - } - } - } - else { - (assure().clear(), ...); - } - } - - /** - * @brief Delivers all the pending events of the given type. - * - * This method is blocking and it doesn't return until all the events are - * delivered to the registered listeners. It's responsibility of the users - * to reduce at a minimum the time spent in the bodies of the listeners. - * - * @tparam Event Type of events to send. - */ - template - void update() { - assure().publish(); - } - - /** - * @brief Delivers all the pending events. - * - * This method is blocking and it doesn't return until all the events are - * delivered to the registered listeners. It's responsibility of the users - * to reduce at a minimum the time spent in the bodies of the listeners. - */ - void update() const { - for (auto pos = pools.size(); pos; --pos) { - if (auto&& cpool = pools[pos - 1]; cpool) { - cpool->publish(); - } - } - } - - private: - std::vector> pools; - }; - - -} - - -#endif - -// #include "signal/emitter.hpp" -#ifndef ENTT_SIGNAL_EMITTER_HPP -#define ENTT_SIGNAL_EMITTER_HPP - - -#include -#include -#include -#include -#include -#include -#include -#include -// #include "../config/config.h" - -// #include "../core/fwd.hpp" - -// #include "../core/type_info.hpp" - - - -namespace entt { - - - /** - * @brief General purpose event emitter. - * - * The emitter class template follows the CRTP idiom. To create a custom emitter - * type, derived classes must inherit directly from the base class as: - * - * @code{.cpp} - * struct my_emitter: emitter { - * // ... - * } - * @endcode - * - * Pools for the type of events are created internally on the fly. It's not - * required to specify in advance the full list of accepted types.
- * Moreover, whenever an event is published, an emitter provides the listeners - * with a reference to itself along with a const reference to the event. - * Therefore listeners have an handy way to work with it without incurring in - * the need of capturing a reference to the emitter. - * - * @tparam Derived Actual type of emitter that extends the class template. - */ - template - class emitter { - struct basic_pool { - virtual ~basic_pool() = default; - virtual bool empty() const ENTT_NOEXCEPT = 0; - virtual void clear() ENTT_NOEXCEPT = 0; - virtual id_type type_id() const ENTT_NOEXCEPT = 0; - }; - - template - struct pool_handler final : basic_pool { - using listener_type = std::function; - using element_type = std::pair; - using container_type = std::list; - using connection_type = typename container_type::iterator; - - bool empty() const ENTT_NOEXCEPT override { - auto pred = [](auto&& element) { return element.first; }; - - return std::all_of(once_list.cbegin(), once_list.cend(), pred) && - std::all_of(on_list.cbegin(), on_list.cend(), pred); - } - - void clear() ENTT_NOEXCEPT override { - if (publishing) { - for (auto&& element : once_list) { - element.first = true; - } - - for (auto&& element : on_list) { - element.first = true; - } - } - else { - once_list.clear(); - on_list.clear(); - } - } - - connection_type once(listener_type listener) { - return once_list.emplace(once_list.cend(), false, std::move(listener)); - } - - connection_type on(listener_type listener) { - return on_list.emplace(on_list.cend(), false, std::move(listener)); - } - - void erase(connection_type conn) { - conn->first = true; - - if (!publishing) { - auto pred = [](auto&& element) { return element.first; }; - once_list.remove_if(pred); - on_list.remove_if(pred); - } - } - - void publish(const Event& event, Derived& ref) { - container_type swap_list; - once_list.swap(swap_list); - - publishing = true; - - for (auto&& element : on_list) { - element.first ? void() : element.second(event, ref); - } - - for (auto&& element : swap_list) { - element.first ? void() : element.second(event, ref); - } - - publishing = false; - - on_list.remove_if([](auto&& element) { return element.first; }); - } - - id_type type_id() const ENTT_NOEXCEPT override { - return type_info::id(); - } - - private: - bool publishing{ false }; - container_type once_list{}; - container_type on_list{}; - }; - - template - const pool_handler& assure() const { - static_assert(std::is_same_v>); - - if constexpr (has_type_index_v) { - const auto index = type_index::value(); - - if (!(index < pools.size())) { - pools.resize(index + 1); - } - - if (!pools[index]) { - pools[index].reset(new pool_handler{}); - } - - return static_cast &>(*pools[index]); - } - else { - auto it = std::find_if(pools.begin(), pools.end(), [id = type_info::id()](const auto& cpool) { return id == cpool->type_id(); }); - return static_cast &>(it == pools.cend() ? *pools.emplace_back(new pool_handler{}) : **it); - } - } - - template - pool_handler& assure() { - return const_cast &>(std::as_const(*this).template assure()); - } - - public: - /** @brief Type of listeners accepted for the given event. */ - template - using listener = typename pool_handler::listener_type; - - /** - * @brief Generic connection type for events. - * - * Type of the connection object returned by the event emitter whenever a - * listener for the given type is registered.
- * It can be used to break connections still in use. - * - * @tparam Event Type of event for which the connection is created. - */ - template - struct connection : private pool_handler::connection_type { - /** @brief Event emitters are friend classes of connections. */ - friend class emitter; - - /*! @brief Default constructor. */ - connection() = default; - - /** - * @brief Creates a connection that wraps its underlying instance. - * @param conn A connection object to wrap. - */ - connection(typename pool_handler::connection_type conn) - : pool_handler::connection_type{ std::move(conn) } - {} - }; - - /*! @brief Default constructor. */ - emitter() = default; - - /*! @brief Default destructor. */ - virtual ~emitter() { - static_assert(std::is_base_of_v, Derived>); - } - - /*! @brief Default move constructor. */ - emitter(emitter&&) = default; - - /*! @brief Default move assignment operator. @return This emitter. */ - emitter& operator=(emitter&&) = default; - - /** - * @brief Emits the given event. - * - * All the listeners registered for the specific event type are invoked with - * the given event. The event type must either have a proper constructor for - * the arguments provided or be an aggregate type. - * - * @tparam Event Type of event to publish. - * @tparam Args Types of arguments to use to construct the event. - * @param args Parameters to use to initialize the event. - */ - template - void publish(Args &&... args) { - assure().publish(Event{ std::forward(args)... }, *static_cast(this)); - } - - /** - * @brief Registers a long-lived listener with the event emitter. - * - * This method can be used to register a listener designed to be invoked - * more than once for the given event type.
- * The connection returned by the method can be freely discarded. It's meant - * to be used later to disconnect the listener if required. - * - * The listener is as a callable object that can be moved and the type of - * which is `void(const Event &, Derived &)`. - * - * @note - * Whenever an event is emitted, the emitter provides the listener with a - * reference to the derived class. Listeners don't have to capture those - * instances for later uses. - * - * @tparam Event Type of event to which to connect the listener. - * @param instance The listener to register. - * @return Connection object that can be used to disconnect the listener. - */ - template - connection on(listener instance) { - return assure().on(std::move(instance)); - } - - /** - * @brief Registers a short-lived listener with the event emitter. - * - * This method can be used to register a listener designed to be invoked - * only once for the given event type.
- * The connection returned by the method can be freely discarded. It's meant - * to be used later to disconnect the listener if required. - * - * The listener is as a callable object that can be moved and the type of - * which is `void(const Event &, Derived &)`. - * - * @note - * Whenever an event is emitted, the emitter provides the listener with a - * reference to the derived class. Listeners don't have to capture those - * instances for later uses. - * - * @tparam Event Type of event to which to connect the listener. - * @param instance The listener to register. - * @return Connection object that can be used to disconnect the listener. - */ - template - connection once(listener instance) { - return assure().once(std::move(instance)); - } - - /** - * @brief Disconnects a listener from the event emitter. - * - * Do not use twice the same connection to disconnect a listener, it results - * in undefined behavior. Once used, discard the connection object. - * - * @tparam Event Type of event of the connection. - * @param conn A valid connection. - */ - template - void erase(connection conn) { - assure().erase(std::move(conn)); - } - - /** - * @brief Disconnects all the listeners for the given event type. - * - * All the connections previously returned for the given event are - * invalidated. Using them results in undefined behavior. - * - * @tparam Event Type of event to reset. - */ - template - void clear() { - assure().clear(); - } - - /** - * @brief Disconnects all the listeners. - * - * All the connections previously returned are invalidated. Using them - * results in undefined behavior. - */ - void clear() ENTT_NOEXCEPT { - for (auto&& cpool : pools) { - if (cpool) { - cpool->clear(); - } - } - } - - /** - * @brief Checks if there are listeners registered for the specific event. - * @tparam Event Type of event to test. - * @return True if there are no listeners registered, false otherwise. - */ - template - bool empty() const { - return assure().empty(); - } - - /** - * @brief Checks if there are listeners registered with the event emitter. - * @return True if there are no listeners registered, false otherwise. - */ - bool empty() const ENTT_NOEXCEPT { - return std::all_of(pools.cbegin(), pools.cend(), [](auto&& cpool) { - return !cpool || cpool->empty(); - }); - } - - private: - mutable std::vector> pools{}; - }; - - -} - - -#endif - -// #include "signal/sigh.hpp" - diff --git a/Dependencies/stb_image/build.lua b/Dependencies/stb_image/build.lua deleted file mode 100644 index 3b5bf32..0000000 --- a/Dependencies/stb_image/build.lua +++ /dev/null @@ -1,48 +0,0 @@ -project "stb_image" - - -- Output Directories -- - location "%{wks.location}/Dependencies/stb_image" - - targetdir (target_dir) - objdir (object_dir) - - -- Compiler -- - kind "StaticLib" - language "C" - - -- Project Files --- - files - { - "stb_image.c", - "stb_image.h", - - "%{prj.location}/build.lua", - } - - --- Filters --- - -- windows - filter "system:windows" - systemversion "latest" - staticruntime "On" - - defines - { - "_CRT_SECURE_NO_WARNINGS", - } - - flags { "MultiProcessorCompile" } - - -- debug - filter "configurations:Debug" - runtime "Debug" - symbols "on" - - -- release - filter "configurations:Release" - runtime "Release" - optimize "on" - - -- distribution - filter "configurations:Distribution" - runtime "Release" - optimize "full" \ No newline at end of file diff --git a/Dependencies/stb_image/stb_image.c b/Dependencies/stb_image/stb_image.c deleted file mode 100644 index e4d0a33..0000000 --- a/Dependencies/stb_image/stb_image.c +++ /dev/null @@ -1,7130 +0,0 @@ -#include "stb_image.h" - -#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ - || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ - || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ - || defined(STBI_ONLY_ZLIB) -#ifndef STBI_ONLY_JPEG -#define STBI_NO_JPEG -#endif -#ifndef STBI_ONLY_PNG -#define STBI_NO_PNG -#endif -#ifndef STBI_ONLY_BMP -#define STBI_NO_BMP -#endif -#ifndef STBI_ONLY_PSD -#define STBI_NO_PSD -#endif -#ifndef STBI_ONLY_TGA -#define STBI_NO_TGA -#endif -#ifndef STBI_ONLY_GIF -#define STBI_NO_GIF -#endif -#ifndef STBI_ONLY_HDR -#define STBI_NO_HDR -#endif -#ifndef STBI_ONLY_PIC -#define STBI_NO_PIC -#endif -#ifndef STBI_ONLY_PNM -#define STBI_NO_PNM -#endif -#endif - -#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) -#define STBI_NO_ZLIB -#endif - - -#include -#include // ptrdiff_t on osx -#include -#include -#include - -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -#include // ldexp, pow -#endif - -#ifndef STBI_NO_STDIO -#include -#endif - -#ifndef STBI_ASSERT -#include -#define STBI_ASSERT(x) assert(x) -#endif - -#ifdef __cplusplus -#define STBI_EXTERN extern "C" -#else -#define STBI_EXTERN extern -#endif - - -#ifndef _MSC_VER -#ifdef __cplusplus -#define stbi_inline inline -#else -#define stbi_inline -#endif -#else -#define stbi_inline __forceinline -#endif - -#ifndef STBI_NO_THREAD_LOCALS -#if defined(__cplusplus) && __cplusplus >= 201103L -#define STBI_THREAD_LOCAL thread_local -#elif defined(__GNUC__) && __GNUC__ < 5 -#define STBI_THREAD_LOCAL __thread -#elif defined(_MSC_VER) -#define STBI_THREAD_LOCAL __declspec(thread) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) -#define STBI_THREAD_LOCAL _Thread_local -#endif - -#ifndef STBI_THREAD_LOCAL -#if defined(__GNUC__) -#define STBI_THREAD_LOCAL __thread -#endif -#endif -#endif - -#ifdef _MSC_VER -typedef unsigned short stbi__uint16; -typedef signed short stbi__int16; -typedef unsigned int stbi__uint32; -typedef signed int stbi__int32; -#else -#include -typedef uint16_t stbi__uint16; -typedef int16_t stbi__int16; -typedef uint32_t stbi__uint32; -typedef int32_t stbi__int32; -#endif - -// should produce compiler error if size is wrong -typedef unsigned char validate_uint32[sizeof(stbi__uint32) == 4 ? 1 : -1]; - -#ifdef _MSC_VER -#define STBI_NOTUSED(v) (void)(v) -#else -#define STBI_NOTUSED(v) (void)sizeof(v) -#endif - -#ifdef _MSC_VER -#define STBI_HAS_LROTL -#endif - -#ifdef STBI_HAS_LROTL -#define stbi_lrot(x,y) _lrotl(x,y) -#else -#define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) -#endif - -#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) -// ok -#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) -// ok -#else -#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." -#endif - -#ifndef STBI_MALLOC -#define STBI_MALLOC(sz) malloc(sz) -#define STBI_REALLOC(p,newsz) realloc(p,newsz) -#define STBI_FREE(p) free(p) -#endif - -#ifndef STBI_REALLOC_SIZED -#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) -#endif - -// x86/x64 detection -#if defined(__x86_64__) || defined(_M_X64) -#define STBI__X64_TARGET -#elif defined(__i386) || defined(_M_IX86) -#define STBI__X86_TARGET -#endif - -#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) -// gcc doesn't support sse2 intrinsics unless you compile with -msse2, -// which in turn means it gets to use SSE2 everywhere. This is unfortunate, -// but previous attempts to provide the SSE2 functions with runtime -// detection caused numerous issues. The way architecture extensions are -// exposed in GCC/Clang is, sadly, not really suited for one-file libs. -// New behavior: if compiled with -msse2, we use SSE2 without any -// detection; if not, we don't use it at all. -#define STBI_NO_SIMD -#endif - -#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) -// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET -// -// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the -// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. -// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not -// simultaneously enabling "-mstackrealign". -// -// See https://github.com/nothings/stb/issues/81 for more information. -// -// So default to no SSE2 on 32-bit MinGW. If you've read this far and added -// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. -#define STBI_NO_SIMD -#endif - -#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) -#define STBI_SSE2 -#include - -#ifdef _MSC_VER - -#if _MSC_VER >= 1400 // not VC6 -#include // __cpuid -static int stbi__cpuid3(void) -{ - int info[4]; - __cpuid(info, 1); - return info[3]; -} -#else -static int stbi__cpuid3(void) -{ - int res; - __asm { - mov eax, 1 - cpuid - mov res, edx - } - return res; -} -#endif - -#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name - -#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) -static int stbi__sse2_available(void) -{ - int info3 = stbi__cpuid3(); - return ((info3 >> 26) & 1) != 0; -} -#endif - -#else // assume GCC-style if not VC++ -#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) - -#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) -static int stbi__sse2_available(void) -{ - // If we're even attempting to compile this on GCC/Clang, that means - // -msse2 is on, which means the compiler is allowed to use SSE2 - // instructions at will, and so are we. - return 1; -} -#endif - -#endif -#endif - -// ARM NEON -#if defined(STBI_NO_SIMD) && defined(STBI_NEON) -#undef STBI_NEON -#endif - -#ifdef STBI_NEON -#include -// assume GCC or Clang on ARM targets -#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) -#endif - -#ifndef STBI_SIMD_ALIGN -#define STBI_SIMD_ALIGN(type, name) type name -#endif - -#ifndef STBI_MAX_DIMENSIONS -#define STBI_MAX_DIMENSIONS (1 << 24) -#endif - -/////////////////////////////////////////////// -// -// stbi__context struct and start_xxx functions - -// stbi__context structure is our basic context used by all images, so it -// contains all the IO context, plus some basic image information -typedef struct -{ - stbi__uint32 img_x, img_y; - int img_n, img_out_n; - - stbi_io_callbacks io; - void* io_user_data; - - int read_from_callbacks; - int buflen; - stbi_uc buffer_start[128]; - int callback_already_read; - - stbi_uc* img_buffer, * img_buffer_end; - stbi_uc* img_buffer_original, * img_buffer_original_end; -} stbi__context; - - -static void stbi__refill_buffer(stbi__context* s); - -// initialize a memory-decode context -static void stbi__start_mem(stbi__context* s, stbi_uc const* buffer, int len) -{ - s->io.read = NULL; - s->read_from_callbacks = 0; - s->callback_already_read = 0; - s->img_buffer = s->img_buffer_original = (stbi_uc*)buffer; - s->img_buffer_end = s->img_buffer_original_end = (stbi_uc*)buffer + len; -} - -// initialize a callback-based context -static void stbi__start_callbacks(stbi__context* s, stbi_io_callbacks* c, void* user) -{ - s->io = *c; - s->io_user_data = user; - s->buflen = sizeof(s->buffer_start); - s->read_from_callbacks = 1; - s->callback_already_read = 0; - s->img_buffer = s->img_buffer_original = s->buffer_start; - stbi__refill_buffer(s); - s->img_buffer_original_end = s->img_buffer_end; -} - -#ifndef STBI_NO_STDIO - -static int stbi__stdio_read(void* user, char* data, int size) -{ - return (int)fread(data, 1, size, (FILE*)user); -} - -static void stbi__stdio_skip(void* user, int n) -{ - int ch; - fseek((FILE*)user, n, SEEK_CUR); - ch = fgetc((FILE*)user); /* have to read a byte to reset feof()'s flag */ - if (ch != EOF) { - ungetc(ch, (FILE*)user); /* push byte back onto stream if valid. */ - } -} - -static int stbi__stdio_eof(void* user) -{ - return feof((FILE*)user) || ferror((FILE*)user); -} - -static stbi_io_callbacks stbi__stdio_callbacks = -{ - stbi__stdio_read, - stbi__stdio_skip, - stbi__stdio_eof, -}; - -static void stbi__start_file(stbi__context* s, FILE* f) -{ - stbi__start_callbacks(s, &stbi__stdio_callbacks, (void*)f); -} - -//static void stop_file(stbi__context *s) { } - -#endif // !STBI_NO_STDIO - -static void stbi__rewind(stbi__context* s) -{ - // conceptually rewind SHOULD rewind to the beginning of the stream, - // but we just rewind to the beginning of the initial buffer, because - // we only use it after doing 'test', which only ever looks at at most 92 bytes - s->img_buffer = s->img_buffer_original; - s->img_buffer_end = s->img_buffer_original_end; -} - -enum -{ - STBI_ORDER_RGB, - STBI_ORDER_BGR -}; - -typedef struct -{ - int bits_per_channel; - int num_channels; - int channel_order; -} stbi__result_info; - -#ifndef STBI_NO_JPEG -static int stbi__jpeg_test(stbi__context* s); -static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri); -static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp); -#endif - -#ifndef STBI_NO_PNG -static int stbi__png_test(stbi__context* s); -static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri); -static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp); -static int stbi__png_is16(stbi__context* s); -#endif - -#ifndef STBI_NO_BMP -static int stbi__bmp_test(stbi__context* s); -static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri); -static int stbi__bmp_info(stbi__context* s, int* x, int* y, int* comp); -#endif - -#ifndef STBI_NO_TGA -static int stbi__tga_test(stbi__context* s); -static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri); -static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp); -#endif - -#ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context* s); -static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc); -static int stbi__psd_info(stbi__context* s, int* x, int* y, int* comp); -static int stbi__psd_is16(stbi__context* s); -#endif - -#ifndef STBI_NO_HDR -static int stbi__hdr_test(stbi__context* s); -static float* stbi__hdr_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri); -static int stbi__hdr_info(stbi__context* s, int* x, int* y, int* comp); -#endif - -#ifndef STBI_NO_PIC -static int stbi__pic_test(stbi__context* s); -static void* stbi__pic_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri); -static int stbi__pic_info(stbi__context* s, int* x, int* y, int* comp); -#endif - -#ifndef STBI_NO_GIF -static int stbi__gif_test(stbi__context* s); -static void* stbi__gif_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri); -static void* stbi__load_gif_main(stbi__context* s, int** delays, int* x, int* y, int* z, int* comp, int req_comp); -static int stbi__gif_info(stbi__context* s, int* x, int* y, int* comp); -#endif - -#ifndef STBI_NO_PNM -static int stbi__pnm_test(stbi__context* s); -static void* stbi__pnm_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri); -static int stbi__pnm_info(stbi__context* s, int* x, int* y, int* comp); -#endif - -static -#ifdef STBI_THREAD_LOCAL -STBI_THREAD_LOCAL -#endif -const char* stbi__g_failure_reason; - -STBIDEF const char* stbi_failure_reason(void) -{ - return stbi__g_failure_reason; -} - -#ifndef STBI_NO_FAILURE_STRINGS -static int stbi__err(const char* str) -{ - stbi__g_failure_reason = str; - return 0; -} -#endif - -static void* stbi__malloc(size_t size) -{ - return STBI_MALLOC(size); -} - -// stb_image uses ints pervasively, including for offset calculations. -// therefore the largest decoded image size we can support with the -// current code, even on 64-bit targets, is INT_MAX. this is not a -// significant limitation for the intended use case. -// -// we do, however, need to make sure our size calculations don't -// overflow. hence a few helper functions for size calculations that -// multiply integers together, making sure that they're non-negative -// and no overflow occurs. - -// return 1 if the sum is valid, 0 on overflow. -// negative terms are considered invalid. -static int stbi__addsizes_valid(int a, int b) -{ - if (b < 0) return 0; - // now 0 <= b <= INT_MAX, hence also - // 0 <= INT_MAX - b <= INTMAX. - // And "a + b <= INT_MAX" (which might overflow) is the - // same as a <= INT_MAX - b (no overflow) - return a <= INT_MAX - b; -} - -// returns 1 if the product is valid, 0 on overflow. -// negative factors are considered invalid. -static int stbi__mul2sizes_valid(int a, int b) -{ - if (a < 0 || b < 0) return 0; - if (b == 0) return 1; // mul-by-0 is always safe - // portable way to check for no overflows in a*b - return a <= INT_MAX / b; -} - -#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) -// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow -static int stbi__mad2sizes_valid(int a, int b, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); -} -#endif - -// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow -static int stbi__mad3sizes_valid(int a, int b, int c, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && - stbi__addsizes_valid(a * b * c, add); -} - -// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && - stbi__mul2sizes_valid(a * b * c, d) && stbi__addsizes_valid(a * b * c * d, add); -} -#endif - -#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) -// mallocs with size overflow checking -static void* stbi__malloc_mad2(int a, int b, int add) -{ - if (!stbi__mad2sizes_valid(a, b, add)) return NULL; - return stbi__malloc(a * b + add); -} -#endif - -static void* stbi__malloc_mad3(int a, int b, int c, int add) -{ - if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; - return stbi__malloc(a * b * c + add); -} - -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -static void* stbi__malloc_mad4(int a, int b, int c, int d, int add) -{ - if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; - return stbi__malloc(a * b * c * d + add); -} -#endif - -// stbi__err - error -// stbi__errpf - error returning pointer to float -// stbi__errpuc - error returning pointer to unsigned char - -#ifdef STBI_NO_FAILURE_STRINGS -#define stbi__err(x,y) 0 -#elif defined(STBI_FAILURE_USERMSG) -#define stbi__err(x,y) stbi__err(y) -#else -#define stbi__err(x,y) stbi__err(x) -#endif - -#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) -#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) - -STBIDEF void stbi_image_free(void* retval_from_stbi_load) -{ - STBI_FREE(retval_from_stbi_load); -} - -#ifndef STBI_NO_LINEAR -static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp); -#endif - -#ifndef STBI_NO_HDR -static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp); -#endif - -static int stbi__vertically_flip_on_load_global = 0; - -STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) -{ - stbi__vertically_flip_on_load_global = flag_true_if_should_flip; -} - -#ifndef STBI_THREAD_LOCAL -#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global -#else -static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; - -STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) -{ - stbi__vertically_flip_on_load_local = flag_true_if_should_flip; - stbi__vertically_flip_on_load_set = 1; -} - -#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ - ? stbi__vertically_flip_on_load_local \ - : stbi__vertically_flip_on_load_global) -#endif // STBI_THREAD_LOCAL - -static void* stbi__load_main(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) -{ - memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields - ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed - ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order - ri->num_channels = 0; - -#ifndef STBI_NO_JPEG - if (stbi__jpeg_test(s)) return stbi__jpeg_load(s, x, y, comp, req_comp, ri); -#endif -#ifndef STBI_NO_PNG - if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); -#endif -#ifndef STBI_NO_BMP - if (stbi__bmp_test(s)) return stbi__bmp_load(s, x, y, comp, req_comp, ri); -#endif -#ifndef STBI_NO_GIF - if (stbi__gif_test(s)) return stbi__gif_load(s, x, y, comp, req_comp, ri); -#endif -#ifndef STBI_NO_PSD - if (stbi__psd_test(s)) return stbi__psd_load(s, x, y, comp, req_comp, ri, bpc); -#else - STBI_NOTUSED(bpc); -#endif -#ifndef STBI_NO_PIC - if (stbi__pic_test(s)) return stbi__pic_load(s, x, y, comp, req_comp, ri); -#endif -#ifndef STBI_NO_PNM - if (stbi__pnm_test(s)) return stbi__pnm_load(s, x, y, comp, req_comp, ri); -#endif - -#ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - float* hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri); - return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); - } -#endif - -#ifndef STBI_NO_TGA - // test tga last because it's a crappy test! - if (stbi__tga_test(s)) - return stbi__tga_load(s, x, y, comp, req_comp, ri); -#endif - - return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); -} - -static stbi_uc* stbi__convert_16_to_8(stbi__uint16* orig, int w, int h, int channels) -{ - int i; - int img_len = w * h * channels; - stbi_uc* reduced; - - reduced = (stbi_uc*)stbi__malloc(img_len); - if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); - - for (i = 0; i < img_len; ++i) - reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling - - STBI_FREE(orig); - return reduced; -} - -static stbi__uint16* stbi__convert_8_to_16(stbi_uc* orig, int w, int h, int channels) -{ - int i; - int img_len = w * h * channels; - stbi__uint16* enlarged; - - enlarged = (stbi__uint16*)stbi__malloc(img_len * 2); - if (enlarged == NULL) return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); - - for (i = 0; i < img_len; ++i) - enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff - - STBI_FREE(orig); - return enlarged; -} - -static void stbi__vertical_flip(void* image, int w, int h, int bytes_per_pixel) -{ - int row; - size_t bytes_per_row = (size_t)w * bytes_per_pixel; - stbi_uc temp[2048]; - stbi_uc* bytes = (stbi_uc*)image; - - for (row = 0; row < (h >> 1); row++) { - stbi_uc* row0 = bytes + row * bytes_per_row; - stbi_uc* row1 = bytes + (h - row - 1) * bytes_per_row; - // swap row0 with row1 - size_t bytes_left = bytes_per_row; - while (bytes_left) { - size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); - memcpy(temp, row0, bytes_copy); - memcpy(row0, row1, bytes_copy); - memcpy(row1, temp, bytes_copy); - row0 += bytes_copy; - row1 += bytes_copy; - bytes_left -= bytes_copy; - } - } -} - -#ifndef STBI_NO_GIF -static void stbi__vertical_flip_slices(void* image, int w, int h, int z, int bytes_per_pixel) -{ - int slice; - int slice_size = w * h * bytes_per_pixel; - - stbi_uc* bytes = (stbi_uc*)image; - for (slice = 0; slice < z; ++slice) { - stbi__vertical_flip(bytes, w, h, bytes_per_pixel); - bytes += slice_size; - } -} -#endif - -static unsigned char* stbi__load_and_postprocess_8bit(stbi__context* s, int* x, int* y, int* comp, int req_comp) -{ - stbi__result_info ri; - void* result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); - - if (result == NULL) - return NULL; - - // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. - STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); - - if (ri.bits_per_channel != 8) { - result = stbi__convert_16_to_8((stbi__uint16*)result, *x, *y, req_comp == 0 ? *comp : req_comp); - ri.bits_per_channel = 8; - } - - // @TODO: move stbi__convert_format to here - - if (stbi__vertically_flip_on_load) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); - } - - return (unsigned char*)result; -} - -static stbi__uint16* stbi__load_and_postprocess_16bit(stbi__context* s, int* x, int* y, int* comp, int req_comp) -{ - stbi__result_info ri; - void* result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); - - if (result == NULL) - return NULL; - - // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. - STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); - - if (ri.bits_per_channel != 16) { - result = stbi__convert_8_to_16((stbi_uc*)result, *x, *y, req_comp == 0 ? *comp : req_comp); - ri.bits_per_channel = 16; - } - - // @TODO: move stbi__convert_format16 to here - // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision - - if (stbi__vertically_flip_on_load) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); - } - - return (stbi__uint16*)result; -} - -#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) -static void stbi__float_postprocess(float* result, int* x, int* y, int* comp, int req_comp) -{ - if (stbi__vertically_flip_on_load && result != NULL) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); - } -} -#endif - -#ifndef STBI_NO_STDIO - -#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) -STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char* str, int cbmb, wchar_t* widestr, int cchwide); -STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t* widestr, int cchwide, char* str, int cbmb, const char* defchar, int* used_default); -#endif - -#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) -STBIDEF int stbi_convert_wchar_to_utf8(char* buffer, size_t bufferlen, const wchar_t* input) -{ - return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int)bufferlen, NULL, NULL); -} -#endif - -static FILE* stbi__fopen(char const* filename, char const* mode) -{ - FILE* f; -#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) - wchar_t wMode[64]; - wchar_t wFilename[1024]; - if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename))) - return 0; - - if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode))) - return 0; - -#if _MSC_VER >= 1400 - if (0 != _wfopen_s(&f, wFilename, wMode)) - f = 0; -#else - f = _wfopen(wFilename, wMode); -#endif - -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - if (0 != fopen_s(&f, filename, mode)) - f = 0; -#else - f = fopen(filename, mode); -#endif - return f; -} - - -STBIDEF stbi_uc* stbi_load(char const* filename, int* x, int* y, int* comp, int req_comp) -{ - FILE* f = stbi__fopen(filename, "rb"); - unsigned char* result; - if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file(f, x, y, comp, req_comp); - fclose(f); - return result; -} - -STBIDEF stbi_uc* stbi_load_from_file(FILE* f, int* x, int* y, int* comp, int req_comp) -{ - unsigned char* result; - stbi__context s; - stbi__start_file(&s, f); - result = stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); - if (result) { - // need to 'unget' all the characters in the IO buffer - fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR); - } - return result; -} - -STBIDEF stbi__uint16* stbi_load_from_file_16(FILE* f, int* x, int* y, int* comp, int req_comp) -{ - stbi__uint16* result; - stbi__context s; - stbi__start_file(&s, f); - result = stbi__load_and_postprocess_16bit(&s, x, y, comp, req_comp); - if (result) { - // need to 'unget' all the characters in the IO buffer - fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR); - } - return result; -} - -STBIDEF stbi_us* stbi_load_16(char const* filename, int* x, int* y, int* comp, int req_comp) -{ - FILE* f = stbi__fopen(filename, "rb"); - stbi__uint16* result; - if (!f) return (stbi_us*)stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file_16(f, x, y, comp, req_comp); - fclose(f); - return result; -} - - -#endif //!STBI_NO_STDIO - -STBIDEF stbi_us* stbi_load_16_from_memory(stbi_uc const* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels) -{ - stbi__context s; - stbi__start_mem(&s, buffer, len); - return stbi__load_and_postprocess_16bit(&s, x, y, channels_in_file, desired_channels); -} - -STBIDEF stbi_us* stbi_load_16_from_callbacks(stbi_io_callbacks const* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks*)clbk, user); - return stbi__load_and_postprocess_16bit(&s, x, y, channels_in_file, desired_channels); -} - -STBIDEF stbi_uc* stbi_load_from_memory(stbi_uc const* buffer, int len, int* x, int* y, int* comp, int req_comp) -{ - stbi__context s; - stbi__start_mem(&s, buffer, len); - return stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); -} - -STBIDEF stbi_uc* stbi_load_from_callbacks(stbi_io_callbacks const* clbk, void* user, int* x, int* y, int* comp, int req_comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks*)clbk, user); - return stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); -} - -#ifndef STBI_NO_GIF -STBIDEF stbi_uc* stbi_load_gif_from_memory(stbi_uc const* buffer, int len, int** delays, int* x, int* y, int* z, int* comp, int req_comp) -{ - unsigned char* result; - stbi__context s; - stbi__start_mem(&s, buffer, len); - - result = (unsigned char*)stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); - if (stbi__vertically_flip_on_load) { - stbi__vertical_flip_slices(result, *x, *y, *z, *comp); - } - - return result; -} -#endif - -#ifndef STBI_NO_LINEAR -static float* stbi__loadf_main(stbi__context* s, int* x, int* y, int* comp, int req_comp) -{ - unsigned char* data; -#ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - stbi__result_info ri; - float* hdr_data = stbi__hdr_load(s, x, y, comp, req_comp, &ri); - if (hdr_data) - stbi__float_postprocess(hdr_data, x, y, comp, req_comp); - return hdr_data; - } -#endif - data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); - if (data) - return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); - return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); -} - -STBIDEF float* stbi_loadf_from_memory(stbi_uc const* buffer, int len, int* x, int* y, int* comp, int req_comp) -{ - stbi__context s; - stbi__start_mem(&s, buffer, len); - return stbi__loadf_main(&s, x, y, comp, req_comp); -} - -STBIDEF float* stbi_loadf_from_callbacks(stbi_io_callbacks const* clbk, void* user, int* x, int* y, int* comp, int req_comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks*)clbk, user); - return stbi__loadf_main(&s, x, y, comp, req_comp); -} - -#ifndef STBI_NO_STDIO -STBIDEF float* stbi_loadf(char const* filename, int* x, int* y, int* comp, int req_comp) -{ - float* result; - FILE* f = stbi__fopen(filename, "rb"); - if (!f) return stbi__errpf("can't fopen", "Unable to open file"); - result = stbi_loadf_from_file(f, x, y, comp, req_comp); - fclose(f); - return result; -} - -STBIDEF float* stbi_loadf_from_file(FILE* f, int* x, int* y, int* comp, int req_comp) -{ - stbi__context s; - stbi__start_file(&s, f); - return stbi__loadf_main(&s, x, y, comp, req_comp); -} -#endif // !STBI_NO_STDIO - -#endif // !STBI_NO_LINEAR - -// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is -// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always -// reports false! - -STBIDEF int stbi_is_hdr_from_memory(stbi_uc const* buffer, int len) -{ -#ifndef STBI_NO_HDR - stbi__context s; - stbi__start_mem(&s, buffer, len); - return stbi__hdr_test(&s); -#else - STBI_NOTUSED(buffer); - STBI_NOTUSED(len); - return 0; -#endif -} - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr(char const* filename) -{ - FILE* f = stbi__fopen(filename, "rb"); - int result = 0; - if (f) { - result = stbi_is_hdr_from_file(f); - fclose(f); - } - return result; -} - -STBIDEF int stbi_is_hdr_from_file(FILE* f) -{ -#ifndef STBI_NO_HDR - long pos = ftell(f); - int res; - stbi__context s; - stbi__start_file(&s, f); - res = stbi__hdr_test(&s); - fseek(f, pos, SEEK_SET); - return res; -#else - STBI_NOTUSED(f); - return 0; -#endif -} -#endif // !STBI_NO_STDIO - -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const* clbk, void* user) -{ -#ifndef STBI_NO_HDR - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks*)clbk, user); - return stbi__hdr_test(&s); -#else - STBI_NOTUSED(clbk); - STBI_NOTUSED(user); - return 0; -#endif -} - -#ifndef STBI_NO_LINEAR -static float stbi__l2h_gamma = 2.2f, stbi__l2h_scale = 1.0f; - -STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } -STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } -#endif - -static float stbi__h2l_gamma_i = 1.0f / 2.2f, stbi__h2l_scale_i = 1.0f; - -STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1 / gamma; } -STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1 / scale; } - - -////////////////////////////////////////////////////////////////////////////// -// -// Common code used by all image loaders -// - -enum -{ - STBI__SCAN_load = 0, - STBI__SCAN_type, - STBI__SCAN_header -}; - -static void stbi__refill_buffer(stbi__context* s) -{ - int n = (s->io.read)(s->io_user_data, (char*)s->buffer_start, s->buflen); - s->callback_already_read += (int)(s->img_buffer - s->img_buffer_original); - if (n == 0) { - // at end of file, treat same as if from memory, but need to handle case - // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file - s->read_from_callbacks = 0; - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start + 1; - *s->img_buffer = 0; - } - else { - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start + n; - } -} - -stbi_inline static stbi_uc stbi__get8(stbi__context* s) -{ - if (s->img_buffer < s->img_buffer_end) - return *s->img_buffer++; - if (s->read_from_callbacks) { - stbi__refill_buffer(s); - return *s->img_buffer++; - } - return 0; -} - -#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) -// nothing -#else -stbi_inline static int stbi__at_eof(stbi__context* s) -{ - if (s->io.read) { - if (!(s->io.eof)(s->io_user_data)) return 0; - // if feof() is true, check if buffer = end - // special case: we've only got the special 0 character at the end - if (s->read_from_callbacks == 0) return 1; - } - - return s->img_buffer >= s->img_buffer_end; -} -#endif - -#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) -// nothing -#else -static void stbi__skip(stbi__context* s, int n) -{ - if (n == 0) return; // already there! - if (n < 0) { - s->img_buffer = s->img_buffer_end; - return; - } - if (s->io.read) { - int blen = (int)(s->img_buffer_end - s->img_buffer); - if (blen < n) { - s->img_buffer = s->img_buffer_end; - (s->io.skip)(s->io_user_data, n - blen); - return; - } - } - s->img_buffer += n; -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) -// nothing -#else -static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) -{ - if (s->io.read) { - int blen = (int)(s->img_buffer_end - s->img_buffer); - if (blen < n) { - int res, count; - - memcpy(buffer, s->img_buffer, blen); - - count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); - res = (count == (n - blen)); - s->img_buffer = s->img_buffer_end; - return res; - } - } - - if (s->img_buffer + n <= s->img_buffer_end) { - memcpy(buffer, s->img_buffer, n); - s->img_buffer += n; - return 1; - } - else - return 0; -} -#endif - -#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) -// nothing -#else -static int stbi__get16be(stbi__context* s) -{ - int z = stbi__get8(s); - return (z << 8) + stbi__get8(s); -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) -// nothing -#else -static stbi__uint32 stbi__get32be(stbi__context* s) -{ - stbi__uint32 z = stbi__get16be(s); - return (z << 16) + stbi__get16be(s); -} -#endif - -#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) -// nothing -#else -static int stbi__get16le(stbi__context* s) -{ - int z = stbi__get8(s); - return z + (stbi__get8(s) << 8); -} -#endif - -#ifndef STBI_NO_BMP -static stbi__uint32 stbi__get32le(stbi__context* s) -{ - stbi__uint32 z = stbi__get16le(s); - return z + (stbi__get16le(s) << 16); -} -#endif - -#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings - -#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) -// nothing -#else -////////////////////////////////////////////////////////////////////////////// -// -// generic converter from built-in img_n to req_comp -// individual types do this automatically as much as possible (e.g. jpeg -// does all cases internally since it needs to colorspace convert anyway, -// and it never has alpha, so very few cases ). png can automatically -// interleave an alpha=255 channel, but falls back to this for other cases -// -// assume data buffer is malloced, so malloc a new one and free that one -// only failure mode is malloc failing - -static stbi_uc stbi__compute_y(int r, int g, int b) -{ - return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) -// nothing -#else -static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) -{ - int i, j; - unsigned char* good; - - if (req_comp == img_n) return data; - STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - - good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); - if (good == NULL) { - STBI_FREE(data); - return stbi__errpuc("outofmem", "Out of memory"); - } - - for (j = 0; j < (int)y; ++j) { - unsigned char* src = data + j * x * img_n; - unsigned char* dest = good + j * x * req_comp; - -#define STBI__COMBO(a,b) ((a)*8+(b)) -#define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; - STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; - STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; - STBI__CASE(2, 1) { dest[0] = src[0]; } break; - STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; - STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; - STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; - STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; - STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; - STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; - STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; - STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; - default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); - } -#undef STBI__CASE - } - - STBI_FREE(data); - return good; -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) -// nothing -#else -static stbi__uint16 stbi__compute_y_16(int r, int g, int b) -{ - return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); -} -#endif - -#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) -// nothing -#else -static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) -{ - int i, j; - stbi__uint16* good; - - if (req_comp == img_n) return data; - STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - - good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); - if (good == NULL) { - STBI_FREE(data); - return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); - } - - for (j = 0; j < (int)y; ++j) { - stbi__uint16* src = data + j * x * img_n; - stbi__uint16* dest = good + j * x * req_comp; - -#define STBI__COMBO(a,b) ((a)*8+(b)) -#define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; - STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; - STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; - STBI__CASE(2, 1) { dest[0] = src[0]; } break; - STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; - STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; - STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; - STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; - STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; - STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; - STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; - STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; - default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); - } -#undef STBI__CASE - } - - STBI_FREE(data); - return good; -} -#endif - -#ifndef STBI_NO_LINEAR -static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) -{ - int i, k, n; - float* output; - if (!data) return NULL; - output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); - if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp - 1; - for (i = 0; i < x * y; ++i) { - for (k = 0; k < n; ++k) { - output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); - } - } - if (n < comp) { - for (i = 0; i < x * y; ++i) { - output[i * comp + n] = data[i * comp + n] / 255.0f; - } - } - STBI_FREE(data); - return output; -} -#endif - -#ifndef STBI_NO_HDR -#define stbi__float2int(x) ((int) (x)) -static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) -{ - int i, k, n; - stbi_uc* output; - if (!data) return NULL; - output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); - if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp - 1; - for (i = 0; i < x * y; ++i) { - for (k = 0; k < n; ++k) { - float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i * comp + k] = (stbi_uc)stbi__float2int(z); - } - if (k < comp) { - float z = data[i * comp + k] * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i * comp + k] = (stbi_uc)stbi__float2int(z); - } - } - STBI_FREE(data); - return output; -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// "baseline" JPEG/JFIF decoder -// -// simple implementation -// - doesn't support delayed output of y-dimension -// - simple interface (only one output format: 8-bit interleaved RGB) -// - doesn't try to recover corrupt jpegs -// - doesn't allow partial loading, loading multiple at once -// - still fast on x86 (copying globals into locals doesn't help x86) -// - allocates lots of intermediate memory (full size of all components) -// - non-interleaved case requires this anyway -// - allows good upsampling (see next) -// high-quality -// - upsampled channels are bilinearly interpolated, even across blocks -// - quality integer IDCT derived from IJG's 'slow' -// performance -// - fast huffman; reasonable integer IDCT -// - some SIMD kernels for common paths on targets with SSE2/NEON -// - uses a lot of intermediate memory, could cache poorly - -#ifndef STBI_NO_JPEG - -// huffman decoding acceleration -#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache - -typedef struct -{ - stbi_uc fast[1 << FAST_BITS]; - // weirdly, repacking this into AoS is a 10% speed loss, instead of a win - stbi__uint16 code[256]; - stbi_uc values[256]; - stbi_uc size[257]; - unsigned int maxcode[18]; - int delta[17]; // old 'firstsymbol' - old 'firstcode' -} stbi__huffman; - -typedef struct -{ - stbi__context* s; - stbi__huffman huff_dc[4]; - stbi__huffman huff_ac[4]; - stbi__uint16 dequant[4][64]; - stbi__int16 fast_ac[4][1 << FAST_BITS]; - - // sizes for components, interleaved MCUs - int img_h_max, img_v_max; - int img_mcu_x, img_mcu_y; - int img_mcu_w, img_mcu_h; - - // definition of jpeg image component - struct - { - int id; - int h, v; - int tq; - int hd, ha; - int dc_pred; - - int x, y, w2, h2; - stbi_uc* data; - void* raw_data, * raw_coeff; - stbi_uc* linebuf; - short* coeff; // progressive only - int coeff_w, coeff_h; // number of 8x8 coefficient blocks - } img_comp[4]; - - stbi__uint32 code_buffer; // jpeg entropy-coded buffer - int code_bits; // number of valid bits - unsigned char marker; // marker seen while filling entropy buffer - int nomore; // flag if we saw a marker so must stop - - int progressive; - int spec_start; - int spec_end; - int succ_high; - int succ_low; - int eob_run; - int jfif; - int app14_color_transform; // Adobe APP14 tag - int rgb; - - int scan_n, order[4]; - int restart_interval, todo; - - // kernels - void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); - void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); - stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); -} stbi__jpeg; - -static int stbi__build_huffman(stbi__huffman* h, int* count) -{ - int i, j, k = 0; - unsigned int code; - // build size list for each symbol (from JPEG spec) - for (i = 0; i < 16; ++i) - for (j = 0; j < count[i]; ++j) - h->size[k++] = (stbi_uc)(i + 1); - h->size[k] = 0; - - // compute actual symbols (from jpeg spec) - code = 0; - k = 0; - for (j = 1; j <= 16; ++j) { - // compute delta to add to code to compute symbol id - h->delta[j] = k - code; - if (h->size[k] == j) { - while (h->size[k] == j) - h->code[k++] = (stbi__uint16)(code++); - if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); - } - // compute largest code + 1 for this size, preshifted as needed later - h->maxcode[j] = code << (16 - j); - code <<= 1; - } - h->maxcode[j] = 0xffffffff; - - // build non-spec acceleration table; 255 is flag for not-accelerated - memset(h->fast, 255, 1 << FAST_BITS); - for (i = 0; i < k; ++i) { - int s = h->size[i]; - if (s <= FAST_BITS) { - int c = h->code[i] << (FAST_BITS - s); - int m = 1 << (FAST_BITS - s); - for (j = 0; j < m; ++j) { - h->fast[c + j] = (stbi_uc)i; - } - } - } - return 1; -} - -// build a table that decodes both magnitude and value of small ACs in -// one go. -static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) -{ - int i; - for (i = 0; i < (1 << FAST_BITS); ++i) { - stbi_uc fast = h->fast[i]; - fast_ac[i] = 0; - if (fast < 255) { - int rs = h->values[fast]; - int run = (rs >> 4) & 15; - int magbits = rs & 15; - int len = h->size[fast]; - - if (magbits && len + magbits <= FAST_BITS) { - // magnitude code followed by receive_extend code - int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); - int m = 1 << (magbits - 1); - if (k < m) k += (~0U << magbits) + 1; - // if the result is small enough, we can fit it in fast_ac table - if (k >= -128 && k <= 127) - fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); - } - } - } -} - -static void stbi__grow_buffer_unsafe(stbi__jpeg* j) -{ - do { - unsigned int b = j->nomore ? 0 : stbi__get8(j->s); - if (b == 0xff) { - int c = stbi__get8(j->s); - while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes - if (c != 0) { - j->marker = (unsigned char)c; - j->nomore = 1; - return; - } - } - j->code_buffer |= b << (24 - j->code_bits); - j->code_bits += 8; - } while (j->code_bits <= 24); -} - -// (1 << n) - 1 -static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; - -// decode a jpeg huffman value from the bitstream -stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) -{ - unsigned int temp; - int c, k; - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - - // look at the top FAST_BITS and determine what symbol ID it is, - // if the code is <= FAST_BITS - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); - k = h->fast[c]; - if (k < 255) { - int s = h->size[k]; - if (s > j->code_bits) - return -1; - j->code_buffer <<= s; - j->code_bits -= s; - return h->values[k]; - } - - // naive test is to shift the code_buffer down so k bits are - // valid, then test against maxcode. To speed this up, we've - // preshifted maxcode left so that it has (16-k) 0s at the - // end; in other words, regardless of the number of bits, it - // wants to be compared against something shifted to have 16; - // that way we don't need to shift inside the loop. - temp = j->code_buffer >> 16; - for (k = FAST_BITS + 1; ; ++k) - if (temp < h->maxcode[k]) - break; - if (k == 17) { - // error! code not found - j->code_bits -= 16; - return -1; - } - - if (k > j->code_bits) - return -1; - - // convert the huffman code to the symbol id - c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; - STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); - - // convert the id to a symbol - j->code_bits -= k; - j->code_buffer <<= k; - return h->values[c]; -} - -// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); - - sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB - k = stbi_lrot(j->code_buffer, n); - if (n < 0 || n >= (int)(sizeof(stbi__bmask) / sizeof(*stbi__bmask))) return 0; - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; - return k + (stbi__jbias[n] & ~sgn); -} - -// get some unsigned bits -stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) -{ - unsigned int k; - if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - k = stbi_lrot(j->code_buffer, n); - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; - return k; -} - -stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) -{ - unsigned int k; - if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); - k = j->code_buffer; - j->code_buffer <<= 1; - --j->code_bits; - return k & 0x80000000; -} - -// given a value that's at position X in the zigzag stream, -// where does it appear in the 8x8 matrix coded as row-major? -static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = -{ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - // let corrupt input sample past end - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63 -}; - -// decode one 64-entry block-- -static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) -{ - int diff, dc, k; - int t; - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - t = stbi__jpeg_huff_decode(j, hdc); - if (t < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); - - // 0 all the ac values now so we can do it 32-bits at a time - memset(data, 0, 64 * sizeof(data[0])); - - diff = t ? stbi__extend_receive(j, t) : 0; - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - data[0] = (short)(dc * dequant[0]); - - // decode AC components, see JPEG spec - k = 1; - do { - unsigned int zig; - int c, r, s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); - r = fac[c]; - if (r) { // fast-AC path - k += (r >> 4) & 15; // run - s = r & 15; // combined length - j->code_buffer <<= s; - j->code_bits -= s; - // decode into unzigzag'd location - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short)((r >> 8) * dequant[zig]); - } - else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (rs != 0xf0) break; // end block - k += 16; - } - else { - k += r; - // decode into unzigzag'd location - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); - } - } - } while (k < 64); - return 1; -} - -static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) -{ - int diff, dc; - int t; - if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - - if (j->succ_high == 0) { - // first scan for DC coefficient, must be first - memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now - t = stbi__jpeg_huff_decode(j, hdc); - if (t == -1) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - diff = t ? stbi__extend_receive(j, t) : 0; - - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - data[0] = (short)(dc << j->succ_low); - } - else { - // refinement scan for DC coefficient - if (stbi__jpeg_get_bit(j)) - data[0] += (short)(1 << j->succ_low); - } - return 1; -} - -// @OPTIMIZE: store non-zigzagged during the decode passes, -// and only de-zigzag when dequantizing -static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) -{ - int k; - if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - - if (j->succ_high == 0) { - int shift = j->succ_low; - - if (j->eob_run) { - --j->eob_run; - return 1; - } - - k = j->spec_start; - do { - unsigned int zig; - int c, r, s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); - r = fac[c]; - if (r) { // fast-AC path - k += (r >> 4) & 15; // run - s = r & 15; // combined length - j->code_buffer <<= s; - j->code_bits -= s; - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short)((r >> 8) << shift); - } - else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (r < 15) { - j->eob_run = (1 << r); - if (r) - j->eob_run += stbi__jpeg_get_bits(j, r); - --j->eob_run; - break; - } - k += 16; - } - else { - k += r; - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short)(stbi__extend_receive(j, s) << shift); - } - } - } while (k <= j->spec_end); - } - else { - // refinement scan for these AC coefficients - - short bit = (short)(1 << j->succ_low); - - if (j->eob_run) { - --j->eob_run; - for (k = j->spec_start; k <= j->spec_end; ++k) { - short* p = &data[stbi__jpeg_dezigzag[k]]; - if (*p != 0) - if (stbi__jpeg_get_bit(j)) - if ((*p & bit) == 0) { - if (*p > 0) - *p += bit; - else - *p -= bit; - } - } - } - else { - k = j->spec_start; - do { - int r, s; - int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh - if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (r < 15) { - j->eob_run = (1 << r) - 1; - if (r) - j->eob_run += stbi__jpeg_get_bits(j, r); - r = 64; // force end of block - } - else { - // r=15 s=0 should write 16 0s, so we just do - // a run of 15 0s and then write s (which is 0), - // so we don't have to do anything special here - } - } - else { - if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); - // sign bit - if (stbi__jpeg_get_bit(j)) - s = bit; - else - s = -bit; - } - - // advance by r - while (k <= j->spec_end) { - short* p = &data[stbi__jpeg_dezigzag[k++]]; - if (*p != 0) { - if (stbi__jpeg_get_bit(j)) - if ((*p & bit) == 0) { - if (*p > 0) - *p += bit; - else - *p -= bit; - } - } - else { - if (r == 0) { - *p = (short)s; - break; - } - --r; - } - } - } while (k <= j->spec_end); - } - } - return 1; -} - -// take a -128..127 value and stbi__clamp it and convert to 0..255 -stbi_inline static stbi_uc stbi__clamp(int x) -{ - // trick to use a single test to catch both cases - if ((unsigned int)x > 255) { - if (x < 0) return 0; - if (x > 255) return 255; - } - return (stbi_uc)x; -} - -#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) -#define stbi__fsh(x) ((x) * 4096) - -// derived from jidctint -- DCT_ISLOW -#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ - int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ - p2 = s2; \ - p3 = s6; \ - p1 = (p2+p3) * stbi__f2f(0.5411961f); \ - t2 = p1 + p3*stbi__f2f(-1.847759065f); \ - t3 = p1 + p2*stbi__f2f( 0.765366865f); \ - p2 = s0; \ - p3 = s4; \ - t0 = stbi__fsh(p2+p3); \ - t1 = stbi__fsh(p2-p3); \ - x0 = t0+t3; \ - x3 = t0-t3; \ - x1 = t1+t2; \ - x2 = t1-t2; \ - t0 = s7; \ - t1 = s5; \ - t2 = s3; \ - t3 = s1; \ - p3 = t0+t2; \ - p4 = t1+t3; \ - p1 = t0+t3; \ - p2 = t1+t2; \ - p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ - t0 = t0*stbi__f2f( 0.298631336f); \ - t1 = t1*stbi__f2f( 2.053119869f); \ - t2 = t2*stbi__f2f( 3.072711026f); \ - t3 = t3*stbi__f2f( 1.501321110f); \ - p1 = p5 + p1*stbi__f2f(-0.899976223f); \ - p2 = p5 + p2*stbi__f2f(-2.562915447f); \ - p3 = p3*stbi__f2f(-1.961570560f); \ - p4 = p4*stbi__f2f(-0.390180644f); \ - t3 += p1+p4; \ - t2 += p2+p3; \ - t1 += p2+p4; \ - t0 += p1+p3; - -static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) -{ - int i, val[64], * v = val; - stbi_uc* o; - short* d = data; - - // columns - for (i = 0; i < 8; ++i, ++d, ++v) { - // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing - if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 - && d[40] == 0 && d[48] == 0 && d[56] == 0) { - // no shortcut 0 seconds - // (1|2|3|4|5|6|7)==0 0 seconds - // all separate -0.047 seconds - // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds - int dcterm = d[0] * 4; - v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; - } - else { - STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) - // constants scaled things up by 1<<12; let's bring them back - // down, but keep 2 extra bits of precision - x0 += 512; x1 += 512; x2 += 512; x3 += 512; - v[0] = (x0 + t3) >> 10; - v[56] = (x0 - t3) >> 10; - v[8] = (x1 + t2) >> 10; - v[48] = (x1 - t2) >> 10; - v[16] = (x2 + t1) >> 10; - v[40] = (x2 - t1) >> 10; - v[24] = (x3 + t0) >> 10; - v[32] = (x3 - t0) >> 10; - } - } - - for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { - // no fast case since the first 1D IDCT spread components out - STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) - // constants scaled things up by 1<<12, plus we had 1<<2 from first - // loop, plus horizontal and vertical each scale by sqrt(8) so together - // we've got an extra 1<<3, so 1<<17 total we need to remove. - // so we want to round that, which means adding 0.5 * 1<<17, - // aka 65536. Also, we'll end up with -128 to 127 that we want - // to encode as 0..255 by adding 128, so we'll add that before the shift - x0 += 65536 + (128 << 17); - x1 += 65536 + (128 << 17); - x2 += 65536 + (128 << 17); - x3 += 65536 + (128 << 17); - // tried computing the shifts into temps, or'ing the temps to see - // if any were out of range, but that was slower - o[0] = stbi__clamp((x0 + t3) >> 17); - o[7] = stbi__clamp((x0 - t3) >> 17); - o[1] = stbi__clamp((x1 + t2) >> 17); - o[6] = stbi__clamp((x1 - t2) >> 17); - o[2] = stbi__clamp((x2 + t1) >> 17); - o[5] = stbi__clamp((x2 - t1) >> 17); - o[3] = stbi__clamp((x3 + t0) >> 17); - o[4] = stbi__clamp((x3 - t0) >> 17); - } -} - -#ifdef STBI_SSE2 -// sse2 integer IDCT. not the fastest possible implementation but it -// produces bit-identical results to the generic C version so it's -// fully "transparent". -static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) -{ - // This is constructed to match our regular (generic) integer IDCT exactly. - __m128i row0, row1, row2, row3, row4, row5, row6, row7; - __m128i tmp; - - // dot product constant: even elems=x, odd elems=y -#define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) - -// out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) -// out(1) = c1[even]*x + c1[odd]*y -#define dct_rot(out0,out1, x,y,c0,c1) \ - __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ - __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ - __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ - __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ - __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ - __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) - - // out = in << 12 (in 16-bit, out 32-bit) -#define dct_widen(out, in) \ - __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ - __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) - - // wide add -#define dct_wadd(out, a, b) \ - __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_add_epi32(a##_h, b##_h) - - // wide sub -#define dct_wsub(out, a, b) \ - __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) - - // butterfly a/b, add bias, then shift by "s" and pack -#define dct_bfly32o(out0, out1, a,b,bias,s) \ - { \ - __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ - __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ - dct_wadd(sum, abiased, b); \ - dct_wsub(dif, abiased, b); \ - out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ - out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ - } - - // 8-bit interleave step (for transposes) -#define dct_interleave8(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi8(a, b); \ - b = _mm_unpackhi_epi8(tmp, b) - - // 16-bit interleave step (for transposes) -#define dct_interleave16(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi16(a, b); \ - b = _mm_unpackhi_epi16(tmp, b) - -#define dct_pass(bias,shift) \ - { \ - /* even part */ \ - dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ - __m128i sum04 = _mm_add_epi16(row0, row4); \ - __m128i dif04 = _mm_sub_epi16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ - dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ - __m128i sum17 = _mm_add_epi16(row1, row7); \ - __m128i sum35 = _mm_add_epi16(row3, row5); \ - dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ - dct_wadd(x4, y0o, y4o); \ - dct_wadd(x5, y1o, y5o); \ - dct_wadd(x6, y2o, y5o); \ - dct_wadd(x7, y3o, y4o); \ - dct_bfly32o(row0,row7, x0,x7,bias,shift); \ - dct_bfly32o(row1,row6, x1,x6,bias,shift); \ - dct_bfly32o(row2,row5, x2,x5,bias,shift); \ - dct_bfly32o(row3,row4, x3,x4,bias,shift); \ - } - - __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); - __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); - __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); - __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); - __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); - __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); - __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); - __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); - - // rounding biases in column/row passes, see stbi__idct_block for explanation. - __m128i bias_0 = _mm_set1_epi32(512); - __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); - - // load - row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); - row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); - row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); - row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); - row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); - row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); - row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); - row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); - - // column pass - dct_pass(bias_0, 10); - - { - // 16bit 8x8 transpose pass 1 - dct_interleave16(row0, row4); - dct_interleave16(row1, row5); - dct_interleave16(row2, row6); - dct_interleave16(row3, row7); - - // transpose pass 2 - dct_interleave16(row0, row2); - dct_interleave16(row1, row3); - dct_interleave16(row4, row6); - dct_interleave16(row5, row7); - - // transpose pass 3 - dct_interleave16(row0, row1); - dct_interleave16(row2, row3); - dct_interleave16(row4, row5); - dct_interleave16(row6, row7); - } - - // row pass - dct_pass(bias_1, 17); - - { - // pack - __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 - __m128i p1 = _mm_packus_epi16(row2, row3); - __m128i p2 = _mm_packus_epi16(row4, row5); - __m128i p3 = _mm_packus_epi16(row6, row7); - - // 8bit 8x8 transpose pass 1 - dct_interleave8(p0, p2); // a0e0a1e1... - dct_interleave8(p1, p3); // c0g0c1g1... - - // transpose pass 2 - dct_interleave8(p0, p1); // a0c0e0g0... - dct_interleave8(p2, p3); // b0d0f0h0... - - // transpose pass 3 - dct_interleave8(p0, p2); // a0b0c0d0... - dct_interleave8(p1, p3); // a4b4c4d4... - - // store - _mm_storel_epi64((__m128i*) out, p0); out += out_stride; - _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i*) out, p2); out += out_stride; - _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i*) out, p1); out += out_stride; - _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i*) out, p3); out += out_stride; - _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); - } - -#undef dct_const -#undef dct_rot -#undef dct_widen -#undef dct_wadd -#undef dct_wsub -#undef dct_bfly32o -#undef dct_interleave8 -#undef dct_interleave16 -#undef dct_pass -} - -#endif // STBI_SSE2 - -#ifdef STBI_NEON - -// NEON integer IDCT. should produce bit-identical -// results to the generic C version. -static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) -{ - int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; - - int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); - int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); - int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); - int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); - int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); - int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); - int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); - int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); - int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); - int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); - int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); - int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); - -#define dct_long_mul(out, inq, coeff) \ - int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ - int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) - -#define dct_long_mac(out, acc, inq, coeff) \ - int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ - int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) - -#define dct_widen(out, inq) \ - int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ - int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) - - // wide add -#define dct_wadd(out, a, b) \ - int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ - int32x4_t out##_h = vaddq_s32(a##_h, b##_h) - -// wide sub -#define dct_wsub(out, a, b) \ - int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ - int32x4_t out##_h = vsubq_s32(a##_h, b##_h) - -// butterfly a/b, then shift using "shiftop" by "s" and pack -#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ - { \ - dct_wadd(sum, a, b); \ - dct_wsub(dif, a, b); \ - out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ - out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ - } - -#define dct_pass(shiftop, shift) \ - { \ - /* even part */ \ - int16x8_t sum26 = vaddq_s16(row2, row6); \ - dct_long_mul(p1e, sum26, rot0_0); \ - dct_long_mac(t2e, p1e, row6, rot0_1); \ - dct_long_mac(t3e, p1e, row2, rot0_2); \ - int16x8_t sum04 = vaddq_s16(row0, row4); \ - int16x8_t dif04 = vsubq_s16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - int16x8_t sum15 = vaddq_s16(row1, row5); \ - int16x8_t sum17 = vaddq_s16(row1, row7); \ - int16x8_t sum35 = vaddq_s16(row3, row5); \ - int16x8_t sum37 = vaddq_s16(row3, row7); \ - int16x8_t sumodd = vaddq_s16(sum17, sum35); \ - dct_long_mul(p5o, sumodd, rot1_0); \ - dct_long_mac(p1o, p5o, sum17, rot1_1); \ - dct_long_mac(p2o, p5o, sum35, rot1_2); \ - dct_long_mul(p3o, sum37, rot2_0); \ - dct_long_mul(p4o, sum15, rot2_1); \ - dct_wadd(sump13o, p1o, p3o); \ - dct_wadd(sump24o, p2o, p4o); \ - dct_wadd(sump23o, p2o, p3o); \ - dct_wadd(sump14o, p1o, p4o); \ - dct_long_mac(x4, sump13o, row7, rot3_0); \ - dct_long_mac(x5, sump24o, row5, rot3_1); \ - dct_long_mac(x6, sump23o, row3, rot3_2); \ - dct_long_mac(x7, sump14o, row1, rot3_3); \ - dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ - dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ - dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ - dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ - } - - // load - row0 = vld1q_s16(data + 0 * 8); - row1 = vld1q_s16(data + 1 * 8); - row2 = vld1q_s16(data + 2 * 8); - row3 = vld1q_s16(data + 3 * 8); - row4 = vld1q_s16(data + 4 * 8); - row5 = vld1q_s16(data + 5 * 8); - row6 = vld1q_s16(data + 6 * 8); - row7 = vld1q_s16(data + 7 * 8); - - // add DC bias - row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); - - // column pass - dct_pass(vrshrn_n_s32, 10); - - // 16bit 8x8 transpose - { - // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. - // whether compilers actually get this is another story, sadly. -#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } -#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } - - // pass 1 - dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 - dct_trn16(row2, row3); - dct_trn16(row4, row5); - dct_trn16(row6, row7); - - // pass 2 - dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 - dct_trn32(row1, row3); - dct_trn32(row4, row6); - dct_trn32(row5, row7); - - // pass 3 - dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 - dct_trn64(row1, row5); - dct_trn64(row2, row6); - dct_trn64(row3, row7); - -#undef dct_trn16 -#undef dct_trn32 -#undef dct_trn64 - } - - // row pass - // vrshrn_n_s32 only supports shifts up to 16, we need - // 17. so do a non-rounding shift of 16 first then follow - // up with a rounding shift by 1. - dct_pass(vshrn_n_s32, 16); - - { - // pack and round - uint8x8_t p0 = vqrshrun_n_s16(row0, 1); - uint8x8_t p1 = vqrshrun_n_s16(row1, 1); - uint8x8_t p2 = vqrshrun_n_s16(row2, 1); - uint8x8_t p3 = vqrshrun_n_s16(row3, 1); - uint8x8_t p4 = vqrshrun_n_s16(row4, 1); - uint8x8_t p5 = vqrshrun_n_s16(row5, 1); - uint8x8_t p6 = vqrshrun_n_s16(row6, 1); - uint8x8_t p7 = vqrshrun_n_s16(row7, 1); - - // again, these can translate into one instruction, but often don't. -#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } -#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } - - // sadly can't use interleaved stores here since we only write - // 8 bytes to each scan line! - - // 8x8 8-bit transpose pass 1 - dct_trn8_8(p0, p1); - dct_trn8_8(p2, p3); - dct_trn8_8(p4, p5); - dct_trn8_8(p6, p7); - - // pass 2 - dct_trn8_16(p0, p2); - dct_trn8_16(p1, p3); - dct_trn8_16(p4, p6); - dct_trn8_16(p5, p7); - - // pass 3 - dct_trn8_32(p0, p4); - dct_trn8_32(p1, p5); - dct_trn8_32(p2, p6); - dct_trn8_32(p3, p7); - - // store - vst1_u8(out, p0); out += out_stride; - vst1_u8(out, p1); out += out_stride; - vst1_u8(out, p2); out += out_stride; - vst1_u8(out, p3); out += out_stride; - vst1_u8(out, p4); out += out_stride; - vst1_u8(out, p5); out += out_stride; - vst1_u8(out, p6); out += out_stride; - vst1_u8(out, p7); - -#undef dct_trn8_8 -#undef dct_trn8_16 -#undef dct_trn8_32 - } - -#undef dct_long_mul -#undef dct_long_mac -#undef dct_widen -#undef dct_wadd -#undef dct_wsub -#undef dct_bfly32o -#undef dct_pass -} - -#endif // STBI_NEON - -#define STBI__MARKER_none 0xff -// if there's a pending marker from the entropy stream, return that -// otherwise, fetch from the stream and get a marker. if there's no -// marker, return 0xff, which is never a valid marker value -static stbi_uc stbi__get_marker(stbi__jpeg* j) -{ - stbi_uc x; - if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } - x = stbi__get8(j->s); - if (x != 0xff) return STBI__MARKER_none; - while (x == 0xff) - x = stbi__get8(j->s); // consume repeated 0xff fill bytes - return x; -} - -// in each scan, we'll have scan_n components, and the order -// of the components is specified by order[] -#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) - -// after a restart interval, stbi__jpeg_reset the entropy decoder and -// the dc prediction -static void stbi__jpeg_reset(stbi__jpeg* j) -{ - j->code_bits = 0; - j->code_buffer = 0; - j->nomore = 0; - j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; - j->marker = STBI__MARKER_none; - j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; - j->eob_run = 0; - // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, - // since we don't even allow 1<<30 pixels -} - -static int stbi__parse_entropy_coded_data(stbi__jpeg* z) -{ - stbi__jpeg_reset(z); - if (!z->progressive) { - if (z->scan_n == 1) { - int i, j; - STBI_SIMD_ALIGN(short, data[64]); - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x + 7) >> 3; - int h = (z->img_comp[n].y + 7) >> 3; - for (j = 0; j < h; ++j) { - for (i = 0; i < w; ++i) { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - // if it's NOT a restart, then just bail, so we get corrupt data - // rather than no data - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - else { // interleaved - int i, j, k, x, y; - STBI_SIMD_ALIGN(short, data[64]); - for (j = 0; j < z->img_mcu_y; ++j) { - for (i = 0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k = 0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y = 0; y < z->img_comp[n].v; ++y) { - for (x = 0; x < z->img_comp[n].h; ++x) { - int x2 = (i * z->img_comp[n].h + x) * 8; - int y2 = (j * z->img_comp[n].v + y) * 8; - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - } - else { - if (z->scan_n == 1) { - int i, j; - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x + 7) >> 3; - int h = (z->img_comp[n].y + 7) >> 3; - for (j = 0; j < h; ++j) { - for (i = 0; i < w; ++i) { - short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - if (z->spec_start == 0) { - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } - else { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) - return 0; - } - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - else { // interleaved - int i, j, k, x, y; - for (j = 0; j < z->img_mcu_y; ++j) { - for (i = 0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k = 0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y = 0; y < z->img_comp[n].v; ++y) { - for (x = 0; x < z->img_comp[n].h; ++x) { - int x2 = (i * z->img_comp[n].h + x); - int y2 = (j * z->img_comp[n].v + y); - short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - } -} - -static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) -{ - int i; - for (i = 0; i < 64; ++i) - data[i] *= dequant[i]; -} - -static void stbi__jpeg_finish(stbi__jpeg* z) -{ - if (z->progressive) { - // dequantize and idct the data - int i, j, n; - for (n = 0; n < z->s->img_n; ++n) { - int w = (z->img_comp[n].x + 7) >> 3; - int h = (z->img_comp[n].y + 7) >> 3; - for (j = 0; j < h; ++j) { - for (i = 0; i < w; ++i) { - short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); - z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); - } - } - } - } -} - -static int stbi__process_marker(stbi__jpeg* z, int m) -{ - int L; - switch (m) { - case STBI__MARKER_none: // no marker found - return stbi__err("expected marker", "Corrupt JPEG"); - - case 0xDD: // DRI - specify restart interval - if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); - z->restart_interval = stbi__get16be(z->s); - return 1; - - case 0xDB: // DQT - define quantization table - L = stbi__get16be(z->s) - 2; - while (L > 0) { - int q = stbi__get8(z->s); - int p = q >> 4, sixteen = (p != 0); - int t = q & 15, i; - if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); - if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); - - for (i = 0; i < 64; ++i) - z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); - L -= (sixteen ? 129 : 65); - } - return L == 0; - - case 0xC4: // DHT - define huffman table - L = stbi__get16be(z->s) - 2; - while (L > 0) { - stbi_uc* v; - int sizes[16], i, n = 0; - int q = stbi__get8(z->s); - int tc = q >> 4; - int th = q & 15; - if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); - for (i = 0; i < 16; ++i) { - sizes[i] = stbi__get8(z->s); - n += sizes[i]; - } - L -= 17; - if (tc == 0) { - if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; - v = z->huff_dc[th].values; - } - else { - if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; - v = z->huff_ac[th].values; - } - for (i = 0; i < n; ++i) - v[i] = stbi__get8(z->s); - if (tc != 0) - stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); - L -= n; - } - return L == 0; - } - - // check for comment block or APP blocks - if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { - L = stbi__get16be(z->s); - if (L < 2) { - if (m == 0xFE) - return stbi__err("bad COM len", "Corrupt JPEG"); - else - return stbi__err("bad APP len", "Corrupt JPEG"); - } - L -= 2; - - if (m == 0xE0 && L >= 5) { // JFIF APP0 segment - static const unsigned char tag[5] = { 'J','F','I','F','\0' }; - int ok = 1; - int i; - for (i = 0; i < 5; ++i) - if (stbi__get8(z->s) != tag[i]) - ok = 0; - L -= 5; - if (ok) - z->jfif = 1; - } - else if (m == 0xEE && L >= 12) { // Adobe APP14 segment - static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; - int ok = 1; - int i; - for (i = 0; i < 6; ++i) - if (stbi__get8(z->s) != tag[i]) - ok = 0; - L -= 6; - if (ok) { - stbi__get8(z->s); // version - stbi__get16be(z->s); // flags0 - stbi__get16be(z->s); // flags1 - z->app14_color_transform = stbi__get8(z->s); // color transform - L -= 6; - } - } - - stbi__skip(z->s, L); - return 1; - } - - return stbi__err("unknown marker", "Corrupt JPEG"); -} - -// after we see SOS -static int stbi__process_scan_header(stbi__jpeg* z) -{ - int i; - int Ls = stbi__get16be(z->s); - z->scan_n = stbi__get8(z->s); - if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); - if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); - for (i = 0; i < z->scan_n; ++i) { - int id = stbi__get8(z->s), which; - int q = stbi__get8(z->s); - for (which = 0; which < z->s->img_n; ++which) - if (z->img_comp[which].id == id) - break; - if (which == z->s->img_n) return 0; // no match - z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); - z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); - z->order[i] = which; - } - - { - int aa; - z->spec_start = stbi__get8(z->s); - z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 - aa = stbi__get8(z->s); - z->succ_high = (aa >> 4); - z->succ_low = (aa & 15); - if (z->progressive) { - if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) - return stbi__err("bad SOS", "Corrupt JPEG"); - } - else { - if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); - if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); - z->spec_end = 63; - } - } - - return 1; -} - -static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) -{ - int i; - for (i = 0; i < ncomp; ++i) { - if (z->img_comp[i].raw_data) { - STBI_FREE(z->img_comp[i].raw_data); - z->img_comp[i].raw_data = NULL; - z->img_comp[i].data = NULL; - } - if (z->img_comp[i].raw_coeff) { - STBI_FREE(z->img_comp[i].raw_coeff); - z->img_comp[i].raw_coeff = 0; - z->img_comp[i].coeff = 0; - } - if (z->img_comp[i].linebuf) { - STBI_FREE(z->img_comp[i].linebuf); - z->img_comp[i].linebuf = NULL; - } - } - return why; -} - -static int stbi__process_frame_header(stbi__jpeg* z, int scan) -{ - stbi__context* s = z->s; - int Lf, p, i, q, h_max = 1, v_max = 1, c; - Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG - p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline - s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG - s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); - c = stbi__get8(s); - if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); - s->img_n = c; - for (i = 0; i < c; ++i) { - z->img_comp[i].data = NULL; - z->img_comp[i].linebuf = NULL; - } - - if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); - - z->rgb = 0; - for (i = 0; i < s->img_n; ++i) { - static const unsigned char rgb[3] = { 'R', 'G', 'B' }; - z->img_comp[i].id = stbi__get8(s); - if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) - ++z->rgb; - q = stbi__get8(s); - z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); - z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); - z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); - } - - if (scan != STBI__SCAN_load) return 1; - - if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); - - for (i = 0; i < s->img_n; ++i) { - if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; - if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; - } - - // compute interleaved mcu info - z->img_h_max = h_max; - z->img_v_max = v_max; - z->img_mcu_w = h_max * 8; - z->img_mcu_h = v_max * 8; - // these sizes can't be more than 17 bits - z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; - z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; - - for (i = 0; i < s->img_n; ++i) { - // number of effective pixels (e.g. for non-interleaved MCU) - z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; - z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; - // to simplify generation, we'll allocate enough memory to decode - // the bogus oversized data from using interleaved MCUs and their - // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't - // discard the extra data until colorspace conversion - // - // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) - // so these muls can't overflow with 32-bit ints (which we require) - z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; - z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; - z->img_comp[i].coeff = 0; - z->img_comp[i].raw_coeff = 0; - z->img_comp[i].linebuf = NULL; - z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); - if (z->img_comp[i].raw_data == NULL) - return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); - // align blocks for idct using mmx/sse - z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); - if (z->progressive) { - // w2, h2 are multiples of 8 (see above) - z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; - z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; - z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); - if (z->img_comp[i].raw_coeff == NULL) - return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); - z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); - } - } - - return 1; -} - -// use comparisons since in some cases we handle more than one case (e.g. SOF) -#define stbi__DNL(x) ((x) == 0xdc) -#define stbi__SOI(x) ((x) == 0xd8) -#define stbi__EOI(x) ((x) == 0xd9) -#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) -#define stbi__SOS(x) ((x) == 0xda) - -#define stbi__SOF_progressive(x) ((x) == 0xc2) - -static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) -{ - int m; - z->jfif = 0; - z->app14_color_transform = -1; // valid values are 0,1,2 - z->marker = STBI__MARKER_none; // initialize cached marker to empty - m = stbi__get_marker(z); - if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); - if (scan == STBI__SCAN_type) return 1; - m = stbi__get_marker(z); - while (!stbi__SOF(m)) { - if (!stbi__process_marker(z, m)) return 0; - m = stbi__get_marker(z); - while (m == STBI__MARKER_none) { - // some files have extra padding after their blocks, so ok, we'll scan - if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); - m = stbi__get_marker(z); - } - } - z->progressive = stbi__SOF_progressive(m); - if (!stbi__process_frame_header(z, scan)) return 0; - return 1; -} - -// decode image to YCbCr format -static int stbi__decode_jpeg_image(stbi__jpeg* j) -{ - int m; - for (m = 0; m < 4; m++) { - j->img_comp[m].raw_data = NULL; - j->img_comp[m].raw_coeff = NULL; - } - j->restart_interval = 0; - if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; - m = stbi__get_marker(j); - while (!stbi__EOI(m)) { - if (stbi__SOS(m)) { - if (!stbi__process_scan_header(j)) return 0; - if (!stbi__parse_entropy_coded_data(j)) return 0; - if (j->marker == STBI__MARKER_none) { - // handle 0s at the end of image data from IP Kamera 9060 - while (!stbi__at_eof(j->s)) { - int x = stbi__get8(j->s); - if (x == 255) { - j->marker = stbi__get8(j->s); - break; - } - } - // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 - } - } - else if (stbi__DNL(m)) { - int Ld = stbi__get16be(j->s); - stbi__uint32 NL = stbi__get16be(j->s); - if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); - if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); - } - else { - if (!stbi__process_marker(j, m)) return 0; - } - m = stbi__get_marker(j); - } - if (j->progressive) - stbi__jpeg_finish(j); - return 1; -} - -// static jfif-centered resampling (across block boundaries) - -typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, - int w, int hs); - -#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) - -static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) -{ - STBI_NOTUSED(out); - STBI_NOTUSED(in_far); - STBI_NOTUSED(w); - STBI_NOTUSED(hs); - return in_near; -} - -static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) -{ - // need to generate two samples vertically for every one in input - int i; - STBI_NOTUSED(hs); - for (i = 0; i < w; ++i) - out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); - return out; -} - -static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) -{ - // need to generate two samples horizontally for every one in input - int i; - stbi_uc* input = in_near; - - if (w == 1) { - // if only one sample, can't do any interpolation - out[0] = out[1] = input[0]; - return out; - } - - out[0] = input[0]; - out[1] = stbi__div4(input[0] * 3 + input[1] + 2); - for (i = 1; i < w - 1; ++i) { - int n = 3 * input[i] + 2; - out[i * 2 + 0] = stbi__div4(n + input[i - 1]); - out[i * 2 + 1] = stbi__div4(n + input[i + 1]); - } - out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); - out[i * 2 + 1] = input[w - 1]; - - STBI_NOTUSED(in_far); - STBI_NOTUSED(hs); - - return out; -} - -#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) - -static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i, t0, t1; - if (w == 1) { - out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3 * in_near[0] + in_far[0]; - out[0] = stbi__div4(t1 + 2); - for (i = 1; i < w; ++i) { - t0 = t1; - t1 = 3 * in_near[i] + in_far[i]; - out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); - out[i * 2] = stbi__div16(3 * t1 + t0 + 8); - } - out[w * 2 - 1] = stbi__div4(t1 + 2); - - STBI_NOTUSED(hs); - - return out; -} - -#if defined(STBI_SSE2) || defined(STBI_NEON) -static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i = 0, t0, t1; - - if (w == 1) { - out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3 * in_near[0] + in_far[0]; - // process groups of 8 pixels for as long as we can. - // note we can't handle the last pixel in a row in this loop - // because we need to handle the filter boundary conditions. - for (; i < ((w - 1) & ~7); i += 8) { -#if defined(STBI_SSE2) - // load and perform the vertical filtering pass - // this uses 3*x + y = 4*x + (y - x) - __m128i zero = _mm_setzero_si128(); - __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); - __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); - __m128i farw = _mm_unpacklo_epi8(farb, zero); - __m128i nearw = _mm_unpacklo_epi8(nearb, zero); - __m128i diff = _mm_sub_epi16(farw, nearw); - __m128i nears = _mm_slli_epi16(nearw, 2); - __m128i curr = _mm_add_epi16(nears, diff); // current row - - // horizontal filter works the same based on shifted vers of current - // row. "prev" is current row shifted right by 1 pixel; we need to - // insert the previous pixel value (from t1). - // "next" is current row shifted left by 1 pixel, with first pixel - // of next block of 8 pixels added in. - __m128i prv0 = _mm_slli_si128(curr, 2); - __m128i nxt0 = _mm_srli_si128(curr, 2); - __m128i prev = _mm_insert_epi16(prv0, t1, 0); - __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); - - // horizontal filter, polyphase implementation since it's convenient: - // even pixels = 3*cur + prev = cur*4 + (prev - cur) - // odd pixels = 3*cur + next = cur*4 + (next - cur) - // note the shared term. - __m128i bias = _mm_set1_epi16(8); - __m128i curs = _mm_slli_epi16(curr, 2); - __m128i prvd = _mm_sub_epi16(prev, curr); - __m128i nxtd = _mm_sub_epi16(next, curr); - __m128i curb = _mm_add_epi16(curs, bias); - __m128i even = _mm_add_epi16(prvd, curb); - __m128i odd = _mm_add_epi16(nxtd, curb); - - // interleave even and odd pixels, then undo scaling. - __m128i int0 = _mm_unpacklo_epi16(even, odd); - __m128i int1 = _mm_unpackhi_epi16(even, odd); - __m128i de0 = _mm_srli_epi16(int0, 4); - __m128i de1 = _mm_srli_epi16(int1, 4); - - // pack and write output - __m128i outv = _mm_packus_epi16(de0, de1); - _mm_storeu_si128((__m128i*) (out + i * 2), outv); -#elif defined(STBI_NEON) - // load and perform the vertical filtering pass - // this uses 3*x + y = 4*x + (y - x) - uint8x8_t farb = vld1_u8(in_far + i); - uint8x8_t nearb = vld1_u8(in_near + i); - int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); - int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); - int16x8_t curr = vaddq_s16(nears, diff); // current row - - // horizontal filter works the same based on shifted vers of current - // row. "prev" is current row shifted right by 1 pixel; we need to - // insert the previous pixel value (from t1). - // "next" is current row shifted left by 1 pixel, with first pixel - // of next block of 8 pixels added in. - int16x8_t prv0 = vextq_s16(curr, curr, 7); - int16x8_t nxt0 = vextq_s16(curr, curr, 1); - int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); - int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); - - // horizontal filter, polyphase implementation since it's convenient: - // even pixels = 3*cur + prev = cur*4 + (prev - cur) - // odd pixels = 3*cur + next = cur*4 + (next - cur) - // note the shared term. - int16x8_t curs = vshlq_n_s16(curr, 2); - int16x8_t prvd = vsubq_s16(prev, curr); - int16x8_t nxtd = vsubq_s16(next, curr); - int16x8_t even = vaddq_s16(curs, prvd); - int16x8_t odd = vaddq_s16(curs, nxtd); - - // undo scaling and round, then store with even/odd phases interleaved - uint8x8x2_t o; - o.val[0] = vqrshrun_n_s16(even, 4); - o.val[1] = vqrshrun_n_s16(odd, 4); - vst2_u8(out + i * 2, o); -#endif - - // "previous" value for next iter - t1 = 3 * in_near[i + 7] + in_far[i + 7]; - } - - t0 = t1; - t1 = 3 * in_near[i] + in_far[i]; - out[i * 2] = stbi__div16(3 * t1 + t0 + 8); - - for (++i; i < w; ++i) { - t0 = t1; - t1 = 3 * in_near[i] + in_far[i]; - out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); - out[i * 2] = stbi__div16(3 * t1 + t0 + 8); - } - out[w * 2 - 1] = stbi__div4(t1 + 2); - - STBI_NOTUSED(hs); - - return out; -} -#endif - -static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) -{ - // resample with nearest-neighbor - int i, j; - STBI_NOTUSED(in_far); - for (i = 0; i < w; ++i) - for (j = 0; j < hs; ++j) - out[i * hs + j] = in_near[i]; - return out; -} - -// this is a reduced-precision calculation of YCbCr-to-RGB introduced -// to make sure the code produces the same results in both SIMD and scalar -#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) -static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) -{ - int i; - for (i = 0; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1 << 19); // rounding - int r, g, b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr * stbi__float2fixed(1.40200f); - g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb * stbi__float2fixed(1.77200f); - r >>= 20; - g >>= 20; - b >>= 20; - if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} - -#if defined(STBI_SSE2) || defined(STBI_NEON) -static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) -{ - int i = 0; - -#ifdef STBI_SSE2 - // step == 3 is pretty ugly on the final interleave, and i'm not convinced - // it's useful in practice (you wouldn't use it for textures, for example). - // so just accelerate step == 4 case. - if (step == 4) { - // this is a fairly straightforward implementation and not super-optimized. - __m128i signflip = _mm_set1_epi8(-0x80); - __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); - __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); - __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); - __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); - __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); - __m128i xw = _mm_set1_epi16(255); // alpha channel - - for (; i + 7 < count; i += 8) { - // load - __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); - __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); - __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); - __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 - __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 - - // unpack to short (and left-shift cr, cb by 8) - __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); - __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); - __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); - - // color transform - __m128i yws = _mm_srli_epi16(yw, 4); - __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); - __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); - __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); - __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); - __m128i rws = _mm_add_epi16(cr0, yws); - __m128i gwt = _mm_add_epi16(cb0, yws); - __m128i bws = _mm_add_epi16(yws, cb1); - __m128i gws = _mm_add_epi16(gwt, cr1); - - // descale - __m128i rw = _mm_srai_epi16(rws, 4); - __m128i bw = _mm_srai_epi16(bws, 4); - __m128i gw = _mm_srai_epi16(gws, 4); - - // back to byte, set up for transpose - __m128i brb = _mm_packus_epi16(rw, bw); - __m128i gxb = _mm_packus_epi16(gw, xw); - - // transpose to interleave channels - __m128i t0 = _mm_unpacklo_epi8(brb, gxb); - __m128i t1 = _mm_unpackhi_epi8(brb, gxb); - __m128i o0 = _mm_unpacklo_epi16(t0, t1); - __m128i o1 = _mm_unpackhi_epi16(t0, t1); - - // store - _mm_storeu_si128((__m128i*) (out + 0), o0); - _mm_storeu_si128((__m128i*) (out + 16), o1); - out += 32; - } - } -#endif - -#ifdef STBI_NEON - // in this version, step=3 support would be easy to add. but is there demand? - if (step == 4) { - // this is a fairly straightforward implementation and not super-optimized. - uint8x8_t signflip = vdup_n_u8(0x80); - int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); - int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); - int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); - int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); - - for (; i + 7 < count; i += 8) { - // load - uint8x8_t y_bytes = vld1_u8(y + i); - uint8x8_t cr_bytes = vld1_u8(pcr + i); - uint8x8_t cb_bytes = vld1_u8(pcb + i); - int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); - int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); - - // expand to s16 - int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); - int16x8_t crw = vshll_n_s8(cr_biased, 7); - int16x8_t cbw = vshll_n_s8(cb_biased, 7); - - // color transform - int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); - int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); - int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); - int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); - int16x8_t rws = vaddq_s16(yws, cr0); - int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); - int16x8_t bws = vaddq_s16(yws, cb1); - - // undo scaling, round, convert to byte - uint8x8x4_t o; - o.val[0] = vqrshrun_n_s16(rws, 4); - o.val[1] = vqrshrun_n_s16(gws, 4); - o.val[2] = vqrshrun_n_s16(bws, 4); - o.val[3] = vdup_n_u8(255); - - // store, interleaving r/g/b/a - vst4_u8(out, o); - out += 8 * 4; - } - } -#endif - - for (; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1 << 19); // rounding - int r, g, b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr * stbi__float2fixed(1.40200f); - g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb * stbi__float2fixed(1.77200f); - r >>= 20; - g >>= 20; - b >>= 20; - if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} -#endif - -// set up the kernels -static void stbi__setup_jpeg(stbi__jpeg* j) -{ - j->idct_block_kernel = stbi__idct_block; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; - -#ifdef STBI_SSE2 - if (stbi__sse2_available()) { - j->idct_block_kernel = stbi__idct_simd; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; - } -#endif - -#ifdef STBI_NEON - j->idct_block_kernel = stbi__idct_simd; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; -#endif -} - -// clean up the temporary component buffers -static void stbi__cleanup_jpeg(stbi__jpeg* j) -{ - stbi__free_jpeg_components(j, j->s->img_n, 0); -} - -typedef struct -{ - resample_row_func resample; - stbi_uc* line0, * line1; - int hs, vs; // expansion factor in each axis - int w_lores; // horizontal pixels pre-expansion - int ystep; // how far through vertical expansion we are - int ypos; // which pre-expansion row we're on -} stbi__resample; - -// fast 0..255 * 0..255 => 0..255 rounded multiplication -static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) -{ - unsigned int t = x * y + 128; - return (stbi_uc)((t + (t >> 8)) >> 8); -} - -static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) -{ - int n, decode_n, is_rgb; - z->s->img_n = 0; // make stbi__cleanup_jpeg safe - - // validate req_comp - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - - // load a jpeg image from whichever source, but leave in YCbCr format - if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } - - // determine actual number of components to generate - n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; - - is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); - - if (z->s->img_n == 3 && n < 3 && !is_rgb) - decode_n = 1; - else - decode_n = z->s->img_n; - - // resample and color-convert - { - int k; - unsigned int i, j; - stbi_uc* output; - stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; - - stbi__resample res_comp[4]; - - for (k = 0; k < decode_n; ++k) { - stbi__resample* r = &res_comp[k]; - - // allocate line buffer big enough for upsampling off the edges - // with upsample factor of 4 - z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); - if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } - - r->hs = z->img_h_max / z->img_comp[k].h; - r->vs = z->img_v_max / z->img_comp[k].v; - r->ystep = r->vs >> 1; - r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; - r->ypos = 0; - r->line0 = r->line1 = z->img_comp[k].data; - - if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; - else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; - else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; - else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; - else r->resample = stbi__resample_row_generic; - } - - // can't error after this so, this is safe - output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); - if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } - - // now go ahead and resample - for (j = 0; j < z->s->img_y; ++j) { - stbi_uc* out = output + n * z->s->img_x * j; - for (k = 0; k < decode_n; ++k) { - stbi__resample* r = &res_comp[k]; - int y_bot = r->ystep >= (r->vs >> 1); - coutput[k] = r->resample(z->img_comp[k].linebuf, - y_bot ? r->line1 : r->line0, - y_bot ? r->line0 : r->line1, - r->w_lores, r->hs); - if (++r->ystep >= r->vs) { - r->ystep = 0; - r->line0 = r->line1; - if (++r->ypos < z->img_comp[k].y) - r->line1 += z->img_comp[k].w2; - } - } - if (n >= 3) { - stbi_uc* y = coutput[0]; - if (z->s->img_n == 3) { - if (is_rgb) { - for (i = 0; i < z->s->img_x; ++i) { - out[0] = y[i]; - out[1] = coutput[1][i]; - out[2] = coutput[2][i]; - out[3] = 255; - out += n; - } - } - else { - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - } - } - else if (z->s->img_n == 4) { - if (z->app14_color_transform == 0) { // CMYK - for (i = 0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - out[0] = stbi__blinn_8x8(coutput[0][i], m); - out[1] = stbi__blinn_8x8(coutput[1][i], m); - out[2] = stbi__blinn_8x8(coutput[2][i], m); - out[3] = 255; - out += n; - } - } - else if (z->app14_color_transform == 2) { // YCCK - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - for (i = 0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - out[0] = stbi__blinn_8x8(255 - out[0], m); - out[1] = stbi__blinn_8x8(255 - out[1], m); - out[2] = stbi__blinn_8x8(255 - out[2], m); - out += n; - } - } - else { // YCbCr + alpha? Ignore the fourth channel for now - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - } - } - else - for (i = 0; i < z->s->img_x; ++i) { - out[0] = out[1] = out[2] = y[i]; - out[3] = 255; // not used if n==3 - out += n; - } - } - else { - if (is_rgb) { - if (n == 1) - for (i = 0; i < z->s->img_x; ++i) - *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); - else { - for (i = 0; i < z->s->img_x; ++i, out += 2) { - out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); - out[1] = 255; - } - } - } - else if (z->s->img_n == 4 && z->app14_color_transform == 0) { - for (i = 0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); - stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); - stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); - out[0] = stbi__compute_y(r, g, b); - out[1] = 255; - out += n; - } - } - else if (z->s->img_n == 4 && z->app14_color_transform == 2) { - for (i = 0; i < z->s->img_x; ++i) { - out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); - out[1] = 255; - out += n; - } - } - else { - stbi_uc* y = coutput[0]; - if (n == 1) - for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; - else - for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } - } - } - } - stbi__cleanup_jpeg(z); - *out_x = z->s->img_x; - *out_y = z->s->img_y; - if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output - return output; - } -} - -static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) -{ - unsigned char* result; - stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); - STBI_NOTUSED(ri); - j->s = s; - stbi__setup_jpeg(j); - result = load_jpeg_image(j, x, y, comp, req_comp); - STBI_FREE(j); - return result; -} - -static int stbi__jpeg_test(stbi__context* s) -{ - int r; - stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); - j->s = s; - stbi__setup_jpeg(j); - r = stbi__decode_jpeg_header(j, STBI__SCAN_type); - stbi__rewind(s); - STBI_FREE(j); - return r; -} - -static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) -{ - if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { - stbi__rewind(j->s); - return 0; - } - if (x) *x = j->s->img_x; - if (y) *y = j->s->img_y; - if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; - return 1; -} - -static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) -{ - int result; - stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); - j->s = s; - result = stbi__jpeg_info_raw(j, x, y, comp); - STBI_FREE(j); - return result; -} -#endif - -// public domain zlib decode v0.2 Sean Barrett 2006-11-18 -// simple implementation -// - all input must be provided in an upfront buffer -// - all output is written to a single output buffer (can malloc/realloc) -// performance -// - fast huffman - -#ifndef STBI_NO_ZLIB - -// fast-way is faster to check than jpeg huffman, but slow way is slower -#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables -#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) - -// zlib-style huffman encoding -// (jpegs packs from left, zlib from right, so can't share code) -typedef struct -{ - stbi__uint16 fast[1 << STBI__ZFAST_BITS]; - stbi__uint16 firstcode[16]; - int maxcode[17]; - stbi__uint16 firstsymbol[16]; - stbi_uc size[288]; - stbi__uint16 value[288]; -} stbi__zhuffman; - -stbi_inline static int stbi__bitreverse16(int n) -{ - n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); - n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); - n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); - n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); - return n; -} - -stbi_inline static int stbi__bit_reverse(int v, int bits) -{ - STBI_ASSERT(bits <= 16); - // to bit reverse n bits, reverse 16 and shift - // e.g. 11 bits, bit reverse and shift away 5 - return stbi__bitreverse16(v) >> (16 - bits); -} - -static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) -{ - int i, k = 0; - int code, next_code[16], sizes[17]; - - // DEFLATE spec for generating codes - memset(sizes, 0, sizeof(sizes)); - memset(z->fast, 0, sizeof(z->fast)); - for (i = 0; i < num; ++i) - ++sizes[sizelist[i]]; - sizes[0] = 0; - for (i = 1; i < 16; ++i) - if (sizes[i] > (1 << i)) - return stbi__err("bad sizes", "Corrupt PNG"); - code = 0; - for (i = 1; i < 16; ++i) { - next_code[i] = code; - z->firstcode[i] = (stbi__uint16)code; - z->firstsymbol[i] = (stbi__uint16)k; - code = (code + sizes[i]); - if (sizes[i]) - if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); - z->maxcode[i] = code << (16 - i); // preshift for inner loop - code <<= 1; - k += sizes[i]; - } - z->maxcode[16] = 0x10000; // sentinel - for (i = 0; i < num; ++i) { - int s = sizelist[i]; - if (s) { - int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; - stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); - z->size[c] = (stbi_uc)s; - z->value[c] = (stbi__uint16)i; - if (s <= STBI__ZFAST_BITS) { - int j = stbi__bit_reverse(next_code[s], s); - while (j < (1 << STBI__ZFAST_BITS)) { - z->fast[j] = fastv; - j += (1 << s); - } - } - ++next_code[s]; - } - } - return 1; -} - -// zlib-from-memory implementation for PNG reading -// because PNG allows splitting the zlib stream arbitrarily, -// and it's annoying structurally to have PNG call ZLIB call PNG, -// we require PNG read all the IDATs and combine them into a single -// memory buffer - -typedef struct -{ - stbi_uc* zbuffer, * zbuffer_end; - int num_bits; - stbi__uint32 code_buffer; - - char* zout; - char* zout_start; - char* zout_end; - int z_expandable; - - stbi__zhuffman z_length, z_distance; -} stbi__zbuf; - -stbi_inline static int stbi__zeof(stbi__zbuf* z) -{ - return (z->zbuffer >= z->zbuffer_end); -} - -stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) -{ - return stbi__zeof(z) ? 0 : *z->zbuffer++; -} - -static void stbi__fill_bits(stbi__zbuf* z) -{ - do { - if (z->code_buffer >= (1U << z->num_bits)) { - z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ - return; - } - z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; - z->num_bits += 8; - } while (z->num_bits <= 24); -} - -stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) -{ - unsigned int k; - if (z->num_bits < n) stbi__fill_bits(z); - k = z->code_buffer & ((1 << n) - 1); - z->code_buffer >>= n; - z->num_bits -= n; - return k; -} - -static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) -{ - int b, s, k; - // not resolved by fast table, so compute it the slow way - // use jpeg approach, which requires MSbits at top - k = stbi__bit_reverse(a->code_buffer, 16); - for (s = STBI__ZFAST_BITS + 1; ; ++s) - if (k < z->maxcode[s]) - break; - if (s >= 16) return -1; // invalid code! - // code size is s, so: - b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; - if (b >= sizeof(z->size)) return -1; // some data was corrupt somewhere! - if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; -} - -stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) -{ - int b, s; - if (a->num_bits < 16) { - if (stbi__zeof(a)) { - return -1; /* report error for unexpected end of data. */ - } - stbi__fill_bits(a); - } - b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; - if (b) { - s = b >> 9; - a->code_buffer >>= s; - a->num_bits -= s; - return b & 511; - } - return stbi__zhuffman_decode_slowpath(a, z); -} - -static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes -{ - char* q; - unsigned int cur, limit, old_limit; - z->zout = zout; - if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); - cur = (unsigned int)(z->zout - z->zout_start); - limit = old_limit = (unsigned)(z->zout_end - z->zout_start); - if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); - while (cur + n > limit) { - if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); - limit *= 2; - } - q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); - STBI_NOTUSED(old_limit); - if (q == NULL) return stbi__err("outofmem", "Out of memory"); - z->zout_start = q; - z->zout = q + cur; - z->zout_end = q + limit; - return 1; -} - -static const int stbi__zlength_base[31] = { - 3,4,5,6,7,8,9,10,11,13, - 15,17,19,23,27,31,35,43,51,59, - 67,83,99,115,131,163,195,227,258,0,0 }; - -static const int stbi__zlength_extra[31] = -{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; - -static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, -257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; - -static const int stbi__zdist_extra[32] = -{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; - -static int stbi__parse_huffman_block(stbi__zbuf* a) -{ - char* zout = a->zout; - for (;;) { - int z = stbi__zhuffman_decode(a, &a->z_length); - if (z < 256) { - if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes - if (zout >= a->zout_end) { - if (!stbi__zexpand(a, zout, 1)) return 0; - zout = a->zout; - } - *zout++ = (char)z; - } - else { - stbi_uc* p; - int len, dist; - if (z == 256) { - a->zout = zout; - return 1; - } - z -= 257; - len = stbi__zlength_base[z]; - if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); - z = stbi__zhuffman_decode(a, &a->z_distance); - if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); - dist = stbi__zdist_base[z]; - if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); - if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); - if (zout + len > a->zout_end) { - if (!stbi__zexpand(a, zout, len)) return 0; - zout = a->zout; - } - p = (stbi_uc*)(zout - dist); - if (dist == 1) { // run of one byte; common in images. - stbi_uc v = *p; - if (len) { do *zout++ = v; while (--len); } - } - else { - if (len) { do *zout++ = *p++; while (--len); } - } - } - } -} - -static int stbi__compute_huffman_codes(stbi__zbuf* a) -{ - static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; - stbi__zhuffman z_codelength; - stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op - stbi_uc codelength_sizes[19]; - int i, n; - - int hlit = stbi__zreceive(a, 5) + 257; - int hdist = stbi__zreceive(a, 5) + 1; - int hclen = stbi__zreceive(a, 4) + 4; - int ntot = hlit + hdist; - - memset(codelength_sizes, 0, sizeof(codelength_sizes)); - for (i = 0; i < hclen; ++i) { - int s = stbi__zreceive(a, 3); - codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; - } - if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; - - n = 0; - while (n < ntot) { - int c = stbi__zhuffman_decode(a, &z_codelength); - if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); - if (c < 16) - lencodes[n++] = (stbi_uc)c; - else { - stbi_uc fill = 0; - if (c == 16) { - c = stbi__zreceive(a, 2) + 3; - if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); - fill = lencodes[n - 1]; - } - else if (c == 17) { - c = stbi__zreceive(a, 3) + 3; - } - else if (c == 18) { - c = stbi__zreceive(a, 7) + 11; - } - else { - return stbi__err("bad codelengths", "Corrupt PNG"); - } - if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); - memset(lencodes + n, fill, c); - n += c; - } - } - if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); - if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; - return 1; -} - -static int stbi__parse_uncompressed_block(stbi__zbuf* a) -{ - stbi_uc header[4]; - int len, nlen, k; - if (a->num_bits & 7) - stbi__zreceive(a, a->num_bits & 7); // discard - // drain the bit-packed data into header - k = 0; - while (a->num_bits > 0) { - header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check - a->code_buffer >>= 8; - a->num_bits -= 8; - } - if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); - // now fill header the normal way - while (k < 4) - header[k++] = stbi__zget8(a); - len = header[1] * 256 + header[0]; - nlen = header[3] * 256 + header[2]; - if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); - if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); - if (a->zout + len > a->zout_end) - if (!stbi__zexpand(a, a->zout, len)) return 0; - memcpy(a->zout, a->zbuffer, len); - a->zbuffer += len; - a->zout += len; - return 1; -} - -static int stbi__parse_zlib_header(stbi__zbuf* a) -{ - int cmf = stbi__zget8(a); - int cm = cmf & 15; - /* int cinfo = cmf >> 4; */ - int flg = stbi__zget8(a); - if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec - if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec - if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png - if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png - // window = 1 << (8 + cinfo)... but who cares, we fully buffer output - return 1; -} - -static const stbi_uc stbi__zdefault_length[288] = -{ - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 -}; -static const stbi_uc stbi__zdefault_distance[32] = -{ - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 -}; -/* -Init algorithm: -{ - int i; // use <= to match clearly with spec - for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; - for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; - for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; - for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; - - for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; -} -*/ - -static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) -{ - int final, type; - if (parse_header) - if (!stbi__parse_zlib_header(a)) return 0; - a->num_bits = 0; - a->code_buffer = 0; - do { - final = stbi__zreceive(a, 1); - type = stbi__zreceive(a, 2); - if (type == 0) { - if (!stbi__parse_uncompressed_block(a)) return 0; - } - else if (type == 3) { - return 0; - } - else { - if (type == 1) { - // use fixed code lengths - if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, 288)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; - } - else { - if (!stbi__compute_huffman_codes(a)) return 0; - } - if (!stbi__parse_huffman_block(a)) return 0; - } - } while (!final); - return 1; -} - -static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) -{ - a->zout_start = obuf; - a->zout = obuf; - a->zout_end = obuf + olen; - a->z_expandable = exp; - - return stbi__parse_zlib(a, parse_header); -} - -STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) -{ - stbi__zbuf a; - char* p = (char*)stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc*)buffer; - a.zbuffer_end = (stbi_uc*)buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { - if (outlen) *outlen = (int)(a.zout - a.zout_start); - return a.zout_start; - } - else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) -{ - return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); -} - -STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) -{ - stbi__zbuf a; - char* p = (char*)stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc*)buffer; - a.zbuffer_end = (stbi_uc*)buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { - if (outlen) *outlen = (int)(a.zout - a.zout_start); - return a.zout_start; - } - else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) -{ - stbi__zbuf a; - a.zbuffer = (stbi_uc*)ibuffer; - a.zbuffer_end = (stbi_uc*)ibuffer + ilen; - if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) - return (int)(a.zout - a.zout_start); - else - return -1; -} - -STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) -{ - stbi__zbuf a; - char* p = (char*)stbi__malloc(16384); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc*)buffer; - a.zbuffer_end = (stbi_uc*)buffer + len; - if (stbi__do_zlib(&a, p, 16384, 1, 0)) { - if (outlen) *outlen = (int)(a.zout - a.zout_start); - return a.zout_start; - } - else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) -{ - stbi__zbuf a; - a.zbuffer = (stbi_uc*)ibuffer; - a.zbuffer_end = (stbi_uc*)ibuffer + ilen; - if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) - return (int)(a.zout - a.zout_start); - else - return -1; -} -#endif - -// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 -// simple implementation -// - only 8-bit samples -// - no CRC checking -// - allocates lots of intermediate memory -// - avoids problem of streaming data between subsystems -// - avoids explicit window management -// performance -// - uses stb_zlib, a PD zlib implementation with fast huffman decoding - -#ifndef STBI_NO_PNG -typedef struct -{ - stbi__uint32 length; - stbi__uint32 type; -} stbi__pngchunk; - -static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) -{ - stbi__pngchunk c; - c.length = stbi__get32be(s); - c.type = stbi__get32be(s); - return c; -} - -static int stbi__check_png_header(stbi__context* s) -{ - static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; - int i; - for (i = 0; i < 8; ++i) - if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); - return 1; -} - -typedef struct -{ - stbi__context* s; - stbi_uc* idata, * expanded, * out; - int depth; -} stbi__png; - - -enum { - STBI__F_none = 0, - STBI__F_sub = 1, - STBI__F_up = 2, - STBI__F_avg = 3, - STBI__F_paeth = 4, - // synthetic filters used for first scanline to avoid needing a dummy row of 0s - STBI__F_avg_first, - STBI__F_paeth_first -}; - -static stbi_uc first_row_filter[5] = -{ - STBI__F_none, - STBI__F_sub, - STBI__F_none, - STBI__F_avg_first, - STBI__F_paeth_first -}; - -static int stbi__paeth(int a, int b, int c) -{ - int p = a + b - c; - int pa = abs(p - a); - int pb = abs(p - b); - int pc = abs(p - c); - if (pa <= pb && pa <= pc) return a; - if (pb <= pc) return b; - return c; -} - -static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; - -// create the png data from post-deflated data -static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) -{ - int bytes = (depth == 16 ? 2 : 1); - stbi__context* s = a->s; - stbi__uint32 i, j, stride = x * out_n * bytes; - stbi__uint32 img_len, img_width_bytes; - int k; - int img_n = s->img_n; // copy it into a local for later - - int output_bytes = out_n * bytes; - int filter_bytes = img_n * bytes; - int width = x; - - STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); - a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into - if (!a->out) return stbi__err("outofmem", "Out of memory"); - - if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); - img_width_bytes = (((img_n * x * depth) + 7) >> 3); - img_len = (img_width_bytes + 1) * y; - - // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, - // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), - // so just check for raw_len < img_len always. - if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); - - for (j = 0; j < y; ++j) { - stbi_uc* cur = a->out + stride * j; - stbi_uc* prior; - int filter = *raw++; - - if (filter > 4) - return stbi__err("invalid filter", "Corrupt PNG"); - - if (depth < 8) { - if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); - cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place - filter_bytes = 1; - width = img_width_bytes; - } - prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above - - // if first row, use special filter that doesn't sample previous row - if (j == 0) filter = first_row_filter[filter]; - - // handle first byte explicitly - for (k = 0; k < filter_bytes; ++k) { - switch (filter) { - case STBI__F_none: cur[k] = raw[k]; break; - case STBI__F_sub: cur[k] = raw[k]; break; - case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; - case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; - case STBI__F_avg_first: cur[k] = raw[k]; break; - case STBI__F_paeth_first: cur[k] = raw[k]; break; - } - } - - if (depth == 8) { - if (img_n != out_n) - cur[img_n] = 255; // first pixel - raw += img_n; - cur += out_n; - prior += out_n; - } - else if (depth == 16) { - if (img_n != out_n) { - cur[filter_bytes] = 255; // first pixel top byte - cur[filter_bytes + 1] = 255; // first pixel bottom byte - } - raw += filter_bytes; - cur += output_bytes; - prior += output_bytes; - } - else { - raw += 1; - cur += 1; - prior += 1; - } - - // this is a little gross, so that we don't switch per-pixel or per-component - if (depth < 8 || img_n == out_n) { - int nk = (width - 1) * filter_bytes; -#define STBI__CASE(f) \ - case f: \ - for (k=0; k < nk; ++k) - switch (filter) { - // "none" filter turns into a memcpy here; make that explicit. - case STBI__F_none: memcpy(cur, raw, nk); break; - STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; - STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; - STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; - STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; - STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; - } -#undef STBI__CASE - raw += nk; - } - else { - STBI_ASSERT(img_n + 1 == out_n); -#define STBI__CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ - for (k=0; k < filter_bytes; ++k) - switch (filter) { - STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; - STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; - STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; - STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; - STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; - STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; - } -#undef STBI__CASE - - // the loop above sets the high byte of the pixels' alpha, but for - // 16 bit png files we also need the low byte set. we'll do that here. - if (depth == 16) { - cur = a->out + stride * j; // start at the beginning of the row again - for (i = 0; i < x; ++i, cur += output_bytes) { - cur[filter_bytes + 1] = 255; - } - } - } - } - - // we make a separate pass to expand bits to pixels; for performance, - // this could run two scanlines behind the above code, so it won't - // intefere with filtering but will still be in the cache. - if (depth < 8) { - for (j = 0; j < y; ++j) { - stbi_uc* cur = a->out + stride * j; - stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; - // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit - // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop - stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range - - // note that the final byte might overshoot and write more data than desired. - // we can allocate enough data that this never writes out of memory, but it - // could also overwrite the next scanline. can it overwrite non-empty data - // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. - // so we need to explicitly clamp the final ones - - if (depth == 4) { - for (k = x * img_n; k >= 2; k -= 2, ++in) { - *cur++ = scale * ((*in >> 4)); - *cur++ = scale * ((*in) & 0x0f); - } - if (k > 0) *cur++ = scale * ((*in >> 4)); - } - else if (depth == 2) { - for (k = x * img_n; k >= 4; k -= 4, ++in) { - *cur++ = scale * ((*in >> 6)); - *cur++ = scale * ((*in >> 4) & 0x03); - *cur++ = scale * ((*in >> 2) & 0x03); - *cur++ = scale * ((*in) & 0x03); - } - if (k > 0) *cur++ = scale * ((*in >> 6)); - if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); - if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); - } - else if (depth == 1) { - for (k = x * img_n; k >= 8; k -= 8, ++in) { - *cur++ = scale * ((*in >> 7)); - *cur++ = scale * ((*in >> 6) & 0x01); - *cur++ = scale * ((*in >> 5) & 0x01); - *cur++ = scale * ((*in >> 4) & 0x01); - *cur++ = scale * ((*in >> 3) & 0x01); - *cur++ = scale * ((*in >> 2) & 0x01); - *cur++ = scale * ((*in >> 1) & 0x01); - *cur++ = scale * ((*in) & 0x01); - } - if (k > 0) *cur++ = scale * ((*in >> 7)); - if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); - if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); - if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); - if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); - if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); - if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); - } - if (img_n != out_n) { - int q; - // insert alpha = 255 - cur = a->out + stride * j; - if (img_n == 1) { - for (q = x - 1; q >= 0; --q) { - cur[q * 2 + 1] = 255; - cur[q * 2 + 0] = cur[q]; - } - } - else { - STBI_ASSERT(img_n == 3); - for (q = x - 1; q >= 0; --q) { - cur[q * 4 + 3] = 255; - cur[q * 4 + 2] = cur[q * 3 + 2]; - cur[q * 4 + 1] = cur[q * 3 + 1]; - cur[q * 4 + 0] = cur[q * 3 + 0]; - } - } - } - } - } - else if (depth == 16) { - // force the image data from big-endian to platform-native. - // this is done in a separate pass due to the decoding relying - // on the data being untouched, but could probably be done - // per-line during decode if care is taken. - stbi_uc* cur = a->out; - stbi__uint16* cur16 = (stbi__uint16*)cur; - - for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { - *cur16 = (cur[0] << 8) | cur[1]; - } - } - - return 1; -} - -static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) -{ - int bytes = (depth == 16 ? 2 : 1); - int out_bytes = out_n * bytes; - stbi_uc* final; - int p; - if (!interlaced) - return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); - - // de-interlacing - final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); - for (p = 0; p < 7; ++p) { - int xorig[] = { 0,4,0,2,0,1,0 }; - int yorig[] = { 0,0,4,0,2,0,1 }; - int xspc[] = { 8,8,4,4,2,2,1 }; - int yspc[] = { 8,8,8,4,4,2,2 }; - int i, j, x, y; - // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 - x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; - y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; - if (x && y) { - stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; - if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { - STBI_FREE(final); - return 0; - } - for (j = 0; j < y; ++j) { - for (i = 0; i < x; ++i) { - int out_y = j * yspc[p] + yorig[p]; - int out_x = i * xspc[p] + xorig[p]; - memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, - a->out + (j * x + i) * out_bytes, out_bytes); - } - } - STBI_FREE(a->out); - image_data += img_len; - image_data_len -= img_len; - } - } - a->out = final; - - return 1; -} - -static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) -{ - stbi__context* s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi_uc* p = z->out; - - // compute color-based transparency, assuming we've - // already got 255 as the alpha value in the output - STBI_ASSERT(out_n == 2 || out_n == 4); - - if (out_n == 2) { - for (i = 0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 255); - p += 2; - } - } - else { - for (i = 0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; -} - -static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) -{ - stbi__context* s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi__uint16* p = (stbi__uint16*)z->out; - - // compute color-based transparency, assuming we've - // already got 65535 as the alpha value in the output - STBI_ASSERT(out_n == 2 || out_n == 4); - - if (out_n == 2) { - for (i = 0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 65535); - p += 2; - } - } - else { - for (i = 0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; -} - -static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) -{ - stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; - stbi_uc* p, * temp_out, * orig = a->out; - - p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); - if (p == NULL) return stbi__err("outofmem", "Out of memory"); - - // between here and free(out) below, exitting would leak - temp_out = p; - - if (pal_img_n == 3) { - for (i = 0; i < pixel_count; ++i) { - int n = orig[i] * 4; - p[0] = palette[n]; - p[1] = palette[n + 1]; - p[2] = palette[n + 2]; - p += 3; - } - } - else { - for (i = 0; i < pixel_count; ++i) { - int n = orig[i] * 4; - p[0] = palette[n]; - p[1] = palette[n + 1]; - p[2] = palette[n + 2]; - p[3] = palette[n + 3]; - p += 4; - } - } - STBI_FREE(a->out); - a->out = temp_out; - - STBI_NOTUSED(len); - - return 1; -} - -static int stbi__unpremultiply_on_load = 0; -static int stbi__de_iphone_flag = 0; - -STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) -{ - stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; -} - -STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) -{ - stbi__de_iphone_flag = flag_true_if_should_convert; -} - -static void stbi__de_iphone(stbi__png* z) -{ - stbi__context* s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi_uc* p = z->out; - - if (s->img_out_n == 3) { // convert bgr to rgb - for (i = 0; i < pixel_count; ++i) { - stbi_uc t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 3; - } - } - else { - STBI_ASSERT(s->img_out_n == 4); - if (stbi__unpremultiply_on_load) { - // convert bgr to rgb and unpremultiply - for (i = 0; i < pixel_count; ++i) { - stbi_uc a = p[3]; - stbi_uc t = p[0]; - if (a) { - stbi_uc half = a / 2; - p[0] = (p[2] * 255 + half) / a; - p[1] = (p[1] * 255 + half) / a; - p[2] = (t * 255 + half) / a; - } - else { - p[0] = p[2]; - p[2] = t; - } - p += 4; - } - } - else { - // convert bgr to rgb - for (i = 0; i < pixel_count; ++i) { - stbi_uc t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 4; - } - } - } -} - -#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) - -static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) -{ - stbi_uc palette[1024], pal_img_n = 0; - stbi_uc has_trans = 0, tc[3] = { 0 }; - stbi__uint16 tc16[3]; - stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; - int first = 1, k, interlace = 0, color = 0, is_iphone = 0; - stbi__context* s = z->s; - - z->expanded = NULL; - z->idata = NULL; - z->out = NULL; - - if (!stbi__check_png_header(s)) return 0; - - if (scan == STBI__SCAN_type) return 1; - - for (;;) { - stbi__pngchunk c = stbi__get_chunk_header(s); - switch (c.type) { - case STBI__PNG_TYPE('C', 'g', 'B', 'I'): - is_iphone = 1; - stbi__skip(s, c.length); - break; - case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { - int comp, filter; - if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); - first = 0; - if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); - s->img_x = stbi__get32be(s); - s->img_y = stbi__get32be(s); - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); - z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); - color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); - if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); - if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); - comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); - filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); - interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); - if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); - if (!pal_img_n) { - s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); - if (scan == STBI__SCAN_header) return 1; - } - else { - // if paletted, then pal_n is our final components, and - // img_n is # components to decompress/filter. - s->img_n = 1; - if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); - // if SCAN_header, have to scan to see if we have a tRNS - } - break; - } - - case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); - pal_len = c.length / 3; - if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); - for (i = 0; i < pal_len; ++i) { - palette[i * 4 + 0] = stbi__get8(s); - palette[i * 4 + 1] = stbi__get8(s); - palette[i * 4 + 2] = stbi__get8(s); - palette[i * 4 + 3] = 255; - } - break; - } - - case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); - if (pal_img_n) { - if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } - if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); - if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); - pal_img_n = 4; - for (i = 0; i < c.length; ++i) - palette[i * 4 + 3] = stbi__get8(s); - } - else { - if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); - if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); - has_trans = 1; - if (z->depth == 16) { - for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is - } - else { - for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger - } - } - break; - } - - case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); - if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } - if ((int)(ioff + c.length) < (int)ioff) return 0; - if (ioff + c.length > idata_limit) { - stbi__uint32 idata_limit_old = idata_limit; - stbi_uc* p; - if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; - while (ioff + c.length > idata_limit) - idata_limit *= 2; - STBI_NOTUSED(idata_limit_old); - p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); - z->idata = p; - } - if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); - ioff += c.length; - break; - } - - case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { - stbi__uint32 raw_len, bpl; - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (scan != STBI__SCAN_load) return 1; - if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); - // initial guess for decoded data size to avoid unnecessary reallocs - bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component - raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; - z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); - if (z->expanded == NULL) return 0; // zlib should set error - STBI_FREE(z->idata); z->idata = NULL; - if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) - s->img_out_n = s->img_n + 1; - else - s->img_out_n = s->img_n; - if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; - if (has_trans) { - if (z->depth == 16) { - if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; - } - else { - if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; - } - } - if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) - stbi__de_iphone(z); - if (pal_img_n) { - // pal_img_n == 3 or 4 - s->img_n = pal_img_n; // record the actual colors we had - s->img_out_n = pal_img_n; - if (req_comp >= 3) s->img_out_n = req_comp; - if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) - return 0; - } - else if (has_trans) { - // non-paletted image with tRNS -> source image has (constant) alpha - ++s->img_n; - } - STBI_FREE(z->expanded); z->expanded = NULL; - // end of PNG chunk, read and skip CRC - stbi__get32be(s); - return 1; - } - - default: - // if critical, fail - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if ((c.type & (1 << 29)) == 0) { -#ifndef STBI_NO_FAILURE_STRINGS - // not threadsafe - static char invalid_chunk[] = "XXXX PNG chunk not known"; - invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); - invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); - invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); - invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); -#endif - return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); - } - stbi__skip(s, c.length); - break; - } - // end of PNG chunk, read and skip CRC - stbi__get32be(s); - } -} - -static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) -{ - void* result = NULL; - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { - if (p->depth <= 8) - ri->bits_per_channel = 8; - else if (p->depth == 16) - ri->bits_per_channel = 16; - else - return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); - result = p->out; - p->out = NULL; - if (req_comp && req_comp != p->s->img_out_n) { - if (ri->bits_per_channel == 8) - result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); - else - result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); - p->s->img_out_n = req_comp; - if (result == NULL) return result; - } - *x = p->s->img_x; - *y = p->s->img_y; - if (n) *n = p->s->img_n; - } - STBI_FREE(p->out); p->out = NULL; - STBI_FREE(p->expanded); p->expanded = NULL; - STBI_FREE(p->idata); p->idata = NULL; - - return result; -} - -static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) -{ - stbi__png p; - p.s = s; - return stbi__do_png(&p, x, y, comp, req_comp, ri); -} - -static int stbi__png_test(stbi__context* s) -{ - int r; - r = stbi__check_png_header(s); - stbi__rewind(s); - return r; -} - -static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) -{ - if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { - stbi__rewind(p->s); - return 0; - } - if (x) *x = p->s->img_x; - if (y) *y = p->s->img_y; - if (comp) *comp = p->s->img_n; - return 1; -} - -static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) -{ - stbi__png p; - p.s = s; - return stbi__png_info_raw(&p, x, y, comp); -} - -static int stbi__png_is16(stbi__context* s) -{ - stbi__png p; - p.s = s; - if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) - return 0; - if (p.depth != 16) { - stbi__rewind(p.s); - return 0; - } - return 1; -} -#endif - -// Microsoft/Windows BMP image - -#ifndef STBI_NO_BMP -static int stbi__bmp_test_raw(stbi__context* s) -{ - int r; - int sz; - if (stbi__get8(s) != 'B') return 0; - if (stbi__get8(s) != 'M') return 0; - stbi__get32le(s); // discard filesize - stbi__get16le(s); // discard reserved - stbi__get16le(s); // discard reserved - stbi__get32le(s); // discard data offset - sz = stbi__get32le(s); - r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); - return r; -} - -static int stbi__bmp_test(stbi__context* s) -{ - int r = stbi__bmp_test_raw(s); - stbi__rewind(s); - return r; -} - - -// returns 0..31 for the highest set bit -static int stbi__high_bit(unsigned int z) -{ - int n = 0; - if (z == 0) return -1; - if (z >= 0x10000) { n += 16; z >>= 16; } - if (z >= 0x00100) { n += 8; z >>= 8; } - if (z >= 0x00010) { n += 4; z >>= 4; } - if (z >= 0x00004) { n += 2; z >>= 2; } - if (z >= 0x00002) { n += 1;/* >>= 1;*/ } - return n; -} - -static int stbi__bitcount(unsigned int a) -{ - a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 - a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits - a = (a + (a >> 8)); // max 16 per 8 bits - a = (a + (a >> 16)); // max 32 per 8 bits - return a & 0xff; -} - -// extract an arbitrarily-aligned N-bit value (N=bits) -// from v, and then make it 8-bits long and fractionally -// extend it to full full range. -static int stbi__shiftsigned(unsigned int v, int shift, int bits) -{ - static unsigned int mul_table[9] = { - 0, - 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, - 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, - }; - static unsigned int shift_table[9] = { - 0, 0,0,1,0,2,4,6,0, - }; - if (shift < 0) - v <<= -shift; - else - v >>= shift; - STBI_ASSERT(v < 256); - v >>= (8 - bits); - STBI_ASSERT(bits >= 0 && bits <= 8); - return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; -} - -typedef struct -{ - int bpp, offset, hsz; - unsigned int mr, mg, mb, ma, all_a; - int extra_read; -} stbi__bmp_data; - -static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) -{ - int hsz; - if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); - stbi__get32le(s); // discard filesize - stbi__get16le(s); // discard reserved - stbi__get16le(s); // discard reserved - info->offset = stbi__get32le(s); - info->hsz = hsz = stbi__get32le(s); - info->mr = info->mg = info->mb = info->ma = 0; - info->extra_read = 14; - - if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); - - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); - if (hsz == 12) { - s->img_x = stbi__get16le(s); - s->img_y = stbi__get16le(s); - } - else { - s->img_x = stbi__get32le(s); - s->img_y = stbi__get32le(s); - } - if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); - info->bpp = stbi__get16le(s); - if (hsz != 12) { - int compress = stbi__get32le(s); - if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); - stbi__get32le(s); // discard sizeof - stbi__get32le(s); // discard hres - stbi__get32le(s); // discard vres - stbi__get32le(s); // discard colorsused - stbi__get32le(s); // discard max important - if (hsz == 40 || hsz == 56) { - if (hsz == 56) { - stbi__get32le(s); - stbi__get32le(s); - stbi__get32le(s); - stbi__get32le(s); - } - if (info->bpp == 16 || info->bpp == 32) { - if (compress == 0) { - if (info->bpp == 32) { - info->mr = 0xffu << 16; - info->mg = 0xffu << 8; - info->mb = 0xffu << 0; - info->ma = 0xffu << 24; - info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 - } - else { - info->mr = 31u << 10; - info->mg = 31u << 5; - info->mb = 31u << 0; - } - } - else if (compress == 3) { - info->mr = stbi__get32le(s); - info->mg = stbi__get32le(s); - info->mb = stbi__get32le(s); - info->extra_read += 12; - // not documented, but generated by photoshop and handled by mspaint - if (info->mr == info->mg && info->mg == info->mb) { - // ?!?!? - return stbi__errpuc("bad BMP", "bad BMP"); - } - } - else - return stbi__errpuc("bad BMP", "bad BMP"); - } - } - else { - int i; - if (hsz != 108 && hsz != 124) - return stbi__errpuc("bad BMP", "bad BMP"); - info->mr = stbi__get32le(s); - info->mg = stbi__get32le(s); - info->mb = stbi__get32le(s); - info->ma = stbi__get32le(s); - stbi__get32le(s); // discard color space - for (i = 0; i < 12; ++i) - stbi__get32le(s); // discard color space parameters - if (hsz == 124) { - stbi__get32le(s); // discard rendering intent - stbi__get32le(s); // discard offset of profile data - stbi__get32le(s); // discard size of profile data - stbi__get32le(s); // discard reserved - } - } - } - return (void*)1; -} - - -static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) -{ - stbi_uc* out; - unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; - stbi_uc pal[256][4]; - int psize = 0, i, j, width; - int flip_vertically, pad, target; - stbi__bmp_data info; - STBI_NOTUSED(ri); - - info.all_a = 255; - if (stbi__bmp_parse_header(s, &info) == NULL) - return NULL; // error code already set - - flip_vertically = ((int)s->img_y) > 0; - s->img_y = abs((int)s->img_y); - - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - - mr = info.mr; - mg = info.mg; - mb = info.mb; - ma = info.ma; - all_a = info.all_a; - - if (info.hsz == 12) { - if (info.bpp < 24) - psize = (info.offset - info.extra_read - 24) / 3; - } - else { - if (info.bpp < 16) - psize = (info.offset - info.extra_read - info.hsz) >> 2; - } - if (psize == 0) { - STBI_ASSERT(info.offset == s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original)); - if (info.offset != s->callback_already_read + (s->img_buffer - s->buffer_start)) { - return stbi__errpuc("bad offset", "Corrupt BMP"); - } - } - - if (info.bpp == 24 && ma == 0xff000000) - s->img_n = 3; - else - s->img_n = ma ? 4 : 3; - if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 - target = req_comp; - else - target = s->img_n; // if they want monochrome, we'll post-convert - - // sanity-check size - if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) - return stbi__errpuc("too large", "Corrupt BMP"); - - out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - if (info.bpp < 16) { - int z = 0; - if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } - for (i = 0; i < psize; ++i) { - pal[i][2] = stbi__get8(s); - pal[i][1] = stbi__get8(s); - pal[i][0] = stbi__get8(s); - if (info.hsz != 12) stbi__get8(s); - pal[i][3] = 255; - } - stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); - if (info.bpp == 1) width = (s->img_x + 7) >> 3; - else if (info.bpp == 4) width = (s->img_x + 1) >> 1; - else if (info.bpp == 8) width = s->img_x; - else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } - pad = (-width) & 3; - if (info.bpp == 1) { - for (j = 0; j < (int)s->img_y; ++j) { - int bit_offset = 7, v = stbi__get8(s); - for (i = 0; i < (int)s->img_x; ++i) { - int color = (v >> bit_offset) & 0x1; - out[z++] = pal[color][0]; - out[z++] = pal[color][1]; - out[z++] = pal[color][2]; - if (target == 4) out[z++] = 255; - if (i + 1 == (int)s->img_x) break; - if ((--bit_offset) < 0) { - bit_offset = 7; - v = stbi__get8(s); - } - } - stbi__skip(s, pad); - } - } - else { - for (j = 0; j < (int)s->img_y; ++j) { - for (i = 0; i < (int)s->img_x; i += 2) { - int v = stbi__get8(s), v2 = 0; - if (info.bpp == 4) { - v2 = v & 15; - v >>= 4; - } - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - if (i + 1 == (int)s->img_x) break; - v = (info.bpp == 8) ? stbi__get8(s) : v2; - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - } - stbi__skip(s, pad); - } - } - } - else { - int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; - int z = 0; - int easy = 0; - stbi__skip(s, info.offset - info.extra_read - info.hsz); - if (info.bpp == 24) width = 3 * s->img_x; - else if (info.bpp == 16) width = 2 * s->img_x; - else /* bpp = 32 and pad = 0 */ width = 0; - pad = (-width) & 3; - if (info.bpp == 24) { - easy = 1; - } - else if (info.bpp == 32) { - if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) - easy = 2; - } - if (!easy) { - if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } - // right shift amt to put high bit in position #7 - rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); - gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); - bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); - ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); - if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } - } - for (j = 0; j < (int)s->img_y; ++j) { - if (easy) { - for (i = 0; i < (int)s->img_x; ++i) { - unsigned char a; - out[z + 2] = stbi__get8(s); - out[z + 1] = stbi__get8(s); - out[z + 0] = stbi__get8(s); - z += 3; - a = (easy == 2 ? stbi__get8(s) : 255); - all_a |= a; - if (target == 4) out[z++] = a; - } - } - else { - int bpp = info.bpp; - for (i = 0; i < (int)s->img_x; ++i) { - stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); - unsigned int a; - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); - a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); - all_a |= a; - if (target == 4) out[z++] = STBI__BYTECAST(a); - } - } - stbi__skip(s, pad); - } - } - - // if alpha channel is all 0s, replace with all 255s - if (target == 4 && all_a == 0) - for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) - out[i] = 255; - - if (flip_vertically) { - stbi_uc t; - for (j = 0; j < (int)s->img_y >> 1; ++j) { - stbi_uc* p1 = out + j * s->img_x * target; - stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; - for (i = 0; i < (int)s->img_x * target; ++i) { - t = p1[i]; p1[i] = p2[i]; p2[i] = t; - } - } - } - - if (req_comp && req_comp != target) { - out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - return out; -} -#endif - -// Targa Truevision - TGA -// by Jonathan Dummer -#ifndef STBI_NO_TGA -// returns STBI_rgb or whatever, 0 on error -static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) -{ - // only RGB or RGBA (incl. 16bit) or grey allowed - if (is_rgb16) *is_rgb16 = 0; - switch (bits_per_pixel) { - case 8: return STBI_grey; - case 16: if (is_grey) return STBI_grey_alpha; - // fallthrough - case 15: if (is_rgb16) *is_rgb16 = 1; - return STBI_rgb; - case 24: // fallthrough - case 32: return bits_per_pixel / 8; - default: return 0; - } -} - -static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) -{ - int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; - int sz, tga_colormap_type; - stbi__get8(s); // discard Offset - tga_colormap_type = stbi__get8(s); // colormap type - if (tga_colormap_type > 1) { - stbi__rewind(s); - return 0; // only RGB or indexed allowed - } - tga_image_type = stbi__get8(s); // image type - if (tga_colormap_type == 1) { // colormapped (paletted) image - if (tga_image_type != 1 && tga_image_type != 9) { - stbi__rewind(s); - return 0; - } - stbi__skip(s, 4); // skip index of first colormap entry and number of entries - sz = stbi__get8(s); // check bits per palette color entry - if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { - stbi__rewind(s); - return 0; - } - stbi__skip(s, 4); // skip image x and y origin - tga_colormap_bpp = sz; - } - else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE - if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { - stbi__rewind(s); - return 0; // only RGB or grey allowed, +/- RLE - } - stbi__skip(s, 9); // skip colormap specification and image x/y origin - tga_colormap_bpp = 0; - } - tga_w = stbi__get16le(s); - if (tga_w < 1) { - stbi__rewind(s); - return 0; // test width - } - tga_h = stbi__get16le(s); - if (tga_h < 1) { - stbi__rewind(s); - return 0; // test height - } - tga_bits_per_pixel = stbi__get8(s); // bits per pixel - stbi__get8(s); // ignore alpha bits - if (tga_colormap_bpp != 0) { - if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { - // when using a colormap, tga_bits_per_pixel is the size of the indexes - // I don't think anything but 8 or 16bit indexes makes sense - stbi__rewind(s); - return 0; - } - tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); - } - else { - tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); - } - if (!tga_comp) { - stbi__rewind(s); - return 0; - } - if (x) *x = tga_w; - if (y) *y = tga_h; - if (comp) *comp = tga_comp; - return 1; // seems to have passed everything -} - -static int stbi__tga_test(stbi__context* s) -{ - int res = 0; - int sz, tga_color_type; - stbi__get8(s); // discard Offset - tga_color_type = stbi__get8(s); // color type - if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed - sz = stbi__get8(s); // image type - if (tga_color_type == 1) { // colormapped (paletted) image - if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 - stbi__skip(s, 4); // skip index of first colormap entry and number of entries - sz = stbi__get8(s); // check bits per palette color entry - if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; - stbi__skip(s, 4); // skip image x and y origin - } - else { // "normal" image w/o colormap - if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE - stbi__skip(s, 9); // skip colormap specification and image x/y origin - } - if (stbi__get16le(s) < 1) goto errorEnd; // test width - if (stbi__get16le(s) < 1) goto errorEnd; // test height - sz = stbi__get8(s); // bits per pixel - if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index - if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; - - res = 1; // if we got this far, everything's good and we can return 1 instead of 0 - -errorEnd: - stbi__rewind(s); - return res; -} - -// read 16bit value and convert to 24bit RGB -static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) -{ - stbi__uint16 px = (stbi__uint16)stbi__get16le(s); - stbi__uint16 fiveBitMask = 31; - // we have 3 channels with 5bits each - int r = (px >> 10) & fiveBitMask; - int g = (px >> 5) & fiveBitMask; - int b = px & fiveBitMask; - // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later - out[0] = (stbi_uc)((r * 255) / 31); - out[1] = (stbi_uc)((g * 255) / 31); - out[2] = (stbi_uc)((b * 255) / 31); - - // some people claim that the most significant bit might be used for alpha - // (possibly if an alpha-bit is set in the "image descriptor byte") - // but that only made 16bit test images completely translucent.. - // so let's treat all 15 and 16bit TGAs as RGB with no alpha. -} - -static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) -{ - // read in the TGA header stuff - int tga_offset = stbi__get8(s); - int tga_indexed = stbi__get8(s); - int tga_image_type = stbi__get8(s); - int tga_is_RLE = 0; - int tga_palette_start = stbi__get16le(s); - int tga_palette_len = stbi__get16le(s); - int tga_palette_bits = stbi__get8(s); - int tga_x_origin = stbi__get16le(s); - int tga_y_origin = stbi__get16le(s); - int tga_width = stbi__get16le(s); - int tga_height = stbi__get16le(s); - int tga_bits_per_pixel = stbi__get8(s); - int tga_comp, tga_rgb16 = 0; - int tga_inverted = stbi__get8(s); - // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) - // image data - unsigned char* tga_data; - unsigned char* tga_palette = NULL; - int i, j; - unsigned char raw_data[4] = { 0 }; - int RLE_count = 0; - int RLE_repeating = 0; - int read_next_pixel = 1; - STBI_NOTUSED(ri); - STBI_NOTUSED(tga_x_origin); // @TODO - STBI_NOTUSED(tga_y_origin); // @TODO - - if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - - // do a tiny bit of precessing - if (tga_image_type >= 8) - { - tga_image_type -= 8; - tga_is_RLE = 1; - } - tga_inverted = 1 - ((tga_inverted >> 5) & 1); - - // If I'm paletted, then I'll use the number of bits from the palette - if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); - else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); - - if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency - return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); - - // tga info - *x = tga_width; - *y = tga_height; - if (comp) *comp = tga_comp; - - if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) - return stbi__errpuc("too large", "Corrupt TGA"); - - tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); - if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); - - // skip to the data's starting position (offset usually = 0) - stbi__skip(s, tga_offset); - - if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { - for (i = 0; i < tga_height; ++i) { - int row = tga_inverted ? tga_height - i - 1 : i; - stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; - stbi__getn(s, tga_row, tga_width * tga_comp); - } - } - else { - // do I need to load a palette? - if (tga_indexed) - { - if (tga_palette_len == 0) { /* you have to have at least one entry! */ - STBI_FREE(tga_data); - return stbi__errpuc("bad palette", "Corrupt TGA"); - } - - // any data to skip? (offset usually = 0) - stbi__skip(s, tga_palette_start); - // load the palette - tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); - if (!tga_palette) { - STBI_FREE(tga_data); - return stbi__errpuc("outofmem", "Out of memory"); - } - if (tga_rgb16) { - stbi_uc* pal_entry = tga_palette; - STBI_ASSERT(tga_comp == STBI_rgb); - for (i = 0; i < tga_palette_len; ++i) { - stbi__tga_read_rgb16(s, pal_entry); - pal_entry += tga_comp; - } - } - else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { - STBI_FREE(tga_data); - STBI_FREE(tga_palette); - return stbi__errpuc("bad palette", "Corrupt TGA"); - } - } - // load the data - for (i = 0; i < tga_width * tga_height; ++i) - { - // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? - if (tga_is_RLE) - { - if (RLE_count == 0) - { - // yep, get the next byte as a RLE command - int RLE_cmd = stbi__get8(s); - RLE_count = 1 + (RLE_cmd & 127); - RLE_repeating = RLE_cmd >> 7; - read_next_pixel = 1; - } - else if (!RLE_repeating) - { - read_next_pixel = 1; - } - } - else - { - read_next_pixel = 1; - } - // OK, if I need to read a pixel, do it now - if (read_next_pixel) - { - // load however much data we did have - if (tga_indexed) - { - // read in index, then perform the lookup - int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); - if (pal_idx >= tga_palette_len) { - // invalid index - pal_idx = 0; - } - pal_idx *= tga_comp; - for (j = 0; j < tga_comp; ++j) { - raw_data[j] = tga_palette[pal_idx + j]; - } - } - else if (tga_rgb16) { - STBI_ASSERT(tga_comp == STBI_rgb); - stbi__tga_read_rgb16(s, raw_data); - } - else { - // read in the data raw - for (j = 0; j < tga_comp; ++j) { - raw_data[j] = stbi__get8(s); - } - } - // clear the reading flag for the next pixel - read_next_pixel = 0; - } // end of reading a pixel - - // copy data - for (j = 0; j < tga_comp; ++j) - tga_data[i * tga_comp + j] = raw_data[j]; - - // in case we're in RLE mode, keep counting down - --RLE_count; - } - // do I need to invert the image? - if (tga_inverted) - { - for (j = 0; j * 2 < tga_height; ++j) - { - int index1 = j * tga_width * tga_comp; - int index2 = (tga_height - 1 - j) * tga_width * tga_comp; - for (i = tga_width * tga_comp; i > 0; --i) - { - unsigned char temp = tga_data[index1]; - tga_data[index1] = tga_data[index2]; - tga_data[index2] = temp; - ++index1; - ++index2; - } - } - } - // clear my palette, if I had one - if (tga_palette != NULL) - { - STBI_FREE(tga_palette); - } - } - - // swap RGB - if the source data was RGB16, it already is in the right order - if (tga_comp >= 3 && !tga_rgb16) - { - unsigned char* tga_pixel = tga_data; - for (i = 0; i < tga_width * tga_height; ++i) - { - unsigned char temp = tga_pixel[0]; - tga_pixel[0] = tga_pixel[2]; - tga_pixel[2] = temp; - tga_pixel += tga_comp; - } - } - - // convert to target component count - if (req_comp && req_comp != tga_comp) - tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); - - // the things I do to get rid of an error message, and yet keep - // Microsoft's C compilers happy... [8^( - tga_palette_start = tga_palette_len = tga_palette_bits = - tga_x_origin = tga_y_origin = 0; - STBI_NOTUSED(tga_palette_start); - // OK, done - return tga_data; -} -#endif - -// ************************************************************************************************* -// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB - -#ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context* s) -{ - int r = (stbi__get32be(s) == 0x38425053); - stbi__rewind(s); - return r; -} - -static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) -{ - int count, nleft, len; - - count = 0; - while ((nleft = pixelCount - count) > 0) { - len = stbi__get8(s); - if (len == 128) { - // No-op. - } - else if (len < 128) { - // Copy next len+1 bytes literally. - len++; - if (len > nleft) return 0; // corrupt data - count += len; - while (len) { - *p = stbi__get8(s); - p += 4; - len--; - } - } - else if (len > 128) { - stbi_uc val; - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len = 257 - len; - if (len > nleft) return 0; // corrupt data - val = stbi__get8(s); - count += len; - while (len) { - *p = val; - p += 4; - len--; - } - } - } - - return 1; -} - -static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) -{ - int pixelCount; - int channelCount, compression; - int channel, i; - int bitdepth; - int w, h; - stbi_uc* out; - STBI_NOTUSED(ri); - - // Check identifier - if (stbi__get32be(s) != 0x38425053) // "8BPS" - return stbi__errpuc("not PSD", "Corrupt PSD image"); - - // Check file type version. - if (stbi__get16be(s) != 1) - return stbi__errpuc("wrong version", "Unsupported version of PSD image"); - - // Skip 6 reserved bytes. - stbi__skip(s, 6); - - // Read the number of channels (R, G, B, A, etc). - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) - return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); - - // Read the rows and columns of the image. - h = stbi__get32be(s); - w = stbi__get32be(s); - - if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - - // Make sure the depth is 8 bits. - bitdepth = stbi__get16be(s); - if (bitdepth != 8 && bitdepth != 16) - return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); - - // Make sure the color mode is RGB. - // Valid options are: - // 0: Bitmap - // 1: Grayscale - // 2: Indexed color - // 3: RGB color - // 4: CMYK color - // 7: Multichannel - // 8: Duotone - // 9: Lab color - if (stbi__get16be(s) != 3) - return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); - - // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) - stbi__skip(s, stbi__get32be(s)); - - // Skip the image resources. (resolution, pen tool paths, etc) - stbi__skip(s, stbi__get32be(s)); - - // Skip the reserved data. - stbi__skip(s, stbi__get32be(s)); - - // Find out if the data is compressed. - // Known values: - // 0: no compression - // 1: RLE compressed - compression = stbi__get16be(s); - if (compression > 1) - return stbi__errpuc("bad compression", "PSD has an unknown compression format"); - - // Check size - if (!stbi__mad3sizes_valid(4, w, h, 0)) - return stbi__errpuc("too large", "Corrupt PSD"); - - // Create the destination image. - - if (!compression && bitdepth == 16 && bpc == 16) { - out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); - ri->bits_per_channel = 16; - } - else - out = (stbi_uc*)stbi__malloc(4 * w * h); - - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - pixelCount = w * h; - - // Initialize the data to zero. - //memset( out, 0, pixelCount * 4 ); - - // Finally, the image data. - if (compression) { - // RLE as used by .PSD and .TIFF - // Loop until you get the number of unpacked bytes you are expecting: - // Read the next source byte into n. - // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. - // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. - // Else if n is 128, noop. - // Endloop - - // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, - // which we're going to just skip. - stbi__skip(s, h * channelCount * 2); - - // Read the RLE data by channel. - for (channel = 0; channel < 4; channel++) { - stbi_uc* p; - - p = out + channel; - if (channel >= channelCount) { - // Fill this channel with default data. - for (i = 0; i < pixelCount; i++, p += 4) - *p = (channel == 3 ? 255 : 0); - } - else { - // Read the RLE data. - if (!stbi__psd_decode_rle(s, p, pixelCount)) { - STBI_FREE(out); - return stbi__errpuc("corrupt", "bad RLE data"); - } - } - } - - } - else { - // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. - - // Read the data by channel. - for (channel = 0; channel < 4; channel++) { - if (channel >= channelCount) { - // Fill this channel with default data. - if (bitdepth == 16 && bpc == 16) { - stbi__uint16* q = ((stbi__uint16*)out) + channel; - stbi__uint16 val = channel == 3 ? 65535 : 0; - for (i = 0; i < pixelCount; i++, q += 4) - *q = val; - } - else { - stbi_uc* p = out + channel; - stbi_uc val = channel == 3 ? 255 : 0; - for (i = 0; i < pixelCount; i++, p += 4) - *p = val; - } - } - else { - if (ri->bits_per_channel == 16) { // output bpc - stbi__uint16* q = ((stbi__uint16*)out) + channel; - for (i = 0; i < pixelCount; i++, q += 4) - *q = (stbi__uint16)stbi__get16be(s); - } - else { - stbi_uc* p = out + channel; - if (bitdepth == 16) { // input bpc - for (i = 0; i < pixelCount; i++, p += 4) - *p = (stbi_uc)(stbi__get16be(s) >> 8); - } - else { - for (i = 0; i < pixelCount; i++, p += 4) - *p = stbi__get8(s); - } - } - } - } - } - - // remove weird white matte from PSD - if (channelCount >= 4) { - if (ri->bits_per_channel == 16) { - for (i = 0; i < w * h; ++i) { - stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; - if (pixel[3] != 0 && pixel[3] != 65535) { - float a = pixel[3] / 65535.0f; - float ra = 1.0f / a; - float inv_a = 65535.0f * (1 - ra); - pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); - pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); - pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); - } - } - } - else { - for (i = 0; i < w * h; ++i) { - unsigned char* pixel = out + 4 * i; - if (pixel[3] != 0 && pixel[3] != 255) { - float a = pixel[3] / 255.0f; - float ra = 1.0f / a; - float inv_a = 255.0f * (1 - ra); - pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); - pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); - pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); - } - } - } - } - - // convert to desired output format - if (req_comp && req_comp != 4) { - if (ri->bits_per_channel == 16) - out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); - else - out = stbi__convert_format(out, 4, req_comp, w, h); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - - if (comp) *comp = 4; - *y = h; - *x = w; - - return out; -} -#endif - -// ************************************************************************************************* -// Softimage PIC loader -// by Tom Seddon -// -// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format -// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ - -#ifndef STBI_NO_PIC -static int stbi__pic_is4(stbi__context* s, const char* str) -{ - int i; - for (i = 0; i < 4; ++i) - if (stbi__get8(s) != (stbi_uc)str[i]) - return 0; - - return 1; -} - -static int stbi__pic_test_core(stbi__context* s) -{ - int i; - - if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) - return 0; - - for (i = 0; i < 84; ++i) - stbi__get8(s); - - if (!stbi__pic_is4(s, "PICT")) - return 0; - - return 1; -} - -typedef struct -{ - stbi_uc size, type, channel; -} stbi__pic_packet; - -static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) -{ - int mask = 0x80, i; - - for (i = 0; i < 4; ++i, mask >>= 1) { - if (channel & mask) { - if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); - dest[i] = stbi__get8(s); - } - } - - return dest; -} - -static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) -{ - int mask = 0x80, i; - - for (i = 0; i < 4; ++i, mask >>= 1) - if (channel & mask) - dest[i] = src[i]; -} - -static stbi_uc* stbi__pic_load_core(stbi__context* s, int width, int height, int* comp, stbi_uc* result) -{ - int act_comp = 0, num_packets = 0, y, chained; - stbi__pic_packet packets[10]; - - // this will (should...) cater for even some bizarre stuff like having data - // for the same channel in multiple packets. - do { - stbi__pic_packet* packet; - - if (num_packets == sizeof(packets) / sizeof(packets[0])) - return stbi__errpuc("bad format", "too many packets"); - - packet = &packets[num_packets++]; - - chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); - packet->channel = stbi__get8(s); - - act_comp |= packet->channel; - - if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (reading packets)"); - if (packet->size != 8) return stbi__errpuc("bad format", "packet isn't 8bpp"); - } while (chained); - - *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? - - for (y = 0; y < height; ++y) { - int packet_idx; - - for (packet_idx = 0; packet_idx < num_packets; ++packet_idx) { - stbi__pic_packet* packet = &packets[packet_idx]; - stbi_uc* dest = result + y * width * 4; - - switch (packet->type) { - default: - return stbi__errpuc("bad format", "packet has bad compression type"); - - case 0: {//uncompressed - int x; - - for (x = 0; x < width; ++x, dest += 4) - if (!stbi__readval(s, packet->channel, dest)) - return 0; - break; - } - - case 1://Pure RLE - { - int left = width, i; - - while (left > 0) { - stbi_uc count, value[4]; - - count = stbi__get8(s); - if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pure read count)"); - - if (count > left) - count = (stbi_uc)left; - - if (!stbi__readval(s, packet->channel, value)) return 0; - - for (i = 0; i < count; ++i, dest += 4) - stbi__copyval(packet->channel, dest, value); - left -= count; - } - } - break; - - case 2: {//Mixed RLE - int left = width; - while (left > 0) { - int count = stbi__get8(s), i; - if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (mixed read count)"); - - if (count >= 128) { // Repeated - stbi_uc value[4]; - - if (count == 128) - count = stbi__get16be(s); - else - count -= 127; - if (count > left) - return stbi__errpuc("bad file", "scanline overrun"); - - if (!stbi__readval(s, packet->channel, value)) - return 0; - - for (i = 0; i < count; ++i, dest += 4) - stbi__copyval(packet->channel, dest, value); - } - else { // Raw - ++count; - if (count > left) return stbi__errpuc("bad file", "scanline overrun"); - - for (i = 0; i < count; ++i, dest += 4) - if (!stbi__readval(s, packet->channel, dest)) - return 0; - } - left -= count; - } - break; - } - } - } - } - - return result; -} - -static void* stbi__pic_load(stbi__context* s, int* px, int* py, int* comp, int req_comp, stbi__result_info* ri) -{ - stbi_uc* result; - int i, x, y, internal_comp; - STBI_NOTUSED(ri); - - if (!comp) comp = &internal_comp; - - for (i = 0; i < 92; ++i) - stbi__get8(s); - - x = stbi__get16be(s); - y = stbi__get16be(s); - - if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - - if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pic header)"); - if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); - - stbi__get32be(s); //skip `ratio' - stbi__get16be(s); //skip `fields' - stbi__get16be(s); //skip `pad' - - // intermediate buffer is RGBA - result = (stbi_uc*)stbi__malloc_mad3(x, y, 4, 0); - memset(result, 0xff, x * y * 4); - - if (!stbi__pic_load_core(s, x, y, comp, result)) { - STBI_FREE(result); - result = 0; - } - *px = x; - *py = y; - if (req_comp == 0) req_comp = *comp; - result = stbi__convert_format(result, 4, req_comp, x, y); - - return result; -} - -static int stbi__pic_test(stbi__context* s) -{ - int r = stbi__pic_test_core(s); - stbi__rewind(s); - return r; -} -#endif - -// ************************************************************************************************* -// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb - -#ifndef STBI_NO_GIF -typedef struct -{ - stbi__int16 prefix; - stbi_uc first; - stbi_uc suffix; -} stbi__gif_lzw; - -typedef struct -{ - int w, h; - stbi_uc* out; // output buffer (always 4 components) - stbi_uc* background; // The current "background" as far as a gif is concerned - stbi_uc* history; - int flags, bgindex, ratio, transparent, eflags; - stbi_uc pal[256][4]; - stbi_uc lpal[256][4]; - stbi__gif_lzw codes[8192]; - stbi_uc* color_table; - int parse, step; - int lflags; - int start_x, start_y; - int max_x, max_y; - int cur_x, cur_y; - int line_size; - int delay; -} stbi__gif; - -static int stbi__gif_test_raw(stbi__context* s) -{ - int sz; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; - sz = stbi__get8(s); - if (sz != '9' && sz != '7') return 0; - if (stbi__get8(s) != 'a') return 0; - return 1; -} - -static int stbi__gif_test(stbi__context* s) -{ - int r = stbi__gif_test_raw(s); - stbi__rewind(s); - return r; -} - -static void stbi__gif_parse_colortable(stbi__context* s, stbi_uc pal[256][4], int num_entries, int transp) -{ - int i; - for (i = 0; i < num_entries; ++i) { - pal[i][2] = stbi__get8(s); - pal[i][1] = stbi__get8(s); - pal[i][0] = stbi__get8(s); - pal[i][3] = transp == i ? 0 : 255; - } -} - -static int stbi__gif_header(stbi__context* s, stbi__gif* g, int* comp, int is_info) -{ - stbi_uc version; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') - return stbi__err("not GIF", "Corrupt GIF"); - - version = stbi__get8(s); - if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); - if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); - - stbi__g_failure_reason = ""; - g->w = stbi__get16le(s); - g->h = stbi__get16le(s); - g->flags = stbi__get8(s); - g->bgindex = stbi__get8(s); - g->ratio = stbi__get8(s); - g->transparent = -1; - - if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); - if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); - - if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments - - if (is_info) return 1; - - if (g->flags & 0x80) - stbi__gif_parse_colortable(s, g->pal, 2 << (g->flags & 7), -1); - - return 1; -} - -static int stbi__gif_info_raw(stbi__context* s, int* x, int* y, int* comp) -{ - stbi__gif* g = (stbi__gif*)stbi__malloc(sizeof(stbi__gif)); - if (!stbi__gif_header(s, g, comp, 1)) { - STBI_FREE(g); - stbi__rewind(s); - return 0; - } - if (x) *x = g->w; - if (y) *y = g->h; - STBI_FREE(g); - return 1; -} - -static void stbi__out_gif_code(stbi__gif* g, stbi__uint16 code) -{ - stbi_uc* p, * c; - int idx; - - // recurse to decode the prefixes, since the linked-list is backwards, - // and working backwards through an interleaved image would be nasty - if (g->codes[code].prefix >= 0) - stbi__out_gif_code(g, g->codes[code].prefix); - - if (g->cur_y >= g->max_y) return; - - idx = g->cur_x + g->cur_y; - p = &g->out[idx]; - g->history[idx / 4] = 1; - - c = &g->color_table[g->codes[code].suffix * 4]; - if (c[3] > 128) { // don't render transparent pixels; - p[0] = c[2]; - p[1] = c[1]; - p[2] = c[0]; - p[3] = c[3]; - } - g->cur_x += 4; - - if (g->cur_x >= g->max_x) { - g->cur_x = g->start_x; - g->cur_y += g->step; - - while (g->cur_y >= g->max_y && g->parse > 0) { - g->step = (1 << g->parse) * g->line_size; - g->cur_y = g->start_y + (g->step >> 1); - --g->parse; - } - } -} - -static stbi_uc* stbi__process_gif_raster(stbi__context* s, stbi__gif* g) -{ - stbi_uc lzw_cs; - stbi__int32 len, init_code; - stbi__uint32 first; - stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; - stbi__gif_lzw* p; - - lzw_cs = stbi__get8(s); - if (lzw_cs > 12) return NULL; - clear = 1 << lzw_cs; - first = 1; - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - bits = 0; - valid_bits = 0; - for (init_code = 0; init_code < clear; init_code++) { - g->codes[init_code].prefix = -1; - g->codes[init_code].first = (stbi_uc)init_code; - g->codes[init_code].suffix = (stbi_uc)init_code; - } - - // support no starting clear code - avail = clear + 2; - oldcode = -1; - - len = 0; - for (;;) { - if (valid_bits < codesize) { - if (len == 0) { - len = stbi__get8(s); // start new block - if (len == 0) - return g->out; - } - --len; - bits |= (stbi__int32)stbi__get8(s) << valid_bits; - valid_bits += 8; - } - else { - stbi__int32 code = bits & codemask; - bits >>= codesize; - valid_bits -= codesize; - // @OPTIMIZE: is there some way we can accelerate the non-clear path? - if (code == clear) { // clear code - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - avail = clear + 2; - oldcode = -1; - first = 0; - } - else if (code == clear + 1) { // end of stream code - stbi__skip(s, len); - while ((len = stbi__get8(s)) > 0) - stbi__skip(s, len); - return g->out; - } - else if (code <= avail) { - if (first) { - return stbi__errpuc("no clear code", "Corrupt GIF"); - } - - if (oldcode >= 0) { - p = &g->codes[avail++]; - if (avail > 8192) { - return stbi__errpuc("too many codes", "Corrupt GIF"); - } - - p->prefix = (stbi__int16)oldcode; - p->first = g->codes[oldcode].first; - p->suffix = (code == avail) ? p->first : g->codes[code].first; - } - else if (code == avail) - return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - - stbi__out_gif_code(g, (stbi__uint16)code); - - if ((avail & codemask) == 0 && avail <= 0x0FFF) { - codesize++; - codemask = (1 << codesize) - 1; - } - - oldcode = code; - } - else { - return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - } - } - } -} - -// this function is designed to support animated gifs, although stb_image doesn't support it -// two back is the image from two frames ago, used for a very specific disposal format -static stbi_uc* stbi__gif_load_next(stbi__context* s, stbi__gif* g, int* comp, int req_comp, stbi_uc* two_back) -{ - int dispose; - int first_frame; - int pi; - int pcount; - STBI_NOTUSED(req_comp); - - // on first frame, any non-written pixels get the background colour (non-transparent) - first_frame = 0; - if (g->out == 0) { - if (!stbi__gif_header(s, g, comp, 0)) return 0; // stbi__g_failure_reason set by stbi__gif_header - if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) - return stbi__errpuc("too large", "GIF image is too large"); - pcount = g->w * g->h; - g->out = (stbi_uc*)stbi__malloc(4 * pcount); - g->background = (stbi_uc*)stbi__malloc(4 * pcount); - g->history = (stbi_uc*)stbi__malloc(pcount); - if (!g->out || !g->background || !g->history) - return stbi__errpuc("outofmem", "Out of memory"); - - // image is treated as "transparent" at the start - ie, nothing overwrites the current background; - // background colour is only used for pixels that are not rendered first frame, after that "background" - // color refers to the color that was there the previous frame. - memset(g->out, 0x00, 4 * pcount); - memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) - memset(g->history, 0x00, pcount); // pixels that were affected previous frame - first_frame = 1; - } - else { - // second frame - how do we dispose of the previous one? - dispose = (g->eflags & 0x1C) >> 2; - pcount = g->w * g->h; - - if ((dispose == 3) && (two_back == 0)) { - dispose = 2; // if I don't have an image to revert back to, default to the old background - } - - if (dispose == 3) { // use previous graphic - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi]) { - memcpy(&g->out[pi * 4], &two_back[pi * 4], 4); - } - } - } - else if (dispose == 2) { - // restore what was changed last frame to background before that frame; - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi]) { - memcpy(&g->out[pi * 4], &g->background[pi * 4], 4); - } - } - } - else { - // This is a non-disposal case eithe way, so just - // leave the pixels as is, and they will become the new background - // 1: do not dispose - // 0: not specified. - } - - // background is what out is after the undoing of the previou frame; - memcpy(g->background, g->out, 4 * g->w * g->h); - } - - // clear my history; - memset(g->history, 0x00, g->w * g->h); // pixels that were affected previous frame - - for (;;) { - int tag = stbi__get8(s); - switch (tag) { - case 0x2C: /* Image Descriptor */ - { - stbi__int32 x, y, w, h; - stbi_uc* o; - - x = stbi__get16le(s); - y = stbi__get16le(s); - w = stbi__get16le(s); - h = stbi__get16le(s); - if (((x + w) > (g->w)) || ((y + h) > (g->h))) - return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); - - g->line_size = g->w * 4; - g->start_x = x * 4; - g->start_y = y * g->line_size; - g->max_x = g->start_x + w * 4; - g->max_y = g->start_y + h * g->line_size; - g->cur_x = g->start_x; - g->cur_y = g->start_y; - - // if the width of the specified rectangle is 0, that means - // we may not see *any* pixels or the image is malformed; - // to make sure this is caught, move the current y down to - // max_y (which is what out_gif_code checks). - if (w == 0) - g->cur_y = g->max_y; - - g->lflags = stbi__get8(s); - - if (g->lflags & 0x40) { - g->step = 8 * g->line_size; // first interlaced spacing - g->parse = 3; - } - else { - g->step = g->line_size; - g->parse = 0; - } - - if (g->lflags & 0x80) { - stbi__gif_parse_colortable(s, g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); - g->color_table = (stbi_uc*)g->lpal; - } - else if (g->flags & 0x80) { - g->color_table = (stbi_uc*)g->pal; - } - else - return stbi__errpuc("missing color table", "Corrupt GIF"); - - o = stbi__process_gif_raster(s, g); - if (!o) return NULL; - - // if this was the first frame, - pcount = g->w * g->h; - if (first_frame && (g->bgindex > 0)) { - // if first frame, any pixel not drawn to gets the background color - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi] == 0) { - g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; - memcpy(&g->out[pi * 4], &g->pal[g->bgindex], 4); - } - } - } - - return o; - } - - case 0x21: // Comment Extension. - { - int len; - int ext = stbi__get8(s); - if (ext == 0xF9) { // Graphic Control Extension. - len = stbi__get8(s); - if (len == 4) { - g->eflags = stbi__get8(s); - g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. - - // unset old transparent - if (g->transparent >= 0) { - g->pal[g->transparent][3] = 255; - } - if (g->eflags & 0x01) { - g->transparent = stbi__get8(s); - if (g->transparent >= 0) { - g->pal[g->transparent][3] = 0; - } - } - else { - // don't need transparent - stbi__skip(s, 1); - g->transparent = -1; - } - } - else { - stbi__skip(s, len); - break; - } - } - while ((len = stbi__get8(s)) != 0) { - stbi__skip(s, len); - } - break; - } - - case 0x3B: // gif stream termination code - return (stbi_uc*)s; // using '1' causes warning on some compilers - - default: - return stbi__errpuc("unknown code", "Corrupt GIF"); - } - } -} - -static void* stbi__load_gif_main(stbi__context* s, int** delays, int* x, int* y, int* z, int* comp, int req_comp) -{ - if (stbi__gif_test(s)) { - int layers = 0; - stbi_uc* u = 0; - stbi_uc* out = 0; - stbi_uc* two_back = 0; - stbi__gif g; - int stride; - int out_size = 0; - int delays_size = 0; - memset(&g, 0, sizeof(g)); - if (delays) { - *delays = 0; - } - - do { - u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); - if (u == (stbi_uc*)s) u = 0; // end of animated gif marker - - if (u) { - *x = g.w; - *y = g.h; - ++layers; - stride = g.w * g.h * 4; - - if (out) { - void* tmp = (stbi_uc*)STBI_REALLOC_SIZED(out, out_size, layers * stride); - if (NULL == tmp) { - STBI_FREE(g.out); - STBI_FREE(g.history); - STBI_FREE(g.background); - return stbi__errpuc("outofmem", "Out of memory"); - } - else { - out = (stbi_uc*)tmp; - out_size = layers * stride; - } - - if (delays) { - *delays = (int*)STBI_REALLOC_SIZED(*delays, delays_size, sizeof(int) * layers); - delays_size = layers * sizeof(int); - } - } - else { - out = (stbi_uc*)stbi__malloc(layers * stride); - out_size = layers * stride; - if (delays) { - *delays = (int*)stbi__malloc(layers * sizeof(int)); - delays_size = layers * sizeof(int); - } - } - memcpy(out + ((layers - 1) * stride), u, stride); - if (layers >= 2) { - two_back = out - 2 * stride; - } - - if (delays) { - (*delays)[layers - 1U] = g.delay; - } - } - } while (u != 0); - - // free temp buffer; - STBI_FREE(g.out); - STBI_FREE(g.history); - STBI_FREE(g.background); - - // do the final conversion after loading everything; - if (req_comp && req_comp != 4) - out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); - - *z = layers; - return out; - } - else { - return stbi__errpuc("not GIF", "Image was not as a gif type."); - } -} - -static void* stbi__gif_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) -{ - stbi_uc* u = 0; - stbi__gif g; - memset(&g, 0, sizeof(g)); - STBI_NOTUSED(ri); - - u = stbi__gif_load_next(s, &g, comp, req_comp, 0); - if (u == (stbi_uc*)s) u = 0; // end of animated gif marker - if (u) { - *x = g.w; - *y = g.h; - - // moved conversion to after successful load so that the same - // can be done for multiple frames. - if (req_comp && req_comp != 4) - u = stbi__convert_format(u, 4, req_comp, g.w, g.h); - } - else if (g.out) { - // if there was an error and we allocated an image buffer, free it! - STBI_FREE(g.out); - } - - // free buffers needed for multiple frame loading; - STBI_FREE(g.history); - STBI_FREE(g.background); - - return u; -} - -static int stbi__gif_info(stbi__context* s, int* x, int* y, int* comp) -{ - return stbi__gif_info_raw(s, x, y, comp); -} -#endif - -// ************************************************************************************************* -// Radiance RGBE HDR loader -// originally by Nicolas Schulz -#ifndef STBI_NO_HDR -static int stbi__hdr_test_core(stbi__context* s, const char* signature) -{ - int i; - for (i = 0; signature[i]; ++i) - if (stbi__get8(s) != signature[i]) - return 0; - stbi__rewind(s); - return 1; -} - -static int stbi__hdr_test(stbi__context* s) -{ - int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); - stbi__rewind(s); - if (!r) { - r = stbi__hdr_test_core(s, "#?RGBE\n"); - stbi__rewind(s); - } - return r; -} - -#define STBI__HDR_BUFLEN 1024 -static char* stbi__hdr_gettoken(stbi__context* z, char* buffer) -{ - int len = 0; - char c = '\0'; - - c = (char)stbi__get8(z); - - while (!stbi__at_eof(z) && c != '\n') { - buffer[len++] = c; - if (len == STBI__HDR_BUFLEN - 1) { - // flush to end of line - while (!stbi__at_eof(z) && stbi__get8(z) != '\n') - ; - break; - } - c = (char)stbi__get8(z); - } - - buffer[len] = 0; - return buffer; -} - -static void stbi__hdr_convert(float* output, stbi_uc* input, int req_comp) -{ - if (input[3] != 0) { - float f1; - // Exponent - f1 = (float)ldexp(1.0f, input[3] - (int)(128 + 8)); - if (req_comp <= 2) - output[0] = (input[0] + input[1] + input[2]) * f1 / 3; - else { - output[0] = input[0] * f1; - output[1] = input[1] * f1; - output[2] = input[2] * f1; - } - if (req_comp == 2) output[1] = 1; - if (req_comp == 4) output[3] = 1; - } - else { - switch (req_comp) { - case 4: output[3] = 1; /* fallthrough */ - case 3: output[0] = output[1] = output[2] = 0; - break; - case 2: output[1] = 1; /* fallthrough */ - case 1: output[0] = 0; - break; - } - } -} - -static float* stbi__hdr_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) -{ - char buffer[STBI__HDR_BUFLEN]; - char* token; - int valid = 0; - int width, height; - stbi_uc* scanline; - float* hdr_data; - int len; - unsigned char count, value; - int i, j, k, c1, c2, z; - const char* headerToken; - STBI_NOTUSED(ri); - - // Check identifier - headerToken = stbi__hdr_gettoken(s, buffer); - if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) - return stbi__errpf("not HDR", "Corrupt HDR image"); - - // Parse header - for (;;) { - token = stbi__hdr_gettoken(s, buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); - - // Parse width and height - // can't use sscanf() if we're not using stdio! - token = stbi__hdr_gettoken(s, buffer); - if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); - token += 3; - height = (int)strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); - token += 3; - width = (int)strtol(token, NULL, 10); - - if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large", "Very large image (corrupt?)"); - if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large", "Very large image (corrupt?)"); - - *x = width; - *y = height; - - if (comp) *comp = 3; - if (req_comp == 0) req_comp = 3; - - if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) - return stbi__errpf("too large", "HDR image is too large"); - - // Read data - hdr_data = (float*)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); - if (!hdr_data) - return stbi__errpf("outofmem", "Out of memory"); - - // Load image data - // image data is stored as some number of sca - if (width < 8 || width >= 32768) { - // Read flat data - for (j = 0; j < height; ++j) { - for (i = 0; i < width; ++i) { - stbi_uc rgbe[4]; - main_decode_loop: - stbi__getn(s, rgbe, 4); - stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); - } - } - } - else { - // Read RLE-encoded data - scanline = NULL; - - for (j = 0; j < height; ++j) { - c1 = stbi__get8(s); - c2 = stbi__get8(s); - len = stbi__get8(s); - if (c1 != 2 || c2 != 2 || (len & 0x80)) { - // not run-length encoded, so we have to actually use THIS data as a decoded - // pixel (note this can't be a valid pixel--one of RGB must be >= 128) - stbi_uc rgbe[4]; - rgbe[0] = (stbi_uc)c1; - rgbe[1] = (stbi_uc)c2; - rgbe[2] = (stbi_uc)len; - rgbe[3] = (stbi_uc)stbi__get8(s); - stbi__hdr_convert(hdr_data, rgbe, req_comp); - i = 1; - j = 0; - STBI_FREE(scanline); - goto main_decode_loop; // yes, this makes no sense - } - len <<= 8; - len |= stbi__get8(s); - if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) { - scanline = (stbi_uc*)stbi__malloc_mad2(width, 4, 0); - if (!scanline) { - STBI_FREE(hdr_data); - return stbi__errpf("outofmem", "Out of memory"); - } - } - - for (k = 0; k < 4; ++k) { - int nleft; - i = 0; - while ((nleft = width - i) > 0) { - count = stbi__get8(s); - if (count > 128) { - // Run - value = stbi__get8(s); - count -= 128; - if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = value; - } - else { - // Dump - if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = stbi__get8(s); - } - } - } - for (i = 0; i < width; ++i) - stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp); - } - if (scanline) - STBI_FREE(scanline); - } - - return hdr_data; -} - -static int stbi__hdr_info(stbi__context* s, int* x, int* y, int* comp) -{ - char buffer[STBI__HDR_BUFLEN]; - char* token; - int valid = 0; - int dummy; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - if (stbi__hdr_test(s) == 0) { - stbi__rewind(s); - return 0; - } - - for (;;) { - token = stbi__hdr_gettoken(s, buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) { - stbi__rewind(s); - return 0; - } - token = stbi__hdr_gettoken(s, buffer); - if (strncmp(token, "-Y ", 3)) { - stbi__rewind(s); - return 0; - } - token += 3; - *y = (int)strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) { - stbi__rewind(s); - return 0; - } - token += 3; - *x = (int)strtol(token, NULL, 10); - *comp = 3; - return 1; -} -#endif // STBI_NO_HDR - -#ifndef STBI_NO_BMP -static int stbi__bmp_info(stbi__context* s, int* x, int* y, int* comp) -{ - void* p; - stbi__bmp_data info; - - info.all_a = 255; - p = stbi__bmp_parse_header(s, &info); - stbi__rewind(s); - if (p == NULL) - return 0; - if (x) *x = s->img_x; - if (y) *y = s->img_y; - if (comp) { - if (info.bpp == 24 && info.ma == 0xff000000) - *comp = 3; - else - *comp = info.ma ? 4 : 3; - } - return 1; -} -#endif - -#ifndef STBI_NO_PSD -static int stbi__psd_info(stbi__context* s, int* x, int* y, int* comp) -{ - int channelCount, dummy, depth; - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind(s); - return 0; - } - if (stbi__get16be(s) != 1) { - stbi__rewind(s); - return 0; - } - stbi__skip(s, 6); - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind(s); - return 0; - } - *y = stbi__get32be(s); - *x = stbi__get32be(s); - depth = stbi__get16be(s); - if (depth != 8 && depth != 16) { - stbi__rewind(s); - return 0; - } - if (stbi__get16be(s) != 3) { - stbi__rewind(s); - return 0; - } - *comp = 4; - return 1; -} - -static int stbi__psd_is16(stbi__context* s) -{ - int channelCount, depth; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind(s); - return 0; - } - if (stbi__get16be(s) != 1) { - stbi__rewind(s); - return 0; - } - stbi__skip(s, 6); - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind(s); - return 0; - } - (void)stbi__get32be(s); - (void)stbi__get32be(s); - depth = stbi__get16be(s); - if (depth != 16) { - stbi__rewind(s); - return 0; - } - return 1; -} -#endif - -#ifndef STBI_NO_PIC -static int stbi__pic_info(stbi__context* s, int* x, int* y, int* comp) -{ - int act_comp = 0, num_packets = 0, chained, dummy; - stbi__pic_packet packets[10]; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) { - stbi__rewind(s); - return 0; - } - - stbi__skip(s, 88); - - *x = stbi__get16be(s); - *y = stbi__get16be(s); - if (stbi__at_eof(s)) { - stbi__rewind(s); - return 0; - } - if ((*x) != 0 && (1 << 28) / (*x) < (*y)) { - stbi__rewind(s); - return 0; - } - - stbi__skip(s, 8); - - do { - stbi__pic_packet* packet; - - if (num_packets == sizeof(packets) / sizeof(packets[0])) - return 0; - - packet = &packets[num_packets++]; - chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); - packet->channel = stbi__get8(s); - act_comp |= packet->channel; - - if (stbi__at_eof(s)) { - stbi__rewind(s); - return 0; - } - if (packet->size != 8) { - stbi__rewind(s); - return 0; - } - } while (chained); - - *comp = (act_comp & 0x10 ? 4 : 3); - - return 1; -} -#endif - -// ************************************************************************************************* -// Portable Gray Map and Portable Pixel Map loader -// by Ken Miller -// -// PGM: http://netpbm.sourceforge.net/doc/pgm.html -// PPM: http://netpbm.sourceforge.net/doc/ppm.html -// -// Known limitations: -// Does not support comments in the header section -// Does not support ASCII image data (formats P2 and P3) -// Does not support 16-bit-per-channel - -#ifndef STBI_NO_PNM - -static int stbi__pnm_test(stbi__context* s) -{ - char p, t; - p = (char)stbi__get8(s); - t = (char)stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind(s); - return 0; - } - return 1; -} - -static void* stbi__pnm_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) -{ - stbi_uc* out; - STBI_NOTUSED(ri); - - if (!stbi__pnm_info(s, (int*)&s->img_x, (int*)&s->img_y, (int*)&s->img_n)) - return 0; - - if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); - - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - - if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) - return stbi__errpuc("too large", "PNM too large"); - - out = (stbi_uc*)stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - stbi__getn(s, out, s->img_n * s->img_x * s->img_y); - - if (req_comp && req_comp != s->img_n) { - out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - return out; -} - -static int stbi__pnm_isspace(char c) -{ - return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; -} - -static void stbi__pnm_skip_whitespace(stbi__context* s, char* c) -{ - for (;;) { - while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) - *c = (char)stbi__get8(s); - - if (stbi__at_eof(s) || *c != '#') - break; - - while (!stbi__at_eof(s) && *c != '\n' && *c != '\r') - *c = (char)stbi__get8(s); - } -} - -static int stbi__pnm_isdigit(char c) -{ - return c >= '0' && c <= '9'; -} - -static int stbi__pnm_getinteger(stbi__context* s, char* c) -{ - int value = 0; - - while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { - value = value * 10 + (*c - '0'); - *c = (char)stbi__get8(s); - } - - return value; -} - -static int stbi__pnm_info(stbi__context* s, int* x, int* y, int* comp) -{ - int maxv, dummy; - char c, p, t; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - stbi__rewind(s); - - // Get identifier - p = (char)stbi__get8(s); - t = (char)stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind(s); - return 0; - } - - *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm - - c = (char)stbi__get8(s); - stbi__pnm_skip_whitespace(s, &c); - - *x = stbi__pnm_getinteger(s, &c); // read width - stbi__pnm_skip_whitespace(s, &c); - - *y = stbi__pnm_getinteger(s, &c); // read height - stbi__pnm_skip_whitespace(s, &c); - - maxv = stbi__pnm_getinteger(s, &c); // read max value - - if (maxv > 255) - return stbi__err("max value > 255", "PPM image not 8-bit"); - else - return 1; -} -#endif - -static int stbi__info_main(stbi__context* s, int* x, int* y, int* comp) -{ -#ifndef STBI_NO_JPEG - if (stbi__jpeg_info(s, x, y, comp)) return 1; -#endif - -#ifndef STBI_NO_PNG - if (stbi__png_info(s, x, y, comp)) return 1; -#endif - -#ifndef STBI_NO_GIF - if (stbi__gif_info(s, x, y, comp)) return 1; -#endif - -#ifndef STBI_NO_BMP - if (stbi__bmp_info(s, x, y, comp)) return 1; -#endif - -#ifndef STBI_NO_PSD - if (stbi__psd_info(s, x, y, comp)) return 1; -#endif - -#ifndef STBI_NO_PIC - if (stbi__pic_info(s, x, y, comp)) return 1; -#endif - -#ifndef STBI_NO_PNM - if (stbi__pnm_info(s, x, y, comp)) return 1; -#endif - -#ifndef STBI_NO_HDR - if (stbi__hdr_info(s, x, y, comp)) return 1; -#endif - - // test tga last because it's a crappy test! -#ifndef STBI_NO_TGA - if (stbi__tga_info(s, x, y, comp)) - return 1; -#endif - return stbi__err("unknown image type", "Image not of any known type, or corrupt"); -} - -static int stbi__is_16_main(stbi__context* s) -{ -#ifndef STBI_NO_PNG - if (stbi__png_is16(s)) return 1; -#endif - -#ifndef STBI_NO_PSD - if (stbi__psd_is16(s)) return 1; -#endif - - return 0; -} - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_info(char const* filename, int* x, int* y, int* comp) -{ - FILE* f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_info_from_file(f, x, y, comp); - fclose(f); - return result; -} - -STBIDEF int stbi_info_from_file(FILE* f, int* x, int* y, int* comp) -{ - int r; - stbi__context s; - long pos = ftell(f); - stbi__start_file(&s, f); - r = stbi__info_main(&s, x, y, comp); - fseek(f, pos, SEEK_SET); - return r; -} - -STBIDEF int stbi_is_16_bit(char const* filename) -{ - FILE* f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_is_16_bit_from_file(f); - fclose(f); - return result; -} - -STBIDEF int stbi_is_16_bit_from_file(FILE* f) -{ - int r; - stbi__context s; - long pos = ftell(f); - stbi__start_file(&s, f); - r = stbi__is_16_main(&s); - fseek(f, pos, SEEK_SET); - return r; -} -#endif // !STBI_NO_STDIO - -STBIDEF int stbi_info_from_memory(stbi_uc const* buffer, int len, int* x, int* y, int* comp) -{ - stbi__context s; - stbi__start_mem(&s, buffer, len); - return stbi__info_main(&s, x, y, comp); -} - -STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const* c, void* user, int* x, int* y, int* comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks*)c, user); - return stbi__info_main(&s, x, y, comp); -} - -STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const* buffer, int len) -{ - stbi__context s; - stbi__start_mem(&s, buffer, len); - return stbi__is_16_main(&s); -} - -STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const* c, void* user) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks*)c, user); - return stbi__is_16_main(&s); -} diff --git a/Dependencies/stb_image/stb_image.h b/Dependencies/stb_image/stb_image.h deleted file mode 100644 index dedb071..0000000 --- a/Dependencies/stb_image/stb_image.h +++ /dev/null @@ -1,738 +0,0 @@ -/* stb_image - v2.26 - public domain image loader - http://nothings.org/stb - no warranty implied; use at your own risk - - Do this: - #define STB_IMAGE_IMPLEMENTATION - before you include this file in *one* C or C++ file to create the implementation. - - // i.e. it should look like this: - #include ... - #include ... - #include ... - #define STB_IMAGE_IMPLEMENTATION - #include "stb_image.h" - - You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. - And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free - - - QUICK NOTES: - Primarily of interest to game developers and other people who can - avoid problematic images and only need the trivial interface - - JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) - PNG 1/2/4/8/16-bit-per-channel - - TGA (not sure what subset, if a subset) - BMP non-1bpp, non-RLE - PSD (composited view only, no extra channels, 8/16 bit-per-channel) - - GIF (*comp always reports as 4-channel) - HDR (radiance rgbE format) - PIC (Softimage PIC) - PNM (PPM and PGM binary only) - - Animated GIF still needs a proper API, but here's one way to do it: - http://gist.github.com/urraka/685d9a6340b26b830d49 - - - decode from memory or through FILE (define STBI_NO_STDIO to remove code) - - decode from arbitrary I/O callbacks - - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) - - Full documentation under "DOCUMENTATION" below. - - -LICENSE - - See end of file for license information. - -RECENT REVISION HISTORY: - - 2.26 (2020-07-13) many minor fixes - 2.25 (2020-02-02) fix warnings - 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically - 2.23 (2019-08-11) fix clang static analysis warning - 2.22 (2019-03-04) gif fixes, fix warnings - 2.21 (2019-02-25) fix typo in comment - 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs - 2.19 (2018-02-11) fix warning - 2.18 (2018-01-30) fix warnings - 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings - 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes - 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC - 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs - 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes - 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes - 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 - RGB-format JPEG; remove white matting in PSD; - allocate large structures on the stack; - correct channel count for PNG & BMP - 2.10 (2016-01-22) avoid warning introduced in 2.09 - 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED - - See end of file for full revision history. - - - ============================ Contributors ========================= - - Image formats Extensions, features - Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) - Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) - Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) - Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) - Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) - Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) - Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) - github:urraka (animated gif) Junggon Kim (PNM comments) - Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) - socks-the-fox (16-bit PNG) - Jeremy Sawicki (handle all ImageNet JPGs) - Optimizations & bugfixes Mikhail Morozov (1-bit BMP) - Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) - Arseny Kapoulkine - John-Mark Allen - Carmelo J Fdez-Aguera - - Bug & warning fixes - Marc LeBlanc David Woo Guillaume George Martins Mozeiko - Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski - Phil Jordan Dave Moore Roy Eltham - Hayaki Saito Nathan Reed Won Chun - Luke Graham Johan Duparc Nick Verigakis the Horde3D community - Thomas Ruf Ronny Chevalier github:rlyeh - Janez Zemva John Bartholomew Michal Cichon github:romigrou - Jonathan Blow Ken Hamada Tero Hanninen github:svdijk - Laurent Gomila Cort Stratton github:snagar - Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex - Cass Everitt Ryamond Barbiero github:grim210 - Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw - Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus - Josh Tobin Matthew Gregan github:poppolopoppo - Julian Raschke Gregory Mullen Christian Floisand github:darealshinji - Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 - Brad Weinberger Matvey Cherevko [reserved] - Luca Sas Alexander Veselov Zack Middleton [reserved] - Ryan C. Gordon [reserved] [reserved] - DO NOT ADD YOUR NAME HERE - - To add your name to the credits, pick a random blank space in the middle and fill it. - 80% of merge conflicts on stb PRs are due to people adding their name at the end - of the credits. -*/ - -#ifndef STBI_INCLUDE_STB_IMAGE_H -#define STBI_INCLUDE_STB_IMAGE_H - -// DOCUMENTATION -// -// Limitations: -// - no 12-bit-per-channel JPEG -// - no JPEGs with arithmetic coding -// - GIF always returns *comp=4 -// -// Basic usage (see HDR discussion below for HDR usage): -// int x,y,n; -// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); -// // ... process data if not NULL ... -// // ... x = width, y = height, n = # 8-bit components per pixel ... -// // ... replace '0' with '1'..'4' to force that many components per pixel -// // ... but 'n' will always be the number that it would have been if you said 0 -// stbi_image_free(data) -// -// Standard parameters: -// int *x -- outputs image width in pixels -// int *y -- outputs image height in pixels -// int *channels_in_file -- outputs # of image components in image file -// int desired_channels -- if non-zero, # of image components requested in result -// -// The return value from an image loader is an 'unsigned char *' which points -// to the pixel data, or NULL on an allocation failure or if the image is -// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, -// with each pixel consisting of N interleaved 8-bit components; the first -// pixel pointed to is top-left-most in the image. There is no padding between -// image scanlines or between pixels, regardless of format. The number of -// components N is 'desired_channels' if desired_channels is non-zero, or -// *channels_in_file otherwise. If desired_channels is non-zero, -// *channels_in_file has the number of components that _would_ have been -// output otherwise. E.g. if you set desired_channels to 4, you will always -// get RGBA output, but you can check *channels_in_file to see if it's trivially -// opaque because e.g. there were only 3 channels in the source image. -// -// An output image with N components has the following components interleaved -// in this order in each pixel: -// -// N=#comp components -// 1 grey -// 2 grey, alpha -// 3 red, green, blue -// 4 red, green, blue, alpha -// -// If image loading fails for any reason, the return value will be NULL, -// and *x, *y, *channels_in_file will be unchanged. The function -// stbi_failure_reason() can be queried for an extremely brief, end-user -// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS -// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly -// more user-friendly ones. -// -// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. -// -// =========================================================================== -// -// UNICODE: -// -// If compiling for Windows and you wish to use Unicode filenames, compile -// with -// #define STBI_WINDOWS_UTF8 -// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert -// Windows wchar_t filenames to utf8. -// -// =========================================================================== -// -// Philosophy -// -// stb libraries are designed with the following priorities: -// -// 1. easy to use -// 2. easy to maintain -// 3. good performance -// -// Sometimes I let "good performance" creep up in priority over "easy to maintain", -// and for best performance I may provide less-easy-to-use APIs that give higher -// performance, in addition to the easy-to-use ones. Nevertheless, it's important -// to keep in mind that from the standpoint of you, a client of this library, -// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. -// -// Some secondary priorities arise directly from the first two, some of which -// provide more explicit reasons why performance can't be emphasized. -// -// - Portable ("ease of use") -// - Small source code footprint ("easy to maintain") -// - No dependencies ("ease of use") -// -// =========================================================================== -// -// I/O callbacks -// -// I/O callbacks allow you to read from arbitrary sources, like packaged -// files or some other source. Data read from callbacks are processed -// through a small internal buffer (currently 128 bytes) to try to reduce -// overhead. -// -// The three functions you must define are "read" (reads some bytes of data), -// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). -// -// =========================================================================== -// -// SIMD support -// -// The JPEG decoder will try to automatically use SIMD kernels on x86 when -// supported by the compiler. For ARM Neon support, you must explicitly -// request it. -// -// (The old do-it-yourself SIMD API is no longer supported in the current -// code.) -// -// On x86, SSE2 will automatically be used when available based on a run-time -// test; if not, the generic C versions are used as a fall-back. On ARM targets, -// the typical path is to have separate builds for NEON and non-NEON devices -// (at least this is true for iOS and Android). Therefore, the NEON support is -// toggled by a build flag: define STBI_NEON to get NEON loops. -// -// If for some reason you do not want to use any of SIMD code, or if -// you have issues compiling it, you can disable it entirely by -// defining STBI_NO_SIMD. -// -// =========================================================================== -// -// HDR image support (disable by defining STBI_NO_HDR) -// -// stb_image supports loading HDR images in general, and currently the Radiance -// .HDR file format specifically. You can still load any file through the existing -// interface; if you attempt to load an HDR file, it will be automatically remapped -// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; -// both of these constants can be reconfigured through this interface: -// -// stbi_hdr_to_ldr_gamma(2.2f); -// stbi_hdr_to_ldr_scale(1.0f); -// -// (note, do not use _inverse_ constants; stbi_image will invert them -// appropriately). -// -// Additionally, there is a new, parallel interface for loading files as -// (linear) floats to preserve the full dynamic range: -// -// float *data = stbi_loadf(filename, &x, &y, &n, 0); -// -// If you load LDR images through this interface, those images will -// be promoted to floating point values, run through the inverse of -// constants corresponding to the above: -// -// stbi_ldr_to_hdr_scale(1.0f); -// stbi_ldr_to_hdr_gamma(2.2f); -// -// Finally, given a filename (or an open file or memory block--see header -// file for details) containing image data, you can query for the "most -// appropriate" interface to use (that is, whether the image is HDR or -// not), using: -// -// stbi_is_hdr(char *filename); -// -// =========================================================================== -// -// iPhone PNG support: -// -// By default we convert iphone-formatted PNGs back to RGB, even though -// they are internally encoded differently. You can disable this conversion -// by calling stbi_convert_iphone_png_to_rgb(0), in which case -// you will always just get the native iphone "format" through (which -// is BGR stored in RGB). -// -// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per -// pixel to remove any premultiplied alpha *only* if the image file explicitly -// says there's premultiplied data (currently only happens in iPhone images, -// and only if iPhone convert-to-rgb processing is on). -// -// =========================================================================== -// -// ADDITIONAL CONFIGURATION -// -// - You can suppress implementation of any of the decoders to reduce -// your code footprint by #defining one or more of the following -// symbols before creating the implementation. -// -// STBI_NO_JPEG -// STBI_NO_PNG -// STBI_NO_BMP -// STBI_NO_PSD -// STBI_NO_TGA -// STBI_NO_GIF -// STBI_NO_HDR -// STBI_NO_PIC -// STBI_NO_PNM (.ppm and .pgm) -// -// - You can request *only* certain decoders and suppress all other ones -// (this will be more forward-compatible, as addition of new decoders -// doesn't require you to disable them explicitly): -// -// STBI_ONLY_JPEG -// STBI_ONLY_PNG -// STBI_ONLY_BMP -// STBI_ONLY_PSD -// STBI_ONLY_TGA -// STBI_ONLY_GIF -// STBI_ONLY_HDR -// STBI_ONLY_PIC -// STBI_ONLY_PNM (.ppm and .pgm) -// -// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still -// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB -// -// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater -// than that size (in either width or height) without further processing. -// This is to let programs in the wild set an upper bound to prevent -// denial-of-service attacks on untrusted data, as one could generate a -// valid image of gigantic dimensions and force stb_image to allocate a -// huge block of memory and spend disproportionate time decoding it. By -// default this is set to (1 << 24), which is 16777216, but that's still -// very big. - -#ifndef STBI_NO_STDIO -#include -#endif // STBI_NO_STDIO - -#define STBI_VERSION 1 - -enum -{ - STBI_default = 0, // only used for desired_channels - - STBI_grey = 1, - STBI_grey_alpha = 2, - STBI_rgb = 3, - STBI_rgb_alpha = 4 -}; - -#include -typedef unsigned char stbi_uc; -typedef unsigned short stbi_us; - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef STBIDEF -#ifdef STB_IMAGE_STATIC -#define STBIDEF static -#else -#define STBIDEF extern -#endif -#endif - - ////////////////////////////////////////////////////////////////////////////// - // - // PRIMARY API - works on images of any type - // - - // - // load image by filename, open file, or memory buffer - // - - typedef struct - { - int (*read) (void* user, char* data, int size); // fill 'data' with 'size' bytes. return number of bytes actually read - void (*skip) (void* user, int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative - int (*eof) (void* user); // returns nonzero if we are at end of file/data - } stbi_io_callbacks; - - //////////////////////////////////// - // - // 8-bits-per-channel interface - // - - STBIDEF stbi_uc* stbi_load_from_memory(stbi_uc const* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels); - STBIDEF stbi_uc* stbi_load_from_callbacks(stbi_io_callbacks const* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels); - -#ifndef STBI_NO_STDIO - STBIDEF stbi_uc* stbi_load(char const* filename, int* x, int* y, int* channels_in_file, int desired_channels); - STBIDEF stbi_uc* stbi_load_from_file(FILE* f, int* x, int* y, int* channels_in_file, int desired_channels); - // for stbi_load_from_file, file pointer is left pointing immediately after image -#endif - -#ifndef STBI_NO_GIF - STBIDEF stbi_uc* stbi_load_gif_from_memory(stbi_uc const* buffer, int len, int** delays, int* x, int* y, int* z, int* comp, int req_comp); -#endif - -#ifdef STBI_WINDOWS_UTF8 - STBIDEF int stbi_convert_wchar_to_utf8(char* buffer, size_t bufferlen, const wchar_t* input); -#endif - - //////////////////////////////////// - // - // 16-bits-per-channel interface - // - - STBIDEF stbi_us* stbi_load_16_from_memory(stbi_uc const* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels); - STBIDEF stbi_us* stbi_load_16_from_callbacks(stbi_io_callbacks const* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels); - -#ifndef STBI_NO_STDIO - STBIDEF stbi_us* stbi_load_16(char const* filename, int* x, int* y, int* channels_in_file, int desired_channels); - STBIDEF stbi_us* stbi_load_from_file_16(FILE* f, int* x, int* y, int* channels_in_file, int desired_channels); -#endif - - //////////////////////////////////// - // - // float-per-channel interface - // -#ifndef STBI_NO_LINEAR - STBIDEF float* stbi_loadf_from_memory(stbi_uc const* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels); - STBIDEF float* stbi_loadf_from_callbacks(stbi_io_callbacks const* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels); - -#ifndef STBI_NO_STDIO - STBIDEF float* stbi_loadf(char const* filename, int* x, int* y, int* channels_in_file, int desired_channels); - STBIDEF float* stbi_loadf_from_file(FILE* f, int* x, int* y, int* channels_in_file, int desired_channels); -#endif -#endif - -#ifndef STBI_NO_HDR - STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); - STBIDEF void stbi_hdr_to_ldr_scale(float scale); -#endif // STBI_NO_HDR - -#ifndef STBI_NO_LINEAR - STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); - STBIDEF void stbi_ldr_to_hdr_scale(float scale); -#endif // STBI_NO_LINEAR - - // stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR - STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const* clbk, void* user); - STBIDEF int stbi_is_hdr_from_memory(stbi_uc const* buffer, int len); -#ifndef STBI_NO_STDIO - STBIDEF int stbi_is_hdr(char const* filename); - STBIDEF int stbi_is_hdr_from_file(FILE* f); -#endif // STBI_NO_STDIO - - - // get a VERY brief reason for failure - // on most compilers (and ALL modern mainstream compilers) this is threadsafe - STBIDEF const char* stbi_failure_reason(void); - - // free the loaded image -- this is just free() - STBIDEF void stbi_image_free(void* retval_from_stbi_load); - - // get image dimensions & components without fully decoding - STBIDEF int stbi_info_from_memory(stbi_uc const* buffer, int len, int* x, int* y, int* comp); - STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const* clbk, void* user, int* x, int* y, int* comp); - STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const* buffer, int len); - STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const* clbk, void* user); - -#ifndef STBI_NO_STDIO - STBIDEF int stbi_info(char const* filename, int* x, int* y, int* comp); - STBIDEF int stbi_info_from_file(FILE* f, int* x, int* y, int* comp); - STBIDEF int stbi_is_16_bit(char const* filename); - STBIDEF int stbi_is_16_bit_from_file(FILE* f); -#endif - - - - // for image formats that explicitly notate that they have premultiplied alpha, - // we just return the colors as stored in the file. set this flag to force - // unpremultiplication. results are undefined if the unpremultiply overflow. - STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); - - // indicate whether we should process iphone images back to canonical format, - // or just pass them through "as-is" - STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); - - // flip the image vertically, so the first pixel in the output array is the bottom left - STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); - - // as above, but only applies to images loaded on the thread that calls the function - // this function is only available if your compiler supports thread-local variables; - // calling it will fail to link if your compiler doesn't - STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); - - // ZLIB client - used by PNG, available for other purposes - - STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen); - STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header); - STBIDEF char* stbi_zlib_decode_malloc(const char* buffer, int len, int* outlen); - STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, const char* ibuffer, int ilen); - - STBIDEF char* stbi_zlib_decode_noheader_malloc(const char* buffer, int len, int* outlen); - STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen); - - -#ifdef __cplusplus -} -#endif - -// -// -//// end header file ///////////////////////////////////////////////////// -#endif // STBI_INCLUDE_STB_IMAGE_H - -/* - revision history: - 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs - 2.19 (2018-02-11) fix warning - 2.18 (2018-01-30) fix warnings - 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug - 1-bit BMP - *_is_16_bit api - avoid warnings - 2.16 (2017-07-23) all functions have 16-bit variants; - STBI_NO_STDIO works again; - compilation fixes; - fix rounding in unpremultiply; - optimize vertical flip; - disable raw_len validation; - documentation fixes - 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; - warning fixes; disable run-time SSE detection on gcc; - uniform handling of optional "return" values; - thread-safe initialization of zlib tables - 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs - 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now - 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes - 2.11 (2016-04-02) allocate large structures on the stack - remove white matting for transparent PSD - fix reported channel count for PNG & BMP - re-enable SSE2 in non-gcc 64-bit - support RGB-formatted JPEG - read 16-bit PNGs (only as 8-bit) - 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED - 2.09 (2016-01-16) allow comments in PNM files - 16-bit-per-pixel TGA (not bit-per-component) - info() for TGA could break due to .hdr handling - info() for BMP to shares code instead of sloppy parse - can use STBI_REALLOC_SIZED if allocator doesn't support realloc - code cleanup - 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA - 2.07 (2015-09-13) fix compiler warnings - partial animated GIF support - limited 16-bpc PSD support - #ifdef unused functions - bug with < 92 byte PIC,PNM,HDR,TGA - 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value - 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning - 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit - 2.03 (2015-04-12) extra corruption checking (mmozeiko) - stbi_set_flip_vertically_on_load (nguillemot) - fix NEON support; fix mingw support - 2.02 (2015-01-19) fix incorrect assert, fix warning - 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 - 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG - 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) - progressive JPEG (stb) - PGM/PPM support (Ken Miller) - STBI_MALLOC,STBI_REALLOC,STBI_FREE - GIF bugfix -- seemingly never worked - STBI_NO_*, STBI_ONLY_* - 1.48 (2014-12-14) fix incorrectly-named assert() - 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) - optimize PNG (ryg) - fix bug in interlaced PNG with user-specified channel count (stb) - 1.46 (2014-08-26) - fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG - 1.45 (2014-08-16) - fix MSVC-ARM internal compiler error by wrapping malloc - 1.44 (2014-08-07) - various warning fixes from Ronny Chevalier - 1.43 (2014-07-15) - fix MSVC-only compiler problem in code changed in 1.42 - 1.42 (2014-07-09) - don't define _CRT_SECURE_NO_WARNINGS (affects user code) - fixes to stbi__cleanup_jpeg path - added STBI_ASSERT to avoid requiring assert.h - 1.41 (2014-06-25) - fix search&replace from 1.36 that messed up comments/error messages - 1.40 (2014-06-22) - fix gcc struct-initialization warning - 1.39 (2014-06-15) - fix to TGA optimization when req_comp != number of components in TGA; - fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) - add support for BMP version 5 (more ignored fields) - 1.38 (2014-06-06) - suppress MSVC warnings on integer casts truncating values - fix accidental rename of 'skip' field of I/O - 1.37 (2014-06-04) - remove duplicate typedef - 1.36 (2014-06-03) - convert to header file single-file library - if de-iphone isn't set, load iphone images color-swapped instead of returning NULL - 1.35 (2014-05-27) - various warnings - fix broken STBI_SIMD path - fix bug where stbi_load_from_file no longer left file pointer in correct place - fix broken non-easy path for 32-bit BMP (possibly never used) - TGA optimization by Arseny Kapoulkine - 1.34 (unknown) - use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case - 1.33 (2011-07-14) - make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements - 1.32 (2011-07-13) - support for "info" function for all supported filetypes (SpartanJ) - 1.31 (2011-06-20) - a few more leak fixes, bug in PNG handling (SpartanJ) - 1.30 (2011-06-11) - added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) - removed deprecated format-specific test/load functions - removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway - error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) - fix inefficiency in decoding 32-bit BMP (David Woo) - 1.29 (2010-08-16) - various warning fixes from Aurelien Pocheville - 1.28 (2010-08-01) - fix bug in GIF palette transparency (SpartanJ) - 1.27 (2010-08-01) - cast-to-stbi_uc to fix warnings - 1.26 (2010-07-24) - fix bug in file buffering for PNG reported by SpartanJ - 1.25 (2010-07-17) - refix trans_data warning (Won Chun) - 1.24 (2010-07-12) - perf improvements reading from files on platforms with lock-heavy fgetc() - minor perf improvements for jpeg - deprecated type-specific functions so we'll get feedback if they're needed - attempt to fix trans_data warning (Won Chun) - 1.23 fixed bug in iPhone support - 1.22 (2010-07-10) - removed image *writing* support - stbi_info support from Jetro Lauha - GIF support from Jean-Marc Lienher - iPhone PNG-extensions from James Brown - warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) - 1.21 fix use of 'stbi_uc' in header (reported by jon blow) - 1.20 added support for Softimage PIC, by Tom Seddon - 1.19 bug in interlaced PNG corruption check (found by ryg) - 1.18 (2008-08-02) - fix a threading bug (local mutable static) - 1.17 support interlaced PNG - 1.16 major bugfix - stbi__convert_format converted one too many pixels - 1.15 initialize some fields for thread safety - 1.14 fix threadsafe conversion bug - header-file-only version (#define STBI_HEADER_FILE_ONLY before including) - 1.13 threadsafe - 1.12 const qualifiers in the API - 1.11 Support installable IDCT, colorspace conversion routines - 1.10 Fixes for 64-bit (don't use "unsigned long") - optimized upsampling by Fabian "ryg" Giesen - 1.09 Fix format-conversion for PSD code (bad global variables!) - 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz - 1.07 attempt to fix C++ warning/errors again - 1.06 attempt to fix C++ warning/errors again - 1.05 fix TGA loading to return correct *comp and use good luminance calc - 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free - 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR - 1.02 support for (subset of) HDR files, float interface for preferred access to them - 1.01 fix bug: possible bug in handling right-side up bmps... not sure - fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all - 1.00 interface to zlib that skips zlib header - 0.99 correct handling of alpha in palette - 0.98 TGA loader by lonesock; dynamically add loaders (untested) - 0.97 jpeg errors on too large a file; also catch another malloc failure - 0.96 fix detection of invalid v value - particleman@mollyrocket forum - 0.95 during header scan, seek to markers in case of padding - 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same - 0.93 handle jpegtran output; verbose errors - 0.92 read 4,8,16,24,32-bit BMP files of several formats - 0.91 output 24-bit Windows 3.0 BMP files - 0.90 fix a few more warnings; bump version number to approach 1.0 - 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd - 0.60 fix compiling as c++ - 0.59 fix warnings: merge Dave Moore's -Wall fixes - 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian - 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available - 0.56 fix bug: zlib uncompressed mode len vs. nlen - 0.55 fix bug: restart_interval not initialized to 0 - 0.54 allow NULL for 'int *comp' - 0.53 fix bug in png 3->4; speedup png decoding - 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments - 0.51 obey req_comp requests, 1-component jpegs return as 1-component, - on 'test' only check type, not whether we support this variant - 0.50 (2006-11-19) - first released version -*/ - - -/* ------------------------------------------------------------------------------- -This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------- -ALTERNATIVE A - MIT License -Copyright (c) 2017 Sean Barrett -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. ------------------------------------------------------------------------------- -ALTERNATIVE B - Public Domain (www.unlicense.org) -This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, -commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to -this software under copyright law. -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 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. ------------------------------------------------------------------------------- -*/ diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt new file mode 100644 index 0000000..5d815be --- /dev/null +++ b/Engine/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 3.21.2) + +message("______________________________________________________________________") +message("Building Engine...") + +if (CMAKE_COMPILER_IS_GNUCC) + add_compile_options(-w) +endif() +if(MSVC) + add_compile_options(/MP) + add_compile_options(/W0) +endif() + +file(GLOB_RECURSE ENGINE_ALL_FILES true ABSOLUTE ${ENGINE_DIR}src/*) +file(GLOB_RECURSE ENGINE_RES_FILES true ABSOLUTE ${ENGINE_DIR}res/*) +list(LENGTH ENGINE_ALL_FILES ENGINE_ALL_FILES_COUNT) +message("Found " ${ENGINE_ALL_FILES_COUNT} " files in Engine") + +if(NOT WIN32) + set (DX_DIR ${ENGINE_DIR}src/Platform/GraphicsAPI/DirectX/) + set (WIN_DIR ${ENGINE_DIR}src/Platform/OS/Windows/) + + list(REMOVE_ITEM ENGINE_ALL_FILES + ${DX_DIR}dxBlender.cpp + ${DX_DIR}dxBuffers.cpp + ${DX_DIR}dxFramebuffer.cpp + ${DX_DIR}dxGraphicsContext.cpp + ${DX_DIR}dxRenderCommand.cpp + ${DX_DIR}dxShader.cpp + ${DX_DIR}dxSharedContext.cpp + ${DX_DIR}dxTexture.cpp + ${DX_DIR}dxUserInterface.cpp + ${DX_DIR}dxVertexLayout.cpp + ${WIN_DIR}wWindow.cpp) + +endif() + +list(LENGTH ENGINE_ALL_FILES ENGINE_ALL_FILES_COUNT) +message(${ENGINE_ALL_FILES_COUNT} " files left in Engine after excludes") + +include_directories( +${ENGINE_DIR}src/Engine/ +${ENGINE_DIR}src/Platform/GraphicsAPI/ +${ENGINE_DIR}src/Platform/OS/ +${DEPENDENCIES_DIR}entt/src/ +${DEPENDENCIES_DIR}GLAD/include/ +${DEPENDENCIES_DIR}GLFW/include/ +${DEPENDENCIES_DIR}glm/ +${DEPENDENCIES_DIR}imgui/ +${DEPENDENCIES_DIR}spdlog/include +${DEPENDENCIES_DIR}stb_image/ +) + +source_group(TREE ${ENGINE_DIR} FILES ${ENGINE_ALL_FILES} ${ENGINE_RES_FILES}) +add_library(Engine STATIC ${ENGINE_ALL_FILES} ${ENGINE_RES_FILES}) + +if(WIN32) + target_link_libraries(Engine d3d11) + target_link_libraries(Engine dxguid) + target_link_libraries(Engine D3DCompiler) +endif() + +message("______________________________________________________________________") diff --git a/Engine/res/Fonts/OpenSans/LICENSE.txt b/Engine/res/Fonts/OpenSans/LICENSE.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Engine/res/Fonts/OpenSans/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Engine/res/Fonts/OpenSans/OpenSans-Bold.ttf b/Engine/res/Fonts/OpenSans/OpenSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..efdd5e84a0397ecada7b9cfde51db87db08766bd GIT binary patch literal 104120 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

n{#NV($fZ=b2Ttd7 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 -Ui0>vvum!cQP#SwwX988o3plLZOz)* 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 literal 0 HcmV?d00001 diff --git a/Engine/res/Fonts/OpenSans/OpenSans-BoldItalic.ttf b/Engine/res/Fonts/OpenSans/OpenSans-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9bf9b4e97b6576c8cc3d4527073731fd9cc57493 GIT binary patch literal 92628 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

4J;+I{;ffTJG!iGMcG*?Vwl&%p(3b?*`L@59ZU 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

9nNjw4~{@r0I~;bjWEs}nhrT# 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

!GC&_!#ZtN*Mh&_?3T(2tal^%sA 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%0A4!eHJa6ihh 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 tF{6TqYG~a+&=^Ld*=$fFp9q2yx(>MC>Dm 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�?uC|3&0+ngjt%GBCAB^%e& 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

_T_kl)Xoan=RX{3lY#VQTZ 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 literal 0 HcmV?d00001 diff --git a/Engine/res/Fonts/OpenSans/OpenSans-SemiBold.ttf b/Engine/res/Fonts/OpenSans/OpenSans-SemiBold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..54e7059cf36359cb5a3860085714a95306af0dea GIT binary patch literal 100820 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 DEZ%x^ literal 0 HcmV?d00001 diff --git a/Engine/res/Fonts/OpenSans/OpenSans-SemiBoldItalic.ttf b/Engine/res/Fonts/OpenSans/OpenSans-SemiBoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aebcf1421226d045b8043d26433d780fa365b7de GIT binary patch literal 92180 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 OmxABnc!Ht?`Tqc{BF`NF literal 0 HcmV?d00001 diff --git a/Engine/res/Shaders/TintedTexture/TintedTexture_VS.glsl b/Engine/res/Shaders/TintedTexture/TintedTexture_VS.glsl index 642b4ef..ff835df 100644 --- a/Engine/res/Shaders/TintedTexture/TintedTexture_VS.glsl +++ b/Engine/res/Shaders/TintedTexture/TintedTexture_VS.glsl @@ -10,7 +10,7 @@ layout(std140, binding = 0) uniform ub_ViewProjection }; out vec4 vso_Tint; -out vec2 vso_TexCoord; +out vec2 vso_TexCoord; void main() { diff --git a/Engine/src/Engine/Base/Base.h b/Engine/src/Engine/Base/Base.h index 7e9f5bb..c099ca9 100644 --- a/Engine/src/Engine/Base/Base.h +++ b/Engine/src/Engine/Base/Base.h @@ -56,8 +56,7 @@ namespace Light { #define LT_MAC(x) x #else - #error "Unsupported platform: Unknown" - + // #error "Unsupported platform: Unknown" #endif //========== PLATFORM ==========// diff --git a/Engine/src/Engine/Core/Application.cpp b/Engine/src/Engine/Core/Application.cpp index 227be8f..1e83195 100644 --- a/Engine/src/Engine/Core/Application.cpp +++ b/Engine/src/Engine/Core/Application.cpp @@ -26,6 +26,7 @@ namespace Light { m_Window(nullptr) { m_Logger = Logger::Create(); + LogDebugData(); m_Instrumentor = Instrumentor::Create(); m_Instrumentor->BeginSession("Logs/ProfileResults_Startup.json"); @@ -48,7 +49,6 @@ namespace Light { LT_ENGINE_ASSERT(!m_LayerStack->IsEmpty(), "Application::GameLoop(pre): LayerStack is empty"); // log debug data - LogDebugData(); m_Logger->LogDebugData(); m_Window->GetGfxContext()->LogDebugData(); m_Window->GetGfxContext()->GetUserInterface()->LogDebugData(); diff --git a/Engine/src/Engine/Graphics/RendererPrograms/QuadRendererProgram.cpp b/Engine/src/Engine/Graphics/RendererPrograms/QuadRendererProgram.cpp index 1fb918d..6cc8b81 100644 --- a/Engine/src/Engine/Graphics/RendererPrograms/QuadRendererProgram.cpp +++ b/Engine/src/Engine/Graphics/RendererPrograms/QuadRendererProgram.cpp @@ -21,7 +21,7 @@ namespace Light { m_MaxVertices(maxVertices) { // #todo: don't use relative path - ResourceManager::LoadShader("LT_ENGINE_RESOURCES_QUAD_SHADER", "../Engine/res/Shaders/Quad/Quad_VS", "../Engine//res/Shaders/Quad/Quad_PS"); + ResourceManager::LoadShader("LT_ENGINE_RESOURCES_QUAD_SHADER", "../../Engine/res/Shaders/Quad/Quad_VS", "../../Engine//res/Shaders/Quad/Quad_PS"); m_Shader = ResourceManager::GetShader("LT_ENGINE_RESOURCES_QUAD_SHADER"); m_VertexBuffer = Ref(VertexBuffer::Create(nullptr, sizeof(QuadVertexData), maxVertices, sharedContext)); diff --git a/Engine/src/Engine/Graphics/RendererPrograms/TextureRendererProgram.cpp b/Engine/src/Engine/Graphics/RendererPrograms/TextureRendererProgram.cpp index 024e932..a195ab4 100644 --- a/Engine/src/Engine/Graphics/RendererPrograms/TextureRendererProgram.cpp +++ b/Engine/src/Engine/Graphics/RendererPrograms/TextureRendererProgram.cpp @@ -21,7 +21,7 @@ namespace Light { m_MaxVertices(maxVertices) { // #todo: don't use relative path - ResourceManager::LoadShader("LT_ENGINE_RESOURCES_TEXTURE_SHADER", "../Engine/res/Shaders/Texture/Texture_VS", "../Engine/res/Shaders/Texture/Texture_PS"); + ResourceManager::LoadShader("LT_ENGINE_RESOURCES_TEXTURE_SHADER", "../../Engine/res/Shaders/Texture/Texture_VS", "../../Engine/res/Shaders/Texture/Texture_PS"); m_Shader = ResourceManager::GetShader("LT_ENGINE_RESOURCES_TEXTURE_SHADER"); m_VertexBuffer = Ref(VertexBuffer::Create(nullptr, sizeof(TextureVertexData), maxVertices, sharedContext)); diff --git a/Engine/src/Engine/Graphics/RendererPrograms/TintedTextureRendererProgram.cpp b/Engine/src/Engine/Graphics/RendererPrograms/TintedTextureRendererProgram.cpp index af944f1..80a17cf 100644 --- a/Engine/src/Engine/Graphics/RendererPrograms/TintedTextureRendererProgram.cpp +++ b/Engine/src/Engine/Graphics/RendererPrograms/TintedTextureRendererProgram.cpp @@ -21,7 +21,7 @@ namespace Light { m_MaxVertices(maxVertices) { // #todo: don't use relative path - ResourceManager::LoadShader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER", "../Engine/res/Shaders/TintedTexture/TintedTexture_VS", "../Engine/res/Shaders/TintedTexture/TintedTexture_PS"); + ResourceManager::LoadShader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER", "../../Engine/res/Shaders/TintedTexture/TintedTexture_VS", "../../Engine/res/Shaders/TintedTexture/TintedTexture_PS"); m_Shader = ResourceManager::GetShader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER"); m_VertexBuffer = Ref(VertexBuffer::Create(nullptr, sizeof(TintedTextureVertexData), maxVertices, sharedContext)); @@ -33,13 +33,14 @@ namespace Light { bool TintedTextureRendererProgram::Advance() { - if (m_MapCurrent + 4 >= m_MapEnd) + m_MapCurrent += 4; + + if (m_MapCurrent >= m_MapEnd) { LT_ENGINE_WARN("TintedTextureRendererProgram::Advance: 'VertexBuffer' map went beyond 'MaxVertices': {}", m_MaxVertices); return false; } - m_MapCurrent += 4; m_QuadCount++; return true; } diff --git a/Engine/src/Engine/Input/Input.h b/Engine/src/Engine/Input/Input.h index ff2b0b8..f8fd48c 100644 --- a/Engine/src/Engine/Input/Input.h +++ b/Engine/src/Engine/Input/Input.h @@ -4,6 +4,8 @@ #include +#include + namespace Light { class Event; diff --git a/Engine/src/Engine/Scene/Components/TransformComponent.h b/Engine/src/Engine/Scene/Components/TransformComponent.h index dd74066..b9aeb94 100644 --- a/Engine/src/Engine/Scene/Components/TransformComponent.h +++ b/Engine/src/Engine/Scene/Components/TransformComponent.h @@ -4,6 +4,7 @@ #include #include +#include namespace Light { @@ -25,18 +26,9 @@ namespace Light { { } - const glm::mat4& GetTransform() const - { - return glm::translate(glm::mat4(1.0f), translation) * + inline glm::mat4 GetTransform() const { return glm::translate(translation) * glm::rotate(rotation.z, glm::vec3(0.0f, 0.0f, 1.0f)) * glm::scale(scale); } - glm::rotate(glm::mat4(1.0f), rotation.x, glm::vec3(1.0f, 0.0f, 0.0f)) * - glm::rotate(glm::mat4(1.0f), rotation.y, glm::vec3(0.0f, 1.0f, 0.0f)) * - glm::rotate(glm::mat4(1.0f), rotation.z, glm::vec3(0.0f, 0.0f, 1.0f)) * - - glm::scale(glm::mat4(1.0f), scale); - } - - operator const glm::mat4& () const { return GetTransform(); } + operator const glm::mat4() const { return GetTransform(); } }; } \ No newline at end of file diff --git a/Engine/src/Engine/Scene/Entity.h b/Engine/src/Engine/Scene/Entity.h index e9779b6..1302d61 100644 --- a/Engine/src/Engine/Scene/Entity.h +++ b/Engine/src/Engine/Scene/Entity.h @@ -4,9 +4,9 @@ #include "Scene.h" -#include +#include -namespace Light { +namespace Light { class Entity { @@ -33,7 +33,7 @@ namespace Light { template inline bool HasComponent() { - return m_Scene->m_Registry.has(m_Handle); + return m_Scene->m_Registry.any_of(m_Handle); } template diff --git a/Engine/src/Engine/Scene/Scene.h b/Engine/src/Engine/Scene/Scene.h index 20fd9bc..7999d3d 100644 --- a/Engine/src/Engine/Scene/Scene.h +++ b/Engine/src/Engine/Scene/Scene.h @@ -4,7 +4,7 @@ #include "Components/TransformComponent.h" -#include +#include #include diff --git a/Engine/src/Engine/UserInterface/UserInterface.cpp b/Engine/src/Engine/UserInterface/UserInterface.cpp index 706688f..e640494 100644 --- a/Engine/src/Engine/UserInterface/UserInterface.cpp +++ b/Engine/src/Engine/UserInterface/UserInterface.cpp @@ -105,8 +105,8 @@ namespace Light { io.KeyMap[ImGuiKey_Y] = Key::Y; io.KeyMap[ImGuiKey_Z] = Key::Z; - io.Fonts->AddFontFromFileTTF("res/Fonts/OpenSans/OpenSans-Bold.ttf", 18.0f); - io.FontDefault = io.Fonts->AddFontFromFileTTF("res/Fonts/OpenSans/OpenSans-Regular.ttf", 18.0f); + io.Fonts->AddFontFromFileTTF("../../Engine/res/Fonts/OpenSans/OpenSans-Bold.ttf", 18.0f); + io.FontDefault = io.Fonts->AddFontFromFileTTF("../../Engine/res/Fonts/OpenSans/OpenSans-Regular.ttf", 18.0f); SetDarkThemeColors(); } diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxUserInterface.cpp b/Engine/src/Platform/GraphicsAPI/DirectX/dxUserInterface.cpp index 00b6cbd..c5450e7 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxUserInterface.cpp +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxUserInterface.cpp @@ -9,8 +9,8 @@ #include #include -#include -#include +#include +#include namespace Light { diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp index faee8ac..303030a 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp @@ -7,8 +7,8 @@ #include #include -#include -#include +#include +#include namespace Light { diff --git a/Mirror/CMakeLists.txt b/Mirror/CMakeLists.txt new file mode 100644 index 0000000..e9feab4 --- /dev/null +++ b/Mirror/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.21.2) + +if (CMAKE_COMPILER_IS_GNUCC) + add_compile_options(-w) +endif() +if(MSVC) + add_compile_options(/MP) + add_compile_options(/W0) +endif() + +add_compile_definitions(LIGHT_PLATFORM_WINDOWS) + +include_directories( +${ENGINE_DIR}src/Engine/ +${ENGINE_DIR}src/Platform/GraphicsAPI/ +${ENGINE_DIR}src/Platform/OS/ +${DEPENDENCIES_DIR}entt/src/ +${DEPENDENCIES_DIR}GLAD/include/ +${DEPENDENCIES_DIR}GLFW/include/ +${DEPENDENCIES_DIR}glm/ +${DEPENDENCIES_DIR}imgui/ +${DEPENDENCIES_DIR}spdlog/include +${DEPENDENCIES_DIR}stb_image/ +) + + +file(GLOB_RECURSE MIRROR_FILES true ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/src/* ${CMAKE_CURRENT_SOURCE_DIR}/res/*) +source_group(TREE ${MIRROR_DIR} FILES ${MIRROR_FILES}) +add_executable(Mirror ${MIRROR_FILES}) \ No newline at end of file diff --git a/Mirror/res/Textures/awesomeface.png b/Mirror/res/Textures/awesomeface.png index 58daba04f1f35d41821194d972b510cbbb86278d..364350cd84bbf3e1e1c413bbc54486b89cd2cf17 100644 GIT binary patch literal 81332 zcmXtg1z1$;_w@l3Bm_Z4K}rGX7L-O&N$GH?K?Ua0T@o``sC0v*(v5V3MGXvyg!CvO z-5oREd-(mo`#kqi8O}NHd1LLh*Is+x>1e5(r(&jpAn3fB>U}*3Is^WC20BL${y?(| zyaa!cxa+ChgGz8L3-Cv%yN~Wd(B}y1<0ogqzbRc*5$+H~`yKwDBu;?#8Uzuu)$ZRl z@Ud8)IGbWPSkt;8$twE2yKh1@!6Ud*Rh{>J5U~IE5xAOt(x}pk-BFVEEygB62x>J-+H;7~&(%8F@Z6kH zTk^Yi?}b^Tk1j4nnzOUB(@2<)PYstU%X3B8tV}`HZ?`D!XbXk*I@q*cs%X(~(K7_GBdn~l;;Gu@ zo9RF@?xCBFoM-<86lCJn#gs0e8}M8muPa_FcpQ1#*@90e1LG-wJVbw}2*y&90dBIc zL9!Iz`Q;@=@q^^oNx}!%y%5WXT9`w|0H!t-*WfUpbG;U8ma=o1G`>;~pqD6Dq$a;_boovR#LgUi->Gp^vZIa`d#Kf!i@k(+0 zhFK<6c0x(OGJJ$o;7&X{26gOvq_i?xm2FgPB3^%T z^@I=n-W%`~j){S>lh@Q&2%quD&ri?(TOgC7qNR=h`y+&y&CxnU0x3P$1@|;FoRc@T z>iHnKIp*Bb+334f^gyxr7_;@gt#GFX%BrKOpmh{@fmUsE#CqZD zW|QsSbVa0Ax zQ{}Vqw9aSa6X6o3Q|H}5Q^LE8 zJY64^gSUC0by-Q}jJq$%jl7k>#;_*5qy|5PYT$;T;kL8z zv`pA=Is|DdflW^n+35CBGg+$V`LELEba_7`G%3^!5aY@Diw=VYah3MNT66O2$%Hcy z-Tm%!9ruASflgLPY>J<#1%_O?ilCmWf$Qf!wY$cikm#t5QYq1=-`e<3bwofj{j0_ zKP;Sj78-vG4uDAosezbfudJUZBjnNqR_Z`lo~20BR_fQhb!1L-=Q zuwasa@*A2c!pRXfoK@C?5yIaGNEicPxr>ZWj)U4yq#psbri10iD0Y@Td#RZy`bDPR zd9>0tIwhqD%v>UesHhIJlmoB#q;GE3153@|&tPpKcqkWdZ(J$-fn=TVUL4>9bCIaY z%9mG9I=~p@*;_n}fYy=V1^0^uoR0>-qUXAkz&pEScEt&pzQ)L|*1jwO$29~XLyP-U zoPj-(NT+zr(H_qF3jv1G5zQUqu{fZ{=C>?{*x9xNcPE0~jzM;mdlz=6$(tVTt_Z~N zXvbp{4t`QV1Wi_+JS|!sbCQ|~ujJ7GB=o=(tb!H86mkn6^)S!x?F=I|%*;~2LaYe&nQY+Qey+?A=X4|&Ju_UGyQaLAzOu`Yl#YgV2+ z0ARu3E5HO>HqOLRTjN`UHfIx%U0_8#8C|L)@k*W1d|WF6+agmHHbzs*+|SY%JDo&MZ3ozE=99 z=$Xp#g^Glk{%iwj^z{b}!dx0pN2?A!J3I5;7B!>I)YXp!uS>5SMyJRHbav%0DWbL2 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%0DE#JE*JKDcvcAPI|Fccci2CJTN; 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 literal 76691 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≈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 diff --git a/Mirror/src/EditorLayer.cpp b/Mirror/src/EditorLayer.cpp index 9d2e1f5..e90256f 100644 --- a/Mirror/src/EditorLayer.cpp +++ b/Mirror/src/EditorLayer.cpp @@ -18,9 +18,6 @@ namespace Light { // for native script components m_Scene->OnCreate(); - - // #temp - srand(time(NULL)); } void EditorLayer::OnUpdate(float deltaTime) @@ -53,16 +50,16 @@ namespace Light { Input::ReceiveGameEvents(ImGui::IsWindowFocused()); ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - if(m_AvailableContentRegionPrev != regionAvail) + if (m_AvailableContentRegionPrev != regionAvail) { m_Framebuffer->Resize({ regionAvail.x, regionAvail.y }); auto& camera = m_CameraEntity.GetComponent().camera; - camera.SetViewportSize(regionAvail.x, regionAvail.y);; + camera.SetViewportSize(regionAvail.x, regionAvail.y); m_AvailableContentRegionPrev = regionAvail; } - if(GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX) + if (GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX) ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail); else ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); @@ -76,22 +73,20 @@ namespace Light { void EditorLayer::SummonAwesomeness() { - ResourceManager::LoadTexture("awesomeface", "res/Textures/awesomeface.png"); + ResourceManager::LoadTexture("awesomeface", "../../Mirror/res/Textures/awesomeface.png"); auto texture = ResourceManager::GetTexture("awesomeface"); for(unsigned int i = 0; i < 250; i++) { const glm::vec3 translation = Math::RandVec3(-500, 500); const glm::vec3 scale = glm::vec3(Math::Rand(125, 200)); - const glm::vec3 rotation = glm::radians(glm::vec3(0.0f, 0.0f, Math::Rand(0, 360))); + const glm::vec3 rotation = glm::vec3(0.0f, 0.0f, glm::radians(Math::Rand(0, 359))); const glm::vec4 tint = glm::vec4(Math::RandVec3(0, 1, 2), 1.0f); auto& entity = m_Scene->CreateEntity("quad" + std::to_string(i), { translation, scale, rotation }); entity.AddComponent(texture, tint); } - - ResourceManager::ReleaseTexture("awesomeface"); } } \ No newline at end of file diff --git a/Mirror/src/EditorLayer.h b/Mirror/src/EditorLayer.h index d246cd9..bffd873 100644 --- a/Mirror/src/EditorLayer.h +++ b/Mirror/src/EditorLayer.h @@ -16,6 +16,8 @@ namespace Light { glm::vec2 m_Direction; float m_Speed = 1000.0f; + std::vector m_Entities; + Ref m_Scene; Ref m_SceneHierarchyPanel; diff --git a/Mirror/src/Panels/SceneHierarchyPanel.cpp b/Mirror/src/Panels/SceneHierarchyPanel.cpp index 044c8bb..ad99999 100644 --- a/Mirror/src/Panels/SceneHierarchyPanel.cpp +++ b/Mirror/src/Panels/SceneHierarchyPanel.cpp @@ -4,7 +4,7 @@ #include "Scene/Components.h" -#include +#include #include