Skip to content

Commit

Permalink
scripting+ecs: introduce an ability to despawn entities on gamemode u…
Browse files Browse the repository at this point in the history
…nload
  • Loading branch information
zpl-zak committed Jan 10, 2024
1 parent d8a6e31 commit b2947a3
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 0 deletions.
8 changes: 8 additions & 0 deletions code/framework/src/scripting/engines/node/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#include "engine.h"
#include "../../events.h"

#include "core_modules.h"

#include "world/server.h"

static const char bootstrap_code[] = R"(
const publicRequire = require("module").createRequire(process.cwd() + "/gamemode/");
globalThis.require = publicRequire;
Expand Down Expand Up @@ -274,6 +278,10 @@ namespace Framework::Scripting::Engines::Node {
// Invoke the gamemode loaded event
InvokeEvent(Events[EventIDs::GAMEMODE_UNLOADING]);

const auto worldEngine = CoreModules::GetWorldEngine();
if (worldEngine)
worldEngine->PurgeAllGameModeEntities();

// Stop node environment
node::Stop(_gamemodeEnvironment);

Expand Down
9 changes: 9 additions & 0 deletions code/framework/src/world/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,13 @@ namespace Framework::World {
flecs::entity Engine::WrapEntity(flecs::entity_t serverID) const {
return flecs::entity(_world->get_world(), serverID);
}

void Engine::PurgeAllGameModeEntities() {
_world->defer_begin();
_findAllGameModeEntities.each([this](flecs::entity e, Modules::Base::RemovedOnGameModeReload &rhs) {
if (e.is_alive())
e.add<Modules::Base::PendingRemoval>();
});
_world->defer_end();
}
} // namespace Framework::World
9 changes: 9 additions & 0 deletions code/framework/src/world/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,20 @@
} \
} while (0)

namespace Framework::Scripting::Engines::Node {
class Engine;
}

namespace Framework::World {
class Engine {
private:
friend class Framework::Scripting::Engines::Node::Engine;
void PurgeAllGameModeEntities();

protected:
flecs::query<Modules::Base::Streamer> _findAllStreamerEntities;
flecs::query<Modules::Base::Transform, Modules::Base::Streamable> _allStreamableEntities;
flecs::query<Modules::Base::RemovedOnGameModeReload> _findAllGameModeEntities;
std::unique_ptr<flecs::world> _world;
Networking::NetworkPeer *_networkPeer = nullptr;

Expand Down
5 changes: 5 additions & 0 deletions code/framework/src/world/modules/base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ namespace Framework::World::Modules {
[[maybe_unused]] uint8_t _unused;
};

struct RemovedOnGameModeReload {
[[maybe_unused]] uint8_t _unused;
};

struct ServerID {
flecs::entity_t id;
};
Expand Down Expand Up @@ -114,6 +118,7 @@ namespace Framework::World::Modules {
auto _streamable = world.component<Streamable>();
auto _streamer = world.component<Streamer>();

world.component<RemovedOnGameModeReload>();
world.component<PendingRemoval>();
world.component<ServerID>();

Expand Down
2 changes: 2 additions & 0 deletions code/framework/src/world/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ namespace Framework::World {
GetWorld()->set<flecs::Rest>({});
GetWorld()->import <flecs::monitor>();

_findAllGameModeEntities = _world->query_builder<Modules::Base::RemovedOnGameModeReload>().build();

// Set up a proc to validate entity visibility.
_isEntityVisible = [](const flecs::entity streamerEntity, const flecs::entity e, const Modules::Base::Transform &lhsTr, const Modules::Base::Streamer &streamer, const Modules::Base::Streamable &lhsS, const Modules::Base::Transform &rhsTr,
const Modules::Base::Streamable &rhsS) -> bool {
Expand Down

0 comments on commit b2947a3

Please sign in to comment.