diff options
| author | Ruben Beltran del Rio <jj@r.bdr.sh> | 2025-12-14 20:21:24 +0100 |
|---|---|---|
| committer | Ruben Beltran del Rio <jj@r.bdr.sh> | 2025-12-15 00:10:39 +0100 |
| commit | 0d5e6636405dbe332c33c0fb82c7ccccb20f96cb (patch) | |
| tree | a9cda2b711bbfc9277d66310440dd965b16682fc /Map/Business/RenderableMap.swift | |
| parent | a5ae7aedc840a38505b3181f4e5ba92e90d94fa1 (diff) | |
Use wmap-parser-swift and tree-sitter-wmap for parsing and highlighting.
Diffstat (limited to 'Map/Business/RenderableMap.swift')
| -rw-r--r-- | Map/Business/RenderableMap.swift | 198 |
1 files changed, 83 insertions, 115 deletions
diff --git a/Map/Business/RenderableMap.swift b/Map/Business/RenderableMap.swift index d43b584..82acaff 100644 --- a/Map/Business/RenderableMap.swift +++ b/Map/Business/RenderableMap.swift @@ -13,6 +13,7 @@ // 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 +import WmapParser struct RenderableMap { let vertices: [Vertex] @@ -20,111 +21,101 @@ struct RenderableMap { let inertias: [Inertia] let opportunities: [Opportunity] let notes: [Note] - let stages: [CGFloat] + let stages: [Double] let groups: [[Vertex]] static let empty: RenderableMap = RenderableMap( vertices: [], edges: [], inertias: [], opportunities: [], notes: [], stages: defaultDimensions, groups: []) - static func from(_ entities: [Wmap.Entity]) -> RenderableMap { + static func from(_ map: WmapParser.Map) -> RenderableMap { var vertices: [Vertex] = [] var edges: [MapEdge] = [] var inertias: [Inertia] = [] var opportunities: [Opportunity] = [] var notes: [Note] = [] - var stages: [CGFloat] = [25.0, 50.0, 75.0] // default dimensions + var stages: [Double] = [25.0, 50.0, 75.0] // default dimensions var groups: [[Vertex]] = [] // Build a vertex lookup for edges, groups, etc. var vertexMap: [String: Vertex] = [:] - var vertexIdCounter = 0 - - for entity in entities { - switch entity { - case .vertex(let vertex): - let newVertex = Vertex( - id: vertexIdCounter, - label: vertex.label, - position: CGPoint(x: vertex.coordinates.0, y: vertex.coordinates.1), - shape: convertShape(vertex.shape) - ) - vertices.append(newVertex) - vertexMap[vertex.label.lowercased()] = newVertex - vertexIdCounter += 1 - - case .note(let note): - notes.append( - Note( - id: notes.count, - position: CGPoint(x: note.coordinates.0, y: note.coordinates.1), - text: note.text - )) - - case .stage(let stage): - let stageIndex = convertStageNumber(stage.number) - 1 - if stageIndex >= 0 && stageIndex < 3 { - stages[stageIndex] = stage.value - } + + for (index, component) in map.components.enumerated() { + let newVertex = Vertex( + id: index, + label: component.label, + position: CGPoint(x: component.coordinates.xCoordinate, y: component.coordinates.yCoordinate), + shape: component.shape + ) + vertices.append(newVertex) + vertexMap[component.label.lowercased()] = newVertex + } + + for (index, note) in map.notes.enumerated() { + notes.append( + Note( + id: index, + position: CGPoint(x: note.coordinates.xCoordinate, y: note.coordinates.yCoordinate), + text: note.text + )) + } - default: - continue + for stage in map.stages { + let stageIndex = stageToIndex(stage.stage) + if stageIndex >= 0 && stageIndex < 3 { + stages[stageIndex] = stage.value } } // Second pass for entities that depend on vertices - for entity in entities { - switch entity { - case .edge(let edge): - if let fromVertex = vertexMap[edge.from.lowercased()], - let toVertex = vertexMap[edge.to.lowercased()] - { - edges.append( - MapEdge( - id: edges.count, - origin: fromVertex.position, - destination: toVertex.position, - arrowhead: edge.isDirected - )) - } - - case .inertia(let inertia): - if let vertex = vertexMap[inertia.vertex.lowercased()] { - inertias.append( - Inertia( - id: inertias.count, - position: vertex.position - )) - } - - case .evolution(let evolution): - if let vertex = vertexMap[evolution.vertex.lowercased()] { - let direction: CGFloat = evolution.isPositive ? 1.0 : -1.0 - let destination = CGPoint( - x: vertex.position.x + (direction * evolution.value), - y: vertex.position.y - ) - opportunities.append( - Opportunity( - id: opportunities.count, - origin: vertex.position, - destination: destination - )) - } - - case .group(let group): - var groupVertices: [Vertex] = [] - for vertexName in group.vertices { - if let vertex = vertexMap[vertexName.lowercased()] { - groupVertices.append(vertex) - } - } - if !groupVertices.isEmpty { - groups.append(groupVertices) + for (index, dependency) in map.dependencies.enumerated() { + if let fromVertex = vertexMap[dependency.fromComponent.lowercased()], + let toVertex = vertexMap[dependency.toComponent.lowercased()] + { + edges.append( + MapEdge( + id: index, + origin: fromVertex.position, + destination: toVertex.position, + arrowhead: dependency.isDirected + )) + } + } + + for (index, inertia) in map.inertias.enumerated() { + if let vertex = vertexMap[inertia.component.lowercased()] { + inertias.append( + Inertia( + id: index, + position: vertex.position + )) + } + } + + for (index, evolution) in map.evolutions.enumerated() { + if let vertex = vertexMap[evolution.component.lowercased()] { + let destination = CGPoint( + x: vertex.position.x + evolution.value, + y: vertex.position.y + ) + opportunities.append( + Opportunity( + id: index, + origin: vertex.position, + destination: destination + )) + } + } + + for group in map.groups { + var groupVertices: [Vertex] = [] + for componentName in group.components { + if let vertex = vertexMap[componentName.lowercased()] { + groupVertices.append(vertex) } - - default: - continue + } + if !groupVertices.isEmpty { + groups.append(groupVertices) } } @@ -139,23 +130,12 @@ struct RenderableMap { ) } - private static func convertShape(_ shape: String?) -> VertexShape { - guard let shape = shape?.lowercased() else { return .circle } - switch shape { - case "square": return .square - case "triangle": return .triangle - case "x": return .x - default: return .circle - } - } - - private static func convertStageNumber(_ stageNumber: String) -> Int { - switch stageNumber.lowercased() { - case "i": return 1 - case "ii": return 2 - case "iii": return 3 - case "iv": return 4 - default: return 1 + private static func stageToIndex(_ stageNumber: WmapParser.StageNumber) -> Int { + switch stageNumber { + case .stageI: return 0 + case .stageII: return 1 + case .stageIII: return 2 + case .stageIV: return 3 } } } @@ -164,7 +144,7 @@ struct Vertex: Identifiable, Hashable { let id: Int let label: String let position: CGPoint - var shape: VertexShape = .circle + var shape: WmapParser.Shape = .circle } struct Note { @@ -173,13 +153,6 @@ struct Note { let text: String } -enum VertexShape: String { - case circle - case square - case triangle - case x -} - struct MapEdge { let id: Int let origin: CGPoint @@ -198,12 +171,7 @@ struct Opportunity { let destination: CGPoint } -struct StageDimensions { - let index: Int - let dimensions: CGFloat -} - -private let defaultDimensions: [CGFloat] = [ +private let defaultDimensions: [Double] = [ 25.0, 50.0, 75.0, |