Skip to content

Commit

Permalink
feat(ecs): add negative tags
Browse files Browse the repository at this point in the history
  • Loading branch information
RiscadoA committed Oct 30, 2023
1 parent 21e72a4 commit fac09bc
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 11 deletions.
4 changes: 4 additions & 0 deletions core/include/cubos/core/ecs/system/dispatcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ namespace cubos::core::ecs
/// @param tag Tag to add.
void addTag(const std::string& tag);

/// @brief Adds a tag, and sets it as the current negative tag for further settings.
/// @param tag Tag to add.
void addNegativeTag(const std::string& tag);

/// @brief Makes the current tag inherit the settings of another tag.
/// @param tag Tag to inherit from.
void tagInheritTag(const std::string& tag);
Expand Down
17 changes: 17 additions & 0 deletions core/src/cubos/core/ecs/system/dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@ Dispatcher::~Dispatcher()

void Dispatcher::addTag(const std::string& tag)
{
CUBOS_ASSERT(!tag.starts_with('!'), "Tags starting with '!' are reserved for internal use");
ENSURE_TAG_SETTINGS(tag);
mCurrTag = tag;
}

void Dispatcher::addNegativeTag(const std::string& tag)
{
CUBOS_ASSERT(!tag.starts_with('!'), "Tags starting with '!' are reserved for internal use");
ENSURE_TAG_SETTINGS('!' + tag);
mCurrTag = '!' + tag;
}

void Dispatcher::tagInheritTag(const std::string& tag)
{
ENSURE_CURR_TAG();
Expand Down Expand Up @@ -110,6 +118,15 @@ void Dispatcher::compileChain()
// Implement system tag settings with custom settings
for (System* system : mPendingSystems)
{
// Add negative tags when the system doesn't have the respective positive tags
for (auto& [tag, settings] : mTagSettings)
{
if (tag.starts_with('!') && !system->tags.contains(tag.substr(1)))
{
system->tags.insert(tag);
}
}

for (const auto& tag : system->tags)
{
if (!system->settings)
Expand Down
23 changes: 23 additions & 0 deletions core/tests/ecs/dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,21 @@ TEST_CASE("ecs::Dispatcher")
dispatcher.tagSetBeforeTag("2"); // "3" runs before "2"
}

SUBCASE("with constraints on negative tags")
{
dispatcher.addSystem(pushToOrder<1>);
dispatcher.systemAddTag("1");
dispatcher.addSystem(pushToOrder<2>);
dispatcher.systemAddTag("2");
dispatcher.addSystem(pushToOrder<3>);
dispatcher.systemAddTag("3");

dispatcher.addNegativeTag("1");
dispatcher.tagSetBeforeTag("1"); // anything without "1" runs before "1"
dispatcher.addNegativeTag("3");
dispatcher.tagSetAfterTag("3"); // anything without "3" runs after "3"
}

singleDispatch(dispatcher, world, cmdBuffer);
assertOrder(world, {3, 2, 1});
}
Expand Down Expand Up @@ -138,6 +153,14 @@ TEST_CASE("ecs::Dispatcher")
dispatcher.tagSetAfterTag("1"); // Repeat
dispatcher.tagSetBeforeTag("2"); // "3" runs before "2" - redundant
dispatcher.tagSetBeforeTag("2"); // Repeat

dispatcher.addNegativeTag("1");
dispatcher.tagSetAfterTag("1"); // "2" and "3" run after "1" - redundant
dispatcher.tagSetAfterTag("1"); // Repeat

dispatcher.addNegativeTag("2");
dispatcher.tagSetBeforeTag("2"); // "1" and "3" run before "2" - redundant
dispatcher.tagSetBeforeTag("2"); // Repeat
}

singleDispatch(dispatcher, world, cmdBuffer);
Expand Down
22 changes: 16 additions & 6 deletions engine/include/cubos/engine/cubos.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,26 @@ namespace cubos::engine
template <typename E>
Cubos& addEvent();

/// @brief Returns a @ref TagBuilder to configure the given tag.
/// @param tag Tag to configure.
/// @return @ref TagBuilder used to configure the tag.
/// @brief Returns a @ref TagBuilder to configure the systems with the given tag.
/// @param tag Tag.
/// @return @ref TagBuilder.
TagBuilder tag(const std::string& tag);

/// @brief Returns a @ref TagBuilder to configure the given startup tag.
/// @param tag Tag to configure.
/// @return @ref TagBuilder used to configure the tag.
/// @brief Returns a @ref TagBuilder to configure the systems with the given startup tag.
/// @param tag Tag.
/// @return @ref TagBuilder.
TagBuilder startupTag(const std::string& tag);

/// @brief Returns a @ref TagBuilder to configure the systems without the given tag.
/// @param tag Tag.
/// @return @ref TagBuilder.
TagBuilder noTag(const std::string& tag);

/// @brief Returns a @ref TagBuilder to configure the systems without the given startup tag.
/// @param tag Tag.
/// @return @ref TagBuilder.
TagBuilder noStartupTag(const std::string& tag);

/// @brief Adds a new system to the engine, which will be executed at every iteration of
/// the main loop.
/// @tparam F Type of the system function.
Expand Down
18 changes: 13 additions & 5 deletions engine/src/cubos/engine/cubos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,25 @@ Cubos& Cubos::addPlugin(void (*func)(Cubos&))
TagBuilder Cubos::tag(const std::string& tag)
{
mMainDispatcher.addTag(tag);
TagBuilder builder(mMainDispatcher, mMainTags);

return builder;
return TagBuilder{mMainDispatcher, mMainTags};
}

TagBuilder Cubos::startupTag(const std::string& tag)
{
mStartupDispatcher.addTag(tag);
TagBuilder builder(mStartupDispatcher, mStartupTags);
return TagBuilder{mStartupDispatcher, mStartupTags};
}

TagBuilder Cubos::noTag(const std::string& tag)
{
mMainDispatcher.addNegativeTag(tag);
return TagBuilder{mMainDispatcher, mMainTags};
}

return builder;
TagBuilder Cubos::noStartupTag(const std::string& tag)
{
mStartupDispatcher.addNegativeTag(tag);
return TagBuilder{mStartupDispatcher, mStartupTags};
}

Cubos::Cubos()
Expand Down

0 comments on commit fac09bc

Please sign in to comment.