<commit_before>// Copyright (C) 2017 <NAME>
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp

#include <NDK/World.hpp>
#include <Nazara/Core/Error.hpp>
#include <NDK/BaseComponent.hpp>
#include <NDK/Systems/PhysicsSystem2D.hpp>
#include <NDK/Systems/PhysicsSystem3D.hpp>
#include <NDK/Systems/VelocitySystem.hpp>

#ifndef NDK_SERVER
#include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/Systems/ParticleSystem.hpp>
#include <NDK/Systems/RenderSystem.hpp>
#endif

namespace Ndk
{
	/*!
	* \ingroup NDK
	* \class Ndk::World
	* \brief NDK class that represents a world
	*/

	/*!
	* \brief Destructs the object and calls Clear
	*
	* \see Clear
	*/

	World::~World() noexcept
	{
		// The destruct must be done in an ordered way
		Clear();
	}

	/*!
	* \brief Adds default systems to the world
	*/

	void World::AddDefaultSystems()
	{
		AddSystem<PhysicsSystem2D>();
		AddSystem<PhysicsSystem3D>();
		AddSystem<VelocitySystem>();

		#ifndef NDK_SERVER
		AddSystem<ListenerSystem>();
		AddSystem<ParticleSystem>();
		AddSystem<RenderSystem>();
		#endif
	}

	/*!
	* \brief Creates an entity in the world
	* \return The entity created
	*/

	const EntityHandle& World::CreateEntity()
	{
		EntityId id;
		EntityBlock* entBlock;
		if (!m_freeIdList.empty())
		{
			// We get an identifier
			id = m_freeIdList.back();
			m_freeIdList.pop_back();

			entBlock = &m_entities[id];
			entBlock->handle.Reset(&entBlock->entity); //< Reset handle (as it was reset when entity got destroyed)

			m_entityBlocks[id] = entBlock;
		}
		else
		{
			// We allocate a new entity
			id = static_cast<Ndk::EntityId>(m_entityBlocks.size());

			if (m_entities.capacity() > m_entities.size())
			{
				NazaraAssert(m_waitingEntities.empty(), "There should be no waiting entities if space is available in main container");

				m_entities.push_back(Entity(this, id)); //< We can't use emplace_back due to the scope
				entBlock = &m_entities.back();
			}
			else
			{
				// Pushing to entities would reallocate vector and thus, invalidate EntityHandles (which we don't want until world update)
				// To prevent this, allocate them into a separate vector and move them at update
				// For now, we are counting on m_entities grow strategy to keep allocation frequency low
				m_waitingEntities.emplace_back(std::make_unique<EntityBlock>(Entity(this, id)));
				entBlock = m_waitingEntities.back().get();
			}

			if (id >= m_entityBlocks.size())
				m_entityBlocks.resize(id + 1);

			m_entityBlocks[id] = entBlock;
		}

		// We initialize the entity and we add it to the list of alive entities
		entBlock->entity.Create();

		m_aliveEntities.Insert(&entBlock->entity);

		return entBlock->handle;
	}

	/*!
	* \brief Clears the world from every entities
	*
	* \remark Every handles are correctly invalidated, entities are immediately invalidated
	*/

	void World::Clear() noexcept
	{
		// First, destruction of entities, then handles
		// This is made to avoid that handle warn uselessly entities before their destruction
		m_entities.clear();
		m_entityBlocks.clear();
		m_waitingEntities.clear();

		m_aliveEntities.Clear();
		m_dirtyEntities.Clear();
		m_killedEntities.Clear();
	}

	/*!
	* \brief Clones the entity
	* \return The clone newly created
	*
	* \param id Identifier of the entity
	*
	* \remark Produces a NazaraError if the entity to clone does not exist
	*/

	const EntityHandle& World::CloneEntity(EntityId id)
	{
		EntityHandle original = GetEntity(id);
		if (!original)
		{
			NazaraError("Invalid entity ID");
			return EntityHandle::InvalidHandle;
		}
<commit_msg>Sdk/World: Fix Clear not clearing everything<commit_after>// Copyright (C) 2017 <NAME>
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp

#include <NDK/World.hpp>
#include <Nazara/Core/Error.hpp>
#include <NDK/BaseComponent.hpp>
#include <NDK/Systems/PhysicsSystem2D.hpp>
#include <NDK/Systems/PhysicsSystem3D.hpp>
#include <NDK/Systems/VelocitySystem.hpp>

#ifndef NDK_SERVER
#include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/Systems/ParticleSystem.hpp>
#include <NDK/Systems/RenderSystem.hpp>
#endif

namespace Ndk
{
	/*!
	* \ingroup NDK
	* \class Ndk::World
	* \brief NDK class that represents a world
	*/

	/*!
	* \brief Destructs the object and calls Clear
	*
	* \see Clear
	*/

	World::~World() noexcept
	{
		// The destruct must be done in an ordered way
		Clear();
	}

	/*!
	* \brief Adds default systems to the world
	*/

	void World::AddDefaultSystems()
	{
		AddSystem<PhysicsSystem2D>();
		AddSystem<PhysicsSystem3D>();
		AddSystem<VelocitySystem>();

		#ifndef NDK_SERVER
		AddSystem<ListenerSystem>();
		AddSystem<ParticleSystem>();
		AddSystem<RenderSystem>();
		#endif
	}

	/*!
	* \brief Creates an entity in the world
	* \return The entity created
	*/

	const EntityHandle& World::CreateEntity()
	{
		EntityId id;
		EntityBlock* entBlock;
		if (!m_freeIdList.empty())
		{
			// We get an identifier
			id = m_freeIdList.back();
			m_freeIdList.pop_back();

			entBlock = &m_entities[id];
			entBlock->handle.Reset(&entBlock->entity); //< Reset handle (as it was reset when entity got destroyed)

			m_entityBlocks[id] = entBlock;
		}
		else
		{
			// We allocate a new entity
			id = static_cast<Ndk::EntityId>(m_entityBlocks.size());

			if (m_entities.capacity() > m_entities.size())
			{
				NazaraAssert(m_waitingEntities.empty(), "There should be no waiting entities if space is available in main container");

				m_entities.push_back(Entity(this, id)); //< We can't use emplace_back due to the scope
				entBlock = &m_entities.back();
			}
			else
			{
				// Pushing to entities would reallocate vector and thus, invalidate EntityHandles (which we don't want until world update)
				// To prevent this, allocate them into a separate vector and move them at update
				// For now, we are counting on m_entities grow strategy to keep allocation frequency low
				m_waitingEntities.emplace_back(std::make_unique<EntityBlock>(Entity(this, id)));
				entBlock = m_waitingEntities.back().get();
			}

			if (id >= m_entityBlocks.size())
				m_entityBlocks.resize(id + 1);

			m_entityBlocks[id] = entBlock;
		}

		// We initialize the entity and we add it to the list of alive entities
		entBlock->entity.Create();

		m_aliveEntities.Insert(&entBlock->entity);

		return entBlock->handle;
	}

	/*!
	* \brief Clears the world from every entities
	*
	* \remark Every handles are correctly invalidated, entities are immediately invalidated
	*/

	void World::Clear() noexcept
	{
		// First, destruction of entities, then handles
		// This is made to avoid that handle warn uselessly entities before their destruction
		m_entities.clear();
		m_entityBlocks.clear();
		m_freeIdList.clear();
		m_waitingEntities.clear();

		m_aliveEntities.Clear();
		m_dirtyEntities.Clear();
		m_killedEntities.Clear();
	}

	/*!
	* \brief Clones the entity
	* \return The clone newly created
	*
	* \param id Identifier of the entity
	*
	* \remark Produces a NazaraError if the entity to clone does not exist
	*/

	const EntityHandle& World::CloneEntity(EntityId id)
	{
		EntityHandle original = GetEntity(id);
		if (!original)
		{
			NazaraError("Invalid entity ID");
			return EntityHandle::InvalidHandle;
		}

{'fraction_non_alphanumeric': 0.11490810074880871, 'fraction_numerical': 0.002450646698434309, 'mean_word_length': 3.887558216899534, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6397948', 'n_tokens_mistral': 2595, 'n_tokens_neox': 2367, 'n_words': 682}