Skip to content

Commit

Permalink
Update AGDebugKit to add dot format support
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle-Ye committed Mar 28, 2024
1 parent b9bc390 commit 5550944
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 33 deletions.
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/OpenSwiftUIProject/OpenGraph.git",
"state" : {
"revision" : "64b9d17389271f2cdd8f686ca81662f018ed80c4",
"version" : "0.0.5"
"revision" : "7749fd0c5bcc88ba81ea3477790f42706c71a851",
"version" : "0.0.7"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ let package = Package(
.library(name: "AGDebugKit", targets: ["AGDebugKit"]),
],
dependencies: [
.package(url: "https://github.com/OpenSwiftUIProject/OpenGraph.git", exact: "0.0.5"),
.package(url: "https://github.com/OpenSwiftUIProject/OpenGraph.git", exact: "0.0.7"),
.package(url: "https://github.com/OpenSwiftUIProject/Socket.git", from: "0.3.3"),
],
targets: [
Expand Down
30 changes: 23 additions & 7 deletions Sources/AGDebugKit/Graph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@ import Foundation

/// A wrapper class for AGGraph
public final class Graph {
private let graph: AGGraph?
private unowned let graph: AGGraph?

public init() {
graph = nil
}

public init(_ pointer: UnsafeRawPointer?) {
if let pointer {
let sharedGraph = pointer.assumingMemoryBound(to: AGGraph.self).pointee
graph = AGGraph(shared: sharedGraph)
} else {
graph = AGGraph()
}
graph = pointer?.assumingMemoryBound(to: AGGraph.self).pointee
}

public init(bitPattern: Int) {
graph = Unmanaged<AGGraph>.fromOpaque(.init(bitPattern: bitPattern)!).takeUnretainedValue()
}

public var dict: NSDictionary? {
Expand Down Expand Up @@ -54,4 +53,21 @@ public final class Graph {
public static func archiveGraph(name: String) {
name.withCString { AGGraph.archiveJSON(name: $0) }
}

/// Command to transform dot file to svg
/// 1. Install graphviz
/// 2. Execuate `dot -Tsvg xx.dot > xx.svg`
public static func _graphExport(_ bitPattern: Int, name: String = "aggraph_export.dot") {
// TODO: How to get the current in memory's AGGraphStorage objects?
// Currently we just use Xcode Memory Graph and use any of the AGGraphStorage's address
let graph = Graph(bitPattern: bitPattern)
let dot = graph.dot ?? ""
let path = URL(fileURLWithPath: "\(NSTemporaryDirectory())/\(name)")
do {
try dot.write(to: path, atomically: true, encoding: .utf8)
print(#"Wrote graph data to "\#(path.absoluteString)""#)
} catch {
print("Error writing to file: \(error)")
}
}
}
67 changes: 58 additions & 9 deletions Sources/DemoApp/AGDebugModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@
//

import AGDebugKit
import AttributeGraph
import SwiftUI

@available(macOS 13, *)
struct AGDebugItem: Equatable, Identifiable {
var url: URL

init(name: String) {
url = URL(filePath: NSTemporaryDirectory().appending("\(name).json"))
var format: Format

enum Format: String, CaseIterable, Identifiable {
var id: String { rawValue }

case json, dot
}


init(name: String, format: Format) {
url = URL(filePath: NSTemporaryDirectory().appending("\(name).\(format.rawValue)"))
self.format = format
}

var id: String { url.absoluteString }
}

Expand All @@ -24,12 +33,26 @@ struct AGDebugModifier: ViewModifier {
@State private var showInspector = false
@State private var items: [AGDebugItem] = []

fileprivate static var sharedGraphbitPattern: Int = 0
@State private var format: AGDebugItem.Format = .dot

func body(content: Content) -> some View {
content
.toolbar {
Picker("Format", selection: $format) {
ForEach(AGDebugItem.Format.allCases) {
Text($0.rawValue).tag($0)
}
}.pickerStyle(.segmented)
Button {
let item = AGDebugItem(name: Date.now.ISO8601Format())
Graph.archiveGraph(name: item.url.lastPathComponent)
let item = AGDebugItem(name: Date.now.ISO8601Format(), format: format)
let name = item.url.lastPathComponent
switch format {
case .json:
Graph.archiveGraph(name: name)
case .dot:
Graph._graphExport(AGDebugModifier.sharedGraphbitPattern, name: name)
}
items.append(item)
} label: {
Image(systemName: "doc.badge.plus")
Expand All @@ -43,6 +66,7 @@ struct AGDebugModifier: ViewModifier {
.inspector(isPresented: $showInspector) {
inspectorView
}
.overlay { _GraphFetcher() }
}

private var inspectorView: some View {
Expand Down Expand Up @@ -89,16 +113,16 @@ struct AGDebugModifier: ViewModifier {
private func openAction(_ url: URL) {
_ = NSWorkspace.shared.open(url)
}

// MARK: - Move

@State private var moving = false
@State private var moveURL: URL?
private func moveAction(_ url: URL) {
moveURL = url
moving = true
}

// MARK: - Delete

private func deleteAction(_ url: URL) throws {
Expand All @@ -113,3 +137,28 @@ extension View {
modifier(AGDebugModifier())
}
}

struct _GraphFetcher: View {
var body: Never { fatalError("Unimplemented") }

static func _makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs {
if let current = AGSubgraph.current {
let graph = current.graph
if #available(macOS 14, *) {
AGDebugModifier.sharedGraphbitPattern = unsafeBitCast(graph, to: Int.self)
}
}

return withUnsafePointer(to: view) { pointer in
let view = UnsafeRawPointer(pointer).assumingMemoryBound(to: _GraphValue<EmptyView>.self)
return EmptyView._makeView(view: view.pointee, inputs: inputs)
}
}

static func _makeViewList(view: _GraphValue<Self>, inputs: _ViewListInputs) -> _ViewListOutputs {
withUnsafePointer(to: view) { pointer in
let view = UnsafeRawPointer(pointer).assumingMemoryBound(to: _GraphValue<EmptyView>.self)
return EmptyView._makeViewList(view: view.pointee, inputs: inputs)
}
}
}
14 changes: 0 additions & 14 deletions Sources/DemoApp/DemoApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//

import SwiftUI
import AGDebugKit

@main
@available(macOS 14.0, *)
Expand All @@ -18,19 +17,6 @@ struct DemoApp: App {
NSApp.activate(ignoringOtherApps: true)
NSApp.windows.first?.makeKeyAndOrderFront(nil)
}

// Demo test code
let emptyGraph = Graph()
if let dict = emptyGraph.dict {
print(dict)
}
let defaultGraph = Graph(nil)
if let dict = defaultGraph.dict {
print(dict)
}
if let dot = defaultGraph.dot {
print(dot)
}
}

var body: some Scene {
Expand Down

0 comments on commit 5550944

Please sign in to comment.