Skip to content

Commit

Permalink
Refactor plugin activation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
krzyzanowskim committed Apr 28, 2024
1 parent 0c9b4eb commit e03d0db
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 38 deletions.
18 changes: 18 additions & 0 deletions Sources/STTextView/Plugin/Plugin.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Created by Marcin Krzyzanowski
// https://github.com/krzyzanowskim/STTextView/blob/main/LICENSE.md

internal struct Plugin {
let instance: any STPlugin
var events: STPluginEvents?

/// Whether plugin is already setup
var isSetup: Bool {
events != nil
}
}

internal extension Array<Plugin> {
var events: [STPluginEvents] {
compactMap(\.events)
}
}
8 changes: 0 additions & 8 deletions Sources/STTextView/Plugin/STPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@

import Foundation

@MainActor
public protocol PluginContext<Plugin> {
associatedtype Plugin: STPlugin
var coordinator: Plugin.Coordinator { get }
var textView: STTextView { get }
var events: STPluginEvents { get }
}

@MainActor
public protocol STPlugin {
associatedtype Coordinator = Void
Expand Down
8 changes: 8 additions & 0 deletions Sources/STTextView/Plugin/STPluginContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

import Foundation

@MainActor
public protocol PluginContext<Plugin> {
associatedtype Plugin: STPlugin
var coordinator: Plugin.Coordinator { get }
var textView: STTextView { get }
var events: STPluginEvents { get }
}

public struct STPluginContext<Plugin: STPlugin>: PluginContext {
public let coordinator: Plugin.Coordinator
public let textView: STTextView
Expand Down
6 changes: 0 additions & 6 deletions Sources/STTextView/Plugin/STPluginEvents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,3 @@ public class STPluginEvents {
return self
}
}

extension Array<(plugin: STPlugin, events: STPluginEvents?)> {
var events: [STPluginEvents] {
compactMap({ $0.events })
}
}
59 changes: 35 additions & 24 deletions Sources/STTextView/STTextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import AVFoundation
public static let didChangeSelectionNotification = NSTextView.didChangeSelectionNotification

/// Installed plugins. events value is available after plugin is setup
internal var plugins: [(plugin: any STPlugin, events: STPluginEvents?)] = []
internal var plugins: [Plugin] = []

/// A Boolean value that controls whether the text view allows the user to edit text.
@Invalidating(.insertionPoint, .cursorRects)
Expand Down Expand Up @@ -643,8 +643,8 @@ import AVFoundation
deinit {
guard !plugins.isEmpty else { return }
Task { @MainActor [plugins] in
plugins.forEach { plugin, _ in
plugin.tearDown()
plugins.forEach { plugin in
plugin.instance.tearDown()
}
}
}
Expand All @@ -668,25 +668,8 @@ import AVFoundation
textFinder.client = textFinderClient
textFinder.findBarContainer = enclosingScrollView

// unwrap any STPluginProtocol
func setUp(plugin: some STPlugin) -> STPluginEvents {
let events = STPluginEvents()
plugin.setUp(
context: STPluginContext(
coordinator: plugin.makeCoordinator(context: .init(textView: self)),
textView: self,
events: events
)
)
return events
}

for (offset, (plugin, _)) in plugins.enumerated() {
let events = setUp(plugin: plugin)

// set events handler
plugins[offset] = (plugin, events)
}
// setup registerd plugins
setupPlugins()
}

}
Expand Down Expand Up @@ -1315,8 +1298,36 @@ import AVFoundation

}

open func addPlugin(_ plugin: any STPlugin) {
plugins.append((plugin, nil))
open func addPlugin(_ instance: any STPlugin) {
let plugin = Plugin(instance: instance)
plugins.append(plugin)

// setup plugin right away if view is already setup
if self.window != nil {
setupPlugins()
}
}

private func setupPlugins() {
for (offset, plugin) in plugins.enumerated() where plugin.events == nil {
// set events handler
var plugin = plugin
plugin.events = setUp(instance: plugin.instance)
plugins[offset] = plugin
}
}

private func setUp(instance: some STPlugin) -> STPluginEvents {
// unwrap any STPluginProtocol
let events = STPluginEvents()
instance.setUp(
context: STPluginContext(
coordinator: instance.makeCoordinator(context: .init(textView: self)),
textView: self,
events: events
)
)
return events
}
}

Expand Down

0 comments on commit e03d0db

Please sign in to comment.