@startuml !include style.ipuml ' !include hide-groups.ipuml ' !include hide-details.ipuml class main as "main()" hide main circle hide main members exception Exception { + Exception(const char* fmt, ...) + what() : const char* -- # error : char* # va_format(va_list args, const char* fmt) } rectangle Group_FileReading as "File reading" <> { class FileReaderFactory <> { + open(url) : FileReader& } interface FileReader { + read() : string + close() -- # open(string url) # clone() : FileReader* <> } class LocalFileReader { - instance : LocalFileReader <> } class HTTPFileReader { - instance : HTTPFileReader <> } package CPR { } FileReader <|.u. LocalFileReader FileReader <|.u. HTTPFileReader FileReader .l> FileReaderFactory FileReader <. FileReaderFactory HTTPFileReader -l> CPR ' LAYOUT HTTPFileReader -r[hidden] LocalFileReader } rectangle Group_ParsingDeserialization as "Parsing & deserialization" <> { class ParserFactory { + parse(FileReader &, MuseumDeserializer &) <> + register_strategy(Parser *) <> -- - get_collection() : ParserCollection <> } interface Parser { + parse(FileReader &, MuseumDeserializer &) <> + heuristic(FileReader &) : unsigned int <> } Parser .> ParserFactory Parser <. ParserFactory class CSVParser class XMLParser class TXTParser package pugixml { } CSVParser ..|> Parser TXTParser ..|> Parser XMLParser ..|> Parser XMLParser -> pugixml class MuseumDeserializer { + MuseumDeserializer(Museum &) -- + set_canvas(CanvasData) + set_tile(TileData) + add_artist(ArtistData) + add_type(type : string, Color, weight : unsigned int) } CSVParser -up-> MuseumDeserializer XMLParser -up-> MuseumDeserializer TXTParser -up-> MuseumDeserializer ' LAYOUT CSVParser -r[hidden] TXTParser TXTParser -r[hidden] XMLParser } rectangle Group_Algorithms as "Algorithms" <> { class Pathfinding { + Pathfinding(Museum &) } class Collision { + Collision(Museum &) } } rectangle Group_Model as "Model" <> { class Museum { + people : People + canvas : Canvas -- + update() -- - paused : bool <<+get>> <<+set>> - jump : unsigned long -- - working : bool - worker : thread * - work() } class Canvas { + Canvas(Museum &) -- + get_tile(x, y) : Tile & + set_tile(TileData) -- + update() + data : CanvasData + set_data(CanvasData) -- - tiles : vector - museum : Museum & } class People { + People(Museum &) -- + add_artist(ArtistData) + remove_artist(Artist &) + get_artists() : forward_list -- - artists : forward_list - artist_count : size_t - museum : Museum & } class Tile { + data : TileData + color : Color + behavior : uniq + set_data(TileData &) + set_type(type : const string &) + update() + get_neighbor(dx, dy) : Tile * -- - museum : Museum & } struct TileData { + x : unsigned int + y : unsigned int + type : string } class Artist { + update() + step : bool + color : Color + data : ArtistData -- - data : ArtistData - museum : Museum & } struct ArtistData { + x : float + y : float + vx : float + vy : float } struct CanvasData { + rows : unsigned int + columns : unsigned int } struct Color { red : unsigned int green : unsigned int blue : unsigned int } class TileColorFactory <> { + get_color(string) : Color <> + register_color(string, Color) <> } interface TileBehavior { + step(Artist *) + update(Tile &) -- # TileBehavior(Museum &) -- # interactions : unsigned int # museum : Museum & } class TileBehaviorFactory { + TileBehaviorFactory(Museum &) + create(string) : uniq -- - museum : Museum & } together { class NullTileBehavior { - type = "" <> } class StepTileBehavior { - type = "G" : <> } class DeleteArtistTileBehavior { - type = "R" : <> } class SetNeighborTileBehavior { - type = "B" : <> -- - dx : int - dy : int } class CreateArtistTileBehavior { - type = "Y" : <> -- - last_interactions : unsigned int } } 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 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 } together { /' LAYOUT '/ rectangle Group_Visualization as "Visualization" <> { struct Rectangle { x : unsigned int y : unsigned int width : unsigned int height : unsigned int } enum MouseCode { } enum KeyboardCode { } package SDL3 { } class View { + window_size(width, height) + dialog_file(callback : fn(files : vec, data), data) + draw_rect(Rectangle, Color) -- - window : SDL_Window * - renderer : SDL_Renderer * -- + open : bool - worker : thread * - work() } class ViewController { + update() + ev_keydown(KeyboardCode); + ev_mousedown(MouseCode); + ev_mousemove(x, y); -- - draw_artists : bool <<+get>> <<+set>> } ViewController ..> View ViewController <-- View View --> SDL3 View .l> Rectangle ViewController .l> KeyboardCode ViewController .l> MouseCode } rectangle Group_Commands as "Commands" <> { interface Command { + execute() } class ToggleMuseumPauseCommand { + constructor(Museum &) + constructor(Museum &, set : bool) -- toggle : bool value : bool } class OpenFileGUICommand { + constructor(Museum &, View &) -- - museum : Museum & - view : View & } class ToggleArtistVisibilityCommand { + constructor(ViewController &) -- - controller : ViewController & } class LoadFilesCommand { + constructor(Museum &, files : vec) + constructor(Museum &, argc, argv) -- - load_files() - museum : Museum & - files : vec } class StepTileCommand { + constructor(Canvas &, pair) -- - canvas : Canvas & - x : unsigned int - y : unsigned int } class TimeTravelCommand { + constructor(Museum &, forwards : bool) -- - museum : Museum & - forwards : bool } Command <|-d- ToggleMuseumPauseCommand Command <|-u- OpenFileGUICommand Command <|-u- ToggleArtistVisibilityCommand Command <|-d- StepTileCommand Command <|-d- LoadFilesCommand Command <|-d- TimeTravelCommand } } /' LAYOUT '/ Parser .l> FileReader MuseumDeserializer .l> Museum Museum --> Pathfinding Museum --> Collision ViewController -[norank]> Command main -d-> Museum main -u-> LoadFilesCommand ' main -[norank]> MuseumDeserializer main -[norank]> View main .r> Exception @enduml