R-Type  2
Doom but in better
Loading...
Searching...
No Matches
Window.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2024
3** rtype (Workspace)
4** File description:
5** Window.cpp
6*/
7
15
16GUI::ECS::Systems::Window::Window(const std::uint32_t entityId, const std::uint32_t windowWidth, const std::uint32_t windowHeight, const std::string &windowName, unsigned int frameRateLimit)
17 : EntityNode(entityId),
18 _sfWindow(sf::VideoMode({ windowWidth, windowHeight }), windowName),
19 _windowWidth(windowWidth),
20 _windowHeight(windowHeight),
21 _windowName(windowName)
22{
23 _sfWindow.setFramerateLimit(frameRateLimit);
24}
25
27
28void GUI::ECS::Systems::Window::setPosition(const std::pair<int, int> &position)
29{
30 PRETTY_DEBUG << "Setting the position of the window to: " << Recoded::myToString(position) << std::endl;
31 _sfWindow.setPosition({ position.first, position.second });
32 PRETTY_SUCCESS << "Position set to: " << Recoded::myToString(position) << std::endl;
33}
34
36{
37 PRETTY_DEBUG << "Setting window Icon" << std::endl;
38 const GUI::ECS::Components::TextureComponent iconTexture = icon.getImage();
39 const std::any textureCast = iconTexture.getTexture();
40 const std::optional<sf::Texture> textureCapsule = Utilities::unCast<sf::Texture, CustomExceptions::NoTexture>(textureCast, true, "<No instance of sf::Texture in the provided texture (extracted from ImageComponent>, system error: ");
41 if (!textureCapsule.has_value()) {
42 PRETTY_CRITICAL << "There is no texture to work with (gathered from ImageComponent)." << std::endl;
43 throw CustomExceptions::NoTexture("<No instance of sf::Texture in the provided texture (extracted from ImageComponent>");
44 }
45 const sf::Texture texture = textureCapsule.value();
46 const sf::Image image = texture.copyToImage();
47 if (image.getSize().x == 0 || image.getSize().y == 0) {
48 PRETTY_CRITICAL << "Image extracted from texture is invalid." << std::endl;
49 throw CustomExceptions::NoIcon("Invalid image size (extracted from sf::Texture for setting the icon of the window).");
50 }
51 const std::uint8_t *pixelData = image.getPixelsPtr();
52 const sf::Vector2u size = image.getSize();
53 _sfWindow.setIcon(size, pixelData);
54 PRETTY_SUCCESS << "Image icon set." << std::endl;
55}
56
57void GUI::ECS::Systems::Window::setTitle(const std::string &title)
58{
59 PRETTY_DEBUG << "Setting the window title to: '" << title << "'." << std::endl;
60 _sfWindow.setTitle(title);
61 _windowName = title;
62 PRETTY_SUCCESS << "Title set to: '" << title << "'" << std::endl;
63}
64
66{
67 std::any systemColour = color.getRenderColour();
68 if (!systemColour.has_value()) {
69 throw CustomExceptions::NoColour("<There was no content returned by getRenderColour when std::any (containing sf::Font was expected)>");
70 }
71 try {
72 sf::Color result = std::any_cast<sf::Color>(systemColour);
73 _sfWindow.clear(result);
74 }
75 catch (std::bad_any_cast &e) {
76 throw CustomExceptions::NoColour("<The content returned by the getRenderColour function is not of type sf::Color>, system error: " + std::string(e.what()));
77 }
78}
79
81{
82 _sfWindow.display();
83}
84
86{
87 return _sfWindow.isOpen();
88}
89
91{
92 _sfWindow.close();
93}
94
96{
97 std::any response;
98 std::optional<sf::Event> node = _sfWindow.pollEvent();
99 if (node.has_value()) {
100 sf::Event evt = node.value();
101 std::any tmp(static_cast<sf::Event>(evt));
102 response = tmp;
103 }
104 return response;
105}
106
107void GUI::ECS::Systems::Window::setFramerateLimit(const unsigned int framerateLimit)
108{
109 _sfWindow.setFramerateLimit(framerateLimit);
110}
111
113{
114 _fullScreen = fullScreen;
115
116 if (_sfWindow.isOpen()) {
117 _sfWindow.close();
118 }
119
120 if (_fullScreen) {
121 _sfWindow.create(_desktopMode, _windowName, sf::Style::None);
122 } else {
123 _sfWindow.create(sf::VideoMode({ _windowWidth, _windowHeight }), _windowName, sf::Style::Close);
124 }
125}
126
128{
129 return _fullScreen;
130}
131
132const std::string GUI::ECS::Systems::Window::getTitle() const
133{
134 return _windowName;
135}
136
137const std::pair<int, int> GUI::ECS::Systems::Window::getDimensions() const
138{
139 sf::Vector2u dim = _sfWindow.getSize();
140 return std::make_pair<int>(dim.x, dim.y);
141}
142
143const std::pair<int, int> GUI::ECS::Systems::Window::getPosition() const
144{
145 sf::Vector2i pos = _sfWindow.getPosition();
146 return std::pair<int, int>(pos.x, pos.y);
147}
148
149const std::string GUI::ECS::Systems::Window::getInfo(const unsigned int indent) const
150{
151
152 std::string indentation = "";
153 for (unsigned int i = 0; i < indent; ++i) {
154 indentation += "\t";
155 }
156 std::string result = indentation + "Window:\n";
157 result += indentation + "- Entity Id: " + Recoded::myToString(getEntityNodeId()) + "\n";
158 result += indentation + "- Window Name: '" + _windowName + "'\n";
159 result += indentation + "- Window Width: " + Recoded::myToString(_windowWidth) + "\n";
160 result += indentation + "- Window Height: " + Recoded::myToString(_windowHeight) + "\n";
161 result += indentation + "- Full Screen: " + Recoded::myToString(_fullScreen) + "\n";
162 result += indentation + "- Desktop Mode: ( size: ( width: " + Recoded::myToString(_desktopMode.size.x) + ", height: " + Recoded::myToString(_desktopMode.size.y) + "), bits per pixel: " + Recoded::myToString(_desktopMode.bitsPerPixel) + ")\n";
163 return result;
164}
165
166
168{
169 if (!text.isVisible()) {
170 return;
171 }
172 const std::any textCapsule = text.render();
173 const std::optional<sf::Text> txt = Utilities::unCast<sf::Text, CustomExceptions::NoRenderableText>(textCapsule, true, "<Unknown or empty text component, this is not a sf::Text>, any_cast error: ");
174 if (!txt.has_value()) {
175 PRETTY_CRITICAL << "<There is not sf::Text component to render, component id: '" << Recoded::myToString(text.getEntityNodeId()) << "'\n" << std::endl;
176 throw CustomExceptions::NoRenderableText("<There is no sf::Text component to render>");
177 }
178 _sfWindow.draw(txt.value());
179 PRETTY_SUCCESS << "Text component, entity id: '" << Recoded::myToString(text.getEntityNodeId()) << "', is drawn." << std::endl;
180}
181
183{
184 PRETTY_INFO << "Rendering a shape" << std::endl;
185 PRETTY_DEBUG << "Shape info:" << shape.getInfo() << std::endl;
186 if (!shape.isVisible()) {
187 PRETTY_WARNING << "Shape is hidden, id: '"
189 << "', name: '" << shape.getShapeTypeString() << "'." << std::endl;
190 return;
191 }
192 const std::optional<std::pair<GUI::ECS::Systems::ActiveShape, std::any>> shapeCapsule = shape.render();
193 if (!shapeCapsule.has_value()) {
194 PRETTY_WARNING << "Shape is not renderable, id: '"
195 << Recoded::myToString(shape.getEntityNodeId()) << "'" << std::endl;
196 return;
197 // throw CustomExceptions::NoRenderableShape("<std::pair not found in std::any, have you initialised the class with a shape?>");
198 }
199 const std::pair<GUI::ECS::Systems::ActiveShape, std::any> pairNode = shapeCapsule.value();
200 const GUI::ECS::Systems::ActiveShape shapeType = pairNode.first;
201 const std::any shapeData = pairNode.second;
202 if (shapeType == GUI::ECS::Systems::ActiveShape::NONE) {
203 PRETTY_WARNING << "There is no shape to render, skipping" << std::endl;
204 return;
205 };
207 const std::optional<sf::RectangleShape> renderableShape = Utilities::unCast<sf::RectangleShape, CustomExceptions::NoRenderableShape>(shapeData, true, "<Unknown or empty shape, this is not a RectangleShape>, any_cast error: ");
208 if (!renderableShape.has_value()) {
209 PRETTY_CRITICAL << "Shape : '" << shape.getShapeTypeString() << "' could not be rendered.\n" << std::endl;
210 throw CustomExceptions::NoRenderableShape("<There is no sf::RectangleShape located in std::any>");
211 }
212 _sfWindow.draw(renderableShape.value());
213 PRETTY_SUCCESS << "Shape: '" << shape.getShapeTypeString() << "' is drawn." << std::endl;
214 return;
215 };
217 const std::optional<sf::CircleShape> renderableShape = Utilities::unCast<sf::CircleShape, CustomExceptions::NoRenderableShape>(shapeData, true, "<Unknown or empty shape, this is not a CircleShape>, any_cast error: ");
218 if (!renderableShape.has_value()) {
219 PRETTY_CRITICAL << "Shape : '" << shape.getShapeTypeString() << "' could not be rendered.\n" << std::endl;
220 throw CustomExceptions::NoRenderableShape("<There is no sf::CircleShape located in std::any>");
221 }
222 _sfWindow.draw(renderableShape.value());
223 PRETTY_SUCCESS << "Shape: '" << shape.getShapeTypeString() << "' is drawn." << std::endl;
224 return;
225 };
227 const std::optional<sf::ConvexShape> renderableShape = Utilities::unCast<sf::ConvexShape, CustomExceptions::NoRenderableShape>(shapeData, true, "<Unknown or empty shape, this is not a ConvexShape>, any_cast error: ");
228 if (!renderableShape.has_value()) {
229 PRETTY_CRITICAL << "Shape : '" << shape.getShapeTypeString() << "' could not be rendered.\n" << std::endl;
230 throw CustomExceptions::NoRenderableShape("<There is no sf::ConvexShape located in std::any>");
231 }
232 _sfWindow.draw(renderableShape.value());
233 PRETTY_SUCCESS << "Shape: '" << shape.getShapeTypeString() << "' is drawn." << std::endl;
234 return;
235 };
236}
237
239{
240 if (!image.isVisible()) {
241 PRETTY_WARNING << "The image named '" << image.getName()
242 << "' and whom's application is '" << image.getApplication()
243 << "' is set to invisible, it will thus not be rendered."
244 << std::endl;
245 return;
246 }
247 const std::any imageCapsule = image.render();
248 const std::optional<sf::Sprite> spriteCapsule = Utilities::unCast<sf::Sprite, CustomExceptions::NoRenderableImage>(imageCapsule, true, "<Unknown or empty Image, this is not an sf::Sprite>, any_cast error");
249 if (!spriteCapsule.has_value()) {
250 PRETTY_CRITICAL << "Image : '" << image.getName()
251 << "' and whom's application is '" << image.getApplication()
252 << "' could not be rendered.\n" << std::endl;
253 throw CustomExceptions::NoRenderableImage("<Missing Image, this is not an sf::Sprite>, any_cast error");
254 }
255 _sfWindow.draw(spriteCapsule.value());
256 PRETTY_SUCCESS << "Image named '" << image.getName()
257 << "' and whom's application is '" << image.getApplication()
258 << "' is drawn" << std::endl;
259}
260
262{
263 if (!sprite.isVisible()) {
264 PRETTY_WARNING << "The sprite named '" << sprite.getName()
265 << "' and whom's application is '" << sprite.getApplication()
266 << "' is set to invisible, it will thus not be rendered."
267 << std::endl;
268 return;
269 }
270 const std::any spriteNode = sprite.render();
271 const std::optional<sf::Sprite> spriteCapsule = Utilities::unCast<sf::Sprite, CustomExceptions::NoRenderableImage>(spriteNode, true, "<Unknown Image, this is not an sf::Sprite>, any_cast error");
272 if (!spriteCapsule.has_value()) {
273 PRETTY_CRITICAL << "Sprite : '" << sprite.getName()
274 << "' and whom's application is '" << sprite.getApplication()
275 << "' could not be rendered.\n" << std::endl;
276 throw CustomExceptions::NoRenderableImage("<Missing Sprite, this is not an sf::Sprite>, any_cast error");
277 }
278 _sfWindow.draw(spriteCapsule.value());
279 PRETTY_SUCCESS << "Sprite named '" << sprite.getName()
280 << "' and whom's application is '" << sprite.getApplication()
281 << "' is drawn" << std::endl;
282}
283
285{
286 if (!button.isVisible()) {
287 PRETTY_WARNING << "The button named '" << button.getName()
288 << "' and whom's application is '" << button.getApplication()
289 << "' is set to invisible, it will thus not be rendered."
290 << std::endl;
291 return;
292 }
293 std::unordered_map<std::type_index, std::any> buttonCapsule = button.render();
294
295 const std::any shapeCapsule = buttonCapsule[typeid(GUI::ECS::Components::ShapeComponent)];
296 if (shapeCapsule.has_value()) {
297 const std::optional<GUI::ECS::Components::ShapeComponent> shape = Utilities::unCast<GUI::ECS::Components::ShapeComponent, CustomExceptions::NoRenderableShape>(shapeCapsule, false, "<There is no ShapeComponent to render>");
298 if (!shape.has_value()) {
299 PRETTY_WARNING << "There is no shape to render for the button, skipping shape rendering." << std::endl;
300 } else {
301 draw(shape.value());
302 }
303 }
304
305 const std::any textCapsule = buttonCapsule[typeid(GUI::ECS::Components::TextComponent)];
306 if (textCapsule.has_value()) {
307 const std::optional<GUI::ECS::Components::TextComponent> text = Utilities::unCast<GUI::ECS::Components::TextComponent, CustomExceptions::NoRenderableShape>(textCapsule, false, "<There is no TextComponent to render>");
308 if (!text.has_value()) {
309 PRETTY_WARNING << "There is no text to render for the button, skipping text rendering." << std::endl;
310 } else {
311 draw(text.value());
312 }
313 }
314}
315
316std::ostream &GUI::ECS::Systems::operator<<(std::ostream &os, const GUI::ECS::Systems::Window &item)
317{
318 os << item.getInfo();
319 return os;
320}
#define PRETTY_DEBUG
Debug log with details and colour.
#define PRETTY_INFO
Info log with details and colour.
#define PRETTY_CRITICAL
Critical log with details and colour.
#define PRETTY_WARNING
Warning log with details and colour.
#define PRETTY_SUCCESS
Success log with details and colour.
Header file for the Window class, which handles the graphical window and rendering logic.
This is the class in charge of informing the user that they tried to access a non-existant colour ins...
Definition No.hpp:388
This is the class in charge of informing the user that they tried to access a non-existant Icon.
Definition No.hpp:147
This is the class in charge of informing the user that they tried to render a non-existing Image comp...
Definition No.hpp:534
This is the class in charge of informing the user that they tried to render a non-existing Shape comp...
Definition No.hpp:505
This is the class in charge of informing the user that they tried to render a non-existing text compo...
Definition No.hpp:475
This is the class in charge of informing the user that they tried to access a non-existant texture in...
Definition No.hpp:446
Manages button functionalities, including appearance, position, and callbacks.
const std::string getName() const
Get the Name button component.
const std::string getApplication() const
Get the Application of the button component.
const bool isVisible() const
Get the information about if the element is visible.
std::unordered_map< std::type_index, std::any > render() const
Get the components that need rendering.
Represents an image component in the GUI ECS system.
std::any render() const
Renders the image to the given window.
const std::string getName() const
Get the Name of the image.
const bool isVisible() const
Get the visibility state of the Image.
const GUI::ECS::Components::TextureComponent getImage() const
Retrieves the texture associated with the image.
const std::string getApplication() const
Get the Application of the image.
Manages shapes and their associated properties in the ECS framework.
const bool isVisible() const
Get the visibility status of the component.
const std::string getInfo(const unsigned int indent=0) const
This is a function meant for debugging purposes It will dump the current state of the variables upon ...
std::optional< std::pair< GUI::ECS::Systems::ActiveShape, std::any > > render() const
Get an optional std::pair of the object so that it can be displayed on screen.
const std::string getShapeTypeString() const
Get the Shape Type shape, none is returned if none are initialised.
Represents a drawable and interactive sprite in the ECS system.
const std::string getApplication() const
Gets the application name associated with the sprite.
const std::string getName() const
Gets the name of the sprite.
std::any render() const
Renders the sprite to a window.
const bool isVisible() const
Check if the sprite is set to be rendred or not.
A class that represents a text component in the GUI system. It manages font, size,...
const bool isVisible() const
Check if the text is set to be rendered or not.
std::any render() const
Function in charge of rendering the text if it is set to visible, otherwise, does nothing.
Represents a texture component used in an entity component system.
const std::any getTexture() const
Retrieves the texture as a std::any object.
virtual size_t getEntityNodeId() const
A class for representing and manipulating colors using RGBA components. Inherits from EntityNode to a...
Definition Colour.hpp:37
const std::any getRenderColour() const
Retrieves the color as an SFML sf::Color if the sfml library is the underlying library,...
Definition Colour.cpp:215
Manages an SFML-based graphical window and handles rendering of ECS components.
Definition Window.hpp:67
void setPosition(const std::pair< int, int > &position)
Set the Position of the window.
Definition Window.cpp:28
void close()
Closes the window.
Definition Window.cpp:90
Window(const std::uint32_t entityId=0, const std::uint32_t windowWidth=800, const std::uint32_t windowHeight=600, const std::string &windowName="R-Type", unsigned int frameRateLimit=60)
Constructs a new Window object.
Definition Window.cpp:16
~Window()
Destroys the Window object.
Definition Window.cpp:26
void setTitle(const std::string &title="R-Type")
Set the Title of the window.
Definition Window.cpp:57
void draw(const GUI::ECS::Components::TextComponent &text)
Renders a text component to the window.
Definition Window.cpp:167
void display()
Displays the contents of the window on the screen.
Definition Window.cpp:80
const bool getFullScreen() const
Retrieves the current fullscreen mode of the window.
Definition Window.cpp:127
void setFullScreen(const bool fullScreen)
Enables or disables fullscreen mode for the window.
Definition Window.cpp:112
void setIcon(const GUI::ECS::Components::ImageComponent &icon)
Set the Icon of the window.
Definition Window.cpp:35
const std::string getInfo(const unsigned int indent=0) const
This is a function meant for debugging purposes It will dump the current state of the variables upon ...
Definition Window.cpp:149
void clear(const GUI::ECS::Systems::Colour &color=GUI::ECS::Systems::Colour::Black)
Clears the window with the specified color.
Definition Window.cpp:65
void setFramerateLimit(const unsigned int framerateLimit)
Sets the frame rate limit of the window.
Definition Window.cpp:107
bool isOpen() const
Checks if the window is currently open.
Definition Window.cpp:85
const std::pair< int, int > getPosition() const
Get the Position of the window.
Definition Window.cpp:143
const std::string getTitle() const
Get the Title of the window.
Definition Window.cpp:132
std::any pollEvent()
Polls for the next event in the window's event queue.
Definition Window.cpp:95
const std::pair< int, int > getDimensions() const
Get the Dimensions of the window.
Definition Window.cpp:137
ActiveShape
Enum representing different types of shapes managed by the ShapeComponent.
@ NONE
No shape initialized.
std::ostream & operator<<(std::ostream &os, const Clock &item)
Outputs the clock's info to a stream.
Definition Clock.cpp:73
const std::string myToString(const Rect< RectType > &rectangle)
Converts a Rect<T> object to its string representation.
Definition Rect.hpp:223
std::optional< T > unCast(const std::any &classNode, const bool raiseOnError=true, const std::string customErrorMessage="")
Casts the content of a std::any back to its original type.
Definition UnCast.hpp:65