From c15586cd24c6f89c70cf123ca73ed4dc82779e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9au?= <theau.baton@etu.univ-amu.fr> Date: Mon, 13 Jan 2025 00:39:06 +0100 Subject: [PATCH] Start game and finishing kernel --- TODO.txt | 2 + .../engine/graphics/front/engine/Engine.hpp | 4 + source/engine/graphics/front/engine/Layer.hpp | 7 ++ source/engine/graphics/front/object/Image.hpp | 2 +- .../graphics/front/object/Renderable.hpp | 17 ++- .../engine/graphics/front/object/Sprite.hpp | 2 +- source/engine/graphics/front/object/Text.hpp | 2 +- .../graphics/front/object/TileArray.hpp | 2 +- source/engine/io/Keyboard.hpp | 119 ++++++++++++++++++ source/engine/io/Mouse.hpp | 38 ++++++ source/engine/io/Profiler.cpp | 36 ++++++ source/engine/io/Profiler.hpp | 24 ++++ source/engine/physic/front/engine/Engine.cpp | 8 +- source/engine/physic/front/engine/Engine.hpp | 4 +- .../engine/physic/front/object/Tangible.hpp | 7 +- .../physic/front/object/TangibleMovable.cpp | 4 +- .../physic/front/object/TangibleMovable.hpp | 5 +- .../physic/front/object/TangibleStatic.cpp | 4 +- .../physic/front/object/TangibleStatic.hpp | 5 +- source/game/Game.cpp | 47 +++++++ source/game/Game.hpp | 14 +++ source/game/object/Test.cpp | 6 + source/game/object/Test.hpp | 23 ++++ source/game/utility/FrameCounter.cpp | 17 +++ source/game/utility/FrameCouter.hpp | 14 +++ source/kernel/back/engine/GraphicEngine.cpp | 6 +- source/kernel/back/engine/GraphicEngine.hpp | 3 - source/kernel/back/engine/PhysicEngine.cpp | 29 +---- source/kernel/back/linker/GraphicLinker.hpp | 38 ++++++ source/kernel/back/linker/GraphicLinker.tpp | 29 +++++ source/kernel/back/linker/Linker.hpp | 12 ++ source/kernel/back/props/Graphical.hpp | 15 +++ source/kernel/back/props/Physical.hpp | 7 +- source/kernel/back/props/Props.hpp | 4 +- source/kernel/front/Kernel.cpp | 3 +- source/kernel/front/Kernel.hpp | 6 +- .../kernel/front/component/graphic/Sprite.cpp | 26 ++++ .../kernel/front/component/graphic/Sprite.hpp | 38 ++++++ .../kernel/front/component/physic/Fixed.cpp | 32 +++++ .../kernel/front/component/physic/Fixed.hpp | 29 +++++ .../kernel/front/component/physic/Movable.cpp | 30 +++++ .../kernel/front/component/physic/Movable.hpp | 26 ++++ .../kernel/front/resolver/GraphicResolver.cpp | 9 ++ .../kernel/front/resolver/GraphicResolver.hpp | 12 ++ .../kernel/front/resolver/PhysicResolver.cpp | 2 +- source/main.cpp | 31 +++-- source/utility/Identifiable.cpp | 2 +- source/utility/Identifiable.hpp | 2 + 48 files changed, 730 insertions(+), 74 deletions(-) create mode 100644 TODO.txt create mode 100644 source/engine/io/Keyboard.hpp create mode 100644 source/engine/io/Mouse.hpp create mode 100644 source/engine/io/Profiler.cpp create mode 100644 source/engine/io/Profiler.hpp create mode 100644 source/game/Game.cpp create mode 100644 source/game/Game.hpp create mode 100644 source/game/object/Test.cpp create mode 100644 source/game/object/Test.hpp create mode 100644 source/game/utility/FrameCounter.cpp create mode 100644 source/game/utility/FrameCouter.hpp create mode 100644 source/kernel/back/linker/GraphicLinker.hpp create mode 100644 source/kernel/back/linker/GraphicLinker.tpp create mode 100644 source/kernel/back/linker/Linker.hpp create mode 100644 source/kernel/front/component/graphic/Sprite.cpp create mode 100644 source/kernel/front/component/graphic/Sprite.hpp create mode 100644 source/kernel/front/component/physic/Fixed.cpp create mode 100644 source/kernel/front/component/physic/Fixed.hpp create mode 100644 source/kernel/front/component/physic/Movable.cpp create mode 100644 source/kernel/front/component/physic/Movable.hpp create mode 100644 source/kernel/front/resolver/GraphicResolver.cpp create mode 100644 source/kernel/front/resolver/GraphicResolver.hpp diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..41f0933 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,2 @@ +Faire les profile : keyboard, mouse, mouse & keyboard, ... +Faire les props : PropsStatic, PropsDynamic, ~PalyableProps~, ... \ No newline at end of file diff --git a/source/engine/graphics/front/engine/Engine.hpp b/source/engine/graphics/front/engine/Engine.hpp index e634670..7d83972 100644 --- a/source/engine/graphics/front/engine/Engine.hpp +++ b/source/engine/graphics/front/engine/Engine.hpp @@ -23,6 +23,10 @@ namespace megu { this->_layers[layer_priority].get()->push<T>(object_priority, object, modul); } + /*void push(Priority layer_priority, Priority object_priority, Renderable & renderable) { + this->_layers[layer_priority].get()->push(object_priority, renderable); + }*/ + void remove(Priority); std::optional<std::reference_wrapper<const Layer>> get(Priority) const; diff --git a/source/engine/graphics/front/engine/Layer.hpp b/source/engine/graphics/front/engine/Layer.hpp index 3cefe8d..a1dbcce 100644 --- a/source/engine/graphics/front/engine/Layer.hpp +++ b/source/engine/graphics/front/engine/Layer.hpp @@ -27,9 +27,16 @@ namespace megu { template <class T> void push(Priority priority, T & object, Module<T> * modul) { + if(this->_objects.contains(priority)) { + this->_objects.erase(priority); + } this->_objects.insert({priority, Renderable{ object, modul }}); } + /*void push(Priority priority, Renderable & renderable) { + this->_objects[priority] = renderable; + }*/ + const Texture & draw(const Window & w, const TextureArray & a) { this->_frameBuffer.bind(); this->_renderer.clear(); diff --git a/source/engine/graphics/front/object/Image.hpp b/source/engine/graphics/front/object/Image.hpp index 82bad96..715408d 100644 --- a/source/engine/graphics/front/object/Image.hpp +++ b/source/engine/graphics/front/object/Image.hpp @@ -11,7 +11,7 @@ #include <engine/utility/type.hpp> namespace megu { - class Image : public Quads, virtual public Identifiable { + class Image : public Quads { public: Image() = default; Image(const std::filesystem::path &); diff --git a/source/engine/graphics/front/object/Renderable.hpp b/source/engine/graphics/front/object/Renderable.hpp index 9b7d0f3..4787c74 100644 --- a/source/engine/graphics/front/object/Renderable.hpp +++ b/source/engine/graphics/front/object/Renderable.hpp @@ -8,10 +8,12 @@ #include <engine/graphics/front/engine/TextureArray.hpp> #include <engine/io/Window.hpp> +#include <utility/Identifiable.hpp> + namespace megu { - class Renderable { + class Renderable : virtual public Identifiable { public: - Renderable() = delete; + Renderable() = delete; template <class T> Renderable(T & object, Module<T> * module) @@ -35,22 +37,27 @@ namespace megu { virtual void render(const Window &, const Camera &) const = 0; virtual std::unique_ptr<RenderableConcept> clone() const = 0; + virtual const std::type_info & type() const = 0; }; template <class T> struct RenderableModel : public RenderableConcept { RenderableModel(T & v, Module<T> * m) - : _object{ v }, _module{ m } {} + : _objects{ v }, _module{ m } {} void render(const Window & window, const Camera & camera) const override { - this->_module->draw(this->_object, camera, window); + this->_module->draw(this->_objects, camera, window); } std::unique_ptr<RenderableConcept> clone() const override { return std::make_unique<RenderableModel>(*this); } - T & _object; + const std::type_info & type() const { + return typeid(T); + } + + T _objects; Module<T> * _module; }; diff --git a/source/engine/graphics/front/object/Sprite.hpp b/source/engine/graphics/front/object/Sprite.hpp index 3ddff4e..5601f37 100644 --- a/source/engine/graphics/front/object/Sprite.hpp +++ b/source/engine/graphics/front/object/Sprite.hpp @@ -9,7 +9,7 @@ #include <engine/utility/type.hpp> namespace megu { - class Sprite : public Quads, virtual public Identifiable { + class Sprite : public Quads { public: using Frame = glm::vec4; diff --git a/source/engine/graphics/front/object/Text.hpp b/source/engine/graphics/front/object/Text.hpp index 2b45d63..7fd1df3 100644 --- a/source/engine/graphics/front/object/Text.hpp +++ b/source/engine/graphics/front/object/Text.hpp @@ -12,7 +12,7 @@ #include <engine/utility/type.hpp> namespace megu { - class Text : public Quads, public Identifiable { + class Text : public Quads { public: using Frame = Vec4Int; using CharacterMap = std::map<unsigned char, Frame>; diff --git a/source/engine/graphics/front/object/TileArray.hpp b/source/engine/graphics/front/object/TileArray.hpp index 656f168..f88cb68 100644 --- a/source/engine/graphics/front/object/TileArray.hpp +++ b/source/engine/graphics/front/object/TileArray.hpp @@ -11,7 +11,7 @@ #include <engine/utility/type.hpp> namespace megu { - class TileArray : public Quads, public Identifiable { + class TileArray : public Quads { public: TileArray(const std::filesystem::path &, size_t, size_t, float); diff --git a/source/engine/io/Keyboard.hpp b/source/engine/io/Keyboard.hpp new file mode 100644 index 0000000..bcc3ab0 --- /dev/null +++ b/source/engine/io/Keyboard.hpp @@ -0,0 +1,119 @@ +#pragma once + +#include <GLFW/glfw3.h> + +namespace megu { + class Keyboard { + public: + enum class Action { + PRESS = GLFW_PRESS, + HOLD = GLFW_REPEAT, + RELEASE = GLFW_RELEASE, + }; + + enum class Key { + UTIL_SPACE = GLFW_KEY_SPACE, + UTIL_APOSTROPHE = GLFW_KEY_APOSTROPHE, + UTIL_COMMA = GLFW_KEY_COMMA, + UTIL_MINUS = GLFW_KEY_MINUS, + UTIL_PERIOD = GLFW_KEY_PERIOD, + UTIL_SEMICOLON = GLFW_KEY_SEMICOLON, + UTIL_EQUAL = GLFW_KEY_EQUAL, + + UTIL_LEFT_BRACKET = GLFW_KEY_LEFT_BRACKET , + UTIL_RIGHT_BRACKET = GLFW_KEY_RIGHT_BRACKET, + UTIL_BACKSLASH = GLFW_KEY_BACKSLASH, + UTIL_GRAVE_ACCENT = GLFW_KEY_GRAVE_ACCENT, + UTIL_WORLD_1 = GLFW_KEY_WORLD_1, + UTIL_WORLD_2 = GLFW_KEY_WORLD_2, + UTIL_ESCAPE = GLFW_KEY_ESCAPE, + UTIL_TAB = GLFW_KEY_TAB, + UTIL_BACKSPACE = GLFW_KEY_BACKSPACE, + UTIL_INSERT = GLFW_KEY_INSERT, + UTIL_DELETE = GLFW_KEY_DELETE, + + ARROW_UP = GLFW_KEY_UP, + ARROW_DOWN = GLFW_KEY_DOWN, + ARROW_LEFT = GLFW_KEY_LEFT, + ARROW_RIGHT = GLFW_KEY_RIGHT, + + UTIL_PAGE_UP = GLFW_KEY_PAGE_UP, + UTIL_PAGE_DOWN = GLFW_KEY_PAGE_DOWN, + + NUM_0 = GLFW_KEY_0, + NUM_1 = GLFW_KEY_1, + NUM_2 = GLFW_KEY_2, + NUM_3 = GLFW_KEY_3, + NUM_4 = GLFW_KEY_4, + NUM_5 = GLFW_KEY_5, + NUM_6 = GLFW_KEY_6, + NUM_7 = GLFW_KEY_7, + NUM_8 = GLFW_KEY_8, + NUM_9 = GLFW_KEY_9, + + LETTER_A = GLFW_KEY_A, + LETTER_Z = GLFW_KEY_Z, + LETTER_E = GLFW_KEY_E, + LETTER_R = GLFW_KEY_R, + LETTER_T = GLFW_KEY_T, + LETTER_Y = GLFW_KEY_Y, + LETTER_U = GLFW_KEY_U, + LETTER_I = GLFW_KEY_I, + LETTER_O = GLFW_KEY_O, + LETTER_P = GLFW_KEY_P, + LETTER_Q = GLFW_KEY_Q, + LETTER_S = GLFW_KEY_S, + LETTER_D = GLFW_KEY_D, + LETTER_F = GLFW_KEY_F, + LETTER_G = GLFW_KEY_G, + LETTER_H = GLFW_KEY_H, + LETTER_J = GLFW_KEY_J, + LETTER_K = GLFW_KEY_K, + LETTER_L = GLFW_KEY_L, + LETTER_M = GLFW_KEY_M, + LETTER_W = GLFW_KEY_W, + LETTER_X = GLFW_KEY_X, + LETTER_C = GLFW_KEY_C, + LETTER_V = GLFW_KEY_V, + LETTER_B = GLFW_KEY_B, + LETTER_N = GLFW_KEY_N, + + FUNCTION_1 = GLFW_KEY_F1, + FUNCTION_2 = GLFW_KEY_F2, + FUNCTION_3 = GLFW_KEY_F3, + FUNCTION_4 = GLFW_KEY_F4, + FUNCTION_5 = GLFW_KEY_F5, + FUNCTION_6 = GLFW_KEY_F6, + FUNCTION_7 = GLFW_KEY_F7, + FUNCTION_8 = GLFW_KEY_F8, + FUNCTION_9 = GLFW_KEY_F9, + FUNCTION_10 = GLFW_KEY_F10, + FUNCTION_11 = GLFW_KEY_F11, + FUNCTION_12 = GLFW_KEY_F12, + FUNCTION_13 = GLFW_KEY_F13, + FUNCTION_14 = GLFW_KEY_F14, + FUNCTION_15 = GLFW_KEY_F15, + FUNCTION_16 = GLFW_KEY_F16, + FUNCTION_17 = GLFW_KEY_F17, + FUNCTION_18 = GLFW_KEY_F18, + FUNCTION_19 = GLFW_KEY_F19, + FUNCTION_20 = GLFW_KEY_F20, + FUNCTION_21 = GLFW_KEY_F21, + FUNCTION_22 = GLFW_KEY_F22, + FUNCTION_23 = GLFW_KEY_F23, + FUNCTION_24 = GLFW_KEY_F24, + FUNCTION_25 = GLFW_KEY_F25, + }; + + enum class Mod { + SHIFT = GLFW_MOD_SHIFT, + CONTROL = GLFW_MOD_CONTROL, + ALT = GLFW_MOD_ALT, + SUPER = GLFW_MOD_SHIFT, + CAPS_LOCK = GLFW_MOD_CAPS_LOCK, + NUM_LOCK = GLFW_MOD_NUM_LOCK + }; + + virtual void on(Key, int, Action, Mod) = 0; + }; +} \ No newline at end of file diff --git a/source/engine/io/Mouse.hpp b/source/engine/io/Mouse.hpp new file mode 100644 index 0000000..831d797 --- /dev/null +++ b/source/engine/io/Mouse.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include <GLFW/glfw3.h> + +namespace megu { + class Mouse { + public: + enum class Button { + BUTTON_1_LEFT = GLFW_MOUSE_BUTTON_1, + BUTTON_2_RIGHT = GLFW_MOUSE_BUTTON_2, + BUTTON_3_MIDDLE = GLFW_MOUSE_BUTTON_3, + BUTTON_4 = GLFW_MOUSE_BUTTON_4, + BUTTON_5 = GLFW_MOUSE_BUTTON_5, + BUTTON_6 = GLFW_MOUSE_BUTTON_6, + BUTTON_7 = GLFW_MOUSE_BUTTON_7, + BUTTON_8_LAST = GLFW_MOUSE_BUTTON_8, + }; + + enum class Action { + PRESS = GLFW_PRESS, + HOLD = GLFW_REPEAT, + RELEASE = GLFW_RELEASE, + }; + + enum class Mod { + SHIFT = GLFW_MOD_SHIFT, + CONTROL = GLFW_MOD_CONTROL, + ALT = GLFW_MOD_ALT, + SUPER = GLFW_MOD_SHIFT, + CAPS_LOCK = GLFW_MOD_CAPS_LOCK, + NUM_LOCK = GLFW_MOD_NUM_LOCK + }; + + virtual void on(Button, Action, Mod) = 0; + virtual void on(double, double) = 0; + virtual void on(bool) = 0; + }; +} \ No newline at end of file diff --git a/source/engine/io/Profiler.cpp b/source/engine/io/Profiler.cpp new file mode 100644 index 0000000..8464b44 --- /dev/null +++ b/source/engine/io/Profiler.cpp @@ -0,0 +1,36 @@ +#include "Profiler.hpp" + +#include <functional> + +namespace megu { + void Profiler::set(Keyboard * keyboard) { + this->_keyboard = std::unique_ptr<Keyboard>(keyboard); + } + + void Profiler::set(Mouse * mouse) { + this->_mouse = std::unique_ptr<Mouse>(mouse); + } + + void Profiler::link(const Window & window) const { + glfwSetWindowUserPointer(window.ptr(), (void *)(this)); + if(this->_keyboard != nullptr) { + glfwSetKeyCallback(window.ptr(), [](GLFWwindow * window, int key, int scancode, int action, int mods) { + static_cast<Profiler *>(glfwGetWindowUserPointer(window))->keyboard()->on(Keyboard::Key(key), scancode, Keyboard::Action(action),Keyboard::Mod(mods)); + }); + } + + if(this->_mouse != nullptr) { + glfwSetCursorPosCallback(window.ptr(), [](GLFWwindow * window, double x, double y) { + static_cast<Profiler *>(glfwGetWindowUserPointer(window))->mouse()->on(x, y); + }); + + glfwSetCursorEnterCallback(window.ptr(), [](GLFWwindow * window, int entered) { + static_cast<Profiler *>(glfwGetWindowUserPointer(window))->mouse()->on(entered); + }); + + glfwSetMouseButtonCallback(window.ptr(), [](GLFWwindow * window, int button, int action, int mods) { + static_cast<Profiler *>(glfwGetWindowUserPointer(window))->mouse()->on(Mouse::Button(button), Mouse::Action(action), Mouse::Mod(mods)); + }); + } + } +} \ No newline at end of file diff --git a/source/engine/io/Profiler.hpp b/source/engine/io/Profiler.hpp new file mode 100644 index 0000000..13db900 --- /dev/null +++ b/source/engine/io/Profiler.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include <memory> + +#include "Window.hpp" +#include "Keyboard.hpp" +#include "Mouse.hpp" + +namespace megu { + class Profiler { + public: + inline Keyboard * keyboard() const {return this->_keyboard.get();} + inline Mouse * mouse() const {return this->_mouse.get();} + + void set(Keyboard *); + void set(Mouse *); + + void link(const Window &) const; + + private: + std::unique_ptr<Keyboard> _keyboard; + std::unique_ptr<Mouse> _mouse; + }; +} \ No newline at end of file diff --git a/source/engine/physic/front/engine/Engine.cpp b/source/engine/physic/front/engine/Engine.cpp index db989ec..5b21c12 100644 --- a/source/engine/physic/front/engine/Engine.cpp +++ b/source/engine/physic/front/engine/Engine.cpp @@ -19,16 +19,16 @@ namespace megu { } } - void PhysicEngine::step() { + void PhysicEngine::step(double time) { this->_collisions.clear(); for(const auto & [priority, layer] : this->_dynamic) { - this->step(priority); + this->step(time, priority); } } - void PhysicEngine::step(Priority priority) { + void PhysicEngine::step(double delta, Priority priority) { for(auto & source : this->_dynamic[priority]) { - source.get().update_physic(); + source.get().update_physic(delta); for(auto & target : this->_statics[priority]) { if(source.get().isColliding(target)) { diff --git a/source/engine/physic/front/engine/Engine.hpp b/source/engine/physic/front/engine/Engine.hpp index 3b7abde..79bbabd 100644 --- a/source/engine/physic/front/engine/Engine.hpp +++ b/source/engine/physic/front/engine/Engine.hpp @@ -21,8 +21,8 @@ namespace megu { void push(Priority, TangibleStatic &); void push(Priority, TangibleMovable &); - void step(); - void step(Priority); + void step(double); + void step(double, Priority); inline void clearCollision() {this->_collisions.clear();} diff --git a/source/engine/physic/front/object/Tangible.hpp b/source/engine/physic/front/object/Tangible.hpp index 7717e69..926a4ca 100644 --- a/source/engine/physic/front/object/Tangible.hpp +++ b/source/engine/physic/front/object/Tangible.hpp @@ -4,6 +4,7 @@ #include <engine/physic/back/Position.hpp> #include <engine/physic/back/SquareBox.hpp> +#include <functional> namespace megu { class Tangible : virtual public Identifiable { @@ -26,10 +27,12 @@ namespace megu { bool isColliding(const Tangible &) const; bool operator==(const Tangible &) const; - bool operator!=(const Tangible &) const; + bool operator!=(const Tangible &) const; + + using UpdateLambda = std::function<void(double)>; protected: - virtual void update() = 0; + virtual void update(double) = 0; private: SquareBox _box; diff --git a/source/engine/physic/front/object/TangibleMovable.cpp b/source/engine/physic/front/object/TangibleMovable.cpp index 6d1515d..e791729 100644 --- a/source/engine/physic/front/object/TangibleMovable.cpp +++ b/source/engine/physic/front/object/TangibleMovable.cpp @@ -4,7 +4,7 @@ namespace megu { TangibleMovable::TangibleMovable(const Position & position, const Dimension & dimension) : Tangible(position, dimension) {} - void TangibleMovable::update() { - this->update_physic(); + void TangibleMovable::update(double delta) { + this->update_physic(delta); } } \ No newline at end of file diff --git a/source/engine/physic/front/object/TangibleMovable.hpp b/source/engine/physic/front/object/TangibleMovable.hpp index c0b7f6d..2d44fad 100644 --- a/source/engine/physic/front/object/TangibleMovable.hpp +++ b/source/engine/physic/front/object/TangibleMovable.hpp @@ -7,10 +7,11 @@ namespace megu { public: TangibleMovable() = delete; TangibleMovable(const Position &, const Dimension &); + virtual ~TangibleMovable() = default; - virtual void update_physic() {}; + virtual void update_physic(double) = 0; protected: - void update() override; + void update(double) override; }; } \ No newline at end of file diff --git a/source/engine/physic/front/object/TangibleStatic.cpp b/source/engine/physic/front/object/TangibleStatic.cpp index 8596eef..244d16c 100644 --- a/source/engine/physic/front/object/TangibleStatic.cpp +++ b/source/engine/physic/front/object/TangibleStatic.cpp @@ -4,7 +4,7 @@ namespace megu { TangibleStatic::TangibleStatic(const Position & position, const Dimension & dimension) : Tangible(position, dimension) {} - void TangibleStatic::update() { - this->update_physic(); + void TangibleStatic::update(double delta) { + this->update_physic(delta); } } \ No newline at end of file diff --git a/source/engine/physic/front/object/TangibleStatic.hpp b/source/engine/physic/front/object/TangibleStatic.hpp index 81b24b9..2d4d335 100644 --- a/source/engine/physic/front/object/TangibleStatic.hpp +++ b/source/engine/physic/front/object/TangibleStatic.hpp @@ -7,10 +7,11 @@ namespace megu { public: TangibleStatic() = delete; TangibleStatic(const Position &, const Dimension &); + virtual ~TangibleStatic() = default; - virtual void update_physic() const {}; + virtual void update_physic(double) const = 0; protected: - void update() override; + void update(double) override; }; } \ No newline at end of file diff --git a/source/game/Game.cpp b/source/game/Game.cpp new file mode 100644 index 0000000..1920d7a --- /dev/null +++ b/source/game/Game.cpp @@ -0,0 +1,47 @@ +#include "Game.hpp" + + +#include <kernel/front/Kernel.hpp> +#include <engine/io/Window.hpp> +#include <game/utility/FrameCouter.hpp> + +#include <game/object/Test.hpp> + +namespace megu::game { + Game::Game(const std::string & title) + : _title(title) { + + } + + bool Game::run() { + try { + Window window; + window.open(this->_title, 720, 720); + FrameCounter counter; + + kernel::Kernel kernel(window); + + /* object */ + auto path = std::filesystem::path("assets/textures/Neera.png"); + megu::game::Object object(path); + kernel.add(&object); + + megu::game::Object object2(path); + object2.tmp_setPos(20, 0); + kernel.add(&object2); + /* ------ */ + + while(window.isOpen()) { + counter.count(Window::Time()); + window.pollEvents(); + kernel.step(); + } + } + catch(std::exception & error) { + std::cerr << "[Error] : " << error.what() << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + } +} \ No newline at end of file diff --git a/source/game/Game.hpp b/source/game/Game.hpp new file mode 100644 index 0000000..d3d3553 --- /dev/null +++ b/source/game/Game.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include <string> + +namespace megu::game { + class Game { + public: + Game(const std::string &); + virtual bool run(); + + private: + std::string _title; + }; +} \ No newline at end of file diff --git a/source/game/object/Test.cpp b/source/game/object/Test.cpp new file mode 100644 index 0000000..0dbade9 --- /dev/null +++ b/source/game/object/Test.cpp @@ -0,0 +1,6 @@ +#include "Test.hpp" + +namespace megu::game { + Object::Object(std::filesystem::path & path) + : _physic(0, 0, 64, 64), _graphic(path) {} +} \ No newline at end of file diff --git a/source/game/object/Test.hpp b/source/game/object/Test.hpp new file mode 100644 index 0000000..94fb9a6 --- /dev/null +++ b/source/game/object/Test.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include <kernel/back/props/Props.hpp> +#include <kernel/front/component/physic/Fixed.hpp> +#include <kernel/front/component/graphic/Sprite.hpp> + +namespace megu::game { + class Object : public kernel::Props { + public: + Object(std::filesystem::path &); + + inline kernel::Physical<kernel::PhysicEngine> & getPhysicComponent() override {return this->_physic;} + inline kernel::Graphical<kernel::GraphicEngine> & getGraphicComponent() override {return this->_graphic;} + + inline void tmp_setPos(float x, float y) { + this->_graphic.tmp_setPos(x, y); + } + + private: + kernel::Fixed _physic; + kernel::Sprite _graphic; + }; +} \ No newline at end of file diff --git a/source/game/utility/FrameCounter.cpp b/source/game/utility/FrameCounter.cpp new file mode 100644 index 0000000..b45be3e --- /dev/null +++ b/source/game/utility/FrameCounter.cpp @@ -0,0 +1,17 @@ +#include "FrameCouter.hpp" + +namespace megu::game { + FrameCounter::FrameCounter() + : _previous(0.0), _frame(0), _count(0) {} + + unsigned int FrameCounter::count(double time) { + this->_count++; + if(time - this->_previous >= 1.0) { + this->_frame = this->_count; + this->_count = 0; + this->_previous = time; + } + + return this->_frame; + } +} \ No newline at end of file diff --git a/source/game/utility/FrameCouter.hpp b/source/game/utility/FrameCouter.hpp new file mode 100644 index 0000000..bab1bba --- /dev/null +++ b/source/game/utility/FrameCouter.hpp @@ -0,0 +1,14 @@ +#pragma once + +namespace megu::game { + class FrameCounter { + public: + FrameCounter(); + unsigned int count(double); + + private: + double _previous; + unsigned int _count; + unsigned int _frame; + }; +} \ No newline at end of file diff --git a/source/kernel/back/engine/GraphicEngine.cpp b/source/kernel/back/engine/GraphicEngine.cpp index a2c490a..6a811a4 100644 --- a/source/kernel/back/engine/GraphicEngine.cpp +++ b/source/kernel/back/engine/GraphicEngine.cpp @@ -1,18 +1,20 @@ #include "GraphicEngine.hpp" +#include <kernel/front/Kernel.hpp> + namespace megu::kernel { GraphicEngine::GraphicEngine(Window & window) : _engine(window), _renderer(360, 360) {} void GraphicEngine::boot(Kernel &) { - + this->_engine.push(0, this->_renderer); } void GraphicEngine::stop(Kernel &) { } - void GraphicEngine::step(Kernel &, double) { + void GraphicEngine::step(Kernel & kernel, double time) { this->_engine.step(); } diff --git a/source/kernel/back/engine/GraphicEngine.hpp b/source/kernel/back/engine/GraphicEngine.hpp index 4dee18f..f26ef13 100644 --- a/source/kernel/back/engine/GraphicEngine.hpp +++ b/source/kernel/back/engine/GraphicEngine.hpp @@ -6,7 +6,6 @@ #include <engine/graphics/front/engine/Engine.hpp> #include <engine/graphics/front/engine/Renderer.hpp> -#include <engine/graphics/front/module/Quad_Module.hpp> #include <kernel/back/props/Graphical.hpp> @@ -25,11 +24,9 @@ namespace megu::kernel { inline const megu::GraphicEngine & engine() const {return this->_engine;} inline const megu::Renderer & renderer() const {return this->_renderer;} - inline const megu::Quad_Module & module() const {return this->_module;} private: megu::GraphicEngine _engine; megu::Renderer _renderer; - megu::Quad_Module _module; }; } \ No newline at end of file diff --git a/source/kernel/back/engine/PhysicEngine.cpp b/source/kernel/back/engine/PhysicEngine.cpp index b259f9d..f679407 100644 --- a/source/kernel/back/engine/PhysicEngine.cpp +++ b/source/kernel/back/engine/PhysicEngine.cpp @@ -7,32 +7,7 @@ namespace megu::kernel { : _engine() {} void PhysicEngine::boot(Kernel &) { - try { - megu::TangibleMovable a(megu::Position{0.f, 0.f}, megu::Dimension{2.f, 1.f, 0.f}); - a.setId(0); - - megu::TangibleMovable b(megu::Position{10.f, 0.0f}, megu::Dimension{1.f, 1.f, 0.f}); - b.setId(1); - - megu::PhysicEngine engine; - - engine.push(0, a); - engine.push(0, b); - - for(size_t i = 0; i < 8; ++i) { - a.move(1.f, 0.f); - engine.step(); - } - - auto collisions = engine.collision(); - - for(const auto & collision : collisions) { - std::cout << "Collision between " << collision.source().id() << " and " << collision.target().id() << std::endl; - } - } - catch(std::exception & error) { - std::cerr << error.what() << std::endl; - } + } void PhysicEngine::stop(Kernel &) { @@ -40,7 +15,7 @@ namespace megu::kernel { } void PhysicEngine::step(Kernel &, double time) { - this->_engine.step(); + this->_engine.step(time); } void PhysicEngine::add(Kernel & kernel, Physical<PhysicEngine> & props) { diff --git a/source/kernel/back/linker/GraphicLinker.hpp b/source/kernel/back/linker/GraphicLinker.hpp new file mode 100644 index 0000000..86b091a --- /dev/null +++ b/source/kernel/back/linker/GraphicLinker.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "Linker.hpp" +#include <kernel/back/engine/GraphicEngine.hpp> + +namespace megu::kernel { + struct Priority_Pair { + Priority layer; + Priority object; + + bool operator<(const Priority_Pair & pp) const { + if(this->layer == pp.layer) { + return this->object < pp.object; + } + return this->layer < pp.layer; + } + }; + + template <class T> + class GraphicLinker : public Linker<GraphicEngine> { + public: + GraphicLinker(); + + void link(T &, Priority, Priority); + void link(GraphicEngine &) override; + void setModule(Module<ref_set<T>> *); + + inline bool haveModule() const {return this->_module.get() != nullptr;} + inline ref_set<T> & objects() {return this->_object;} + + private: + std::unique_ptr<Module<ref_set<T>>> _module; + std::map<Priority_Pair, ref_set<T>> _objects; + std::set<Priority_Pair> _waiting; + }; +} + +#include "GraphicLinker.tpp" \ No newline at end of file diff --git a/source/kernel/back/linker/GraphicLinker.tpp b/source/kernel/back/linker/GraphicLinker.tpp new file mode 100644 index 0000000..29fe81f --- /dev/null +++ b/source/kernel/back/linker/GraphicLinker.tpp @@ -0,0 +1,29 @@ +#include "GraphicLinker.hpp" + +namespace megu::kernel { + template <class T> + GraphicLinker<T>::GraphicLinker() + : _module(nullptr) {} + + template <class T> + void GraphicLinker<T>::link(T & object, Priority l, Priority o) { + auto layers = Priority_Pair{l, o}; + + this->_objects[layers].insert(object); + this->_waiting.insert(layers); + } + + template <class T> + void GraphicLinker<T>::link(GraphicEngine & engine) { + for(const auto & layers : this->_waiting) { + engine.get().push(layers.layer, layers.object , this->_objects[layers], this->_module.get()); + } + + this->_waiting.clear(); + } + + template <class T> + void GraphicLinker<T>::setModule(Module<ref_set<T>> * mod) { + this->_module = std::unique_ptr<Module<ref_set<T>>>(mod); + } +} \ No newline at end of file diff --git a/source/kernel/back/linker/Linker.hpp b/source/kernel/back/linker/Linker.hpp new file mode 100644 index 0000000..769dd2e --- /dev/null +++ b/source/kernel/back/linker/Linker.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include <engine/utility/ref_set.hpp> +#include <engine/graphics/front/module/Module.hpp> + +namespace megu::kernel { + template <class E> + class Linker { + public: + virtual void link(E &) = 0; + }; +} \ No newline at end of file diff --git a/source/kernel/back/props/Graphical.hpp b/source/kernel/back/props/Graphical.hpp index ab56c64..432e580 100644 --- a/source/kernel/back/props/Graphical.hpp +++ b/source/kernel/back/props/Graphical.hpp @@ -5,6 +5,21 @@ namespace megu::kernel { template <class Ge> class Graphical : public Component<Ge> { + public: + inline Graphical(Priority l = 0, Priority o = 0) + : _layer(l), _object(o) {} + inline Priority getLayerPriority() const {return this->_layer;} + inline Priority getObjectPriority() const {return this->_object;} + + inline void setLayerPriority(Priority p) {this->_layer = p;} + inline void setLayerObject(Priority p) {this->_object = p;} + + virtual void update(double) = 0; + + private: + Priority _layer; + Priority _object; + }; } \ No newline at end of file diff --git a/source/kernel/back/props/Physical.hpp b/source/kernel/back/props/Physical.hpp index dcc0b44..df85056 100644 --- a/source/kernel/back/props/Physical.hpp +++ b/source/kernel/back/props/Physical.hpp @@ -1,11 +1,16 @@ #pragma once +#include <functional> + #include "Component.hpp" +#include <utility/Identifiable.hpp> namespace megu::kernel { template <class Pe> class Physical : public Component<Pe> { public: - virtual void onCollide(double, const Identifiable &, Physical &) = 0; + virtual void on_collide(double, const Identifiable &, Physical &) = 0; + + using CollideLambda = std::function<void(double, const Identifiable &, Physical &)>; }; } \ No newline at end of file diff --git a/source/kernel/back/props/Props.hpp b/source/kernel/back/props/Props.hpp index a3a8cab..a83ccca 100644 --- a/source/kernel/back/props/Props.hpp +++ b/source/kernel/back/props/Props.hpp @@ -10,8 +10,8 @@ namespace megu::kernel { class Props : public Identifiable { public: - virtual Physical<PhysicEngine> & getPhysicComponent() const = 0; - virtual Graphical<GraphicEngine> & getGraphicComponent() const = 0; + virtual Physical<PhysicEngine> & getPhysicComponent() = 0; + virtual Graphical<GraphicEngine> & getGraphicComponent() = 0; }; } \ No newline at end of file diff --git a/source/kernel/front/Kernel.cpp b/source/kernel/front/Kernel.cpp index de6b7e0..c8ce770 100644 --- a/source/kernel/front/Kernel.cpp +++ b/source/kernel/front/Kernel.cpp @@ -17,10 +17,11 @@ namespace megu::kernel { if(this->_window.isOpen()) { this->_gEngine.step(*this, delta); + this->_gResolver.resolve(delta, this->_gEngine, this->_props); } this->_pEngine.step(*this, delta); - this->_resolver.resolve(delta, this->_pEngine, this->_props); + this->_pResolver.resolve(delta, this->_pEngine, this->_props); } void Kernel::add(Props * props) { diff --git a/source/kernel/front/Kernel.hpp b/source/kernel/front/Kernel.hpp index b3169be..7ba3eac 100644 --- a/source/kernel/front/Kernel.hpp +++ b/source/kernel/front/Kernel.hpp @@ -9,6 +9,7 @@ #include <kernel/back/props/Props.hpp> #include "resolver/PhysicResolver.hpp" +#include "resolver/GraphicResolver.hpp" namespace megu::kernel { class Kernel { @@ -19,6 +20,8 @@ namespace megu::kernel { void step(); void add(Props *); + inline Identifiable_Map<Props> & props() {return this->_props;} + private: Window & _window; @@ -26,6 +29,7 @@ namespace megu::kernel { GraphicEngine _gEngine; Identifiable_Map<Props> _props; - PhysicResolver _resolver; + PhysicResolver _pResolver; + GraphicResolver _gResolver; }; } \ No newline at end of file diff --git a/source/kernel/front/component/graphic/Sprite.cpp b/source/kernel/front/component/graphic/Sprite.cpp new file mode 100644 index 0000000..a7deac4 --- /dev/null +++ b/source/kernel/front/component/graphic/Sprite.cpp @@ -0,0 +1,26 @@ +#include "Sprite.hpp" + +namespace megu::kernel { + GraphicLinker<megu::Sprite> Sprite::_Linker = GraphicLinker<megu::Sprite>(); + + Sprite::Sprite(std::filesystem::path & path) + : _sprite(path), _animation(""), _index(0) { + this->_sprite.setFrame({0.f, 0.f, 51.f, 98.f}); + this->_sprite.setSize({50, 100}); + + if(!Sprite::_Linker.haveModule()) { + Sprite::_Linker.setModule(new Sprite_Module{}); + } + } + + void Sprite::update(double) { + if(!this->_animation.empty()) { + this->_sprite.setFrame(this->_frames[this->_animation][this->_index]); + } + } + + void Sprite::apply(Kernel & kernel, GraphicEngine & engine) { + Sprite::_Linker.link(this->_sprite, this->getLayerPriority(), this->getObjectPriority()); + Sprite::_Linker.link(engine); + } +} \ No newline at end of file diff --git a/source/kernel/front/component/graphic/Sprite.hpp b/source/kernel/front/component/graphic/Sprite.hpp new file mode 100644 index 0000000..1f1ad3d --- /dev/null +++ b/source/kernel/front/component/graphic/Sprite.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include <map> +#include <string> +#include <chrono> + +#include <kernel/back/engine/GraphicEngine.hpp> +#include <kernel/back/props/Graphical.hpp> +#include <kernel/back/linker/GraphicLinker.hpp> + +#include <engine/utility/ref_set.hpp> +#include <engine/graphics/front/object/Sprite.hpp> +#include <engine/graphics/front/module/Sprite_Module.hpp> + +namespace megu::kernel { + using Frame_List = std::vector<megu::Sprite::Frame>; + + class Sprite : public Graphical<GraphicEngine> { + public: + Sprite(std::filesystem::path &); + + void update(double) override; + void apply(Kernel &, GraphicEngine &) override; + + inline void tmp_setPos(float x, float y) { + this->_sprite.setPosition({x, y}); + } + + private: + megu::Sprite _sprite; + + std::map<std::string, Frame_List> _frames; + std::string _animation; + size_t _index; + + static GraphicLinker<megu::Sprite> _Linker; + }; +} \ No newline at end of file diff --git a/source/kernel/front/component/physic/Fixed.cpp b/source/kernel/front/component/physic/Fixed.cpp new file mode 100644 index 0000000..f967059 --- /dev/null +++ b/source/kernel/front/component/physic/Fixed.cpp @@ -0,0 +1,32 @@ +#include "Fixed.hpp" + +#include <kernel/front/Kernel.hpp> + +namespace megu::kernel { + Fixed::Fixed(float x, float y, float w, float h) + : TangibleStatic(Position(x, y), Dimension(w, h, 0.f)) {} + + void Fixed::update_physic(double time) const { + if(this->_update != nullptr) { + this->_update(time); + } + } + + void Fixed::on_collide(double time, const Identifiable & identifiable, Physical<PhysicEngine> & physical) { + if(this->_collide != nullptr) { + this->_collide(time, identifiable, physical); + } + } + + void Fixed::apply(Kernel & kernel, PhysicEngine & engine) { + engine.get().push(0, *this); + } + + void Fixed::setCollideLambda(const CollideLambda & lambda) { + this->_collide = lambda; + } + + void Fixed::setUpdateLambda(const UpdateLambda & lambda) { + this->_update = lambda; + } +} \ No newline at end of file diff --git a/source/kernel/front/component/physic/Fixed.hpp b/source/kernel/front/component/physic/Fixed.hpp new file mode 100644 index 0000000..e40d35e --- /dev/null +++ b/source/kernel/front/component/physic/Fixed.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include <kernel/back/props/Physical.hpp> +#include <kernel/back/engine/PhysicEngine.hpp> + +#include <engine/physic/front/object/TangibleStatic.hpp> +#include <functional> +#include <optional> + +namespace megu::kernel { + class Fixed : public TangibleStatic, public Physical<PhysicEngine> { + public: + Fixed(float x, float y, float w, float h); + + void update_physic(double) const override; + void on_collide(double, const Identifiable &, Physical<PhysicEngine> &) override; + void apply(Kernel & k, PhysicEngine &) override; + + void setCollideLambda(const CollideLambda &); + void setUpdateLambda(const UpdateLambda &); + + private: + CollideLambda _collide; + UpdateLambda _update; + + + + }; +} \ No newline at end of file diff --git a/source/kernel/front/component/physic/Movable.cpp b/source/kernel/front/component/physic/Movable.cpp new file mode 100644 index 0000000..01292d3 --- /dev/null +++ b/source/kernel/front/component/physic/Movable.cpp @@ -0,0 +1,30 @@ +#include "Movable.hpp" + +namespace megu::kernel { + Movable::Movable(float x, float y, float w, float h) + : TangibleMovable(Position(x, y), Dimension(w, h, 0.f)) {} + + void Movable::update_physic(double time) { + if(this->_update != nullptr) { + this->_update(time); + } + } + + void Movable::on_collide(double time, const Identifiable & identifiable, Physical<PhysicEngine> & physical) { + if(this->_collide != nullptr) { + this->_collide(time, identifiable, physical); + } + } + + void Movable::apply(Kernel & kernel, PhysicEngine & engine) { + engine.add(kernel, *this); + } + + void Movable::setCollideLambda(CollideLambda & lambda) { + this->_collide = lambda; + } + + void Movable::setUpdateLambda(UpdateLambda & lambda) { + this->_update = lambda; + } +} \ No newline at end of file diff --git a/source/kernel/front/component/physic/Movable.hpp b/source/kernel/front/component/physic/Movable.hpp new file mode 100644 index 0000000..48fd907 --- /dev/null +++ b/source/kernel/front/component/physic/Movable.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include <kernel/back/props/Physical.hpp> +#include <kernel/back/engine/PhysicEngine.hpp> + +#include <engine/physic/front/object/TangibleMovable.hpp> +#include <functional> +#include <optional> + +namespace megu::kernel { + class Movable : public TangibleMovable, public Physical<PhysicEngine> { + public: + Movable(float x, float y, float w, float h); + + void update_physic(double) override; + void on_collide(double, const Identifiable &, Physical<PhysicEngine> &) override; + void apply(Kernel & k, PhysicEngine &) override; + + void setCollideLambda(CollideLambda &); + void setUpdateLambda(UpdateLambda &); + + private: + CollideLambda _collide; + UpdateLambda _update; + }; +} \ No newline at end of file diff --git a/source/kernel/front/resolver/GraphicResolver.cpp b/source/kernel/front/resolver/GraphicResolver.cpp new file mode 100644 index 0000000..5c7c574 --- /dev/null +++ b/source/kernel/front/resolver/GraphicResolver.cpp @@ -0,0 +1,9 @@ +#include "GraphicResolver.hpp" + +namespace megu::kernel { + void GraphicResolver::resolve(double time, GraphicEngine &, const Identifiable_Map<Props> & props) { + for(auto & [id, object] : props) { + object->getGraphicComponent().update(time); + } + } +} \ No newline at end of file diff --git a/source/kernel/front/resolver/GraphicResolver.hpp b/source/kernel/front/resolver/GraphicResolver.hpp new file mode 100644 index 0000000..e1fe0ea --- /dev/null +++ b/source/kernel/front/resolver/GraphicResolver.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "Resolver.hpp" +#include <kernel/back/engine/GraphicEngine.hpp> +#include <kernel/back/props/Props.hpp> + +namespace megu::kernel { + class GraphicResolver : public Resolver<GraphicEngine, Props> { + public: + void resolve(double, GraphicEngine &, const Identifiable_Map<Props> &) override; + }; +} \ No newline at end of file diff --git a/source/kernel/front/resolver/PhysicResolver.cpp b/source/kernel/front/resolver/PhysicResolver.cpp index 0fb0775..2c90527 100644 --- a/source/kernel/front/resolver/PhysicResolver.cpp +++ b/source/kernel/front/resolver/PhysicResolver.cpp @@ -11,7 +11,7 @@ namespace megu::kernel { if(props.contains(source.id()) && props.contains(target.id())) { Props * props_source = props.at(source.id()); Props * props_target = props.at(target.id()); - props_source->getPhysicComponent().onCollide(time, target, props_target->getPhysicComponent()); + props_source->getPhysicComponent().on_collide(time, target, props_target->getPhysicComponent()); } } diff --git a/source/main.cpp b/source/main.cpp index 789c084..7b12b5b 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,16 +1,17 @@ #include <iostream> -#include <engine/physic/front/object/TangibleMovable.hpp> -#include <engine/physic/front/object/TangibleStatic.hpp> -#include <engine/physic/front/object/Collision.hpp> -#include <engine/physic/front/engine/Engine.hpp> - -#define WINDOW_WIDTH 720 -#define WINDOW_HEIGHT 720 - -#include <kernel/front/Kernel.hpp> +#include <game/Game.hpp> int main(int argc, const char * argv[]) { + std::cout << "Programe Start" << std::endl; + megu::game::Game game("My Game"); + std::cout << "Game Start" << std::endl; + + std::cout << "Running..." << std::endl; + return game.run(); +} + +/*int main(int argc, const char * argv[]) { std::cout << "Program Init" << std::endl; try { megu::Window window; @@ -20,6 +21,16 @@ int main(int argc, const char * argv[]) { megu::kernel::Kernel kernel(window); std::cout << "Kernel Init" << std::endl; + auto path = std::filesystem::path("assets/textures/Neera.png"); + megu::game::Object object(path); + + megu::game::Object object2(path); + object2.tmp_setPos(100, 0); + + std::cout << "Object Init" << std::endl; + kernel.add(&object2); + kernel.add(&object); + double previousTime = megu::Window::Time(); int frameCount = 0; @@ -46,4 +57,4 @@ int main(int argc, const char * argv[]) { std::cout << "Program End" << std::endl; return EXIT_SUCCESS; -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/source/utility/Identifiable.cpp b/source/utility/Identifiable.cpp index 206ab70..02c063b 100644 --- a/source/utility/Identifiable.cpp +++ b/source/utility/Identifiable.cpp @@ -4,7 +4,7 @@ namespace megu { size_t Identifiable::_GlobalId = 0; Identifiable::Identifiable() - : _id(Identifiable::_GlobalId++) {} + : _id(++Identifiable::_GlobalId) {} Identifiable::Identifiable(size_t id) : _id(id) {} diff --git a/source/utility/Identifiable.hpp b/source/utility/Identifiable.hpp index e29ee8e..11e91f5 100644 --- a/source/utility/Identifiable.hpp +++ b/source/utility/Identifiable.hpp @@ -22,6 +22,8 @@ namespace megu { bool operator>(const Identifiable &) const; bool operator<(const Identifiable &) const; + static size_t GloabalId() {return Identifiable::_GlobalId;} + private: size_t _id; static size_t _GlobalId; -- GitLab