#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_SCENE_GRAPH_ENTITY_H #define NUCLEX_SCENE_GRAPH_ENTITY_H #include "Nuclex/Scene/Config.h" #include "Nuclex/Scene/Graph/ComponentSet.h" #include "Nuclex/Scene/Graph/ChildEntitySet.h" namespace Nuclex { namespace Scene { namespace Graph { // ------------------------------------------------------------------------------------------- // /// Hierarchical container that houses a number of components /// /// /// Entities form a tree and can store components. Components can be anything, from /// primitive data types such as an integer to POD types or objects from a third-party /// library. /// /// /// Typically, entities are used in one of two ways: /// /// /// /// As services: /// /// Here, the entity performs a management task and stores components that /// provide services to other components or interface with the game itself. This /// type of entity does not have a position, but may draw to the screen. /// /// /// /// As scene nodes: /// /// If used as a scene node, the entity has a transformation (position, /// orientation and scale) and is used to build a hierarchical scene: there might /// be a Car entity that has four child Wheel entities, with /// the children's transformation typically being relative to their parent. /// /// /// /// /// Example use case of an entity /// /// std::shared_ptr bicycle = std::make_shared(); /// bicycle->Components.Add(std::make_unique()); /// /// bicycle->Children.Add(std::make_shared()); /// bicycle->Children.Add(std::make_shared()); /// /// for(std::shared_ptr wheel : bicycle->Children) { /// wheel->Components.Add(std::make_unique()); /// } /// /// /// class Entity : public std::enable_shared_from_this { friend ChildEntitySet; /// Components carried by the entity public: ComponentSet Components; /// The entity's children public: ChildEntitySet Children; /// Initializes a new entity public: NUCLEX_SCENE_API Entity() : Children(*this) {} /// Retrieves the parent of this entity, if any /// The parent of this entity, if it has a parent public: NUCLEX_SCENE_API Entity *GetParent() { return this->parent; } /// Retrieves the parent of this entity, if any /// The parent of this entity, if it has a parent public: NUCLEX_SCENE_API const Entity *GetParent() const { return this->parent; } /// Assigns the parent of this entity or clears it /// Parent that will be assigned to the entity /// The parent of this entity, if it has a parent protected: NUCLEX_SCENE_API void SetParent(Entity *parent) { this->parent = parent; } /// Registers a component that is a permanent part of the entity /// Type of component that will be registered /// Component that will be registered /// /// /// While a component/entity system is data driven, sometimes you have a type of /// entities that have to contain certain elements. A bone in a bone-animated /// mesh for example would always have a position, orientation and scale. And sometimes, /// you just want to reduce the number of allocations needed or allow an entity to /// be pooled, like shots from a weapon. /// /// /// Built-in components allow you to create special entity types that include some /// components with them as direct members. /// /// protected: template void RegisterBuiltInComponent( TComponent *component ) { this->Components.Add( typeid(TComponent), component, [](void *component) { delete static_cast(component); } ); } /// Points to the parent entity of this entity /// /// Not a shared_ptr because that would keep the parent alive indefinitely /// (circular relationship) and not a weak_ptr because the parent may be used /// inline and not have a shared_ptr pointing to it. /// private: Entity *parent; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Scene::Graph #endif // NUCLEX_SCENE_GRAPH_ENTITY_H