Initial commit - restart from existing code
418
CMakeLists.txt
Normal file
@@ -0,0 +1,418 @@
|
||||
# Nous voulons un cmake "récent" pour utiliser les dernières fonctionnalités.
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
set (CMAKE_CXX_STANDARD 23)
|
||||
# Nom du projet.
|
||||
set(PROJECT CosmicEngine)
|
||||
project(${PROJECT})
|
||||
|
||||
# Génération de la liste des fichiers sources.
|
||||
file(GLOB_RECURSE
|
||||
SRCS_ENGINE
|
||||
src/Engine/*
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE
|
||||
SRCS
|
||||
src/main.cpp)
|
||||
|
||||
file(GLOB_RECURSE
|
||||
SRCS_TESTS
|
||||
test/*
|
||||
)
|
||||
|
||||
# ---------- Inclusion des packages sous windows -----------
|
||||
if(WIN32)
|
||||
endif()
|
||||
# ---------- Inclusion des packages sous mac -----------
|
||||
if(APPLE)
|
||||
endif()
|
||||
# ---------- Inclusion des packages sous linux -----------
|
||||
|
||||
if(UNIX)
|
||||
# --------- Inclusion d'OpenGL ----------
|
||||
# OpenGL Lib pour charger OpenGL, fournit avec les drivers, donc se trouve toute seul.
|
||||
# find_package(OpenGL REQUIRED)
|
||||
# if(OPENGL_FOUND)
|
||||
# message("lib OpenGL Trouvé")
|
||||
# else()
|
||||
# message("lib OpenGL Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# --------- Inclusion de Vulkan ----------
|
||||
# Vulkan Lib pour charger Vulkan, fournit avec les drivers, donc se trouve toute seul.
|
||||
# find_package(Vulkan REQUIRED)
|
||||
# if(VULKAN_FOUND)
|
||||
# message("lib OpenGL Trouvé")
|
||||
# else()
|
||||
# message("lib OpenGL Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ---------- Inclusion de GLM -----------
|
||||
# GLM Lib pour mathématique, en mode header only.
|
||||
set(GLMlib_DIR ./lib/CMake/Linux)
|
||||
find_package(GLMlib REQUIRED)
|
||||
if(GLMlib_FOUND)
|
||||
message("lib GLM Trouvé")
|
||||
else()
|
||||
message("lib GLM Introuvable")
|
||||
endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ------- Inclusion de JSONfMC++ --------
|
||||
# JSONfMC++ Lib pour gestion fichier JSON, en mode header only.
|
||||
set(JSONlib_DIR ./lib/CMake/Linux)
|
||||
find_package(JSONlib REQUIRED)
|
||||
|
||||
if(JSONlib_FOUND)
|
||||
message("lib JSONFMC++ Trouvé")
|
||||
else()
|
||||
message("lib JSONFMC++ Introuvable")
|
||||
endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ------- Inclusion de EnTT --------
|
||||
# EnTT Lib pour gestion fichier JSON, en mode header only.
|
||||
set(EnTTlib_DIR ./lib/CMake/Linux)
|
||||
find_package(EnTTlib REQUIRED)
|
||||
|
||||
if(EnTTlib_FOUND)
|
||||
message("lib EnTTlib Trouvé")
|
||||
else()
|
||||
message("lib EnTTlib Introuvable")
|
||||
endif()
|
||||
|
||||
|
||||
# --------- Inclusion de Boost ----------
|
||||
# Boost Lib pour diverse simplification
|
||||
# set(Boost_USE_STATIC_LIBS OFF)
|
||||
# set(Boost_USE_MULTITHREADED ON)
|
||||
# set(Boost_USE_STATIC_RUNTIME OFF)
|
||||
|
||||
# find_package(Boost REQUIRED COMPONENTS log_setup log filesystem chrono thread date_time regex) # header only libraries must not be added here
|
||||
|
||||
# message(STATUS "Boost version: ${Boost_VERSION}")
|
||||
|
||||
# if(NOT TARGET Boost::filesystem)
|
||||
# add_library(Boost::filesystem IMPORTED INTERFACE)
|
||||
# set_property(TARGET Boost::filesystem PROPERTY
|
||||
# INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
|
||||
# set_property(TARGET Boost::filesystem PROPERTY
|
||||
# INTERFACE_LINK_LIBRARIES ${Boost_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
# if(NOT TARGET Boost::thread)
|
||||
# add_library(Boost::thread IMPORTED INTERFACE)
|
||||
# set_property(TARGET Boost::thread PROPERTY
|
||||
# INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
|
||||
# set_property(TARGET Boost::thread PROPERTY
|
||||
# INTERFACE_LINK_LIBRARIES ${Boost_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
# if(NOT TARGET Boost::chrono)
|
||||
# add_library(Boost::chrono IMPORTED INTERFACE)
|
||||
# set_property(TARGET Boost::chrono PROPERTY
|
||||
# INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
|
||||
# set_property(TARGET Boost::chrono PROPERTY
|
||||
# INTERFACE_LINK_LIBRARIES ${Boost_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
# if(NOT TARGET Boost::date_time)
|
||||
# add_library(Boost::date_time IMPORTED INTERFACE)
|
||||
# set_property(TARGET Boost::date_time PROPERTY
|
||||
# INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
|
||||
# set_property(TARGET Boost::date_time PROPERTY
|
||||
# INTERFACE_LINK_LIBRARIES ${Boost_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
# if(NOT TARGET Boost::regex)
|
||||
# add_library(Boost::regex IMPORTED INTERFACE)
|
||||
# set_property(TARGET Boost::regex PROPERTY
|
||||
# INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
|
||||
# set_property(TARGET Boost::regex PROPERTY
|
||||
# INTERFACE_LINK_LIBRARIES ${Boost_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
# if(NOT TARGET Boost::log)
|
||||
# add_library(Boost::log IMPORTED INTERFACE)
|
||||
# set_property(TARGET Boost::log PROPERTY
|
||||
# INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
|
||||
# set_property(TARGET Boost::log PROPERTY
|
||||
# INTERFACE_LINK_LIBRARIES ${Boost_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
# if(NOT TARGET Boost::log_setup)
|
||||
# add_library(Boost::log_setup IMPORTED INTERFACE)
|
||||
# set_property(TARGET Boost::log_setup PROPERTY
|
||||
# INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR})
|
||||
# set_property(TARGET Boost::log_setup PROPERTY
|
||||
# INTERFACE_LINK_LIBRARIES ${Boost_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
# if(Boost_FOUND)
|
||||
# message("lib Boost Trouvé")
|
||||
# else()
|
||||
# message("lib Boost Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# -------- Inclusion de la SDL2 ----------
|
||||
# SDL2 Lib pour fenetre et contrôle
|
||||
|
||||
# Les autre plateforme (Linux...) ont un installateur de paquet, la lib se trouve toute seul.
|
||||
# find_package(SDL2 REQUIRED)
|
||||
# if(SDL2_FOUND)
|
||||
# message("lib SDL2 Trouvé")
|
||||
# else()
|
||||
# message("lib SDL2 Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ------- Inclusion de SDL2_IMAGE --------
|
||||
# SDL2_IMAGE Lib pour charger une image
|
||||
# Les autre plateforme (Linux...) ont un installateur de paquet, la lib se trouve toute seul.
|
||||
# find_package(SDL2_image QUIET)
|
||||
# #find_library(SDL2_image libSDL2_image)
|
||||
|
||||
# if(SDL2_image_FOUND)
|
||||
# message("lib SDL2_IMAGE Trouvé")
|
||||
# else()
|
||||
# message("lib SDL2_IMAGE Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ------- Inclusion de SDL2_TTF --------
|
||||
# SDL2_IMAGE Lib pour charger une police d'écriture.
|
||||
# set(SDL2_ttf_DIR ./lib/CMake/Linux)
|
||||
# # Les autre plateforme (Linux...) ont un installateur de paquet, la lib se trouve toute seul.
|
||||
# find_package(SDL2_ttf QUIET)
|
||||
# #find_library(SDL2_ttf libSDL2_ttf)
|
||||
# if(SDL2_ttf_FOUND)
|
||||
# message("lib SDL2_TTF Trouvé")
|
||||
# else()
|
||||
# message("lib SDL2_TTF Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# --------- Inclusion de GLEW -----------
|
||||
# GLEW Lib pour charger utiliser OpenGL + extension
|
||||
# Les autre plateforme (Linux...) ont un installateur de paquet, la lib se trouve toute seul.
|
||||
# find_package(GLEW REQUIRED)
|
||||
# if(GLEW_FOUND)
|
||||
# message("lib GLEW Trouvé")
|
||||
# else()
|
||||
# message("lib GLEW Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ---------- Inclusion de ASSIMP -----------
|
||||
# Assimp Lib import modèles 3D.
|
||||
# find_package(assimp REQUIRED)
|
||||
# if(assimp_FOUND)
|
||||
# message("lib ASSIMP Trouvé")
|
||||
# else()
|
||||
# message("lib ASSIMP Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ---------- Inclusion de ODE -----------
|
||||
# ODE Lib Moteur physique.
|
||||
# set(ODE_DIR ./lib/CMake/Linux)
|
||||
# # Les autre plateforme (Linux...) ont un installateur de paquet, la lib se trouve toute seul.
|
||||
# find_package(ODE REQUIRED)
|
||||
# if(ODE_FOUND)
|
||||
# message("lib ODE Trouvé")
|
||||
# else()
|
||||
# message("lib ODE Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# --------- Inclusion de SNDFILE ----------
|
||||
# SNDFILE Lib pour inclure le son.
|
||||
# Les autre plateforme (Linux...) ont un installateur de paquet, la lib se trouve toute seul.
|
||||
#set(SNDFILE_DIR ./lib/CMake/Linux)
|
||||
# find_package(sndfile QUIET)#TODO corrige
|
||||
# #find_library(sndfile libsndfile)
|
||||
# if(sndfile_FOUND)
|
||||
# message("lib SNDFILE Trouvé")
|
||||
# else()
|
||||
# message("lib SNDFILE Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ---------- Inclusion de OpenAL-----------
|
||||
# OpenAL Lib gérer le son.
|
||||
# Les autre plateforme (Linux...) ont un installateur de paquet, la lib se trouve toute seul.
|
||||
# set(OPENAL_DIR ./lib/CMake/Linux)
|
||||
# find_package(OPENAL REQUIRED)
|
||||
|
||||
# if(OPENAL_FOUND)
|
||||
# message("lib OpenAL Trouvé")
|
||||
# else()
|
||||
# message("lib OpenAL Introuvable")
|
||||
# endif()
|
||||
# ---------------------------------------
|
||||
|
||||
# ---------- Inclusion de Catch2-----------
|
||||
# Gestion des tests unitaires
|
||||
|
||||
find_package(Catch2 3 REQUIRED)
|
||||
# These tests can use the Catch2-provided main
|
||||
if(Catch2_found)
|
||||
message("lib Catch2 Trouvé")
|
||||
else()
|
||||
message("lib Catch2 Introuvable")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
# Chemin executable
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/${CMAKE_BUILD_TYPE}")
|
||||
|
||||
# On indique que l'on veut un exécutable nommé PROJECT compilé à partir des fichiers décrits par les variables SRCS et HEADERS.
|
||||
|
||||
add_library(Engine SHARED ${SRCS_ENGINE} ${SRCS_EXTERNAL_GLAD})
|
||||
add_executable(${PROJECT} ${SRCS})
|
||||
add_dependencies(${PROJECT} Engine)
|
||||
|
||||
add_executable(CosmicTest ${SRCS_TESTS})
|
||||
target_link_libraries(CosmicTest PRIVATE Catch2::Catch2WithMain Engine)
|
||||
|
||||
# Fichier include
|
||||
# OpenGL
|
||||
#include_directories(${OPENGL_INCLUDE_DIR})
|
||||
# SDL2
|
||||
#include_directories(${SDL2_INCLUDE_DIRS})
|
||||
# GLEW
|
||||
#include_directories(${GLEW_INCLUDE_DIRS})
|
||||
# SDL2_image
|
||||
#include_directories(${SDL2_IMAGE_INCLUDE_DIRS})
|
||||
# SDL2_ttf
|
||||
#include_directories(${SDL2_TTF_INCLUDE_DIRS})
|
||||
# GLM
|
||||
include_directories(${GLM_INCLUDE_DIRS})
|
||||
# JSONFMCPP
|
||||
include_directories(${JSONFMCPP_INCLUDE_DIRS})
|
||||
#ENTT
|
||||
include_directories(${ENTT_INCLUDE_DIRS})
|
||||
|
||||
# ASSIMP
|
||||
#include_directories(${ASSIMP_INCLUDE_DIRS})
|
||||
# ODE
|
||||
#include_directories(${ODE_INCLUDE_DIRS})
|
||||
# SNDFILE
|
||||
#include_directories(${SNDFILE_INCLUDE_DIRS})
|
||||
# OPENAL
|
||||
#include_directories(${OPENAL_INCLUDE_DIRS})
|
||||
|
||||
# Fichier lib
|
||||
# OpenGL
|
||||
#target_link_libraries(Engine OpenMP::OpenMP_CXX)
|
||||
|
||||
# OpenMP
|
||||
#target_link_libraries(Engine ${OPENGL_LIBRARIES})
|
||||
|
||||
# SDL2
|
||||
#target_link_libraries(Engine ${SDL2_LIBRARIES})
|
||||
|
||||
# GLEW
|
||||
#target_link_libraries(Engine ${GLEW_LIBRARIES})
|
||||
|
||||
# SDL2_image
|
||||
#target_link_libraries(Engine SDL2_image)
|
||||
|
||||
# SDL2_ttf
|
||||
#target_link_libraries(Engine SDL2_ttf)
|
||||
|
||||
# Boost
|
||||
|
||||
|
||||
# ASSIMP
|
||||
#target_link_libraries(Engine ${ASSIMP_LIBRARIES})
|
||||
|
||||
|
||||
# ODE
|
||||
#target_link_libraries(Engine ${ODE_LIBRARIES})
|
||||
|
||||
# SNDFILE
|
||||
#target_link_libraries(Engine sndfile)
|
||||
|
||||
# OPENAL
|
||||
#target_link_libraries(Engine ${OPENAL_LIBRARIES})
|
||||
|
||||
|
||||
#target_link_libraries(Engine ${CMAKE_DL_LIBS})
|
||||
|
||||
#target_link_libraries(${PROJECT} ${CMAKE_DL_LIBS})
|
||||
|
||||
|
||||
# Boost
|
||||
# target_link_libraries(Engine Boost::boost)
|
||||
# target_link_libraries(Engine Boost::filesystem)
|
||||
# target_link_libraries(Engine Boost::chrono)
|
||||
# target_link_libraries(Engine Boost::thread)
|
||||
# target_link_libraries(Engine Boost::date_time)
|
||||
# target_link_libraries(Engine Boost::regex)
|
||||
# target_link_libraries(Engine Boost::log)
|
||||
# target_link_libraries(Engine Boost::log_setup)
|
||||
|
||||
target_link_libraries(${PROJECT} Engine)
|
||||
|
||||
if(UNIX)
|
||||
add_custom_command(
|
||||
TARGET Engine POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libEngine.so
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
endif()
|
||||
|
||||
# Paramètre de compilation
|
||||
if (UNIX)
|
||||
set(CMAKE_CXX_FLAGS "-Wall -ldl -fPIC")
|
||||
endif ()
|
||||
|
||||
# Valgrind ne marche que pour Linux...
|
||||
if (UNIX)
|
||||
add_custom_target("valgrind"
|
||||
COMMAND ${CMAKE_CTEST_COMMAND}
|
||||
--force-new-ctest-process --test-action memcheck
|
||||
COMMAND cat "${CMAKE_BINARY_DIR}/Testing/Temporary/MemoryChecker.*.log")
|
||||
endif()
|
||||
|
||||
# Doxygen
|
||||
# check if Doxygen is installed
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
# set input and output files
|
||||
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in)
|
||||
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/doc/Doxyfile)
|
||||
|
||||
# request to configure the file
|
||||
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
|
||||
message("Doxygen build started")
|
||||
|
||||
# note the option ALL which allows to build the docs together with the application
|
||||
add_custom_target("doxygen"
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
VERBATIM)
|
||||
else()
|
||||
message("Doxygen need to be installed to generate the doxygen documentation")
|
||||
endif()
|
||||
|
||||
foreach(source IN LISTS SRCS_ENGINE)
|
||||
get_filename_component(source_path "${source}" PATH)
|
||||
STRING(REGEX REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" source_path ${source_path})
|
||||
string(REPLACE "/" "\\" source_path_msvc "${source_path}")
|
||||
source_group("${source_path_msvc}" FILES "${source}")
|
||||
endforeach()
|
||||
|
||||
foreach(source IN LISTS SRCS)
|
||||
get_filename_component(source_path "${source}" PATH)
|
||||
STRING(REGEX REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" source_path ${source_path})
|
||||
string(REPLACE "/" "\\" source_path_msvc "${source_path}")
|
||||
source_group("${source_path_msvc}" FILES "${source}")
|
||||
endforeach()
|
||||
|
||||
message(STATUS "Tree reorganized")
|
||||
BIN
assets/475uja.jpg
Normal file
|
After Width: | Height: | Size: 237 KiB |
BIN
assets/F.O.O.L - Criminals.ogg
Normal file
199
assets/QTForms/EditorWindow.ui
Normal file
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditorWindow</class>
|
||||
<widget class="QMainWindow" name="m_editorWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>CosmicEngine Editor</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QToolBox" name="m_leftToolBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_scenePage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>377</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Scene</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="m_entitiesPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>377</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Entities</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QOpenGLWidget" name="m_openGLPreview">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>220</x>
|
||||
<y>0</y>
|
||||
<width>361</width>
|
||||
<height>351</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolBox" name="m_rightToolBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>590</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_modelsPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>377</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Models</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="m_shadersPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>377</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Shaders</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QTextBrowser" name="m_logTextBrowser">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>450</y>
|
||||
<width>781</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="cursorWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="m_buttonPlay">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>220</x>
|
||||
<y>380</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Play</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="m_buttonStop">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>360</x>
|
||||
<y>380</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="m_buttonReset">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>500</x>
|
||||
<y>380</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="m_menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="m_menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="m_menuEdit">
|
||||
<property name="title">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="m_menuTools">
|
||||
<property name="title">
|
||||
<string>Tools</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="m_menuHelp">
|
||||
<property name="title">
|
||||
<string>Help</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="m_menuFile"/>
|
||||
<addaction name="m_menuEdit"/>
|
||||
<addaction name="m_menuTools"/>
|
||||
<addaction name="m_menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="m_statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
199
assets/QTForms/EditorWindowWidg.ui
Normal file
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>m_editorWindow</class>
|
||||
<widget class="QMainWindow" name="m_editorWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>CosmicEngine Editor</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QToolBox" name="m_leftToolBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_scenePage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Scene</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="m_entitiesPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>377</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Entities</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QToolBox" name="m_rightToolBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>590</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_modelsPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Models</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="m_shadersPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>211</width>
|
||||
<height>377</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Shaders</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QTextBrowser" name="m_logTextBrowser">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>450</y>
|
||||
<width>781</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="cursorWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="m_buttonPlay">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>220</x>
|
||||
<y>380</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Play</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="m_buttonStop">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>360</x>
|
||||
<y>380</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="m_buttonReset">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>500</x>
|
||||
<y>380</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="m_openGLPreview" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>210</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>351</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="m_menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="m_menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="m_menuEdit">
|
||||
<property name="title">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="m_menuTools">
|
||||
<property name="title">
|
||||
<string>Tools</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="m_menuHelp">
|
||||
<property name="title">
|
||||
<string>Help</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="m_menuFile"/>
|
||||
<addaction name="m_menuEdit"/>
|
||||
<addaction name="m_menuTools"/>
|
||||
<addaction name="m_menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="m_statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
BIN
assets/ccccc.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
15
assets/configs/config.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"config": {
|
||||
"video": {
|
||||
"windowedHeight": 360,
|
||||
"windowedWidth": 640,
|
||||
"fullscreenHeight": 1080,
|
||||
"fullscreenWidth": 1920,
|
||||
"fullscreenSizeAuto": false,
|
||||
"fullscreen": true,
|
||||
"msaa": 16,
|
||||
"vSync": 1,
|
||||
"framerate": 60
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
assets/exotique-1_0.jpg
Normal file
|
After Width: | Height: | Size: 135 KiB |
BIN
assets/fonts/arial.ttf
Normal file
BIN
assets/icons/spaceEngine.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
12
assets/models/cone.mtl
Normal file
@@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material.003
|
||||
Ns 323.999994
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.000000 0.587194
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
170
assets/models/cone.obj
Normal file
@@ -0,0 +1,170 @@
|
||||
# Blender v2.90.1 OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib cone.mtl
|
||||
o Cone
|
||||
v 0.000000 -1.000000 -1.000000
|
||||
v 0.195090 -1.000000 -0.980785
|
||||
v 0.382683 -1.000000 -0.923880
|
||||
v 0.555570 -1.000000 -0.831470
|
||||
v 0.707107 -1.000000 -0.707107
|
||||
v 0.831470 -1.000000 -0.555570
|
||||
v 0.923880 -1.000000 -0.382683
|
||||
v 0.980785 -1.000000 -0.195090
|
||||
v 1.000000 -1.000000 -0.000000
|
||||
v 0.980785 -1.000000 0.195090
|
||||
v 0.923880 -1.000000 0.382683
|
||||
v 0.831470 -1.000000 0.555570
|
||||
v 0.707107 -1.000000 0.707107
|
||||
v 0.555570 -1.000000 0.831470
|
||||
v 0.382683 -1.000000 0.923880
|
||||
v 0.195090 -1.000000 0.980785
|
||||
v -0.000000 -1.000000 1.000000
|
||||
v -0.195091 -1.000000 0.980785
|
||||
v -0.382684 -1.000000 0.923879
|
||||
v -0.555571 -1.000000 0.831469
|
||||
v -0.707107 -1.000000 0.707106
|
||||
v -0.831470 -1.000000 0.555570
|
||||
v -0.923880 -1.000000 0.382683
|
||||
v -0.980785 -1.000000 0.195089
|
||||
v -1.000000 -1.000000 -0.000001
|
||||
v -0.980785 -1.000000 -0.195091
|
||||
v -0.923879 -1.000000 -0.382684
|
||||
v -0.831469 -1.000000 -0.555571
|
||||
v -0.707106 -1.000000 -0.707108
|
||||
v -0.555569 -1.000000 -0.831470
|
||||
v -0.382682 -1.000000 -0.923880
|
||||
v -0.195089 -1.000000 -0.980786
|
||||
v 0.000000 1.000000 0.000000
|
||||
vt 0.250000 0.490000
|
||||
vt 0.250000 0.250000
|
||||
vt 0.296822 0.485388
|
||||
vt 0.341844 0.471731
|
||||
vt 0.383337 0.449553
|
||||
vt 0.419706 0.419706
|
||||
vt 0.449553 0.383337
|
||||
vt 0.471731 0.341844
|
||||
vt 0.485388 0.296822
|
||||
vt 0.490000 0.250000
|
||||
vt 0.485388 0.203178
|
||||
vt 0.471731 0.158156
|
||||
vt 0.449553 0.116663
|
||||
vt 0.419706 0.080294
|
||||
vt 0.383337 0.050447
|
||||
vt 0.341844 0.028269
|
||||
vt 0.296822 0.014612
|
||||
vt 0.250000 0.010000
|
||||
vt 0.203178 0.014612
|
||||
vt 0.158156 0.028269
|
||||
vt 0.116663 0.050447
|
||||
vt 0.080294 0.080294
|
||||
vt 0.050447 0.116663
|
||||
vt 0.028269 0.158156
|
||||
vt 0.014611 0.203179
|
||||
vt 0.010000 0.250000
|
||||
vt 0.014612 0.296822
|
||||
vt 0.028269 0.341844
|
||||
vt 0.050447 0.383337
|
||||
vt 0.080295 0.419706
|
||||
vt 0.116663 0.449553
|
||||
vt 0.158156 0.471731
|
||||
vt 0.750000 0.490000
|
||||
vt 0.796822 0.485388
|
||||
vt 0.841844 0.471731
|
||||
vt 0.883337 0.449553
|
||||
vt 0.919706 0.419706
|
||||
vt 0.949553 0.383337
|
||||
vt 0.971731 0.341844
|
||||
vt 0.985388 0.296822
|
||||
vt 0.990000 0.250000
|
||||
vt 0.985388 0.203178
|
||||
vt 0.971731 0.158156
|
||||
vt 0.949553 0.116663
|
||||
vt 0.919706 0.080294
|
||||
vt 0.883337 0.050447
|
||||
vt 0.841844 0.028269
|
||||
vt 0.796822 0.014612
|
||||
vt 0.750000 0.010000
|
||||
vt 0.703178 0.014612
|
||||
vt 0.658156 0.028269
|
||||
vt 0.616663 0.050447
|
||||
vt 0.580294 0.080294
|
||||
vt 0.550447 0.116663
|
||||
vt 0.528269 0.158156
|
||||
vt 0.514611 0.203179
|
||||
vt 0.510000 0.250000
|
||||
vt 0.514612 0.296822
|
||||
vt 0.528269 0.341844
|
||||
vt 0.550447 0.383337
|
||||
vt 0.580295 0.419706
|
||||
vt 0.616663 0.449553
|
||||
vt 0.658156 0.471731
|
||||
vt 0.703179 0.485389
|
||||
vt 0.203179 0.485389
|
||||
vn 0.0878 0.4455 -0.8910
|
||||
vn 0.2599 0.4455 -0.8567
|
||||
vn 0.4220 0.4455 -0.7896
|
||||
vn 0.5680 0.4455 -0.6921
|
||||
vn 0.6921 0.4455 -0.5680
|
||||
vn 0.7896 0.4455 -0.4220
|
||||
vn 0.8567 0.4455 -0.2599
|
||||
vn 0.8910 0.4455 -0.0878
|
||||
vn 0.8910 0.4455 0.0878
|
||||
vn 0.8567 0.4455 0.2599
|
||||
vn 0.7896 0.4455 0.4220
|
||||
vn 0.6921 0.4455 0.5680
|
||||
vn 0.5680 0.4455 0.6921
|
||||
vn 0.4220 0.4455 0.7896
|
||||
vn 0.2599 0.4455 0.8567
|
||||
vn 0.0878 0.4455 0.8910
|
||||
vn -0.0878 0.4455 0.8910
|
||||
vn -0.2599 0.4455 0.8567
|
||||
vn -0.4220 0.4455 0.7896
|
||||
vn -0.5680 0.4455 0.6921
|
||||
vn -0.6921 0.4455 0.5680
|
||||
vn -0.7896 0.4455 0.4220
|
||||
vn -0.8567 0.4455 0.2599
|
||||
vn -0.8910 0.4455 0.0878
|
||||
vn -0.8910 0.4455 -0.0878
|
||||
vn -0.8567 0.4455 -0.2599
|
||||
vn -0.7896 0.4455 -0.4220
|
||||
vn -0.6921 0.4455 -0.5680
|
||||
vn -0.5680 0.4455 -0.6921
|
||||
vn -0.4220 0.4455 -0.7896
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
vn -0.2599 0.4455 -0.8567
|
||||
vn -0.0878 0.4455 -0.8910
|
||||
usemtl Material.003
|
||||
s off
|
||||
f 1/1/1 33/2/1 2/3/1
|
||||
f 2/3/2 33/2/2 3/4/2
|
||||
f 3/4/3 33/2/3 4/5/3
|
||||
f 4/5/4 33/2/4 5/6/4
|
||||
f 5/6/5 33/2/5 6/7/5
|
||||
f 6/7/6 33/2/6 7/8/6
|
||||
f 7/8/7 33/2/7 8/9/7
|
||||
f 8/9/8 33/2/8 9/10/8
|
||||
f 9/10/9 33/2/9 10/11/9
|
||||
f 10/11/10 33/2/10 11/12/10
|
||||
f 11/12/11 33/2/11 12/13/11
|
||||
f 12/13/12 33/2/12 13/14/12
|
||||
f 13/14/13 33/2/13 14/15/13
|
||||
f 14/15/14 33/2/14 15/16/14
|
||||
f 15/16/15 33/2/15 16/17/15
|
||||
f 16/17/16 33/2/16 17/18/16
|
||||
f 17/18/17 33/2/17 18/19/17
|
||||
f 18/19/18 33/2/18 19/20/18
|
||||
f 19/20/19 33/2/19 20/21/19
|
||||
f 20/21/20 33/2/20 21/22/20
|
||||
f 21/22/21 33/2/21 22/23/21
|
||||
f 22/23/22 33/2/22 23/24/22
|
||||
f 23/24/23 33/2/23 24/25/23
|
||||
f 24/25/24 33/2/24 25/26/24
|
||||
f 25/26/25 33/2/25 26/27/25
|
||||
f 26/27/26 33/2/26 27/28/26
|
||||
f 27/28/27 33/2/27 28/29/27
|
||||
f 28/29/28 33/2/28 29/30/28
|
||||
f 29/30/29 33/2/29 30/31/29
|
||||
f 30/31/30 33/2/30 31/32/30
|
||||
f 1/33/31 2/34/31 3/35/31 4/36/31 5/37/31 6/38/31 7/39/31 8/40/31 9/41/31 10/42/31 11/43/31 12/44/31 13/45/31 14/46/31 15/47/31 16/48/31 17/49/31 18/50/31 19/51/31 20/52/31 21/53/31 22/54/31 23/55/31 24/56/31 25/57/31 26/58/31 27/59/31 28/60/31 29/61/31 30/62/31 31/63/31 32/64/31
|
||||
f 31/32/32 33/2/32 32/65/32
|
||||
f 32/65/33 33/2/33 1/1/33
|
||||
12
assets/models/cube.mtl
Normal file
@@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 323.999994
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.017824 0.005779 0.800000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
40
assets/models/cube.obj
Normal file
@@ -0,0 +1,40 @@
|
||||
# Blender v2.90.1 OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib cube.mtl
|
||||
o Cube
|
||||
v 1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.875000 0.750000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.375000 0.000000
|
||||
vt 0.625000 0.000000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.375000 0.250000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.125000 0.750000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 5/2/1 7/3/1 3/4/1
|
||||
f 4/5/2 3/4/2 7/6/2 8/7/2
|
||||
f 8/8/3 7/9/3 5/10/3 6/11/3
|
||||
f 6/12/4 2/13/4 4/5/4 8/14/4
|
||||
f 2/13/5 1/1/5 3/4/5 4/5/5
|
||||
f 6/11/6 5/10/6 1/1/6 2/13/6
|
||||
12
assets/models/cylindre.mtl
Normal file
@@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material.002
|
||||
Ns 323.999994
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.000000 0.002363
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
268
assets/models/cylindre.obj
Normal file
@@ -0,0 +1,268 @@
|
||||
# Blender v2.90.1 OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib cylindre.mtl
|
||||
o Cylinder
|
||||
v 0.000000 -1.000000 -1.000000
|
||||
v 0.000000 1.000000 -1.000000
|
||||
v 0.195090 -1.000000 -0.980785
|
||||
v 0.195090 1.000000 -0.980785
|
||||
v 0.382683 -1.000000 -0.923880
|
||||
v 0.382683 1.000000 -0.923880
|
||||
v 0.555570 -1.000000 -0.831470
|
||||
v 0.555570 1.000000 -0.831470
|
||||
v 0.707107 -1.000000 -0.707107
|
||||
v 0.707107 1.000000 -0.707107
|
||||
v 0.831470 -1.000000 -0.555570
|
||||
v 0.831470 1.000000 -0.555570
|
||||
v 0.923880 -1.000000 -0.382683
|
||||
v 0.923880 1.000000 -0.382683
|
||||
v 0.980785 -1.000000 -0.195090
|
||||
v 0.980785 1.000000 -0.195090
|
||||
v 1.000000 -1.000000 -0.000000
|
||||
v 1.000000 1.000000 -0.000000
|
||||
v 0.980785 -1.000000 0.195090
|
||||
v 0.980785 1.000000 0.195090
|
||||
v 0.923880 -1.000000 0.382683
|
||||
v 0.923880 1.000000 0.382683
|
||||
v 0.831470 -1.000000 0.555570
|
||||
v 0.831470 1.000000 0.555570
|
||||
v 0.707107 -1.000000 0.707107
|
||||
v 0.707107 1.000000 0.707107
|
||||
v 0.555570 -1.000000 0.831470
|
||||
v 0.555570 1.000000 0.831470
|
||||
v 0.382683 -1.000000 0.923880
|
||||
v 0.382683 1.000000 0.923880
|
||||
v 0.195090 -1.000000 0.980785
|
||||
v 0.195090 1.000000 0.980785
|
||||
v -0.000000 -1.000000 1.000000
|
||||
v -0.000000 1.000000 1.000000
|
||||
v -0.195091 -1.000000 0.980785
|
||||
v -0.195091 1.000000 0.980785
|
||||
v -0.382684 -1.000000 0.923879
|
||||
v -0.382684 1.000000 0.923879
|
||||
v -0.555571 -1.000000 0.831469
|
||||
v -0.555571 1.000000 0.831469
|
||||
v -0.707107 -1.000000 0.707106
|
||||
v -0.707107 1.000000 0.707106
|
||||
v -0.831470 -1.000000 0.555570
|
||||
v -0.831470 1.000000 0.555570
|
||||
v -0.923880 -1.000000 0.382683
|
||||
v -0.923880 1.000000 0.382683
|
||||
v -0.980785 -1.000000 0.195089
|
||||
v -0.980785 1.000000 0.195089
|
||||
v -1.000000 -1.000000 -0.000001
|
||||
v -1.000000 1.000000 -0.000001
|
||||
v -0.980785 -1.000000 -0.195091
|
||||
v -0.980785 1.000000 -0.195091
|
||||
v -0.923879 -1.000000 -0.382684
|
||||
v -0.923879 1.000000 -0.382684
|
||||
v -0.831469 -1.000000 -0.555571
|
||||
v -0.831469 1.000000 -0.555571
|
||||
v -0.707106 -1.000000 -0.707108
|
||||
v -0.707106 1.000000 -0.707108
|
||||
v -0.555569 -1.000000 -0.831470
|
||||
v -0.555569 1.000000 -0.831470
|
||||
v -0.382682 -1.000000 -0.923880
|
||||
v -0.382682 1.000000 -0.923880
|
||||
v -0.195089 -1.000000 -0.980786
|
||||
v -0.195089 1.000000 -0.980786
|
||||
vt 1.000000 0.500000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.968750 1.000000
|
||||
vt 0.968750 0.500000
|
||||
vt 0.937500 1.000000
|
||||
vt 0.937500 0.500000
|
||||
vt 0.906250 1.000000
|
||||
vt 0.906250 0.500000
|
||||
vt 0.875000 1.000000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.843750 1.000000
|
||||
vt 0.843750 0.500000
|
||||
vt 0.812500 1.000000
|
||||
vt 0.812500 0.500000
|
||||
vt 0.781250 1.000000
|
||||
vt 0.781250 0.500000
|
||||
vt 0.750000 1.000000
|
||||
vt 0.750000 0.500000
|
||||
vt 0.718750 1.000000
|
||||
vt 0.718750 0.500000
|
||||
vt 0.687500 1.000000
|
||||
vt 0.687500 0.500000
|
||||
vt 0.656250 1.000000
|
||||
vt 0.656250 0.500000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.593750 1.000000
|
||||
vt 0.593750 0.500000
|
||||
vt 0.562500 1.000000
|
||||
vt 0.562500 0.500000
|
||||
vt 0.531250 1.000000
|
||||
vt 0.531250 0.500000
|
||||
vt 0.500000 1.000000
|
||||
vt 0.500000 0.500000
|
||||
vt 0.468750 1.000000
|
||||
vt 0.468750 0.500000
|
||||
vt 0.437500 1.000000
|
||||
vt 0.437500 0.500000
|
||||
vt 0.406250 1.000000
|
||||
vt 0.406250 0.500000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.343750 1.000000
|
||||
vt 0.343750 0.500000
|
||||
vt 0.312500 1.000000
|
||||
vt 0.312500 0.500000
|
||||
vt 0.281250 1.000000
|
||||
vt 0.281250 0.500000
|
||||
vt 0.250000 1.000000
|
||||
vt 0.250000 0.500000
|
||||
vt 0.218750 1.000000
|
||||
vt 0.218750 0.500000
|
||||
vt 0.187500 1.000000
|
||||
vt 0.187500 0.500000
|
||||
vt 0.156250 1.000000
|
||||
vt 0.156250 0.500000
|
||||
vt 0.125000 1.000000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.093750 1.000000
|
||||
vt 0.093750 0.500000
|
||||
vt 0.062500 1.000000
|
||||
vt 0.062500 0.500000
|
||||
vt 0.296822 0.485388
|
||||
vt 0.250000 0.490000
|
||||
vt 0.203179 0.485389
|
||||
vt 0.158156 0.471731
|
||||
vt 0.116663 0.449553
|
||||
vt 0.080295 0.419706
|
||||
vt 0.050447 0.383337
|
||||
vt 0.028269 0.341844
|
||||
vt 0.014612 0.296822
|
||||
vt 0.010000 0.250000
|
||||
vt 0.014611 0.203179
|
||||
vt 0.028269 0.158156
|
||||
vt 0.050447 0.116663
|
||||
vt 0.080294 0.080294
|
||||
vt 0.116663 0.050447
|
||||
vt 0.158156 0.028269
|
||||
vt 0.203178 0.014612
|
||||
vt 0.250000 0.010000
|
||||
vt 0.296822 0.014612
|
||||
vt 0.341844 0.028269
|
||||
vt 0.383337 0.050447
|
||||
vt 0.419706 0.080294
|
||||
vt 0.449553 0.116663
|
||||
vt 0.471731 0.158156
|
||||
vt 0.485388 0.203178
|
||||
vt 0.490000 0.250000
|
||||
vt 0.485388 0.296822
|
||||
vt 0.471731 0.341844
|
||||
vt 0.449553 0.383337
|
||||
vt 0.419706 0.419706
|
||||
vt 0.383337 0.449553
|
||||
vt 0.341844 0.471731
|
||||
vt 0.031250 1.000000
|
||||
vt 0.031250 0.500000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.500000
|
||||
vt 0.750000 0.490000
|
||||
vt 0.796822 0.485388
|
||||
vt 0.841844 0.471731
|
||||
vt 0.883337 0.449553
|
||||
vt 0.919706 0.419706
|
||||
vt 0.949553 0.383337
|
||||
vt 0.971731 0.341844
|
||||
vt 0.985388 0.296822
|
||||
vt 0.990000 0.250000
|
||||
vt 0.985388 0.203178
|
||||
vt 0.971731 0.158156
|
||||
vt 0.949553 0.116663
|
||||
vt 0.919706 0.080294
|
||||
vt 0.883337 0.050447
|
||||
vt 0.841844 0.028269
|
||||
vt 0.796822 0.014612
|
||||
vt 0.750000 0.010000
|
||||
vt 0.703178 0.014612
|
||||
vt 0.658156 0.028269
|
||||
vt 0.616663 0.050447
|
||||
vt 0.580294 0.080294
|
||||
vt 0.550447 0.116663
|
||||
vt 0.528269 0.158156
|
||||
vt 0.514611 0.203179
|
||||
vt 0.510000 0.250000
|
||||
vt 0.514612 0.296822
|
||||
vt 0.528269 0.341844
|
||||
vt 0.550447 0.383337
|
||||
vt 0.580295 0.419706
|
||||
vt 0.616663 0.449553
|
||||
vt 0.658156 0.471731
|
||||
vt 0.703179 0.485389
|
||||
vn 0.0980 0.0000 -0.9952
|
||||
vn 0.2903 0.0000 -0.9569
|
||||
vn 0.4714 0.0000 -0.8819
|
||||
vn 0.6344 0.0000 -0.7730
|
||||
vn 0.7730 0.0000 -0.6344
|
||||
vn 0.8819 0.0000 -0.4714
|
||||
vn 0.9569 0.0000 -0.2903
|
||||
vn 0.9952 0.0000 -0.0980
|
||||
vn 0.9952 0.0000 0.0980
|
||||
vn 0.9569 0.0000 0.2903
|
||||
vn 0.8819 0.0000 0.4714
|
||||
vn 0.7730 0.0000 0.6344
|
||||
vn 0.6344 0.0000 0.7730
|
||||
vn 0.4714 0.0000 0.8819
|
||||
vn 0.2903 0.0000 0.9569
|
||||
vn 0.0980 0.0000 0.9952
|
||||
vn -0.0980 0.0000 0.9952
|
||||
vn -0.2903 0.0000 0.9569
|
||||
vn -0.4714 0.0000 0.8819
|
||||
vn -0.6344 0.0000 0.7730
|
||||
vn -0.7730 0.0000 0.6344
|
||||
vn -0.8819 0.0000 0.4714
|
||||
vn -0.9569 0.0000 0.2903
|
||||
vn -0.9952 0.0000 0.0980
|
||||
vn -0.9952 0.0000 -0.0980
|
||||
vn -0.9569 0.0000 -0.2903
|
||||
vn -0.8819 0.0000 -0.4714
|
||||
vn -0.7730 0.0000 -0.6344
|
||||
vn -0.6344 0.0000 -0.7730
|
||||
vn -0.4714 0.0000 -0.8819
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -0.2903 0.0000 -0.9569
|
||||
vn -0.0980 0.0000 -0.9952
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
usemtl Material.002
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/4/2 4/3/2 6/5/2 5/6/2
|
||||
f 5/6/3 6/5/3 8/7/3 7/8/3
|
||||
f 7/8/4 8/7/4 10/9/4 9/10/4
|
||||
f 9/10/5 10/9/5 12/11/5 11/12/5
|
||||
f 11/12/6 12/11/6 14/13/6 13/14/6
|
||||
f 13/14/7 14/13/7 16/15/7 15/16/7
|
||||
f 15/16/8 16/15/8 18/17/8 17/18/8
|
||||
f 17/18/9 18/17/9 20/19/9 19/20/9
|
||||
f 19/20/10 20/19/10 22/21/10 21/22/10
|
||||
f 21/22/11 22/21/11 24/23/11 23/24/11
|
||||
f 23/24/12 24/23/12 26/25/12 25/26/12
|
||||
f 25/26/13 26/25/13 28/27/13 27/28/13
|
||||
f 27/28/14 28/27/14 30/29/14 29/30/14
|
||||
f 29/30/15 30/29/15 32/31/15 31/32/15
|
||||
f 31/32/16 32/31/16 34/33/16 33/34/16
|
||||
f 33/34/17 34/33/17 36/35/17 35/36/17
|
||||
f 35/36/18 36/35/18 38/37/18 37/38/18
|
||||
f 37/38/19 38/37/19 40/39/19 39/40/19
|
||||
f 39/40/20 40/39/20 42/41/20 41/42/20
|
||||
f 41/42/21 42/41/21 44/43/21 43/44/21
|
||||
f 43/44/22 44/43/22 46/45/22 45/46/22
|
||||
f 45/46/23 46/45/23 48/47/23 47/48/23
|
||||
f 47/48/24 48/47/24 50/49/24 49/50/24
|
||||
f 49/50/25 50/49/25 52/51/25 51/52/25
|
||||
f 51/52/26 52/51/26 54/53/26 53/54/26
|
||||
f 53/54/27 54/53/27 56/55/27 55/56/27
|
||||
f 55/56/28 56/55/28 58/57/28 57/58/28
|
||||
f 57/58/29 58/57/29 60/59/29 59/60/29
|
||||
f 59/60/30 60/59/30 62/61/30 61/62/30
|
||||
f 4/63/31 2/64/31 64/65/31 62/66/31 60/67/31 58/68/31 56/69/31 54/70/31 52/71/31 50/72/31 48/73/31 46/74/31 44/75/31 42/76/31 40/77/31 38/78/31 36/79/31 34/80/31 32/81/31 30/82/31 28/83/31 26/84/31 24/85/31 22/86/31 20/87/31 18/88/31 16/89/31 14/90/31 12/91/31 10/92/31 8/93/31 6/94/31
|
||||
f 61/62/32 62/61/32 64/95/32 63/96/32
|
||||
f 63/96/33 64/95/33 2/97/33 1/98/33
|
||||
f 1/99/34 3/100/34 5/101/34 7/102/34 9/103/34 11/104/34 13/105/34 15/106/34 17/107/34 19/108/34 21/109/34 23/110/34 25/111/34 27/112/34 29/113/34 31/114/34 33/115/34 35/116/34 37/117/34 39/118/34 41/119/34 43/120/34 45/121/34 47/122/34 49/123/34 51/124/34 53/125/34 55/126/34 57/127/34 59/128/34 61/129/34 63/130/34
|
||||
10
assets/models/map.mtl
Normal file
@@ -0,0 +1,10 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl None
|
||||
Ns 500
|
||||
Ka 0.8 0.8 0.8
|
||||
Kd 0.8 0.8 0.8
|
||||
Ks 0.8 0.8 0.8
|
||||
d 1
|
||||
illum 2
|
||||
1996
assets/models/map.obj
Normal file
12
assets/models/plane.mtl
Normal file
@@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material.001
|
||||
Ns 323.999994
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.066773 0.057077 0.064266
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
16
assets/models/plane.obj
Normal file
@@ -0,0 +1,16 @@
|
||||
# Blender v2.90.1 OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib plane.mtl
|
||||
o Plane
|
||||
v -10.000000 0.000000 10.000000
|
||||
v 10.000000 0.000000 10.000000
|
||||
v -10.000000 0.000000 -10.000000
|
||||
v 10.000000 0.000000 -10.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Material.001
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
12
assets/models/sphere.mtl
Normal file
@@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material.001
|
||||
Ns 323.999994
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.015470 0.800000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
2071
assets/models/sphere.obj
Normal file
12
assets/models/tort.mtl
Normal file
@@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material.004
|
||||
Ns 323.999994
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.693157 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
2083
assets/models/tort.obj
Normal file
5
assets/shaders/basicColor.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name":"basicColor",
|
||||
"vert":"basicColor/basicColor.vert",
|
||||
"frag":"basicColor/basicColor.frag"
|
||||
}
|
||||
16
assets/shaders/basicColor/basicColor.frag
Normal file
@@ -0,0 +1,16 @@
|
||||
#version 330 core
|
||||
// The result : color of the fragment.
|
||||
out vec4 FragColor;
|
||||
|
||||
|
||||
// The input variable from the vertex shader (same name and same type).
|
||||
in vec3 color;
|
||||
uniform float intensity;
|
||||
uniform vec4 colorDiffuse0; // Input Color.
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 ambient = vec3(0.7333, 0.7333, 0.7333);
|
||||
vec3 diffuse = color;
|
||||
FragColor = intensity * vec4(ambient + diffuse, 1.0)*colorDiffuse0;
|
||||
}
|
||||
30
assets/shaders/basicColor/basicColor.vert
Normal file
@@ -0,0 +1,30 @@
|
||||
#version 330 core
|
||||
// Input : vertex attributes.
|
||||
layout (location = 0) in vec3 aPos; // Position of the vertex.
|
||||
layout (location = 1) in vec3 aNormal; // Normal of the vertex.
|
||||
layout (location = 2) in vec2 aTexCoords; // Texture coordonate of the vertex.
|
||||
layout (location = 3) in vec3 aTangent; // Texture coordonate of the vertex.
|
||||
layout (location = 4) in vec3 aBitangent; // Texture coordonate of the vertex.
|
||||
|
||||
// The result : color of the fragment.
|
||||
out vec3 color;
|
||||
|
||||
// Uniform input variable.
|
||||
uniform mat4 projection; // Projection of the camera.
|
||||
uniform mat4 model; // Transforms transformation.
|
||||
uniform mat4 view; // View transformation of the camera.
|
||||
uniform vec3 lightPos;
|
||||
|
||||
void main() {
|
||||
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
vec4 newPos = model * vec4(aPos, 1.0);
|
||||
// vec4 newNormal = model * vec4(aNormal, 1.0);
|
||||
vec3 newPos3 = newPos.xyz;
|
||||
// vec3 newNormal3 = newNormal.xyz;
|
||||
vec3 newNormal3 = mat3(transpose(inverse(model))) * aNormal;
|
||||
vec3 lightVec = vec3(normalize((lightPos - newPos3)));
|
||||
float diffuse = dot(lightVec, newNormal3);
|
||||
//color = vec3(1,1,1);
|
||||
color = vec3(diffuse);
|
||||
}
|
||||
5
assets/shaders/basicColor2.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name":"basicColor2",
|
||||
"vert":"basicColor2/basicColor2.vert",
|
||||
"frag":"basicColor2/basicColor2.frag"
|
||||
}
|
||||
17
assets/shaders/basicColor2/basicColor2.frag
Normal file
@@ -0,0 +1,17 @@
|
||||
#version 330 core
|
||||
// The result : color of the fragment.
|
||||
out vec4 FragColor;
|
||||
|
||||
|
||||
// The input variable from the vertex shader (same name and same type).
|
||||
in vec3 color;
|
||||
in vec2 TexCoords;
|
||||
uniform float intensity;
|
||||
uniform vec4 colorDiffuse0; // Input Color.
|
||||
uniform sampler2D textureDiffuse0;
|
||||
void main() {
|
||||
|
||||
vec3 ambient = vec3(0.7333, 0.7333, 0.7333);
|
||||
vec3 diffuse = color;
|
||||
FragColor = intensity * vec4(ambient + diffuse, 1.0)*colorDiffuse0 * texture(textureDiffuse0, TexCoords);
|
||||
}
|
||||
32
assets/shaders/basicColor2/basicColor2.vert
Normal file
@@ -0,0 +1,32 @@
|
||||
#version 330 core
|
||||
// Input : vertex attributes.
|
||||
layout (location = 0) in vec3 aPos; // Position of the vertex.
|
||||
layout (location = 1) in vec3 aNormal; // Normal of the vertex.
|
||||
layout (location = 2) in vec2 aTexCoords; // Texture coordonate of the vertex.
|
||||
layout (location = 3) in vec3 aTangent; // Texture coordonate of the vertex.
|
||||
layout (location = 4) in vec3 aBitangent; // Texture coordonate of the vertex.
|
||||
|
||||
// The result : color of the fragment.
|
||||
out vec3 color;
|
||||
out vec2 TexCoords;
|
||||
|
||||
// Uniform input variable.
|
||||
uniform mat4 projection; // Projection of the camera.
|
||||
uniform mat4 model; // Transforms transformation.
|
||||
uniform mat4 view; // View transformation of the camera.
|
||||
uniform vec3 lightPos;
|
||||
|
||||
void main() {
|
||||
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
vec4 newPos = model * vec4(aPos, 1.0);
|
||||
// vec4 newNormal = model * vec4(aNormal, 1.0);
|
||||
vec3 newPos3 = newPos.xyz;
|
||||
// vec3 newNormal3 = newNormal.xyz;
|
||||
vec3 newNormal3 = mat3(transpose(inverse(model))) * aNormal;
|
||||
vec3 lightVec = vec3(normalize((lightPos - newPos3)));
|
||||
float diffuse = dot(lightVec, newNormal3);
|
||||
//color = vec3(1,1,1);
|
||||
color = vec3(diffuse);
|
||||
TexCoords = aTexCoords;
|
||||
}
|
||||
BIN
assets/shrekt.png
Normal file
|
After Width: | Height: | Size: 242 KiB |
BIN
assets/spaceEngine.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
assets/spaceEngineIcon.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
331
doc/Doxyfile.in
Normal file
@@ -0,0 +1,331 @@
|
||||
# Doxyfile 1.8.13
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = @PROJECT@
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_LOGO =
|
||||
OUTPUT_DIRECTORY = "@CMAKE_CURRENT_BINARY_DIR@/doc_html"
|
||||
CREATE_SUBDIRS = NO
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
OUTPUT_LANGUAGE = French
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 4
|
||||
ALIASES =
|
||||
TCL_SUBST =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
EXTENSION_MAPPING =
|
||||
MARKDOWN_SUPPORT = YES
|
||||
TOC_INCLUDE_HEADINGS = 0
|
||||
AUTOLINK_SUPPORT = YES
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
GROUP_NESTED_COMPOUNDS = NO
|
||||
SUBGROUPING = YES
|
||||
INLINE_GROUPED_CLASSES = NO
|
||||
INLINE_SIMPLE_STRUCTS = NO
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_PACKAGE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = YES
|
||||
HIDE_COMPOUND_REFERENCE= NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
SHOW_GROUPED_MEMB_INC = NO
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
STRICT_PROTO_MATCHING = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE =
|
||||
CITE_BIB_FILES =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_AS_ERROR = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = "@CMAKE_CURRENT_SOURCE_DIR@/src/"
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.hpp *.h
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
SOURCE_TOOLTIPS = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
CLANG_OPTIONS =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_COLORSTYLE_HUE = 194
|
||||
HTML_COLORSTYLE_SAT = 177
|
||||
HTML_COLORSTYLE_GAMMA = 103
|
||||
HTML_TIMESTAMP = NO
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
HTML_INDEX_NUM_ENTRIES = 100
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
QHP_VIRTUAL_FOLDER = doc
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = NO
|
||||
GENERATE_TREEVIEW = YES
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
USE_MATHJAX = NO
|
||||
MATHJAX_FORMAT = HTML-CSS
|
||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||
MATHJAX_EXTENSIONS =
|
||||
MATHJAX_CODEFILE =
|
||||
SEARCHENGINE = NO
|
||||
SERVER_BASED_SEARCH = NO
|
||||
EXTERNAL_SEARCH = NO
|
||||
SEARCHENGINE_URL =
|
||||
SEARCHDATA_FILE = searchdata.xml
|
||||
EXTERNAL_SEARCH_ID =
|
||||
EXTRA_SEARCH_MAPPINGS =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
LATEX_FOOTER =
|
||||
LATEX_EXTRA_STYLESHEET =
|
||||
LATEX_EXTRA_FILES =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
LATEX_BIB_STYLE = plain
|
||||
LATEX_TIMESTAMP = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
RTF_SOURCE_CODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_SUBDIR =
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the DOCBOOK output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_DOCBOOK = NO
|
||||
DOCBOOK_OUTPUT = docbook
|
||||
DOCBOOK_PROGRAMLISTING = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
EXTERNAL_PAGES = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = NO
|
||||
MSCGEN_PATH =
|
||||
DIA_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = Helvetica
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
INTERACTIVE_SVG = NO
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DIAFILE_DIRS =
|
||||
PLANTUML_JAR_PATH =
|
||||
PLANTUML_CFG_FILE =
|
||||
PLANTUML_INCLUDE_PATH =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
1
lib/All/entt/.bazelignore
Normal file
@@ -0,0 +1 @@
|
||||
test
|
||||
1
lib/All/entt/.bazeliskrc
Normal file
@@ -0,0 +1 @@
|
||||
USE_BAZEL_VERSION=6.x
|
||||
16
lib/All/entt/.bazelrc
Normal file
@@ -0,0 +1,16 @@
|
||||
common --enable_bzlmod
|
||||
build --enable_platform_specific_config
|
||||
build --incompatible_enable_cc_toolchain_resolution
|
||||
build --enable_runfiles
|
||||
build --incompatible_strict_action_env
|
||||
|
||||
# required for googletest
|
||||
build:linux --cxxopt=-std=c++17
|
||||
build:macos --cxxopt=-std=c++17
|
||||
|
||||
common:ci --announce_rc
|
||||
common:ci --verbose_failures
|
||||
common:ci --keep_going
|
||||
test:ci --test_output=errors
|
||||
|
||||
try-import %workspace%/user.bazelrc
|
||||
43
lib/All/entt/.clang-format
Normal file
@@ -0,0 +1,43 @@
|
||||
BasedOnStyle: llvm
|
||||
---
|
||||
AccessModifierOffset: -4
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeTernaryOperators: true
|
||||
ColumnLimit: 0
|
||||
DerivePointerAlignment: false
|
||||
IncludeCategories:
|
||||
- Regex: '<[[:alnum:]_]+>'
|
||||
Priority: 1
|
||||
- Regex: '<(gtest|gmock)/'
|
||||
Priority: 2
|
||||
- Regex: '<[[:alnum:]_./]+>'
|
||||
Priority: 3
|
||||
- Regex: '<entt/'
|
||||
Priority: 4
|
||||
- Regex: '.*'
|
||||
Priority: 5
|
||||
IncludeIsMainRegex: "^$"
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWidth: 4
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
Language: Cpp
|
||||
PointerAlignment: Right
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceAroundPointerQualifiers: After
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCtorInitializerColon: false
|
||||
SpaceBeforeInheritanceColon: false
|
||||
SpaceBeforeParens: Never
|
||||
SpaceBeforeRangeBasedForLoopColon: false
|
||||
Standard: Latest
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
56
lib/All/entt/.clang-tidy
Normal file
@@ -0,0 +1,56 @@
|
||||
Checks: >
|
||||
bugprone-*,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-optin.core.EnumCastOutOfRange,
|
||||
concurrency-*,
|
||||
cppcoreguidelines-*,
|
||||
-cppcoreguidelines-owning-memory,
|
||||
-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||
-cppcoreguidelines-pro-type-const-cast,
|
||||
-cppcoreguidelines-pro-type-member-init,
|
||||
-cppcoreguidelines-pro-type-reinterpret-cast,
|
||||
-cppcoreguidelines-pro-type-union-access,
|
||||
misc-*,
|
||||
-misc-include-cleaner,
|
||||
-misc-no-recursion,
|
||||
modernize-*,
|
||||
-modernize-use-trailing-return-type,
|
||||
performance-*,
|
||||
portability-*,
|
||||
readability-*,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-named-parameter,
|
||||
-readability-uppercase-literal-suffix,
|
||||
CheckOptions:
|
||||
- key: cppcoreguidelines-avoid-magic-numbers.IgnoreAllFloatingPointValues
|
||||
value: true
|
||||
- key: cppcoreguidelines-avoid-magic-numbers.IgnorePowersOf2IntegerValues
|
||||
value: true
|
||||
- key: cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove
|
||||
value: true
|
||||
- key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams
|
||||
value: true
|
||||
- key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions
|
||||
value: true
|
||||
- key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted
|
||||
value: true
|
||||
- key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor
|
||||
value: true
|
||||
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
|
||||
value: true
|
||||
- key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables
|
||||
value: true
|
||||
- key: modernize-avoid-c-arrays.AllowStringArrays
|
||||
value: true
|
||||
- key: performance-enum-size.EnumIgnoreList
|
||||
value: meta_traits
|
||||
- key: readability-function-cognitive-complexity.IgnoreMacros
|
||||
value: true
|
||||
- key: readability-identifier-length.MinimumParameterNameLength
|
||||
value: 2
|
||||
- key: readability-identifier-length.MinimumVariableNameLength
|
||||
value: 2
|
||||
- key: readability-magic-numbers.IgnoreAllFloatingPointValues
|
||||
value: true
|
||||
- key: readability-magic-numbers.IgnorePowersOf2IntegerValues
|
||||
value: true
|
||||
4
lib/All/entt/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: skypjack
|
||||
custom: https://www.paypal.me/skypjack
|
||||
23
lib/All/entt/.github/workflows/bazel-release-archive.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Bazel Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
# A release archive is required for bzlmod
|
||||
# See: https://blog.bazel.build/2023/02/15/github-archive-checksum.html
|
||||
bazel-release-archive:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/setup-go@v5
|
||||
- run: go install github.com/bazelbuild/buildtools/buildozer@latest
|
||||
- uses: actions/checkout@v4
|
||||
- run: ./scripts/sync_bzlmod_version.sh
|
||||
- run: git archive $GITHUB_REF -o "entt-${GITHUB_REF:10}.tar.gz"
|
||||
- run: gh release upload ${GITHUB_REF:10} "entt-${GITHUB_REF:10}.tar.gz"
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
23
lib/All/entt/.github/workflows/bazel.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: bazel
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
- macos-latest
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: bazelisk test --config=ci ...
|
||||
working-directory: test
|
||||
env:
|
||||
USE_BAZEL_VERSION: 6.x
|
||||
104
lib/All/entt/.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
name: build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
|
||||
linux:
|
||||
strategy:
|
||||
matrix:
|
||||
compiler:
|
||||
- { pkg: g++, exe: 'g++', version: 12 }
|
||||
- { pkg: g++, exe: 'g++', version: 13 }
|
||||
- { pkg: g++, exe: 'g++', version: 14 }
|
||||
- { pkg: clang, exe: 'clang++', version: 16 }
|
||||
- { pkg: clang, exe: 'clang++', version: 17 }
|
||||
- { pkg: clang, exe: 'clang++', version: 18 }
|
||||
|
||||
timeout-minutes: 15
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install compiler
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y ${{ matrix.compiler.pkg }}-${{ matrix.compiler.version }}
|
||||
- name: Compile tests
|
||||
working-directory: build
|
||||
env:
|
||||
CXX: ${{ matrix.compiler.exe }}-${{ matrix.compiler.version }}
|
||||
run: |
|
||||
cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ..
|
||||
make -j4
|
||||
- name: Run tests
|
||||
working-directory: build
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
run: ctest -C Debug -j4
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
matrix:
|
||||
toolset: [default, v142, clang-cl]
|
||||
include:
|
||||
- toolset: v142
|
||||
toolset_option: -T"v142"
|
||||
- toolset: clang-cl
|
||||
toolset_option: -T"ClangCl"
|
||||
|
||||
timeout-minutes: 15
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compile tests
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ${{ matrix.toolset_option }} ..
|
||||
cmake --build . -j 4
|
||||
- name: Run tests
|
||||
working-directory: build
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
run: ctest -C Debug -j4
|
||||
|
||||
macos:
|
||||
timeout-minutes: 15
|
||||
runs-on: macOS-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compile tests
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ..
|
||||
make -j4
|
||||
- name: Run tests
|
||||
working-directory: build
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
run: ctest -C Debug -j4
|
||||
|
||||
extra:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, macOS-latest, ubuntu-latest]
|
||||
id_type: ["std::uint32_t", "std::uint64_t"]
|
||||
cxx_std: [cxx_std_17, cxx_std_20]
|
||||
|
||||
timeout-minutes: 15
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compile tests
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake -DENTT_BUILD_TESTING=ON -DENTT_CXX_STD=${{ matrix.cxx_std }} -DENTT_ID_TYPE=${{ matrix.id_type }} ..
|
||||
cmake --build . -j 4
|
||||
- name: Run tests
|
||||
working-directory: build
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
run: ctest -C Debug -j4
|
||||
38
lib/All/entt/.github/workflows/coverage.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: coverage
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
|
||||
codecov:
|
||||
timeout-minutes: 15
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compile tests
|
||||
working-directory: build
|
||||
env:
|
||||
CXXFLAGS: "--coverage -fno-elide-constructors -fno-inline -fno-default-inline"
|
||||
CXX: g++
|
||||
run: |
|
||||
cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ..
|
||||
make -j4
|
||||
- name: Run tests
|
||||
working-directory: build
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
run: ctest -C Debug -j4
|
||||
- name: Collect data
|
||||
working-directory: build
|
||||
run: |
|
||||
sudo apt install lcov
|
||||
lcov -c -d . -o coverage.info --ignore-errors gcov,gcov,mismatch,mismatch
|
||||
lcov -l coverage.info
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: build/coverage.info
|
||||
name: EnTT
|
||||
fail_ci_if_error: true
|
||||
39
lib/All/entt/.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: deploy
|
||||
|
||||
on:
|
||||
release:
|
||||
types: published
|
||||
|
||||
jobs:
|
||||
|
||||
homebrew-entt:
|
||||
timeout-minutes: 5
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
GH_REPO: homebrew-entt
|
||||
FORMULA: entt.rb
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clone repository
|
||||
working-directory: build
|
||||
env:
|
||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
run: git clone https://$GITHUB_ACTOR:$PERSONAL_ACCESS_TOKEN@github.com/$GITHUB_ACTOR/$GH_REPO.git
|
||||
- name: Prepare formula
|
||||
working-directory: build
|
||||
run: |
|
||||
cd $GH_REPO
|
||||
curl "https://github.com/${{ github.repository }}/archive/${{ github.ref }}.tar.gz" --location --fail --silent --show-error --output archive.tar.gz
|
||||
sed -i -e '/url/s/".*"/"'$(echo "https://github.com/${{ github.repository }}/archive/${{ github.ref }}.tar.gz" | sed -e 's/[\/&]/\\&/g')'"/' $FORMULA
|
||||
sed -i -e '/sha256/s/".*"/"'$(openssl sha256 archive.tar.gz | cut -d " " -f 2)'"/' $FORMULA
|
||||
- name: Update remote
|
||||
working-directory: build
|
||||
run: |
|
||||
cd $GH_REPO
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "$GITHUB_ACTOR"
|
||||
git add $FORMULA
|
||||
git commit -m "Update to ${{ github.ref }}"
|
||||
git push origin master
|
||||
31
lib/All/entt/.github/workflows/sanitizer.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: sanitizer
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
|
||||
clang:
|
||||
timeout-minutes: 15
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: [clang++]
|
||||
id_type: ["std::uint32_t", "std::uint64_t"]
|
||||
cxx_std: [cxx_std_17, cxx_std_20]
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compile tests
|
||||
working-directory: build
|
||||
env:
|
||||
CXX: ${{ matrix.compiler }}
|
||||
run: |
|
||||
cmake -DENTT_USE_SANITIZER=ON -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON -DENTT_CXX_STD=${{ matrix.cxx_std }} -DENTT_ID_TYPE=${{ matrix.id_type }} ..
|
||||
make -j4
|
||||
- name: Run tests
|
||||
working-directory: build
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
run: ctest -C Debug -j4
|
||||
84
lib/All/entt/.github/workflows/tools.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
name: tools
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- tools
|
||||
|
||||
jobs:
|
||||
|
||||
iwyu:
|
||||
timeout-minutes: 60
|
||||
|
||||
env:
|
||||
IWYU: "0.23"
|
||||
LLVM: "19"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install llvm/clang
|
||||
# see: https://apt.llvm.org/
|
||||
run: |
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo add-apt-repository "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-$LLVM main"
|
||||
sudo apt update
|
||||
sudo apt remove -y "llvm*"
|
||||
sudo apt remove -y "libclang*"
|
||||
sudo apt remove -y "clang*"
|
||||
sudo apt install -y llvm-$LLVM-dev
|
||||
sudo apt install -y libclang-$LLVM-dev
|
||||
sudo apt install -y clang-$LLVM
|
||||
- name: Compile iwyu
|
||||
# see: https://github.com/include-what-you-use/include-what-you-use
|
||||
working-directory: build
|
||||
run: |
|
||||
git clone https://github.com/include-what-you-use/include-what-you-use.git --branch $IWYU --depth 1
|
||||
mkdir include-what-you-use/build
|
||||
cd include-what-you-use/build
|
||||
cmake -DCMAKE_C_COMPILER=clang-$LLVM \
|
||||
-DCMAKE_CXX_COMPILER=clang++-$LLVM \
|
||||
-DCMAKE_INSTALL_PREFIX=./ \
|
||||
..
|
||||
make -j4
|
||||
bin/include-what-you-use --version
|
||||
- name: Compile tests
|
||||
working-directory: build
|
||||
run: |
|
||||
export PATH=$PATH:${GITHUB_WORKSPACE}/build/include-what-you-use/build/bin
|
||||
cmake -DCMAKE_C_COMPILER=clang-$LLVM \
|
||||
-DCMAKE_CXX_COMPILER=clang++-$LLVM \
|
||||
-DENTT_BUILD_TESTING=ON \
|
||||
-DENTT_BUILD_BENCHMARK=ON \
|
||||
-DENTT_BUILD_EXAMPLE=ON \
|
||||
-DENTT_BUILD_LIB=ON \
|
||||
-DENTT_BUILD_SNAPSHOT=ON \
|
||||
-DENTT_BUILD_TOOLS=ON \
|
||||
-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE="include-what-you-use;-Xiwyu;--mapping_file=${GITHUB_WORKSPACE}/entt.imp;-Xiwyu;--no_fwd_decls;-Xiwyu;--verbose=1" \
|
||||
..
|
||||
make -j4
|
||||
|
||||
clang-tidy:
|
||||
timeout-minutes: 60
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compile tests
|
||||
working-directory: build
|
||||
env:
|
||||
CXX: clang++
|
||||
run: |
|
||||
cmake -DENTT_BUILD_TESTING=ON \
|
||||
-DENTT_BUILD_BENCHMARK=ON \
|
||||
-DENTT_BUILD_EXAMPLE=ON \
|
||||
-DENTT_BUILD_LIB=ON \
|
||||
-DENTT_BUILD_SNAPSHOT=ON \
|
||||
-DENTT_BUILD_TOOLS=ON \
|
||||
-DENTT_USE_CLANG_TIDY=ON \
|
||||
..
|
||||
make -j4
|
||||
16
lib/All/entt/.gitignore
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Conan
|
||||
conan/test_package/build
|
||||
|
||||
# IDEs
|
||||
*.user
|
||||
.idea
|
||||
.vscode
|
||||
.vs
|
||||
CMakeSettings.json
|
||||
cpp.hint
|
||||
|
||||
# Bazel
|
||||
/bazel-*
|
||||
/test/bazel-*
|
||||
/user.bazelrc
|
||||
*.bazel.lock
|
||||
56
lib/All/entt/AUTHORS
Normal file
@@ -0,0 +1,56 @@
|
||||
# Author
|
||||
|
||||
skypjack
|
||||
|
||||
# Contributors
|
||||
|
||||
alexames
|
||||
BenediktConze
|
||||
bjadamson
|
||||
ceeac
|
||||
ColinH
|
||||
corystegel
|
||||
Croydon
|
||||
cschreib
|
||||
cugone
|
||||
dbacchet
|
||||
dBagrat
|
||||
djarek
|
||||
DNKpp
|
||||
DonKult
|
||||
drglove
|
||||
eliasdaler
|
||||
erez-o
|
||||
eugeneko
|
||||
gale83
|
||||
ghost
|
||||
grdowns
|
||||
Green-Sky
|
||||
Innokentiy-Alaytsev
|
||||
Kerndog73
|
||||
Koward
|
||||
Lawrencemm
|
||||
markand
|
||||
mhammerc
|
||||
Milerius
|
||||
Minimonium
|
||||
morbo84
|
||||
m-waka
|
||||
netpoetica
|
||||
NixAJ
|
||||
Oortonaut
|
||||
Paolo-Oliverio
|
||||
pgruenbacher
|
||||
prowolf
|
||||
Qix-
|
||||
stefanofiorentino
|
||||
suVrik
|
||||
szunhammer
|
||||
The5-1
|
||||
vblanco20-1
|
||||
willtunnels
|
||||
WizardIke
|
||||
WoLfulus
|
||||
w1th0utnam3
|
||||
xissburg
|
||||
zaucy
|
||||
6
lib/All/entt/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
alias(
|
||||
name = "entt",
|
||||
actual = "//src:entt",
|
||||
)
|
||||
330
lib/All/entt/CMakeLists.txt
Normal file
@@ -0,0 +1,330 @@
|
||||
# EnTT
|
||||
|
||||
cmake_minimum_required(VERSION 3.15.7)
|
||||
|
||||
# Read project version
|
||||
|
||||
set(ENTT_VERSION_REGEX "#define ENTT_VERSION_.*[ \t]+(.+)")
|
||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/src/entt/config/version.h" ENTT_VERSION REGEX ${ENTT_VERSION_REGEX})
|
||||
list(TRANSFORM ENTT_VERSION REPLACE ${ENTT_VERSION_REGEX} "\\1")
|
||||
string(JOIN "." ENTT_VERSION ${ENTT_VERSION})
|
||||
|
||||
# Project configuration
|
||||
|
||||
project(
|
||||
EnTT
|
||||
VERSION ${ENTT_VERSION}
|
||||
DESCRIPTION "Gaming meets modern C++ - a fast and reliable entity-component system (ECS) and much more"
|
||||
HOMEPAGE_URL "https://github.com/skypjack/entt"
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif()
|
||||
|
||||
message(VERBOSE "*")
|
||||
message(VERBOSE "* ${PROJECT_NAME} v${PROJECT_VERSION} (${CMAKE_BUILD_TYPE})")
|
||||
message(VERBOSE "* Copyright (c) 2017-2025 Michele Caini <michele.caini@gmail.com>")
|
||||
message(VERBOSE "*")
|
||||
|
||||
# CMake stuff
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||
|
||||
# Compiler stuff
|
||||
|
||||
option(ENTT_USE_LIBCPP "Use libc++ by adding -stdlib=libc++ flag if available." OFF)
|
||||
option(ENTT_USE_SANITIZER "Enable sanitizers by adding -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined flags if available." OFF)
|
||||
option(ENTT_USE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF)
|
||||
|
||||
if(ENTT_USE_LIBCPP)
|
||||
if(NOT WIN32)
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CMakePushCheckState)
|
||||
|
||||
cmake_push_check_state()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -stdlib=libc++")
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include<type_traits>
|
||||
int main() { return std::is_same_v<int, char>; }
|
||||
" ENTT_HAS_LIBCPP)
|
||||
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
if(NOT ENTT_HAS_LIBCPP)
|
||||
message(VERBOSE "The option ENTT_USE_LIBCPP is set but libc++ is not available.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENTT_USE_SANITIZER)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
|
||||
set(ENTT_HAS_SANITIZER TRUE CACHE BOOL "" FORCE)
|
||||
mark_as_advanced(ENTT_HAS_SANITIZER)
|
||||
endif()
|
||||
|
||||
if(NOT ENTT_HAS_SANITIZER)
|
||||
message(VERBOSE "The option ENTT_USE_SANITIZER is set but sanitizer support is not available.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENTT_USE_CLANG_TIDY)
|
||||
find_program(ENTT_CLANG_TIDY_EXECUTABLE "clang-tidy")
|
||||
|
||||
if(NOT ENTT_CLANG_TIDY_EXECUTABLE)
|
||||
message(VERBOSE "The option ENTT_USE_CLANG_TIDY is set but clang-tidy executable is not available.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Add EnTT target
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
add_library(EnTT INTERFACE)
|
||||
add_library(EnTT::EnTT ALIAS EnTT)
|
||||
|
||||
target_include_directories(
|
||||
EnTT
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
target_compile_features(EnTT INTERFACE cxx_std_17)
|
||||
|
||||
if(ENTT_HAS_LIBCPP)
|
||||
target_compile_options(EnTT BEFORE INTERFACE -stdlib=libc++)
|
||||
endif()
|
||||
|
||||
if(ENTT_HAS_SANITIZER)
|
||||
target_compile_options(EnTT INTERFACE $<$<CONFIG:Debug>:-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined>)
|
||||
target_link_libraries(EnTT INTERFACE $<$<CONFIG:Debug>:-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined>)
|
||||
endif()
|
||||
|
||||
if(ENTT_CLANG_TIDY_EXECUTABLE)
|
||||
set(CMAKE_CXX_CLANG_TIDY "${ENTT_CLANG_TIDY_EXECUTABLE};--config-file=${EnTT_SOURCE_DIR}/.clang-tidy;--header-filter=${EnTT_SOURCE_DIR}/src/entt/.*")
|
||||
endif()
|
||||
|
||||
# Add EnTT goodies
|
||||
|
||||
option(ENTT_INCLUDE_HEADERS "Add all EnTT headers to the EnTT target." OFF)
|
||||
option(ENTT_INCLUDE_NATVIS "Add EnTT natvis files to the EnTT target." OFF)
|
||||
|
||||
if(ENTT_INCLUDE_NATVIS)
|
||||
if(MSVC)
|
||||
set(ENTT_HAS_NATVIS TRUE CACHE BOOL "" FORCE)
|
||||
mark_as_advanced(ENTT_HAS_NATVIS)
|
||||
endif()
|
||||
|
||||
if(NOT ENTT_HAS_NATVIS)
|
||||
message(VERBOSE "The option ENTT_INCLUDE_NATVIS is set but natvis files are not supported. They will not be added to the target.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENTT_INCLUDE_HEADERS)
|
||||
target_sources(
|
||||
EnTT
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/config/config.h>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/config/macro.h>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/config/version.h>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/container/dense_map.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/container/dense_set.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/container/table.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/container/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/algorithm.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/any.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/attribute.h>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/bit.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/compressed_pair.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/enum.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/family.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/hashed_string.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/ident.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/iterator.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/memory.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/monostate.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/ranges.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/tuple.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/type_info.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/type_traits.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/core/utility.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/component.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/entity.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/group.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/handle.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/mixin.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/helper.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/organizer.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/ranges.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/registry.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/runtime_view.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/snapshot.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/sparse_set.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/storage.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/view.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/graph/adjacency_matrix.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/graph/dot.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/graph/flow.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/graph/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/locator/locator.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/adl_pointer.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/container.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/context.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/factory.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/meta.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/node.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/pointer.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/policy.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/range.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/resolve.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/template.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/type_traits.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/meta/utility.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/poly/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/poly/poly.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/process/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/process/process.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/process/scheduler.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/resource/cache.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/resource/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/resource/loader.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/resource/resource.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/signal/delegate.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/signal/dispatcher.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/signal/emitter.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/signal/fwd.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/signal/sigh.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entt.hpp>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/fwd.hpp>
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENTT_HAS_NATVIS)
|
||||
target_sources(
|
||||
EnTT
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/config.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/container.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/core.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/entity.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/graph.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/locator.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/meta.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/poly.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/process.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/resource.natvis>
|
||||
$<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/natvis/entt/signal.natvis>
|
||||
)
|
||||
endif()
|
||||
|
||||
# Install EnTT and all related files
|
||||
|
||||
option(ENTT_INSTALL "Install EnTT and all related files." OFF)
|
||||
|
||||
if(ENTT_INSTALL)
|
||||
# Install pkg-config file
|
||||
|
||||
include(JoinPaths)
|
||||
|
||||
set(EnTT_PKGCONFIG ${CMAKE_CURRENT_BINARY_DIR}/entt.pc)
|
||||
|
||||
join_paths(EnTT_PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
|
||||
configure_file(
|
||||
${EnTT_SOURCE_DIR}/cmake/in/entt.pc.in
|
||||
${EnTT_PKGCONFIG}
|
||||
@ONLY
|
||||
)
|
||||
|
||||
install(
|
||||
FILES ${EnTT_PKGCONFIG}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
)
|
||||
|
||||
# Install EnTT
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
install(
|
||||
TARGETS EnTT
|
||||
EXPORT EnTTTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
EnTTConfigVersion.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
configure_package_config_file(
|
||||
${EnTT_SOURCE_DIR}/cmake/in/EnTTConfig.cmake.in
|
||||
EnTTConfig.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/EnTT/cmake
|
||||
)
|
||||
|
||||
export(
|
||||
EXPORT EnTTTargets
|
||||
FILE ${CMAKE_CURRENT_BINARY_DIR}/EnTTTargets.cmake
|
||||
NAMESPACE EnTT::
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT EnTTTargets
|
||||
FILE EnTTTargets.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/EnTT/cmake
|
||||
NAMESPACE EnTT::
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${PROJECT_BINARY_DIR}/EnTTConfig.cmake
|
||||
${PROJECT_BINARY_DIR}/EnTTConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/EnTT/cmake
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY src/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.hpp"
|
||||
)
|
||||
|
||||
export(PACKAGE EnTT)
|
||||
endif()
|
||||
|
||||
# Tests
|
||||
|
||||
option(ENTT_BUILD_TESTING "Enable building tests." OFF)
|
||||
|
||||
if(ENTT_BUILD_TESTING)
|
||||
option(ENTT_FIND_GTEST_PACKAGE "Enable finding gtest package." OFF)
|
||||
|
||||
option(ENTT_BUILD_BENCHMARK "Build benchmark." OFF)
|
||||
option(ENTT_BUILD_EXAMPLE "Build examples." OFF)
|
||||
option(ENTT_BUILD_LIB "Build lib tests." OFF)
|
||||
option(ENTT_BUILD_SNAPSHOT "Build snapshot test with Cereal." OFF)
|
||||
|
||||
set(ENTT_ID_TYPE std::uint32_t CACHE STRING "Type of identifiers to use for the tests")
|
||||
set(ENTT_CXX_STD cxx_std_17 CACHE STRING "C++ standard revision to use for the tests")
|
||||
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
# Documentation
|
||||
|
||||
option(ENTT_BUILD_DOCS "Enable building with documentation." OFF)
|
||||
|
||||
if(ENTT_BUILD_DOCS)
|
||||
add_subdirectory(docs)
|
||||
endif()
|
||||
43
lib/All/entt/CONTRIBUTING.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Contributing
|
||||
|
||||
First of all, thank you very much for taking the time to contribute to the
|
||||
`EnTT` library.<br/>
|
||||
How to do it mostly depends on the type of contribution:
|
||||
|
||||
* If you have a question, **please** ensure there isn't already an answer for
|
||||
you by searching on GitHub under
|
||||
[issues](https://github.com/skypjack/entt/issues). Do not forget to search
|
||||
also through the closed ones. If you are unable to find a proper answer, feel
|
||||
free to [open a new issue](https://github.com/skypjack/entt/issues/new).
|
||||
Usually, questions are marked as such and closed in a few days.
|
||||
|
||||
* If you want to fix a typo in the inline documentation or in the README file,
|
||||
if you want to add some new sections or if you want to help me with the
|
||||
language by reviewing what I wrote so far (I'm not a native speaker after
|
||||
all), **please** open a new
|
||||
[pull request](https://github.com/skypjack/entt/pulls) with your changes.
|
||||
|
||||
* If you found a bug, **please** ensure there isn't already an answer for you by
|
||||
searching on GitHub under [issues](https://github.com/skypjack/entt/issues).
|
||||
If you are unable to find an open issue addressing the problem, feel free to
|
||||
[open a new one](https://github.com/skypjack/entt/issues/new). **Please**, do
|
||||
not forget to carefully describe how to reproduce the problem, then add all
|
||||
the information about the system on which you are experiencing it and point
|
||||
out the version of `EnTT` you are using (tag or commit).
|
||||
|
||||
* If you found a bug and you wrote a patch to fix it, open a new
|
||||
[pull request](https://github.com/skypjack/entt/pulls) with your code.
|
||||
**Please**, add some tests to avoid regressions in future if possible, it
|
||||
would be really appreciated. Note that the `EnTT` library has a
|
||||
[coverage at 100%](https://coveralls.io/github/skypjack/entt?branch=master)
|
||||
(at least it was at 100% at the time I wrote this file) and this is the reason
|
||||
for which you can be confident with using it in a production environment.
|
||||
|
||||
* If you want to propose a new feature and you know how to code it, **please**
|
||||
do not issue directly a pull request. Before to do it,
|
||||
[create a new issue](https://github.com/skypjack/entt/issues/new) to discuss
|
||||
your proposal. Other users could be interested in your idea and the discussion
|
||||
that will follow can refine it and therefore give us a better solution.
|
||||
|
||||
* If you want to request a new feature, I'm available for hiring. Take a look at
|
||||
[my profile](https://github.com/skypjack) and feel free to write me.
|
||||
21
lib/All/entt/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2025 Michele Caini, author of EnTT
|
||||
|
||||
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
|
||||
copy 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
|
||||
copy 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.
|
||||
4
lib/All/entt/MODULE.bazel
Normal file
@@ -0,0 +1,4 @@
|
||||
module(name = "entt")
|
||||
|
||||
bazel_dep(name = "rules_cc", version = "0.0.8")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.4.2")
|
||||
414
lib/All/entt/README.md
Normal file
@@ -0,0 +1,414 @@
|
||||

|
||||
|
||||
[](https://github.com/skypjack/entt/actions)
|
||||
[](https://codecov.io/gh/skypjack/entt)
|
||||
[](https://godbolt.org/z/zxW73f)
|
||||
[](https://skypjack.github.io/entt/)
|
||||
[](https://vcpkg.link/ports/entt)
|
||||
[](https://conan.io/center/recipes/entt)
|
||||
[](https://gitter.im/skypjack/entt)
|
||||
[](https://discord.gg/5BjPWBd)
|
||||
|
||||
> `EnTT` has been a dream so far, we haven't found a single bug to date and it's
|
||||
> super easy to work with
|
||||
>
|
||||
> -- Every EnTT User Ever
|
||||
|
||||
`EnTT` is a header-only, tiny and easy to use library for game programming and
|
||||
much more written in **modern C++**.<br/>
|
||||
[Among others](https://github.com/skypjack/entt/wiki/EnTT-in-Action), it's used
|
||||
in [**Minecraft**](https://minecraft.net/en-us/attribution/) by Mojang, the
|
||||
[**ArcGIS Runtime SDKs**](https://developers.arcgis.com/arcgis-runtime/) by Esri
|
||||
and the amazing [**Ragdoll**](https://ragdolldynamics.com/).<br/>
|
||||
If you don't see your project in the list, please open an issue, submit a PR or
|
||||
add the [\#entt](https://github.com/topics/entt) tag to your _topics_! :+1:
|
||||
|
||||
---
|
||||
|
||||
Do you want to **keep up with changes** or do you have a **question** that
|
||||
doesn't require you to open an issue?<br/>
|
||||
Join the [gitter channel](https://gitter.im/skypjack/entt) and the
|
||||
[discord server](https://discord.gg/5BjPWBd), meet other users like you. The
|
||||
more we are, the better for everyone.<br/>
|
||||
Don't forget to check the
|
||||
[FAQs](https://github.com/skypjack/entt/wiki/Frequently-Asked-Questions) and the
|
||||
[wiki](https://github.com/skypjack/entt/wiki) too. Your answers may already be
|
||||
there.
|
||||
|
||||
Do you want to support `EnTT`? Consider becoming a
|
||||
[**sponsor**](https://github.com/users/skypjack/sponsorship) or making a
|
||||
donation via [**PayPal**](https://www.paypal.me/skypjack).<br/>
|
||||
Many thanks to [these people](https://skypjack.github.io/sponsorship/) and
|
||||
**special** thanks to:
|
||||
|
||||
[](https://mojang.com)
|
||||
[](https://img.ly/)
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Code Example](#code-example)
|
||||
* [Motivation](#motivation)
|
||||
* [Benchmark](#benchmark)
|
||||
* [Integration](#integration)
|
||||
* [Requirements](#requirements)
|
||||
* [CMake](#cmake)
|
||||
* [Natvis support](#natvis-support)
|
||||
* [Packaging Tools](#packaging-tools)
|
||||
* [pkg-config](#pkg-config)
|
||||
* [Documentation](#documentation)
|
||||
* [Tests](#tests)
|
||||
* [EnTT in Action](#entt-in-action)
|
||||
* [Contributors](#contributors)
|
||||
* [License](#license)
|
||||
|
||||
# Introduction
|
||||
|
||||
The entity-component-system (also known as _ECS_) is an architectural pattern
|
||||
used mostly in game development. For further details:
|
||||
|
||||
* [Entity Systems Wiki](http://entity-systems.wikidot.com/)
|
||||
* [Evolve Your Hierarchy](http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/)
|
||||
* [ECS on Wikipedia](https://en.wikipedia.org/wiki/Entity%E2%80%93component%E2%80%93system)
|
||||
|
||||
This project started off as a pure entity-component system. Over time the
|
||||
codebase has grown as more and more classes and functionalities were added.<br/>
|
||||
Here is a brief, yet incomplete list of what it offers today:
|
||||
|
||||
* Built-in **RTTI system** mostly similar to the standard one.
|
||||
* A `constexpr` utility for human-readable **resource names**.
|
||||
* Minimal **configuration system** built using the monostate pattern.
|
||||
* Incredibly fast **entity-component system** with its own _pay for what you
|
||||
use_ policy, unconstrained component types with optional pointer stability and
|
||||
hooks for storage customization.
|
||||
* Views and groups to iterate entities and components and allow different access
|
||||
patterns, from **perfect SoA** to fully random.
|
||||
* A lot of **facilities** built on top of the entity-component system to help
|
||||
the users and avoid reinventing the wheel.
|
||||
* General purpose **execution graph builder** for optimal scheduling.
|
||||
* The smallest and most basic implementation of a **service locator** ever seen.
|
||||
* A built-in, non-intrusive and macro-free runtime **reflection system**.
|
||||
* **Static polymorphism** made simple and within everyone's reach.
|
||||
* A few homemade containers, like a sparse set based **hash map**.
|
||||
* A **cooperative scheduler** for processes of any type.
|
||||
* All that is needed for **resource management** (cache, loaders, handles).
|
||||
* Delegates, **signal handlers** and a tiny event dispatcher.
|
||||
* A general purpose **event emitter** as a CRTP idiom based class template.
|
||||
* And **much more**! Check out the
|
||||
[**wiki**](https://github.com/skypjack/entt/wiki).
|
||||
|
||||
Consider this list a work in progress as well as the project. The whole API is
|
||||
fully documented in-code for those who are brave enough to read it.<br/>
|
||||
Please, do note that all tools are also DLL-friendly now and run smoothly across
|
||||
boundaries.
|
||||
|
||||
One thing known to most is that `EnTT` is also used in **Minecraft**.<br/>
|
||||
Given that the game is available literally everywhere, I can confidently say
|
||||
that the library has been sufficiently tested on every platform that can come to
|
||||
mind.
|
||||
|
||||
## Code Example
|
||||
|
||||
```cpp
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
struct position {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct velocity {
|
||||
float dx;
|
||||
float dy;
|
||||
};
|
||||
|
||||
void update(entt::registry ®istry) {
|
||||
auto view = registry.view<const position, velocity>();
|
||||
|
||||
// use a callback
|
||||
view.each([](const auto &pos, auto &vel) { /* ... */ });
|
||||
|
||||
// use an extended callback
|
||||
view.each([](const auto entity, const auto &pos, auto &vel) { /* ... */ });
|
||||
|
||||
// use a range-for
|
||||
for(auto [entity, pos, vel]: view.each()) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// use forward iterators and get only the components of interest
|
||||
for(auto entity: view) {
|
||||
auto &vel = view.get<velocity>(entity);
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
entt::registry registry;
|
||||
|
||||
for(auto i = 0u; i < 10u; ++i) {
|
||||
const auto entity = registry.create();
|
||||
registry.emplace<position>(entity, i * 1.f, i * 1.f);
|
||||
if(i % 2 == 0) { registry.emplace<velocity>(entity, i * .1f, i * .1f); }
|
||||
}
|
||||
|
||||
update(registry);
|
||||
}
|
||||
```
|
||||
|
||||
## Motivation
|
||||
|
||||
I started developing `EnTT` for the _wrong_ reason: my goal was to design an
|
||||
entity-component system to beat another well known open source library both in
|
||||
terms of performance and possibly memory usage.<br/>
|
||||
In the end, I did it, but it wasn't very satisfying. Actually it wasn't
|
||||
satisfying at all. The fastest and nothing more, fairly little indeed. When I
|
||||
realized it, I tried hard to keep intact the great performance of `EnTT` and to
|
||||
add all the features I wanted to see in *my own library* at the same time.
|
||||
|
||||
Nowadays, `EnTT` is finally what I was looking for: still faster than its
|
||||
_competitors_, lower memory usage in the average case, a really good API and an
|
||||
amazing set of features. And even more, of course.
|
||||
|
||||
## Benchmark
|
||||
|
||||
For what it's worth, you'll **never** see me trying to make other projects look
|
||||
bad or offer dubious comparisons just to make this library seem cooler.<br/>
|
||||
I leave this activity to others, if they enjoy it (and it seems that some people
|
||||
actually like it). I prefer to make better use of my time.
|
||||
|
||||
If you are interested, you can compile the `benchmark` test in release mode (to
|
||||
enable compiler optimizations, otherwise it would make little sense) by setting
|
||||
the `ENTT_BUILD_BENCHMARK` option of `CMake` to `ON`, then evaluate yourself
|
||||
whether you're satisfied with the results or not.
|
||||
|
||||
There are also a lot of projects out there that use `EnTT` as a basis for
|
||||
comparison (this should already tell you a lot). Many of these benchmarks are
|
||||
completely wrong, many others are simply incomplete, good at omitting some
|
||||
information and using the wrong function to compare a given feature. Certainly
|
||||
there are also good ones but they age quickly if nobody updates them, especially
|
||||
when the library they are dealing with is actively developed.<br/>
|
||||
Out of all of them, [this](https://github.com/abeimler/ecs_benchmark) seems like
|
||||
the most up-to-date project and also covers a certain number of libraries. I
|
||||
can't say exactly whether `EnTT` is used correctly or not. However, even if used
|
||||
poorly, it should still give the reader an idea of where it's going to operate.
|
||||
|
||||
# Integration
|
||||
|
||||
`EnTT` is a header-only library. This means that including the `entt.hpp` header
|
||||
is enough to include the library as a whole and use it. For those who are
|
||||
interested only in the entity-component system, consider to include the sole
|
||||
`entity/registry.hpp` header instead.<br/>
|
||||
It's a matter of adding the following line to the top of a file:
|
||||
|
||||
```cpp
|
||||
#include <entt/entt.hpp>
|
||||
```
|
||||
|
||||
Use the line below to include only the entity-component system instead:
|
||||
|
||||
```cpp
|
||||
#include <entt/entity/registry.hpp>
|
||||
```
|
||||
|
||||
Then pass the proper `-I` argument to the compiler to add the `src` directory to
|
||||
the include paths.
|
||||
|
||||
## Requirements
|
||||
|
||||
To be able to use `EnTT`, users must provide a full-featured compiler that
|
||||
supports at least C++17.<br/>
|
||||
The requirements below are mandatory to compile the tests and to extract the
|
||||
documentation:
|
||||
|
||||
* `CMake` version 3.7 or later.
|
||||
* `Doxygen` version 1.8 or later.
|
||||
|
||||
Alternatively, [Bazel](https://bazel.build) is also supported as a build system
|
||||
(credits to [zaucy](https://github.com/zaucy) who offered to maintain it).<br/>
|
||||
In the documentation below I'll still refer to `CMake`, this being the official
|
||||
build system of the library.
|
||||
|
||||
## CMake
|
||||
|
||||
To use `EnTT` from a `CMake` project, just link an existing target to the
|
||||
`EnTT::EnTT` alias.<br/>
|
||||
The library offers everything you need for locating (as in `find_package`),
|
||||
embedding (as in `add_subdirectory`), fetching (as in `FetchContent`) or using
|
||||
it in many of the ways that you can think of and that involve `CMake`.<br/>
|
||||
Covering all possible cases would require a treatise and not a simple README
|
||||
file, but I'm confident that anyone reading this section also knows what it's
|
||||
about and can use `EnTT` from a `CMake` project without problems.
|
||||
|
||||
## Natvis support
|
||||
|
||||
When using `CMake`, just enable the option `ENTT_INCLUDE_NATVIS` and enjoy
|
||||
it.<br/>
|
||||
Otherwise, most of the tools are covered via Natvis and all files can be found
|
||||
in the `natvis` directory, divided by module.<br/>
|
||||
If you spot errors or have suggestions, any contribution is welcome!
|
||||
|
||||
## Packaging Tools
|
||||
|
||||
`EnTT` is available for some of the most known packaging tools. In particular:
|
||||
|
||||
* [`Conan`](https://github.com/conan-io/conan-center-index), the C/C++ Package
|
||||
Manager for Developers.
|
||||
|
||||
* [`vcpkg`](https://github.com/Microsoft/vcpkg), Microsoft VC++ Packaging
|
||||
Tool.<br/>
|
||||
You can download and install `EnTT` in just a few simple steps:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/Microsoft/vcpkg.git
|
||||
$ cd vcpkg
|
||||
$ ./bootstrap-vcpkg.sh
|
||||
$ ./vcpkg integrate install
|
||||
$ vcpkg install entt
|
||||
```
|
||||
|
||||
Or you can use the `experimental` feature to test the latest changes:
|
||||
|
||||
```
|
||||
vcpkg install entt[experimental] --head
|
||||
```
|
||||
|
||||
The `EnTT` port in `vcpkg` is kept up to date by Microsoft team members and
|
||||
community contributors.<br/>
|
||||
If the version is out of date, please
|
||||
[create an issue or pull request](https://github.com/Microsoft/vcpkg) on the
|
||||
`vcpkg` repository.
|
||||
|
||||
* [`Homebrew`](https://github.com/skypjack/homebrew-entt), the missing package
|
||||
manager for macOS.<br/>
|
||||
Available as a homebrew formula. Just type the following to install it:
|
||||
|
||||
```
|
||||
brew install skypjack/entt/entt
|
||||
```
|
||||
|
||||
* [`build2`](https://build2.org), build toolchain for developing and packaging C
|
||||
and C++ code.<br/>
|
||||
In order to use the [`entt`](https://cppget.org/entt) package in a `build2`
|
||||
project, add the following line or a similar one to the `manifest` file:
|
||||
|
||||
```
|
||||
depends: entt ^3.0.0
|
||||
```
|
||||
|
||||
Also check that the configuration refers to a valid repository, so that the
|
||||
package can be found by `build2`:
|
||||
|
||||
* [`cppget.org`](https://cppget.org), the open-source community central
|
||||
repository, accessible as `https://pkg.cppget.org/1/stable`.
|
||||
|
||||
* [Package source repository](https://github.com/build2-packaging/entt):
|
||||
accessible as either `https://github.com/build2-packaging/entt.git` or
|
||||
`ssh://git@github.com/build2-packaging/entt.git`.
|
||||
Feel free to [report issues](https://github.com/build2-packaging/entt) with
|
||||
this package.
|
||||
|
||||
Both can be used with `bpkg add-repo` or added in a project
|
||||
`repositories.manifest`. See the official
|
||||
[documentation](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-repositories)
|
||||
for more details.
|
||||
|
||||
* [`bzlmod`](https://bazel.build/external/overview#bzlmod), Bazel's external
|
||||
dependency management system.<br/>
|
||||
To use the [`entt`](https://registry.bazel.build/modules/entt) module in a
|
||||
`bazel` project, add the following to your `MODULE.bazel` file:
|
||||
|
||||
```starlark
|
||||
bazel_dep(name = "entt", version = "3.12.2")
|
||||
```
|
||||
|
||||
EnTT will now be available as `@entt` (short for `@entt//:entt`) to be used
|
||||
in your `cc_*` rule `deps`.
|
||||
|
||||
Consider this list a work in progress and help me to make it longer if you like.
|
||||
|
||||
## pkg-config
|
||||
|
||||
`EnTT` also supports `pkg-config` (for some definition of _supports_ at least).
|
||||
A suitable file called `entt.pc` is generated and installed in a proper
|
||||
directory when running `CMake`.<br/>
|
||||
This should also make it easier to use with tools such as `Meson` or similar.
|
||||
|
||||
# Documentation
|
||||
|
||||
The documentation is based on [doxygen](http://www.doxygen.nl/). To build it:
|
||||
|
||||
$ cd build
|
||||
$ cmake .. -DENTT_BUILD_DOCS=ON
|
||||
$ make
|
||||
|
||||
The API reference is created in HTML format in the `build/docs/html` directory.
|
||||
To navigate it with your favorite browser:
|
||||
|
||||
$ cd build
|
||||
$ your_favorite_browser docs/html/index.html
|
||||
|
||||
The same version is also available [online](https://skypjack.github.io/entt/)
|
||||
for the latest release, that is the last stable tag.<br/>
|
||||
Moreover, there exists a [wiki](https://github.com/skypjack/entt/wiki) dedicated
|
||||
to the project where users can find all related documentation pages.
|
||||
|
||||
# Tests
|
||||
|
||||
To compile and run the tests, `EnTT` requires *googletest*.<br/>
|
||||
`cmake` downloads and compiles the library before compiling anything else. In
|
||||
order to build the tests, set the `CMake` option `ENTT_BUILD_TESTING` to `ON`.
|
||||
|
||||
To build the most basic set of tests:
|
||||
|
||||
* `$ cd build`
|
||||
* `$ cmake -DENTT_BUILD_TESTING=ON ..`
|
||||
* `$ make`
|
||||
* `$ make test`
|
||||
|
||||
Note that benchmarks are not part of this set.
|
||||
|
||||
# EnTT in Action
|
||||
|
||||
`EnTT` is widely used in private and commercial applications. I cannot even
|
||||
mention most of them because of some signatures I put on some documents time
|
||||
ago. Fortunately, there are also people who took the time to implement open
|
||||
source projects based on `EnTT` and did not hold back when it came to
|
||||
documenting them.
|
||||
|
||||
[Here](https://github.com/skypjack/entt/wiki/EnTT-in-Action) you can find an
|
||||
incomplete list of games, applications and articles that can be used as a
|
||||
reference.
|
||||
|
||||
If you know of other resources out there that are about `EnTT`, feel free to
|
||||
open an issue or a PR and I'll be glad to add them to the list.
|
||||
|
||||
# Contributors
|
||||
|
||||
Requests for features, PRs, suggestions and feedback are highly appreciated.
|
||||
|
||||
If you find you can help and want to contribute to the project with your
|
||||
experience or you do want to get part of the project for some other reason, feel
|
||||
free to contact me directly (you can find the mail in the
|
||||
[profile](https://github.com/skypjack)).<br/>
|
||||
I can't promise that each and every contribution will be accepted, but I can
|
||||
assure that I'll do my best to take them all as soon as possible.
|
||||
|
||||
If you decide to participate, please see the guidelines for
|
||||
[contributing](https://github.com/skypjack/entt/blob/master/CONTRIBUTING.md)
|
||||
before to create issues or pull requests.<br/>
|
||||
Take also a look at the
|
||||
[contributors list](https://github.com/skypjack/entt/blob/master/AUTHORS) to
|
||||
know who has participated so far.
|
||||
|
||||
# License
|
||||
|
||||
Code and documentation Copyright (c) 2017-2025 Michele Caini.<br/>
|
||||
Colorful logo Copyright (c) 2018-2021 Richard Caseres.
|
||||
|
||||
Code released under
|
||||
[the MIT license](https://github.com/skypjack/entt/blob/master/LICENSE).<br/>
|
||||
Documentation released under
|
||||
[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).<br/>
|
||||
All logos released under
|
||||
[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
37
lib/All/entt/TODO
Normal file
@@ -0,0 +1,37 @@
|
||||
EXAMPLES
|
||||
* filter on runtime values/variables (not only types)
|
||||
* support to polymorphic types (see #859)
|
||||
|
||||
DOC:
|
||||
* custom storage/view
|
||||
* update entity doc when the storage based model is in place
|
||||
* in-place O(1) release/destroy for non-orphaned entities, out-of-sync model
|
||||
* view: single vs multi type views are no longer a thing actually
|
||||
* bump entities, reserved bits on identifiers
|
||||
|
||||
TODO:
|
||||
* review all NOLINT
|
||||
* bring nested groups back in place (see bd34e7f)
|
||||
* work stealing job system (see #100) + mt scheduler based on const awareness for types
|
||||
* view: reduce inst due to/improve perf with index-based approach in dispatch_get/pick_and_each/each (single type too, define storage ::at and ::at_as_tuple)
|
||||
* view: update natvis as needed after the last rework, merge pools/filter in the same array, drop check (?) and turn view into a position
|
||||
* view: type-only view_iterator (dyn get/excl sizes), type-only basic_common_view (dyn get/excl sizes with pointer to array from derived)
|
||||
* combine version-mask-vs-version-bits tricks with reserved bits to allow things like enabling/disabling
|
||||
* self contained entity traits to avoid explicit specializations (ie enum constants)
|
||||
* auto type info data from types if present
|
||||
* test: push sharing types further
|
||||
* storage entity: fast range-push from above
|
||||
* table: pop back to support swap and pop, single column access, empty type optimization
|
||||
* review cmake warning about FetchContent_Populate (need .28 and EXCLUDE_FROM_ALL for FetchContent)
|
||||
* suppress -Wself-move on CI with g++13
|
||||
* view specializations for multi, single and filtered elements
|
||||
* don't pass reactive storage by default to callback
|
||||
* runtime types support for meta for types that aren't backed by C++ types
|
||||
* built-in no-pagination storage - no_pagination page size as limits::max
|
||||
* any cdynamic to support const ownership construction
|
||||
* allow passing arguments to meta setter/getter (we can fallback on meta invoke probably)
|
||||
* FetchContent_Populate -> FetchContent_MakeAvailable warnings
|
||||
* doc: IMPLICIT_DIR_DOCS for dir docs or \dir
|
||||
* meta non-const allow_cast overloads: (const int &) to (int &) is not allowed, but (const int &) to (double &) is allowed (support only for convertibles)
|
||||
* improve non-const allow cast with in-place switch
|
||||
* meta fixed_size could return the size directly if present
|
||||
1
lib/All/entt/WORKSPACE.bazel
Normal file
@@ -0,0 +1 @@
|
||||
# SEE MODULE.bazel
|
||||
0
lib/All/entt/bazel/BUILD.bazel
Normal file
13
lib/All/entt/bazel/copts.bzl
Normal file
@@ -0,0 +1,13 @@
|
||||
load("@bazel_skylib//lib:selects.bzl", "selects")
|
||||
|
||||
COPTS = selects.with_or({
|
||||
("//conditions:default", "@rules_cc//cc/compiler:clang", "@rules_cc//cc/compiler:gcc", "@rules_cc//cc/compiler:mingw-gcc"): [
|
||||
"-std=c++17",
|
||||
"-w",
|
||||
],
|
||||
("@rules_cc//cc/compiler:msvc-cl", "@rules_cc//cc/compiler:clang-cl"): [
|
||||
"/std:c++17",
|
||||
"/permissive-",
|
||||
"/w",
|
||||
],
|
||||
})
|
||||
2
lib/All/entt/build/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
5
lib/All/entt/cmake/in/EnTTConfig.cmake.in
Normal file
@@ -0,0 +1,5 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set(EnTT_VERSION "@PROJECT_VERSION@")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/EnTTTargets.cmake")
|
||||
check_required_components("@PROJECT_NAME@")
|
||||
8
lib/All/entt/cmake/in/entt.pc.in
Normal file
@@ -0,0 +1,8 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
includedir=@EnTT_PKGCONFIG_INCLUDEDIR@
|
||||
|
||||
Name: EnTT
|
||||
Description: Gaming meets modern C++
|
||||
Url: https://github.com/skypjack/entt
|
||||
Version: @ENTT_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
23
lib/All/entt/cmake/modules/JoinPaths.cmake
Normal file
@@ -0,0 +1,23 @@
|
||||
# This module provides function for joining paths
|
||||
# known from most languages
|
||||
#
|
||||
# SPDX-License-Identifier: (MIT OR CC0-1.0)
|
||||
# Copyright 2020 Jan Tojnar
|
||||
# https://github.com/jtojnar/cmake-snips
|
||||
#
|
||||
# Modelled after Python’s os.path.join
|
||||
# https://docs.python.org/3.7/library/os.path.html#os.path.join
|
||||
# Windows not supported
|
||||
function(join_paths joined_path first_path_segment)
|
||||
set(temp_path "${first_path_segment}")
|
||||
foreach(current_segment IN LISTS ARGN)
|
||||
if(NOT ("${current_segment}" STREQUAL ""))
|
||||
if(IS_ABSOLUTE "${current_segment}")
|
||||
set(temp_path "${current_segment}")
|
||||
else()
|
||||
set(temp_path "${temp_path}/${current_segment}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(${joined_path} "${temp_path}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
37
lib/All/entt/conan/build.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from cpt.packager import ConanMultiPackager
|
||||
import os
|
||||
|
||||
if __name__ == "__main__":
|
||||
username = os.getenv("GITHUB_ACTOR")
|
||||
tag_version = os.getenv("GITHUB_REF")
|
||||
tag_package = os.getenv("GITHUB_REPOSITORY")
|
||||
login_username = os.getenv("CONAN_LOGIN_USERNAME")
|
||||
package_version = tag_version.replace("refs/tags/v", "")
|
||||
package_name = tag_package.replace("skypjack/", "")
|
||||
reference = "{}/{}".format(package_name, package_version)
|
||||
channel = os.getenv("CONAN_CHANNEL", "stable")
|
||||
upload = os.getenv("CONAN_UPLOAD")
|
||||
stable_branch_pattern = os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+.*")
|
||||
test_folder = os.getenv("CPT_TEST_FOLDER", os.path.join("conan", "test_package"))
|
||||
upload_only_when_stable = os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", True)
|
||||
disable_shared = os.getenv("CONAN_DISABLE_SHARED_BUILD", "False")
|
||||
|
||||
builder = ConanMultiPackager(username=username,
|
||||
reference=reference,
|
||||
channel=channel,
|
||||
login_username=login_username,
|
||||
upload=upload,
|
||||
stable_branch_pattern=stable_branch_pattern,
|
||||
upload_only_when_stable=upload_only_when_stable,
|
||||
test_folder=test_folder)
|
||||
builder.add()
|
||||
|
||||
filtered_builds = []
|
||||
for settings, options, env_vars, build_requires, reference in builder.items:
|
||||
if disable_shared == "False" or not options["{}:shared".format(package_name)]:
|
||||
filtered_builds.append([settings, options, env_vars, build_requires])
|
||||
builder.builds = filtered_builds
|
||||
|
||||
builder.run()
|
||||
7
lib/All/entt/conan/ci/build.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
conan user
|
||||
python conan/build.py
|
||||
6
lib/All/entt/conan/ci/install.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
pip install -U conan_package_tools conan
|
||||
13
lib/All/entt/conan/test_package/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.7.2)
|
||||
project(test_package)
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE TRUE)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||
conan_basic_setup()
|
||||
|
||||
add_executable(${PROJECT_NAME} test_package.cpp)
|
||||
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
|
||||
19
lib/All/entt/conan/test_package/conanfile.py
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from conans import ConanFile, CMake
|
||||
import os
|
||||
|
||||
|
||||
class TestPackageConan(ConanFile):
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
generators = "cmake"
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
cmake.build()
|
||||
|
||||
def test(self):
|
||||
bin_path = os.path.join("bin", "test_package")
|
||||
self.run(bin_path, run_environment=True)
|
||||
56
lib/All/entt/conan/test_package/test_package.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <entt/entt.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
struct position {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct velocity {
|
||||
float dx;
|
||||
float dy;
|
||||
};
|
||||
|
||||
void update(entt::registry ®istry) {
|
||||
auto view = registry.view<position, velocity>();
|
||||
|
||||
for(auto entity: view) {
|
||||
// gets only the elements that are going to be used ...
|
||||
|
||||
auto &vel = view.get<velocity>(entity);
|
||||
|
||||
vel.dx = 0.;
|
||||
vel.dy = 0.;
|
||||
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
void update(std::uint64_t dt, entt::registry ®istry) {
|
||||
registry.view<position, velocity>().each([dt](auto &pos, auto &vel) {
|
||||
// gets all the elements of the view at once ...
|
||||
|
||||
pos.x += vel.dx * dt;
|
||||
pos.y += vel.dy * dt;
|
||||
|
||||
// ...
|
||||
});
|
||||
}
|
||||
|
||||
int main() {
|
||||
entt::registry registry;
|
||||
std::uint64_t dt = 16;
|
||||
|
||||
for(auto i = 0; i < 10; ++i) {
|
||||
auto entity = registry.create();
|
||||
registry.emplace<position>(entity, i * 1.f, i * 1.f);
|
||||
if(i % 2 == 0) { registry.emplace<velocity>(entity, i * .1f, i * .1f); }
|
||||
}
|
||||
|
||||
update(dt, registry);
|
||||
update(registry);
|
||||
|
||||
// ...
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
27
lib/All/entt/conanfile.py
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from conans import ConanFile
|
||||
|
||||
|
||||
class EnttConan(ConanFile):
|
||||
name = "entt"
|
||||
description = "Gaming meets modern C++ - a fast and reliable entity-component system (ECS) and much more "
|
||||
topics = ("conan," "entt", "gaming", "entity", "ecs")
|
||||
url = "https://github.com/skypjack/entt"
|
||||
homepage = url
|
||||
author = "Michele Caini <michele.caini@gmail.com>"
|
||||
license = "MIT"
|
||||
exports = ["LICENSE"]
|
||||
exports_sources = ["src/*"]
|
||||
no_copy_source = True
|
||||
|
||||
def package(self):
|
||||
self.copy(pattern="LICENSE", dst="licenses")
|
||||
self.copy(pattern="*", dst="include", src="src", keep_path=True)
|
||||
|
||||
def package_info(self):
|
||||
if not self.in_local_cache:
|
||||
self.cpp_info.includedirs = ["src"]
|
||||
|
||||
def package_id(self):
|
||||
self.info.header_only()
|
||||
59
lib/All/entt/docs/CMakeLists.txt
Normal file
@@ -0,0 +1,59 @@
|
||||
# Doxygen configuration (documentation)
|
||||
|
||||
find_package(Doxygen 1.13)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
doxygen-awesome-css
|
||||
GIT_REPOSITORY https://github.com/jothepro/doxygen-awesome-css
|
||||
GIT_TAG main
|
||||
GIT_SHALLOW 1
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(doxygen-awesome-css)
|
||||
|
||||
if(NOT doxygen-awesome-css_POPULATED)
|
||||
FetchContent_Populate(doxygen-awesome-css)
|
||||
set(doxygen-awesome-css_INCLUDE_DIR ${doxygen-awesome-css_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
set(DOXY_SOURCE_DIRECTORY ${EnTT_SOURCE_DIR}/src)
|
||||
set(DOXY_CSS_DIRECTORY ${doxygen-awesome-css_INCLUDE_DIR})
|
||||
set(DOXY_DOCS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(DOXY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
configure_file(doxy.in doxy.cfg @ONLY)
|
||||
|
||||
add_custom_target(
|
||||
docs ALL
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.cfg
|
||||
WORKING_DIRECTORY ${EnTT_SOURCE_DIR}
|
||||
VERBATIM
|
||||
SOURCES
|
||||
md/config.md
|
||||
md/container.md
|
||||
md/core.md
|
||||
md/entity.md
|
||||
md/faq.md
|
||||
md/lib.md
|
||||
md/links.md
|
||||
md/locator.md
|
||||
md/meta.md
|
||||
md/poly.md
|
||||
md/process.md
|
||||
md/reference.md
|
||||
md/resource.md
|
||||
md/signal.md
|
||||
md/unreal.md
|
||||
doxy.in
|
||||
)
|
||||
|
||||
if(ENTT_INSTALL)
|
||||
install(
|
||||
DIRECTORY ${DOXY_OUTPUT_DIRECTORY}/html
|
||||
DESTINATION share/${PROJECT_NAME}-${PROJECT_VERSION}/
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
2914
lib/All/entt/docs/doxy.in
Normal file
115
lib/All/entt/docs/md/config.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Crash Course: configuration
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Definitions](#definitions)
|
||||
* [ENTT_NOEXCEPTION](#entt_noexception)
|
||||
* [ENTT_USE_ATOMIC](#entt_use_atomic)
|
||||
* [ENTT_ID_TYPE](#entt_id_type)
|
||||
* [ENTT_SPARSE_PAGE](#entt_sparse_page)
|
||||
* [ENTT_PACKED_PAGE](#entt_packed_page)
|
||||
* [ENTT_ASSERT](#entt_assert)
|
||||
* [ENTT_ASSERT_CONSTEXPR](#entt_assert_constexpr)
|
||||
* [ENTT_DISABLE_ASSERT](#entt_disable_assert)
|
||||
* [ENTT_NO_ETO](#entt_no_eto)
|
||||
* [ENTT_STANDARD_CPP](#entt_standard_cpp)
|
||||
|
||||
# Introduction
|
||||
|
||||
`EnTT` has become almost completely customizable over time, in many
|
||||
respects. These variables are just one of the many ways to customize how it
|
||||
works.<br/>
|
||||
In the vast majority of cases, users will have no interest in changing the
|
||||
default parameters. For all other cases, the list of possible configurations
|
||||
with which it is possible to adjust the behavior of the library at runtime can
|
||||
be found below.
|
||||
|
||||
# Definitions
|
||||
|
||||
All options are intended as parameters to the compiler (or user-defined macros
|
||||
within the compilation units, if preferred).<br/>
|
||||
Each parameter can result in internal library definitions. It is not recommended
|
||||
to try to also modify these definitions, since there is no guarantee that they
|
||||
will remain stable over time unlike the options below.
|
||||
|
||||
## ENTT_NOEXCEPTION
|
||||
|
||||
Define this variable without assigning any value to it to turn off exception
|
||||
handling in `EnTT`.<br/>
|
||||
This is roughly equivalent to setting the compiler flag `-fno-exceptions` but is
|
||||
also limited to this library only.
|
||||
|
||||
## ENTT_USE_ATOMIC
|
||||
|
||||
In general, `EnTT` does not offer primitives to support multi-threading. Many of
|
||||
the features can be split over multiple threads without any explicit control and
|
||||
the user is the one who knows if a synchronization point is required.<br/>
|
||||
However, some features are not easily accessible to users and are made
|
||||
thread-safe by means of this definition.
|
||||
|
||||
## ENTT_ID_TYPE
|
||||
|
||||
`entt::id_type` is directly controlled by this definition and widely used within
|
||||
the library.<br/>
|
||||
By default, its type is `std::uint32_t`. However, users can define a different
|
||||
default type if necessary.
|
||||
|
||||
## ENTT_SPARSE_PAGE
|
||||
|
||||
It is known that the ECS module of `EnTT` is based on _sparse sets_. What is
|
||||
less known perhaps is that the sparse arrays are paged to reduce memory
|
||||
usage.<br/>
|
||||
Default size of pages (that is, the number of elements they contain) is 4096 but
|
||||
users can adjust it if appropriate. In all cases, the chosen value **must** be a
|
||||
power of 2.
|
||||
|
||||
## ENTT_PACKED_PAGE
|
||||
|
||||
As it happens with sparse arrays, packed arrays are also paginated. However, in
|
||||
this case the aim is not to reduce memory usage but to have pointer stability
|
||||
upon component creation.<br/>
|
||||
Default size of pages (that is, the number of elements they contain) is 1024 but
|
||||
users can adjust it if appropriate. In all cases, the chosen value **must** be a
|
||||
power of 2.
|
||||
|
||||
## ENTT_ASSERT
|
||||
|
||||
For performance reasons, `EnTT` does not use exceptions or any other control
|
||||
structures. In fact, it offers many features that result in undefined behavior
|
||||
if not used correctly.<br/>
|
||||
To get around this, the library relies on a lot of asserts for the purpose of
|
||||
detecting errors in debug builds. By default, it uses `assert` internally. Users
|
||||
are allowed to overwrite its behavior by setting this variable.
|
||||
|
||||
### ENTT_ASSERT_CONSTEXPR
|
||||
|
||||
Usually, an assert within a `constexpr` function is not a big deal. However, in
|
||||
case of extreme customizations, it might be useful to differentiate.<br/>
|
||||
For this purpose, `EnTT` introduces an admittedly badly named variable to make
|
||||
the job easier in this regard. By default, this variable forwards its arguments
|
||||
to `ENTT_ASSERT`.
|
||||
|
||||
### ENTT_DISABLE_ASSERT
|
||||
|
||||
Assertions may in turn affect performance to an extent when enabled. Whether
|
||||
`ENTT_ASSERT` and `ENTT_ASSERT_CONSTEXPR` are redefined or not, all asserts can
|
||||
be disabled at once by means of this definition.<br/>
|
||||
Note that `ENTT_DISABLE_ASSERT` takes precedence over the redefinition of the
|
||||
other variables and is therefore meant to disable all controls no matter what.
|
||||
|
||||
## ENTT_NO_ETO
|
||||
|
||||
In order to reduce memory consumption and increase performance, empty types are
|
||||
never instantiated nor stored by the ECS module of `EnTT`.<br/>
|
||||
Use this variable to treat these types like all others and therefore to create a
|
||||
dedicated storage for them.
|
||||
|
||||
## ENTT_STANDARD_CPP
|
||||
|
||||
`EnTT` mixes non-standard language features with others that are perfectly
|
||||
compliant to offer some of its functionalities.<br/>
|
||||
This definition prevents the library from using non-standard techniques, that
|
||||
is, functionalities that are not fully compliant with the standard C++.<br/>
|
||||
While there are no known portability issues at the time of this writing, this
|
||||
should make the library fully portable anyway if needed.
|
||||
85
lib/All/entt/docs/md/container.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Crash Course: containers
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Containers](#containers)
|
||||
* [Dense map](#dense-map)
|
||||
* [Dense set](#dense-set)
|
||||
* [Adaptors](#adaptors)
|
||||
* [Table](#table)
|
||||
|
||||
# Introduction
|
||||
|
||||
The standard C++ library offers a wide range of containers and adaptors already.
|
||||
It is really difficult to do better (although it is very easy to do worse, as
|
||||
many examples available online demonstrate).<br/>
|
||||
`EnTT` does not try in any way to replace what is offered by the standard. Quite
|
||||
the opposite, given the widespread use that is made of standard containers.<br/>
|
||||
However, the library also tries to fill a gap in features and functionalities by
|
||||
making available some containers and adaptors initially developed for internal
|
||||
use.
|
||||
|
||||
This section of the library is likely to grow larger over time. However, for the
|
||||
moment it is quite small and mainly aimed at satisfying some internal
|
||||
needs.<br/>
|
||||
For all containers and adaptors made available, full test coverage and stability
|
||||
over time is guaranteed as usual.
|
||||
|
||||
# Containers
|
||||
|
||||
## Dense map
|
||||
|
||||
The dense map made available in `EnTT` is a hash map that aims to return a
|
||||
packed array of elements, so as to reduce the number of jumps in memory during
|
||||
iterations.<br/>
|
||||
The implementation is based on _sparse sets_ and each bucket is identified by an
|
||||
implicit list within the packed array itself.
|
||||
|
||||
The interface is very close to its counterpart in the standard library, that is,
|
||||
the `std::unordered_map` class.<br/>
|
||||
However, both local and non-local iterators returned by a dense map belong to
|
||||
the input iterator category although they respectively model the concepts of a
|
||||
_forward iterator_ type and a _random access iterator_ type.<br/>
|
||||
This is because they return a pair of references rather than a reference to a
|
||||
pair. In other words, dense maps return a so called _proxy iterator_ the value
|
||||
type of which is:
|
||||
|
||||
* `std::pair<const Key &, Type &>` for non-const iterator types.
|
||||
* `std::pair<const Key &, const Type &>` for const iterator types.
|
||||
|
||||
This is quite different from what any standard library map returns and should be
|
||||
taken into account when looking for a drop-in replacement.
|
||||
|
||||
## Dense set
|
||||
|
||||
The dense set made available in `EnTT` is a hash set that aims to return a
|
||||
packed array of elements, so as to reduce the number of jumps in memory during
|
||||
iterations.<br/>
|
||||
The implementation is based on _sparse sets_ and each bucket is identified by an
|
||||
implicit list within the packed array itself.
|
||||
|
||||
The interface is in all respects similar to its counterpart in the standard
|
||||
library, that is, the `std::unordered_set` class.<br/>
|
||||
However, this type of set also supports reverse iteration and therefore offers
|
||||
all the functions necessary for the purpose (such as `rbegin` and `rend`).
|
||||
|
||||
# Adaptors
|
||||
|
||||
## Table
|
||||
|
||||
The `basic_table` class is a container adaptor which manages multiple sequential
|
||||
containers together, treating them as different columns of the same table.<br/>
|
||||
The `table` alias allows users to provide only the types to handle, using
|
||||
`std::vector` as the default sequential container.
|
||||
|
||||
Only a small set of functions is provided, although very close to what the API
|
||||
of the `std::vector` class offers.<br/>
|
||||
The internal implementation is purposely supported by a tuple of containers
|
||||
rather than a container of tuples. The purpose is to allow efficient access to
|
||||
single columns and not just access to the entire data set of the table.
|
||||
|
||||
When a row is accessed, all data is returned in the form of a tuple containing
|
||||
(possibly const) references to the elements of the row itself.<br/>
|
||||
Similarly, when a table is iterated, tuples of references to table elements are
|
||||
returned for each row.
|
||||
986
lib/All/entt/docs/md/core.md
Normal file
@@ -0,0 +1,986 @@
|
||||
# Crash Course: core functionalities
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Any as in any type](#any-as-in-any-type)
|
||||
* [Small buffer optimization](#small-buffer-optimization)
|
||||
* [Alignment requirement](#alignment-requirement)
|
||||
* [Bit](#bit)
|
||||
* [Compressed pair](#compressed-pair)
|
||||
* [Enum as bitmask](#enum-as-bitmask)
|
||||
* [Hashed strings](#hashed-strings)
|
||||
* [Wide characters](#wide-characters)
|
||||
* [Conflicts](#conflicts)
|
||||
* [Iterators](#iterators)
|
||||
* [Input iterator pointer](#input-iterator-pointer)
|
||||
* [Iota iterator](#iota-iterator)
|
||||
* [Iterable adaptor](#iterable-adaptor)
|
||||
* [Memory](#memory)
|
||||
* [Allocator aware unique pointers](#allocator-aware-unique-pointers)
|
||||
* [Monostate](#monostate)
|
||||
* [Type support](#type-support)
|
||||
* [Built-in RTTI support](#built-in-rtti-support)
|
||||
* [Type info](#type-info)
|
||||
* [Almost unique identifiers](#almost-unique-identifiers)
|
||||
* [Type traits](#type-traits)
|
||||
* [Size of](#size-of)
|
||||
* [Is applicable](#is-applicable)
|
||||
* [Constness as](#constness-as)
|
||||
* [Member class type](#member-class-type)
|
||||
* [N-th argument](#n-th-argument)
|
||||
* [Integral constant](#integral-constant)
|
||||
* [Tag](#tag)
|
||||
* [Type list and value list](#type-list-and-value-list)
|
||||
* [Unique sequential identifiers](#unique-sequential-identifiers)
|
||||
* [Compile-time generator](#compile-time-generator)
|
||||
* [Runtime generator](#runtime-generator)
|
||||
* [Utilities](#utilities)
|
||||
|
||||
# Introduction
|
||||
|
||||
`EnTT` comes with a bunch of core functionalities mostly used by the other parts
|
||||
of the library.<br/>
|
||||
Many of these tools are also useful in everyday work. Therefore, it is worth
|
||||
describing them so as not to reinvent the wheel in case of need.
|
||||
|
||||
# Any as in any type
|
||||
|
||||
`EnTT` offers its own `any` type. It may seem redundant considering that C++17
|
||||
introduced `std::any`, but it is not (hopefully).<br/>
|
||||
First of all, the _type_ returned by an `std::any` is a const reference to an
|
||||
`std::type_info`, an implementation defined class that is not something everyone
|
||||
wants to see in a software. Furthermore, there is no way to bind it to the type
|
||||
system of the library and therefore with its integrated RTTI support.
|
||||
|
||||
The `any` API is very similar to that of its most famous counterpart, mainly
|
||||
because this class serves the same purpose of being an opaque container for any
|
||||
type of value.<br/>
|
||||
Instances also minimize the number of allocations by relying on a well known
|
||||
technique called _small buffer optimization_ and a fake vtable.
|
||||
|
||||
Creating an object of the `any` type, whether empty or not, is trivial:
|
||||
|
||||
```cpp
|
||||
// an empty container
|
||||
entt::any empty{};
|
||||
|
||||
// a container for an int
|
||||
entt::any any{0};
|
||||
|
||||
// in place type construction
|
||||
entt::any in_place_type{std::in_place_type<int>, 42};
|
||||
|
||||
// take ownership of already existing, dynamically allocated objects
|
||||
entt::any in_place{std::in_place, std::make_unique<int>(42).release()};
|
||||
```
|
||||
|
||||
Alternatively, the `make_any` function serves the same purpose. It requires to
|
||||
always be explicit about the type and does not support taking ownership:
|
||||
|
||||
```cpp
|
||||
entt::any any = entt::make_any<int>(42);
|
||||
```
|
||||
|
||||
In all cases, the `any` class takes the burden of destroying the contained
|
||||
element when required, regardless of the storage strategy used for the specific
|
||||
object.<br/>
|
||||
Furthermore, an instance of `any` is not tied to an actual type. Therefore, the
|
||||
wrapper is reconfigured when it is assigned a new object of a type other than
|
||||
the one it contains.
|
||||
|
||||
There is also a way to directly assign a value to the variable contained by an
|
||||
`entt::any`, without necessarily replacing it. This is especially useful when
|
||||
the object is used in _aliasing mode_, as described below:
|
||||
|
||||
```cpp
|
||||
entt::any any{42};
|
||||
entt::any value{3};
|
||||
|
||||
// assigns by copy
|
||||
any.assign(value);
|
||||
|
||||
// assigns by move
|
||||
any.assign(std::move(value));
|
||||
```
|
||||
|
||||
The `any` class performs a check on the type information and whether or not the
|
||||
original type was copy or move assignable, as appropriate.<br/>
|
||||
In all cases, the `assign` function returns a boolean value that is true in case
|
||||
of success and false otherwise.
|
||||
|
||||
When in doubt about the type of object contained, the `type` member function
|
||||
returns a const reference to the `type_info` associated with its element, or
|
||||
`type_id<void>()` if the container is empty.<br/>
|
||||
The type is also used internally when comparing two `any` objects:
|
||||
|
||||
```cpp
|
||||
if(any == empty) { /* ... */ }
|
||||
```
|
||||
|
||||
In this case, before proceeding with a comparison, it is verified that the
|
||||
_type_ of the two objects is actually the same.<br/>
|
||||
Refer to the `EnTT` type system documentation for more details about how
|
||||
`type_info` works and the possible risks of a comparison.
|
||||
|
||||
A particularly interesting feature of this class is that it can also be used as
|
||||
an opaque container for const and non-const references:
|
||||
|
||||
```cpp
|
||||
int value = 42;
|
||||
|
||||
entt::any any{std::in_place_type<int &>(value)};
|
||||
entt::any cany = entt::make_any<const int &>(value);
|
||||
entt::any fwd = entt::forward_as_any(value);
|
||||
|
||||
any.emplace<const int &>(value);
|
||||
```
|
||||
|
||||
In other words, whenever `any` is explicitly told to construct an _alias_, it
|
||||
acts as a pointer to the original instance rather than making a copy of it or
|
||||
moving it internally. The contained object is never destroyed, and users must
|
||||
ensure that its lifetime exceeds that of the container.<br/>
|
||||
Similarly, it is possible to create non-owning copies of `any` from an existing
|
||||
object:
|
||||
|
||||
```cpp
|
||||
// aliasing constructor
|
||||
entt::any ref = other.as_ref();
|
||||
```
|
||||
|
||||
In this case, it does not matter if the original container actually holds an
|
||||
object or is as a reference for unmanaged elements already. The new instance
|
||||
thus created does not create copies and only serves as a reference for the
|
||||
original item.
|
||||
|
||||
It is worth mentioning that, while everything works transparently when it comes
|
||||
to non-const references, there are some exceptions when it comes to const
|
||||
references.<br/>
|
||||
In particular, the `data` member function invoked on a non-const instance of
|
||||
`any` that wraps a const reference returns a null pointer in all cases.
|
||||
|
||||
To cast an instance of `any` to a type, the library offers a set of `any_cast`
|
||||
functions in all respects similar to their most famous counterparts.<br/>
|
||||
The only difference is that, in the case of `EnTT`, they will not raise
|
||||
exceptions but will only trigger an assert in debug mode, otherwise resulting in
|
||||
undefined behavior in case of misuse in release mode.
|
||||
|
||||
## Small buffer optimization
|
||||
|
||||
The `any` class uses a technique called _small buffer optimization_ to reduce
|
||||
the number of allocations where possible.<br/>
|
||||
The default reserved size for an instance of `any` is `sizeof(double[2])`.
|
||||
However, this is also configurable if needed. In fact, `any` is defined as an
|
||||
alias for `basic_any<Len>`, where `Len` is the size above.<br/>
|
||||
Users can easily set a custom size or define their own aliases:
|
||||
|
||||
```cpp
|
||||
using my_any = entt::basic_any<sizeof(double[4])>;
|
||||
```
|
||||
|
||||
This feature, in addition to allowing the choice of a size that best suits the
|
||||
needs of an application, also offers the possibility of forcing dynamic creation
|
||||
of objects during construction.<br/>
|
||||
In other terms, if the size is 0, `any` suppresses the small buffer optimization
|
||||
and always dynamically allocates objects (except for aliasing cases).
|
||||
|
||||
## Alignment requirement
|
||||
|
||||
The alignment requirement is optional and by default the most stringent (the
|
||||
largest) for any object whose size is at most equal to the one provided.<br/>
|
||||
It is provided as an optional second parameter following the desired size for
|
||||
the internal storage:
|
||||
|
||||
```cpp
|
||||
using my_any = entt::basic_any<sizeof(double[4]), alignof(double[4])>;
|
||||
```
|
||||
|
||||
The `basic_any` class template inspects the alignment requirements in each case,
|
||||
even when not provided and may decide not to use the small buffer optimization
|
||||
in order to meet them.
|
||||
|
||||
# Bit
|
||||
|
||||
Finding out the population count of an unsigned integral value (`popcount`),
|
||||
whether a number is a power of two or not (`has_single_bit`) as well as the next
|
||||
power of two given a random value (`next_power_of_two`) can be useful.<br/>
|
||||
For example, it helps to allocate memory in pages having a size suitable for the
|
||||
fast modulus:
|
||||
|
||||
```cpp
|
||||
const std::size_t result = entt::fast_mod(value, modulus);
|
||||
```
|
||||
|
||||
Where `modulus` is necessarily a power of two. Perhaps not everyone knows that
|
||||
this type of operation is far superior in terms of performance to the basic
|
||||
modulus and for this reason preferred in many areas.
|
||||
|
||||
# Compressed pair
|
||||
|
||||
Primarily designed for internal use and far from being feature complete, the
|
||||
`compressed_pair` class does exactly what it promises: it tries to reduce the
|
||||
size of a pair by exploiting _Empty Base Class Optimization_ (or _EBCO_).<br/>
|
||||
This class **is not** a drop-in replacement for `std::pair`. However, it offers
|
||||
enough functionalities to be a good alternative for when reducing memory usage
|
||||
is more important than having some cool and probably useless feature.
|
||||
|
||||
Although the API is very close to that of `std::pair` (apart from the fact that
|
||||
the template parameters are inferred from the constructor and therefore there is
|
||||
no `entt::make_compressed_pair`), the major difference is that `first` and
|
||||
`second` are functions for implementation requirements:
|
||||
|
||||
```cpp
|
||||
entt::compressed_pair pair{0, 3.};
|
||||
pair.first() = 42;
|
||||
```
|
||||
|
||||
There is not much to describe then. It is recommended to rely on documentation
|
||||
and intuition. At the end of the day, it is just a pair and nothing more.
|
||||
|
||||
# Enum as bitmask
|
||||
|
||||
Sometimes it is useful to be able to use enums as bitmasks. However, enum
|
||||
classes are not really suitable for the purpose. Main problem is that they do
|
||||
not convert implicitly to their underlying type.<br/>
|
||||
The choice is then between using old-fashioned enums (with all their problems
|
||||
that I do not want to discuss here) or writing _ugly_ code.
|
||||
|
||||
Fortunately, there is also a third way: adding enough operators in the global
|
||||
scope to treat enum classes as bitmasks transparently.<br/>
|
||||
The ultimate goal is to write code like the following (or maybe something more
|
||||
meaningful, but this should give a grasp and remain simple at the same time):
|
||||
|
||||
```cpp
|
||||
enum class my_flag {
|
||||
unknown = 0x01,
|
||||
enabled = 0x02,
|
||||
disabled = 0x04
|
||||
};
|
||||
|
||||
const my_flag flags = my_flag::enabled;
|
||||
const bool is_enabled = !!(flags & my_flag::enabled);
|
||||
```
|
||||
|
||||
The problem with adding all operators to the global scope is that these come
|
||||
into play even when not required, with the risk of introducing errors that are
|
||||
difficult to deal with.<br/>
|
||||
However, C++ offers enough tools to get around this problem. In particular, the
|
||||
library requires users to register the enum classes for which bitmask support
|
||||
should be enabled:
|
||||
|
||||
```cpp
|
||||
template<>
|
||||
struct entt::enum_as_bitmask<my_flag>
|
||||
: std::true_type
|
||||
{};
|
||||
```
|
||||
|
||||
This is handy when dealing with enum classes defined by third party libraries
|
||||
and over which the user has no control. However, it is also verbose and can be
|
||||
avoided by adding a specific value to the enum class itself:
|
||||
|
||||
```cpp
|
||||
enum class my_flag {
|
||||
unknown = 0x01,
|
||||
enabled = 0x02,
|
||||
disabled = 0x04,
|
||||
_entt_enum_as_bitmask
|
||||
};
|
||||
```
|
||||
|
||||
In this case, there is no need to specialize the `enum_as_bitmask` traits, since
|
||||
`EnTT` automatically detects the flag and enables the bitmask support.<br/>
|
||||
Once the enum class is registered (in one way or the other), the most common
|
||||
operators such as `&`, `|` but also `&=` and `|=` are available for use.
|
||||
|
||||
Refer to the official documentation for the full list of operators.
|
||||
|
||||
# Hashed strings
|
||||
|
||||
Hashed strings are human-readable identifiers in the codebase that turn into
|
||||
numeric values at runtime, thus without affecting performance.<br/>
|
||||
The class has an implicit `constexpr` constructor that chews a bunch of
|
||||
characters. Once created, one can get the original string by means of the `data`
|
||||
member function or convert the instance into a number.<br/>
|
||||
A hashed string is well suited wherever a constant expression is required. No
|
||||
_string-to-number_ conversion will take place at runtime if used carefully.
|
||||
|
||||
Example of use:
|
||||
|
||||
```cpp
|
||||
auto load(entt::hashed_string::hash_type resource) {
|
||||
// uses the numeric representation of the resource to load and return it
|
||||
}
|
||||
|
||||
auto resource = load(entt::hashed_string{"gui/background"});
|
||||
```
|
||||
|
||||
There is also a _user defined literal_ dedicated to hashed strings to make them
|
||||
more _user-friendly_:
|
||||
|
||||
```cpp
|
||||
using namespace entt::literals;
|
||||
constexpr auto str = "text"_hs;
|
||||
```
|
||||
|
||||
User defined literals in `EnTT` are enclosed in the `entt::literals` namespace.
|
||||
Therefore, the entire namespace or selectively the literal of interest must be
|
||||
explicitly included before each use, a bit like `std::literals`.<br/>
|
||||
The class also offers the necessary functionalities to create hashed strings at
|
||||
runtime:
|
||||
|
||||
```cpp
|
||||
std::string orig{"text"};
|
||||
|
||||
// create a full-featured hashed string...
|
||||
entt::hashed_string str{orig.c_str()};
|
||||
|
||||
// ... or compute only the unique identifier
|
||||
const auto hash = entt::hashed_string::value(orig.c_str());
|
||||
```
|
||||
|
||||
This possibility should not be exploited in tight loops, since the computation
|
||||
takes place at runtime and no longer at compile-time. It could therefore affect
|
||||
performance to some degrees.
|
||||
|
||||
## Wide characters
|
||||
|
||||
The `hashed_string` class is an alias for `basic_hashed_string<char>`. To use
|
||||
the C++ type for wide character representations, there exists also the alias
|
||||
`hashed_wstring` for `basic_hashed_string<wchar_t>`.<br/>
|
||||
In this case, the user defined literal to use to create hashed strings on the
|
||||
fly is `_hws`:
|
||||
|
||||
```cpp
|
||||
constexpr auto str = L"text"_hws;
|
||||
```
|
||||
|
||||
The hash type of `hashed_wstring` is the same as its counterpart.
|
||||
|
||||
## Conflicts
|
||||
|
||||
The hashed string class uses FNV-1a internally to hash strings. Because of the
|
||||
_pigeonhole principle_, conflicts are possible. This is a fact.<br/>
|
||||
There is no silver bullet to solve the problem of conflicts when dealing with
|
||||
hashing functions. In this case, the best solution is likely to give up. That is
|
||||
all.<br/>
|
||||
After all, human-readable unique identifiers are not something strictly defined
|
||||
and over which users have not the control. Choosing a slightly different
|
||||
identifier is probably the best solution to make the conflict disappear in this
|
||||
case.
|
||||
|
||||
# Iterators
|
||||
|
||||
Writing and working with iterators is not always easy. More often than not it
|
||||
also leads to duplicated code.<br/>
|
||||
`EnTT` tries to overcome this problem by offering some utilities designed to
|
||||
make this hard work easier.
|
||||
|
||||
## Input iterator pointer
|
||||
|
||||
When writing an input iterator that returns in-place constructed values if
|
||||
dereferenced, it is not always straightforward to figure out what `value_type`
|
||||
is and how to make it behave like a full-fledged pointer.<br/>
|
||||
Conversely, it would be very useful to have an `operator->` available on the
|
||||
iterator itself that always works without too much complexity.
|
||||
|
||||
The input iterator pointer is meant for this. It is a small class that wraps the
|
||||
in-place constructed value and adds some functions on top of it to make it
|
||||
suitable for use with input iterators:
|
||||
|
||||
```cpp
|
||||
struct iterator_type {
|
||||
using value_type = std::pair<first_type, second_type>;
|
||||
using pointer = input_iterator_pointer<value_type>;
|
||||
using reference = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The library makes extensive use of this class internally. In many cases, the
|
||||
`value_type` of the returned iterators is just an input iterator pointer.
|
||||
|
||||
## Iota iterator
|
||||
|
||||
Waiting for C++20, this iterator accepts an integral value and returns all
|
||||
elements in a certain range:
|
||||
|
||||
```cpp
|
||||
entt::iota_iterator first{0};
|
||||
entt::iota_iterator last{100};
|
||||
|
||||
for(; first != last; ++first) {
|
||||
int value = *first;
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
In the future, views will replace this class. Meanwhile, the library makes some
|
||||
interesting uses of it when a range of integral values is to be returned to the
|
||||
user.
|
||||
|
||||
## Iterable adaptor
|
||||
|
||||
Typically, a container class provides `begin` and `end` member functions (with
|
||||
their const counterparts) for iteration.<br/>
|
||||
However, it can happen that a class offers multiple iteration methods or allows
|
||||
users to iterate different sets of _elements_.
|
||||
|
||||
The iterable adaptor is a utility class that makes it easier to use and access
|
||||
data in this case.<br/>
|
||||
It accepts a couple of iterators (or an iterator and a sentinel) and offers an
|
||||
_iterable_ object with all the expected methods like `begin`, `end` and whatnot.
|
||||
|
||||
The library uses this class extensively.<br/>
|
||||
Think for example of views, which can be iterated to access entities but also
|
||||
offer a method for obtaining an iterable object that returns tuples of entities
|
||||
and components at once.<br/>
|
||||
Another example is the registry class which allows users to iterate its storage
|
||||
by returning an iterable object for the purpose.
|
||||
|
||||
# Memory
|
||||
|
||||
There are a handful of tools within `EnTT` to interact with memory in one way or
|
||||
another.<br/>
|
||||
Some are geared towards simplifying the implementation of (internal or external)
|
||||
allocator aware containers. Others are designed to help the developer with
|
||||
everyday problems.
|
||||
|
||||
The former are very specific and for niche problems. These are tools designed to
|
||||
unwrap fancy or plain pointers (`to_address`) or to help forget the meaning of
|
||||
acronyms like _POCCA_, _POCMA_ or _POCS_.<br/>
|
||||
I will not describe them here in detail. Instead, I recommend reading the inline
|
||||
documentation to those interested in the subject.
|
||||
|
||||
## Allocator aware unique pointers
|
||||
|
||||
A nasty thing in C++ (at least up to C++20) is the fact that shared pointers
|
||||
support allocators while unique pointers do not.<br/>
|
||||
There is a proposal at the moment that also shows (among the other things) how
|
||||
this can be implemented without any compiler support.
|
||||
|
||||
The `allocate_unique` function follows this proposal, making a virtue out of
|
||||
necessity:
|
||||
|
||||
```cpp
|
||||
std::unique_ptr<my_type, entt::allocation_deleter<my_type>> ptr = entt::allocate_unique<my_type>(allocator, arguments);
|
||||
```
|
||||
|
||||
Although the internal implementation is slightly different from what is proposed
|
||||
for the standard, this function offers an API that is a drop-in replacement for
|
||||
the same feature.
|
||||
|
||||
# Monostate
|
||||
|
||||
The monostate pattern is often presented as an alternative to a singleton based
|
||||
configuration system.<br/>
|
||||
This is exactly its purpose in `EnTT`. Moreover, this implementation is thread
|
||||
safe by design (hopefully).
|
||||
|
||||
Keys are integral values (easily obtained by hashed strings), values are basic
|
||||
types like `int`s or `bool`s. Values of different types can be associated with
|
||||
each key, even more than one at a time.<br/>
|
||||
Because of this, one should pay attention to use the same type both during an
|
||||
assignment and when trying to read back the data. Otherwise, there is the risk
|
||||
to incur in unexpected results.
|
||||
|
||||
Example of use:
|
||||
|
||||
```cpp
|
||||
entt::monostate<entt::hashed_string{"mykey"}>{} = true;
|
||||
entt::monostate<"mykey"_hs>{} = 42;
|
||||
|
||||
// ...
|
||||
|
||||
const bool b = entt::monostate<"mykey"_hs>{};
|
||||
const int i = entt::monostate<entt::hashed_string{"mykey"}>{};
|
||||
```
|
||||
|
||||
# Type support
|
||||
|
||||
`EnTT` provides some basic information about types of all kinds.<br/>
|
||||
It also offers additional features that are not yet available in the standard
|
||||
library or that will never be.
|
||||
|
||||
## Built-in RTTI support
|
||||
|
||||
Runtime type identification support (or RTTI) is one of the most frequently
|
||||
disabled features in the C++ world, especially in the gaming sector. Regardless
|
||||
of the reasons for this, it is often a shame not to be able to rely on opaque
|
||||
type information at runtime.<br/>
|
||||
The library tries to fill this gap by offering a built-in system that does not
|
||||
serve as a replacement but comes very close to being one and offers similar
|
||||
information to that provided by its counterpart.
|
||||
|
||||
Basically, the whole system relies on a handful of classes. In particular:
|
||||
|
||||
* The unique sequential identifier associated with a given type:
|
||||
|
||||
```cpp
|
||||
auto index = entt::type_index<a_type>::value();
|
||||
```
|
||||
|
||||
The returned value is not guaranteed to be stable across different runs.<br/>
|
||||
However, it can be very useful as index in associative and unordered
|
||||
associative containers or for positional accesses in a vector or an array.
|
||||
|
||||
An external generator can also be used if needed. In fact, `type_index` can be
|
||||
specialized by type and is also _sfinae-friendly_ in order to allow more
|
||||
refined specializations such as:
|
||||
|
||||
```cpp
|
||||
template<typename Type>
|
||||
struct entt::type_index<Type, std::void_d<decltype(Type::index())>> {
|
||||
static entt::id_type value() noexcept {
|
||||
return Type::index();
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Indexes **must** be sequentially generated in this case.<br/>
|
||||
The tool is widely used within `EnTT`. Generating indices not sequentially
|
||||
would break an assumption and would likely lead to undesired behaviors.
|
||||
|
||||
* The hash value associated with a given type:
|
||||
|
||||
```cpp
|
||||
auto hash = entt::type_hash<a_type>::value();
|
||||
```
|
||||
|
||||
In general, the `value` function exposed by `type_hash` is also `constexpr`
|
||||
but this is not guaranteed for all compilers and platforms (although it is
|
||||
valid with the most well-known and popular ones).
|
||||
|
||||
This function **can** use non-standard features of the language for its own
|
||||
purposes. This makes it possible to provide compile-time identifiers that
|
||||
remain stable across different runs.<br/>
|
||||
Users can prevent the library from using these features by means of the
|
||||
`ENTT_STANDARD_CPP` definition. In this case, there is no guarantee that
|
||||
identifiers remain stable across executions. Moreover, they are generated
|
||||
at runtime and are no longer a compile-time thing.
|
||||
|
||||
As it happens with `type_index`, also `type_hash` is a _sfinae-friendly_ class
|
||||
that can be specialized in order to customize its behavior globally or on a
|
||||
per-type or per-traits basis.
|
||||
|
||||
* The name associated with a given type:
|
||||
|
||||
```cpp
|
||||
auto name = entt::type_name<a_type>::value();
|
||||
```
|
||||
|
||||
This value is extracted from some information generally made available by the
|
||||
compiler in use. Therefore, it may differ depending on the compiler and may be
|
||||
empty in the event that this information is not available.<br/>
|
||||
For example, given the following class:
|
||||
|
||||
```cpp
|
||||
struct my_type { /* ... */ };
|
||||
```
|
||||
|
||||
The name is `my_type` when compiled with GCC or CLang and `struct my_type`
|
||||
when MSVC is in use.<br/>
|
||||
Most of the time the name is also retrieved at compile-time and is therefore
|
||||
always returned through an `std::string_view`. Users can easily access it and
|
||||
modify it as needed, for example by removing the word `struct` to normalize
|
||||
the result. `EnTT` does not do this for obvious reasons, since it would be
|
||||
creating a new string at runtime otherwise.
|
||||
|
||||
This function **can** use non-standard features of the language for its own
|
||||
purposes. Users can prevent the library from using these features by means of
|
||||
the `ENTT_STANDARD_CPP` definition. In this case, the name is just empty.
|
||||
|
||||
As it happens with `type_index`, also `type_name` is a _sfinae-friendly_ class
|
||||
that can be specialized in order to customize its behavior globally or on a
|
||||
per-type or per-traits basis.
|
||||
|
||||
These are then combined into utilities that aim to offer an API that is somewhat
|
||||
similar to that made available by the standard library.
|
||||
|
||||
### Type info
|
||||
|
||||
The `type_info` class is not a drop-in replacement for `std::type_info` but can
|
||||
provide similar information which are not implementation defined and do not
|
||||
require to enable RTTI.<br/>
|
||||
Therefore, they can sometimes be even more reliable than those obtained
|
||||
otherwise.
|
||||
|
||||
Its type defines an opaque class that is also copyable and movable.<br/>
|
||||
Objects of this type are generally returned by the `type_id` functions:
|
||||
|
||||
```cpp
|
||||
// by type
|
||||
auto info = entt::type_id<a_type>();
|
||||
|
||||
// by value
|
||||
auto other = entt::type_id(42);
|
||||
```
|
||||
|
||||
All elements thus received are nothing more than const references to instances
|
||||
of `type_info` with static storage duration.<br/>
|
||||
This is convenient for saving the entire object aside for the cost of a pointer.
|
||||
However, nothing prevents from constructing `type_info` objects directly:
|
||||
|
||||
```cpp
|
||||
entt::type_info info{std::in_place_type<int>};
|
||||
```
|
||||
|
||||
These are the information made available by `type_info`:
|
||||
|
||||
* The index associated with a given type:
|
||||
|
||||
```cpp
|
||||
auto idx = entt::type_id<a_type>().index();
|
||||
```
|
||||
|
||||
This is also an alias for the following:
|
||||
|
||||
```cpp
|
||||
auto idx = entt::type_index<std::remove_cv_t<std::remove_reference_t<a_type>>>::value();
|
||||
```
|
||||
|
||||
* The hash value associated with a given type:
|
||||
|
||||
```cpp
|
||||
auto hash = entt::type_id<a_type>().hash();
|
||||
```
|
||||
|
||||
This is also an alias for the following:
|
||||
|
||||
```cpp
|
||||
auto hash = entt::type_hash<std::remove_cv_t<std::remove_reference_t<a_type>>>::value();
|
||||
```
|
||||
|
||||
* The name associated with a given type:
|
||||
|
||||
```cpp
|
||||
auto name = entt::type_id<my_type>().name();
|
||||
```
|
||||
|
||||
This is also an alias for the following:
|
||||
|
||||
```cpp
|
||||
auto name = entt::type_name<std::remove_cv_t<std::remove_reference_t<a_type>>>::value();
|
||||
```
|
||||
|
||||
Where all accessed features are available at compile-time, the `type_info` class
|
||||
is also fully `constexpr`. However, this cannot be guaranteed in advance and
|
||||
depends mainly on the compiler in use and any specializations of the classes
|
||||
described above.
|
||||
|
||||
### Almost unique identifiers
|
||||
|
||||
Since the default non-standard, compile-time implementation of `type_hash` makes
|
||||
use of hashed strings, it may happen that two types are assigned the same hash
|
||||
value.<br/>
|
||||
In fact, although this is quite rare, it is not entirely excluded.
|
||||
|
||||
Another case where two types are assigned the same identifier is when classes
|
||||
from different contexts (for example two or more libraries loaded at runtime)
|
||||
have the same fully qualified name. In this case, `type_name` returns the same
|
||||
value for the two types.<br/>
|
||||
Fortunately, there are several easy ways to deal with this:
|
||||
|
||||
* The most trivial one is to define the `ENTT_STANDARD_CPP` macro. Runtime
|
||||
identifiers do not suffer from the same problem in fact. However, this
|
||||
solution does not work well with a plugin system, where the libraries are not
|
||||
linked.
|
||||
|
||||
* Another possibility is to specialize the `type_name` class for one of the
|
||||
conflicting types, in order to assign it a custom identifier. This is probably
|
||||
the easiest solution that also preserves the feature of the tool.
|
||||
|
||||
* A fully customized identifier generation policy (based for example on enum
|
||||
classes or preprocessing steps) may represent yet another option.
|
||||
|
||||
These are just some examples of possible approaches to the problem, but there
|
||||
are many others. As already mentioned above, since users have full control over
|
||||
their types, this problem is in any case easy to solve and should not worry too
|
||||
much.<br/>
|
||||
In all likelihood, it will never happen to run into a conflict anyway.
|
||||
|
||||
## Type traits
|
||||
|
||||
A handful of utilities and traits not present in the standard template library
|
||||
but which can be useful in everyday life.<br/>
|
||||
This list **is not** exhaustive and contains only some of the most useful
|
||||
classes. Refer to the inline documentation for more information on the features
|
||||
offered by this module.
|
||||
|
||||
### Size of
|
||||
|
||||
The standard operator `sizeof` complains if users provide it with functions or
|
||||
incomplete types. On the other hand, it is guaranteed that its result is always
|
||||
non-zero, even if applied to an empty class type.<br/>
|
||||
This small class combines the two and offers an alternative to `sizeof` that
|
||||
works under all circumstances, returning zero if the type is not supported:
|
||||
|
||||
```cpp
|
||||
const auto size = entt::size_of_v<void>;
|
||||
```
|
||||
|
||||
### Is applicable
|
||||
|
||||
The standard library offers the great `std::is_invocable` trait in several
|
||||
forms. This takes a function type and a series of arguments and returns true if
|
||||
the condition is satisfied.<br/>
|
||||
Moreover, users are also provided with `std::apply`, a tool for combining
|
||||
invocable elements and tuples of arguments.
|
||||
|
||||
It would therefore be a good idea to have a variant of `std::is_invocable` that
|
||||
also accepts its arguments in the form of a tuple-like type, so as to complete
|
||||
the offer:
|
||||
|
||||
```cpp
|
||||
constexpr bool result = entt::is_applicable<Func, std::tuple<a_type, another_type>>;
|
||||
```
|
||||
|
||||
This trait is built on top of `std::is_invocable` and does nothing but unpack a
|
||||
tuple-like type and simplify the code at the call site.
|
||||
|
||||
### Constness as
|
||||
|
||||
A utility to easily transfer the constness of a type to another type:
|
||||
|
||||
```cpp
|
||||
// type is const dst_type because of the constness of src_type
|
||||
using type = entt::constness_as_t<dst_type, const src_type>;
|
||||
```
|
||||
|
||||
The trait is subject to the rules of the language. For example, _transferring_
|
||||
constness between references will not give the desired effect.
|
||||
|
||||
### Member class type
|
||||
|
||||
The `auto` template parameter introduced with C++17 made it possible to simplify
|
||||
many class templates and template functions but also made the class type opaque
|
||||
when members are passed as template arguments.<br/>
|
||||
The purpose of this utility is to extract the class type in a few lines of code:
|
||||
|
||||
```cpp
|
||||
template<typename Member>
|
||||
using clazz = entt::member_class_t<Member>;
|
||||
```
|
||||
|
||||
### N-th argument
|
||||
|
||||
A utility to quickly find the n-th argument of a function, member function or
|
||||
data member (for blind operations on opaque types):
|
||||
|
||||
```cpp
|
||||
using type = entt::nth_argument_t<1u, decltype(&clazz::member)>;
|
||||
```
|
||||
|
||||
Disambiguation of overloaded functions is the responsibility of the user, should
|
||||
it be needed.
|
||||
|
||||
### Integral constant
|
||||
|
||||
Since `std::integral_constant` may be annoying because of its form that requires
|
||||
to specify both a type and a value of that type, there is a more user-friendly
|
||||
shortcut for the creation of integral constants.<br/>
|
||||
This shortcut is the alias template `entt::integral_constant`:
|
||||
|
||||
```cpp
|
||||
constexpr auto constant = entt::integral_constant<42>;
|
||||
```
|
||||
|
||||
Among the other uses, when combined with a hashed string it helps to define tags
|
||||
as human-readable _names_ where actual types would be required otherwise:
|
||||
|
||||
```cpp
|
||||
constexpr auto enemy_tag = entt::integral_constant<"enemy"_hs>;
|
||||
registry.emplace<enemy_tag>(entity);
|
||||
```
|
||||
|
||||
### Tag
|
||||
|
||||
Type `id_type` is very important and widely used in `EnTT`. Therefore, there is
|
||||
a more user-friendly shortcut for the creation of constants based on it.<br/>
|
||||
This shortcut is the alias template `entt::tag`.
|
||||
|
||||
If used in combination with hashed strings, it helps to use human-readable names
|
||||
where types would be required otherwise. As an example:
|
||||
|
||||
```cpp
|
||||
registry.emplace<entt::tag<"enemy"_hs>>(entity);
|
||||
```
|
||||
|
||||
However, this is not the only permitted use. Literally any value convertible to
|
||||
`id_type` is a good candidate, such as the named constants of an unscoped enum.
|
||||
|
||||
### Type list and value list
|
||||
|
||||
There is no respectable library where the much desired _type list_ can be
|
||||
missing.<br/>
|
||||
`EnTT` is no exception and provides (making extensive use of it internally) the
|
||||
`type_list` type, in addition to its `value_list` counterpart dedicated to
|
||||
non-type template parameters.
|
||||
|
||||
Here is a (possibly incomplete) list of the functionalities that come with a
|
||||
type list:
|
||||
|
||||
* `type_list_element[_t]` to get the N-th element of a type list.
|
||||
* `type_list_index[_v]` to get the index of a given element of a type list.
|
||||
* `type_list_cat[_t]` and a handy `operator+` to concatenate type lists.
|
||||
* `type_list_unique[_t]` to remove duplicate types from a type list.
|
||||
* `type_list_contains[_v]` to know if a type list contains a given type.
|
||||
* `type_list_diff[_t]` to remove types from type lists.
|
||||
* `type_list_transform[_t]` to _transform_ a range and create another type list.
|
||||
|
||||
I am also pretty sure that more and more utilities will be added over time as
|
||||
needs become apparent.<br/>
|
||||
Many of these functionalities also exist in their version dedicated to value
|
||||
lists. We therefore have `value_list_element[_v]` as well as
|
||||
`value_list_cat[_t]`and so on.
|
||||
|
||||
# Unique sequential identifiers
|
||||
|
||||
Sometimes it is useful to be able to give unique, sequential numeric identifiers
|
||||
to types either at compile-time or runtime.<br/>
|
||||
There are plenty of different solutions for this out there, and I could have
|
||||
used one of them. However, I decided to spend my time to define a couple of
|
||||
tools that fully embrace what modern C++ has to offer.
|
||||
|
||||
## Compile-time generator
|
||||
|
||||
To generate sequential numeric identifiers at compile-time, `EnTT` offers the
|
||||
`ident` class template:
|
||||
|
||||
```cpp
|
||||
// defines the identifiers for the given types
|
||||
using id = entt::ident<a_type, another_type>;
|
||||
|
||||
// ...
|
||||
|
||||
switch(a_type_identifier) {
|
||||
case id::value<a_type>:
|
||||
// ...
|
||||
break;
|
||||
case id::value<another_type>:
|
||||
// ...
|
||||
break;
|
||||
default:
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
This is what this class template has to offer: a `value` inline variable that
|
||||
contains a numeric identifier for the given type. It can be used in any context
|
||||
where constant expressions are required.
|
||||
|
||||
As long as the list remains unchanged, identifiers are also guaranteed to be
|
||||
stable across different runs. If used in a production environment where a type
|
||||
needs to be removed, a placeholder can help to leave the other identifiers the
|
||||
same:
|
||||
|
||||
```cpp
|
||||
template<typename>
|
||||
struct ignore_type {};
|
||||
|
||||
using id = entt::ident<
|
||||
a_type_still_valid,
|
||||
ignore_type<no_longer_valid_type>,
|
||||
another_type_still_valid
|
||||
>;
|
||||
```
|
||||
|
||||
Perhaps a bit ugly to see in a codebase, but it gets the job done at least.
|
||||
|
||||
## Runtime generator
|
||||
|
||||
The `family` class template helps to generate sequential numeric identifiers for
|
||||
types at runtime:
|
||||
|
||||
```cpp
|
||||
// defines a custom generator
|
||||
using id = entt::family<struct my_tag>;
|
||||
|
||||
// ...
|
||||
|
||||
const auto a_type_id = id::value<a_type>;
|
||||
const auto another_type_id = id::value<another_type>;
|
||||
```
|
||||
|
||||
This is what a _family_ has to offer: a `value` inline variable that contains a
|
||||
numeric identifier for the given type.<br/>
|
||||
The generator is customizable, so as to get different _sequences_ for different
|
||||
purposes if needed.
|
||||
|
||||
Identifiers are not guaranteed to be stable across different runs. Indeed it
|
||||
mostly depends on the flow of execution.
|
||||
|
||||
# Utilities
|
||||
|
||||
It is not possible to escape the temptation to add utilities of some kind to a
|
||||
library. In fact, `EnTT` also provides a handful of tools to simplify the
|
||||
life of developers:
|
||||
|
||||
* `entt::identity`: the identity function object that will be available with
|
||||
C++20. It returns its argument unchanged and nothing more. It is useful as a
|
||||
sort of _do nothing_ function in template programming.
|
||||
|
||||
* `entt::overload`: a tool to disambiguate different overloads from their
|
||||
function type. It works with both free and member functions.<br/>
|
||||
Consider the following definition:
|
||||
|
||||
```cpp
|
||||
struct clazz {
|
||||
void bar(int) {}
|
||||
void bar() {}
|
||||
};
|
||||
```
|
||||
|
||||
This utility can be used to get the _right_ overload as:
|
||||
|
||||
```cpp
|
||||
auto *member = entt::overload<void(int)>(&clazz::bar);
|
||||
```
|
||||
|
||||
The line above is literally equivalent to:
|
||||
|
||||
```cpp
|
||||
auto *member = static_cast<void(clazz:: *)(int)>(&clazz::bar);
|
||||
```
|
||||
|
||||
Just easier to read and shorter to type.
|
||||
|
||||
* `entt::overloaded`: a small class template used to create a new type with an
|
||||
overloaded `operator()` from a bunch of lambdas or functors.<br/>
|
||||
As an example:
|
||||
|
||||
```cpp
|
||||
entt::overloaded func{
|
||||
[](int value) { /* ... */ },
|
||||
[](char value) { /* ... */ }
|
||||
};
|
||||
|
||||
func(42);
|
||||
func('c');
|
||||
```
|
||||
|
||||
Rather useful when doing metaprogramming and having to pass to a function a
|
||||
callable object that supports multiple types at once.
|
||||
|
||||
* `entt::y_combinator`: this is a C++ implementation of **the** _y-combinator_.
|
||||
If it is not clear what it is, there is probably no need for this
|
||||
utility.<br/>
|
||||
Below is a small example to show its use:
|
||||
|
||||
```cpp
|
||||
entt::y_combinator gauss([](const auto &self, auto value) -> unsigned int {
|
||||
return value ? (value + self(value-1u)) : 0;
|
||||
});
|
||||
|
||||
const auto result = gauss(3u);
|
||||
```
|
||||
|
||||
Maybe convoluted at first glance but certainly effective. Unfortunately,
|
||||
the language does not make it possible to do much better.
|
||||
|
||||
This is a rundown of the (actually few) utilities made available by `EnTT`. The
|
||||
list will probably grow over time, but the size of each will remain rather
|
||||
small, as has been the case so far.
|
||||
2421
lib/All/entt/docs/md/entity.md
Normal file
208
lib/All/entt/docs/md/faq.md
Normal file
@@ -0,0 +1,208 @@
|
||||
# Frequently Asked Questions
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [FAQ](#faq)
|
||||
* [Why is my debug build on Windows so slow?](#why-is-my-debug-build-on-windows-so-slow)
|
||||
* [How can I represent hierarchies with my components?](#how-can-i-represent-hierarchies-with-my-components)
|
||||
* [Custom entity identifiers: yay or nay?](#custom-entity-identifiers-yay-or-nay)
|
||||
* [Warning C4003: the min, the max and the macro](#warning-c4003-the-min-the-max-and-the-macro)
|
||||
* [The standard and the non-copyable types](#the-standard-and-the-non-copyable-types)
|
||||
* [Which functions trigger which signals](#which-functions-trigger-which-signals)
|
||||
* [Duplicate storage for the same component](#duplicate-storage-for-the-same-component)
|
||||
|
||||
# Introduction
|
||||
|
||||
This is a constantly updated section where I am trying to put the answers to the
|
||||
most frequently asked questions.<br/>
|
||||
If you do not find your answer here, there are two cases: nobody has done it
|
||||
yet, or this section needs updating. In both cases, you can
|
||||
[open a new issue](https://github.com/skypjack/entt/issues/new) or enter either
|
||||
the [gitter channel](https://gitter.im/skypjack/entt) or the
|
||||
[discord server](https://discord.gg/5BjPWBd) to ask for help.<br/>
|
||||
Probably someone already has an answer for you and we can then integrate this
|
||||
part of the documentation.
|
||||
|
||||
# FAQ
|
||||
|
||||
## Why is my debug build on Windows so slow?
|
||||
|
||||
`EnTT` is an experimental project that I also use to keep me up-to-date with the
|
||||
latest revision of the language and the standard library. For this reason, it is
|
||||
likely that some classes you are working with are using standard containers
|
||||
under the hood.<br/>
|
||||
Unfortunately, it is known that the standard containers are not particularly
|
||||
performing in debugging (the reasons for this go beyond this document) and are
|
||||
even less so on Windows, apparently. Fortunately, this can also be mitigated a
|
||||
lot, achieving good results in many cases.
|
||||
|
||||
First of all, there are two things to do in a Windows project:
|
||||
|
||||
* Disable the [`/JMC`](https://docs.microsoft.com/cpp/build/reference/jmc)
|
||||
option (_Just My Code_ debugging), available starting with Visual Studio 2017
|
||||
version 15.8.
|
||||
|
||||
* Set the [`_ITERATOR_DEBUG_LEVEL`](https://docs.microsoft.com/cpp/standard-library/iterator-debug-level)
|
||||
macro to 0. This will disable checked iterators and iterator debugging.
|
||||
|
||||
Moreover, set the `ENTT_DISABLE_ASSERT` variable or redefine the `ENTT_ASSERT`
|
||||
macro to disable internal debug checks in `EnTT`:
|
||||
|
||||
```cpp
|
||||
#define ENTT_ASSERT(...) ((void)0)
|
||||
```
|
||||
|
||||
These asserts are introduced to help the users, but they require access to the
|
||||
underlying containers and therefore risk ruining the performance in some cases.
|
||||
|
||||
With these changes, debug performance should increase enough in most cases. If
|
||||
you want something more, you can also switch to an optimization level `O0` or
|
||||
preferably `O1`.
|
||||
|
||||
## How can I represent hierarchies with my components?
|
||||
|
||||
This is one of the first questions that anyone makes when starting to work with
|
||||
the entity-component-system architectural pattern.<br/>
|
||||
There are several approaches to the problem, and the best one depends mainly on
|
||||
the real problem one is facing. In all cases, how to do it does not strictly
|
||||
depend on the library in use, but the latter certainly allows or not different
|
||||
techniques depending on how the data are laid out.
|
||||
|
||||
I tried to describe some of the approaches that fit well with the model of
|
||||
`EnTT`. [This](https://skypjack.github.io/2019-06-25-ecs-baf-part-4/) is the
|
||||
first post of a series that tries to _explore_ the problem. More will probably
|
||||
come in the future.<br/>
|
||||
In addition, `EnTT` also offers the possibility to create stable storage types
|
||||
and therefore have pointer stability for one, all or some components. This is by
|
||||
far the most convenient solution when it comes to creating hierarchies and
|
||||
whatnot. See the documentation for the ECS part of the library and in particular
|
||||
what concerns the `component_traits` class for further details.
|
||||
|
||||
## Custom entity identifiers: yay or nay?
|
||||
|
||||
Custom entity identifiers are definitely a good idea in two cases at least:
|
||||
|
||||
* If `std::uint32_t` is not large enough for your purposes, since this is the
|
||||
underlying type of `entt::entity`.
|
||||
|
||||
* If you want to avoid conflicts when using multiple registries.
|
||||
|
||||
Identifiers can be defined through enum classes and class types that define an
|
||||
`entity_type` member of type `std::uint32_t` or `std::uint64_t`.<br/>
|
||||
In fact, this is a definition equivalent to that of `entt::entity`:
|
||||
|
||||
```cpp
|
||||
enum class entity: std::uint32_t {};
|
||||
```
|
||||
|
||||
There is no limit to the number of identifiers that can be defined.
|
||||
|
||||
## Warning C4003: the min, the max and the macro
|
||||
|
||||
On Windows, a header file defines two macros `min` and `max` which may result in
|
||||
conflicts with their counterparts in the standard library and therefore in
|
||||
errors during compilation.
|
||||
|
||||
It is a pretty big problem. However, fortunately it is not a problem of `EnTT`
|
||||
and there is a fairly simple solution to it.<br/>
|
||||
It consists in defining the `NOMINMAX` macro before including any other header
|
||||
so as to get rid of the extra definitions:
|
||||
|
||||
```cpp
|
||||
#define NOMINMAX
|
||||
```
|
||||
|
||||
Please refer to [this](https://github.com/skypjack/entt/issues/96) issue for
|
||||
more details.
|
||||
|
||||
## The standard and the non-copyable types
|
||||
|
||||
`EnTT` uses internally the trait `std::is_copy_constructible_v` to check if a
|
||||
component is actually copyable. However, this trait does not really check
|
||||
whether a type is actually copyable. Instead, it just checks that a suitable
|
||||
copy constructor and copy operator exist.<br/>
|
||||
This can lead to surprising results due to some idiosyncrasies of the standard.
|
||||
|
||||
For example, `std::vector` defines a copy constructor that is conditionally
|
||||
enabled depending on whether the value type is copyable or not. As a result,
|
||||
`std::is_copy_constructible_v` returns true for the following specialization:
|
||||
|
||||
```cpp
|
||||
struct type {
|
||||
std::vector<std::unique_ptr<action>> vec;
|
||||
};
|
||||
```
|
||||
|
||||
However, the copy constructor is effectively disabled upon specialization.
|
||||
Therefore, trying to assign an instance of this type to an entity may trigger a
|
||||
compilation error.<br/>
|
||||
As a workaround, users can mark the type explicitly as non-copyable. This also
|
||||
suppresses the implicit generation of the move constructor and operator, which
|
||||
will therefore have to be defaulted accordingly:
|
||||
|
||||
```cpp
|
||||
struct type {
|
||||
type(const type &) = delete;
|
||||
type(type &&) = default;
|
||||
|
||||
type & operator=(const type &) = delete;
|
||||
type & operator=(type &&) = default;
|
||||
|
||||
std::vector<std::unique_ptr<action>> vec;
|
||||
};
|
||||
```
|
||||
|
||||
Note that aggregate initialization is also disabled as a consequence.<br/>
|
||||
Fortunately, this type of trick is quite rare. The bad news is that there is no
|
||||
way to deal with it at the library level, this being due to the design of the
|
||||
language. On the other hand, the fact that the language itself also offers a way
|
||||
to mitigate the problem makes it manageable.
|
||||
|
||||
## Which functions trigger which signals
|
||||
|
||||
Storage classes offer three _signals_ that are emitted following specific
|
||||
operations. Maybe not everyone knows what these operations are, though.<br/>
|
||||
If this is not clear, below you can find a _vademecum_ for this purpose:
|
||||
|
||||
* `on_created` is invoked when a component is first added (neither modified nor
|
||||
replaced) to an entity.
|
||||
|
||||
* `on_update` is called whenever an existing component is modified or replaced.
|
||||
|
||||
* `on_destroyed` is called when a component is explicitly or implicitly removed
|
||||
from an entity.
|
||||
|
||||
Among the most controversial functions can be found `emplace_or_replace` and
|
||||
`destroy`. However, following the above rules, it is quite simple to know what
|
||||
will happen.<br/>
|
||||
In the first case, `on_created` is invoked if the entity has not the component,
|
||||
otherwise the latter is replaced and therefore `on_update` is triggered. As for
|
||||
the second case, components are removed from their entities and thus freed when
|
||||
they are recycled. It means that `on_destroyed` is triggered for every component
|
||||
owned by the entity that is destroyed.
|
||||
|
||||
## Duplicate storage for the same component
|
||||
|
||||
It is rare, but you can see double sometimes, especially when it comes to
|
||||
storage. This can be caused by a conflict in the hash assigned to the various
|
||||
component types (one of a kind) or by bugs in your compiler
|
||||
([more common](https://github.com/skypjack/entt/issues/1063) apparently).<br/>
|
||||
Regardless of the cause, `EnTT` offers a customization point that also serves as
|
||||
a solution in this case:
|
||||
|
||||
```cpp
|
||||
template<>
|
||||
struct entt::type_hash<Type> final {
|
||||
[[nodiscard]] static constexpr id_type value() noexcept {
|
||||
return hashed_string::value("Type");
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr operator id_type() const noexcept {
|
||||
return value();
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Specializing `type_hash` directly bypasses the default implementation offered by
|
||||
`EnTT`, thus avoiding any possible conflicts or compiler bugs.
|
||||
367
lib/All/entt/docs/md/graph.md
Normal file
@@ -0,0 +1,367 @@
|
||||
# Crash Course: graph
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Data structures](#data-structures)
|
||||
* [Adjacency matrix](#adjacency-matrix)
|
||||
* [Graphviz dot language](#graphviz-dot-language)
|
||||
* [Flow builder](#flow-builder)
|
||||
* [Tasks and resources](#tasks-and-resources)
|
||||
* [Fake resources and order of execution](#fake-resources-and-order-of-execution)
|
||||
* [Sync points](#sync-points)
|
||||
* [Execution graph](#execution-graph)
|
||||
|
||||
# Introduction
|
||||
|
||||
`EnTT` does not aim to offer everything one needs to work with graphs.
|
||||
Therefore, anyone looking for this in the _graph_ submodule will be
|
||||
disappointed.<br/>
|
||||
Quite the opposite is true though. This submodule is minimal and contains only
|
||||
the data structures and algorithms strictly necessary for the development of
|
||||
some tools such as the _flow builder_.
|
||||
|
||||
# Data structures
|
||||
|
||||
As anticipated in the introduction, the aim is not to offer all possible data
|
||||
structures suitable for representing and working with graphs. Many will likely
|
||||
be added or refined over time. However, I want to discourage anyone expecting
|
||||
tight scheduling on the subject.<br/>
|
||||
The data structures presented in this section are mainly useful for the
|
||||
development and support of some tools that are also part of the same submodule.
|
||||
|
||||
## Adjacency matrix
|
||||
|
||||
The adjacency matrix is designed to represent either a directed or an undirected
|
||||
graph:
|
||||
|
||||
```cpp
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{};
|
||||
```
|
||||
|
||||
The `directed_tag` type _creates_ the graph as directed. There is also an
|
||||
`undirected_tag` counterpart which creates it as undirected.<br/>
|
||||
The interface deviates slightly from the typical double indexing of C and offers
|
||||
an API that is perhaps more familiar to a C++ programmer. Therefore, the access
|
||||
and modification of an element takes place via the `contains`, `insert` and
|
||||
`erase` functions rather than a double call to an `operator[]`:
|
||||
|
||||
```cpp
|
||||
if(adjacency_matrix.contains(0u, 1u)) {
|
||||
adjacency_matrix.erase(0u, 1u);
|
||||
} else {
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
}
|
||||
```
|
||||
|
||||
Both `insert` and` erase` are _idempotent_ functions which have no effect if the
|
||||
element already exists or has already been deleted.<br/>
|
||||
The first one returns an `std::pair` containing the iterator to the element and
|
||||
a boolean value indicating whether the element was newly inserted or not. The
|
||||
second one returns the number of deleted elements (0 or 1).
|
||||
|
||||
An adjacency matrix is initialized with the number of elements (vertices) when
|
||||
constructing it but can also be resized later using the `resize` function:
|
||||
|
||||
```cpp
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
```
|
||||
|
||||
To visit all vertices, the class offers a function named `vertices` that returns
|
||||
an iterable object suitable for the purpose:
|
||||
|
||||
```cpp
|
||||
for(auto &&vertex: adjacency_matrix.vertices()) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The same result is obtained with the following snippet, since the vertices are
|
||||
plain unsigned integral values:
|
||||
|
||||
```cpp
|
||||
for(auto last = adjacency_matrix.size(), pos = {}; pos < last; ++pos) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
As for visiting the edges, a few functions are available.<br/>
|
||||
When the purpose is to visit all the edges of a given adjacency matrix, the
|
||||
`edges` function returns an iterable object that is used to get them as pairs of
|
||||
vertices:
|
||||
|
||||
```cpp
|
||||
for(auto [lhs, rhs]: adjacency_matrix.edges()) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
If the goal is to visit all the in- or out-edges of a given vertex instead, the
|
||||
`in_edges` and `out_edges` functions are meant for that:
|
||||
|
||||
```cpp
|
||||
for(auto [lhs, rhs]: adjacency_matrix.out_edges(3u)) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Both the functions expect the vertex to visit (that is, to return the in- or
|
||||
out-edges for) as an argument.<br/>
|
||||
Finally, the adjacency matrix is an allocator-aware container and offers most of
|
||||
the functionalities one would expect from this type of containers, such as
|
||||
`clear` or `get_allocator` and so on.
|
||||
|
||||
## Graphviz dot language
|
||||
|
||||
As it is one of the most popular formats, the library offers minimal support for
|
||||
converting a graph to a Graphviz dot snippet.<br/>
|
||||
The simplest way is to pass both an output stream and a graph to the `dot`
|
||||
function:
|
||||
|
||||
```cpp
|
||||
std::ostringstream output{};
|
||||
entt::dot(output, adjacency_matrix);
|
||||
```
|
||||
|
||||
It is also possible to provide a callback to which the vertices are passed and
|
||||
which can be used to add (`dot`) properties to the output as needed:
|
||||
|
||||
```cpp
|
||||
std::ostringstream output{};
|
||||
|
||||
entt::dot(output, adjacency_matrix, [](auto &output, auto vertex) {
|
||||
out << "label=\"v\"" << vertex << ",shape=\"box\"";
|
||||
});
|
||||
```
|
||||
|
||||
This second mode is particularly convenient when the user wants to associate
|
||||
externally managed data to the graph being converted.
|
||||
|
||||
# Flow builder
|
||||
|
||||
A flow builder is used to create execution graphs from tasks and resources.<br/>
|
||||
The implementation is as generic as possible and does not bind to any other part
|
||||
of the library.
|
||||
|
||||
This class is designed as a sort of _state machine_ to which a specific task is
|
||||
attached for which the resources accessed in read-only or read-write mode are
|
||||
specified.<br/>
|
||||
Most of the functions in the API also return the flow builder itself, according
|
||||
to what is the common sense API when it comes to builder classes.
|
||||
|
||||
Once all tasks are registered and resources assigned to them, an execution graph
|
||||
in the form of an adjacency matrix is returned to the user.<br/>
|
||||
This graph contains all the tasks assigned to the flow builder in the form of
|
||||
_vertices_. The _vertex_ itself is used as an index to get the identifier passed
|
||||
during registration.
|
||||
|
||||
## Tasks and resources
|
||||
|
||||
Although these terms are used extensively in the documentation, the flow builder
|
||||
has no real concept of tasks and resources.<br/>
|
||||
This class works mainly with _identifiers_, that is, values of type `id_type`.
|
||||
In other terms, both tasks and resources are identified by integral values.<br/>
|
||||
This allows not to couple the class itself to the rest of the library or to any
|
||||
particular data structure. On the other hand, it requires the user to keep track
|
||||
of the association between identifiers and operations or actual data.
|
||||
|
||||
Once a flow builder is created (which requires no constructor arguments), the
|
||||
first thing to do is to bind a task. This tells the builder _who_ intends to
|
||||
consume the resources that are specified immediately after:
|
||||
|
||||
```cpp
|
||||
entt::flow builder{};
|
||||
builder.bind("task_1"_hs);
|
||||
```
|
||||
|
||||
The example uses the `EnTT` hashed string to generate an identifier for the
|
||||
task.<br/>
|
||||
Indeed, the use of `id_type` as an identifier type is not by accident. In fact,
|
||||
it matches well with the internal hashed string class. Moreover, it is also the
|
||||
same type returned by the hash function of the internal RTTI system, in case the
|
||||
user wants to rely on that.<br/>
|
||||
However, being an integral value, it leaves the user full freedom to rely on his
|
||||
own tools if necessary.
|
||||
|
||||
Once a task is associated with the flow builder, it has also assigned read-only
|
||||
or read-write resources as appropriate:
|
||||
|
||||
```cpp
|
||||
builder
|
||||
.bind("task_1"_hs)
|
||||
.ro("resource_1"_hs)
|
||||
.ro("resource_2"_hs)
|
||||
.bind("task_2"_hs)
|
||||
.rw("resource_2"_hs)
|
||||
```
|
||||
|
||||
As mentioned, many functions return the builder itself, and it is therefore easy
|
||||
to concatenate the different calls.<br/>
|
||||
Also in the case of resources, they are identified by numeric values of type
|
||||
`id_type`. As above, the choice is not entirely random. This goes well with the
|
||||
tools offered by the library while leaving room for maximum flexibility.
|
||||
|
||||
Finally, both the `ro` and` rw` functions also offer an overload that accepts a
|
||||
pair of iterators, so that one can pass a range of resources in one go.
|
||||
|
||||
### Rebinding
|
||||
|
||||
The `flow` class is resource based rather than task based. This means that graph
|
||||
generation is driven by resources and not by the order of _appearance_ of tasks
|
||||
during flow definition.<br/>
|
||||
Although this concept is particularly important, it is almost irrelevant for the
|
||||
vast majority of cases. However, it becomes relevant when _rebinding_ resources
|
||||
or tasks.
|
||||
|
||||
In fact, nothing prevents rebinding elements to a flow.<br/>
|
||||
However, the behavior changes slightly from case to case and has some nuances
|
||||
that it is worth knowing about.
|
||||
|
||||
Directly rebinding a resource without the task being replaced trivially results
|
||||
in the task's access mode for that resource being updated:
|
||||
|
||||
```cpp
|
||||
builder.bind("task"_hs).rw("resource"_hs).ro("resource"_hs)
|
||||
```
|
||||
|
||||
In this case, the resource is accessed in read-only mode, regardless of the
|
||||
first call to `rw`.<br/>
|
||||
Behind the scenes, the call does not actually _replace_ the previous one but is
|
||||
queued after it instead, overwriting it when generating the graph. Thus, a large
|
||||
number of resource rebindings may even impact processing times (very difficult
|
||||
to observe but theoretically possible).
|
||||
|
||||
Rebinding resources and also combining it with changes to tasks has far more
|
||||
implications instead.<br/>
|
||||
As mentioned, graph generation takes place starting from resources and not from
|
||||
tasks. Therefore, the result may not be as expected:
|
||||
|
||||
```cpp
|
||||
builder
|
||||
.bind("task_1"_hs)
|
||||
.ro("resource"_hs)
|
||||
.bind("task_2"_hs)
|
||||
.ro("resource"_hs)
|
||||
.bind("task_1"_hs)
|
||||
.rw("resource"_hs);
|
||||
```
|
||||
|
||||
What happens here is that the resource first _sees_ a read-only access request
|
||||
from the first task, then a read-only request from the second task and finally
|
||||
a read-write request from the first task.<br/>
|
||||
Although this definition would probably be counted as an error, the resulting
|
||||
graph may be unexpected. In fact, this consists of a single edge outgoing from
|
||||
the second task and directed to the first task.<br/>
|
||||
To intuitively understand what happens, it is enough to think of the fact that a
|
||||
task never has an edge pointing to itself.
|
||||
|
||||
While not obvious, this approach has its pros and cons like any other solution.
|
||||
For example, creating loops is actually simple in the context of resource-based
|
||||
graph generations:
|
||||
|
||||
```cpp
|
||||
builder
|
||||
.bind("task_1"_hs)
|
||||
.rw("resource"_hs)
|
||||
.bind("task_2"_hs)
|
||||
.rw("resource"_hs)
|
||||
.bind("task_1"_hs)
|
||||
.rw("resource"_hs);
|
||||
```
|
||||
|
||||
As expected, this definition leads to the creation of two edges that define a
|
||||
loop between the two tasks.
|
||||
|
||||
As a general rule, rebinding resources and tasks is highly discouraged because
|
||||
it could lead to subtle bugs if users do not know what they are doing.<br/>
|
||||
However, once the mechanisms of resource-based graph generation are understood,
|
||||
it can offer to the expert user flexibility and a range of possibilities
|
||||
otherwise inaccessible.
|
||||
|
||||
## Fake resources and order of execution
|
||||
|
||||
The flow builder does not offer the ability to specify when a task should run
|
||||
before or after another task.<br/>
|
||||
In fact, the order of _registration_ on the resources also determines the order
|
||||
in which the tasks are processed during the generation of the execution graph.
|
||||
|
||||
However, there is a way to _force_ the execution order of two processes.<br/>
|
||||
Briefly, since accessing a resource in opposite modes requires sequential rather
|
||||
than parallel scheduling, it is possible to make use of fake resources to rule
|
||||
on the execution order:
|
||||
|
||||
```cpp
|
||||
builder
|
||||
.bind("task_1"_hs)
|
||||
.ro("resource_1"_hs)
|
||||
.rw("fake"_hs)
|
||||
.bind("task_2"_hs)
|
||||
.ro("resource_2"_hs)
|
||||
.ro("fake"_hs)
|
||||
.bind("task_3"_hs)
|
||||
.ro("resource_2"_hs)
|
||||
.ro("fake"_hs)
|
||||
```
|
||||
|
||||
This snippet forces the execution of `task_1` **before** `task_2` and `task_3`.
|
||||
This is due to the fact that the former sets a read-write requirement on a fake
|
||||
resource that the other tasks also want to access in read-only mode.<br/>
|
||||
Similarly, it is possible to force a task to run **after** a certain group:
|
||||
|
||||
```cpp
|
||||
builder
|
||||
.bind("task_1"_hs)
|
||||
.ro("resource_1"_hs)
|
||||
.ro("fake"_hs)
|
||||
.bind("task_2"_hs)
|
||||
.ro("resource_1"_hs)
|
||||
.ro("fake"_hs)
|
||||
.bind("task_3"_hs)
|
||||
.ro("resource_2"_hs)
|
||||
.rw("fake"_hs)
|
||||
```
|
||||
|
||||
In this case, since there are a number of processes that want to read a specific
|
||||
resource, they will do so in parallel by forcing `task_3` to run after all the
|
||||
other tasks.
|
||||
|
||||
## Sync points
|
||||
|
||||
Sometimes it is useful to assign the role of _sync point_ to a node.<br/>
|
||||
Whether it accesses new resources or is simply a watershed, the procedure for
|
||||
assigning this role to a vertex is always the same. First it is tied to the flow
|
||||
builder, then the `sync` function is invoked:
|
||||
|
||||
```cpp
|
||||
builder.bind("sync_point"_hs).sync();
|
||||
```
|
||||
|
||||
The choice to assign an _identity_ to this type of node lies in the fact that,
|
||||
more often than not, they also perform operations on resources.<br/>
|
||||
If this is not the case, it will still be possible to create no-op vertices to
|
||||
which empty tasks are assigned.
|
||||
|
||||
## Execution graph
|
||||
|
||||
Once both the resources and their consumers have been properly registered, the
|
||||
purpose of this tool is to generate an execution graph that takes into account
|
||||
all specified constraints to return the best scheduling for the vertices:
|
||||
|
||||
```cpp
|
||||
entt::adjacency_matrix<entt::directed_tag> graph = builder.graph();
|
||||
```
|
||||
|
||||
Searching for the main vertices (that is, those without in-edges) is usually the
|
||||
first thing required:
|
||||
|
||||
```cpp
|
||||
for(auto &&vertex: graph) {
|
||||
if(auto in_edges = graph.in_edges(vertex); in_edges.begin() == in_edges.end()) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then it is possible to instantiate an execution graph by means of other
|
||||
functions such as `out_edges` to retrieve the children of a given task or
|
||||
`edges` to get the identifiers.
|
||||
92
lib/All/entt/docs/md/lib.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Push EnTT across boundaries
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Working across boundaries](#working-across-boundaries)
|
||||
* [Smooth until proven otherwise](#smooth-until-proven-otherwise)
|
||||
* [Meta context](#meta-context)
|
||||
* [Memory management](#memory-management)
|
||||
|
||||
# Working across boundaries
|
||||
|
||||
`EnTT` has historically had a limit when used across boundaries on Windows in
|
||||
general and on GNU/Linux when default visibility was set to hidden. The
|
||||
limitation was mainly due to a custom utility used to assign unique, sequential
|
||||
identifiers with different types.<br/>
|
||||
Fortunately, nowadays `EnTT` works smoothly across boundaries.
|
||||
|
||||
## Smooth until proven otherwise
|
||||
|
||||
Many classes in `EnTT` make extensive use of type erasure for their purposes.
|
||||
This raises the need to identify objects whose type has been erased.<br/>
|
||||
The `type_hash` class template is how identifiers are generated and thus made
|
||||
available to the rest of the library. In general, this class arouses little
|
||||
interest. The only exception is when a conflict between identifiers occurs
|
||||
(definitely uncommon though) or when the default solution proposed by `EnTT` is
|
||||
not suitable for the user's purposes.<br/>
|
||||
The section dedicated to `type_info` contains all the details to get around the
|
||||
issue in a concise and elegant way. Please refer to the specific documentation.
|
||||
|
||||
When working with linked libraries, compile definitions `ENTT_API_EXPORT` and
|
||||
`ENTT_API_IMPORT` are to import or export symbols, so as to make everything work
|
||||
nicely across boundaries.<br/>
|
||||
On the other hand, everything should run smoothly when working with plugins or
|
||||
shared libraries that do not export any symbols.
|
||||
|
||||
For those who need more details, the test suite contains many examples covering
|
||||
the most common cases (see the `lib` directory for all details).<br/>
|
||||
It goes without saying that it is impossible to cover **all** possible cases.
|
||||
However, what is offered should hopefully serve as a basis for all of them.
|
||||
|
||||
## Meta context
|
||||
|
||||
The runtime reflection system deserves a special mention when it comes to using
|
||||
it across boundaries.<br/>
|
||||
Since it is linked already to a static context to which the elements are
|
||||
attached and different contexts do not relate to each other, they must be
|
||||
_shared_ to allow the use of meta types across boundaries.
|
||||
|
||||
Fortunately, sharing a context is also trivial to do. First of all, the local
|
||||
one is acquired in the main space:
|
||||
|
||||
```cpp
|
||||
auto handle = entt::locator<entt::meta_ctx>::handle();
|
||||
```
|
||||
|
||||
Then, it is passed to the receiving space that sets it as its default context,
|
||||
thus discarding or storing aside the local one:
|
||||
|
||||
```cpp
|
||||
entt::locator<entt::meta_ctx>::reset(handle);
|
||||
```
|
||||
|
||||
From now on, both spaces refer to the same context and to it are all new meta
|
||||
types attached, no matter where they are created.<br/>
|
||||
Note that _replacing_ the main context does not also propagate changes across
|
||||
boundaries. In other words, replacing a context results in the decoupling of the
|
||||
two sides and therefore a divergence in the contents.
|
||||
|
||||
## Memory Management
|
||||
|
||||
There is another subtle problem due to memory management that can lead to
|
||||
headaches.<br/>
|
||||
It can occur where there are pools of objects (such as components or events)
|
||||
dynamically created on demand. This is usually not a problem when working with
|
||||
linked libraries that rely on the same dynamic runtime. However, it can occur in
|
||||
the case of plugins or statically linked runtimes.
|
||||
|
||||
As an example, imagine creating an instance of `registry` in the main executable
|
||||
and sharing it with a plugin. If the latter starts working with a component that
|
||||
is unknown to the former, a dedicated pool is created within the registry on
|
||||
first use.<br/>
|
||||
As one can guess, this pool is instantiated on a different side of the boundary
|
||||
from the `registry`. Therefore, the instance is now managing memory from
|
||||
different spaces, and this can quickly lead to crashes if not properly
|
||||
addressed.
|
||||
|
||||
To overcome the risk, it is recommended to use well-defined interfaces that make
|
||||
fundamental types pass through the boundaries, isolating the instances of the
|
||||
`EnTT` classes from time to time and as appropriate.<br/>
|
||||
Refer to the test suite for some examples, read the documentation available
|
||||
online about this type of issues or consult someone who has already had such
|
||||
experiences to avoid problems.
|
||||
355
lib/All/entt/docs/md/links.md
Normal file
@@ -0,0 +1,355 @@
|
||||
# EnTT in Action
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [EnTT in Action](#entt-in-action)
|
||||
* [Games](#games)
|
||||
* [Engines and the like](#engines-and-the-like)
|
||||
* [Articles, videos and blog posts](#articles-videos-and-blog-posts)
|
||||
* [Any Other Business](#any-other-business)
|
||||
|
||||
# Introduction
|
||||
|
||||
`EnTT` is widely used in private and commercial applications. I cannot even
|
||||
mention most of them because of some signatures I put on some documents time
|
||||
ago. Fortunately, there are also people who took the time to implement open
|
||||
source projects based on `EnTT` and did not hold back when it came to
|
||||
documenting them.
|
||||
|
||||
Below an incomplete list of games, applications and articles that can be used as
|
||||
a reference.<br/>
|
||||
Where I put the word _apparently_ means that the use of `EnTT` is documented but
|
||||
the authors did not make explicit announcements or contacted me directly.
|
||||
|
||||
If you know of other resources out there that are about `EnTT`, feel free to
|
||||
open an issue or a PR. I will be glad to add them to this page.<br/>
|
||||
I hope the following lists can grow much more in the future.
|
||||
|
||||
# EnTT in Action
|
||||
|
||||
## Games
|
||||
|
||||
* [Minecraft](https://minecraft.net/en-us/attribution/) by
|
||||
[Mojang](https://mojang.com/): of course, **that** Minecraft, see the
|
||||
open source attributions page for more details.
|
||||
* [Minecraft Legends](https://www.minecraft.net/it-it/about-legends) by
|
||||
[Mojang](https://mojang.com/): an action strategy game where users have to
|
||||
fight to defend the Overworld.
|
||||
* [Minecraft Earth](https://www.minecraft.net/en-us/about-earth) by
|
||||
[Mojang](https://mojang.com/): an augmented reality game for mobile, that
|
||||
lets users bring Minecraft into the real world.
|
||||
* [Ember Sword](https://embersword.com/): a modern Free-to-Play MMORPG with a
|
||||
player-driven economy, a classless combat system, and scarce, tradable
|
||||
cosmetic collectibles.
|
||||
* Apparently [Diablo II: Resurrected](https://diablo2.blizzard.com/) by
|
||||
[Blizzard](https://www.blizzard.com/): monsters, heroes, items, spells, all
|
||||
resurrected. Thanks unknown insider.
|
||||
* [Apparently](https://www.youtube.com/watch?v=P8xvOA3ikrQ&t=1105s)
|
||||
[Call of Duty: Vanguard](https://www.callofduty.com/vanguard) by
|
||||
[Sledgehammer Games](https://www.sledgehammergames.com/): I can neither
|
||||
confirm nor deny, but there is a license I know in the credits.
|
||||
* Apparently [D&D Dark Alliance](https://darkalliance.wizards.com) by
|
||||
[Wizards of the Coast](https://company.wizards.com): your party, their
|
||||
funeral.
|
||||
* [TiltedEvolution](https://github.com/tiltedphoques/TiltedEvolution) by
|
||||
[Tilted Phoques](https://github.com/tiltedphoques): Skyrim and Fallout 4 mod
|
||||
to play online.
|
||||
* [Antkeeper](https://github.com/antkeeper/antkeeper-source): an ant colony
|
||||
simulation [game](https://antkeeper.com/).
|
||||
* [Openblack](https://github.com/openblack/openblack): open source
|
||||
reimplementation of the game _Black & White_ (2001).
|
||||
* [Land of the Rair](https://github.com/LandOfTheRair/core2): the new backend
|
||||
of [a retro-style MUD](https://rair.land/) for the new age.
|
||||
* [Face Smash](https://play.google.com/store/apps/details?id=com.gamee.facesmash):
|
||||
a game to play with your face.
|
||||
* [EnTT Pacman](https://github.com/Kerndog73/EnTT-Pacman): an example of how
|
||||
to make Pacman with `EnTT`.
|
||||
* [Wacman](https://github.com/carlfindahl/wacman): a pacman clone with OpenGL.
|
||||
* [Classic Tower Defence](https://github.com/kerndog73/Classic-Tower-Defence):
|
||||
a tiny little tower defence game featuring a homemade font.
|
||||
[Check it out](https://indi-kernick.itch.io/classic-tower-defence).
|
||||
* [The Machine](https://github.com/Kerndog73/The-Machine): a box pushing
|
||||
puzzler with logic gates and other cool stuff.
|
||||
[Check it out](https://indi-kernick.itch.io/the-machine-web-version).
|
||||
* [EnTTPong](https://github.com/DomRe/EnttPong): a basic game made to showcase
|
||||
different parts of `EnTT` and C++17.
|
||||
* [Randballs](https://github.com/gale93/randballs): simple `SFML` and `EnTT`
|
||||
playground.
|
||||
* [EnTT Tower Defense](https://github.com/Daivuk/tddod): a data oriented tower
|
||||
defense example.
|
||||
* [EnTT Breakout](https://github.com/vblanco20-1/entt-breakout): simple
|
||||
example of a breakout game, using `SDL` and `EnTT`.
|
||||
* [Arcade puzzle game with EnTT](https://github.com/MasonRG/ArcadePuzzleGame):
|
||||
arcade puzzle game made in C++ using the `SDL2` and `EnTT` libraries.
|
||||
* [Snake with EnTT](https://github.com/MasonRG/SnakeGame): simple snake game
|
||||
made in C++ with the `SDL2` and `EnTT` libraries.
|
||||
* [Mirrors lasers and robots](https://github.com/guillaume-haerinck/imac-tower-defense):
|
||||
a small tower defense game based on mirror orientation.
|
||||
* [PopHead](https://github.com/SPC-Some-Polish-Coders/PopHead/): 2D, Zombie,
|
||||
RPG game made from scratch in C++.
|
||||
* [Robotligan](https://github.com/Trisslotten/robotligan): multiplayer
|
||||
football game.
|
||||
* [DungeonSlayer](https://github.com/alohaeee/DungeonSlayer): 2D game made
|
||||
from scratch in C++.
|
||||
* [3DGame](https://github.com/kwarkGorny/3DGame): 2.5D top-down space shooter.
|
||||
* [Pulcher](https://github.com/AODQ/pulcher): 2D cross-platform game inspired
|
||||
by Quake.
|
||||
* [Destroid](https://github.com/tyrannicaltoucan/destroid): _one-bazillionth_
|
||||
arcade game about shooting dirty rocks in space, inspired by Asteroids.
|
||||
* [Wanderer](https://github.com/albin-johansson/wanderer): a 2D
|
||||
exploration-based indie game.
|
||||
* [Spelunky® Classic remake](https://github.com/dbeef/spelunky-psp): a truly
|
||||
multiplatform experience with a rewrite from scratch.
|
||||
* [CubbyTower](https://github.com/utilForever/CubbyTower): a simple tower
|
||||
defense game using C++ with Entity Component System (ECS).
|
||||
* [Runeterra](https://github.com/utilForever/Runeterra): Legends of Runeterra
|
||||
simulator using C++ with some reinforcement learning.
|
||||
* [Black Sun](https://store.steampowered.com/app/1670930/Black_Sun/): fly your
|
||||
spaceship through a large 2D open world.
|
||||
* [PokeMaster](https://github.com/utilForever/PokeMaster): Pokémon Battle
|
||||
simulator using C++ with some reinforcement learning.
|
||||
* [HomeHearth](https://youtu.be/GrEWl8npL9Y): choose your hero, protect the
|
||||
town, before it is too late.
|
||||
* [City Builder Game](https://github.com/PhiGei2000/CityBuilderGame): a simple
|
||||
city-building game using C++ and OpenGL.
|
||||
* [BattleSub](https://github.com/bfeldpw/battlesub): two player 2D submarine
|
||||
game with some fluid dynamics.
|
||||
* [Crimson Rush](https://github.com/WilKam01/LuaCGame): a dungeon-crawler and
|
||||
rougelike inspired game about exploring and surviving as long as possible.
|
||||
* [Space Fight](https://github.com/cholushkin/SpaceFight): one screen
|
||||
multi-player arcade shooter game prototype.
|
||||
* [Confetti Party](https://github.com/hexerei/entt-confetti): C++ sample
|
||||
application as a starting point using `EnTT` and `SDL2`.
|
||||
* [Hellbound](https://buas.itch.io/hellbound): a top-down action rogue-like
|
||||
where to fight colossal demons in procedurally generated levels of hell.
|
||||
* [Saurian Sorcery](https://github.com/cajallen/spellbook): a tower defense
|
||||
game where to assemble a tribe of lizards to defend against robot invaders.
|
||||
* [robotfindskitten](https://github.com/autogalkin/robotfindskitten): a clone
|
||||
of `robotfindskitten` inside `Notepad.exe`, powered by `EnTT`.
|
||||
* [Orion](https://github.com/alekskoloch/Orion): Outer-space Research and
|
||||
Interstellar Observation Network (a space shooter game).
|
||||
* [EnTT Boids](https://github.com/DanielEliasib/entt_boids): a simple boids
|
||||
implementation using `EnTT` and `Raylib`.
|
||||
* [PalmRide: After Flight](https://store.steampowered.com/app/2812540/PalmRide_After_Flight/):
|
||||
an on-rails shooter with retro outrun aesthetics.
|
||||
* [Exhibition of Speed](https://store.steampowered.com/app/2947450/Exhibition_of_Speed/):
|
||||
build your own car and go racing.
|
||||
* [Lichgate](https://buas.itch.io/lichgate): top-down action rogue-like where
|
||||
users unlock abilities to fight horde of enemies in an endless world.
|
||||
* [Letalka](https://github.com/dviglo2d/dviglo2d/tree/main/games/letalka):
|
||||
small demo game with ships and bullets flying everywhere on the screen.
|
||||
* [Lichgate](https://buas.itch.io/lichgate): step into the robes of a powerful
|
||||
mage determined to halt the relentless hordes of undead.
|
||||
|
||||
## Engines and the like:
|
||||
|
||||
* [Hazel Engine](https://github.com/TheCherno/Hazel): a work in progress
|
||||
engine created by [The Cherno](https://github.com/TheCherno/Hazel) during
|
||||
one of his most famous video series.
|
||||
* [Aether Engine](https://hadean.com/spatial-simulation/)
|
||||
[v1.1+](https://docs.hadean.com/v1.1/Licenses/) by
|
||||
[Hadean](https://hadean.com/): a library designed for spatially partitioning
|
||||
agent-based simulations.
|
||||
* [Fling Engine](https://github.com/flingengine/FlingEngine): a Vulkan game
|
||||
engine with a focus on data oriented design.
|
||||
* [NovusCore](https://github.com/novuscore/NovusCore): a modern take on World
|
||||
of Warcraft emulation.
|
||||
* [Chrysalis](https://github.com/ivanhawkes/Chrysalis): action RPG SDK for
|
||||
CRYENGINE games.
|
||||
* [LM-Engine](https://github.com/Lawrencemm/LM-Engine): the Vim of game
|
||||
engines.
|
||||
* [Edyn](https://github.com/xissburg/edyn): a real-time physics engine
|
||||
organized as an ECS.
|
||||
* [MushMachine](https://github.com/MadeOfJelly/MushMachine): engine...
|
||||
vrooooommm.
|
||||
* [Antara Gaming SDK](https://github.com/KomodoPlatform/antara-gaming-sdk):
|
||||
the Komodo Gaming Software Development Kit.
|
||||
* [XVP](https://ravingbots.com/xvp-expansive-vehicle-physics-for-unreal-engine/):
|
||||
[_eXpansive Vehicle Physics_](https://github.com/raving-bots/xvp/wiki/Plugin-integration-guide)
|
||||
plugin for Unreal Engine.
|
||||
* [Apparently](https://teamwisp.github.io/credits/)
|
||||
[Wisp](https://teamwisp.github.io/product/) by
|
||||
[Team Wisp](https://teamwisp.github.io/): an advanced real-time ray tracing
|
||||
renderer built for the demands of video game artists.
|
||||
* [shiva](https://github.com/Milerius/shiva): modern C++ engine with
|
||||
modularity.
|
||||
* [ImGui/EnTT editor](https://github.com/Green-Sky/imgui_entt_entity_editor):
|
||||
a drop-in, single-file entity editor for `EnTT` that uses `ImGui` as
|
||||
graphical backend (with
|
||||
[demo code](https://github.com/Green-Sky/imgui_entt_entity_editor_demo)).
|
||||
* [SgOgl](https://github.com/stwe/SgOgl): a game engine library for OpenGL
|
||||
developed for educational purposes.
|
||||
* [Lumos](https://github.com/jmorton06/Lumos): game engine written in C++
|
||||
using OpenGL and Vulkan.
|
||||
* [Silvanus](https://github.com/hobbyistmaker/silvanus): Silvanus Fusion 360
|
||||
Box Generator.
|
||||
* [Lina Engine](https://github.com/inanevin/LinaEngine): an open-source,
|
||||
modular, tiny and fast C++ game engine, aimed to develop 3D desktop games.
|
||||
* [Spike](https://github.com/FahimFuad/Spike): a powerful game engine which
|
||||
can run on a toaster.
|
||||
* [Helena Framework](https://github.com/NIKEA-SOFT/HelenaFramework): a modern
|
||||
framework in C++17 for backend development.
|
||||
* [Unity/EnTT](https://github.com/TongTungGiang/unity-entt): tech demo of a
|
||||
native simulation layer using `EnTT` and `Unity` as a rendering engine.
|
||||
* [OverEngine](https://github.com/OverShifted/OverEngine): an overengineered
|
||||
game engine.
|
||||
* [Electro](https://github.com/Electro-Technologies/Electro): high performance
|
||||
3D game engine with a high emphasis on rendering.
|
||||
* [Kawaii](https://github.com/Mathieu-Lala/Kawaii_Engine): a modern data
|
||||
oriented game engine.
|
||||
* [Becketron](https://github.com/Doctor-Foxling/Becketron): a game engine
|
||||
written mostly in C++.
|
||||
* [Spatial Engine](https://github.com/luizgabriel/Spatial.Engine): a
|
||||
cross-platform engine created on top of Google's filament rendering engine.
|
||||
* [Kaguya](https://github.com/KaiH0717/Kaguya): D3D12 Rendering Engine.
|
||||
* [OpenAWE](https://github.com/OpenAWE-Project/OpenAWE): open implementation
|
||||
of the Alan Wake Engine.
|
||||
* [Nazara Engine](https://github.com/DigitalPulseSoftware/NazaraEngine): fast,
|
||||
cross-platform, object-oriented API to help in daily developer life.
|
||||
* [Billy Engine](https://github.com/billy4479/BillyEngine): some kind of 2D
|
||||
engine based on `SDL2` and `EnTT`.
|
||||
* [Ducktape](https://github.com/DucktapeEngine/Ducktape): an open source C++
|
||||
2D & 3D game engine that focuses on being fast and powerful.
|
||||
* [The Worst Engine](https://github.com/Parasik72/TWE): a game engine based on
|
||||
OpenGL.
|
||||
* [Ecsact](https://ecsact.dev/): a language aimed at describing ECS, with a
|
||||
[runtime implementation](https://github.com/ecsact-dev/ecsact_rt_entt) based
|
||||
on `EnTT`.
|
||||
* [AGE (Arc Game Engine)](https://github.com/MohitSethi99/ArcGameEngine): an
|
||||
open-source engine for building 2D & 3D real-time rendering and interactive
|
||||
contents.
|
||||
* [Kengine](https://github.com/phisko/kengine): the _Koala engine_ is a game
|
||||
engine entirely implemented as an entity-component-system.
|
||||
* [Scion2D](https://github.com/dwjclark11/Scion2D): 2D game engine with
|
||||
[YouTube series](https://www.youtube.com/playlist?list=PL3HUvSWOJR7XRDwVVQqqWO-zyyscb8L-v)
|
||||
included.
|
||||
* [EnTT Editor](https://github.com/TheDimin/EnttEditor): an editor for `EnTT`
|
||||
libary that combines its built-in reflection system with `ImGui`.
|
||||
* [Era Game Engine](https://github.com/EldarMuradov/EraGameEngine): a modern
|
||||
ECS-based game engine.
|
||||
* [Core SDK of Trollworks engine](https://github.com/trollworks/sdk-core): 2D
|
||||
game engine based on procrastination.
|
||||
* [Rocky](https://github.com/pelicanmapping/rocky): 3D geospatial application
|
||||
engine.
|
||||
* [Donner](https://github.com/jwmcglynn/donner): a modern C++20 SVG2 rendering
|
||||
API with CSS3.
|
||||
* [Coral Engine](https://github.com/GuusKemperman/CoralEngine): open-source
|
||||
student engine with the tools to make games in C++ and Visual scripting.
|
||||
* [Star Engine](https://github.com/HODAKdev/StarEngine): an Advanced C++
|
||||
DirectX 11 game engine.
|
||||
* [Darmok](https://github.com/miguelibero/darmok): another C++ game engine.
|
||||
* [Magique](https://github.com/gk646/magique): 2D game engine for programmers
|
||||
(or those yet to be).
|
||||
|
||||
## Articles, videos and blog posts:
|
||||
|
||||
* [Some posts](https://skypjack.github.io/tags/#entt) on my personal
|
||||
[blog](https://skypjack.github.io/) are about `EnTT`, for those who want to
|
||||
know **more** on this project.
|
||||
* [Game Engine series](https://www.youtube.com/c/TheChernoProject/videos) by
|
||||
[The Cherno](https://github.com/TheCherno) (not only about `EnTT` but also
|
||||
on the use of an ECS in general):
|
||||
- [Intro to EnTT](https://www.youtube.com/watch?v=D4hz0wEB978).
|
||||
- [Entities and Components](https://www.youtube.com/watch?v=-B1iu4QJTUc).
|
||||
- [The ENTITY Class](https://www.youtube.com/watch?v=GfSzeAcsBb0).
|
||||
- [Camera Systems](https://www.youtube.com/watch?v=ubZn7BlrnTU).
|
||||
- [Scene Camera](https://www.youtube.com/watch?v=UKVFRRufKzo).
|
||||
- [Native Scripting](https://www.youtube.com/watch?v=iIUhg88MK5M).
|
||||
- [Native Scripting (now with virtual functions!)](https://www.youtube.com/watch?v=1cHEcrIn8IQ).
|
||||
- [Scene Hierarchy Panel](https://www.youtube.com/watch?v=wziDnE8guvI).
|
||||
- [Properties Panel](https://www.youtube.com/watch?v=NBpB0qscF3E).
|
||||
- [Camera Component UI](https://www.youtube.com/watch?v=RIMt_6agUiU).
|
||||
- [Drawing Component UI](https://www.youtube.com/watch?v=u3yq8s3KuSE).
|
||||
- [Transform Component UI](https://www.youtube.com/watch?v=8JqcXYbzPJc).
|
||||
- [Adding/Removing Entities and Components UI](https://www.youtube.com/watch?v=PsyGmsIgp9M).
|
||||
- [Saving and Loading Scenes](https://www.youtube.com/watch?v=IEiOP7Y-Mbc).
|
||||
- ... And so on.
|
||||
[Check out](https://www.youtube.com/channel/UCQ-W1KE9EYfdxhL6S4twUNw) the
|
||||
_Game Engine Series_ by The Cherno for more videos.
|
||||
* [Game Engine series](https://www.youtube.com/@JADE-iteGames/videos) by
|
||||
[dwjclark11](https://github.com/dwjclark11) (not just `EnTT` but a lot of
|
||||
it):
|
||||
- [Getting into ECS](https://youtu.be/k9CbonLopJU?si=za3Tisyc96_92DWM)
|
||||
- [Creating ECS Wrapper Classes](https://youtu.be/yetyuMJRdbo?si=PJTkmap4Ysqbzb_M)
|
||||
- [Runtime Reflection using EnTT meta](https://youtu.be/GrXV5A07GTY?si=fKdWTj9AOhnhtiXq)
|
||||
- [Adding entt::meta and Sol2 bindings](https://youtu.be/IM55JgxOqFA?si=rsbb4AG_NVh4IUmD)
|
||||
(with [part two](https://youtu.be/-PTt-b1tzRw?si=zPJ4vEluyheMcNgO) too)
|
||||
- ... And so on.
|
||||
[Check it out](https://www.youtube.com/playlist?list=PL3HUvSWOJR7XRDwVVQqqWO-zyyscb8L-v)
|
||||
for more videos.
|
||||
* [Warmonger Dynasty devlog series](https://david-delassus.medium.com/list/warmonger-dynasty-devlogs-f64b71f556de)
|
||||
by [linkdd](https://github.com/linkdd): an interesting walkthrough of
|
||||
developing a game (also) with EnTT.
|
||||
* [Use EnTT When You Need An ECS](https://www.codingwiththomas.com/blog/use-entt-when-you-need-an-ecs)
|
||||
by [Thomas](https://www.codingwiththomas.com/): I could not have said it
|
||||
better.
|
||||
* [Space Battle: Huge edition](http://victor.madtriangles.com/code%20experiment/2018/06/11/post-ecs-battle-huge.html):
|
||||
huge space battle built entirely from scratch.
|
||||
* [Space Battle](https://github.com/vblanco20-1/ECS_SpaceBattle): huge space
|
||||
battle built on `UE4`.
|
||||
* [Experimenting with ECS in UE4](http://victor.madtriangles.com/code%20experiment/2018/03/25/post-ue4-ecs-battle.html):
|
||||
interesting article about `UE4` and `EnTT`.
|
||||
* [Implementing ECS architecture in UE4](https://forums.unrealengine.com/development-discussion/c-gameplay-programming/1449913-implementing-ecs-architecture-in-ue4-giant-space-battle):
|
||||
giant space battle.
|
||||
* [Conan Adventures (SFML and EnTT in C++)](https://leinnan.github.io/blog/conan-adventuressfml-and-entt-in-c.html):
|
||||
create projects in modern C++ using `SFML`, `EnTT`, `Conan` and `CMake`.
|
||||
* [Adding EnTT ECS to Chrysalis](https://www.tauradius.com/post/adding-an-ecs-to-chrysalis/):
|
||||
a blog entry (and its
|
||||
[follow-up](https://www.tauradius.com/post/chrysalis-update-2020-08-02/))
|
||||
about the integration of `EnTT` into `Chrysalis`, an action RPG SDK for
|
||||
CRYENGINE games.
|
||||
* [Creating Minecraft in One Week with C++ and Vulkan](https://vazgriz.com/189/creating-minecraft-in-one-week-with-c-and-vulkan/):
|
||||
a crack at recreating Minecraft in one week using a custom C++ engine and
|
||||
Vulkan ([code included](https://github.com/vazgriz/VoxelGame)).
|
||||
* [Ability Creator](https://www.erichildebrand.net/blog/ability-creator-project-retrospect):
|
||||
project retrospect by [Eric Hildebrand](https://www.erichildebrand.net/).
|
||||
* [EnTT Entity Component System Gaming Library](https://gamefromscratch.com/entt-entity-component-system-gaming-library/):
|
||||
`EnTT` on GameFromScratch.com.
|
||||
* [Custom C++ server for UE5](https://youtu.be/fbXZVNCOvjM) optimized for
|
||||
MMO(RPG)s and its [follow-up](https://youtu.be/yGlZeopx2hU) episode about
|
||||
player bots and full external ECS: a series definitely worth looking at.
|
||||
|
||||
## Any Other Business:
|
||||
|
||||
* [ArcGIS Runtime SDKs](https://developers.arcgis.com/arcgis-runtime/) by
|
||||
[Esri](https://www.esri.com/): they use `EnTT` for the internal ECS and the
|
||||
cross-platform C++ rendering engine. The SDKs are used by a lot of
|
||||
enterprise custom apps, as well as by Esri for its own public applications
|
||||
such as
|
||||
[Explorer](https://play.google.com/store/apps/details?id=com.esri.explorer),
|
||||
[Collector](https://play.google.com/store/apps/details?id=com.esri.arcgis.collector)
|
||||
and
|
||||
[Navigator](https://play.google.com/store/apps/details?id=com.esri.navigator).
|
||||
* [FASTSUITE Edition 2](https://www.fastsuite.com/en_EN/fastsuite/fastsuite-edition-2.html)
|
||||
by [Cenit](http://www.cenit.com/en_EN/about-us/overview.html): they use
|
||||
`EnTT` to drive their simulation, that is, the communication between robot
|
||||
controller emulator and renderer.
|
||||
* [Ragdoll](https://ragdolldynamics.com/): real-time physics for Autodesk Maya
|
||||
2020.
|
||||
* [Project Lagrange](https://github.com/adobe/lagrange): a robust geometry
|
||||
processing library by [Adobe](https://github.com/adobe).
|
||||
* [AtomicDEX](https://github.com/KomodoPlatform/atomicDEX-Desktop): a secure
|
||||
wallet and noncustodial decentralized exchange rolled into one application.
|
||||
* [Apparently](https://www.linkedin.com/in/skypjack/)
|
||||
[NIO](https://www.nio.io/): there was a collaboration to make some changes
|
||||
to `EnTT`, at the time used for internal projects.
|
||||
* [Apparently](https://www.linkedin.com/jobs/view/architekt-c%2B%2B-at-tieto-1219512333/)
|
||||
[Tieto](https://www.tieto.com/): they published a job post where `EnTT` was
|
||||
listed on their software stack.
|
||||
* [Sequentity](https://github.com/alanjfs/sequentity): A MIDI-like
|
||||
sequencer/tracker for C++ and `ImGui` (with `Magnum` and `EnTT`).
|
||||
* [EnTT meets Sol2](https://github.com/skaarj1989/entt-meets-sol2): freely
|
||||
available examples of how to combine `EnTT` and `Sol2`.
|
||||
* [Godot meets EnTT](https://github.com/portaloffreedom/godot_entt_example/):
|
||||
a simple example on how to use `EnTT` within
|
||||
[`Godot`](https://godotengine.org/).
|
||||
* [Godot and GameNetworkingSockets meet EnTT](https://github.com/portaloffreedom/godot_entt_net_example):
|
||||
a simple example on how to use `EnTT` and
|
||||
[`GameNetworkingSockets`](https://github.com/ValveSoftware/GameNetworkingSockets)
|
||||
within [`Godot`](https://godotengine.org/).
|
||||
* [MatchOneEntt](https://github.com/mhaemmerle/MatchOneEntt): port of
|
||||
[Match One](https://github.com/sschmid/Match-One) for `Entitas-CSharp`.
|
||||
* GitHub contains also
|
||||
[many other examples](https://github.com/search?o=desc&q=%22skypjack%2Fentt%22&s=indexed&type=Code)
|
||||
of use of `EnTT` from which to take inspiration if interested.
|
||||
82
lib/All/entt/docs/md/locator.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Crash Course: service locator
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Service locator](#service-locator)
|
||||
* [Opaque handles](#opaque-handles)
|
||||
|
||||
# Introduction
|
||||
|
||||
Usually, service locators are tightly bound to the services they expose. It is
|
||||
hard to define a general purpose solution.<br/>
|
||||
This tiny class tries to fill the gap and gets rid of the burden of defining a
|
||||
different specific locator for each application.
|
||||
|
||||
# Service locator
|
||||
|
||||
The service locator API tries to mimic that of `std::optional` and adds some
|
||||
extra functionalities on top of it such as allocator support.<br/>
|
||||
There are a couple of functions to set up a service, namely `emplace` and
|
||||
`allocate_emplace`:
|
||||
|
||||
```cpp
|
||||
entt::locator<interface>::emplace<service>(argument);
|
||||
entt::locator<interface>::allocate_emplace<service>(allocator, argument);
|
||||
```
|
||||
|
||||
The difference is that the latter expects an allocator as the first argument and
|
||||
uses it to allocate the service itself.<br/>
|
||||
Once a service is set up, it is retrieved using the `value` function:
|
||||
|
||||
```cpp
|
||||
interface &service = entt::locator<interface>::value();
|
||||
```
|
||||
|
||||
Since the service may not be set (and therefore this function may result in an
|
||||
undefined behavior), the `has_value` and `value_or` functions are also available
|
||||
to test a service locator and to get a fallback service in case there is none:
|
||||
|
||||
```cpp
|
||||
if(entt::locator<interface>::has_value()) {
|
||||
// ...
|
||||
}
|
||||
|
||||
interface &service = entt::locator<interface>::value_or<fallback_impl>(argument);
|
||||
```
|
||||
|
||||
All arguments are used only if necessary, that is, if a service does not already
|
||||
exist and therefore the fallback service is constructed and returned. In all
|
||||
other cases, they are discarded.<br/>
|
||||
Finally, to reset a service, use the `reset` function.
|
||||
|
||||
## Opaque handles
|
||||
|
||||
Sometimes it is useful to _transfer_ a copy of a service to another locator. For
|
||||
example, when working across boundaries it is common to _share_ a service with a
|
||||
dynamically loaded module.<br/>
|
||||
Options are not much in this case. Among these is the possibility of _exporting_
|
||||
services and assigning them to a different locator.
|
||||
|
||||
This is what the `handle` and `reset` functions are meant for.<br/>
|
||||
The former returns an opaque object useful for _exporting_ (or rather, obtaining
|
||||
a reference to) a service. The latter also accepts an optional argument to a
|
||||
handle which then allows users to reset a service by initializing it with an
|
||||
opaque handle:
|
||||
|
||||
```cpp
|
||||
auto handle = entt::locator<interface>::handle();
|
||||
entt::locator<interface>::reset(handle);
|
||||
```
|
||||
|
||||
It is worth noting that it is possible to get handles for uninitialized services
|
||||
and use them with other locators. Of course, all a user will get is to have an
|
||||
uninitialized service elsewhere as well.
|
||||
|
||||
Note that exporting a service allows users to _share_ the object currently set
|
||||
in a locator. Replacing it will not replace the element, even where a service
|
||||
has been configured with a handle to the previous item.<br/>
|
||||
In other words, if an audio service is replaced with a null object to silence an
|
||||
application and the original service was shared, this operation will not
|
||||
propagate to the other locators. Therefore, a module that shares the ownership
|
||||
of the original audio service is still able to emit sounds.
|
||||
1011
lib/All/entt/docs/md/meta.md
Normal file
351
lib/All/entt/docs/md/poly.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# Crash Course: poly
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Other libraries](#other-libraries)
|
||||
* [Concept and implementation](#concept-and-implementation)
|
||||
* [Deduced interface](#deduced-interface)
|
||||
* [Defined interface](#defined-interface)
|
||||
* [Fulfill a concept](#fulfill-a-concept)
|
||||
* [Inheritance](#inheritance)
|
||||
* [Static polymorphism in the wild](#static-polymorphism-in-the-wild)
|
||||
* [Storage size and alignment requirement](#storage-size-and-alignment-requirement)
|
||||
|
||||
# Introduction
|
||||
|
||||
Static polymorphism is a very powerful tool in C++, albeit sometimes cumbersome
|
||||
to obtain.<br/>
|
||||
This module aims to make it simple and easy to use.
|
||||
|
||||
The library allows to define _concepts_ as interfaces to fulfill with concrete
|
||||
classes without having to inherit from a common base.<br/>
|
||||
Among others, this is one of the advantages of static polymorphism in general
|
||||
and of a generic wrapper like that offered by the `poly` class template in
|
||||
particular.<br/>
|
||||
The result is an object to pass around as such and not through a reference or a
|
||||
pointer, as it happens when it comes to working with dynamic polymorphism.
|
||||
|
||||
Since the `poly` class template makes use of `entt::any` internally, it also
|
||||
supports most of its feature. For example, the possibility to create aliases to
|
||||
existing and thus unmanaged objects. This allows users to exploit the static
|
||||
polymorphism while maintaining ownership of objects.<br/>
|
||||
Likewise, the `poly` class template also benefits from the small buffer
|
||||
optimization offered by the `entt::any` class and therefore minimizes the number
|
||||
of allocations, avoiding them altogether where possible.
|
||||
|
||||
## Other libraries
|
||||
|
||||
There are some very interesting libraries regarding static polymorphism.<br/>
|
||||
The ones that I like more are:
|
||||
|
||||
* [`dyno`](https://github.com/ldionne/dyno): runtime polymorphism done right.
|
||||
* [`Poly`](https://github.com/facebook/folly/blob/master/folly/docs/Poly.md):
|
||||
a class template that makes it easy to define a type-erasing polymorphic
|
||||
object wrapper.
|
||||
|
||||
The former is admittedly an experimental library, with many interesting ideas.
|
||||
I have some doubts about the usefulness of some features in real world projects,
|
||||
but perhaps my lack of experience comes into play here. In my opinion, its only
|
||||
flaw is the API that I find slightly more cumbersome than other solutions.<br/>
|
||||
The latter was undoubtedly a source of inspiration for this module. Although I
|
||||
opted for different choices in the implementation of both the final API and some
|
||||
features.
|
||||
|
||||
Either way, the authors are gurus of the C++ community, people I only have to
|
||||
learn from.
|
||||
|
||||
# Concept and implementation
|
||||
|
||||
The first thing to do to create a _type-erasing polymorphic object wrapper_ (to
|
||||
use the terminology introduced by Eric Niebler) is to define a _concept_ that
|
||||
types will have to adhere to.<br/>
|
||||
For this purpose, the library offers a single class that supports both deduced
|
||||
and fully defined interfaces. Although having interfaces deduced automatically
|
||||
is convenient and allows users to write less code in most cases, it has some
|
||||
limitations. It is therefore useful to be able to get around the deduction by
|
||||
providing a custom definition for the static virtual table.
|
||||
|
||||
Once the interface is defined, a generic implementation is needed to fulfill the
|
||||
concept itself.<br/>
|
||||
Also in this case, the library allows customizations based on types or families
|
||||
of types, so as to be able to go beyond the generic case where necessary.
|
||||
|
||||
## Deduced interface
|
||||
|
||||
This is how a concept with a deduced interface is defined:
|
||||
|
||||
```cpp
|
||||
struct Drawable: entt::type_list<> {
|
||||
template<typename Base>
|
||||
struct type: Base {
|
||||
void draw() { this->template invoke<0>(*this); }
|
||||
};
|
||||
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
It is recognizable by the fact that it inherits from an empty type list.<br/>
|
||||
Functions can also be const, accept any number of parameters and return a type
|
||||
other than `void`:
|
||||
|
||||
```cpp
|
||||
struct Drawable: entt::type_list<> {
|
||||
template<typename Base>
|
||||
struct type: Base {
|
||||
bool draw(int pt) const { return this->template invoke<0>(*this, pt); }
|
||||
};
|
||||
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
In this case, all parameters are passed to `invoke` after the reference to
|
||||
`this` and the return value is whatever the internal call returns.<br/>
|
||||
As for `invoke`, this is a name that is injected into the _concept_ through
|
||||
`Base`, from which one must necessarily inherit. Since it is also a dependent
|
||||
name, the `this-> template` form is unfortunately necessary due to the rules of
|
||||
the language. However, there also exists an alternative that goes through an
|
||||
external call:
|
||||
|
||||
```cpp
|
||||
struct Drawable: entt::type_list<> {
|
||||
template<typename Base>
|
||||
struct type: Base {
|
||||
void draw() const { entt::poly_call<0>(*this); }
|
||||
};
|
||||
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
Once the _concept_ is defined, users must provide a generic implementation of it
|
||||
in order to tell the system how any type can satisfy its requirements. This is
|
||||
done via an alias template within the concept itself.<br/>
|
||||
The index passed as a template parameter to either `invoke` or `poly_call`
|
||||
refers to how this alias is defined.
|
||||
|
||||
## Defined interface
|
||||
|
||||
A fully defined concept is no different to one for which the interface is
|
||||
deduced, with the only difference that the list of types is not empty this time:
|
||||
|
||||
```cpp
|
||||
struct Drawable: entt::type_list<void()> {
|
||||
template<typename Base>
|
||||
struct type: Base {
|
||||
void draw() { entt::poly_call<0>(*this); }
|
||||
};
|
||||
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
Again, parameters and return values other than `void` are allowed. Also, the
|
||||
function type must be const when the method to bind to it is const:
|
||||
|
||||
```cpp
|
||||
struct Drawable: entt::type_list<bool(int) const> {
|
||||
template<typename Base>
|
||||
struct type: Base {
|
||||
bool draw(int pt) const { return entt::poly_call<0>(*this, pt); }
|
||||
};
|
||||
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
Why should a user fully define a concept if the function types are the same as
|
||||
the deduced ones?<br>
|
||||
In fact, this is the limitation that can be worked around by manually defining
|
||||
the static virtual table.
|
||||
|
||||
When things are deduced, there is an implicit constraint.<br/>
|
||||
If the concept exposes a member function called `draw` with function type
|
||||
`void()`, a concept is satisfied:
|
||||
|
||||
* Either by a class that exposes a member function with the same name and the
|
||||
same signature.
|
||||
|
||||
* Or through a lambda that makes use of existing member functions from the
|
||||
interface itself.
|
||||
|
||||
In other words, it is not possible to make use of functions not belonging to the
|
||||
interface, even if they are part of the types that fulfill the concept.<br/>
|
||||
Similarly, it is not possible to deduce a function in the static virtual table
|
||||
with a function type different from that of the associated member function in
|
||||
the interface itself.
|
||||
|
||||
Explicitly defining a static virtual table suppresses the deduction step and
|
||||
allows maximum flexibility when providing the implementation for a concept.
|
||||
|
||||
## Fulfill a concept
|
||||
|
||||
The `impl` alias template of a concept is used to define how it is fulfilled:
|
||||
|
||||
```cpp
|
||||
struct Drawable: entt::type_list<> {
|
||||
// ...
|
||||
|
||||
template<typename Type>
|
||||
using impl = entt::value_list<&Type::draw>;
|
||||
};
|
||||
```
|
||||
|
||||
In this case, it is stated that the `draw` method of a generic type is enough to
|
||||
satisfy the requirements of the `Drawable` concept.<br/>
|
||||
Both member functions and free functions are supported to fulfill concepts:
|
||||
|
||||
```cpp
|
||||
template<typename Type>
|
||||
void print(Type &self) { self.print(); }
|
||||
|
||||
struct Drawable: entt::type_list<void()> {
|
||||
// ...
|
||||
|
||||
template<typename Type>
|
||||
using impl = entt::value_list<&print<Type>>;
|
||||
};
|
||||
```
|
||||
|
||||
Likewise, as long as the parameter types and return type support conversions to
|
||||
and from those of the function type referenced in the static virtual table, the
|
||||
actual implementation may differ in its function type since it is erased
|
||||
internally.<br/>
|
||||
Moreover, the `self` parameter is not strictly required by the system and can be
|
||||
left out for free functions if not required.
|
||||
|
||||
Refer to the inline documentation for more details.
|
||||
|
||||
# Inheritance
|
||||
|
||||
_Concept inheritance_ is straightforward due to how poly looks like in `EnTT`.
|
||||
Therefore, it is quite easy to build hierarchies of concepts if necessary.<br/>
|
||||
The only constraint is that all concepts in a hierarchy must belong to the same
|
||||
_family_, that is, they must be either all deduced or all defined.
|
||||
|
||||
For a deduced concept, inheritance is achieved in a few steps:
|
||||
|
||||
```cpp
|
||||
struct DrawableAndErasable: entt::type_list<> {
|
||||
template<typename Base>
|
||||
struct type: typename Drawable::type<Base> {
|
||||
static constexpr auto base = Drawable::impl<Drawable::type<entt::poly_inspector>>::size;
|
||||
void erase() { entt::poly_call<base + 0>(*this); }
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
using impl = entt::value_list_cat_t<
|
||||
typename Drawable::impl<Type>,
|
||||
entt::value_list<&Type::erase>
|
||||
>;
|
||||
};
|
||||
```
|
||||
|
||||
The static virtual table is empty and must remain so.<br/>
|
||||
On the other hand, `type` no longer inherits from `Base`. Instead, it forwards
|
||||
its template parameter to the type exposed by the _base class_. Internally, the
|
||||
_size_ of the static virtual table of the base class is used as an offset for
|
||||
the local indexes.<br/>
|
||||
Finally, by means of the `value_list_cat_t` utility, the implementation consists
|
||||
in appending the new functions to the previous list.
|
||||
|
||||
As for a defined concept instead, the list of types is _extended_ in a similar
|
||||
way to what is shown for the implementation of the above concept.<br/>
|
||||
To do this, it is useful to declare a function that allows to convert a
|
||||
_concept_ into its underlying `type_list` object:
|
||||
|
||||
```cpp
|
||||
template<typename... Type>
|
||||
entt::type_list<Type...> as_type_list(const entt::type_list<Type...> &);
|
||||
```
|
||||
|
||||
The definition is not strictly required, since the function is only used through
|
||||
a `decltype` as it follows:
|
||||
|
||||
```cpp
|
||||
struct DrawableAndErasable: entt::type_list_cat_t<
|
||||
decltype(as_type_list(std::declval<Drawable>())),
|
||||
entt::type_list<void()>> {
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
Similar to above, `type_list_cat_t` is used to concatenate the underlying static
|
||||
virtual table with the new function types.<br/>
|
||||
Everything else is the same as already shown instead.
|
||||
|
||||
# Static polymorphism in the wild
|
||||
|
||||
Once the _concept_ and implementation are defined, it is possible to use the
|
||||
`poly` class template to _wrap_ instances that meet the requirements:
|
||||
|
||||
```cpp
|
||||
using drawable = entt::poly<Drawable>;
|
||||
|
||||
struct circle {
|
||||
void draw() { /* ... */ }
|
||||
};
|
||||
|
||||
struct square {
|
||||
void draw() { /* ... */ }
|
||||
};
|
||||
|
||||
// ...
|
||||
|
||||
drawable instance{circle{}};
|
||||
instance->draw();
|
||||
|
||||
instance = square{};
|
||||
instance->draw();
|
||||
```
|
||||
|
||||
This class offers a wide range of constructors, from the default one (which
|
||||
returns an uninitialized `poly` object) to the copy and move constructors, as
|
||||
well as the ability to create objects in-place.<br/>
|
||||
Among others, there is also a constructor that allows users to wrap unmanaged
|
||||
objects in a `poly` instance (either const or non-const ones):
|
||||
|
||||
```cpp
|
||||
circle shape;
|
||||
drawable instance{std::in_place_type<circle &>, shape};
|
||||
```
|
||||
|
||||
Similarly, it is possible to create non-owning copies of `poly` from an existing
|
||||
object:
|
||||
|
||||
```cpp
|
||||
drawable other = instance.as_ref();
|
||||
```
|
||||
|
||||
In both cases, although the interface of the `poly` object does not change, it
|
||||
does not construct any element or take care of destroying the referenced
|
||||
objects.
|
||||
|
||||
Note also how the underlying concept is accessed via a call to `operator->` and
|
||||
not directly as `instance.draw()`.<br/>
|
||||
This allows users to decouple the API of the wrapper from that of the concept.
|
||||
Therefore, where `instance.data()` invokes the `data` member function of the
|
||||
poly object, `instance->data()` maps directly to the functionality exposed by
|
||||
the underlying concept.
|
||||
|
||||
# Storage size and alignment requirement
|
||||
|
||||
Under the hood, the `poly` class template makes use of `entt::any`. Therefore,
|
||||
it can take advantage of the possibility of defining at compile-time the size of
|
||||
the storage suitable for the small buffer optimization as well as the alignment
|
||||
requirements:
|
||||
|
||||
```cpp
|
||||
entt::basic_poly<Drawable, sizeof(double[4]), alignof(double[4])>
|
||||
```
|
||||
|
||||
The default size is `sizeof(double[2])`, which seems like a good compromise
|
||||
between a buffer that is too large and one unable to hold anything larger than
|
||||
an integer. The alignment requirement is optional, and by default such that it
|
||||
is the most stringent (the largest) for any object whose size is at most equal
|
||||
to the one provided.<br/>
|
||||
It is worth noting that providing a size of 0 (which is an accepted value in all
|
||||
respects) will force the system to dynamically allocate the contained objects in
|
||||
all cases.
|
||||
211
lib/All/entt/docs/md/process.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# Crash Course: cooperative scheduler
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [The process](#the-process)
|
||||
* [Adaptor](#adaptor)
|
||||
* [The scheduler](#the-scheduler)
|
||||
|
||||
# Introduction
|
||||
|
||||
Processes are a useful tool to work around the strict definition of a system and
|
||||
introduce logic in a different way, usually without resorting to other component
|
||||
types.<br/>
|
||||
`EnTT` offers minimal support to this paradigm by introducing a few classes used
|
||||
to define and execute cooperative processes.
|
||||
|
||||
# The process
|
||||
|
||||
A typical task inherits from the `process` class template that stays true to the
|
||||
CRTP idiom. Moreover, derived classes specify what the intended type for elapsed
|
||||
times is.
|
||||
|
||||
A process should expose publicly the following member functions whether needed
|
||||
(note that it is not required to define a function unless the derived class
|
||||
wants to _override_ the default behavior):
|
||||
|
||||
* `void update(Delta, void *);`
|
||||
|
||||
This is invoked once per tick until a process is explicitly aborted or ends
|
||||
either with or without errors. Technically speaking, this member function is
|
||||
not strictly required. However, 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.
|
||||
|
||||
* `void init();`
|
||||
|
||||
This is invoked when the process joins the running queue of a scheduler. It
|
||||
happens usually when the process is attached to the scheduler if it is a top
|
||||
level one, or when it replaces its parent if it is a _continuation_.
|
||||
|
||||
* `void succeeded();`
|
||||
|
||||
This is invoked in case of success, immediately after an update and during the
|
||||
same tick.
|
||||
|
||||
* `void failed();`
|
||||
|
||||
This is invoked in case of errors, immediately after an update and during the
|
||||
same tick.
|
||||
|
||||
* `void aborted();`
|
||||
|
||||
This is invoked only if a process is explicitly aborted. There is no guarantee
|
||||
that it executes in the same tick, it depends solely on whether the process is
|
||||
aborted immediately or not.
|
||||
|
||||
Derived classes can also change the internal state of a process by invoking
|
||||
`succeed` and `fail`, as well as `pause` and `unpause` the process itself.<br/>
|
||||
All these are protected member functions made available to manage the life cycle
|
||||
of a process from a derived class.
|
||||
|
||||
Here is a minimal example for the sake of curiosity:
|
||||
|
||||
```cpp
|
||||
struct my_process: entt::process<my_process, std::uint32_t> {
|
||||
using delta_type = std::uint32_t;
|
||||
|
||||
my_process(delta_type delay)
|
||||
: remaining{delay}
|
||||
{}
|
||||
|
||||
void update(delta_type delta, void *) {
|
||||
remaining -= std::min(remaining, delta);
|
||||
|
||||
// ...
|
||||
|
||||
if(!remaining) {
|
||||
succeed();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
delta_type remaining;
|
||||
};
|
||||
```
|
||||
|
||||
## Adaptor
|
||||
|
||||
Lambdas and functors cannot be used directly with a scheduler because they are
|
||||
not properly defined processes with managed life cycles.<br/>
|
||||
This class helps in filling the gap and turning lambdas and functors into
|
||||
full-featured processes usable by a scheduler.
|
||||
|
||||
The function call operator has a signature similar to the one of the `update`
|
||||
function of a process but for the fact that it receives two extra callbacks to
|
||||
invoke whenever a process terminates with success or with an error:
|
||||
|
||||
```cpp
|
||||
void(Delta delta, void *data, auto succeed, auto fail);
|
||||
```
|
||||
|
||||
Parameters have the following meaning:
|
||||
|
||||
* `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.
|
||||
|
||||
Both `succeed` and `fail` accept no parameters at all.
|
||||
|
||||
Note that usually users should not worry about creating adaptors at all. A
|
||||
scheduler creates them internally, each and every time a lambda or a functor is
|
||||
used as a process.
|
||||
|
||||
# The scheduler
|
||||
|
||||
A cooperative scheduler runs different processes and helps manage their life
|
||||
cycles.
|
||||
|
||||
Each process is invoked once per tick. If it terminates, it is removed
|
||||
automatically from the scheduler, and it is never invoked again. Otherwise,
|
||||
it is a good candidate to run one more time the next tick.<br/>
|
||||
A process can also have a _child_. In this case, the parent process is replaced
|
||||
with its child when it terminates and only if it returns with success. In case
|
||||
of errors, both the parent process and its child are discarded. This way, it is
|
||||
easy to create a chain of processes to run sequentially.
|
||||
|
||||
Using a scheduler is straightforward. To create it, users must provide only the
|
||||
type for the elapsed times and no arguments at all:
|
||||
|
||||
```cpp
|
||||
entt::basic_scheduler<std::uint64_t> scheduler;
|
||||
```
|
||||
|
||||
Otherwise, the `scheduler` alias is also available for the most common cases. It
|
||||
uses `std::uint32_t` as a default type:
|
||||
|
||||
```cpp
|
||||
entt::scheduler scheduler;
|
||||
```
|
||||
|
||||
The class has member functions to query its internal data structures, like
|
||||
`empty` or `size`, as well as a `clear` utility to reset it to a clean state:
|
||||
|
||||
```cpp
|
||||
// checks if there are processes still running
|
||||
const auto empty = scheduler.empty();
|
||||
|
||||
// gets the number of processes still running
|
||||
entt::scheduler::size_type size = scheduler.size();
|
||||
|
||||
// resets the scheduler to its initial state and discards all the processes
|
||||
scheduler.clear();
|
||||
```
|
||||
|
||||
To attach a process to a scheduler, there are mainly two ways:
|
||||
|
||||
* If the process inherits from the `process` class template, it is enough to
|
||||
indicate its type and submit all the parameters required to construct it to
|
||||
the `attach` member function:
|
||||
|
||||
```cpp
|
||||
scheduler.attach<my_process>(1000u);
|
||||
```
|
||||
|
||||
* Otherwise, in case of a lambda or a functor, it is enough to provide an
|
||||
instance of the class to the `attach` member function:
|
||||
|
||||
```cpp
|
||||
scheduler.attach([](auto...){ /* ... */ });
|
||||
```
|
||||
|
||||
In both cases, the scheduler is returned and its `then` member function can be
|
||||
used to create chains of processes to run sequentially.<br/>
|
||||
As a minimal example of use:
|
||||
|
||||
```cpp
|
||||
// schedules a task in the form of a lambda function
|
||||
scheduler.attach([](auto delta, void *, auto succeed, auto fail) {
|
||||
// ...
|
||||
})
|
||||
// appends a child in the form of another lambda function
|
||||
.then([](auto delta, void *, auto succeed, auto fail) {
|
||||
// ...
|
||||
})
|
||||
// appends a child in the form of a process class
|
||||
.then<my_process>(1000u);
|
||||
```
|
||||
|
||||
To update a scheduler and therefore all its processes, the `update` member
|
||||
function is the way to go:
|
||||
|
||||
```cpp
|
||||
// updates all the processes, no user data are provided
|
||||
scheduler.update(delta);
|
||||
|
||||
// updates all the processes and provides them with custom data
|
||||
scheduler.update(delta, &data);
|
||||
```
|
||||
|
||||
In addition to these functions, the scheduler offers an `abort` member function
|
||||
that is used to discard all the running processes at once:
|
||||
|
||||
```cpp
|
||||
// aborts all the processes abruptly ...
|
||||
scheduler.abort(true);
|
||||
|
||||
// ... or gracefully during the next tick
|
||||
scheduler.abort();
|
||||
```
|
||||
91
lib/All/entt/docs/md/reference.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Similar projects
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Similar projects](#similar-projects)
|
||||
|
||||
# Introduction
|
||||
|
||||
There are many projects similar to `EnTT`, both open source and not.<br/>
|
||||
Some even borrowed some ideas from this library and expressed them in different
|
||||
languages.<br/>
|
||||
Others developed different architectures from scratch and therefore offer
|
||||
alternative solutions with their pros and cons.
|
||||
|
||||
If you know of other similar projects out there, feel free to open an issue or a
|
||||
PR, and I will be glad to add them to this page.<br/>
|
||||
I hope the following lists can grow much more in the future.
|
||||
|
||||
# Similar projects
|
||||
|
||||
Below an incomplete list of similar projects that I have come across so
|
||||
far.<br/>
|
||||
If some terms or designs are not clear, I recommend referring to the
|
||||
[_ECS Back and Forth_](https://skypjack.github.io/tags/#ecs) series for all the
|
||||
details.
|
||||
|
||||
* C:
|
||||
* [destral_ecs](https://github.com/roig/destral_ecs): a single-file ECS based
|
||||
on sparse sets.
|
||||
* [Diana](https://github.com/discoloda/Diana): an ECS that uses sparse sets to
|
||||
keep track of entities in systems.
|
||||
* [Flecs](https://github.com/SanderMertens/flecs): a multithreaded archetype
|
||||
ECS based on semi-contiguous arrays rather than chunks.
|
||||
* [lent](https://github.com/nem0/lent): the Donald Trump of the ECS libraries.
|
||||
|
||||
* C++:
|
||||
* [decs](https://github.com/vblanco20-1/decs): a chunk-based archetype ECS.
|
||||
* [ecst](https://github.com/SuperV1234/ecst): a multithreaded compile-time
|
||||
ECS that uses sparse sets to keep track of entities in systems.
|
||||
* [EntityX](https://github.com/alecthomas/entityx): a bitset based ECS that
|
||||
uses a single large matrix of components indexed with entities.
|
||||
* [Gaia-ECS](https://github.com/richardbiely/gaia-ecs): a chunk-based
|
||||
archetype ECS.
|
||||
* [Polypropylene](https://github.com/pmbittner/Polypropylene): a hybrid
|
||||
solution between an ECS and dynamic mixins.
|
||||
|
||||
* C#
|
||||
* [Arch](https://github.com/genaray/Arch): a simple, fast and _unity entities_
|
||||
inspired archetype ECS with optional multithreading.
|
||||
* [Entitas](https://github.com/sschmid/Entitas-CSharp): the ECS framework for
|
||||
C# and Unity, where _reactive systems_ were invented.
|
||||
* [Fennecs](https://github.com/outfox/fennecs): the little archetype ECS that
|
||||
loves you back.
|
||||
* [Friflo ECS](https://github.com/friflo/Friflo.Engine.ECS): an archetype ECS
|
||||
with focus on performance and minimal GC allocations.
|
||||
* [LeoECS](https://github.com/Leopotam/ecs): simple lightweight C# Entity
|
||||
Component System framework.
|
||||
* [Massive ECS](https://github.com/nilpunch/massive): sparse set based ECS
|
||||
featuring rollbacks.
|
||||
* [Svelto.ECS](https://github.com/sebas77/Svelto.ECS): a very interesting
|
||||
platform-agnostic and table-based ECS framework.
|
||||
|
||||
* Go:
|
||||
* [gecs](https://github.com/tutumagi/gecs): a sparse sets based ECS inspired
|
||||
by `EnTT`.
|
||||
|
||||
* Javascript:
|
||||
* [\@javelin/ecs](https://github.com/3mcd/javelin/tree/master/packages/ecs):
|
||||
an archetype ECS in TypeScript.
|
||||
* [ecsy](https://github.com/MozillaReality/ecsy): I have not had the time to
|
||||
investigate the underlying design of `ecsy` but it looks cool anyway.
|
||||
|
||||
* Perl:
|
||||
* [Game::Entities](https://gitlab.com/jjatria/perl-game-entities): a simple
|
||||
entity registry for ECS designs inspired by `EnTT`.
|
||||
|
||||
* Raku:
|
||||
* [Game::Entities](https://gitlab.com/jjatria/raku-game-entities): a simple
|
||||
entity registry for ECS designs inspired by `EnTT`.
|
||||
|
||||
* Rust:
|
||||
* [Shipyard](https://github.com/leudz/shipyard): it borrows some ideas from
|
||||
`EnTT` and offers a sparse sets based ECS with grouping functionalities.
|
||||
* [Sparsey](https://github.com/LechintanTudor/sparsey): sparse set based ECS
|
||||
written in Rust.
|
||||
* [Specs](https://github.com/amethyst/specs): a parallel ECS based mainly on
|
||||
hierarchical bitsets that allows different types of storage as needed.
|
||||
|
||||
* Zig
|
||||
* [zig-ecs](https://github.com/prime31/zig-ecs): a _zig-ification_ of `EnTT`.
|
||||
186
lib/All/entt/docs/md/resource.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# Crash Course: resource management
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [The resource, the loader and the cache](#the-resource-the-loader-and-the-cache)
|
||||
* [Resource handle](#resource-handle)
|
||||
* [Loaders](#loaders)
|
||||
* [The cache class](#the-cache-class)
|
||||
|
||||
# Introduction
|
||||
|
||||
Resource management is usually one of the most critical parts of a game.
|
||||
Solutions are often tuned to the particular application. There exist several
|
||||
approaches and all of them are perfectly fine as long as they fit the
|
||||
requirements of the piece of software in which they are used.<br/>
|
||||
Examples are loading everything on start, loading on request, predictive
|
||||
loading, and so on.
|
||||
|
||||
`EnTT` does not pretend to offer a _one-fits-all_ solution for the different
|
||||
cases.<br/>
|
||||
Instead, the library comes with a minimal, general purpose resource cache that
|
||||
might be useful in many cases.
|
||||
|
||||
# The resource, the loader and the cache
|
||||
|
||||
Resource, loader and cache are the three main actors for the purpose.<br/>
|
||||
The _resource_ is an image, an audio, a video or any other type:
|
||||
|
||||
```cpp
|
||||
struct my_resource { const int value; };
|
||||
```
|
||||
|
||||
The _loader_ is a callable type, the aim of which is to load a specific
|
||||
resource:
|
||||
|
||||
```cpp
|
||||
struct my_loader final {
|
||||
using result_type = std::shared_ptr<my_resource>;
|
||||
|
||||
result_type operator()(int value) const {
|
||||
// ...
|
||||
return std::make_shared<my_resource>(value);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Its function operator can accept any arguments and should return a value of the
|
||||
declared result type (`std::shared_ptr<my_resource>` in the example).<br/>
|
||||
A loader can also overload its function call operator to make it possible to
|
||||
construct the same or another resource from different lists of arguments.
|
||||
|
||||
Finally, a cache is a specialization of a class template tailored to a specific
|
||||
resource and (optionally) a loader:
|
||||
|
||||
```cpp
|
||||
using my_cache = entt::resource_cache<my_resource, my_loader>;
|
||||
|
||||
// ...
|
||||
|
||||
my_cache cache{};
|
||||
```
|
||||
|
||||
The class is designed to create different caches for different resource types
|
||||
and to manage each one independently in the most appropriate way.<br/>
|
||||
As a (very) trivial example, audio tracks can survive in most of the scenes of
|
||||
an application while meshes can be associated with a single scene only, then
|
||||
discarded when a player leaves it.
|
||||
|
||||
## Resource handle
|
||||
|
||||
Resources are not returned directly to the caller. Instead, they are wrapped in
|
||||
a _resource handle_, an instance of the `entt::resource` class template.<br/>
|
||||
For those who know the _flyweight design pattern_ already, that is exactly what
|
||||
it is. To all others, this is the time to brush up on some notions instead.
|
||||
|
||||
A shared pointer could have been used as a resource handle. In fact, the default
|
||||
implementation mostly maps the interface of its standard counterpart and only
|
||||
adds a few things on top of it.<br/>
|
||||
However, the handle in `EnTT` is designed as a standalone class template. This
|
||||
is due to the fact that specializing a class in the standard library is often
|
||||
undefined behavior while having the ability to specialize the handle for one,
|
||||
more or all resource types could help over time.
|
||||
|
||||
## Loaders
|
||||
|
||||
A loader is responsible for _loading_ resources (quite obviously).<br/>
|
||||
By default, it is just a callable object that forwards its arguments to the
|
||||
resource itself. That is, a _passthrough type_. All the work is demanded to the
|
||||
constructor(s) of the resource itself.<br/>
|
||||
Loaders also are fully customizable as expected.
|
||||
|
||||
A custom loader is a class with at least one function call operator and a member
|
||||
type named `result_type`.<br/>
|
||||
The loader is not required to return a resource handle. As long as `return_type`
|
||||
is suitable for constructing a handle, that is fine.
|
||||
|
||||
When using the default handle, it expects a resource type which is convertible
|
||||
to or suitable for constructing an `std::shared_ptr<Type>` (where `Type` is the
|
||||
actual resource type).<br/>
|
||||
In other terms, the loader should return shared pointers to the given resource
|
||||
type. However, this is not mandatory. Users can easily get around this
|
||||
constraint by specializing both the handle and the loader.
|
||||
|
||||
A cache forwards all its arguments to the loader if required. This means that
|
||||
loaders can also support tag dispatching to offer different loading policies:
|
||||
|
||||
```cpp
|
||||
struct my_loader {
|
||||
using result_type = std::shared_ptr<my_resource>;
|
||||
|
||||
struct from_disk_tag{};
|
||||
struct from_network_tag{};
|
||||
|
||||
template<typename Args>
|
||||
result_type operator()(from_disk_tag, Args&&... args) {
|
||||
// ...
|
||||
return std::make_shared<my_resource>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename Args>
|
||||
result_type operator()(from_network_tag, Args&&... args) {
|
||||
// ...
|
||||
return std::make_shared<my_resource>(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This makes the whole loading logic quite flexible and easy to extend over time.
|
||||
|
||||
## The cache class
|
||||
|
||||
The cache is the class that is asked to _connect the dots_.<br/>
|
||||
It loads the resources, stores them aside and returns handles as needed:
|
||||
|
||||
```cpp
|
||||
entt::resource_cache<my_resource, my_loader> cache{};
|
||||
```
|
||||
|
||||
Under the hood, a cache is nothing more than a map where the key value has type
|
||||
`entt::id_type` while the mapped value is whatever type its loader returns.<br/>
|
||||
For this reason, it offers most of the functionalities a user would expect from
|
||||
a map, such as `empty` or `size` and so on. Similarly, it is an iterable type
|
||||
that also supports indexing by resource id:
|
||||
|
||||
```cpp
|
||||
for(auto [id, res]: cache) {
|
||||
// ...
|
||||
}
|
||||
|
||||
if(entt::resource<my_resource> res = cache["resource/id"_hs]; res) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Please, refer to the inline documentation for all the details about the other
|
||||
functions (such as `contains` or `erase`).
|
||||
|
||||
Set aside the part of the API that this class _shares_ with a map, it also adds
|
||||
something on top of it in order to address the most common requirements of a
|
||||
resource cache.<br/>
|
||||
In particular, it does not have an `emplace` member function which is replaced
|
||||
by `load` and `force_load` instead (where the former loads a new resource only
|
||||
if not present while the second triggers a forced loading in any case):
|
||||
|
||||
```cpp
|
||||
auto ret = cache.load("resource/id"_hs);
|
||||
|
||||
// true only if the resource was not already present
|
||||
const bool loaded = ret.second;
|
||||
|
||||
// takes the resource handle pointed to by the returned iterator
|
||||
entt::resource<my_resource> res = ret.first->second;
|
||||
```
|
||||
|
||||
Note that the hashed string is used for convenience in the example above.<br/>
|
||||
Resource identifiers are nothing more than integral values. Therefore, plain
|
||||
numbers as well as non-class enum value are accepted.
|
||||
|
||||
It is worth mentioning that the iterators of a cache as well as its indexing
|
||||
operators return resource handles rather than instances of the mapped type.<br/>
|
||||
Since the cache has no control over the loader and a resource is not required to
|
||||
also be convertible to bool, these handles can be invalid. This usually means an
|
||||
error in the user logic, but it may also be an _expected_ event.<br/>
|
||||
It is therefore recommended to verify handles validity with a check in debug
|
||||
(for example, when loading) or an appropriate logic in retail.
|
||||
559
lib/All/entt/docs/md/signal.md
Normal file
@@ -0,0 +1,559 @@
|
||||
# Crash Course: events, signals and everything in between
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Delegate](#delegate)
|
||||
* [Runtime arguments](#runtime-arguments)
|
||||
* [Lambda support](#lambda-support)
|
||||
* [Raw access](#raw-access)
|
||||
* [Signals](#signals)
|
||||
* [Event dispatcher](#event-dispatcher)
|
||||
* [Named queues](#named-queues)
|
||||
* [Event emitter](#event-emitter)
|
||||
|
||||
# Introduction
|
||||
|
||||
Signals are more often than not a core part of games and software architectures
|
||||
in general.<br/>
|
||||
They help to decouple the various parts of a system while allowing them to
|
||||
communicate with each other somehow.
|
||||
|
||||
The so-called _modern C++_ comes with a tool that can be useful in this regard,
|
||||
the `std::function`. As an example, it can be used to create delegates.<br/>
|
||||
However, there is no guarantee that an `std::function` does not perform
|
||||
allocations under the hood and this could be problematic sometimes. Furthermore,
|
||||
it solves a problem but may not adapt well to other requirements that may arise
|
||||
from time to time.
|
||||
|
||||
In case that the flexibility and power of an `std::function` is not required or
|
||||
if the price to pay for them is too high, `EnTT` offers a complete set of
|
||||
lightweight classes to solve the same and many other problems.
|
||||
|
||||
# Delegate
|
||||
|
||||
A delegate can be used as a general purpose invoker with no memory overhead for
|
||||
free functions, lambdas and members provided along with an instance on which to
|
||||
invoke them.<br/>
|
||||
It does not claim to be a drop-in replacement for an `std::function`, so do not
|
||||
expect to use it whenever an `std::function` fits well. That said, it is most
|
||||
likely even a better fit than an `std::function` in a lot of cases, so expect to
|
||||
use it quite a lot anyway.
|
||||
|
||||
The interface is trivial. It offers a default constructor to create empty
|
||||
delegates:
|
||||
|
||||
```cpp
|
||||
entt::delegate<int(int)> delegate{};
|
||||
```
|
||||
|
||||
What is needed to create an instance is to specify the type of the function the
|
||||
delegate _accepts_, that is the signature of the functions it models.<br/>
|
||||
However, attempting to use an empty delegate by invoking its function call
|
||||
operator results in undefined behavior or most likely a crash.
|
||||
|
||||
There exist a few overloads of the `connect` member function to initialize a
|
||||
delegate:
|
||||
|
||||
```cpp
|
||||
int f(int i) { return i; }
|
||||
|
||||
struct my_struct {
|
||||
int f(const int &i) const { return i; }
|
||||
};
|
||||
|
||||
// bind a free function to the delegate
|
||||
delegate.connect<&f>();
|
||||
|
||||
// bind a member function to the delegate
|
||||
my_struct instance;
|
||||
delegate.connect<&my_struct::f>(instance);
|
||||
```
|
||||
|
||||
The delegate class also accepts data members, if needed. In this case, the
|
||||
function type of the delegate is such that the parameter list is empty and the
|
||||
value of the data member is at least convertible to the return type.
|
||||
|
||||
Free functions having type equivalent to `void(T &, args...)` are accepted as
|
||||
well. The first argument `T &` is considered a payload, and the function will
|
||||
receive it back every time it is invoked. In other terms, this works just fine
|
||||
with the above definition:
|
||||
|
||||
```cpp
|
||||
void g(const char &c, int i) { /* ... */ }
|
||||
const char c = 'c';
|
||||
|
||||
delegate.connect<&g>(c);
|
||||
delegate(42);
|
||||
```
|
||||
|
||||
Function `g` is invoked with a reference to `c` and `42`. However, the function
|
||||
type of the delegate is still `void(int)`. This is also the signature of its
|
||||
function call operator.<br/>
|
||||
Another interesting aspect of the delegate class is that it accepts functions
|
||||
with a list of parameters that is shorter than that of its function type:
|
||||
|
||||
```cpp
|
||||
void g() { /* ... */ }
|
||||
delegate.connect<&g>();
|
||||
delegate(42);
|
||||
```
|
||||
|
||||
Where the function type of the delegate is `void(int)` as above. It goes without
|
||||
saying that the extra arguments are silently discarded internally. This is a
|
||||
nice-to-have feature in a lot of cases, as an example when the `delegate` class
|
||||
is used as a building block of a signal-slot system.<br/>
|
||||
In fact, this filtering works both ways. The class tries to pass its first
|
||||
_count_ arguments **first**, then the last _count_. Watch out for conversion
|
||||
rules if in doubt when connecting a listener!<br/>
|
||||
Arbitrary functions that pull random arguments from the delegate list are not
|
||||
supported instead. Other features were preferred, such as support for functions
|
||||
with compatible argument lists although not equal to those of the delegate.
|
||||
|
||||
To create and initialize a delegate at once, there are a few specialized
|
||||
constructors. Because of the rules of the language, the listener is provided by
|
||||
means of the `entt::connect_arg` variable template:
|
||||
|
||||
```cpp
|
||||
entt::delegate<int(int)> func{entt::connect_arg<&f>};
|
||||
```
|
||||
|
||||
Aside `connect`, a `disconnect` counterpart is not provided. Instead, there
|
||||
exists a `reset` member function to use to clear a delegate.<br/>
|
||||
To know if a delegate is empty, it can be used explicitly in every conditional
|
||||
statement:
|
||||
|
||||
```cpp
|
||||
if(delegate) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Finally, to invoke a delegate, the function call operator is the way to go as
|
||||
already shown in the examples above:
|
||||
|
||||
```cpp
|
||||
auto ret = delegate(42);
|
||||
```
|
||||
|
||||
In all cases, listeners do not have to strictly follow the signature of the
|
||||
delegate. As long as a listener can be invoked with the given arguments to yield
|
||||
a result that is convertible to the given result type, everything works just
|
||||
fine.
|
||||
|
||||
As a side note, members of classes may or may not be associated with instances.
|
||||
If they are not, the first argument of the function type must be that of the
|
||||
class on which the members operate, and an instance of this class must obviously
|
||||
be passed when invoking the delegate:
|
||||
|
||||
```cpp
|
||||
entt::delegate<void(my_struct &, int)> delegate;
|
||||
delegate.connect<&my_struct::f>();
|
||||
|
||||
my_struct instance;
|
||||
delegate(instance, 42);
|
||||
```
|
||||
|
||||
In this case, it is not possible to _deduce_ the function type since the first
|
||||
argument does not necessarily have to be a reference (for example, it can be a
|
||||
pointer, as well as a const reference).<br/>
|
||||
Therefore, the function type must be declared explicitly for unbound members.
|
||||
|
||||
## Runtime arguments
|
||||
|
||||
The `delegate` class is meant to be used primarily with template arguments.
|
||||
However, as a consequence of its design, it also offers minimal support for
|
||||
runtime arguments.<br/>
|
||||
When used like this, some features are not supported though. In particular:
|
||||
|
||||
* Curried functions are not accepted.
|
||||
* Functions with an argument list that differs from that of the delegate are not
|
||||
supported.
|
||||
* Return type and types of arguments **must** coincide with those of the
|
||||
delegate and _being at least convertible_ is not enough anymore.
|
||||
|
||||
Moreover, for a given function type `Ret(Args...)`, the signature of the
|
||||
functions connected at runtime must necessarily be `Ret(const void *, Args...)`.
|
||||
|
||||
Runtime arguments can be passed both to the constructor of a delegate and to the
|
||||
`connect` member function. An optional parameter is also accepted in both cases.
|
||||
This argument is used to pass arbitrary user data back and forth as a
|
||||
`const void *` upon invocation.<br/>
|
||||
To connect a function to a delegate _in the hard way_:
|
||||
|
||||
```cpp
|
||||
int func(const void *ptr, int i) { return *static_cast<const int *>(ptr) * i; }
|
||||
const int value = 42;
|
||||
|
||||
// use the constructor ...
|
||||
entt::delegate delegate{&func, &value};
|
||||
|
||||
// ... or the connect member function
|
||||
delegate.connect(&func, &value);
|
||||
```
|
||||
|
||||
The type of the delegate is deduced from the function if possible. In this case,
|
||||
since the first argument is an implementation detail, the deduced function type
|
||||
is `int(int)`.<br/>
|
||||
Invoking a delegate built in this way follows the same rules as previously
|
||||
explained.
|
||||
|
||||
## Lambda support
|
||||
|
||||
In general, the `delegate` class does not fully support lambda functions in all
|
||||
their nuances. The reason is pretty simple: a `delegate` is not a drop-in
|
||||
replacement for an `std::function`. Instead, it tries to overcome the problems
|
||||
with the latter.<br/>
|
||||
That being said, non-capturing lambda functions are supported, even though some
|
||||
features are not available in this case.
|
||||
|
||||
This is a logical consequence of the support for connecting functions at
|
||||
runtime. Therefore, lambda functions undergo the same rules and
|
||||
limitations.<br/>
|
||||
In fact, since non-capturing lambda functions decay to pointers to functions,
|
||||
they can be used with a `delegate` as if they were _normal functions_ with
|
||||
optional payload:
|
||||
|
||||
```cpp
|
||||
my_struct instance;
|
||||
|
||||
// use the constructor ...
|
||||
entt::delegate delegate{+[](const void *ptr, int value) {
|
||||
return static_cast<const my_struct *>(ptr)->f(value);
|
||||
}, &instance};
|
||||
|
||||
// ... or the connect member function
|
||||
delegate.connect([](const void *ptr, int value) {
|
||||
return static_cast<const my_struct *>(ptr)->f(value);
|
||||
}, &instance);
|
||||
```
|
||||
|
||||
As above, the first parameter (`const void *`) is not part of the function type
|
||||
of the delegate and is used to dispatch arbitrary user data back and forth. In
|
||||
other terms, the function type of the delegate above is `int(int)`.
|
||||
|
||||
## Raw access
|
||||
|
||||
While not recommended, a delegate also allows direct access to the stored
|
||||
callable function target and underlying data, if any.<br/>
|
||||
This makes it possible to bypass the behavior of the delegate itself and force
|
||||
calls on different instances:
|
||||
|
||||
```cpp
|
||||
my_struct other;
|
||||
delegate.target(&other, 42);
|
||||
```
|
||||
|
||||
It goes without saying that this type of approach is **very** risky, especially
|
||||
since there is no way of knowing whether the contained function was originally a
|
||||
member function of some class, a free function or a lambda.<br/>
|
||||
Another possible (and meaningful) use of this feature is that of identifying a
|
||||
particular delegate through its descriptive _traits_ instead.
|
||||
|
||||
# Signals
|
||||
|
||||
Signal handlers work with references to classes, function pointers, and pointers
|
||||
to members. Listeners can be any kind of objects, and users are in charge of
|
||||
connecting and disconnecting them from a signal to avoid crashes due to
|
||||
different lifetimes. On the other side, performance should not be affected that
|
||||
much by the presence of such a signal handler.<br/>
|
||||
Signals make use of delegates internally, and therefore they undergo the same
|
||||
rules and offer similar functionalities. It may be a good idea to consult the
|
||||
documentation of the `delegate` class for further information.
|
||||
|
||||
A signal handler is can be used as a private data member without exposing any
|
||||
_publish_ functionality to the clients of a class.<br/>
|
||||
The basic idea is to impose a clear separation between the signal itself and the
|
||||
`sink` class, that is a tool to be used to connect and disconnect listeners on
|
||||
the fly.
|
||||
|
||||
The API of a signal handler is straightforward. If a collector is supplied to
|
||||
the signal when something is published, all the values returned by its listeners
|
||||
are literally _collected_ and used later by the caller. Otherwise, the class
|
||||
works just like a plain signal that emits events from time to time.<br/>
|
||||
To create instances of signal handlers it is sufficient to provide the type of
|
||||
function to which they refer:
|
||||
|
||||
```cpp
|
||||
entt::sigh<void(int, char)> signal;
|
||||
```
|
||||
|
||||
Signals offer all the basic functionalities required to know how many listeners
|
||||
they contain (`size`) or if they contain at least a listener (`empty`), as well
|
||||
as a function to use to swap handlers (`swap`).
|
||||
|
||||
Besides them, there are member functions to use both to connect and disconnect
|
||||
listeners in all their forms by means of a sink:
|
||||
|
||||
```cpp
|
||||
void foo(int, char) { /* ... */ }
|
||||
|
||||
struct listener {
|
||||
void bar(const int &, char) { /* ... */ }
|
||||
};
|
||||
|
||||
// ...
|
||||
|
||||
entt::sink sink{signal};
|
||||
listener instance;
|
||||
|
||||
sink.connect<&foo>();
|
||||
sink.connect<&listener::bar>(instance);
|
||||
|
||||
// ...
|
||||
|
||||
// disconnects a free function
|
||||
sink.disconnect<&foo>();
|
||||
|
||||
// disconnect a member function of an instance
|
||||
sink.disconnect<&listener::bar>(instance);
|
||||
|
||||
// disconnect all member functions of an instance, if any
|
||||
sink.disconnect(&instance);
|
||||
|
||||
// discards all listeners at once
|
||||
sink.disconnect();
|
||||
```
|
||||
|
||||
As shown above, listeners do not have to strictly follow the signature of the
|
||||
signal. As long as a listener can be invoked with the given arguments to yield a
|
||||
result that is convertible to the given return type, everything works just
|
||||
fine.<br/>
|
||||
In all cases, the `connect` member function returns by default a `connection`
|
||||
object to be used as an alternative to break a connection by means of its
|
||||
`release` member function.<br/>
|
||||
A `scoped_connection` can also be created from a connection. In this case, the
|
||||
link is broken automatically as soon as the object goes out of scope.
|
||||
|
||||
Once listeners are attached (or even if there are no listeners at all), events
|
||||
and data in general are published through a signal by means of the `publish`
|
||||
member function:
|
||||
|
||||
```cpp
|
||||
signal.publish(42, 'c');
|
||||
```
|
||||
|
||||
To collect data, the `collect` member function is used instead:
|
||||
|
||||
```cpp
|
||||
int f() { return 0; }
|
||||
int g() { return 1; }
|
||||
|
||||
// ...
|
||||
|
||||
entt::sigh<int()> signal;
|
||||
entt::sink sink{signal};
|
||||
|
||||
sink.connect<&f>();
|
||||
sink.connect<&g>();
|
||||
|
||||
std::vector<int> vec{};
|
||||
signal.collect([&vec](int value) { vec.push_back(value); });
|
||||
|
||||
assert(vec[0] == 0);
|
||||
assert(vec[1] == 1);
|
||||
```
|
||||
|
||||
A collector must expose a function operator that accepts as an argument a type
|
||||
to which the return type of the listeners can be converted. Moreover, it can
|
||||
optionally return a boolean value that is true to stop collecting data, false
|
||||
otherwise. This way one can avoid calling all the listeners in case it is not
|
||||
necessary.<br/>
|
||||
Functors can also be used in place of a lambda. Since the collector is copied
|
||||
when invoking the `collect` member function, `std::ref` is the way to go in this
|
||||
case:
|
||||
|
||||
```cpp
|
||||
struct my_collector {
|
||||
std::vector<int> vec{};
|
||||
|
||||
bool operator()(int v) {
|
||||
vec.push_back(v);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// ...
|
||||
|
||||
my_collector collector;
|
||||
signal.collect(std::ref(collector));
|
||||
```
|
||||
|
||||
# Event dispatcher
|
||||
|
||||
The event dispatcher class allows users to trigger immediate events or to queue
|
||||
and publish them all together later.<br/>
|
||||
This class lazily instantiates its queues. Therefore, it is not necessary to
|
||||
_announce_ the event types in advance:
|
||||
|
||||
```cpp
|
||||
// define a general purpose dispatcher
|
||||
entt::dispatcher dispatcher{};
|
||||
```
|
||||
|
||||
A listener registered with a dispatcher is such that its type offers one or more
|
||||
member functions that take arguments of type `Event &` for any type of event,
|
||||
regardless of the return value.<br/>
|
||||
These functions are linked directly via `connect` to a _sink_:
|
||||
|
||||
```cpp
|
||||
struct an_event { int value; };
|
||||
struct another_event {};
|
||||
|
||||
struct listener {
|
||||
void receive(const an_event &) { /* ... */ }
|
||||
void method(const another_event &) { /* ... */ }
|
||||
};
|
||||
|
||||
// ...
|
||||
|
||||
listener listener;
|
||||
dispatcher.sink<an_event>().connect<&listener::receive>(listener);
|
||||
dispatcher.sink<another_event>().connect<&listener::method>(listener);
|
||||
```
|
||||
|
||||
Note that connecting listeners within event handlers can result in undefined
|
||||
behavior.<br/>
|
||||
The `disconnect` member function is used to remove one listener at a time or all
|
||||
of them at once:
|
||||
|
||||
```cpp
|
||||
dispatcher.sink<an_event>().disconnect<&listener::receive>(listener);
|
||||
dispatcher.sink<another_event>().disconnect(&listener);
|
||||
```
|
||||
|
||||
The `trigger` member function serves the purpose of sending an immediate event
|
||||
to all the listeners registered so far:
|
||||
|
||||
```cpp
|
||||
dispatcher.trigger(an_event{42});
|
||||
dispatcher.trigger<another_event>();
|
||||
```
|
||||
|
||||
Listeners are invoked immediately, order of execution is not guaranteed. This
|
||||
method can be used to push around urgent messages like an _is terminating_
|
||||
notification on a mobile app.
|
||||
|
||||
On the other hand, the `enqueue` member function queues messages together and
|
||||
helps to maintain control over the moment they are sent to listeners:
|
||||
|
||||
```cpp
|
||||
dispatcher.enqueue<an_event>(42);
|
||||
dispatcher.enqueue(another_event{});
|
||||
```
|
||||
|
||||
Events are stored aside until the `update` member function is invoked:
|
||||
|
||||
```cpp
|
||||
// emits all the events of the given type at once
|
||||
dispatcher.update<an_event>();
|
||||
|
||||
// emits all the events queued so far at once
|
||||
dispatcher.update();
|
||||
```
|
||||
|
||||
This way users can embed the dispatcher in a loop and literally dispatch events
|
||||
once per tick to their systems.
|
||||
|
||||
## Named queues
|
||||
|
||||
All queues within a dispatcher are associated by default with an event type and
|
||||
then retrieved from it.<br/>
|
||||
However, it is possible to create queues with different _names_ (and therefore
|
||||
also multiple queues for a single type). In fact, more or less all functions
|
||||
also take an additional parameter. As an example:
|
||||
|
||||
```cpp
|
||||
dispatcher.sink<an_event>("custom"_hs).connect<&listener::receive>(listener);
|
||||
```
|
||||
|
||||
In this case, the term _name_ is misused as these are actual numeric identifiers
|
||||
of type `id_type`.<br/>
|
||||
An exception to this rule is the `enqueue` function. There is no additional
|
||||
parameter for it but rather a different function:
|
||||
|
||||
```cpp
|
||||
dispatcher.enqueue_hint<an_event>("custom"_hs, 42);
|
||||
```
|
||||
|
||||
This is mainly due to the template argument deduction rules, and there is no
|
||||
real (elegant) way to avoid it.
|
||||
|
||||
# Event emitter
|
||||
|
||||
A general purpose event emitter thought mainly for those cases where it comes to
|
||||
working with asynchronous stuff.<br/>
|
||||
Originally designed to fit the requirements of
|
||||
[`uvw`](https://github.com/skypjack/uvw) (a wrapper for `libuv` written in
|
||||
modern C++), it was adapted later to be included in this library.
|
||||
|
||||
To create an emitter type, derived classes must inherit from the base as:
|
||||
|
||||
```cpp
|
||||
struct my_emitter: emitter<my_emitter> {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Handlers for the different events are created internally on the fly. It is not
|
||||
required to specify in advance the full list of accepted events.<br/>
|
||||
Moreover, whenever an event is published, an emitter also passes a reference
|
||||
to itself to its listeners.
|
||||
|
||||
To create new instances of an emitter, no arguments are required:
|
||||
|
||||
```cpp
|
||||
my_emitter emitter{};
|
||||
```
|
||||
|
||||
Listeners are movable and callable objects (free functions, lambdas, functors,
|
||||
`std::function`s, whatever) whose function type is compatible with:
|
||||
|
||||
```cpp
|
||||
void(Type &, my_emitter &)
|
||||
```
|
||||
|
||||
Where `Type` is the type of event they want to receive.<br/>
|
||||
To attach a listener to an emitter, there exists the `on` member function:
|
||||
|
||||
```cpp
|
||||
emitter.on<my_event>([](const my_event &event, my_emitter &emitter) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Similarly, the `reset` member function is used to disconnect listeners given a
|
||||
type while `clear` is used to disconnect all listeners at once:
|
||||
|
||||
```cpp
|
||||
// resets the listener for my_event
|
||||
emitter.erase<my_event>();
|
||||
|
||||
// resets all listeners
|
||||
emitter.clear()
|
||||
```
|
||||
|
||||
To send an event to the listener registered on a given type, the `publish`
|
||||
function is the way to go:
|
||||
|
||||
```cpp
|
||||
struct my_event { int i; };
|
||||
|
||||
// ...
|
||||
|
||||
emitter.publish(my_event{42});
|
||||
```
|
||||
|
||||
Finally, the `empty` member function tests if there exists at least a listener
|
||||
registered with the event emitter while `contains` is used to check if a given
|
||||
event type is associated with a valid listener:
|
||||
|
||||
```cpp
|
||||
if(emitter.contains<my_event>()) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
This class introduces a _nice-to-have_ model based on events and listeners.<br/>
|
||||
More in general, it is a handy tool when the derived classes _wrap_ asynchronous
|
||||
operations, but it is not limited to such uses.
|
||||
103
lib/All/entt/docs/md/unreal.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# EnTT and Unreal Engine
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Enable Cpp17](#enable-cpp17)
|
||||
* [EnTT as a third party module](#entt-as-a-third-party-module)
|
||||
* [Include EnTT](#include-entt)
|
||||
|
||||
## Enable Cpp17
|
||||
|
||||
> Skip this part if you are working with UE5, Since UE5 uses cpp17 by default.
|
||||
|
||||
As of writing (Unreal Engine v4.25), the default C++ standard of Unreal Engine
|
||||
is C++14.<br/>
|
||||
On the other hand, note that `EnTT` requires C++17 to compile. To enable it, in
|
||||
the main module of the project there should be a `<Game Name>.Build.cs` file,
|
||||
the constructor of which must contain the following lines:
|
||||
|
||||
```cs
|
||||
PCHUsage = PCHUsageMode.NoSharedPCHs;
|
||||
PrivatePCHHeaderFile = "<PCH filename>.h";
|
||||
CppStandard = CppStandardVersion.Cpp17;
|
||||
```
|
||||
|
||||
Replace `<PCH filename>.h` with the name of the already existing PCH header
|
||||
file, if any.<br/>
|
||||
In case the project does not already contain a file of this type, it is possible
|
||||
to create one with the following content:
|
||||
|
||||
```cpp
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
```
|
||||
|
||||
Remember to remove any old `PCHUsage = <...>` line that was previously there. At
|
||||
this point, C++17 support should be in place.<br/>
|
||||
Try to compile the project to ensure it works as expected before following
|
||||
further steps.
|
||||
|
||||
Note that updating a *project* to C++17 does not necessarily mean that the IDE
|
||||
in use will also start to recognize its syntax.<br/>
|
||||
If the plan is to use C++17 in the project too, check the specific instructions
|
||||
for the IDE in use.
|
||||
|
||||
## EnTT as a third party module
|
||||
|
||||
Once this point is reached, the `Source` directory should look like this:
|
||||
|
||||
```
|
||||
Source
|
||||
| MyGame.Target.cs
|
||||
| MyGameEditor.Target.cs
|
||||
|
|
||||
+---MyGame
|
||||
| | MyGame.Build.cs
|
||||
| | MyGame.h (PCH Header file)
|
||||
|
|
||||
\---ThirdParty
|
||||
\---EnTT
|
||||
| EnTT.Build.cs
|
||||
|
|
||||
\---entt (GitHub repository content inside)
|
||||
```
|
||||
|
||||
To make this happen, create the folder `ThirdParty` under `Source` if it does
|
||||
not exist already. Then, add an `EnTT` folder under `ThirdParty`.<br/>
|
||||
Within the latter, create a new file `EnTT.Build.cs` with the following content:
|
||||
|
||||
```cs
|
||||
using System.IO;
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class EnTT: ModuleRules {
|
||||
public EnTT(ReadOnlyTargetRules Target) : base(Target) {
|
||||
Type = ModuleType.External;
|
||||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "entt", "src", "entt"));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The last line indicates that the actual files will be found in the directory
|
||||
`EnTT/entt/src/entt`.<br/>
|
||||
Download the repository for `EnTT` and place it next to `EnTT.Build.cs` or
|
||||
update the path above accordingly.
|
||||
|
||||
Finally, open the `<Game Name>.Build.cs` file and add `EnTT` as a dependency at
|
||||
the end of the list:
|
||||
|
||||
```cs
|
||||
PublicDependencyModuleNames.AddRange(new[] {
|
||||
"Core", "CoreUObject", "Engine", "InputCore", [...], "EnTT"
|
||||
});
|
||||
```
|
||||
|
||||
Note that some IDEs might require a restart to start recognizing the new module
|
||||
for code-highlighting features and such.
|
||||
|
||||
## Include EnTT
|
||||
|
||||
In any source file of the project, add `#include "entt.hpp"` or any other path
|
||||
to the file from `EnTT` to use it.<br/>
|
||||
Try to create a registry as `entt::registry registry;` to make sure everything
|
||||
compiles fine.
|
||||
52
lib/All/entt/entt.imp
Normal file
@@ -0,0 +1,52 @@
|
||||
[
|
||||
# gtest only
|
||||
{ "include": [ "@<gtest/internal/.*>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ "include": [ "@<gtest/gtest-.*>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
# forward files
|
||||
{ "include": [ "@[\"<].*/container/fwd\\.hpp[\">]", "private", "<entt/container/dense_map.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/container/fwd\\.hpp[\">]", "private", "<entt/container/dense_set.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/container/fwd\\.hpp[\">]", "private", "<entt/container/table.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/core/fwd\\.hpp[\">]", "private", "<entt/core/any.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/core/fwd\\.hpp[\">]", "private", "<entt/core/compressed_pair.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/core/fwd\\.hpp[\">]", "private", "<entt/core/family.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/core/fwd\\.hpp[\">]", "private", "<entt/core/hashed_string.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/core/fwd\\.hpp[\">]", "private", "<entt/core/ident.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/core/fwd\\.hpp[\">]", "private", "<entt/core/monostate.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/core/fwd\\.hpp[\">]", "private", "<entt/core/type_info.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/core/fwd\\.hpp[\">]", "private", "<entt/core/type_traits.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/component.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/entity.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/group.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/handle.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/helper.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/mixin.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/organizer.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/ranges.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/registry.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/runtime_view.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/snapshot.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/sparse_set.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/storage.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/entity/fwd\\.hpp[\">]", "private", "<entt/entity/view.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/graph/fwd\\.hpp[\">]", "private", "<entt/graph/adjacency_matrix.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/graph/fwd\\.hpp[\">]", "private", "<entt/graph/dot.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/graph/fwd\\.hpp[\">]", "private", "<entt/graph/flow.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/meta/fwd\\.hpp[\">]", "private", "<entt/meta/meta.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/poly/fwd\\.hpp[\">]", "private", "<entt/poly/poly.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/process/fwd\\.hpp[\">]", "private", "<entt/process/process.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/process/fwd\\.hpp[\">]", "private", "<entt/process/scheduler.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/resource/fwd\\.hpp[\">]", "private", "<entt/resource/cache.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/resource/fwd\\.hpp[\">]", "private", "<entt/resource/loader.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/resource/fwd\\.hpp[\">]", "private", "<entt/resource/resource.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/signal/fwd\\.hpp[\">]", "private", "<entt/signal/delegate.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/signal/fwd\\.hpp[\">]", "private", "<entt/signal/dispatcher.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/signal/fwd\\.hpp[\">]", "private", "<entt/signal/emitter.hpp>", "public" ] },
|
||||
{ "include": [ "@[\"<].*/signal/fwd\\.hpp[\">]", "private", "<entt/signal/sigh.hpp>", "public" ] },
|
||||
# symbols
|
||||
{ symbol: [ "std::allocator", private, "<entt/container/fwd.hpp>", public ] },
|
||||
{ symbol: [ "std::allocator", private, "<entt/entity/fwd.hpp>", public ] },
|
||||
{ symbol: [ "std::allocator", private, "<entt/graph/fwd.hpp>", public ] },
|
||||
{ symbol: [ "std::allocator", private, "<entt/process/fwd.hpp>", public ] },
|
||||
{ symbol: [ "std::allocator", private, "<entt/resource/fwd.hpp>", public ] },
|
||||
{ symbol: [ "std::allocator", private, "<entt/signal/fwd.hpp>", public ] }
|
||||
]
|
||||
3
lib/All/entt/natvis/entt/config.natvis
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
</AutoVisualizer>
|
||||
39
lib/All/entt/natvis/entt/container.natvis
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="entt::dense_map<*>">
|
||||
<Intrinsic Name="size" Expression="packed.first_base::value.size()"/>
|
||||
<Intrinsic Name="bucket_count" Expression="sparse.first_base::value.size()"/>
|
||||
<DisplayString>{{ size={ size() } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[capacity]" ExcludeView="simple">packed.first_base::value.capacity()</Item>
|
||||
<Item Name="[bucket_count]" ExcludeView="simple">bucket_count()</Item>
|
||||
<Item Name="[load_factor]" ExcludeView="simple">(float)size() / (float)bucket_count()</Item>
|
||||
<Item Name="[max_load_factor]" ExcludeView="simple">threshold</Item>
|
||||
<IndexListItems>
|
||||
<Size>size()</Size>
|
||||
<ValueNode>packed.first_base::value[$i].element</ValueNode>
|
||||
</IndexListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::dense_set<*>">
|
||||
<Intrinsic Name="size" Expression="packed.first_base::value.size()"/>
|
||||
<Intrinsic Name="bucket_count" Expression="sparse.first_base::value.size()"/>
|
||||
<DisplayString>{{ size={ size() } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[capacity]" ExcludeView="simple">packed.first_base::value.capacity()</Item>
|
||||
<Item Name="[bucket_count]" ExcludeView="simple">bucket_count()</Item>
|
||||
<Item Name="[load_factor]" ExcludeView="simple">(float)size() / (float)bucket_count()</Item>
|
||||
<Item Name="[max_load_factor]" ExcludeView="simple">threshold</Item>
|
||||
<IndexListItems>
|
||||
<Size>size()</Size>
|
||||
<ValueNode>packed.first_base::value[$i].second</ValueNode>
|
||||
</IndexListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_table<*>">
|
||||
<DisplayString>{ payload }</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem>payload</ExpandedItem>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
32
lib/All/entt/natvis/entt/core.natvis
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="entt::basic_any<*>">
|
||||
<DisplayString>{{ type={ info->alias,na }, policy={ mode,en } }}</DisplayString>
|
||||
</Type>
|
||||
<Type Name="entt::compressed_pair<*>">
|
||||
<Intrinsic Name="first" Optional="true" Expression="((first_base*)this)->value"/>
|
||||
<Intrinsic Name="first" Optional="true" Expression="*(first_base::base_type*)this"/>
|
||||
<Intrinsic Name="second" Optional="true" Expression="((second_base*)this)->value"/>
|
||||
<Intrinsic Name="second" Optional="true" Expression="*(second_base::base_type*)this"/>
|
||||
<DisplayString>({ first() }, { second() })</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[first]">first()</Item>
|
||||
<Item Name="[second]">second()</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_hashed_string<*>">
|
||||
<DisplayString Condition="base_type::repr != nullptr">{{ hash={ base_type::hash } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[data]">base_type::repr,na</Item>
|
||||
<Item Name="[length]">base_type::length</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::type_info">
|
||||
<DisplayString>{{ name={ alias,na } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[hash]">identifier</Item>
|
||||
<Item Name="[index]">seq</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
181
lib/All/entt/natvis/entt/entity.natvis
Normal file
@@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="entt::basic_registry<*>">
|
||||
<DisplayString>{{ pools={ pools.size() } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[entities]">entities</Item>
|
||||
<Synthetic Name="[pools]">
|
||||
<DisplayString>{ pools.size() }</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="pos" InitialValue="0" />
|
||||
<Variable Name="last" InitialValue="pools.size()"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<Item Name="[{ pools.packed.first_base::value[pos].element.first }]">
|
||||
*pools.packed.first_base::value[pos].element.second,view(simple)
|
||||
</Item>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Synthetic>
|
||||
<Item Name="[groups]">groups.size()</Item>
|
||||
<Synthetic Name="[vars]">
|
||||
<DisplayString>{ vars.ctx.size() }</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="pos" InitialValue="0" />
|
||||
<Variable Name="last" InitialValue="vars.ctx.size()"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<Item Name="[{ vars.ctx.packed.first_base::value[pos].element.first }]">
|
||||
vars.ctx.packed.first_base::value[pos].element.second
|
||||
</Item>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Synthetic>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_sparse_set<*>">
|
||||
<Intrinsic Name="is_valid_position" Expression="sparse[page] && ((*((traits_type::entity_type *)&sparse[page][offset]) & traits_type::entity_mask) != traits_type::entity_mask)">
|
||||
<Parameter Name="page" Type="traits_type::entity_type"/>
|
||||
<Parameter Name="offset" Type="traits_type::entity_type"/>
|
||||
</Intrinsic>
|
||||
<Intrinsic Name="is_valid_entity" Expression="!traits_type::version_mask || (*((traits_type::entity_type *)&entity) < (traits_type::version_mask << traits_type::length))">
|
||||
<Parameter Name="entity" Type="const traits_type::value_type &"/>
|
||||
</Intrinsic>
|
||||
<DisplayString>{{ size={ packed.size() }, type={ info->alias,na } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[capacity]" ExcludeView="simple">packed.capacity()</Item>
|
||||
<Item Name="[policy]" ExcludeView="simple">mode,en</Item>
|
||||
<Item Name="[free_list]" ExcludeView="simple">head</Item>
|
||||
<Synthetic Name="[sparse]">
|
||||
<DisplayString>{ sparse.size() * traits_type::page_size }</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="pos" InitialValue="0"/>
|
||||
<Variable Name="page" InitialValue="0"/>
|
||||
<Variable Name="offset" InitialValue="0"/>
|
||||
<Variable Name="last" InitialValue="sparse.size() * traits_type::page_size"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<Exec>page = pos / traits_type::page_size</Exec>
|
||||
<Exec>offset = pos & (traits_type::page_size - 1)</Exec>
|
||||
<If Condition="is_valid_position(page, offset)">
|
||||
<Item Name="[{ pos }]">*((traits_type::entity_type *)&sparse[page][offset]) & traits_type::entity_mask</Item>
|
||||
</If>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Synthetic>
|
||||
<Synthetic Name="[packed]">
|
||||
<DisplayString>{ packed.size() }</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="pos" InitialValue="0"/>
|
||||
<Variable Name="last" InitialValue="packed.size()"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<If Condition="is_valid_entity(packed[pos])">
|
||||
<Item Name="[{ pos }]">packed[pos]</Item>
|
||||
</If>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Synthetic>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_storage<*>">
|
||||
<Intrinsic Name="is_valid_entity" Expression="!base_type::traits_type::version_mask || (*((base_type::traits_type::entity_type *)&entity) < (base_type::traits_type::version_mask << base_type::traits_type::length))">
|
||||
<Parameter Name="entity" Type="const base_type::traits_type::value_type &"/>
|
||||
</Intrinsic>
|
||||
<DisplayString>{{ size={ base_type::packed.size() }, type={ base_type::info->alias,na } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[capacity]" Optional="true" ExcludeView="simple">payload.capacity() * traits_type::page_size</Item>
|
||||
<Item Name="[page size]" Optional="true" ExcludeView="simple">traits_type::page_size</Item>
|
||||
<Item Name="[placeholder]" Optional="true" ExcludeView="simple">placeholder</Item>
|
||||
<Item Name="[base]" ExcludeView="simple">(base_type*)this,nand</Item>
|
||||
<Item Name="[base]" IncludeView="simple">(base_type*)this,view(simple)nand</Item>
|
||||
<CustomListItems Condition="payload.size() != 0" Optional="true">
|
||||
<Variable Name="pos" InitialValue="0" />
|
||||
<Variable Name="last" InitialValue="base_type::packed.size()"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<If Condition="is_valid_entity(base_type::packed[pos])">
|
||||
<Item Name="[{ pos }:{ base_type::packed[pos] }]">payload[pos / traits_type::page_size][pos & (traits_type::page_size - 1)]</Item>
|
||||
</If>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_common_view<*,*,*>">
|
||||
<DisplayString Condition="index != $T2">{{ size_hint={ pools[index]->packed.size() } }}</DisplayString>
|
||||
<DisplayString>{{ size_hint=0 }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[pools]">pools,na</Item>
|
||||
<Item Name="[filter]">filter,na</Item>
|
||||
<Item Name="[handle]" Condition="index != $T2">pools[index],na</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_storage_view<*>">
|
||||
<DisplayString Condition="leading != nullptr">{{ size={ leading->packed.size() } }}</DisplayString>
|
||||
<DisplayString>{{ size=0 }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[handle]" Condition="leading != nullptr">leading,na</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_view<*>">
|
||||
<DisplayString>{ *(base_type*)this }</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem>*(base_type*)this</ExpandedItem>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_runtime_view<*>">
|
||||
<DisplayString Condition="pools.size() != 0u">{{ size_hint={ pools[0]->packed.size() } }}</DisplayString>
|
||||
<DisplayString>{{ size_hint=0 }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[pools]">pools,na</Item>
|
||||
<Item Name="[filter]">filter,na</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_handle<*>">
|
||||
<Intrinsic Name="pool_at" Expression="owner->pools.packed.first_base::value[index].element.second._Ptr">
|
||||
<Parameter Name="index" Type="unsigned int"/>
|
||||
</Intrinsic>
|
||||
<DisplayString>{{ entity={ entt } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[entity]">entt</Item>
|
||||
<Item Name="[registry]" Condition="owner != nullptr">owner,na</Item>
|
||||
<Synthetic Name="[components]" Condition="owner != nullptr">
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="entity_mask" InitialValue="traits_type::entity_mask"/>
|
||||
<Variable Name="page" InitialValue="((*((traits_type::entity_type *)&entt)) & entity_mask) / traits_type::page_size"/>
|
||||
<Variable Name="offset" InitialValue="(*((traits_type::entity_type *)&entt)) & (traits_type::page_size - 1u)"/>
|
||||
<Variable Name="last" InitialValue="owner->pools.packed.first_base::value.size()"/>
|
||||
<Variable Name="pos" InitialValue="0u"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<If Condition="pool_at(pos)->sparse.size() > page && pool_at(pos)->sparse[page] != nullptr && ((*((traits_type::entity_type *)&pool_at(pos)->sparse[page][offset])) & entity_mask) != entity_mask">
|
||||
<Item Name="[{ pool_at(pos)->info->alias,na }:{ ((*((traits_type::entity_type *)&pool_at(pos)->sparse[page][offset])) & entity_mask) != entity_mask }]">pool_at(pos),view(simple)nanr</Item>
|
||||
</If>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Synthetic>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::null_t">
|
||||
<DisplayString><null></DisplayString>
|
||||
</Type>
|
||||
<Type Name="entt::tombstone_t">
|
||||
<DisplayString><tombstone></DisplayString>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
19
lib/All/entt/natvis/entt/graph.natvis
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="entt::adjacency_matrix<*>">
|
||||
<DisplayString>{{ size={ vert } }}</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="pos" InitialValue="0" />
|
||||
<Variable Name="last" InitialValue="vert * vert"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<If Condition="matrix[pos] != 0u">
|
||||
<Item Name="{pos / vert}">pos % vert</Item>
|
||||
</If>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
3
lib/All/entt/natvis/entt/locator.natvis
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
</AutoVisualizer>
|
||||
188
lib/All/entt/natvis/entt/meta.natvis
Normal file
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="entt::internal::meta_base_node">
|
||||
<DisplayString Condition="resolve != nullptr">{{ type={ type } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[type]">type</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_conv_node">
|
||||
<DisplayString Condition="conv != nullptr">{{ type={ type } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[type]">type</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_ctor_node">
|
||||
<DisplayString Condition="invoke != nullptr">{{ id={ id } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[id]">id</Item>
|
||||
<Item Name="[arity]">arity</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_custom_node">
|
||||
<DisplayString Condition="value != nullptr">{{ type={ type } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[type]">type</Item>
|
||||
<Item Name="[value]">value</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_data_node">
|
||||
<Intrinsic Name="has_trait" Expression="!!(traits & property)">
|
||||
<Parameter Name="property" Type="int"/>
|
||||
</Intrinsic>
|
||||
<DisplayString Condition="get != nullptr">{{ id={ id } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[id]">id</Item>
|
||||
<Item Name="[arity]">arity</Item>
|
||||
<Item Name="[is_const]">has_trait(entt::internal::meta_traits::is_const)</Item>
|
||||
<Item Name="[is_static]">has_trait(entt::internal::meta_traits::is_static)</Item>
|
||||
<Item Name="[custom]">custom</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_dtor_node">
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand/>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_func_node" >
|
||||
<Intrinsic Name="has_trait" Expression="!!(traits & property)">
|
||||
<Parameter Name="property" Type="int"/>
|
||||
</Intrinsic>
|
||||
<DisplayString Condition="invoke != nullptr">{{ id={ id } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[id]">id</Item>
|
||||
<Item Name="[arity]">arity</Item>
|
||||
<Item Name="[is_const]">has_trait(entt::internal::meta_traits::is_const)</Item>
|
||||
<Item Name="[is_static]">has_trait(entt::internal::meta_traits::is_static)</Item>
|
||||
<Item Name="[next]" Condition="next != nullptr">*next</Item>
|
||||
<Item Name="[custom]">custom</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_template_node">
|
||||
<DisplayString Condition="arity != 0u">{{ arity={ arity } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[arity]">arity</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_type_descriptor">
|
||||
<DisplayString/>
|
||||
<Expand>
|
||||
<Item Name="[ctor]">ctor,view(simple)</Item>
|
||||
<Item Name="[base]">base,view(simple)</Item>
|
||||
<Item Name="[conv]">conv,view(simple)</Item>
|
||||
<Item Name="[data]">data,view(simple)</Item>
|
||||
<Item Name="[func]">func,view(simple)</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::meta_type_node">
|
||||
<Intrinsic Name="has_trait" Expression="!!(traits & property)">
|
||||
<Parameter Name="property" Type="int"/>
|
||||
</Intrinsic>
|
||||
<DisplayString Condition="info != nullptr">{{ type={ info->alias,na } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[id]">id</Item>
|
||||
<Item Name="[sizeof]">size_of</Item>
|
||||
<Item Name="[is_arithmetic]">has_trait(entt::internal::meta_traits::is_arithmetic)</Item>
|
||||
<Item Name="[is_integral]">has_trait(entt::internal::meta_traits::is_integral)</Item>
|
||||
<Item Name="[is_signed]">has_trait(entt::internal::meta_traits::is_signed)</Item>
|
||||
<Item Name="[is_array]">has_trait(entt::internal::meta_traits::is_array)</Item>
|
||||
<Item Name="[is_enum]">has_trait(entt::internal::meta_traits::is_enum)</Item>
|
||||
<Item Name="[is_class]">has_trait(entt::internal::meta_traits::is_class)</Item>
|
||||
<Item Name="[is_pointer]">has_trait(entt::internal::meta_traits::is_pointer)</Item>
|
||||
<Item Name="[is_pointer_like]">has_trait(entt::internal::meta_traits::is_pointer_like)</Item>
|
||||
<Item Name="[is_sequence_container]">has_trait(entt::internal::meta_traits::is_sequence_container)</Item>
|
||||
<Item Name="[is_associative_container]">has_trait(entt::internal::meta_traits::is_associative_container)</Item>
|
||||
<Item Name="[default_constructor]">default_constructor != nullptr</Item>
|
||||
<Item Name="[conversion_helper]">conversion_helper != nullptr</Item>
|
||||
<Item Name="[from_void]">from_void != nullptr</Item>
|
||||
<Item Name="[template_info]">templ</Item>
|
||||
<Item Name="[custom]">custom</Item>
|
||||
<Item Name="[details]" Condition="!(details == nullptr)">*details</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_any">
|
||||
<DisplayString Condition="node.info != nullptr">{{ type={ node.info->alias,na }, policy={ storage.mode,en } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem>node</ExpandedItem>
|
||||
<Item Name="[context]" Condition="ctx != nullptr">ctx->value</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_handle">
|
||||
<DisplayString>{ any }</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem>any</ExpandedItem>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_associative_container">
|
||||
<DisplayString Condition="data != nullptr">{{ const={ const_only } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[context]" Condition="ctx != nullptr">ctx->value</Item>
|
||||
<Item Name="[const]">const_only</Item>
|
||||
<Item Name="[data]">data</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_sequence_container">
|
||||
<DisplayString Condition="data != nullptr">{{ const={ const_only } }}</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[context]" Condition="ctx != nullptr">ctx->value</Item>
|
||||
<Item Name="[const]">const_only</Item>
|
||||
<Item Name="[data]">data</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_custom">
|
||||
<DisplayString>{ node }</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem>node</ExpandedItem>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_data">
|
||||
<DisplayString Condition="node.get != nullptr">{ node }</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem Condition="node.get != nullptr">node</ExpandedItem>
|
||||
<Item Name="[context]" Condition="ctx != nullptr">ctx->value</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_func">
|
||||
<DisplayString Condition="node.invoke != nullptr">{ node }</DisplayString>
|
||||
<DisplayString>{{}}</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem Condition="node.invoke != nullptr">node</ExpandedItem>
|
||||
<Item Name="[context]" Condition="ctx != nullptr">ctx->value</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_type">
|
||||
<DisplayString>{ node }</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem>node</ExpandedItem>
|
||||
<Item Name="[context]" Condition="ctx != nullptr">ctx->value</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::meta_ctx">
|
||||
<Intrinsic Name="element_at" Expression="value.packed.first_base::value[pos].element">
|
||||
<Parameter Name="pos" Type="int"/>
|
||||
</Intrinsic>
|
||||
<DisplayString>{ value }</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="pos" InitialValue="0"/>
|
||||
<Variable Name="last" InitialValue="value.size()"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<Item Name="[{ element_at(pos).first }]">element_at(pos).second</Item>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
6
lib/All/entt/natvis/entt/poly.natvis
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="entt::basic_poly<*>">
|
||||
<DisplayString>{ storage }</DisplayString>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
3
lib/All/entt/natvis/entt/process.natvis
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
</AutoVisualizer>
|
||||
26
lib/All/entt/natvis/entt/resource.natvis
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="entt::resource<*>">
|
||||
<DisplayString>{ value }</DisplayString>
|
||||
<Expand>
|
||||
<ExpandedItem>value</ExpandedItem>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::resource_cache<*>">
|
||||
<Intrinsic Name="size" Expression="pool.first_base::value.size()"/>
|
||||
<DisplayString>{{ size={ size() } }}</DisplayString>
|
||||
<Expand>
|
||||
<CustomListItems>
|
||||
<Variable Name="pos" InitialValue="0" />
|
||||
<Variable Name="last" InitialValue="size()"/>
|
||||
<Loop>
|
||||
<Break Condition="pos == last"/>
|
||||
<Item Name="[{ pool.first_base::value.packed.first_base::value[pos].element.first }]">
|
||||
*pool.first_base::value.packed.first_base::value[pos].element.second
|
||||
</Item>
|
||||
<Exec>++pos</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
50
lib/All/entt/natvis/entt/signal.natvis
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="entt::delegate<*>">
|
||||
<DisplayString>{{ type={ "$T1" } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[empty]">fn == nullptr</Item>
|
||||
<Item Name="[data]">instance</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::basic_dispatcher<*>">
|
||||
<Intrinsic Name="size" Expression="pools.first_base::value.size()"/>
|
||||
<DisplayString>{{ size={ size() } }}</DisplayString>
|
||||
<Expand>
|
||||
<IndexListItems>
|
||||
<Size>size()</Size>
|
||||
<ValueNode>*pools.first_base::value.packed.first_base::value[$i].element.second</ValueNode>
|
||||
</IndexListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::internal::dispatcher_handler<*>">
|
||||
<DisplayString>{{ size={ events.size() }, event={ "$T1" } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[signal]">signal</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::emitter<*>">
|
||||
<DisplayString>{{ size={ handlers.first_base::value.size() } }}</DisplayString>
|
||||
</Type>
|
||||
<Type Name="entt::connection">
|
||||
<DisplayString>{{ bound={ signal != nullptr } }}</DisplayString>
|
||||
</Type>
|
||||
<Type Name="entt::scoped_connection">
|
||||
<DisplayString>{ conn }</DisplayString>
|
||||
</Type>
|
||||
<Type Name="entt::sigh<*>">
|
||||
<DisplayString>{{ size={ calls.size() }, type={ "$T1" } }}</DisplayString>
|
||||
<Expand>
|
||||
<IndexListItems>
|
||||
<Size>calls.size()</Size>
|
||||
<ValueNode>calls[$i]</ValueNode>
|
||||
</IndexListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="entt::sink<*>">
|
||||
<DisplayString>{{ type={ "$T1" } }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[signal]">signal,na</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||