diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp new file mode 100644 index 000000000..91a88ef50 --- /dev/null +++ b/SDK/include/NDK/Entity.hpp @@ -0,0 +1,72 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_ENTITY_HPP +#define NDK_ENTITY_HPP + +#include + +namespace Ndk +{ + class World; + + class NDK_API Entity + { + friend World; + + public: + class Id; + + Entity(); + Entity(const Entity&) = default; + ~Entity() = default; + + void Kill(); + + Id GetId() const; + World* GetWorld() const; + + bool IsValid() const; + + Entity& operator=(const Entity&) = default; + + bool operator==(const Entity& other) const; + bool operator!=(const Entity& other) const; + + // Identifiant + struct Id + { + struct Part + { + nzUInt32 counter, index; + }; + + union + { + Part part; + nzUInt64 value; + }; + + bool operator==(const Id& other) const + { + return value == other.value; + } + + bool operator!=(const Id& other) const + { + return !operator==(other); + } + }; + + private: + Entity(Id id, World* world); + + Id m_id; + World* m_world; + }; +} + +#endif // NDK_ENTITY_HPP diff --git a/SDK/include/NDK/Prerequesites.hpp b/SDK/include/NDK/Prerequesites.hpp new file mode 100644 index 000000000..d42c75dc0 --- /dev/null +++ b/SDK/include/NDK/Prerequesites.hpp @@ -0,0 +1,58 @@ +/* + Nazara Development Kit ("NDK"), also called Nazara Engine - SDK ("Software Development Kit") + + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef NDK_PREREQUESITES_HPP +#define NDK_PREREQUESITES_HPP + +#include + +// Version du SDK +#define NDK_VERSION_MAJOR 0 +#define NDK_VERSION_MINOR 1 + +// Importation/Exportation de l'API +#if defined(NAZARA_PLATFORM_WINDOWS) + #if !defined(NDK_STATIC) + #ifdef NDK_BUILD + #define NDK_API NAZARA_EXPORT + #else + #define NDK_API NAZARA_IMPORT + #endif + #else + #define NDK_API + #endif +#elif defined(NAZARA_PLATFORM_LINUX) + #if !defined(NDK_STATIC) && defined(NAZARA_COMPILER_GCC) + #define NDK_API NAZARA_EXPORT + #else + #define NDK_API + #endif +#else + // À commenter pour tenter quand même une compilation + #error This operating system is not fully supported by the Nazara Development Kit + + #define NDK_API +#endif + +#endif // NDK_PREREQUESITES_HPP diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp new file mode 100644 index 000000000..232edceb1 --- /dev/null +++ b/SDK/include/NDK/World.hpp @@ -0,0 +1,47 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_WORLD_HPP +#define NDK_WORLD_HPP + +#include +#include +#include +#include + +namespace Ndk +{ + class NDK_API World : NzNonCopyable + { + public: + using EntityList = std::vector; + + World(); + ~World(); + + Entity CreateEntity(); + EntityList CreateEntities(unsigned int count); + + void KillEntity(Entity& entity); + void KillEntities(EntityList& list); + + Entity GetEntity(Entity::Id id); + + bool IsEntityValid(const Entity& entity) const; + bool IsEntityIdValid(Entity::Id id) const; + + void Update(); + + private: + std::vector m_entitiesCounter; + std::vector m_freeIdList; + EntityList m_aliveEntities; + EntityList m_killedEntities; + nzUInt32 m_nextIndex; + }; +} + +#endif // NDK_WORLD_HPP diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp new file mode 100644 index 000000000..f25763fc5 --- /dev/null +++ b/SDK/src/NDK/Entity.cpp @@ -0,0 +1,49 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include +#include + +namespace Ndk +{ + Entity::Entity() : + m_world(nullptr) + { + m_id.value = 0; + } + + Entity::Entity(Id id, World* world) : + m_id(id), + m_world(world) + { + } + + void Entity::Kill() + { + m_world->KillEntity(*this); + } + + Entity::Id Entity::GetId() const + { + return m_id; + } + + World* Entity::GetWorld() const + { + return m_world; + } + + bool Entity::IsValid() const + { + return m_world != nullptr && m_world->IsEntityIdValid(m_id); + } + + bool Entity::operator==(const Entity& other) const + { + return m_world == other.m_world && m_id == other.m_id; + } + + bool Entity::operator!=(const Entity& other) const + { + return !operator==(other); + } +} diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp new file mode 100644 index 000000000..98815a280 --- /dev/null +++ b/SDK/src/NDK/World.cpp @@ -0,0 +1,119 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include +#include + +namespace Ndk +{ + World::World() : + m_nextIndex(0) + { + } + + World::~World() = default; + + Entity World::CreateEntity() + { + Entity::Id id; + if (!m_freeIdList.empty()) + { + // On récupère un identifiant + id = m_freeIdList.back(); + m_freeIdList.pop_back(); + } + else + { + // On alloue un nouvel identifiant + m_entitiesCounter.resize(m_entitiesCounter.size() + 1); + + auto& counter = m_entitiesCounter.back(); + counter = 1; + + id.part.counter = counter; + id.part.index = m_nextIndex; + + m_nextIndex++; + } + + Entity entity(id, this); + m_aliveEntities.push_back(entity); + + return entity; + } + + World::EntityList World::CreateEntities(unsigned int count) + { + EntityList list; + for (unsigned int i = 0; i < count; ++i) + list.push_back(CreateEntity()); + + return list; + } + + void World::KillEntity(Entity& entity) + { + m_killedEntities.push_back(entity); + } + + void World::KillEntities(EntityList& list) + { + m_killedEntities.reserve(m_killedEntities.size() + list.size()); + for (Entity& entity : list) + KillEntity(entity); + } + + Entity World::GetEntity(Entity::Id id) + { + if (IsEntityIdValid(id)) + return Entity(id, this); + else + { + NazaraError("Invalid ID"); + return Entity(); + } + } + + bool World::IsEntityValid(const Entity& entity) const + { + return entity.GetWorld() == this && IsEntityIdValid(entity.GetId()); + } + + bool World::IsEntityIdValid(Entity::Id id) const + { + return m_entitiesCounter[id.part.index] == id.part.counter; + } + + void World::Update() + { + if (!m_killedEntities.empty()) + { + ///FIXME: Inverser les deux boucles ? + for (unsigned int i = 0; i < m_aliveEntities.size(); ++i) + { + Entity::Id e1 = m_aliveEntities[i].GetId(); + + for (unsigned int j = 0; j < m_killedEntities.size(); ++j) + { + Entity::Id e2 = m_killedEntities[j].GetId(); + if (e1 == e2) + { + // Remise en file de l'identifiant d'entité + nzUInt32& counter = m_entitiesCounter[e1.part.index]; + counter++; + + e1.part.counter = counter; + m_freeIdList.push_back(e1); + + // Suppression de l'entité des deux tableaux + m_aliveEntities.erase(m_aliveEntities.begin() + i); + m_killedEntities.erase(m_killedEntities.begin() + j); + break; + } + } + + if (m_killedEntities.empty()) + break; + } + } + } +}