diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-10-21 14:02:34 +0200 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-10-21 14:02:34 +0200 |
commit | fe8f7273f0efdfe319a0d3e3b2fc2847992745af (patch) | |
tree | 9f56560c8a35c3e281881fa48cd79b26f8e8de7e | |
parent | 4cb7ca42003c177e3acc80075d7594e555966106 (diff) |
fix more design
-rw-r--r-- | Canvas.cpp | 2 | ||||
-rw-r--r-- | CreateArtistTileBehavior.cpp | 11 | ||||
-rw-r--r-- | CreateArtistTileBehavior.h | 8 | ||||
-rw-r--r-- | DeleteArtistTileBehavior.cpp | 12 | ||||
-rw-r--r-- | DeleteArtistTileBehavior.h | 9 | ||||
-rw-r--r-- | NullTileBehavior.cpp | 10 | ||||
-rw-r--r-- | NullTileBehavior.h | 11 | ||||
-rw-r--r-- | SetNeighborTileBehavior.cpp | 10 | ||||
-rw-r--r-- | SetNeighborTileBehavior.h | 9 | ||||
-rw-r--r-- | StepTileBehavior.cpp | 10 | ||||
-rw-r--r-- | StepTileBehavior.h | 9 | ||||
-rw-r--r-- | StepTileCommand.cpp | 2 | ||||
-rw-r--r-- | Tile.cpp | 6 | ||||
-rw-r--r-- | Tile.h | 1 | ||||
-rw-r--r-- | TileBehavior.cpp | 4 | ||||
-rw-r--r-- | TileBehavior.h | 6 | ||||
-rw-r--r-- | TileBehaviorFactory.cpp | 32 | ||||
-rw-r--r-- | TileBehaviorFactory.h | 13 | ||||
-rw-r--r-- | docs/class-diag.puml | 72 | ||||
-rw-r--r-- | docs/style.ipuml | 2 |
20 files changed, 82 insertions, 157 deletions
@@ -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(); } @@ -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; @@ -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 |