|
12 | 12 | #ifndef PAX_GRAPHICA_CIRCLE_HPP |
13 | 13 | #define PAX_GRAPHICA_CIRCLE_HPP |
14 | 14 |
|
| 15 | +#include <memory> |
| 16 | + |
| 17 | +#include <PAX_GRAPHICA/Color.hpp> |
| 18 | +#include <PAX_GRAPHICA/Interface/CircleImpl.hpp> |
| 19 | +#include <PAX_SAPIENTICA/Core/Type/Vector2.hpp> |
| 20 | + |
15 | 21 | #if defined(PAXS_USING_SIV3D) |
16 | | -#include <Siv3D.hpp> |
| 22 | +#include <PAX_GRAPHICA/Siv3D/Siv3DCircleImpl.hpp> |
17 | 23 | #elif defined(PAXS_USING_DXLIB) |
18 | | -#include <DxLib.h> |
| 24 | +#include <PAX_GRAPHICA/DxLib/DxLibCircleImpl.hpp> |
19 | 25 | #elif defined(PAXS_USING_SFML) |
20 | | -#include <SFML/Graphics.hpp> |
21 | | -#include <PAX_GRAPHICA/SFML_Circle.hpp> |
| 26 | +#include <PAX_GRAPHICA/SFML/SFMLCircleImpl.hpp> |
| 27 | +#else |
| 28 | +#include <PAX_GRAPHICA/Null/NullCircleImpl.hpp> |
22 | 29 | #endif |
23 | 30 |
|
24 | | -#include <PAX_GRAPHICA/Window.hpp> |
25 | | - |
26 | | -#include <PAX_SAPIENTICA/Core/Type/Vector2.hpp> |
27 | | - |
28 | 31 | namespace paxg { |
29 | 32 |
|
30 | | - struct Circle |
31 | | - { |
| 33 | + /// @brief Circle class with Pimpl idiom for graphics library abstraction |
| 34 | + /// @note Uses shared_ptr for value semantics and automatic resource management |
| 35 | + struct Circle { |
| 36 | + private: |
| 37 | + std::shared_ptr<CircleImpl> impl; |
| 38 | + |
| 39 | + /// @brief Create implementation based on the active graphics library |
| 40 | + /// @param x X-coordinate of the circle center |
| 41 | + /// @param y Y-coordinate of the circle center |
| 42 | + /// @param r Radius of the circle |
| 43 | + /// @return Shared pointer to the implementation |
| 44 | + static std::shared_ptr<CircleImpl> createImpl(float x, float y, float r) { |
32 | 45 | #if defined(PAXS_USING_SIV3D) |
33 | | - s3d::Circle circle; |
34 | | - constexpr Circle(const paxs::Vector2<int>& pos, const float r) : circle(pos.x, pos.y, r) {} |
35 | | - constexpr Circle(const paxs::Vector2<float>& pos, const float r) : circle(pos.x, pos.y, r) {} |
36 | | - constexpr Circle(const paxs::Vector2<double>& pos, const float r) : circle(static_cast<float>(pos.x), static_cast<float>(pos.y), r) {} |
37 | | - constexpr operator s3d::Circle() const { return circle; } |
| 46 | + return std::make_shared<Siv3DCircleImpl>(x, y, r); |
| 47 | +#elif defined(PAXS_USING_DXLIB) |
| 48 | + return std::make_shared<DxLibCircleImpl>(x, y, r); |
| 49 | +#elif defined(PAXS_USING_SFML) |
| 50 | + return std::make_shared<SFMLCircleImpl>(x, y, r); |
38 | 51 | #else |
39 | | - float x, y, r; |
40 | | - constexpr Circle(const paxs::Vector2<int>& pos, const float r) : x(static_cast<float>(pos.x)), y(static_cast<float>(pos.y)), r(r) {} |
41 | | - constexpr Circle(const paxs::Vector2<float>& pos, const float r) : x(pos.x), y(pos.y), r(r) {} |
42 | | - constexpr Circle(const paxs::Vector2<double>& pos, const float r) : x(static_cast<float>(pos.x)), y(static_cast<float>(pos.y)), r(r) {} |
| 52 | + return std::make_shared<NullCircleImpl>(x, y, r); |
43 | 53 | #endif |
| 54 | + } |
| 55 | + |
| 56 | + public: |
| 57 | + /// @brief Constructor with separate x, y coordinates and radius |
| 58 | + /// @param x X-coordinate of the circle center |
| 59 | + /// @param y Y-coordinate of the circle center |
| 60 | + /// @param r Radius of the circle |
| 61 | + Circle(float x, float y, float r) |
| 62 | + : impl(createImpl(x, y, r)) {} |
| 63 | + |
| 64 | + /// @brief Constructor with Vector2<int> position and radius |
| 65 | + /// @param pos Position of the circle center |
| 66 | + /// @param r Radius of the circle |
| 67 | + Circle(const paxs::Vector2<int>& pos, const float r) |
| 68 | + : impl(createImpl(static_cast<float>(pos.x), static_cast<float>(pos.y), r)) {} |
| 69 | + |
| 70 | + /// @brief Constructor with Vector2<float> position and radius |
| 71 | + /// @param pos Position of the circle center |
| 72 | + /// @param r Radius of the circle |
| 73 | + Circle(const paxs::Vector2<float>& pos, const float r) |
| 74 | + : impl(createImpl(pos.x, pos.y, r)) {} |
| 75 | + |
| 76 | + /// @brief Constructor with Vector2<double> position and radius |
| 77 | + /// @param pos Position of the circle center |
| 78 | + /// @param r Radius of the circle |
| 79 | + Circle(const paxs::Vector2<double>& pos, const float r) |
| 80 | + : impl(createImpl(static_cast<float>(pos.x), static_cast<float>(pos.y), r)) {} |
| 81 | + |
| 82 | + /// @brief Draw the circle without color |
44 | 83 | void draw() const { |
45 | | -#if defined(PAXS_USING_SIV3D) |
46 | | - circle.draw(); |
| 84 | + if (impl) { |
| 85 | + impl->draw(); |
| 86 | + } |
| 87 | + } |
47 | 88 |
|
48 | | -#elif defined(PAXS_USING_SFML) |
49 | | - SFML_Circle::getInstance()->circle.setRadius(r); |
50 | | - SFML_Circle::getInstance()->circle.setPosition({ x, y }); |
51 | | - paxg::Window::window().draw(SFML_Circle::getInstance()->circle); |
52 | | -#endif |
| 89 | + /// @brief Draw the circle with specified color |
| 90 | + /// @param color The color to draw the circle |
| 91 | + void draw(const Color& color) const { |
| 92 | + if (impl) { |
| 93 | + impl->draw(color); |
| 94 | + } |
53 | 95 | } |
54 | 96 |
|
55 | | -#if defined(PAXS_USING_SIV3D) |
56 | | - void draw(const paxg::Color& c_) const { |
57 | | - circle.draw(c_.color); |
| 97 | + /// @brief Get the position of the circle center |
| 98 | + /// @return Position as Vector2<float> |
| 99 | + paxs::Vector2<float> getPosition() const { |
| 100 | + return impl ? impl->getPosition() : paxs::Vector2<float>(0.0f, 0.0f); |
58 | 101 | } |
59 | | -#elif defined(PAXS_USING_DXLIB) |
60 | | - void draw(const paxg::Color& c_) const { |
61 | | - DxLib::DrawCircle( |
62 | | - static_cast<int>(x), static_cast<int>(y), static_cast<int>(r), |
63 | | - DxLib::GetColor(c_.r, c_.g, c_.b), TRUE); |
| 102 | + |
| 103 | + /// @brief Get the radius of the circle |
| 104 | + float getRadius() const { |
| 105 | + return impl ? impl->getRadius() : 0.0f; |
64 | 106 | } |
65 | | -#elif defined(PAXS_USING_SFML) |
66 | | - void draw(const paxg::Color& c_) const { |
67 | | - SFML_Circle::getInstance()->circle.setRadius(r); |
68 | | - SFML_Circle::getInstance()->circle.setPosition({ x, y }); |
69 | 107 |
|
70 | | - SFML_Circle::getInstance()->circle.setFillColor(c_.color); |
71 | | - paxg::Window::window().draw(SFML_Circle::getInstance()->circle); |
| 108 | +#if defined(PAXS_USING_SIV3D) |
| 109 | + /// @brief Conversion operator to s3d::Circle (Siv3D only) |
| 110 | + operator s3d::Circle() const { |
| 111 | + auto* siv3dImpl = dynamic_cast<Siv3DCircleImpl*>(impl.get()); |
| 112 | + if (siv3dImpl) { |
| 113 | + return siv3dImpl->getNativeCircle(); |
| 114 | + } |
| 115 | + return s3d::Circle(0, 0, 0); |
72 | 116 | } |
73 | | -#else |
74 | | - void draw(const paxg::Color&) const {} |
75 | 117 | #endif |
76 | 118 | }; |
77 | 119 | } |
|
0 commit comments