Skip to content

Commit

Permalink
BREAKING CHANGE: ecstasy::ResourceReference now use std::reference_wr…
Browse files Browse the repository at this point in the history
…apper when not thread safe

Also removed the templated ecstasy::Resource and base ecstasy::ResourceBase classes, both replaced by the simplier IResource base class.

Close #170
  • Loading branch information
AndreasLrx committed Oct 18, 2024
1 parent fb60b28 commit 8bd8928
Show file tree
Hide file tree
Showing 24 changed files with 196 additions and 145 deletions.
2 changes: 1 addition & 1 deletion doc/Building.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ _In case this documentation is not up to date with the [Options.cmake](/cmake/Op
| ENABLE_COVERAGE | Enable code coverage tracking. Must be set with **BUILD_TEST_SUITE** to have the tests coverage | OFF |
| BUILD_SHARED_LIBS | Build Ecstasy as shared libaries | OFF |
| ECSTASY_THREAD_SAFE | Combination of **ECSTASY_AUTO_LOCK**, **ECSTASY_AUTO_LOCK_RESOURCES**, **ECSTASY_LOCKABLE_RESOURCES** and **ECSTASY_LOCKABLE_STORAGES** | OFF |
| ECSTASY_LOCKABLE_RESOURCES | Make [Resource](@ref ecstasy::Resource) inherit [SharedRecursiveMutex](@ref ecstasy::thread::SharedRecursiveMutex) | OFF |
| ECSTASY_LOCKABLE_RESOURCES | Make [IResource](@ref ecstasy::IResource) inherit [SharedRecursiveMutex](@ref ecstasy::thread::SharedRecursiveMutex) | OFF |
| ECSTASY_LOCKABLE_STORAGES | Make [IStorage](@ref ecstasy::IStorage) inherit [SharedRecursiveMutex](@ref ecstasy::thread::SharedRecursiveMutex) | OFF |
| ECSTASY_AUTO_LOCK | Auto lock lockable queryables in registry queries | OFF |
| ECSTASY_AUTO_LOCK_RESOURCES | Auto lock resources with registry.getResource. Requires **ECSTASY_LOCKABLE_RESOURCES** | OFF |
Expand Down
4 changes: 2 additions & 2 deletions doc/Glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ In ecstasy, the [Entities](@ref ecstasy::Entities) class is a resource present b
A simple use case would be a Timer resource to improve our previous Movement system:

```cpp
class Timer : public ecstasy::Resource {
class Timer : public ecstasy::IResource {
public:
/// Creates a new timer.
explicit Timer() noexcept : _lastReset(std::chrono::steady_clock::now()) {}
Expand Down Expand Up @@ -99,7 +99,7 @@ struct Movement : public ecstasy::ISystem {
};
```

References: [Resource](@ref ecstasy::Resource), [registry.addResource()](@ref ecstasy::Registry::addResource), [registry.getResource()](@ref ecstasy::Registry.getResource), [Entities](@ref ecstasy::Entities)
References: [IResource](@ref ecstasy::IResource), [registry.addResource()](@ref ecstasy::Registry::addResource), [registry.getResource()](@ref ecstasy::Registry.getResource), [Entities](@ref ecstasy::Entities)

## Registry

Expand Down
2 changes: 1 addition & 1 deletion doc/Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ By default ecstasy is not thread safe. By not thread safe I mean there is absolu

But no worries it is just some compilation options to set:

- @b ECSTASY_LOCKABLE_RESOURCES will make @ref Resource class validate the [Lockable](@ref ecstasy::thread::Lockable) concept.
- @b ECSTASY_LOCKABLE_RESOURCES will make @ref IResource class validate the [Lockable](@ref ecstasy::thread::Lockable) concept.
- @b ECSTASY_LOCKABLE_STORAGES will make @ref IStorage class validate the [Lockable](@ref ecstasy::thread::Lockable) concept.
- @b ECSTASY_AUTO_LOCK will lock any [Lockable](@ref ecstasy::thread::Lockable) queryables in any registry queries or registry modifiers.
- @b ECSTASY_THREAD_SAFE will enable the three options above.
Expand Down
19 changes: 12 additions & 7 deletions src/ecstasy/integrations/event/EventsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,25 @@ namespace ecstasy::integration::event
callListeners(registry, event.mouseButton);

if (registry.hasResource<Mouse>())
registry.getResource<Mouse>()->setButtonState(event.mouseButton.button, event.mouseButton.pressed);
registry.getResource<Mouse>().get().setButtonState(
event.mouseButton.button, event.mouseButton.pressed);
break;
case Event::Type::MouseWheelScrolled: callListeners(registry, event.mouseWheel); break;
case Event::Type::MouseMoved:
callListeners(registry, event.mouseMove);

if (registry.hasResource<Mouse>()) {
RR<Mouse> mouse = registry.getResource<Mouse>();
mouse->setPosition(event.mouseMove.x + mouse->getX(), event.mouseMove.y + mouse->getY());
mouse.get().setPosition(
event.mouseMove.x + mouse.get().getX(), event.mouseMove.y + mouse.get().getY());
}
break;
case Event::Type::KeyPressed:
case Event::Type::KeyReleased:
callKeyListeners(registry, event.key);

if (registry.hasResource<Keyboard>())
registry.getResource<Keyboard>()->setKeyState(event.key.key, event.key.pressed);
registry.getResource<Keyboard>().get().setKeyState(event.key.key, event.key.pressed);
break;
case Event::Type::TextEntered: callListeners(registry, event.text); break;
case Event::Type::GamepadButtonPressed:
Expand All @@ -115,7 +117,8 @@ namespace ecstasy::integration::event

if (registry.hasResource<Gamepads>())
registry.getResource<Gamepads>()
->get(event.gamepadButton.id)
.get()
.get(event.gamepadButton.id)
.setButtonState(event.gamepadButton.button, event.gamepadButton.pressed);
break;
case Event::Type::GamepadConnected:
Expand All @@ -124,23 +127,25 @@ namespace ecstasy::integration::event

if (registry.hasResource<Gamepads>())
registry.getResource<Gamepads>()
->get(event.gamepadConnected.id)
.get()
.get(event.gamepadConnected.id)
.setConnected(event.gamepadConnected.connected);
break;
case Event::Type::GamepadAxis:
callListeners(registry, event.gamepadAxis);

if (registry.hasResource<Gamepads>())
registry.getResource<Gamepads>()
->get(event.gamepadAxis.id)
.get()
.get(event.gamepadAxis.id)
.setAxisValue(event.gamepadAxis.axis, event.gamepadAxis.value);
break;
default: break;
}

#ifdef ECSTASY_INTEGRATIONS_USER_ACTION
if (registry.hasResource<user_action::Users>())
registry.getResource<const user_action::Users>()->handleEvent(registry, event);
registry.getResource<const user_action::Users>().get().handleEvent(registry, event);
#endif
}
} // namespace ecstasy::integration::event
4 changes: 2 additions & 2 deletions src/ecstasy/integrations/event/inputs/Gamepads.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#define ECSTASY_INTEGRATIONS_EVENT_INPUTS_GAMEPADS_HPP_

#include "Gamepad.hpp"
#include "ecstasy/resources/Resource.hpp"
#include "ecstasy/resources/IResource.hpp"

namespace ecstasy::integration::event
{
Expand All @@ -23,7 +23,7 @@ namespace ecstasy::integration::event
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2022-11-18)
///
class Gamepads : public ecstasy::Resource<Gamepads> {
class Gamepads : public ecstasy::IResource {
public:
/// @brief Number of supported gamepads.
static const size_t GamepadCount = 4;
Expand Down
4 changes: 2 additions & 2 deletions src/ecstasy/integrations/event/inputs/Keyboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <iostream>
#include <unordered_map>

#include "ecstasy/resources/Resource.hpp"
#include "ecstasy/resources/IResource.hpp"
#include "util/serialization/SerializableEnum.hpp"

namespace ecstasy::integration::event
Expand All @@ -27,7 +27,7 @@ namespace ecstasy::integration::event
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2022-11-16)
///
class Keyboard : public Resource<Keyboard> {
class Keyboard : public IResource {
public:
// LCOV_EXCL_START

Expand Down
4 changes: 2 additions & 2 deletions src/ecstasy/integrations/event/inputs/Mouse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <iostream>
#include <utility>

#include "ecstasy/resources/Resource.hpp"
#include "ecstasy/resources/IResource.hpp"
#include "util/serialization/SerializableEnum.hpp"

namespace ecstasy::integration::event
Expand All @@ -27,7 +27,7 @@ namespace ecstasy::integration::event
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2022-11-04)
///
class Mouse : public Resource<Mouse> {
class Mouse : public IResource {
public:
// LCOV_EXCL_START

Expand Down
4 changes: 2 additions & 2 deletions src/ecstasy/integrations/sfml/systems/PollEvents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ namespace ecstasy::integration::sfml
RR<RenderWindow> windowWrapper = registry.getResource<RenderWindow>();

sf::Event event;
while (windowWrapper->pollEvent(event)) {
while (windowWrapper.get().pollEvent(event)) {
switch (event.type) {
/// Mouse events
case sf::Event::MouseButtonPressed:
Expand Down Expand Up @@ -117,7 +117,7 @@ namespace ecstasy::integration::sfml
event.joystickMove.position / 100.f));
break;

case sf::Event::Closed: windowWrapper->get().close(); break;
case sf::Event::Closed: windowWrapper.get()->close(); break;
default: break;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/ecstasy/integrations/user_action/PollActions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ namespace ecstasy::integration::user_action
if (!registry.hasResource<PendingActions>()) [[unlikely]]
return;
RR<PendingActions> pendingActions = registry.getResource<PendingActions>();
while (!pendingActions->get().empty()) {
std::ignore = std::make_tuple((callListeners<Actions>(registry, pendingActions->get().front()), 0)...);
pendingActions->get().pop();
while (!pendingActions.get()->empty()) {
std::ignore = std::make_tuple((callListeners<Actions>(registry, pendingActions.get()->front()), 0)...);
pendingActions.get()->pop();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/ecstasy/integrations/user_action/Users.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace ecstasy::integration::user_action
{
if (!registry.hasResource<Users>()) [[unlikely]]
return;
registry.getResource<Users>()->updateBindings();
registry.getResource<Users>().get().updateBindings();
}

void Users::updateBindings()
Expand Down Expand Up @@ -61,7 +61,7 @@ namespace ecstasy::integration::user_action
void Users::callActionListeners(Registry &registry, Action action)
{
if (registry.hasResource<PendingActions>())
registry.getResource<PendingActions>()->get().push(action);
registry.getResource<PendingActions>().get()->push(action);

for (auto [entity, maybeListener, maybeListeners] :
registry.select<Entities, Maybe<ActionListener>, Maybe<ActionListeners>>()
Expand Down
4 changes: 2 additions & 2 deletions src/ecstasy/integrations/user_action/Users.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "ecstasy/integrations/event/inputs/Keyboard.hpp"
#include "ecstasy/integrations/event/inputs/Mouse.hpp"
#include "ecstasy/registry/Registry.hpp"
#include "ecstasy/resources/Resource.hpp"
#include "ecstasy/resources/IResource.hpp"
#include "ecstasy/storages/MapStorage.hpp"
#include <unordered_map>

Expand All @@ -37,7 +37,7 @@ namespace ecstasy::integration::user_action
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2022-12-02)
///
class Users : public ecstasy::Resource<Users> {
class Users : public ecstasy::IResource {
private:
/// @brief Helper type instead of using @ref std::pair.
/// Describe a link between an action and a user.
Expand Down
2 changes: 1 addition & 1 deletion src/ecstasy/query/concepts/Queryable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ namespace ecstasy::query
///
template <typename T, bool ThreadSafe>
struct thread_safe_reference {
using type = T &;
using type = std::reference_wrapper<T>;
};

/// @copydoc thread_safe_reference
Expand Down
8 changes: 4 additions & 4 deletions src/ecstasy/registry/Registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace ecstasy
{
Registry::EntityBuilder::EntityBuilder(Registry &registry) noexcept
: _registry(registry), _builder(registry.getResource<Entities>()->builder())
: _registry(registry), _builder(registry.getResource<Entities>().get().builder())
{
}

Expand All @@ -37,7 +37,7 @@ namespace ecstasy

Entity Registry::getEntity(Entity::Index index)
{
return getResource<const Entities>()->get(index);
return getResource<const Entities>().get().get(index);
}

std::vector<std::reference_wrapper<IStorage>> Registry::getEntityStorages(Entity entity)
Expand All @@ -51,7 +51,7 @@ namespace ecstasy

bool Registry::eraseEntity(Entity entity)
{
bool erased = getResource<Entities>()->erase(entity);
bool erased = getResource<Entities>().get().erase(entity);

if (!erased)
return false;
Expand All @@ -61,7 +61,7 @@ namespace ecstasy

size_t Registry::eraseEntities(std::span<Entity> entities)
{
size_t erased = getResource<Entities>()->erase(entities);
size_t erased = getResource<Entities>().get().erase(entities);

if (!erased)
return 0;
Expand Down
16 changes: 9 additions & 7 deletions src/ecstasy/registry/Registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ namespace ecstasy
/// @brief Resource reference type.
/// This type is used to reference a resource in a thread-safe way depending on the AutoLock parameter.
///
/// @note Consider this as a thread_safe @ref std::reference_wrapper.
///
/// @tparam R Resource type.
/// @tparam AutoLock Whether the resource should be locked automatically.
///
Expand Down Expand Up @@ -95,7 +97,7 @@ namespace ecstasy
}

/// @copydoc getQueryable()
template <std::derived_from<ResourceBase> R>
template <std::derived_from<IResource> R>
requires query::Queryable<R>
[[nodiscard]] constexpr R &getQueryable()
{
Expand Down Expand Up @@ -137,7 +139,7 @@ namespace ecstasy
}

/// @copydoc getFromType()
template <std::derived_from<ResourceBase> R>
template <std::derived_from<IResource> R>
[[nodiscard]] constexpr R &getFromType()
{
return getResource<R, false>();
Expand Down Expand Up @@ -847,7 +849,7 @@ namespace ecstasy
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2022-10-18)
///
template <std::derived_from<ResourceBase> R, typename... Args>
template <std::derived_from<IResource> R, typename... Args>
R &addResource(Args &&...args)
{
return _resources.emplace<R>(std::forward<Args>(args)...);
Expand Down Expand Up @@ -881,7 +883,7 @@ namespace ecstasy
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2022-11-06)
///
template <std::derived_from<ResourceBase> R>
template <std::derived_from<IResource> R>
[[nodiscard]] bool hasResource() const
{
return _resources.contains<R>();
Expand All @@ -900,7 +902,7 @@ namespace ecstasy
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2022-10-18)
///
template <std::derived_from<ResourceBase> R, bool Locked = thread::AUTO_LOCK_RESOURCES_DEFAULT>
template <std::derived_from<IResource> R, bool Locked = thread::AUTO_LOCK_RESOURCES_DEFAULT>
[[nodiscard]] ResourceReference<const R, Locked> getResource() const
{
return _resources.get<R>();
Expand All @@ -918,7 +920,7 @@ namespace ecstasy
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2022-10-18)
///
template <std::derived_from<ResourceBase> R, bool Locked = thread::AUTO_LOCK_RESOURCES_DEFAULT>
template <std::derived_from<IResource> R, bool Locked = thread::AUTO_LOCK_RESOURCES_DEFAULT>
[[nodiscard]] ResourceReference<R, Locked> getResource()
{
return _resources.get<R>();
Expand Down Expand Up @@ -1223,7 +1225,7 @@ namespace ecstasy

private:
/// @brief Registry resources.
Instances<ResourceBase> _resources;
Instances<IResource> _resources;
/// @brief Registry storages.
Instances<IStorage> _storages;
/// @brief Registry systems.
Expand Down
6 changes: 3 additions & 3 deletions src/ecstasy/registry/concepts/queryable_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "ecstasy/query/concepts/Modifier.hpp"
#include "ecstasy/query/concepts/Queryable.hpp"
#include "ecstasy/registry/concepts/RegistryModifier.hpp"
#include "ecstasy/resources/Resource.hpp"
#include "ecstasy/resources/IResource.hpp"
#include "ecstasy/storages/StorageConcepts.hpp"

namespace ecstasy
Expand All @@ -24,7 +24,7 @@ namespace ecstasy
/// @brief Try to get the type of a queryable associated to a type stored in the registry (component, storage,
/// resource...).
/// Returns C if:
/// - C is derived from the @ref ecstasy::Resource class and match the @ref Queryable concept.
/// - C is derived from the @ref ecstasy::IResource class and match the @ref Queryable concept.
/// - C match the @ref ecstasy::IsStorage concept and match the @ref Queryable concept.
/// - C is a const type matching the @ref ConstQueryableObject concept.
/// - C match the @ref ecstasy::query::Modifier
Expand All @@ -49,7 +49,7 @@ namespace ecstasy
};

/// @copydoc queryable_type
template <std::derived_from<ResourceBase> R>
template <std::derived_from<IResource> R>
requires query::Queryable<R>
struct queryable_type<R> {
using type = R;
Expand Down
4 changes: 2 additions & 2 deletions src/ecstasy/resources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ set(SRC
${SRC}
${INCROOT}/include.hpp
${INCROOT}/ObjectWrapper.hpp
${INCROOT}/Resource.hpp
${INCROOT}/IResource.hpp
PARENT_SCOPE
)
)
Loading

0 comments on commit 8bd8928

Please sign in to comment.