From 3a66eaf74654ba1934c1ab03558505aabab95248 Mon Sep 17 00:00:00 2001 From: Danilo Date: Sat, 27 Apr 2024 00:10:07 -0300 Subject: [PATCH] Implementa GameComponent --- framework/CMakeLists.txt | 2 +- framework/enums.hpp | 7 +- framework/forward.hpp | 4 +- framework/game/component.cpp | 4 + framework/game/component.hpp | 188 +++++++++++++++++++++++++++++++++ framework/game/game.hpp | 3 + framework/platform/game-dx.cpp | 35 ++++++ framework/platform/game-dx.hpp | 11 ++ framework/xna.cpp | 2 +- framework/xna.h | 1 + 10 files changed, 253 insertions(+), 4 deletions(-) create mode 100644 framework/game/component.cpp create mode 100644 framework/game/component.hpp diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 566b5d4..2de2f6d 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -3,7 +3,7 @@ # # Add source to this project's executable. -add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp" "platform/gdevicemanager-dx.cpp" "platform/vertexinput-dx.cpp" "platform/shader-dx.cpp" "platform/rasterizerstate-dx.cpp" "platform/vertexbuffer-dx.cpp" "platform/indexbuffer-dx.cpp" "common/matrix.cpp" "platform/constbuffer-dx.cpp" "platform/databuffer-dx.cpp" "platform/samplerstate-dx.cpp" "platform/spritebatch-dx.cpp" "platform/spritefont-dx.cpp" "platform/depthstencilstate-dx.cpp" "platform/keyboard-dx.cpp" "platform/mouse-dx.cpp" "platform/gamepad-dx.cpp" "common/vectors.cpp" "platform/soundeffect-dx.cpp" "platform/displaymode-dx.cpp" "platform/presentparameters-dx.cpp") +add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp" "platform/gdevicemanager-dx.cpp" "platform/vertexinput-dx.cpp" "platform/shader-dx.cpp" "platform/rasterizerstate-dx.cpp" "platform/vertexbuffer-dx.cpp" "platform/indexbuffer-dx.cpp" "common/matrix.cpp" "platform/constbuffer-dx.cpp" "platform/databuffer-dx.cpp" "platform/samplerstate-dx.cpp" "platform/spritebatch-dx.cpp" "platform/spritefont-dx.cpp" "platform/depthstencilstate-dx.cpp" "platform/keyboard-dx.cpp" "platform/mouse-dx.cpp" "platform/gamepad-dx.cpp" "common/vectors.cpp" "platform/soundeffect-dx.cpp" "platform/displaymode-dx.cpp" "platform/presentparameters-dx.cpp" "game/component.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/enums.hpp b/framework/enums.hpp index 2b27ff4..0e2fa74 100644 --- a/framework/enums.hpp +++ b/framework/enums.hpp @@ -114,7 +114,7 @@ namespace xna { Blue, Alpha, All - }; + }; enum class ComparisonFunction { Never, @@ -171,6 +171,11 @@ namespace xna { Solid, }; + enum class GameComponentType { + Updatable, + Drawable, + }; + enum class GamePadCapabilitiesType { Unknown = 0, diff --git a/framework/forward.hpp b/framework/forward.hpp index 93bdb91..58adc53 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -35,14 +35,16 @@ namespace xna { struct Vector3; struct Vector4; - //Game class Game; + class GameComponent; class GameClock; class GameTime; class GameWindow; class GraphicsDeviceInformation; class GraphicsDeviceManager; + class IGameTime; + class IGameComponent; //Graphics class BlendState; diff --git a/framework/game/component.cpp b/framework/game/component.cpp new file mode 100644 index 0000000..cb36050 --- /dev/null +++ b/framework/game/component.cpp @@ -0,0 +1,4 @@ +#include "component.hpp" + +namespace xna { +} \ No newline at end of file diff --git a/framework/game/component.hpp b/framework/game/component.hpp new file mode 100644 index 0000000..cab3087 --- /dev/null +++ b/framework/game/component.hpp @@ -0,0 +1,188 @@ +#ifndef XNA_GAME_COMPONENT_HPP +#define XNA_GAME_COMPONENT_HPP + +#include "../default.hpp" +#include "time.hpp" +#include + +namespace xna { + class IGameComponent { + public: + virtual void Initialize() = 0; + virtual GameComponentType Type() = 0; + }; + + class IUpdateable { + public: + virtual bool Enabled() const = 0; + virtual Int UpdateOrder() const = 0; + virtual void Update(GameTime const& gameTime) = 0; + }; + + class IDrawable + { + public: + virtual bool Visible() const = 0; + virtual Int DrawOrder() const = 0; + virtual void Draw(GameTime const& gameTime) = 0; + }; + + class GameComponent : public IGameComponent, public IUpdateable { + public: + virtual ~GameComponent() {} + + virtual void Initialize() override {} + + constexpr bool Enabled() const override { + return enabled; + } + + constexpr void Enabled(bool value) { + enabled = value; + } + + constexpr Int UpdateOrder() const override { + return updateOrder; + } + + constexpr void UpdateOrder(Int value) { + updateOrder = value; + } + + virtual constexpr GameComponentType Type() override { + return GameComponentType::Updatable; + } + + virtual void Update(GameTime const& gameTime) override{} + + private: + bool enabled{ false }; + Int updateOrder{ 0 }; + }; + + class DrawableGameComponent : public GameComponent, public IDrawable { + public: + virtual ~DrawableGameComponent() {} + + constexpr bool Visible() const override { + return visible; + } + + constexpr Int DrawOrder() const override { + return drawOrder; + } + + virtual void Draw(GameTime const& gameTime) override { + } + + constexpr void Visible(bool value) { + visible = value; + } + + constexpr void DrawOrder(Int value) { + drawOrder = value; + } + + inline virtual void Initialize() override{ + if(!initialized) LoadContent(); + initialized = true; + } + + virtual constexpr GameComponentType Type() override { + return GameComponentType::Drawable; + } + + protected: + virtual void LoadContent() {} + virtual void UnloadContent() {} + + private: + bool visible{ false }; + bool initialized{ false }; + Int drawOrder{ 0 }; + }; + + class GameComponentCollection { + public: + void InsertItem(size_t index, sptr const& item) { + const auto it = components.begin(); + components.insert(it + index, item); + + std::sort(components.begin(), components.end(), UpdateOrderComparer); + } + + void RemoveItem(size_t index) { + if (index >= components.size()) + return; + + const auto it = components.begin(); + components.erase(it + index); + + std::sort(components.begin(), components.end(), UpdateOrderComparer); + } + + void ClearItems() { + components.clear(); + } + + void Add(sptr const& item) { + components.push_back(item); + std::sort(components.begin(), components.end(), UpdateOrderComparer); + } + + constexpr size_t Count() const { + return components.size(); + } + + sptr operator[](size_t index) const { + if (index >= components.size()) + return nullptr; + + return components[index]; + } + + sptr At(size_t index) const { + if (index >= components.size()) + return nullptr; + + return components[index]; + } + + static bool UpdateOrderComparer(sptr const& x, sptr const& y) { + auto comp1 = std::reinterpret_pointer_cast(x); + auto comp2 = std::reinterpret_pointer_cast(y); + + if (!comp1 && !comp2) + return false; + + if (!comp1) + return true; + + if (!comp2) + return false; + + return comp1->UpdateOrder() < comp2->UpdateOrder(); + } + + static bool DrawOrderComparer(sptr const& x, sptr const& y) { + auto comp1 = std::reinterpret_pointer_cast(x); + auto comp2 = std::reinterpret_pointer_cast(y); + + if (!comp1 && !comp2) + return false; + + if (!comp1) + return true; + + if (!comp2) + return false; + + return comp1->UpdateOrder() < comp2->UpdateOrder(); + } + + public: + std::vector> components; + }; +} + +#endif \ No newline at end of file diff --git a/framework/game/game.hpp b/framework/game/game.hpp index 6f0a0bc..de2c48a 100644 --- a/framework/game/game.hpp +++ b/framework/game/game.hpp @@ -6,6 +6,7 @@ #include "../types.hpp" #include "time.hpp" #include "window.hpp" +#include "../game/component.hpp" namespace xna { class IGame { @@ -16,6 +17,8 @@ namespace xna { virtual int Run() = 0; virtual sptr Window() = 0; virtual sptr GetGraphicsDevice() = 0; + virtual sptr Components() = 0; + virtual void DisableGameComponets(bool value) = 0; protected: virtual void Draw(GameTime const& gameTime) = 0; diff --git a/framework/platform/game-dx.cpp b/framework/platform/game-dx.cpp index 787deb9..8a92e1c 100644 --- a/framework/platform/game-dx.cpp +++ b/framework/platform/game-dx.cpp @@ -18,6 +18,8 @@ namespace xna { _gameWindow->Size( GraphicsDeviceManager::DefaultBackBufferWidth, GraphicsDeviceManager::DefaultBackBufferHeight, false); + + _gameComponents = New(); } void Game::Exit() @@ -37,6 +39,23 @@ namespace xna { } void Game::Draw(GameTime const& gameTime) { + if (!_disableGameComponent) { + std::sort(_drawableGameComponents.begin(), _drawableGameComponents.end(), GameComponentCollection::DrawOrderComparer); + + for (size_t i = 0; i < _drawableGameComponents.size(); ++i) { + auto& component = _drawableGameComponents[i]; + + if (!component) continue; + + auto drawable = reinterpret_pointer_cast(component); + + if(drawable && drawable->Visible()) + drawable->Draw(gameTime); + } + + _drawableGameComponents.clear(); + } + _graphicsDevice->Present(); } @@ -65,6 +84,22 @@ namespace xna { void Game::Update(GameTime const& gameTime) { _audioEngine->Update(); + + if (!_disableGameComponent) { + for (size_t i = 0; i < _gameComponents->Count(); ++i) { + auto component = _gameComponents->At(i); + + if (!component) continue; + + if (component->Type() == GameComponentType::Drawable) + _drawableGameComponents.push_back(component); + + auto updatable = reinterpret_pointer_cast(component); + + if(updatable && updatable->Enabled()) + updatable->Update(gameTime); + } + } } int Game::startLoop() { diff --git a/framework/platform/game-dx.hpp b/framework/platform/game-dx.hpp index ba18972..a4d262c 100644 --- a/framework/platform/game-dx.hpp +++ b/framework/platform/game-dx.hpp @@ -26,6 +26,14 @@ namespace xna { return _graphicsDevice; } + sptr Components() override { + return _gameComponents; + } + + void DisableGameComponets(bool value) override { + _disableGameComponent = value; + } + protected: virtual void Draw(GameTime const& gameTime) override; @@ -48,6 +56,9 @@ namespace xna { private: int startLoop(); void step(); + sptr _gameComponents = nullptr; + std::vector> _drawableGameComponents; + bool _disableGameComponent{ false }; }; } diff --git a/framework/xna.cpp b/framework/xna.cpp index c7824ca..2be7edb 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -13,7 +13,7 @@ namespace xna { auto _game = reinterpret_cast(this); graphics = New(_game); graphics->PreferredBackBufferWidth(1280); - graphics->PreferredBackBufferHeight(720); + graphics->PreferredBackBufferHeight(720); } void Initialize() override { diff --git a/framework/xna.h b/framework/xna.h index aebe77f..7a0a6eb 100644 --- a/framework/xna.h +++ b/framework/xna.h @@ -20,6 +20,7 @@ #include "platform/window-dx.hpp" #include "graphics/vertexposition.hpp" #include "platform/vertexbuffer-dx.hpp" +#include "game/component.hpp" #include "Windows.h" #include