Skip to content

Commit 1791ea2

Browse files
authored
Merge pull request #7 from stevenewald/refactor
Refactor into observer pattern
2 parents 2bb27f3 + 2fb74f5 commit 1791ea2

19 files changed

+465
-264
lines changed

CMakeLists.txt

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ include(cmake/variables.cmake)
1717

1818
add_library(
1919
fractal-generator_lib OBJECT
20-
source/graphics/basic_display.cpp
21-
source/graphics/color_conversions.cpp
20+
source/graphics/display/display.cpp
21+
source/graphics/selection_window/selection_window.cpp
22+
source/mandelbrot/mandelbrot_window.cpp
23+
source/graphics/color_conversions/color_conversions.cpp
24+
source/graphics/aspect_ratio/aspect_ratio.cpp
2225
)
2326

2427
target_include_directories(

source/config.hpp

+17
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
11
#pragma once
22

3+
#include "coordinates.hpp"
4+
#include "units.hpp"
5+
36
#include <cstddef>
47

58
namespace fractal {
9+
610
constexpr std::size_t WINDOW_WIDTH = 800UZ;
711
constexpr std::size_t WINDOW_HEIGHT = 600UZ;
812
constexpr std::size_t FRAME_RATE = 60UZ;
13+
14+
constexpr display_domain DISPLAY_DOMAIN{
15+
{0, 0 },
16+
{WINDOW_WIDTH - 1, WINDOW_HEIGHT - 1}
17+
};
18+
19+
constexpr complex_domain START_COMPLEX_DOMAIN{
20+
{complex_underlying{-2}, complex_underlying{-1.5}},
21+
{complex_underlying{1}, complex_underlying{1.5} }
22+
};
23+
24+
const complex_underlying MANDELBROT_DIVERGENCE_NORM = 4;
25+
const iteration_count MANDELBROT_MAX_ITERATIONS = 256;
926
} // namespace fractal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "aspect_ratio.hpp"
2+
3+
namespace fractal {
4+
5+
display_coordinate calculate_rectangle_end_point(
6+
display_coordinate start, display_coordinate current, float target_aspect_ratio
7+
)
8+
{
9+
auto width = static_cast<float>(std::abs(current.first - start.first));
10+
auto height = static_cast<float>(std::abs(current.second - start.second));
11+
12+
// Adjust the dimensions to maintain the target aspect ratio
13+
if (width / height > target_aspect_ratio) {
14+
// Too wide, adjust width
15+
width = height * target_aspect_ratio;
16+
}
17+
else {
18+
// Too tall, adjust height
19+
height = width / target_aspect_ratio;
20+
}
21+
22+
auto x = static_cast<float>(std::min(current.first, start.first));
23+
auto y = static_cast<float>(std::min(current.second, start.second));
24+
25+
// Adjust the top-left corner based on new dimensions
26+
if (current.first < start.first) {
27+
x = static_cast<float>(start.first) - width;
28+
}
29+
if (current.second < start.second) {
30+
y = static_cast<float>(start.second) - height;
31+
}
32+
33+
// Return the top-left and bottom-right corners as a pair of sf::Vector2f
34+
return {x + width, y + height};
35+
}
36+
} // namespace fractal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
#include "coordinates.hpp"
4+
5+
namespace fractal {
6+
display_coordinate calculate_rectangle_end_point(
7+
display_coordinate start, display_coordinate current,
8+
float target_aspect_ratio = 800.0f / 600.0f
9+
);
10+
} // namespace fractal

source/graphics/basic_display.cpp

-127
This file was deleted.

source/graphics/basic_display.hpp

-34
This file was deleted.

source/graphics/color_conversions.hpp

-12
This file was deleted.

source/graphics/color_conversions.cpp source/graphics/color_conversions/color_conversions.cpp

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
#include "color_conversions.hpp"
22

3+
#include <fmt/format.h>
4+
35
#include <cmath>
46

7+
#include <stdexcept>
8+
59
namespace fractal {
6-
std::tuple<uint16_t, uint16_t, uint16_t>
7-
hsv_to_rgb(float hue, float saturation, float value)
10+
color hsv_to_rgb(float hue, float saturation, float value)
811
{
912
float chroma = value * saturation;
1013
float hue_prime = hue / 60.0f;
@@ -50,16 +53,20 @@ hsv_to_rgb(float hue, float saturation, float value)
5053
float green = green_temp + match_value;
5154
float blue = blue_temp + match_value;
5255

53-
auto red_int = static_cast<uint16_t>(red * 255);
54-
auto green_int = static_cast<uint16_t>(green * 255);
55-
auto blue_int = static_cast<uint16_t>(blue * 255);
56+
auto red_int = static_cast<uint8_t>(red * 255);
57+
auto green_int = static_cast<uint8_t>(green * 255);
58+
auto blue_int = static_cast<uint8_t>(blue * 255);
5659

5760
return {red_int, green_int, blue_int};
5861
}
5962

60-
std::tuple<uint16_t, uint16_t, uint16_t> number_to_rgb(uint16_t number)
63+
color ratio_to_rgb(float ratio)
6164
{
62-
float hue = (static_cast<float>(number) / 65535.0f) * 360.0f;
65+
if (ratio < 0 || ratio > 1) [[unlikely]] {
66+
throw std::out_of_range(fmt::format("Ratio out of range: {}", ratio));
67+
}
68+
69+
float hue = ratio * 360.0f;
6370
float saturation = 1.0f;
6471
float value = 1.0f;
6572

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include "units.hpp"
4+
5+
namespace fractal {
6+
color hsv_to_rgb(float hue, float saturation, float value);
7+
8+
color ratio_to_rgb(float ratio);
9+
} // namespace fractal

source/graphics/display/display.cpp

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "display.hpp"
2+
3+
#include <fmt/format.h>
4+
5+
#include <cmath>
6+
7+
namespace fractal {
8+
PixelDisplay::PixelDisplay()
9+
{
10+
window_.clear(sf::Color::Black);
11+
window_.setFramerateLimit(FRAME_RATE);
12+
window_.display();
13+
}
14+
15+
void PixelDisplay::handle_event_(const sf::Event& event)
16+
{
17+
switch (event.type) {
18+
case sf::Event::MouseMoved:
19+
for (const auto& observer : observers_) {
20+
observer->on_mouse_moved(event.mouseMove);
21+
}
22+
return;
23+
case sf::Event::MouseButtonPressed:
24+
std::for_each(
25+
observers_.begin(), observers_.end(),
26+
[&](const auto& observer) {
27+
observer->on_mouse_button_pressed(event.mouseButton);
28+
}
29+
);
30+
return;
31+
case sf::Event::MouseButtonReleased:
32+
std::for_each(
33+
observers_.begin(), observers_.end(),
34+
[&](const auto& observer) {
35+
observer->on_mouse_button_released(event.mouseButton);
36+
}
37+
);
38+
return;
39+
default:
40+
return;
41+
}
42+
}
43+
44+
void PixelDisplay::add_observer(std::unique_ptr<DisplayEventObserver> observer)
45+
{
46+
observers_.push_back(std::move(observer));
47+
}
48+
49+
void PixelDisplay::poll_window_events()
50+
{
51+
sf::Event event{};
52+
while (window_.pollEvent(event)) {
53+
handle_event_(event);
54+
}
55+
}
56+
57+
void PixelDisplay::display_window()
58+
{
59+
auto draw_from_observer = [this](const auto& observer) {
60+
if (auto opt = observer->get_drawable(); opt) {
61+
window_.draw(*(opt.value()));
62+
}
63+
};
64+
65+
window_.clear(sf::Color::Black);
66+
std::for_each(observers_.begin(), observers_.end(), draw_from_observer);
67+
window_.display();
68+
}
69+
} // namespace fractal

0 commit comments

Comments
 (0)