From 3bacbf6ac85330d35493953d7296e5ba420b7750 Mon Sep 17 00:00:00 2001 From: Ruben Beltran del Rio Date: Mon, 7 Jul 2025 13:51:43 +0200 Subject: Use inertia instead of blockers --- Map/Business/MapParser/MapParser.swift | 22 ++++----- .../Strategies/BlockerParserStrategy.swift | 40 ---------------- .../Strategies/InertiaParserStrategy.swift | 40 ++++++++++++++++ Map/Localizable.xcstrings | 2 +- .../Base Components/MapRender/MapBlockers.swift | 55 ---------------------- .../Base Components/MapRender/MapIntertias.swift | 55 ++++++++++++++++++++++ .../Base Components/MapTextEditor.swift | 4 +- .../MapRender/MapRenderView.swift | 2 +- Map/Presentation/Theme/Color+theme.swift | 2 +- 9 files changed, 111 insertions(+), 111 deletions(-) delete mode 100644 Map/Business/MapParser/Strategies/BlockerParserStrategy.swift create mode 100644 Map/Business/MapParser/Strategies/InertiaParserStrategy.swift delete mode 100644 Map/Presentation/Base Components/MapRender/MapBlockers.swift create mode 100644 Map/Presentation/Base Components/MapRender/MapIntertias.swift (limited to 'Map') diff --git a/Map/Business/MapParser/MapParser.swift b/Map/Business/MapParser/MapParser.swift index e94de77..fc11415 100644 --- a/Map/Business/MapParser/MapParser.swift +++ b/Map/Business/MapParser/MapParser.swift @@ -22,7 +22,7 @@ struct MapParser { AnyMapParserStrategy(NoteParserStrategy()), AnyMapParserStrategy(VertexParserStrategy()), AnyMapParserStrategy(EdgeParserStrategy()), - AnyMapParserStrategy(BlockerParserStrategy()), + AnyMapParserStrategy(InertiaParserStrategy()), AnyMapParserStrategy(OpportunityParserStrategy()), AnyMapParserStrategy(StageParserStrategy()), AnyMapParserStrategy(GroupParserStrategy()), @@ -55,8 +55,8 @@ struct MapParsingPatterns { options: [.caseInsensitive, .anchorsMatchLines]) static let edge = try! NSRegularExpression( pattern: "^(.+?)[\\s]*-([->])[\\s]*(.+)", options: [.caseInsensitive, .anchorsMatchLines]) - static let blocker = try! NSRegularExpression( - pattern: "^\\[(Blocker)\\][\\s]*(.+)", options: [.caseInsensitive, .anchorsMatchLines]) + static let inertia = try! NSRegularExpression( + pattern: "^\\[(Inertia)\\][\\s]*(.+)", options: [.caseInsensitive, .anchorsMatchLines]) static let opportunity = try! NSRegularExpression( pattern: "^\\[(Evolution)\\][\\s]*(.+)[\\s]+([-+])[\\s]*([0-9]+.?[0-9]*)", options: [.caseInsensitive, .anchorsMatchLines]) @@ -74,14 +74,14 @@ struct MapParsingPatterns { struct ParsedMap { let vertices: [Vertex] let edges: [MapEdge] - let blockers: [Blocker] + let inertias: [Inertia] let opportunities: [Opportunity] let notes: [Note] let stages: [CGFloat] let groups: [[Vertex]] static let empty: ParsedMap = ParsedMap( - vertices: [], edges: [], blockers: [], opportunities: [], notes: [], stages: defaultDimensions, + vertices: [], edges: [], inertias: [], opportunities: [], notes: [], stages: defaultDimensions, groups: []) } @@ -112,7 +112,7 @@ struct MapEdge { let arrowhead: Bool } -struct Blocker { +struct Inertia { let id: Int let position: CGPoint } @@ -162,7 +162,7 @@ struct AnyMapParserStrategy: MapParserStrategy { class MapBuilder { var vertices: [String: Vertex] = [:] private var edges: [MapEdge] = [] - private var blockers: [Blocker] = [] + private var inertias: [Inertia] = [] private var opportunities: [Opportunity] = [] private var notes: [Note] = [] private var stages: [CGFloat] = defaultDimensions @@ -179,9 +179,9 @@ class MapBuilder { edges.append(edge) } - if type == Blocker.self { - let blocker = object as! Blocker - blockers.append(blocker) + if type == Inertia.self { + let inertia = object as! Inertia + inertias.append(inertia) } if type == Opportunity.self { @@ -208,7 +208,7 @@ class MapBuilder { func build() -> ParsedMap { let mappedVertices = vertices.map { label, vertex in return vertex } return ParsedMap( - vertices: mappedVertices, edges: edges, blockers: blockers, opportunities: opportunities, + vertices: mappedVertices, edges: edges, inertias: inertias, opportunities: opportunities, notes: notes, stages: stages, groups: groups) } diff --git a/Map/Business/MapParser/Strategies/BlockerParserStrategy.swift b/Map/Business/MapParser/Strategies/BlockerParserStrategy.swift deleted file mode 100644 index 4bd2ce4..0000000 --- a/Map/Business/MapParser/Strategies/BlockerParserStrategy.swift +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2024 Rubén Beltrán del Río - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see https://map.tranquil.systems. -import Foundation - -struct BlockerParserStrategy: MapParserStrategy { - private let regex = MapParsingPatterns.blocker - - func canHandle(line: String) -> Bool { - let range = NSRange(location: 0, length: line.utf16.count) - let matches = regex.matches(in: String(line), options: [], range: range) - return matches.count > 0 && matches[0].numberOfRanges == 3 - } - - func handle(index: Int, line: String, vertices: [String: Vertex]) -> (Any.Type, Any) { - let range = NSRange(location: 0, length: line.utf16.count) - let matches = regex.matches(in: String(line), options: [], range: range) - - let match = matches[0] - let vertexA = String(line[Range(match.range(at: 2), in: line)!]) - - if let vertex = vertices[vertexA] { - let blocker = Blocker(id: index, position: vertex.position) - return (Blocker.self, blocker) - } - - return (NSObject.self, NSObject()) // No matching object - } -} diff --git a/Map/Business/MapParser/Strategies/InertiaParserStrategy.swift b/Map/Business/MapParser/Strategies/InertiaParserStrategy.swift new file mode 100644 index 0000000..d5d515e --- /dev/null +++ b/Map/Business/MapParser/Strategies/InertiaParserStrategy.swift @@ -0,0 +1,40 @@ +// Copyright (C) 2024 Rubén Beltrán del Río + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see https://map.tranquil.systems. +import Foundation + +struct InertiaParserStrategy: MapParserStrategy { + private let regex = MapParsingPatterns.inertia + + func canHandle(line: String) -> Bool { + let range = NSRange(location: 0, length: line.utf16.count) + let matches = regex.matches(in: String(line), options: [], range: range) + return matches.count > 0 && matches[0].numberOfRanges == 3 + } + + func handle(index: Int, line: String, vertices: [String: Vertex]) -> (Any.Type, Any) { + let range = NSRange(location: 0, length: line.utf16.count) + let matches = regex.matches(in: String(line), options: [], range: range) + + let match = matches[0] + let vertexA = String(line[Range(match.range(at: 2), in: line)!]) + + if let vertex = vertices[vertexA] { + let inertia = Inertia(id: index, position: vertex.position) + return (Inertia.self, inertia) + } + + return (NSObject.self, NSObject()) // No matching object + } +} diff --git a/Map/Localizable.xcstrings b/Map/Localizable.xcstrings index a4b07f0..4dc5e1b 100644 --- a/Map/Localizable.xcstrings +++ b/Map/Localizable.xcstrings @@ -165,7 +165,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "Anchor (95, 80)\nUsers (90, 20)\nWalking App (70, 20)\nWalking App Database (50, 60)\nUser Interface (80, 50)\nWeb Server (60, 30)\nCRM (30, 70)\n\nUsers -> Walking App\nUsers -> User Interface\nWalking App -> Walking App Database\nWalking App -> Web Server\nUser Interface -> Web Server\nWeb Server -> CRM\n\n[Note] (80, 5) Social walking app for everyone\n\n[Group] Client Side, Walking App, User Interface\n\n[Evolution] Walking App +5\n\n[Blocker] Unreliable Data" + "value" : "Anchor (95, 80)\nUsers (90, 20)\nWalking App (70, 20)\nWalking App Database (50, 60)\nUser Interface (80, 50)\nWeb Server (60, 30)\nCRM (30, 70)\n\nUsers -> Walking App\nUsers -> User Interface\nWalking App -> Walking App Database\nWalking App -> Web Server\nUser Interface -> Web Server\nWeb Server -> CRM\n\n[Note] (80, 5) Social walking app for everyone\n\n[Group] Client Side, Walking App, User Interface\n\n[Evolution] Walking App +5\n\n[Inertia] Unreliable Data" } } } diff --git a/Map/Presentation/Base Components/MapRender/MapBlockers.swift b/Map/Presentation/Base Components/MapRender/MapBlockers.swift deleted file mode 100644 index e550ca9..0000000 --- a/Map/Presentation/Base Components/MapRender/MapBlockers.swift +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2024 Rubén Beltrán del Río - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see https://map.tranquil.systems. -import SwiftUI - -struct MapBlockers: View { - - let mapSize: CGSize - let vertexSize: CGSize - let blockers: [Blocker] - - let cornerSize = CGSize(width: 2.0, height: 2.0) - - var body: some View { - ForEach(blockers, id: \.id) { vertex in - Path { path in - path.addRoundedRect( - in: CGRect( - origin: CGPoint( - x: w(vertex.position.x) + 3 * vertexSize.width, - y: h(vertex.position.y) - vertexSize.height * 2 / 3), - size: CGSize(width: vertexSize.width / 2, height: vertexSize.height * 2) - ), cornerSize: cornerSize) - }.fill(Color.Theme.Map.blockerColor) - } - } - - func h(_ dimension: CGFloat) -> CGFloat { - max(0.0, min(mapSize.height, dimension * mapSize.height / 100.0)) - } - - func w(_ dimension: CGFloat) -> CGFloat { - max(0.0, min(mapSize.width, dimension * mapSize.width / 100.0)) - } -} - -#Preview { - MapBlockers( - mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0), - blockers: [ - Blocker(id: 0, position: CGPoint(x: 50.0, y: 50.0)), - Blocker(id: 1, position: CGPoint(x: 10.0, y: 20.0)), - ]) -} diff --git a/Map/Presentation/Base Components/MapRender/MapIntertias.swift b/Map/Presentation/Base Components/MapRender/MapIntertias.swift new file mode 100644 index 0000000..91ec6f9 --- /dev/null +++ b/Map/Presentation/Base Components/MapRender/MapIntertias.swift @@ -0,0 +1,55 @@ +// Copyright (C) 2024 Rubén Beltrán del Río + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see https://map.tranquil.systems. +import SwiftUI + +struct MapIntertias: View { + + let mapSize: CGSize + let vertexSize: CGSize + let inertias: [Inertia] + + let cornerSize = CGSize(width: 2.0, height: 2.0) + + var body: some View { + ForEach(inertias, id: \.id) { vertex in + Path { path in + path.addRoundedRect( + in: CGRect( + origin: CGPoint( + x: w(vertex.position.x) + 3 * vertexSize.width, + y: h(vertex.position.y) - vertexSize.height * 2 / 3), + size: CGSize(width: vertexSize.width / 2, height: vertexSize.height * 2) + ), cornerSize: cornerSize) + }.fill(Color.Theme.Map.inertia) + } + } + + func h(_ dimension: CGFloat) -> CGFloat { + max(0.0, min(mapSize.height, dimension * mapSize.height / 100.0)) + } + + func w(_ dimension: CGFloat) -> CGFloat { + max(0.0, min(mapSize.width, dimension * mapSize.width / 100.0)) + } +} + +#Preview { + MapIntertias( + mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0), + inertias: [ + Inertia(id: 0, position: CGPoint(x: 50.0, y: 50.0)), + Inertia(id: 1, position: CGPoint(x: 10.0, y: 20.0)), + ]) +} diff --git a/Map/Presentation/Base Components/MapTextEditor.swift b/Map/Presentation/Base Components/MapTextEditor.swift index fe4a7d6..b247047 100644 --- a/Map/Presentation/Base Components/MapTextEditor.swift +++ b/Map/Presentation/Base Components/MapTextEditor.swift @@ -36,7 +36,7 @@ class MapTextEditorController: NSViewController { private let vertexRegex = MapParsingPatterns.vertex private let edgeRegex = MapParsingPatterns.edge - private let blockerRegex = MapParsingPatterns.blocker + private let inertiaRegex = MapParsingPatterns.inertia private let opportunityRegex = MapParsingPatterns.opportunity private let noteRegex = MapParsingPatterns.note private let stageRegex = MapParsingPatterns.stage @@ -195,7 +195,7 @@ extension MapTextEditorController: NSTextStorageDelegate { [.foregroundColor: NSColor.Theme.Syntax.number], range: match.range(at: 4)) } - matches = blockerRegex.matches(in: textStorage.string, options: [], range: range) + matches = inertiaRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { textStorage.addAttributes( diff --git a/Map/Presentation/Complex Components/MapRender/MapRenderView.swift b/Map/Presentation/Complex Components/MapRender/MapRenderView.swift index b821634..3b97945 100644 --- a/Map/Presentation/Complex Components/MapRender/MapRenderView.swift +++ b/Map/Presentation/Complex Components/MapRender/MapRenderView.swift @@ -65,7 +65,7 @@ struct MapRenderView: View { MapOpportunities( mapSize: mapSize, lineWidth: lineWidth, vertexSize: vertexSize, opportunities: parsedMap.opportunities) - MapBlockers(mapSize: mapSize, vertexSize: vertexSize, blockers: parsedMap.blockers) + MapIntertias(mapSize: mapSize, vertexSize: vertexSize, inertias: parsedMap.inertias) }.mask { MapMask( mapSize: mapSize, vertexSize: vertexSize, vertices: parsedMap.vertices) diff --git a/Map/Presentation/Theme/Color+theme.swift b/Map/Presentation/Theme/Color+theme.swift index 22dc18b..4433dc1 100644 --- a/Map/Presentation/Theme/Color+theme.swift +++ b/Map/Presentation/Theme/Color+theme.swift @@ -44,7 +44,7 @@ extension Color { static let labelColor = Color.Theme.darkSlate static let axisColor = Color.Theme.darkSlate static let vertexColor = Color.Theme.darkSlate - static let blockerColor = Color.Theme.jasperRed + static let inertia = Color.Theme.jasperRed static let opportunityColor = Color.Theme.olympicBlue static let stageForeground = Color.Theme.lightNeutralGray static let stageBackground = Color.white -- cgit