-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdrawing.h
115 lines (92 loc) · 3.23 KB
/
drawing.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#pragma once
#ifndef ASSIGNMENT_DRAWING_H
#define ASSIGNMENT_DRAWING_H
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <vector>
using namespace std;
namespace drawing {
struct Pixel {
size_t X, Y;
int Colour;
};
class Shape;
class Observer {
public:
virtual ~Observer() = default;
/**
* Notifies the observer of a shape change.
* @param shape The shape instance that has been changed.
* @param refresh True if the change is supposed to produce immediate effect; false otherwise.
*/
virtual void Update(Shape& shape, bool refresh) = 0;
/**
* Notifies deleted shape to the observer.
* @param shape The shape instance that has been deleted.
* @param refresh True if the shape removal is supposed to produce immediate effect; false otherwise.
*/
virtual void Delete(Shape& shape, bool refresh) = 0;
};
class Shape {
vector<Observer*> observers;
protected:
int colour;
bool selected;
friend void swap(Shape& first, Shape& second);
explicit Shape(const int& colour, const bool& selected = true) noexcept;
Shape() noexcept: colour{}, selected{} { };
Shape(const Shape& other) noexcept;
inline Shape(Shape&& other) noexcept: Shape() {
swap(*this, other);
}
void Notify();
public:
virtual ~Shape() noexcept;
[[nodiscard]] virtual unique_ptr<Shape> Clone() const = 0;
[[nodiscard]] virtual vector<Pixel> GetPixels() const = 0;
void Attach(Observer& observer);
uint Detach(const Observer& observer, bool all = false);
[[nodiscard]] bool Selected() const;
bool Selected(bool value);
[[nodiscard]] int Colour() const;
int Colour(int value);
};
class Canvas final : public Observer {
bool paused;
mutex mtx;
int* canvas;
size_t height, width, length;
unique_ptr<int[]> buffer;
map<Shape* const, unique_ptr<Shape>> shapes;
friend void swap(Canvas& first, Canvas& second);
Canvas() noexcept: paused{}, canvas{nullptr}, height{}, width{}, length{} { };
public:
Canvas(int* array, const size_t& width, const size_t& height, const set<Shape*>& shapes = {}, const bool& paused = false) noexcept(false);
inline Canvas(Canvas&& other) noexcept: Canvas() {
swap(*this, other);
}
inline Canvas& operator=(Canvas other) {
swap(*this, other);
return *this;
}
~Canvas() noexcept override;
/**
* If not in batch update mode, refreshes the underlying 2D array with the canvas' contents.
* @param force True to ignore batch update mode and force refresh; false otherwise.
*/
void Refresh(const bool& force = false);
void Update(Shape& shape, bool refresh) override;
void Delete(Shape& shape, bool refresh) override;
/**
* Enter the batch update mode.
*/
void Pause();
/**
* Complete and quit the batch update mode.
*/
void Resume();
};
}
#endif //ASSIGNMENT_DRAWING_H