aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-10-21 14:02:34 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-10-21 14:02:34 +0200
commitfe8f7273f0efdfe319a0d3e3b2fc2847992745af (patch)
tree9f56560c8a35c3e281881fa48cd79b26f8e8de7e
parent4cb7ca42003c177e3acc80075d7594e555966106 (diff)
fix more design
-rw-r--r--Canvas.cpp2
-rw-r--r--CreateArtistTileBehavior.cpp11
-rw-r--r--CreateArtistTileBehavior.h8
-rw-r--r--DeleteArtistTileBehavior.cpp12
-rw-r--r--DeleteArtistTileBehavior.h9
-rw-r--r--NullTileBehavior.cpp10
-rw-r--r--NullTileBehavior.h11
-rw-r--r--SetNeighborTileBehavior.cpp10
-rw-r--r--SetNeighborTileBehavior.h9
-rw-r--r--StepTileBehavior.cpp10
-rw-r--r--StepTileBehavior.h9
-rw-r--r--StepTileCommand.cpp2
-rw-r--r--Tile.cpp6
-rw-r--r--Tile.h1
-rw-r--r--TileBehavior.cpp4
-rw-r--r--TileBehavior.h6
-rw-r--r--TileBehaviorFactory.cpp32
-rw-r--r--TileBehaviorFactory.h13
-rw-r--r--docs/class-diag.puml72
-rw-r--r--docs/style.ipuml2
20 files changed, 82 insertions, 157 deletions
diff --git a/Canvas.cpp b/Canvas.cpp
index 423670d..adfb846 100644
--- a/Canvas.cpp
+++ b/Canvas.cpp
@@ -80,7 +80,7 @@ void Canvas::update_steps() {
if (artist->step == false) continue;
artist->step = false;
- this->get_tile(artist->data.x, artist->data.y).step(artist);
+ this->get_tile(artist->data.x, artist->data.y).behavior->step(artist);
}
}
diff --git a/CreateArtistTileBehavior.cpp b/CreateArtistTileBehavior.cpp
index ae0cd7c..3e0f1c1 100644
--- a/CreateArtistTileBehavior.cpp
+++ b/CreateArtistTileBehavior.cpp
@@ -1,4 +1,3 @@
-#include <memory>
#include <random>
#include "CreateArtistTileBehavior.h"
@@ -12,8 +11,6 @@ using std::random_device;
using std::mt19937;
using namespace std;
-CreateArtistTileBehavior CreateArtistTileBehavior::instance { CreateArtistTileBehavior::type };
-
random_device dev{};
mt19937 rng(dev());
uniform_int_distribution<int> random_bool(0, 1);
@@ -31,16 +28,10 @@ void CreateArtistTileBehavior::update(Tile & tile) {
};
float velocity = random_float(rng);
random_bool(rng) ? new_data.vx = velocity : new_data.vy = velocity;
- this->museum->people.add_artist(new_data);
+ this->museum.people.add_artist(new_data);
}
if (this->interactions < 2) return;
tile.set_type(StepTileBehavior::type);
}
-unique_ptr<TileBehavior> CreateArtistTileBehavior::clone(Museum & museum) {
- auto instance = new CreateArtistTileBehavior();
- instance->museum = &museum;
- return unique_ptr<TileBehavior>(instance);
-}
-
diff --git a/CreateArtistTileBehavior.h b/CreateArtistTileBehavior.h
index 6abd67f..41b3e12 100644
--- a/CreateArtistTileBehavior.h
+++ b/CreateArtistTileBehavior.h
@@ -3,17 +3,15 @@
#include "TileBehavior.h"
class CreateArtistTileBehavior : public TileBehavior {
+ friend class TileBehaviorFactory;
+ using TileBehavior::TileBehavior;
+
public:
virtual void update(Tile &);
- virtual std::unique_ptr<TileBehavior> clone(Museum &);
static constexpr const char * type = "Y";
private:
- using TileBehavior::TileBehavior;
- static CreateArtistTileBehavior instance;
- CreateArtistTileBehavior() = default;
-
unsigned int last_interactions = 0;
};
diff --git a/DeleteArtistTileBehavior.cpp b/DeleteArtistTileBehavior.cpp
index 091a251..71cc20e 100644
--- a/DeleteArtistTileBehavior.cpp
+++ b/DeleteArtistTileBehavior.cpp
@@ -1,5 +1,3 @@
-#include <memory>
-
#include "DeleteArtistTileBehavior.h"
#include "SetNeighborTileBehavior.h"
#include "Tile.h"
@@ -7,12 +5,10 @@
using namespace std;
-DeleteArtistTileBehavior DeleteArtistTileBehavior::instance { DeleteArtistTileBehavior::type };
-
void DeleteArtistTileBehavior::step(Artist * artist) {
this->interactions++;
if (artist != nullptr)
- this->museum->people.remove_artist(*artist);
+ this->museum.people.remove_artist(*artist);
}
void DeleteArtistTileBehavior::update(Tile & tile) {
@@ -20,9 +16,3 @@ void DeleteArtistTileBehavior::update(Tile & tile) {
tile.set_type(SetNeighborTileBehavior::type);
}
-unique_ptr<TileBehavior> DeleteArtistTileBehavior::clone(Museum & museum) {
- auto instance = new DeleteArtistTileBehavior();
- instance->museum = &museum;
- return unique_ptr<TileBehavior>(instance);
-}
-
diff --git a/DeleteArtistTileBehavior.h b/DeleteArtistTileBehavior.h
index 0b2b0d4..9454864 100644
--- a/DeleteArtistTileBehavior.h
+++ b/DeleteArtistTileBehavior.h
@@ -3,17 +3,14 @@
#include "TileBehavior.h"
class DeleteArtistTileBehavior : public TileBehavior {
+ friend class TileBehaviorFactory;
+ using TileBehavior::TileBehavior;
+
public:
virtual void step(Artist *);
virtual void update(Tile &);
- virtual std::unique_ptr<TileBehavior> clone(Museum &);
static constexpr const char * type = "R";
-
-private:
- using TileBehavior::TileBehavior;
- static DeleteArtistTileBehavior instance;
- DeleteArtistTileBehavior() = default;
};
diff --git a/NullTileBehavior.cpp b/NullTileBehavior.cpp
index 7a056a4..c5a35d9 100644
--- a/NullTileBehavior.cpp
+++ b/NullTileBehavior.cpp
@@ -1,16 +1,6 @@
-#include <memory>
-
#include "NullTileBehavior.h"
using namespace std;
-NullTileBehavior NullTileBehavior::instance { NullTileBehavior::type };
-
void NullTileBehavior::update(Tile &) { }
-unique_ptr<TileBehavior> NullTileBehavior::clone(Museum & museum) {
- auto instance = new NullTileBehavior();
- instance->museum = &museum;
- return unique_ptr<TileBehavior>(instance);
-}
-
diff --git a/NullTileBehavior.h b/NullTileBehavior.h
index 72aa196..004b256 100644
--- a/NullTileBehavior.h
+++ b/NullTileBehavior.h
@@ -3,15 +3,10 @@
#include "TileBehavior.h"
class NullTileBehavior : public TileBehavior {
+ friend class TileBehaviorFactory;
+ using TileBehavior::TileBehavior;
+
public:
virtual void update(Tile &);
- virtual std::unique_ptr<TileBehavior> clone(Museum &);
-
- static constexpr const char * type = "";
-
-private:
- using TileBehavior::TileBehavior;
- static NullTileBehavior instance;
- NullTileBehavior() = default;
};
diff --git a/SetNeighborTileBehavior.cpp b/SetNeighborTileBehavior.cpp
index d934d4b..d56fa0b 100644
--- a/SetNeighborTileBehavior.cpp
+++ b/SetNeighborTileBehavior.cpp
@@ -1,5 +1,3 @@
-#include <memory>
-
#include "SetNeighborTileBehavior.h"
#include "CreateArtistTileBehavior.h"
#include "Artist.h"
@@ -7,8 +5,6 @@
using namespace std;
-SetNeighborTileBehavior SetNeighborTileBehavior::instance { SetNeighborTileBehavior::type };
-
void SetNeighborTileBehavior::step(Artist * artist) {
this->interactions++;
if (dx != 0 || dy != 0) return;
@@ -36,9 +32,3 @@ void SetNeighborTileBehavior::update(Tile & tile) {
tile.set_type(CreateArtistTileBehavior::type);
}
-unique_ptr<TileBehavior> SetNeighborTileBehavior::clone(Museum & museum) {
- auto instance = new SetNeighborTileBehavior();
- instance->museum = &museum;
- return unique_ptr<TileBehavior>(instance);
-}
-
diff --git a/SetNeighborTileBehavior.h b/SetNeighborTileBehavior.h
index d316420..53bfbc0 100644
--- a/SetNeighborTileBehavior.h
+++ b/SetNeighborTileBehavior.h
@@ -3,19 +3,16 @@
#include "TileBehavior.h"
class SetNeighborTileBehavior : public TileBehavior {
+ friend class TileBehaviorFactory;
+ using TileBehavior::TileBehavior;
+
public:
virtual void step(Artist *);
virtual void update(Tile &);
- virtual std::unique_ptr<TileBehavior> clone(Museum &);
static constexpr const char * type = "B";
private:
- using TileBehavior::TileBehavior;
- static SetNeighborTileBehavior instance;
- SetNeighborTileBehavior() = default;
-
-private:
int dx = 0;
int dy = 0;
};
diff --git a/StepTileBehavior.cpp b/StepTileBehavior.cpp
index 2023bb8..ff1217e 100644
--- a/StepTileBehavior.cpp
+++ b/StepTileBehavior.cpp
@@ -1,21 +1,11 @@
-#include <memory>
-
#include "StepTileBehavior.h"
#include "DeleteArtistTileBehavior.h"
#include "Tile.h"
using namespace std;
-StepTileBehavior StepTileBehavior::instance { StepTileBehavior::type };
-
void StepTileBehavior::update(Tile & tile) {
if (this->interactions < 3) return;
tile.set_type(DeleteArtistTileBehavior::type);
}
-unique_ptr<TileBehavior> StepTileBehavior::clone(Museum & museum) {
- auto instance = new StepTileBehavior();
- instance->museum = &museum;
- return unique_ptr<TileBehavior>(instance);
-}
-
diff --git a/StepTileBehavior.h b/StepTileBehavior.h
index d044fe7..856760f 100644
--- a/StepTileBehavior.h
+++ b/StepTileBehavior.h
@@ -3,15 +3,12 @@
#include "TileBehavior.h"
class StepTileBehavior : public TileBehavior {
+ friend class TileBehaviorFactory;
+ using TileBehavior::TileBehavior;
+
public:
virtual void update(Tile &);
- virtual std::unique_ptr<TileBehavior> clone(Museum &);
static constexpr const char * type = "G";
-
-private:
- using TileBehavior::TileBehavior;
- static StepTileBehavior instance;
- StepTileBehavior() = default;
};
diff --git a/StepTileCommand.cpp b/StepTileCommand.cpp
index cc7d62d..bac9f5d 100644
--- a/StepTileCommand.cpp
+++ b/StepTileCommand.cpp
@@ -13,7 +13,7 @@ void StepTileCommand::execute() {
if (this->x >= canvas.data.columns) return;
if (this->y >= canvas.data.rows) return;
Tile & tile = canvas.get_tile(this->x, this->y);
- tile.step(nullptr);
+ tile.behavior->step(nullptr);
tile.update();
}
diff --git a/Tile.cpp b/Tile.cpp
index f4fa623..5172c24 100644
--- a/Tile.cpp
+++ b/Tile.cpp
@@ -19,17 +19,13 @@ void Tile::set_type(const string & type) {
void Tile::set_data(TileData & data) {
this->data = data;
this->color = TileColorFactory::get_color(this->data.type);
- this->behavior = TileBehaviorFactory::get_strategy(this->data.type).clone(this->museum);
+ this->behavior = TileBehaviorFactory(this->museum).create(this->data.type);
}
void Tile::update() {
this->behavior->update(*this);
}
-void Tile::step(Artist * artist) {
- this->behavior->step(artist);
-}
-
Tile * Tile::get_neighbor(int dx, int dy) {
Canvas & canvas = this->museum.canvas;
int x = this->data.x + dx;
diff --git a/Tile.h b/Tile.h
index 00da207..ccf8d3b 100644
--- a/Tile.h
+++ b/Tile.h
@@ -21,7 +21,6 @@ public:
void set_data(TileData & data);
void set_type(const std::string & type);
void update();
- void step(Artist *);
Tile * get_neighbor(int dx, int dy);
private:
diff --git a/TileBehavior.cpp b/TileBehavior.cpp
index 9de896e..cf1915a 100644
--- a/TileBehavior.cpp
+++ b/TileBehavior.cpp
@@ -1,8 +1,6 @@
-#include "TileBehaviorFactory.h"
#include "TileBehavior.h"
-TileBehavior::TileBehavior(const std::string type) {
- TileBehaviorFactory::register_strategy(type, this);
+TileBehavior::TileBehavior(Museum & m) : museum(m) {
}
void TileBehavior::step(Artist *) {
diff --git a/TileBehavior.h b/TileBehavior.h
index b79e7f5..c6e6859 100644
--- a/TileBehavior.h
+++ b/TileBehavior.h
@@ -11,14 +11,12 @@ class TileBehavior {
public:
virtual void step(Artist *);
virtual void update(Tile &) = 0;
- virtual std::unique_ptr<TileBehavior> clone(Museum & m) = 0;
protected:
- TileBehavior(const std::string type);
- TileBehavior() = default;
+ TileBehavior(Museum &);
protected:
unsigned int interactions = 0;
- Museum * museum = nullptr;
+ Museum & museum;
};
diff --git a/TileBehaviorFactory.cpp b/TileBehaviorFactory.cpp
index 99301ac..b795578 100644
--- a/TileBehaviorFactory.cpp
+++ b/TileBehaviorFactory.cpp
@@ -1,20 +1,30 @@
+#include <memory>
+
#include "TileBehaviorFactory.h"
-#include "Exception.h"
+#include "CreateArtistTileBehavior.h"
+#include "DeleteArtistTileBehavior.h"
+#include "NullTileBehavior.h"
+#include "SetNeighborTileBehavior.h"
+#include "StepTileBehavior.h"
using namespace std;
-TileBehavior & TileBehaviorFactory::get_strategy(string type) {
- auto & type_map = TileBehaviorFactory::get_collection();
+TileBehaviorFactory::TileBehaviorFactory(Museum & m) : museum(m) {};
- if (type_map.contains(type))
- return *type_map.at(type);
-
- throw Exception("unknown behavior for tile type \"%s\"", type.c_str());
-}
+unique_ptr<TileBehavior> TileBehaviorFactory::create(string type) {
+ TileBehavior * out = nullptr;
-void TileBehaviorFactory::register_strategy(string type, TileBehavior * strategy) {
- auto & type_map = TileBehaviorFactory::get_collection();
+ if (type == SetNeighborTileBehavior::type)
+ out = new SetNeighborTileBehavior(this->museum);
+ else if (type == CreateArtistTileBehavior::type)
+ out = new CreateArtistTileBehavior(this->museum);
+ else if (type == StepTileBehavior::type)
+ out = new StepTileBehavior(this->museum);
+ else if (type == DeleteArtistTileBehavior::type)
+ out = new DeleteArtistTileBehavior(this->museum);
- type_map[type] = strategy;
+ if (out == nullptr)
+ out = new NullTileBehavior(this->museum);
+ return unique_ptr<TileBehavior>(out);
}
diff --git a/TileBehaviorFactory.h b/TileBehaviorFactory.h
index 33cd795..6167067 100644
--- a/TileBehaviorFactory.h
+++ b/TileBehaviorFactory.h
@@ -1,21 +1,16 @@
#pragma once
-#include <map>
#include <string>
+#include "Museum.h"
#include "TileBehavior.h"
class TileBehaviorFactory {
- typedef std::map<std::string, TileBehavior *> TileBehaviorCollection;
-
public:
- static TileBehavior & get_strategy(std::string);
- static void register_strategy(std::string, TileBehavior *);
+ TileBehaviorFactory(Museum & m);
+ std::unique_ptr<TileBehavior> create(std::string);
private:
- static TileBehaviorCollection & get_collection() {
- static TileBehaviorCollection c = {};
- return c;
- }
+ Museum & museum;
};
diff --git a/docs/class-diag.puml b/docs/class-diag.puml
index 56a334f..273e9f1 100644
--- a/docs/class-diag.puml
+++ b/docs/class-diag.puml
@@ -17,10 +17,9 @@ exception Exception {
# va_format(va_list args, const char* fmt)
}
-together { /' LAYOUT '/
rectangle Group_FileReading as "File reading" <<group>> {
class FileReaderFactory <<Factory>> {
- +open(url) : FileReader&
+ + open(url) : FileReader&
}
interface FileReader {
+ read() : string
@@ -92,9 +91,7 @@ rectangle Group_ParsingDeserialization as "Parsing & deserialization" <<group>>
CSVParser -r[hidden] TXTParser
TXTParser -r[hidden] XMLParser
}
-} /' LAYOUT '/
-together { /' LAYOUT '/
rectangle Group_Algorithms as "Algorithms" <<group>> {
class Pathfinding {
+ Pathfinding(Museum &)
@@ -149,7 +146,6 @@ rectangle Group_Model as "Model" <<group>> {
+ set_data(TileData &)
+ set_type(type : const string &)
+ update()
- + step(Artist *)
+ get_neighbor(dx, dy) : Tile *
--
- museum : Museum &
@@ -179,52 +175,31 @@ rectangle Group_Model as "Model" <<group>> {
+ columns : unsigned int
}
- Museum --> People
- Museum --> Canvas
-
- Canvas --> Tile
- People --> Artist
-
- Tile -> TileData
- Artist -l> ArtistData
- Canvas -> CanvasData
-
- ' LAYOUT
- Artist -r[hidden] Tile
-}
-rectangle Group_TileAppearance as "Tile appearance" <<group>> {
struct Color {
red : unsigned int
green : unsigned int
blue : unsigned int
}
- class TileColorFactory {
+ class TileColorFactory <<singleton>> {
+ get_color(string) : Color <<static>>
+ register_color(string, Color) <<static>>
}
- Tile --> Color
-
- Color <.. TileColorFactory
-}
-rectangle Group_TileBehavior as "Tile behavior" <<group>> {
interface TileBehavior {
+ step(Artist *)
+ update(Tile &)
- + clone(Museum &) : uniq<TileBehavior>
--
- # TileBehavior(type : string)
- # TileBehavior()
+ # TileBehavior(Museum &)
--
# interactions : unsigned int
- # museum : Museum *
+ # museum : Museum &
}
class TileBehaviorFactory {
- + get_strategy(string) : TileBehavior & <<static>>
- + register_strategy(string, TileBehavior *) <<static>>
+ + TileBehaviorFactory(Museum &)
+ + create(string) : uniq<TileBehavior>
--
- - get_collection() : TileBehaviorCollection & <<static>>
+ - museum : Museum &
}
together {
@@ -250,18 +225,42 @@ rectangle Group_TileBehavior as "Tile behavior" <<group>> {
}
}
+ Museum --> People
+ Museum --> Canvas
+
+ Canvas --> Tile
+ People --> Artist
+
+ Tile -> TileData
+ Artist -l> ArtistData
+ Canvas -> CanvasData
+
+ Tile --> "state" Color
+ Tile .[norank].> TileColorFactory
+
+ TileColorFactory .> Color
+
TileBehavior <|.. NullTileBehavior
TileBehavior <|.. StepTileBehavior
TileBehavior <|.. DeleteArtistTileBehavior
TileBehavior <|.. SetNeighborTileBehavior
TileBehavior <|.. CreateArtistTileBehavior
- Tile --> "state" TileBehaviorFactory
+ TileBehaviorFactory --> NullTileBehavior
+ TileBehaviorFactory --> StepTileBehavior
+ TileBehaviorFactory --> DeleteArtistTileBehavior
+ TileBehaviorFactory --> SetNeighborTileBehavior
+ TileBehaviorFactory --> CreateArtistTileBehavior
+
+ Tile --> "state" TileBehavior
+ Tile .[norank].> TileBehaviorFactory
TileBehaviorFactory .l> TileBehavior
TileBehaviorFactory <. TileBehavior
+
+ ' LAYOUT
+ Artist -r[hidden] Tile
}
-} /' LAYOUT '/
together { /' LAYOUT '/
rectangle Group_Visualization as "Visualization" <<group>> {
@@ -372,10 +371,5 @@ main -u-> LoadFilesCommand
main -[norank]> View
main .r> Exception
-' LAYOUT
-Group_TileBehavior -r[hidden] Group_TileAppearance
-Group_ParsingDeserialization -r[hidden] Group_Model
-' Collision -r[hidden] People
-
@enduml
diff --git a/docs/style.ipuml b/docs/style.ipuml
index ca4ece7..9fc8fc2 100644
--- a/docs/style.ipuml
+++ b/docs/style.ipuml
@@ -7,7 +7,7 @@ skinparam ClassFontStyle bold
skinparam DefaultFontName Inter
skinparam DefaultFontSize 10
skinparam MaxMessageSize 200
-skinparam Ranksep 25
+skinparam Ranksep 35
skinparam RoundCorner 0
skinparam PackageStyle rectangle
skinparam PackageFontStyle italic