Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd83fba6cd | ||
|
|
15b9255a25 | ||
|
|
6794d21487 | ||
|
|
118c4432ec | ||
|
|
ccda429bf1 | ||
|
|
590937d2a0 | ||
|
|
241827dd80 | ||
|
|
77b4e0b4bd | ||
|
|
6a53cb32d8 | ||
|
|
f12ff3b15e | ||
|
|
69ad8676b7 | ||
|
|
d0fd756f6b | ||
|
|
7f8ab67e9e | ||
|
|
0e68bb3d2c | ||
|
|
d5b3933752 | ||
|
|
0b7206a92d | ||
|
|
e875f306fd | ||
|
|
8ed5e5ee28 | ||
|
|
948b0d40f6 | ||
|
|
48f4feb7a7 | ||
|
|
ddc0a32bbc |
@@ -37,7 +37,7 @@ matrix:
|
||||
compiler: clang
|
||||
env: COMPILER=clang++
|
||||
- os: osx
|
||||
osx_image: xcode9.1
|
||||
osx_image: xcode9.4
|
||||
compiler: clang
|
||||
env: COMPILER=clang++
|
||||
- os: linux
|
||||
@@ -71,3 +71,9 @@ script:
|
||||
- mkdir -p build && cd build
|
||||
- cmake .. && make -j4
|
||||
- CTEST_OUTPUT_ON_FAILURE=1 make test
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
script: scripts/update_packages.sh $TRAVIS_TAG
|
||||
on:
|
||||
tags: true
|
||||
|
||||
1
AUTHORS
1
AUTHORS
@@ -8,3 +8,4 @@ Paolo Monteverde aka morbo84
|
||||
David Nerjes aka DavidHamburg
|
||||
Indi Kernick aka Kerndog73
|
||||
Malte Müller-Rowold aka m-waka
|
||||
Richard Caseres aka richardbmx
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# EnTT
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.7.2)
|
||||
|
||||
#
|
||||
# Building in-tree is not allowed (we take care of your craziness).
|
||||
@@ -16,7 +16,7 @@ endif()
|
||||
# Project configuration
|
||||
#
|
||||
|
||||
project(entt VERSION 2.6.1)
|
||||
project(EnTT VERSION 2.7.2)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
@@ -31,11 +31,12 @@ set(PROJECT_AUTHOR_EMAIL "michele.caini@gmail.com")
|
||||
|
||||
message("*")
|
||||
message("* ${PROJECT_NAME} v${PROJECT_VERSION} (${CMAKE_BUILD_TYPE})")
|
||||
message("* Copyright (c) 2018 ${PROJECT_AUTHOR} <${PROJECT_AUTHOR_EMAIL}>")
|
||||
message("* Copyright (c) 2017-2018 ${PROJECT_AUTHOR} <${PROJECT_AUTHOR_EMAIL}>")
|
||||
message("*")
|
||||
|
||||
option(ENTT_COMPILE_OPTIONS "Use compile options from EnTT." ON)
|
||||
option(USE_LIBCPP "Use libc++ by adding -stdlib=libc++ flag if availbale." ON)
|
||||
option(USE_ASAN "Use address sanitizer by adding -fsanitize=address -fno-omit-frame-pointer flags" OFF)
|
||||
option(USE_COMPILE_OPTIONS "Use compile options from EnTT." ON)
|
||||
|
||||
#
|
||||
# Compiler stuff
|
||||
@@ -79,18 +80,23 @@ target_compile_definitions(
|
||||
INTERFACE $<$<AND:$<CONFIG:Release>,$<NOT:$<CXX_COMPILER_ID:MSVC>>>:RELEASE>
|
||||
)
|
||||
|
||||
if(ENTT_COMPILE_OPTIONS)
|
||||
if(USE_ASAN)
|
||||
target_compile_options(EnTT INTERFACE $<$<AND:$<CONFIG:Debug>,$<NOT:$<CXX_COMPILER_ID:MSVC>>>:-fsanitize=address -fno-omit-frame-pointer>)
|
||||
target_link_libraries(EnTT INTERFACE $<$<AND:$<CONFIG:Debug>,$<NOT:$<CXX_COMPILER_ID:MSVC>>>:-fsanitize=address -fno-omit-frame-pointer>)
|
||||
endif()
|
||||
|
||||
if(USE_COMPILE_OPTIONS)
|
||||
target_compile_options(
|
||||
EnTT
|
||||
INTERFACE $<$<AND:$<CONFIG:Debug>,$<NOT:$<CXX_COMPILER_ID:MSVC>>>:-O0 -g>
|
||||
# it seems that -O3 ruins the performance when using clang ...
|
||||
# it seems that -O3 ruins a bit the performance when using clang ...
|
||||
INTERFACE $<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:Clang>>:-O2>
|
||||
# ... on the other side, GCC is incredibly comfortable with it.
|
||||
INTERFACE $<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:GNU>>:-O3>
|
||||
)
|
||||
endif()
|
||||
|
||||
if(USE_LIBCPP AND HAS_LIBCPP)
|
||||
if(HAS_LIBCPP)
|
||||
target_compile_options(EnTT BEFORE INTERFACE -stdlib=libc++)
|
||||
endif()
|
||||
|
||||
@@ -101,20 +107,20 @@ target_compile_features(EnTT INTERFACE cxx_std_14)
|
||||
#
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
set(ENTT_INSTALL_CONFIGDIR cmake)
|
||||
set(CUSTOM_INSTALL_CONFIGDIR cmake)
|
||||
else()
|
||||
set(ENTT_INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/entt)
|
||||
set(CUSTOM_INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/entt)
|
||||
endif()
|
||||
|
||||
install(DIRECTORY src/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(TARGETS EnTT EXPORT EnTTTargets)
|
||||
|
||||
export(EXPORT EnTTTargets FILE ${entt_BINARY_DIR}/EnTTTargets.cmake)
|
||||
export(EXPORT EnTTTargets FILE ${EnTT_BINARY_DIR}/EnTTTargets.cmake)
|
||||
|
||||
install(
|
||||
EXPORT EnTTTargets
|
||||
FILE EnTTTargets.cmake
|
||||
DESTINATION ${ENTT_INSTALL_CONFIGDIR}
|
||||
DESTINATION ${CUSTOM_INSTALL_CONFIGDIR}
|
||||
)
|
||||
|
||||
#
|
||||
@@ -131,23 +137,23 @@ include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(
|
||||
cmake/in/EnTTConfig.cmake.in
|
||||
${ENTT_INSTALL_CONFIGDIR}/EnTTConfig.cmake
|
||||
INSTALL_DESTINATION ${ENTT_INSTALL_CONFIGDIR}
|
||||
${CUSTOM_INSTALL_CONFIGDIR}/EnTTConfig.cmake
|
||||
INSTALL_DESTINATION ${CUSTOM_INSTALL_CONFIGDIR}
|
||||
PATH_VARS CMAKE_INSTALL_INCLUDEDIR
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
${entt_BINARY_DIR}/EnTTConfigVersion.cmake
|
||||
${EnTT_BINARY_DIR}/EnTTConfigVersion.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${entt_BINARY_DIR}/${ENTT_INSTALL_CONFIGDIR}/EnTTConfig.cmake
|
||||
${entt_BINARY_DIR}/EnTTConfigVersion.cmake
|
||||
DESTINATION ${ENTT_INSTALL_CONFIGDIR}
|
||||
${EnTT_BINARY_DIR}/${CUSTOM_INSTALL_CONFIGDIR}/EnTTConfig.cmake
|
||||
${EnTT_BINARY_DIR}/EnTTConfigVersion.cmake
|
||||
DESTINATION ${CUSTOM_INSTALL_CONFIGDIR}
|
||||
)
|
||||
|
||||
export(PACKAGE EnTT)
|
||||
@@ -162,18 +168,25 @@ if(BUILD_TESTING)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
option(FIND_GTEST_PACKAGE "Enable finding gtest package." OFF)
|
||||
|
||||
if(FIND_GTEST_PACKAGE)
|
||||
find_package(GTest REQUIRED)
|
||||
else()
|
||||
# gtest, gtest_main, gmock and gmock_main targets are available from now on
|
||||
set(GOOGLETEST_DEPS_DIR ${EnTT_SOURCE_DIR}/deps/googletest)
|
||||
configure_file(${EnTT_SOURCE_DIR}/cmake/in/googletest.in ${GOOGLETEST_DEPS_DIR}/CMakeLists.txt)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${GOOGLETEST_DEPS_DIR})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${GOOGLETEST_DEPS_DIR})
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
add_subdirectory(${GOOGLETEST_DEPS_DIR}/src ${GOOGLETEST_DEPS_DIR}/build)
|
||||
add_library(GTest::Main ALIAS gtest_main)
|
||||
endif()
|
||||
|
||||
option(BUILD_BENCHMARK "Build benchmark." OFF)
|
||||
option(BUILD_MOD "Build mod example." OFF)
|
||||
option(BUILD_SNAPSHOT "Build snapshot example." OFF)
|
||||
|
||||
# gtest, gtest_main, gmock and gmock_main targets are available from now on
|
||||
set(GOOGLETEST_DEPS_DIR ${entt_SOURCE_DIR}/deps/googletest)
|
||||
configure_file(${entt_SOURCE_DIR}/cmake/in/googletest.in ${GOOGLETEST_DEPS_DIR}/CMakeLists.txt)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${GOOGLETEST_DEPS_DIR})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${GOOGLETEST_DEPS_DIR})
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
add_subdirectory(${GOOGLETEST_DEPS_DIR}/src ${GOOGLETEST_DEPS_DIR}/build)
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
@@ -201,9 +214,10 @@ add_custom_target(
|
||||
SOURCES
|
||||
appveyor.yml
|
||||
AUTHORS
|
||||
CONTRIBUTING
|
||||
LICENSE
|
||||
README.md
|
||||
TODO
|
||||
.travis.yml
|
||||
docs/CONTRIBUTING.md
|
||||
docs/extra.dox
|
||||
)
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Michele Caini
|
||||
Copyright (c) 2017-2018 Michele Caini
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
216
README.md
216
README.md
@@ -1,8 +1,12 @@
|
||||
# EnTT Framework
|
||||

|
||||
|
||||
<!--
|
||||
@cond TURN_OFF_DOXYGEN
|
||||
-->
|
||||
[](https://travis-ci.org/skypjack/entt)
|
||||
[](https://ci.appveyor.com/project/skypjack/entt)
|
||||
[](https://coveralls.io/github/skypjack/entt?branch=master)
|
||||
[](https://gitter.im/skypjack/entt)
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=W2HF9FESD5LJY&lc=IT&item_name=Michele%20Caini¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)
|
||||
|
||||
# Table of Contents
|
||||
@@ -29,6 +33,7 @@
|
||||
* [Prototype](#prototype)
|
||||
* [Helpers](#helpers)
|
||||
* [Dependency function](#dependency-function)
|
||||
* [Labels](#labels)
|
||||
* [Null entity](#null-entity)
|
||||
* [View: to persist or not to persist?](#view-to-persist-or-not-to-persist)
|
||||
* [Standard View](#standard-view)
|
||||
@@ -62,13 +67,16 @@
|
||||
* [Support](#support)
|
||||
* [Donation](#donation)
|
||||
* [Hire me](#hire-me)
|
||||
<!--
|
||||
@endcond TURN_OFF_DOXYGEN
|
||||
-->
|
||||
|
||||
# Introduction
|
||||
|
||||
`EnTT` is a header-only, tiny and easy to use framework written in modern
|
||||
C++.<br/>
|
||||
It was originally designed entirely around an architectural pattern called _ECS_
|
||||
that is used mostly in game development. For further details:
|
||||
`EnTT` is a header-only, tiny and easy to use entity-component system (and much
|
||||
more) written in modern C++.<br/>
|
||||
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/)
|
||||
@@ -77,35 +85,12 @@ that is used mostly in game development. For further details:
|
||||
A long time ago, the sole entity-component system was part of the project. After
|
||||
a while the codebase has grown and more and more classes have become part of the
|
||||
repository.<br/>
|
||||
That's why today it's called _the EnTT Framework_.
|
||||
|
||||
Currently, `EnTT` is tested on Linux, Microsoft Windows and OS X. It has proven
|
||||
to work also on both Android and iOS.<br/>
|
||||
Most likely it will not be problematic on other systems as well, but has not
|
||||
been sufficiently tested so far.
|
||||
|
||||
## The framework
|
||||
|
||||
`EnTT` was written initially as a faster alternative to other well known and
|
||||
open source entity-component systems. Nowadays the `EnTT` framework is moving
|
||||
its first steps. Much more will come in the future and hopefully I'm going to
|
||||
work on it for a long time.<br/>
|
||||
Requests for feature, PR, suggestions ad feedback are highly appreciated.
|
||||
|
||||
If you find you can help me and want to contribute to the `EnTT` framework with
|
||||
your experience or you do want to get part of the project for some other
|
||||
reasons, 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 seriously.
|
||||
|
||||
### State of the art
|
||||
|
||||
Here is a brief list of what it offers today:
|
||||
Here is a brief, yet incomplete list of what it offers today:
|
||||
|
||||
* Statically generated integer identifiers for types (assigned either at
|
||||
compile-time or at runtime).
|
||||
* A constexpr utility for human readable resource identifiers.
|
||||
* A minimal configuration system built on top of the monostate pattern.
|
||||
* An incredibly fast entity-component system based on sparse sets, with its own
|
||||
views and a _pay for what you use_ policy to adjust performance and memory
|
||||
usage according to users' requirements.
|
||||
@@ -120,12 +105,13 @@ Here is a brief list of what it offers today:
|
||||
* ...
|
||||
* Any other business.
|
||||
|
||||
Consider it a work in progress. For more details and an updated list, please
|
||||
refer to the [online documentation](https://skypjack.github.io/entt/). It
|
||||
probably contains much more. Moreover, the whole API is fully documented in-code
|
||||
for those who are brave enough to read it.<br/>
|
||||
Continue reading to know how the different parts of the project work or follow
|
||||
the link above to take a look at the API reference.
|
||||
Consider it a work in progress. The whole API is also fully documented in-code
|
||||
for those who are brave enough to read it.
|
||||
|
||||
Currently, `EnTT` is tested on Linux, Microsoft Windows and OS X. It has proven
|
||||
to work also on both Android and iOS.<br/>
|
||||
Most likely it will not be problematic on other systems as well, but has not
|
||||
been sufficiently tested so far.
|
||||
|
||||
## Code Example
|
||||
|
||||
@@ -197,7 +183,7 @@ 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.
|
||||
|
||||
Today `EnTT` is finally what I was looking for: still faster than its
|
||||
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.
|
||||
|
||||
@@ -265,8 +251,8 @@ documentation:
|
||||
|
||||
## Library
|
||||
|
||||
`EnTT` is a header-only library. This means that including the `entt.hpp`
|
||||
header is enough to include the whole framework and use it. For those who are
|
||||
`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:
|
||||
@@ -284,6 +270,46 @@ Use the line below to include only the entity-component system instead:
|
||||
Then pass the proper `-I` argument to the compiler to add the `src` directory to
|
||||
the include paths.
|
||||
|
||||
### Side note: shared libraries
|
||||
|
||||
To make sure that an application and a shared library that use both `EnTT` can
|
||||
interact correctly when symbols are hidden by default, there are some tricks to
|
||||
follow.<br/>
|
||||
In particular and in order to avoid undefined behaviors, all the instantiation
|
||||
of the `Family` class template shall be made explicit along with the system-wide
|
||||
specifier to use to export them.
|
||||
|
||||
At the time I'm writing this document, the classes that use internally the above
|
||||
mentioned class template are `Dispatcher`, `Emitter` and `Registry`. Therefore
|
||||
and as an example, if you use the `Registry` class template in your shared
|
||||
library and want to set symbols visibility to _hidden_ by default, the following
|
||||
lines are required to allow it to function properly with a client that also uses
|
||||
the `Registry` somehow:
|
||||
|
||||
* On GNU/Linux:
|
||||
|
||||
```cpp
|
||||
namespace entt {
|
||||
template class __attribute__((visibility("default"))) Family<struct InternalRegistryTagFamily>;
|
||||
template class __attribute__((visibility("default"))) Family<struct InternalRegistryComponentFamily>;
|
||||
template class __attribute__((visibility("default"))) Family<struct InternalRegistryHandlerFamily>;
|
||||
}
|
||||
```
|
||||
|
||||
* On Windows:
|
||||
|
||||
```cpp
|
||||
namespace entt {
|
||||
template class __declspec(dllexport) Family<struct InternalRegistryTagFamily>;
|
||||
template class __declspec(dllexport) Family<struct InternalRegistryComponentFamily>;
|
||||
template class __declspec(dllexport) Family<struct InternalRegistryHandlerFamily>;
|
||||
}
|
||||
```
|
||||
|
||||
Otherwise, the risk is that type identifiers are different between the shared
|
||||
library and the application and this will prevent the whole thing from
|
||||
functioning correctly for obvious reasons.
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation is based on [doxygen](http://www.stack.nl/~dimitri/doxygen/).
|
||||
@@ -299,8 +325,14 @@ The API reference will be created in HTML format within the directory
|
||||
$ cd build
|
||||
$ your_favorite_browser docs/html/index.html
|
||||
|
||||
<!--
|
||||
@cond TURN_OFF_DOXYGEN
|
||||
-->
|
||||
The API reference is also available [online](https://skypjack.github.io/entt/)
|
||||
for the latest version.
|
||||
<!--
|
||||
@endcond TURN_OFF_DOXYGEN
|
||||
-->
|
||||
|
||||
## Tests
|
||||
|
||||
@@ -380,8 +412,8 @@ them the way they prefer. No need to register systems or their types neither
|
||||
with the registry nor with the entity-component system at all.
|
||||
|
||||
The following sections will explain in short how to use the entity-component
|
||||
system, the core part of the whole framework.<br/>
|
||||
In fact, the framework is composed of many other classes in addition to those
|
||||
system, the core part of the whole library.<br/>
|
||||
In fact, the project is composed of many other classes in addition to those
|
||||
describe below. For more details, please refer to the inline documentation.
|
||||
|
||||
## The Registry, the Entity and the Component
|
||||
@@ -730,10 +762,10 @@ In `EnTT`, identifiers are easily accessible:
|
||||
entt::DefaultRegistry registry;
|
||||
|
||||
// standard component identifier
|
||||
auto ctype = registry.component<Position>();
|
||||
auto ctype = registry.type<Position>();
|
||||
|
||||
// single instance component identifier
|
||||
auto ttype = registry.tag<PlayingCharacter>();
|
||||
auto ttype = registry.type<PlayingCharacter>(entt::tag_t{});
|
||||
```
|
||||
|
||||
Once the identifiers are made available, almost everything becomes pretty
|
||||
@@ -1134,11 +1166,25 @@ A dependency can easily be broken by means of the same function template:
|
||||
entt::dependency<AType, AnotherType>(entt::break_t{}, registry.construction<MyType>());
|
||||
```
|
||||
|
||||
#### Labels
|
||||
|
||||
There's nothing magical about the way labels can be assigned to entities while
|
||||
avoiding a performance hit at runtime. Nonetheless, the syntax can be annoying
|
||||
and that's why a more user-friendly shortcut is provided to do it.<br/>
|
||||
This shortcut is the alias template `entt::label`.
|
||||
|
||||
If used in combination with hashed strings, it helps to use labels where types
|
||||
would be required otherwise. As an example:
|
||||
|
||||
```cpp
|
||||
registry.assign<entt::label<"enemy"_hs>>(entity);
|
||||
```
|
||||
|
||||
### Null entity
|
||||
|
||||
In `EnTT`, there exists a sort of _null entity_ made available to users that is
|
||||
accessible via the `entt::null` variable.<br/>
|
||||
The framework guarantees that the following expression always returns false:
|
||||
The library guarantees that the following expression always returns false:
|
||||
|
||||
```cpp
|
||||
registry.valid(entt::null);
|
||||
@@ -1658,11 +1704,10 @@ expedients.
|
||||
|
||||
# Crash Course: core functionalities
|
||||
|
||||
The `EnTT` framework comes with a bunch of core functionalities mostly used by
|
||||
the other parts of the library itself.<br/>
|
||||
Hardly users of the framework will include these features in their code, but
|
||||
it's worth describing what `EnTT` offers so as not to reinvent the wheel in case
|
||||
of need.
|
||||
`EnTT` comes with a bunch of core functionalities mostly used by the other parts
|
||||
of the library itself.<br/>
|
||||
Hardly users will include these features in their code, but it's worth
|
||||
describing what `EnTT` offers so as not to reinvent the wheel in case of need.
|
||||
|
||||
## Compile-time identifiers
|
||||
|
||||
@@ -1721,7 +1766,7 @@ Sometimes it's useful to be able to give unique identifiers to types at
|
||||
runtime.<br/>
|
||||
There are plenty of different solutions out there and I could have used one of
|
||||
them. In fact, I adapted the most common one to my requirements and used it
|
||||
extensively within the entire framework.
|
||||
extensively within the entire library.
|
||||
|
||||
It's the `Family` class. Here is an example of use directly from the
|
||||
entity-component system:
|
||||
@@ -1765,6 +1810,13 @@ auto load(entt::HashedString::hash_type resource) {
|
||||
auto resource = load(entt::HashedString{"gui/background"});
|
||||
```
|
||||
|
||||
There is also a _user defined literal_ dedicated to hashed strings to make them
|
||||
more user-friendly:
|
||||
|
||||
```cpp
|
||||
constexpr auto str = "text"_hs;
|
||||
```
|
||||
|
||||
### Conflicts
|
||||
|
||||
The hashed string class uses internally FNV-1a to compute the numeric
|
||||
@@ -1868,8 +1920,8 @@ Sometimes 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 the
|
||||
introduction of other components.
|
||||
|
||||
The `EnTT` framework offers a minimal support to this paradigm by introducing a
|
||||
few classes that users can use to define and execute cooperative processes.
|
||||
`EnTT` offers a minimal support to this paradigm by introducing a few classes
|
||||
that users can use to define and execute cooperative processes.
|
||||
|
||||
## The process
|
||||
|
||||
@@ -2068,9 +2120,9 @@ 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.
|
||||
|
||||
The `EnTT` framework doesn't pretend to offer a _one-fits-all_ solution for the
|
||||
different cases. Instead, it offers a minimal and perhaps trivial cache that can
|
||||
be useful most of the time during prototyping and sometimes even in a production
|
||||
`EnTT` doesn't pretend to offer a _one-fits-all_ solution for the different
|
||||
cases. Instead, it offers a minimal and perhaps trivial cache that can be useful
|
||||
most of the time during prototyping and sometimes even in a production
|
||||
environment.<br/>
|
||||
For those interested in the subject, the plan is to improve it considerably over
|
||||
time in terms of performance, memory usage and functionalities. Hoping to make
|
||||
@@ -2302,8 +2354,8 @@ 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 potential of an `std::function` are not
|
||||
required or where you are looking for something different, the `EnTT` framework
|
||||
offers a full set of classes to solve completely different problems.
|
||||
required or where you are looking for something different, `EnTT` offers a full
|
||||
set of classes to solve completely different problems.
|
||||
|
||||
## Signals
|
||||
|
||||
@@ -2472,7 +2524,7 @@ auto ret = delegate(42);
|
||||
|
||||
Probably too much small and pretty poor of functionalities, but the delegate
|
||||
class can help in a lot of cases and it has shown that it is worth keeping it
|
||||
within the framework.
|
||||
within the library.
|
||||
|
||||
## Event dispatcher
|
||||
|
||||
@@ -2709,8 +2761,10 @@ projects based on EnTT and did not hold back when it came to documenting them.
|
||||
|
||||
Below an incomplete list of projects and articles:
|
||||
|
||||
* [EnttPong](https://github.com/reworks/EnttPong): example game for `EnTT`
|
||||
framework.
|
||||
* [Minecraft](https://minecraft.net/en-us/attribution/): of course, **that** Minecraft, by Mojang (see the open source attributions page).
|
||||
* [Face Smash](https://play.google.com/store/apps/details?id=com.gamee.facesmash):
|
||||
the emojis dominate the world, destroy them all with your facial expressions.
|
||||
* [EnttPong](https://github.com/reworks/EnttPong): example game with `EnTT`.
|
||||
* [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
|
||||
@@ -2728,30 +2782,55 @@ Below an incomplete list of projects and articles:
|
||||
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.
|
||||
|
||||
<!--
|
||||
@cond TURN_OFF_DOXYGEN
|
||||
-->
|
||||
# Contributors
|
||||
|
||||
If you want to participate, please see the guidelines for
|
||||
[contributing](https://github.com/skypjack/entt/blob/master/CONTRIBUTING)
|
||||
before to create issues or pull requests.<br/>
|
||||
`EnTT` was written initially as a faster alternative to other well known and
|
||||
open source entity-component systems. Nowadays this library is moving its first
|
||||
steps. Much more will come in the future and hopefully I'm going to work on it
|
||||
for a long time.<br/>
|
||||
Requests for features, PR, suggestions ad feedback are highly appreciated.
|
||||
|
||||
If you find you can help me and want to contribute to the project with your
|
||||
experience or you do want to get part of the project for some other reasons,
|
||||
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 seriously.
|
||||
|
||||
If you decide to participate, please see the guidelines for
|
||||
[contributing](docs/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.
|
||||
<!--
|
||||
@endcond TURN_OFF_DOXYGEN
|
||||
-->
|
||||
|
||||
# License
|
||||
|
||||
Code and documentation Copyright (c) 2018 Michele Caini.<br/>
|
||||
Code and documentation Copyright (c) 2017-2018 Michele Caini.<br/>
|
||||
Logo Copyright (c) 2018 Richard Caseres.
|
||||
|
||||
Code released under
|
||||
[the MIT license](https://github.com/skypjack/entt/blob/master/LICENSE).
|
||||
Docs released under
|
||||
[Creative Commons](https://github.com/skypjack/entt/blob/master/docs/LICENSE).
|
||||
Documentation released under
|
||||
[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).<br/>
|
||||
Logo released under
|
||||
[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
|
||||
<!--
|
||||
@cond TURN_OFF_DOXYGEN
|
||||
-->
|
||||
# Support
|
||||
|
||||
## Donation
|
||||
|
||||
Developing and maintaining `EnTT` takes some time and lots of coffee. I'd like
|
||||
to add more and more functionalities in future and turn it in a full-featured
|
||||
framework.<br/>
|
||||
solution.<br/>
|
||||
If you want to support this project, you can offer me an espresso. I'm from
|
||||
Italy, we're used to turning the best coffee ever in code. If you find that
|
||||
it's not enough, feel free to support me the way you prefer.<br/>
|
||||
@@ -2765,3 +2844,6 @@ to give it the highest priority, if you have any other reason to contact me:
|
||||
do not hesitate. I'm available for hiring.<br/>
|
||||
Feel free to take a look at my [profile](https://github.com/skypjack) and
|
||||
contact me by mail.
|
||||
<!--
|
||||
@endcond TURN_OFF_DOXYGEN
|
||||
-->
|
||||
|
||||
7
TODO
7
TODO
@@ -5,8 +5,11 @@
|
||||
* define basic reactive systems (track entities to which component is attached, track entities from which component is removed, and so on)
|
||||
* define systems as composable mixins (initializazion, reactive, update, whatever) with flexible auto-detected arguments (registry, views, etc)
|
||||
* create dedicated flat map based on types implementation (sort of "type map") for types to use within the registry and so on...
|
||||
* ease the assignment of tags as string (type-less assign member function + user defined literal for hashed strings)
|
||||
* family -> std::uint32_t (or some other fixed and known size type)
|
||||
* registry::create with a "hint" on the entity identifier to use, it should ease combining multiple registries
|
||||
* optimize for empty components, it would be a mid improvement in terms of memory usage
|
||||
* add some lazy iterative sorters like "single bubble sort loop"
|
||||
* can we do more for shared libraries? who knows... see #144
|
||||
* work stealing job system (see #100)
|
||||
* reflection system (maybe)
|
||||
* C++17. That's all.
|
||||
* AOB
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Doxygen configuration (documentation)
|
||||
#
|
||||
|
||||
set(DOXY_SOURCE_DIRECTORY ${entt_SOURCE_DIR}/src)
|
||||
set(DOXY_SOURCE_DIRECTORY ${EnTT_SOURCE_DIR}/src)
|
||||
set(DOXY_DOCS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(DOXY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
@@ -11,7 +11,7 @@ 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}
|
||||
WORKING_DIRECTORY ${EnTT_SOURCE_DIR}
|
||||
VERBATIM
|
||||
SOURCES doxy.in
|
||||
)
|
||||
|
||||
395
docs/LICENSE
395
docs/LICENSE
@@ -1,395 +0,0 @@
|
||||
Attribution 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More_considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution 4.0 International Public License ("Public License"). To the
|
||||
extent this Public License may be interpreted as a contract, You are
|
||||
granted the Licensed Rights in consideration of Your acceptance of
|
||||
these terms and conditions, and the Licensor grants You such rights in
|
||||
consideration of benefits the Licensor receives from making the
|
||||
Licensed Material available under these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
d. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
f. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
g. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
i. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
j. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
k. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
4. If You Share Adapted Material You produce, the Adapter's
|
||||
License You apply must not prevent recipients of the Adapted
|
||||
Material from complying with this Public License.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material; and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
||||
60
scripts/update_homebrew.sh
Executable file
60
scripts/update_homebrew.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
|
||||
# only argument should be the version to upgrade to
|
||||
if [ $# != 1 ]
|
||||
then
|
||||
echo "Expected a version tag like v2.7.1"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION="$1"
|
||||
URL="https://github.com/skypjack/entt/archive/$VERSION.tar.gz"
|
||||
FORMULA="entt.rb"
|
||||
|
||||
echo "Updating homebrew package to $VERSION"
|
||||
|
||||
echo "Cloning..."
|
||||
git clone https://github.com/skypjack/homebrew-entt.git
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
cd homebrew-entt
|
||||
|
||||
# download the repo at the version
|
||||
# exit with error messages if curl fails
|
||||
echo "Curling..."
|
||||
curl "$URL" --location --fail --silent --show-error --output archive.tar.gz
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# compute sha256 hash
|
||||
echo "Hashing..."
|
||||
HASH="$(openssl sha256 archive.tar.gz | cut -d " " -f 2)"
|
||||
|
||||
# delete the archive
|
||||
rm archive.tar.gz
|
||||
|
||||
echo "Sedding..."
|
||||
|
||||
# change the url in the formula file
|
||||
# the slashes in the URL must be escaped
|
||||
ESCAPED_URL="$(sed -e 's/[\/&]/\\&/g' <<< "$URL")"
|
||||
sed -i -e '/url/s/".*"/"'$ESCAPED_URL'"/' $FORMULA
|
||||
|
||||
# change the hash in the formula file
|
||||
sed -i -e '/sha256/s/".*"/"'$HASH'"/' $FORMULA
|
||||
|
||||
# delete temporary file created by sed
|
||||
rm "$FORMULA-e"
|
||||
|
||||
# update remote repo
|
||||
echo "Gitting..."
|
||||
git add entt.rb
|
||||
git commit -m "Update to $VERSION"
|
||||
git push origin master
|
||||
|
||||
# out of homebrew-entt dir
|
||||
cd ..
|
||||
3
scripts/update_packages.sh
Executable file
3
scripts/update_packages.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
scripts/update_homebrew.sh $1
|
||||
@@ -18,11 +18,11 @@ namespace entt {
|
||||
* This class fills the gap by wrapping some flavors of `std::sort` in a
|
||||
* function object.
|
||||
*/
|
||||
struct StdSort {
|
||||
struct StdSort final {
|
||||
/**
|
||||
* @brief Sorts the element in a range.
|
||||
* @brief Sorts the elements in a range.
|
||||
*
|
||||
* Sorts the element in a range using the given binary comparison function.
|
||||
* Sorts the elements in a range using the given binary comparison function.
|
||||
*
|
||||
* @tparam It Type of random access iterator.
|
||||
* @tparam Compare Type of comparison function object.
|
||||
@@ -40,11 +40,11 @@ struct StdSort {
|
||||
|
||||
|
||||
/*! @brief Function object for performing insertion sort. */
|
||||
struct InsertionSort {
|
||||
struct InsertionSort final {
|
||||
/**
|
||||
* @brief Sorts the element in a range.
|
||||
* @brief Sorts the elements in a range.
|
||||
*
|
||||
* Sorts the element in a range using the given binary comparison function.
|
||||
* Sorts the elements in a range using the given binary comparison function.
|
||||
*
|
||||
* @tparam It Type of random access iterator.
|
||||
* @tparam Compare Type of comparison function object.
|
||||
@@ -72,6 +72,39 @@ struct InsertionSort {
|
||||
};
|
||||
|
||||
|
||||
/*! @brief Function object for performing bubble sort (single iteration). */
|
||||
struct OneShotBubbleSort final {
|
||||
/**
|
||||
* @brief Tries to sort the elements in a range.
|
||||
*
|
||||
* Performs a single iteration to sort the elements in a range using the
|
||||
* given binary comparison function. The range may not be completely sorted
|
||||
* after running this function.
|
||||
*
|
||||
* @tparam It Type of random access iterator.
|
||||
* @tparam Compare Type of comparison function object.
|
||||
* @param first An iterator to the first element of the range to sort.
|
||||
* @param last An iterator past the last element of the range to sort.
|
||||
* @param compare A valid comparison function object.
|
||||
*/
|
||||
template<typename It, typename Compare = std::less<>>
|
||||
void operator()(It first, It last, Compare compare = Compare{}) const {
|
||||
if(first != last) {
|
||||
auto it = first++;
|
||||
|
||||
while(first != last) {
|
||||
if(compare(*first, *it)) {
|
||||
using std::swap;
|
||||
std::swap(*first, *it);
|
||||
}
|
||||
|
||||
it = first++;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -108,6 +108,11 @@ constexpr bool operator!=(const HashedString &lhs, const HashedString &rhs) ENTT
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief User defined literal for hashed strings.
|
||||
* @param str The literal without its suffix.
|
||||
* @return A properly initialized hashed string.
|
||||
*/
|
||||
constexpr entt::HashedString operator"" ENTT_HS_SUFFIX(const char *str, std::size_t) ENTT_NOEXCEPT {
|
||||
return entt::HashedString{str};
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define ENTT_ENTITY_HELPER_HPP
|
||||
|
||||
|
||||
#include <type_traits>
|
||||
#include "../core/hashed_string.hpp"
|
||||
#include "../signal/sigh.hpp"
|
||||
#include "registry.hpp"
|
||||
#include "utility.hpp"
|
||||
@@ -78,6 +80,25 @@ void dependency(break_t, Sink<void(Registry<Entity> &, const Entity)> sink) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Alias template to ease the assignment of labels to entities.
|
||||
*
|
||||
* If used in combination with hashed strings, it simplifies the assignment of
|
||||
* labels to entities and the use of labels in general where a type would be
|
||||
* required otherwise.<br/>
|
||||
* As an example and where the user defined literal for hashed strings hasn't
|
||||
* been changed:
|
||||
* @code{.cpp}
|
||||
* entt::DefaultRegistry registry;
|
||||
* registry.assign<entt::label<"enemy"_hs>>(entity);
|
||||
* @endcode
|
||||
*
|
||||
* @tparam Value The numeric representation of an instance of hashed string.
|
||||
*/
|
||||
template<typename HashedString::hash_type Value>
|
||||
using label = std::integral_constant<typename HashedString::hash_type, Value>;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@ class Registry {
|
||||
using signal_type = SigH<void(Registry &, const Entity)>;
|
||||
using traits_type = entt_traits<Entity>;
|
||||
|
||||
template<typename... Component>
|
||||
template<typename handler_family::family_type(*Type)(), typename... Component>
|
||||
static void creating(Registry ®istry, const Entity entity) {
|
||||
if(registry.has<Component...>(entity)) {
|
||||
registry.handlers[handler_family::type<Component...>()]->construct(entity);
|
||||
registry.handlers[Type()]->construct(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,35 @@ class Registry {
|
||||
Tag tag;
|
||||
};
|
||||
|
||||
template<typename Comp, std::size_t Pivot, typename... Component, std::size_t... Indexes>
|
||||
void connect(std::index_sequence<Indexes...>) {
|
||||
auto &cpool = pools[component_family::type<Comp>()];
|
||||
std::get<1>(cpool).sink().template connect<&Registry::creating<&handler_family::type<Component...>, std::tuple_element_t<(Indexes < Pivot ? Indexes : (Indexes+1)), std::tuple<Component...>>...>>();
|
||||
std::get<2>(cpool).sink().template connect<&Registry::destroying<Component...>>();
|
||||
}
|
||||
|
||||
template<typename... Component, std::size_t... Indexes>
|
||||
void connect(std::index_sequence<Indexes...>) {
|
||||
using accumulator_type = int[];
|
||||
accumulator_type accumulator = { (assure<Component>(), connect<Component, Indexes, Component...>(std::make_index_sequence<sizeof...(Component)-1>{}), 0)... };
|
||||
(void)accumulator;
|
||||
}
|
||||
|
||||
template<typename Comp, std::size_t Pivot, typename... Component, std::size_t... Indexes>
|
||||
void disconnect(std::index_sequence<Indexes...>) {
|
||||
auto &cpool = pools[component_family::type<Comp>()];
|
||||
std::get<1>(cpool).sink().template disconnect<&Registry::creating<&handler_family::type<Component...>, std::tuple_element_t<(Indexes < Pivot ? Indexes : (Indexes+1)), std::tuple<Component...>>...>>();
|
||||
std::get<2>(cpool).sink().template disconnect<&Registry::destroying<Component...>>();
|
||||
}
|
||||
|
||||
template<typename... Component, std::size_t... Indexes>
|
||||
void disconnect(std::index_sequence<Indexes...>) {
|
||||
using accumulator_type = int[];
|
||||
// if a set exists, pools have already been created for it
|
||||
accumulator_type accumulator = { (disconnect<Component, Indexes, Component...>(std::make_index_sequence<sizeof...(Component)-1>{}), 0)... };
|
||||
(void)accumulator;
|
||||
}
|
||||
|
||||
template<typename Component>
|
||||
inline bool managed() const ENTT_NOEXCEPT {
|
||||
const auto ctype = component_family::type<Component>();
|
||||
@@ -187,11 +216,19 @@ public:
|
||||
return managed<Component>() ? pool<Component>().size() : size_type{};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of entities created so far.
|
||||
* @return Number of entities created so far.
|
||||
*/
|
||||
size_type size() const ENTT_NOEXCEPT {
|
||||
return entities.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of entities still in use.
|
||||
* @return Number of entities still in use.
|
||||
*/
|
||||
size_type size() const ENTT_NOEXCEPT {
|
||||
size_type alive() const ENTT_NOEXCEPT {
|
||||
return entities.size() - available;
|
||||
}
|
||||
|
||||
@@ -350,10 +387,19 @@ public:
|
||||
return (entities[pos] == entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the entity identifier without the version.
|
||||
* @param entity An entity identifier, either valid or not.
|
||||
* @return The entity identifier without the version.
|
||||
*/
|
||||
entity_type entity(const entity_type entity) const ENTT_NOEXCEPT {
|
||||
return entity & traits_type::entity_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the version stored along with an entity identifier.
|
||||
* @param entity An entity identifier, either valid or not.
|
||||
* @return Version stored along with the given entity identifier.
|
||||
* @return The version stored along with the given entity identifier.
|
||||
*/
|
||||
version_type version(const entity_type entity) const ENTT_NOEXCEPT {
|
||||
return version_type((entity >> traits_type::entity_shift) & traits_type::version_mask);
|
||||
@@ -405,7 +451,6 @@ public:
|
||||
if(available) {
|
||||
const auto entt = next;
|
||||
const auto version = entities[entt] & (~traits_type::entity_mask);
|
||||
|
||||
entity = entt | version;
|
||||
next = entities[entt] & traits_type::entity_mask;
|
||||
entities[entt] = entity;
|
||||
@@ -487,17 +532,17 @@ public:
|
||||
// just a way to protect users from listeners that attach components
|
||||
assert(orphan(entity));
|
||||
|
||||
// lengthens the implicit list of destroyed entities
|
||||
const auto entt = entity & traits_type::entity_mask;
|
||||
const auto version = (((entity >> traits_type::entity_shift) + 1) & traits_type::version_mask) << traits_type::entity_shift;
|
||||
const auto node = (available ? next : ((entt + 1) & traits_type::entity_mask)) | version;
|
||||
|
||||
entities[entt] = node;
|
||||
next = entt;
|
||||
++available;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroys the entities that own he given components, if any.
|
||||
* @brief Destroys the entities that own the given components, if any.
|
||||
*
|
||||
* Convenient shortcut to destroy a set of entities at once.<br/>
|
||||
* Syntactic sugar for the following snippet:
|
||||
@@ -1335,22 +1380,13 @@ public:
|
||||
}
|
||||
|
||||
if(!handlers[htype]) {
|
||||
connect<Component...>(std::make_index_sequence<sizeof...(Component)>{});
|
||||
handlers[htype] = std::make_unique<SparseSet<entity_type>>();
|
||||
auto &handler = handlers[htype];
|
||||
auto &handler = *handlers[htype];
|
||||
|
||||
for(auto entity: view<Component...>()) {
|
||||
handler->construct(entity);
|
||||
handler.construct(entity);
|
||||
}
|
||||
|
||||
auto connect = [this](const auto ctype) {
|
||||
auto &cpool = pools[ctype];
|
||||
std::get<1>(cpool).sink().template connect<&Registry::creating<Component...>>();
|
||||
std::get<2>(cpool).sink().template connect<&Registry::destroying<Component...>>();
|
||||
};
|
||||
|
||||
using accumulator_type = int[];
|
||||
accumulator_type accumulator = { (assure<Component>(), connect(component_family::type<Component>()), 0)... };
|
||||
(void)accumulator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1372,19 +1408,8 @@ public:
|
||||
template<typename... Component>
|
||||
void discard() {
|
||||
if(contains<Component...>()) {
|
||||
const auto htype = handler_family::type<Component...>();
|
||||
|
||||
auto disconnect = [this](const auto ctype) {
|
||||
auto &cpool = pools[ctype];
|
||||
std::get<1>(cpool).sink().template disconnect<&Registry::creating<Component...>>();
|
||||
std::get<2>(cpool).sink().template disconnect<&Registry::destroying<Component...>>();
|
||||
};
|
||||
|
||||
// if a set exists, pools have already been created for it
|
||||
using accumulator_type = int[];
|
||||
accumulator_type accumulator = { (disconnect(component_family::type<Component>()), 0)... };
|
||||
handlers[htype].reset();
|
||||
(void)accumulator;
|
||||
disconnect<Component...>(std::make_index_sequence<sizeof...(Component)>{});
|
||||
handlers[handler_family::type<Component...>()].reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
*/
|
||||
template<typename Archive>
|
||||
const Snapshot & entities(Archive &archive) const {
|
||||
archive(static_cast<Entity>(registry.size()));
|
||||
archive(static_cast<Entity>(registry.alive()));
|
||||
registry.each([&archive](const auto entity) { archive(entity); });
|
||||
return *this;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
*/
|
||||
template<typename Archive>
|
||||
const Snapshot & destroyed(Archive &archive) const {
|
||||
auto size = registry.capacity() - registry.size();
|
||||
auto size = registry.size() - registry.alive();
|
||||
archive(static_cast<Entity>(size));
|
||||
auto curr = seed;
|
||||
|
||||
|
||||
@@ -63,16 +63,16 @@ class SparseSet<Entity> {
|
||||
class Iterator final {
|
||||
friend class SparseSet<Entity>;
|
||||
|
||||
using entity_type = Entity;
|
||||
using direct_type = const std::vector<Entity>;
|
||||
using index_type = typename traits_type::difference_type;
|
||||
|
||||
Iterator(const entity_type *direct, index_type index) ENTT_NOEXCEPT
|
||||
Iterator(direct_type *direct, index_type index) ENTT_NOEXCEPT
|
||||
: direct{direct}, index{index}
|
||||
{}
|
||||
|
||||
public:
|
||||
using difference_type = index_type;
|
||||
using value_type = const entity_type;
|
||||
using value_type = const Entity;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
@@ -122,7 +122,7 @@ class SparseSet<Entity> {
|
||||
}
|
||||
|
||||
reference operator[](const difference_type value) const ENTT_NOEXCEPT {
|
||||
return direct[index-value-1];
|
||||
return (*direct)[index-value-1];
|
||||
}
|
||||
|
||||
bool operator==(const Iterator &other) const ENTT_NOEXCEPT {
|
||||
@@ -150,7 +150,7 @@ class SparseSet<Entity> {
|
||||
}
|
||||
|
||||
pointer operator->() const ENTT_NOEXCEPT {
|
||||
return (direct+index-1);
|
||||
return &(*direct)[index-1];
|
||||
}
|
||||
|
||||
inline reference operator*() const ENTT_NOEXCEPT {
|
||||
@@ -158,7 +158,7 @@ class SparseSet<Entity> {
|
||||
}
|
||||
|
||||
private:
|
||||
pointer direct;
|
||||
direct_type *direct;
|
||||
index_type index;
|
||||
};
|
||||
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
*/
|
||||
const_iterator_type cbegin() const ENTT_NOEXCEPT {
|
||||
const typename traits_type::difference_type pos = direct.size();
|
||||
return const_iterator_type{direct.data(), pos};
|
||||
return const_iterator_type{&direct, pos};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,7 +327,7 @@ public:
|
||||
* internal packed array.
|
||||
*/
|
||||
const_iterator_type cend() const ENTT_NOEXCEPT {
|
||||
return const_iterator_type{direct.data(), {}};
|
||||
return const_iterator_type{&direct, {}};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -578,7 +578,7 @@ class SparseSet<Entity, Type>: public SparseSet<Entity> {
|
||||
class Iterator final {
|
||||
friend class SparseSet<Entity, Type>;
|
||||
|
||||
using instance_type = std::conditional_t<Const, const Type, Type>;
|
||||
using instance_type = std::conditional_t<Const, const std::vector<Type>, std::vector<Type>>;
|
||||
using index_type = typename traits_type::difference_type;
|
||||
|
||||
Iterator(instance_type *instances, index_type index) ENTT_NOEXCEPT
|
||||
@@ -587,7 +587,7 @@ class SparseSet<Entity, Type>: public SparseSet<Entity> {
|
||||
|
||||
public:
|
||||
using difference_type = index_type;
|
||||
using value_type = instance_type;
|
||||
using value_type = std::conditional_t<Const, const Type, Type>;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
@@ -637,7 +637,7 @@ class SparseSet<Entity, Type>: public SparseSet<Entity> {
|
||||
}
|
||||
|
||||
reference operator[](const difference_type value) const ENTT_NOEXCEPT {
|
||||
return instances[index-value-1];
|
||||
return (*instances)[index-value-1];
|
||||
}
|
||||
|
||||
bool operator==(const Iterator &other) const ENTT_NOEXCEPT {
|
||||
@@ -665,7 +665,7 @@ class SparseSet<Entity, Type>: public SparseSet<Entity> {
|
||||
}
|
||||
|
||||
pointer operator->() const ENTT_NOEXCEPT {
|
||||
return (instances+index-1);
|
||||
return &(*instances)[index-1];
|
||||
}
|
||||
|
||||
inline reference operator*() const ENTT_NOEXCEPT {
|
||||
@@ -673,7 +673,7 @@ class SparseSet<Entity, Type>: public SparseSet<Entity> {
|
||||
}
|
||||
|
||||
private:
|
||||
pointer instances;
|
||||
instance_type *instances;
|
||||
index_type index;
|
||||
};
|
||||
|
||||
@@ -767,7 +767,7 @@ public:
|
||||
*/
|
||||
const_iterator_type cbegin() const ENTT_NOEXCEPT {
|
||||
const typename traits_type::difference_type pos = instances.size();
|
||||
return const_iterator_type{instances.data(), pos};
|
||||
return const_iterator_type{&instances, pos};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -800,7 +800,7 @@ public:
|
||||
*/
|
||||
iterator_type begin() ENTT_NOEXCEPT {
|
||||
const typename traits_type::difference_type pos = instances.size();
|
||||
return iterator_type{instances.data(), pos};
|
||||
return iterator_type{&instances, pos};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -818,7 +818,7 @@ public:
|
||||
* given type.
|
||||
*/
|
||||
const_iterator_type cend() const ENTT_NOEXCEPT {
|
||||
return const_iterator_type{instances.data(), {}};
|
||||
return const_iterator_type{&instances, {}};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -854,7 +854,7 @@ public:
|
||||
* given type.
|
||||
*/
|
||||
iterator_type end() ENTT_NOEXCEPT {
|
||||
return iterator_type{instances.data(), {}};
|
||||
return iterator_type{&instances, {}};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -590,26 +590,21 @@ class View final {
|
||||
template<typename Comp, typename Func, std::size_t... Indexes>
|
||||
void each(const pool_type<Comp> &cpool, Func func, std::index_sequence<Indexes...>) const {
|
||||
const auto other = unchecked(&cpool);
|
||||
std::array<underlying_iterator_type, sizeof...(Component)> data{{cpool.view_type::cbegin(), std::get<Indexes>(other)->cbegin()...}};
|
||||
std::array<underlying_iterator_type, sizeof...(Indexes)> data{{std::get<Indexes>(other)->cbegin()...}};
|
||||
const auto extent = std::min({ pool<Component>().extent()... });
|
||||
auto raw = std::make_tuple(pool<Component>().cbegin()...);
|
||||
const auto end = cpool.view_type::cend();
|
||||
std::size_t pos{};
|
||||
auto begin = cpool.view_type::cbegin();
|
||||
|
||||
// we can directly use the raw iterators if pools are ordered
|
||||
while(!pos && data[0] != end) {
|
||||
for(pos = data.size() - 1; pos && *(data[pos]++) == *data[pos-1]; --pos);
|
||||
|
||||
if(!pos) {
|
||||
func(*(data[0]++), *(std::get<component_iterator_type<Component>>(raw)++)...);
|
||||
}
|
||||
while(begin != end && std::min({ (*(std::get<Indexes>(data)++) == *begin)... })) {
|
||||
func(*(begin++), *(std::get<component_iterator_type<Component>>(raw)++)...);
|
||||
}
|
||||
|
||||
const auto extent = std::min({ pool<Component>().extent()... });
|
||||
auto it = std::get<component_iterator_type<Comp>>(raw);
|
||||
|
||||
// fallback to visit what remains using indirections
|
||||
for(; data[0] != end; ++data[0], ++it) {
|
||||
const auto entity = *data[0];
|
||||
while(begin != end) {
|
||||
const auto entity = *(begin++);
|
||||
const auto it = std::get<component_iterator_type<Comp>>(raw)++;
|
||||
const auto sz = size_type(entity & traits_type::entity_mask);
|
||||
|
||||
if(sz < extent && std::all_of(other.cbegin(), other.cend(), [entity](const view_type *view) { return view->fast(entity); })) {
|
||||
@@ -1675,7 +1670,7 @@ class RuntimeView {
|
||||
: pools{std::move(others)}
|
||||
{
|
||||
const auto it = std::min_element(pools.begin(), pools.end(), [](const auto *lhs, const auto *rhs) {
|
||||
return !lhs || (rhs && (lhs->size() < rhs->size()));
|
||||
return (!lhs && rhs) || (lhs && rhs && lhs->size() < rhs->size());
|
||||
});
|
||||
|
||||
// brings the best candidate (if any) on front of the vector
|
||||
|
||||
@@ -2,31 +2,21 @@
|
||||
# Tests configuration
|
||||
#
|
||||
|
||||
include_directories($<TARGET_PROPERTY:EnTT,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
add_compile_options($<TARGET_PROPERTY:EnTT,INTERFACE_COMPILE_OPTIONS>)
|
||||
|
||||
add_library(odr OBJECT odr.cpp)
|
||||
|
||||
set_target_properties(odr PROPERTIES CXX_EXTENSIONS OFF)
|
||||
target_compile_definitions(odr PRIVATE $<TARGET_PROPERTY:EnTT,INTERFACE_COMPILE_DEFINITIONS>)
|
||||
target_compile_features(odr PRIVATE $<TARGET_PROPERTY:EnTT,INTERFACE_COMPILE_FEATURES>)
|
||||
target_compile_options(odr PRIVATE $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-pedantic -Wall>)
|
||||
|
||||
target_include_directories(odr
|
||||
PRIVATE $<TARGET_PROPERTY:EnTT,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
target_compile_definitions(odr
|
||||
PRIVATE $<TARGET_PROPERTY:EnTT,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
|
||||
target_compile_options(odr
|
||||
PRIVATE $<TARGET_PROPERTY:EnTT,INTERFACE_COMPILE_OPTIONS>
|
||||
PRIVATE $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-pedantic -Wall>
|
||||
)
|
||||
|
||||
target_compile_features(odr
|
||||
PRIVATE $<TARGET_PROPERTY:EnTT,INTERFACE_COMPILE_FEATURES>
|
||||
)
|
||||
|
||||
macro(ADD_ENTT_TEST TEST_NAME TEST_SOURCE)
|
||||
macro(SETUP_AND_ADD_TEST TEST_NAME TEST_SOURCE)
|
||||
add_executable(${TEST_NAME} $<TARGET_OBJECTS:odr> ${TEST_SOURCE})
|
||||
target_link_libraries(${TEST_NAME} PRIVATE EnTT gtest_main Threads::Threads)
|
||||
set_target_properties(${TEST_NAME} PROPERTIES CXX_EXTENSIONS OFF)
|
||||
target_link_libraries(${TEST_NAME} PRIVATE EnTT GTest::Main Threads::Threads)
|
||||
target_compile_definitions(${TEST_NAME} PRIVATE $<TARGET_PROPERTY:EnTT,INTERFACE_COMPILE_DEFINITIONS>)
|
||||
target_compile_features(${TEST_NAME} PRIVATE $<TARGET_PROPERTY:EnTT,INTERFACE_COMPILE_FEATURES>)
|
||||
target_compile_options(${TEST_NAME} PRIVATE $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-pedantic -Wall>)
|
||||
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
|
||||
endmacro()
|
||||
@@ -34,71 +24,71 @@ endmacro()
|
||||
# Test benchmark
|
||||
|
||||
if(BUILD_BENCHMARK)
|
||||
ADD_ENTT_TEST(benchmark benchmark/benchmark.cpp)
|
||||
SETUP_AND_ADD_TEST(benchmark benchmark/benchmark.cpp)
|
||||
endif()
|
||||
|
||||
# Test mod
|
||||
|
||||
if(BUILD_MOD)
|
||||
set(DUKTAPE_DEPS_DIR ${entt_SOURCE_DIR}/deps/duktape)
|
||||
configure_file(${entt_SOURCE_DIR}/cmake/in/duktape.in ${DUKTAPE_DEPS_DIR}/CMakeLists.txt)
|
||||
set(DUKTAPE_DEPS_DIR ${EnTT_SOURCE_DIR}/deps/duktape)
|
||||
configure_file(${EnTT_SOURCE_DIR}/cmake/in/duktape.in ${DUKTAPE_DEPS_DIR}/CMakeLists.txt)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${DUKTAPE_DEPS_DIR})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${DUKTAPE_DEPS_DIR})
|
||||
set(DUKTAPE_SRC_DIR ${DUKTAPE_DEPS_DIR}/src/src)
|
||||
|
||||
set(MOD_TEST_SOURCE ${DUKTAPE_SRC_DIR}/duktape.c mod/mod.cpp)
|
||||
ADD_ENTT_TEST(mod "${MOD_TEST_SOURCE}")
|
||||
SETUP_AND_ADD_TEST(mod "${MOD_TEST_SOURCE}")
|
||||
target_include_directories(mod PRIVATE ${DUKTAPE_SRC_DIR})
|
||||
endif()
|
||||
|
||||
# Test snapshot
|
||||
|
||||
if(BUILD_SNAPSHOT)
|
||||
set(CEREAL_DEPS_DIR ${entt_SOURCE_DIR}/deps/cereal)
|
||||
configure_file(${entt_SOURCE_DIR}/cmake/in/cereal.in ${CEREAL_DEPS_DIR}/CMakeLists.txt)
|
||||
set(CEREAL_DEPS_DIR ${EnTT_SOURCE_DIR}/deps/cereal)
|
||||
configure_file(${EnTT_SOURCE_DIR}/cmake/in/cereal.in ${CEREAL_DEPS_DIR}/CMakeLists.txt)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${CEREAL_DEPS_DIR})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${CEREAL_DEPS_DIR})
|
||||
set(CEREAL_SRC_DIR ${CEREAL_DEPS_DIR}/src/include)
|
||||
|
||||
ADD_ENTT_TEST(cereal snapshot/snapshot.cpp)
|
||||
SETUP_AND_ADD_TEST(cereal snapshot/snapshot.cpp)
|
||||
target_include_directories(cereal PRIVATE ${CEREAL_SRC_DIR})
|
||||
endif()
|
||||
|
||||
# Test core
|
||||
|
||||
ADD_ENTT_TEST(algorithm entt/core/algorithm.cpp)
|
||||
ADD_ENTT_TEST(family entt/core/family.cpp)
|
||||
ADD_ENTT_TEST(hashed_string entt/core/hashed_string.cpp)
|
||||
ADD_ENTT_TEST(ident entt/core/ident.cpp)
|
||||
ADD_ENTT_TEST(monostate entt/core/monostate.cpp)
|
||||
SETUP_AND_ADD_TEST(algorithm entt/core/algorithm.cpp)
|
||||
SETUP_AND_ADD_TEST(family entt/core/family.cpp)
|
||||
SETUP_AND_ADD_TEST(hashed_string entt/core/hashed_string.cpp)
|
||||
SETUP_AND_ADD_TEST(ident entt/core/ident.cpp)
|
||||
SETUP_AND_ADD_TEST(monostate entt/core/monostate.cpp)
|
||||
|
||||
# Test entity
|
||||
|
||||
ADD_ENTT_TEST(actor entt/entity/actor.cpp)
|
||||
ADD_ENTT_TEST(entity entt/entity/entity.cpp)
|
||||
ADD_ENTT_TEST(helper entt/entity/helper.cpp)
|
||||
ADD_ENTT_TEST(prototype entt/entity/prototype.cpp)
|
||||
ADD_ENTT_TEST(registry entt/entity/registry.cpp)
|
||||
ADD_ENTT_TEST(snapshot entt/entity/snapshot.cpp)
|
||||
ADD_ENTT_TEST(sparse_set entt/entity/sparse_set.cpp)
|
||||
ADD_ENTT_TEST(view entt/entity/view.cpp)
|
||||
SETUP_AND_ADD_TEST(actor entt/entity/actor.cpp)
|
||||
SETUP_AND_ADD_TEST(entity entt/entity/entity.cpp)
|
||||
SETUP_AND_ADD_TEST(helper entt/entity/helper.cpp)
|
||||
SETUP_AND_ADD_TEST(prototype entt/entity/prototype.cpp)
|
||||
SETUP_AND_ADD_TEST(registry entt/entity/registry.cpp)
|
||||
SETUP_AND_ADD_TEST(snapshot entt/entity/snapshot.cpp)
|
||||
SETUP_AND_ADD_TEST(sparse_set entt/entity/sparse_set.cpp)
|
||||
SETUP_AND_ADD_TEST(view entt/entity/view.cpp)
|
||||
|
||||
# Test locator
|
||||
|
||||
ADD_ENTT_TEST(locator entt/locator/locator.cpp)
|
||||
SETUP_AND_ADD_TEST(locator entt/locator/locator.cpp)
|
||||
|
||||
# Test process
|
||||
|
||||
ADD_ENTT_TEST(process entt/process/process.cpp)
|
||||
ADD_ENTT_TEST(scheduler entt/process/scheduler.cpp)
|
||||
SETUP_AND_ADD_TEST(process entt/process/process.cpp)
|
||||
SETUP_AND_ADD_TEST(scheduler entt/process/scheduler.cpp)
|
||||
|
||||
# Test resource
|
||||
|
||||
ADD_ENTT_TEST(resource entt/resource/resource.cpp)
|
||||
SETUP_AND_ADD_TEST(resource entt/resource/resource.cpp)
|
||||
|
||||
# Test signal
|
||||
|
||||
ADD_ENTT_TEST(delegate entt/signal/delegate.cpp)
|
||||
ADD_ENTT_TEST(dispatcher entt/signal/dispatcher.cpp)
|
||||
ADD_ENTT_TEST(emitter entt/signal/emitter.cpp)
|
||||
ADD_ENTT_TEST(sigh entt/signal/sigh.cpp)
|
||||
SETUP_AND_ADD_TEST(delegate entt/signal/delegate.cpp)
|
||||
SETUP_AND_ADD_TEST(dispatcher entt/signal/dispatcher.cpp)
|
||||
SETUP_AND_ADD_TEST(emitter entt/signal/emitter.cpp)
|
||||
SETUP_AND_ADD_TEST(sigh entt/signal/sigh.cpp)
|
||||
|
||||
@@ -9,7 +9,7 @@ TEST(Algorithm, StdSort) {
|
||||
|
||||
sort(arr.begin(), arr.end());
|
||||
|
||||
for(auto i = 0; i < 4; ++i) {
|
||||
for(typename decltype(arr)::size_type i = 0; i < (arr.size() - 1); ++i) {
|
||||
ASSERT_LT(arr[i], arr[i+1]);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,21 @@ TEST(Algorithm, InsertionSort) {
|
||||
|
||||
sort(arr.begin(), arr.end());
|
||||
|
||||
for(auto i = 0; i < 4; ++i) {
|
||||
for(typename decltype(arr)::size_type i = 0; i < (arr.size() - 1); ++i) {
|
||||
ASSERT_LT(arr[i], arr[i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Algorithm, OneShotBubbleSort) {
|
||||
std::array<int, 5> arr{{4, 1, 3, 2, 0}};
|
||||
entt::OneShotBubbleSort sort;
|
||||
|
||||
sort(arr.begin(), arr.end());
|
||||
sort(arr.begin(), arr.end());
|
||||
sort(arr.begin(), arr.end());
|
||||
sort(arr.begin(), arr.end());
|
||||
|
||||
for(typename decltype(arr)::size_type i = 0; i < (arr.size() - 1); ++i) {
|
||||
ASSERT_LT(arr[i], arr[i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ TEST(Identifier, Uniqueness) {
|
||||
switch(ID::get<AnotherType>()) {
|
||||
case ID::get<AType>():
|
||||
FAIL();
|
||||
break;
|
||||
case ID::get<AnotherType>():
|
||||
SUCCEED();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/hashed_string.hpp>
|
||||
#include <entt/entity/helper.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
TEST(Dependency, Functionalities) {
|
||||
TEST(Helper, Dependency) {
|
||||
entt::DefaultRegistry registry;
|
||||
const auto entity = registry.create();
|
||||
entt::dependency<double, float>(registry.construction<int>());
|
||||
@@ -47,3 +48,28 @@ TEST(Dependency, Functionalities) {
|
||||
ASSERT_FALSE(registry.has<double>(entity));
|
||||
ASSERT_FALSE(registry.has<float>(entity));
|
||||
}
|
||||
|
||||
TEST(Helper, Label) {
|
||||
entt::DefaultRegistry registry;
|
||||
const auto entity = registry.create();
|
||||
registry.assign<entt::label<"foobar"_hs>>(entity);
|
||||
registry.assign<int>(entity, 42);
|
||||
int counter{};
|
||||
|
||||
ASSERT_FALSE(registry.has<entt::label<"barfoo"_hs>>(entity));
|
||||
ASSERT_TRUE(registry.has<entt::label<"foobar"_hs>>(entity));
|
||||
|
||||
for(auto entity: registry.view<int, entt::label<"foobar"_hs>>()) {
|
||||
(void)entity;
|
||||
++counter;
|
||||
}
|
||||
|
||||
ASSERT_NE(counter, 0);
|
||||
|
||||
for(auto entity: registry.view<entt::label<"foobar"_hs>>()) {
|
||||
(void)entity;
|
||||
--counter;
|
||||
}
|
||||
|
||||
ASSERT_EQ(counter, 0);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ TEST(DefaultRegistry, Functionalities) {
|
||||
entt::DefaultRegistry registry;
|
||||
|
||||
ASSERT_EQ(registry.size(), entt::DefaultRegistry::size_type{0});
|
||||
ASSERT_EQ(registry.alive(), entt::DefaultRegistry::size_type{0});
|
||||
ASSERT_NO_THROW(registry.reserve(42));
|
||||
ASSERT_NO_THROW(registry.reserve<int>(8));
|
||||
ASSERT_NO_THROW(registry.reserve<char>(8));
|
||||
@@ -134,6 +135,7 @@ TEST(DefaultRegistry, Functionalities) {
|
||||
ASSERT_EQ(static_cast<const entt::DefaultRegistry &>(registry).get<int>(e1), 1);
|
||||
|
||||
ASSERT_EQ(registry.size(), entt::DefaultRegistry::size_type{3});
|
||||
ASSERT_EQ(registry.alive(), entt::DefaultRegistry::size_type{3});
|
||||
ASSERT_FALSE(registry.empty());
|
||||
|
||||
ASSERT_EQ(registry.version(e2), entt::DefaultRegistry::version_type{0});
|
||||
@@ -149,12 +151,14 @@ TEST(DefaultRegistry, Functionalities) {
|
||||
ASSERT_FALSE(registry.valid(e2));
|
||||
ASSERT_FALSE(registry.fast(e2));
|
||||
|
||||
ASSERT_EQ(registry.size(), entt::DefaultRegistry::size_type{2});
|
||||
ASSERT_EQ(registry.size(), entt::DefaultRegistry::size_type{3});
|
||||
ASSERT_EQ(registry.alive(), entt::DefaultRegistry::size_type{2});
|
||||
ASSERT_FALSE(registry.empty());
|
||||
|
||||
ASSERT_NO_THROW(registry.reset());
|
||||
|
||||
ASSERT_EQ(registry.size(), entt::DefaultRegistry::size_type{0});
|
||||
ASSERT_EQ(registry.size(), entt::DefaultRegistry::size_type{3});
|
||||
ASSERT_EQ(registry.alive(), entt::DefaultRegistry::size_type{0});
|
||||
ASSERT_TRUE(registry.empty());
|
||||
|
||||
const auto e3 = registry.create();
|
||||
@@ -194,6 +198,22 @@ TEST(DefaultRegistry, Functionalities) {
|
||||
ASSERT_TRUE(registry.empty<int>());
|
||||
}
|
||||
|
||||
TEST(DefaultRegistry, Identifiers) {
|
||||
entt::DefaultRegistry registry;
|
||||
const auto pre = registry.create();
|
||||
|
||||
ASSERT_EQ(pre, registry.entity(pre));
|
||||
|
||||
registry.destroy(pre);
|
||||
const auto post = registry.create();
|
||||
|
||||
ASSERT_NE(pre, post);
|
||||
ASSERT_EQ(registry.entity(pre), registry.entity(post));
|
||||
ASSERT_NE(registry.version(pre), registry.version(post));
|
||||
ASSERT_NE(registry.version(pre), registry.current(pre));
|
||||
ASSERT_EQ(registry.version(post), registry.current(post));
|
||||
}
|
||||
|
||||
TEST(DefaultRegistry, RawData) {
|
||||
entt::DefaultRegistry registry;
|
||||
const entt::DefaultRegistry &cregistry = registry;
|
||||
|
||||
@@ -337,6 +337,22 @@ TEST(SparseSetNoType, RespectUnordered) {
|
||||
ASSERT_EQ(rhs.get(5), 5u);
|
||||
}
|
||||
|
||||
TEST(SparseSetNoType, CanModifyDuringIteration) {
|
||||
entt::SparseSet<std::uint64_t> set;
|
||||
set.construct(0);
|
||||
|
||||
ASSERT_EQ(set.capacity(), entt::SparseSet<std::uint64_t>::size_type{1});
|
||||
|
||||
const auto it = set.cbegin();
|
||||
set.reserve(entt::SparseSet<std::uint64_t>::size_type{2});
|
||||
|
||||
ASSERT_EQ(set.capacity(), entt::SparseSet<std::uint64_t>::size_type{2});
|
||||
|
||||
// this should crash with asan enabled if we break the constraint
|
||||
const auto entity = *it;
|
||||
(void)entity;
|
||||
}
|
||||
|
||||
TEST(SparseSetWithType, Functionalities) {
|
||||
entt::SparseSet<std::uint64_t, int> set;
|
||||
const auto &cset = set;
|
||||
@@ -823,6 +839,22 @@ TEST(SparseSetWithType, RespectUnordered) {
|
||||
ASSERT_EQ(*(rhs.data() + 5u), 5u);
|
||||
}
|
||||
|
||||
TEST(SparseSetWithType, CanModifyDuringIteration) {
|
||||
entt::SparseSet<std::uint64_t, int> set;
|
||||
set.construct(0, 42);
|
||||
|
||||
ASSERT_EQ(set.capacity(), entt::SparseSet<std::uint64_t>::size_type{1});
|
||||
|
||||
const auto it = set.cbegin();
|
||||
set.reserve(entt::SparseSet<std::uint64_t>::size_type{2});
|
||||
|
||||
ASSERT_EQ(set.capacity(), entt::SparseSet<std::uint64_t>::size_type{2});
|
||||
|
||||
// this should crash with asan enabled if we break the constraint
|
||||
const auto entity = *it;
|
||||
(void)entity;
|
||||
}
|
||||
|
||||
TEST(SparseSetWithType, ReferencesGuaranteed) {
|
||||
struct InternalType { int value; };
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ TEST(SigH, Functions) {
|
||||
sigh.publish(v);
|
||||
|
||||
ASSERT_FALSE(sigh.empty());
|
||||
ASSERT_EQ((entt::SigH<bool(int)>::size_type)1, sigh.size());
|
||||
ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(1), sigh.size());
|
||||
ASSERT_EQ(42, v);
|
||||
|
||||
v = 0;
|
||||
@@ -150,7 +150,7 @@ TEST(SigH, Functions) {
|
||||
sigh.publish(v);
|
||||
|
||||
ASSERT_TRUE(sigh.empty());
|
||||
ASSERT_EQ((entt::SigH<bool(int)>::size_type)0, sigh.size());
|
||||
ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(0), sigh.size());
|
||||
ASSERT_EQ(0, v);
|
||||
|
||||
sigh.sink().connect<&SigHListener::f>();
|
||||
@@ -166,25 +166,25 @@ TEST(SigH, Members) {
|
||||
|
||||
ASSERT_TRUE(s.k);
|
||||
ASSERT_FALSE(sigh.empty());
|
||||
ASSERT_EQ((entt::SigH<bool(int)>::size_type)1, sigh.size());
|
||||
ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(1), sigh.size());
|
||||
|
||||
sigh.sink().disconnect<SigHListener, &SigHListener::g>(ptr);
|
||||
sigh.publish(42);
|
||||
|
||||
ASSERT_TRUE(s.k);
|
||||
ASSERT_TRUE(sigh.empty());
|
||||
ASSERT_EQ((entt::SigH<bool(int)>::size_type)0, sigh.size());
|
||||
ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(0), sigh.size());
|
||||
|
||||
sigh.sink().connect<SigHListener, &SigHListener::g>(ptr);
|
||||
sigh.sink().connect<SigHListener, &SigHListener::h>(ptr);
|
||||
|
||||
ASSERT_FALSE(sigh.empty());
|
||||
ASSERT_EQ((entt::SigH<bool(int)>::size_type)2, sigh.size());
|
||||
ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(2), sigh.size());
|
||||
|
||||
sigh.sink().disconnect(ptr);
|
||||
|
||||
ASSERT_TRUE(sigh.empty());
|
||||
ASSERT_EQ((entt::SigH<bool(int)>::size_type)0, sigh.size());
|
||||
ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(0), sigh.size());
|
||||
}
|
||||
|
||||
TEST(SigH, Collector) {
|
||||
@@ -205,7 +205,7 @@ TEST(SigH, Collector) {
|
||||
|
||||
ASSERT_FALSE(sigh_all.empty());
|
||||
ASSERT_FALSE(collector_all.vec.empty());
|
||||
ASSERT_EQ((std::vector<int>::size_type)2, collector_all.vec.size());
|
||||
ASSERT_EQ(static_cast<std::vector<int>::size_type>(2), collector_all.vec.size());
|
||||
ASSERT_EQ(42, collector_all.vec[0]);
|
||||
ASSERT_EQ(42, collector_all.vec[1]);
|
||||
|
||||
@@ -217,6 +217,6 @@ TEST(SigH, Collector) {
|
||||
|
||||
ASSERT_FALSE(sigh_first.empty());
|
||||
ASSERT_FALSE(collector_first.vec.empty());
|
||||
ASSERT_EQ((std::vector<int>::size_type)1, collector_first.vec.size());
|
||||
ASSERT_EQ(static_cast<std::vector<int>::size_type>(1), collector_first.vec.size());
|
||||
ASSERT_EQ(42, collector_first.vec[0]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user