diff options
-rw-r--r-- | mwe/events/include/event.h | 2 | ||||
-rw-r--r-- | src/crepe/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/crepe/Component.cpp | 2 | ||||
-rw-r--r-- | src/crepe/Component.h | 1 | ||||
-rw-r--r-- | src/crepe/ComponentManager.hpp | 13 | ||||
-rw-r--r-- | src/crepe/Metadata.cpp | 9 | ||||
-rw-r--r-- | src/crepe/Metadata.h | 22 | ||||
-rw-r--r-- | src/crepe/api/GameObject.cpp | 22 | ||||
-rw-r--r-- | src/crepe/api/GameObject.h | 10 | ||||
-rw-r--r-- | src/crepe/api/Transform.cpp | 6 | ||||
-rw-r--r-- | src/crepe/api/Transform.h | 3 | ||||
-rw-r--r-- | src/crepe/system/System.h | 4 | ||||
-rw-r--r-- | src/example/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/example/ecs.cpp | 55 | ||||
-rw-r--r-- | src/example/particle.cpp | 2 | ||||
-rw-r--r-- | src/example/physics.cpp | 10 | ||||
-rw-r--r-- | src/example/rendering.cpp | 21 | ||||
-rw-r--r-- | src/example/script.cpp | 8 |
18 files changed, 145 insertions, 48 deletions
diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h index 16c75bf..3e70201 100644 --- a/mwe/events/include/event.h +++ b/mwe/events/include/event.h @@ -152,7 +152,7 @@ private: }; class ShutDownEvent : public Event { public: - ShutDownEvent() : Event("ShutDownEvent") {}; + ShutDownEvent() : Event("ShutDownEvent"){}; REGISTER_EVENT_TYPE(ShutDownEvent) diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt index 8830e05..867329f 100644 --- a/src/crepe/CMakeLists.txt +++ b/src/crepe/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(crepe PUBLIC ComponentManager.cpp Component.cpp Collider.cpp + Metadata.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -12,6 +13,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES ComponentManager.hpp Component.h Collider.h + Metadata.h ) add_subdirectory(api) diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp index 358ce31..78b47fa 100644 --- a/src/crepe/Component.cpp +++ b/src/crepe/Component.cpp @@ -3,3 +3,5 @@ using namespace crepe; Component::Component(uint32_t id) : game_object_id(id), active(true) {} + +int Component::get_instances_max() const { return -1; } diff --git a/src/crepe/Component.h b/src/crepe/Component.h index bc44865..039836e 100644 --- a/src/crepe/Component.h +++ b/src/crepe/Component.h @@ -13,6 +13,7 @@ protected: public: virtual ~Component() = default; + virtual int get_instances_max() const; public: uint32_t game_object_id; diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp index 9b07f13..f469d12 100644 --- a/src/crepe/ComponentManager.hpp +++ b/src/crepe/ComponentManager.hpp @@ -30,9 +30,18 @@ T & ComponentManager::add_component(uint32_t id, Args &&... args) { // Create a new component of type T (arguments directly forwarded). The // constructor must be called by ComponentManager. - T * instance = new T(id, forward<Args>(args)...); + T * instance_pointer = new T(id, forward<Args>(args)...); + unique_ptr<T> instance = unique_ptr<T>(instance_pointer); + + // Check if the vector size is not greater than get_instances_max + if (instance->get_instances_max() != -1 + && components[type][id].size() >= instance->get_instances_max()) { + throw std::runtime_error( + "Exceeded maximum number of instances for this component type"); + } + // store its unique_ptr in the vector<> - components[type][id].push_back(unique_ptr<T>(instance)); + components[type][id].push_back(move(instance)); return *instance; } diff --git a/src/crepe/Metadata.cpp b/src/crepe/Metadata.cpp new file mode 100644 index 0000000..d362e0a --- /dev/null +++ b/src/crepe/Metadata.cpp @@ -0,0 +1,9 @@ +#include "Metadata.h" + +using namespace crepe; +using namespace std; + +Metadata::Metadata(uint32_t gameObjectId, string name, string tag) + : Component(gameObjectId), name(name), tag(tag) {} + +int Metadata::get_instances_max() const { return 1; } diff --git a/src/crepe/Metadata.h b/src/crepe/Metadata.h new file mode 100644 index 0000000..2f08476 --- /dev/null +++ b/src/crepe/Metadata.h @@ -0,0 +1,22 @@ +#pragma once + +#include <string> +#include <vector> + +#include "Component.h" + +namespace crepe { + +class Metadata : public Component { +public: + Metadata(uint32_t game_object_id, std::string name, std::string tag); + int get_instances_max() const; + +public: + std::string name; + std::string tag; + uint32_t parent = UINT32_MAX; + std::vector<uint32_t> children; +}; + +} // namespace crepe diff --git a/src/crepe/api/GameObject.cpp b/src/crepe/api/GameObject.cpp index 445a60d..2592d2d 100644 --- a/src/crepe/api/GameObject.cpp +++ b/src/crepe/api/GameObject.cpp @@ -1,7 +1,25 @@ +#include "api/Transform.h" + #include "GameObject.h" +#include "Metadata.h" using namespace crepe; using namespace std; -GameObject::GameObject(uint32_t id, string name, string tag, int layer) - : id(id), name(name), tag(tag), active(true), layer(layer) {} +GameObject::GameObject(uint32_t id, std::string name, std::string tag, + Point position, double rotation, double scale) + : id(id) { + ComponentManager & mgr = ComponentManager::get_instance(); + mgr.add_component<Transform>(this->id, position, rotation, scale); + mgr.add_component<Metadata>(this->id, name, tag); +} + +void GameObject::set_parent(GameObject & parent) { + auto & mgr = ComponentManager::get_instance(); + vector<reference_wrapper<Metadata>> thisMetadata + = mgr.get_components_by_id<Metadata>(this->id); + vector<reference_wrapper<Metadata>> parentMetadata + = mgr.get_components_by_id<Metadata>(parent.id); + thisMetadata.at(0).get().parent = parent.id; + parentMetadata.at(0).get().children.push_back(this->id); +} diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h index b5d6399..dcd33ad 100644 --- a/src/crepe/api/GameObject.h +++ b/src/crepe/api/GameObject.h @@ -3,20 +3,20 @@ #include <cstdint> #include <string> +#include "api/Point.h" + namespace crepe { class GameObject { public: - GameObject(uint32_t id, std::string name, std::string tag, int layer); + GameObject(uint32_t id, std::string name, std::string tag, Point position, + double rotation, double scale); + void set_parent(GameObject & parent); template <typename T, typename... Args> T & add_component(Args &&... args); uint32_t id; - std::string name; - std::string tag; - bool active; - int layer; }; } // namespace crepe diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp index 70b16bd..a80aff3 100644 --- a/src/crepe/api/Transform.cpp +++ b/src/crepe/api/Transform.cpp @@ -8,9 +8,11 @@ using namespace crepe; -Transform::Transform(uint32_t game_id, const Point & point, double rot, - double scale) +Transform::Transform(uint32_t game_id, Point point, double rot, double scale) : Component(game_id), position(point), rotation(rot), scale(scale) { dbg_trace(); } + Transform::~Transform() { dbg_trace(); } + +int Transform::get_instances_max() const { return 1; } diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h index d416088..f918115 100644 --- a/src/crepe/api/Transform.h +++ b/src/crepe/api/Transform.h @@ -14,8 +14,9 @@ class Transform : public Component { // works similar (or the same) as those found in GLSL? public: - Transform(uint32_t id, const Point &, double, double); + Transform(uint32_t id, Point, double, double); ~Transform(); + int get_instances_max() const; //! Translation (shift) Point position; //! Rotation, in radians diff --git a/src/crepe/system/System.h b/src/crepe/system/System.h index ecbb7f5..8744920 100644 --- a/src/crepe/system/System.h +++ b/src/crepe/system/System.h @@ -8,8 +8,8 @@ public: virtual void update() = 0; protected: - System() {}; - virtual ~System() {}; + System(){}; + virtual ~System(){}; private: // singleton diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index fea6f60..81df8d1 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -24,3 +24,4 @@ add_example(rendering) add_example(asset_manager) add_example(particle) add_example(physics) +add_example(ecs) diff --git a/src/example/ecs.cpp b/src/example/ecs.cpp new file mode 100644 index 0000000..eb5eeba --- /dev/null +++ b/src/example/ecs.cpp @@ -0,0 +1,55 @@ +#include <iostream> + +#include "../crepe/ComponentManager.h" +#include "../crepe/Metadata.h" +#include "../crepe/api/GameObject.h" +#include "../crepe/api/Transform.h" + +using namespace crepe; +using namespace std; + +int main() { + // Create a few GameObjects + try { + GameObject body(0, "body", "person", Point{0, 0}, 0, 1); + GameObject rightLeg(1, "rightLeg", "person", Point{1, 1}, 0, 1); + GameObject leftLeg(2, "leftLeg", "person", Point{1, 1}, 0, 1); + GameObject rightFoot(3, "rightFoot", "person", Point{2, 2}, 0, 1); + GameObject leftFoot(4, "leftFoot", "person", Point{2, 2}, 0, 1); + + // Set the parent of each GameObject + rightFoot.set_parent(rightLeg); + leftFoot.set_parent(leftLeg); + rightLeg.set_parent(body); + leftLeg.set_parent(body); + + // Adding a second Transform component is not allowed and will invoke an exception + body.add_component<Transform>(Point{10, 10}, 0, 1); + } catch (const exception & e) { + cerr << e.what() << endl; + } + + // Get the Metadata and Transform components of each GameObject + ComponentManager & mgr = ComponentManager::get_instance(); + vector<reference_wrapper<Metadata>> metadata + = mgr.get_components_by_type<Metadata>(); + vector<reference_wrapper<Transform>> transform + = mgr.get_components_by_type<Transform>(); + + // Print the Metadata and Transform components + for (auto & m : metadata) { + cout << "Id: " << m.get().game_object_id << " Name: " << m.get().name + << " Tag: " << m.get().tag << " Parent: " << m.get().parent + << " Children: "; + for (auto & c : m.get().children) { + cout << c << " "; + } + cout << endl; + } + for (auto & t : transform) { + cout << "Id: " << t.get().game_object_id << " Position: [" + << t.get().position.x << ", " << t.get().position.y << "]" << endl; + } + + return 0; +} diff --git a/src/example/particle.cpp b/src/example/particle.cpp index 47ad2e2..69da015 100644 --- a/src/example/particle.cpp +++ b/src/example/particle.cpp @@ -25,7 +25,7 @@ int main(int argc, char * argv[]) { } GameObject * game_object[1]; - game_object[0] = new GameObject(0, "Name", "Tag", 0); + game_object[0] = new GameObject(0, "Name", "Tag", Point{0, 0}, 0, 1); // FIXME: all systems are singletons, so this shouldn't even compile. ParticleSystem particle_system; diff --git a/src/example/physics.cpp b/src/example/physics.cpp index 2dbddc2..c7db6ac 100644 --- a/src/example/physics.cpp +++ b/src/example/physics.cpp @@ -16,13 +16,9 @@ using namespace std; int main(int argc, char * argv[]) { PhysicsSystem physics_system; GameObject * game_object[2]; - game_object[1] = new GameObject(2, "Name", "Tag", 0); // not found not used - game_object[0] = new GameObject(5, "Name", "Tag", 0); - Point point = { - .x = 0, - .y = 0, - }; - game_object[0]->add_component<Transform>(point, 0, 0); + // not found not used + game_object[1] = new GameObject(2, "Name", "Tag", Point{0, 0}, 0, 0); + game_object[0] = new GameObject(5, "Name", "Tag", Point{0, 0}, 0, 0); game_object[0]->add_component<Rigidbody>(1, 1, BodyType::DYNAMIC); game_object[0]->add_component<Force>(1, 0); physics_system.update(); diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp index b0ab60a..f3d8a7d 100644 --- a/src/example/rendering.cpp +++ b/src/example/rendering.cpp @@ -20,19 +20,14 @@ int main() { dbg_trace(); - auto obj = GameObject(0, "name", "tag", 0); - auto obj1 = GameObject(1, "name", "tag", 0); - auto obj2 = GameObject(2, "name", "tag", 0); + auto obj = GameObject(0, "name", "tag", Point{0, 0}, 1, 1); + auto obj1 = GameObject(1, "name", "tag", Point{500, 0}, 1, 0.1); + auto obj2 = GameObject(2, "name", "tag", Point{800, 0}, 1, 0.1); auto & mgr = AssetManager::get_instance(); // Normal adding components { Color color(0, 0, 0, 0); - Point point = { - .x = 0, - .y = 0, - }; - obj.add_component<Transform>(point, 1, 1); obj.add_component<Sprite>( make_shared<Texture>("../asset/texture/img.png"), color, FlipSettings{true, true}); @@ -40,22 +35,12 @@ int main() { { Color color(0, 0, 0, 0); - Point point = { - .x = 500, - .y = 0, - }; - obj1.add_component<Transform>(point, 0, 0.1); auto img = mgr.cache<Texture>("../asset/texture/second.png"); obj1.add_component<Sprite>(img, color, FlipSettings{true, true}); } { Color color(0, 0, 0, 0); - Point point = { - .x = 800, - .y = 0, - }; - //obj.add_component<Transform>(point, 0, 0.1); auto img = mgr.cache<Texture>("../asset/texture/second.png"); obj2.add_component<Sprite>(img, color, FlipSettings{true, true}); } diff --git a/src/example/script.cpp b/src/example/script.cpp index dac7af3..928eddf 100644 --- a/src/example/script.cpp +++ b/src/example/script.cpp @@ -36,13 +36,7 @@ class MyScript : public Script { int main() { // Create game object with Transform and BehaviorScript components - auto obj = GameObject(0, "name", "tag", 0); - obj.add_component<Transform>( - Point{ - .x = 1.2, - .y = 3.4, - }, - 0, 0); + auto obj = GameObject(0, "name", "tag", Point{1.2, 3.4}, 0, 1); obj.add_component<BehaviorScript>().set_script<MyScript>(); // Get ScriptSystem singleton instance (this would normally be done from the |