{"id":13800099,"url":"https://github.com/alskipp/Swift-Diagram-Playgrounds","last_synced_at":"2025-05-13T08:32:45.932Z","repository":{"id":144754059,"uuid":"37473390","full_name":"alskipp/Swift-Diagram-Playgrounds","owner":"alskipp","description":"Drawing diagrams in Swift using a recursive enum data structure","archived":false,"fork":false,"pushed_at":"2016-09-20T22:37:46.000Z","size":696,"stargazers_count":275,"open_issues_count":1,"forks_count":18,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-04-22T12:31:12.806Z","etag":null,"topics":["diagram","enum","playground","protocol","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alskipp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-06-15T15:22:43.000Z","updated_at":"2023-12-15T17:15:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"5446883a-ad26-4d5f-9911-047c11bba65e","html_url":"https://github.com/alskipp/Swift-Diagram-Playgrounds","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alskipp%2FSwift-Diagram-Playgrounds","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alskipp%2FSwift-Diagram-Playgrounds/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alskipp%2FSwift-Diagram-Playgrounds/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alskipp%2FSwift-Diagram-Playgrounds/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alskipp","download_url":"https://codeload.github.com/alskipp/Swift-Diagram-Playgrounds/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225190777,"owners_count":17435489,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diagram","enum","playground","protocol","swift"],"created_at":"2024-08-04T00:01:09.295Z","updated_at":"2024-11-18T14:31:35.072Z","avatar_url":"https://github.com/alskipp.png","language":"Swift","funding_links":[],"categories":["Learning Swift: Advanced Topics","Swift"],"sub_categories":["Protocol Oriented Programming"],"readme":"Swift-Diagram-Playgrounds\n========\n\n[![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg?style=flat)](https://developer.apple.com/swift/)\n\nThis is an adaption of Apple’s sample code for the [Protocol-Oriented Programming in Swift](https://developer.apple.com/videos/wwdc/2015/?id=408) talk given during WWDC 2015.\n\nIncluded is Apple’s original example playground file `Crustacean.playground` that uses a `Protocol-oriented` design (updated for Swift 3). In addition there's an alternative version `CrustaceanEnumOriented.playground` that uses a recursive enum as the data structure.\n\nFinally there's the `Diagrams.playground` which adds a bit more functionality and includes several pages of example diagrams.\n\nThe playgrounds demonstrate two different approaches to creating `Diagram`s as value types and show how to draw them into a CGContext.\n\n* * *\n\n![screenshot](http://alskipp.github.io/Swift-Diagram-Playgrounds/img/screenshot1.png)\n\n* * *\n\nApple’s version uses a variety of structs that conform to the `Drawable` protocol to represent different shapes. The alternative approach uses a recursive enum to achieve the same result. It looks like this:\n\n```swift\npublic enum Diagram {\n  case Polygon([CGPoint])\n  case Line([CGPoint])\n  case Arc(radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat)\n  case Circle(radius: CGFloat)\n  indirect case Scale(x: CGFloat, y: CGFloat, diagram: Diagram)\n  indirect case Translate(x: CGFloat, y: CGFloat, diagram: Diagram)\n  indirect case Rotate(angle: CGFloat, diagram: Diagram)\n  case Diagrams([Diagram])\n}\n```\n\n* * *\n**Note:** `livePreview` will merrily consume processing power to continuously redraw still images, therefore it's recommended to manually stop execution of the Playground after the images have rendered.\n* * *\n\n### Protocol-Oriented or Enum-Oriented – which is better?\n\nThe two approaches are a good demonstration of the [expression problem](https://en.wikipedia.org/wiki/Expression_problem). Which approach is easier to extend? Using a protocol-oriented technique allows you to add new types without too much hassle. In Apple’s example code a `Bubble` struct is added by implementing the `Drawable` protocol and `Equatable` (no pre-existing code needs to be adjusted). If a `Bubble` case were added to the `enum` version it would necessitate the altering of pre-existing functions (`Equatable` for `Diagram` and the `drawDiagram` function) this is more hassle and more error prone. However, we don't need to add a new case to the enum to draw `Bubble`s, we can simply add a function that constructs a bubble and returns a `Diagram`, in that case no code needs to be altered.\n\nThe use of a `Renderer` protocol makes it much easier to add a `TestRenderer` to log drawing. But using the `Renderer` protocol to add diagram transformation functionality is potentially very cumbersome. It is easy to add a `ScaledRenderer` type, but it would be more complicated to add a `TranslateRenderer`, or a `RotateRenderer` and duplicates functionality that is already provided by `CGContext`. The enum approach doesn't attempt to provide the logic for `Diagram` transformation, it simply stores the information needed and uses `CGContext` functions to do the hard work.\n\nWhich approach is better? I dunno ¯\\\\\\_(ツ)_/¯","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falskipp%2FSwift-Diagram-Playgrounds","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falskipp%2FSwift-Diagram-Playgrounds","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falskipp%2FSwift-Diagram-Playgrounds/lists"}