aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--CSVParser.cpp14
-rw-r--r--CSVParser.h10
-rw-r--r--LoadFilesCommand.cpp12
-rw-r--r--Parser.cpp13
-rw-r--r--Parser.h12
-rw-r--r--ParserFactory.cpp35
-rw-r--r--ParserFactory.h14
-rw-r--r--TXTParser.cpp10
-rw-r--r--TXTParser.h10
-rw-r--r--XMLParser.cpp15
-rw-r--r--XMLParser.h10
-rw-r--r--docs/class-diag.puml53
13 files changed, 108 insertions, 103 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 15f889b..cf2f157 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,10 +23,11 @@ add_executable(main
Exception.cpp
FileReaderFactory.cpp
Canvas.cpp
+ Parser.cpp
ParserFactory.cpp
CSVParser.cpp
XMLParser.cpp
- # TXTParser.cpp
+ TXTParser.cpp
MuseumDeserializer.cpp
Tile.cpp
TileColorFactory.cpp
diff --git a/CSVParser.cpp b/CSVParser.cpp
index 824d5f4..8afce80 100644
--- a/CSVParser.cpp
+++ b/CSVParser.cpp
@@ -6,17 +6,11 @@
#include "CSVParser.h"
#include "Exception.h"
-#include "ParserFactory.h"
using namespace std;
-CSVParser CSVParser::instance {};
-CSVParser::CSVParser() {
- ParserFactory::register_strategy(this);
-}
-
-unsigned int CSVParser::heuristic(FileReader & f) {
- const string content = f.read();
+unsigned int CSVParser::heuristic() {
+ const string content = this->get_file().read();
int global_columns = 0;
int columns = 1;
int rows = 0;
@@ -41,10 +35,10 @@ static size_t header_idx(vector<string> header, string field) {
return iter - header.begin();
}
-void CSVParser::parse(FileReader & f, MuseumDeserializer & d) {
+void CSVParser::parse(MuseumDeserializer & d) {
vector<vector<string>> table = {};
- istringstream rows(f.read());
+ istringstream rows(this->get_file().read());
string row;
while (getline(rows, row)) {
// ignore windows line endings
diff --git a/CSVParser.h b/CSVParser.h
index 660cc18..2e3231b 100644
--- a/CSVParser.h
+++ b/CSVParser.h
@@ -3,12 +3,10 @@
#include "Parser.h"
class CSVParser : public Parser {
-public:
- virtual void parse(FileReader & f, MuseumDeserializer & d);
- virtual unsigned int heuristic(FileReader & f);
+ friend class ParserFactory;
-private:
- static CSVParser instance;
- CSVParser();
+public:
+ virtual void parse(MuseumDeserializer & d);
+ virtual unsigned int heuristic();
};
diff --git a/LoadFilesCommand.cpp b/LoadFilesCommand.cpp
index 3fb4978..76cd197 100644
--- a/LoadFilesCommand.cpp
+++ b/LoadFilesCommand.cpp
@@ -1,3 +1,4 @@
+#include <memory>
#include <vector>
#include <string>
@@ -27,12 +28,15 @@ void LoadFilesCommand::load_files() {
ToggleMuseumPauseCommand(this->museum, true).execute();
MuseumDeserializer deserializer { this->museum };
+ ParserFactory factory {};
+
for (string url : files) {
- unique_ptr<FileReader> file = FileReaderFactory().create(url);
try {
- ParserFactory::parse(*file, deserializer);
+ unique_ptr<FileReader> file = FileReaderFactory().create(url);
+ Parser & parser = factory.get_parser(*file);
+ parser.parse(deserializer);
} catch (Exception & e) {
- throw Exception("parser error: %s (%s)", e.what(), url.c_str());
+ throw Exception("%s (%s)", e.what(), url.c_str());
}
}
}
@@ -41,7 +45,7 @@ void LoadFilesCommand::execute() {
try {
this->load_files();
} catch (Exception & e) {
- throw Exception("LoadFilesCommand error: %s", e.what());
+ throw Exception("LoadFilesCommand: %s", e.what());
}
}
diff --git a/Parser.cpp b/Parser.cpp
new file mode 100644
index 0000000..9b07089
--- /dev/null
+++ b/Parser.cpp
@@ -0,0 +1,13 @@
+#include "Parser.h"
+#include "Exception.h"
+
+void Parser::set_file(FileReader & file) {
+ this->file = &file;
+}
+
+FileReader & Parser::get_file() {
+ if (this->file == nullptr)
+ throw Exception("Parser: no file to read");
+ return *this->file;
+}
+
diff --git a/Parser.h b/Parser.h
index 01efb3c..c6a2cf1 100644
--- a/Parser.h
+++ b/Parser.h
@@ -5,7 +5,15 @@
class Parser {
public:
- virtual void parse(FileReader & f, MuseumDeserializer & d) = 0;
- virtual unsigned int heuristic(FileReader & f) = 0;
+ virtual void parse(MuseumDeserializer & d) = 0;
+ virtual unsigned int heuristic() = 0;
+
+protected:
+ friend class ParserFactory;
+ void set_file(FileReader & f);
+ FileReader & get_file();
+
+private:
+ FileReader * file = nullptr;
};
diff --git a/ParserFactory.cpp b/ParserFactory.cpp
index 49c4d00..53bfbc5 100644
--- a/ParserFactory.cpp
+++ b/ParserFactory.cpp
@@ -1,32 +1,33 @@
-#include <algorithm>
-
#include "ParserFactory.h"
#include "Exception.h"
-void ParserFactory::parse(FileReader & file, MuseumDeserializer & deserializer) {
- auto & col = ParserFactory::get_collection();
- if (col.size() < 1)
- throw Exception("no parsers registered");
+#include "XMLParser.h"
+#include "TXTParser.h"
+#include "CSVParser.h"
+
+using namespace std;
+
+ParserFactory::ParserFactory() {
+ this->parsers.push_back(unique_ptr<Parser>(new XMLParser()));
+ this->parsers.push_back(unique_ptr<Parser>(new TXTParser()));
+ this->parsers.push_back(unique_ptr<Parser>(new CSVParser()));
+}
+Parser & ParserFactory::get_parser(FileReader & file) {
unsigned int best_score = 0;
Parser * best_strategy = nullptr;
- for (Parser * strategy : col) {
- unsigned int score = strategy->heuristic(file);
+ for (auto & parser : this->parsers) {
+ parser->set_file(file);
+ unsigned int score = parser->heuristic();
if (score <= best_score) continue;
best_score = score;
- best_strategy = strategy;
+ best_strategy = parser.get();
}
if (best_strategy == nullptr)
- throw Exception("unknown file type");
-
- best_strategy->parse(file, deserializer);
-}
+ throw Exception("ParserFactory: unknown file type");
-void ParserFactory::register_strategy(Parser * ps) {
- auto & col = ParserFactory::get_collection();
- if (std::find(col.begin(), col.end(), ps) != col.end()) return;
- col.push_back(ps);
+ return *best_strategy;
}
diff --git a/ParserFactory.h b/ParserFactory.h
index 5430366..cb8cb99 100644
--- a/ParserFactory.h
+++ b/ParserFactory.h
@@ -1,20 +1,16 @@
#pragma once
+#include <memory>
+
#include "FileReader.h"
-#include "MuseumDeserializer.h"
#include "Parser.h"
class ParserFactory {
- typedef std::vector<Parser*> ParserCollection;
-
public:
- static void parse(FileReader & f, MuseumDeserializer & d);
- static void register_strategy(Parser * p);
+ ParserFactory();
+ Parser & get_parser(FileReader & f);
private:
- static ParserCollection & get_collection() {
- static ParserCollection c = {};
- return c;
- }
+ std::vector<std::unique_ptr<Parser>> parsers;
};
diff --git a/TXTParser.cpp b/TXTParser.cpp
index e19f343..17890e0 100644
--- a/TXTParser.cpp
+++ b/TXTParser.cpp
@@ -1,16 +1,10 @@
#include "TXTParser.h"
-#include "ParserFactory.h"
-TXTParser TXTParser::instance {};
-TXTParser::TXTParser() {
- ParserFactory::register_strategy(this);
-}
-
-unsigned int TXTParser::heuristic(FileReader & f) {
+unsigned int TXTParser::heuristic() {
return 0;
}
-void TXTParser::parse(FileReader & f, MuseumDeserializer & d) {
+void TXTParser::parse(MuseumDeserializer & d) {
printf("%s\n", __PRETTY_FUNCTION__);
}
diff --git a/TXTParser.h b/TXTParser.h
index 064a0cf..cfb485a 100644
--- a/TXTParser.h
+++ b/TXTParser.h
@@ -3,12 +3,10 @@
#include "Parser.h"
class TXTParser : public Parser {
-public:
- virtual void parse(FileReader & f, MuseumDeserializer & d);
- virtual unsigned int heuristic(FileReader & f);
+ friend class ParserFactory;
-private:
- static TXTParser instance;
- TXTParser();
+public:
+ virtual void parse(MuseumDeserializer & d);
+ virtual unsigned int heuristic();
};
diff --git a/XMLParser.cpp b/XMLParser.cpp
index 4bfde46..6252be8 100644
--- a/XMLParser.cpp
+++ b/XMLParser.cpp
@@ -4,18 +4,11 @@
#include "XMLParser.h"
#include "Exception.h"
-#include "ParserFactory.h"
-#include "TileData.h"
using namespace std;
-XMLParser XMLParser::instance {};
-XMLParser::XMLParser() {
- ParserFactory::register_strategy(this);
-}
-
-unsigned int XMLParser::heuristic(FileReader & f) {
- const string content = f.read();
+unsigned int XMLParser::heuristic() {
+ const string content = this->get_file().read();
int open_backets = 0;
int close_brackets = 0;
for (char c : content) {
@@ -27,10 +20,10 @@ unsigned int XMLParser::heuristic(FileReader & f) {
return (open_backets + close_brackets) / penalty;
}
-void XMLParser::parse(FileReader & f, MuseumDeserializer & d) {
+void XMLParser::parse(MuseumDeserializer & d) {
using namespace pugi;
- const string content = f.read();
+ const string content = this->get_file().read();
xml_document doc;
xml_parse_result result = doc.load_string(content.c_str());
if (!result)
diff --git a/XMLParser.h b/XMLParser.h
index 16f8749..8a36f44 100644
--- a/XMLParser.h
+++ b/XMLParser.h
@@ -3,12 +3,10 @@
#include "Parser.h"
class XMLParser : public Parser {
-public:
- virtual void parse(FileReader & f, MuseumDeserializer & d);
- virtual unsigned int heuristic(FileReader & f);
+ friend class ParserFactory;
-private:
- static XMLParser instance;
- XMLParser();
+public:
+ virtual void parse(MuseumDeserializer & d);
+ virtual unsigned int heuristic();
};
diff --git a/docs/class-diag.puml b/docs/class-diag.puml
index 6c38d9c..58ed950 100644
--- a/docs/class-diag.puml
+++ b/docs/class-diag.puml
@@ -50,15 +50,20 @@ rectangle Group_FileReading as "File reading" <<group>> {
HTTPFileReader -r[hidden] LocalFileReader
}
rectangle Group_ParsingDeserialization as "Parsing & deserialization" <<group>> {
- class ParserFactory {
- + parse(FileReader &, MuseumDeserializer &) <<static>>
- + register_strategy(Parser *) <<static>>
+ class ParserFactory <<factory>> {
+ + ParserFactory()
+ + get_parser(FileReader &) : Parser &
--
- - get_collection() : ParserCollection <<static>>
+ - parsers : vec<uniq<Parser>>
}
- interface Parser {
- + parse(FileReader &, MuseumDeserializer &) <<static>>
- + heuristic(FileReader &) : unsigned int <<static>>
+ interface Parser {
+ + parse(FileReader &, MuseumDeserializer &)
+ + heuristic(FileReader &) : unsigned int
+ --
+ # set_file(FileReader &)
+ # get_file() : FileReader &
+ --
+ file : FileReader *
}
class XMLParser
@@ -86,9 +91,7 @@ rectangle Group_ParsingDeserialization as "Parsing & deserialization" <<group>>
+ add_type(type : string, Color, weight : unsigned int)
}
- CSVParser -up-> MuseumDeserializer
- XMLParser -up-> MuseumDeserializer
- TXTParser -up-> MuseumDeserializer
+ Parser .> MuseumDeserializer
' LAYOUT
CSVParser -r[hidden] TXTParser
@@ -103,9 +106,10 @@ rectangle Group_Algorithms as "Algorithms" <<group>> {
class CollisionContext {
+ CollisionContext(Museum &)
}
- class CollisionChecker {
+ class CollisionChecker <<abstract>> {
+ CollisionChecker(Museum &)
- + check(Artist & a, Artist & b)
+ + compare(Artist & a, Artist & b)
+ + check() <<pure virtual>>
}
class QuadTreeCollisionChecker {
+ QuadTree(Museum &)
@@ -208,7 +212,7 @@ rectangle Group_Model as "Model" <<group>> {
green : unsigned int
blue : unsigned int
}
- class TileColorFactory <<singleton>> {
+ class TileColorFactory <<factory>> <<singleton>> {
+ get_color(string) : Color <<static>>
+ register_color(string, Color) <<static>>
}
@@ -224,7 +228,7 @@ rectangle Group_Model as "Model" <<group>> {
# interactions : unsigned int
# museum : Museum &
}
- class TileBehaviorFactory {
+ class TileBehaviorFactory <<factory>> {
+ TileBehaviorFactory(Museum &)
+ create(string) : uniq<TileBehavior>
--
@@ -322,9 +326,9 @@ rectangle Group_Visualization as "Visualization" <<group>> {
}
class ViewController {
+ update()
- + ev_keydown(KeyboardCode);
- + ev_mousedown(MouseCode);
- + ev_mousemove(x, y);
+ + ev_keydown(KeyboardCode)
+ + ev_mousedown(MouseCode)
+ + ev_mousemove(x, y)
--
- draw_artists : bool <<+get>> <<+set>>
}
@@ -355,11 +359,6 @@ rectangle Group_Commands as "Commands" <<group>> {
- museum : Museum &
- view : View &
}
- class ToggleArtistVisibilityCommand {
- + constructor(ViewController &)
- --
- - controller : ViewController &
- }
class LoadFilesCommand {
+ constructor(Museum &, files : vec<string>)
+ constructor(Museum &, argc, argv)
@@ -381,10 +380,18 @@ rectangle Group_Commands as "Commands" <<group>> {
- museum : Museum &
- forwards : bool
}
+ class ControlBooleanCommand {
+ + constructor(target : bool &)
+ + constructor(target : bool &, set : bool)
+ --
+ - toggle : bool
+ - value : bool
+ - target : bool &
+ }
Command <|-d- ToggleMuseumPauseCommand
Command <|-u- OpenFileGUICommand
- Command <|-u- ToggleArtistVisibilityCommand
+ Command <|-u- ControlBooleanCommand
Command <|-d- StepTileCommand
Command <|-d- LoadFilesCommand
Command <|-d- TimeTravelCommand