Implement proper self destruction of signals
This commit is contained in:
parent
049b5b54f8
commit
4e95e4e655
@ -12,6 +12,8 @@ public class SignalData {
|
||||
|
||||
/// The closure.
|
||||
public var closure: ([Any?]) -> Void
|
||||
/// Destroy the class.
|
||||
public var selfDestruction: (() -> Void)?
|
||||
|
||||
/// The closure as a C handler.
|
||||
var handler: @convention(c) (UnsafeMutableRawPointer, UnsafeMutableRawPointer) -> Void {
|
||||
@ -61,15 +63,20 @@ public class SignalData {
|
||||
}
|
||||
|
||||
/// Initialize the signal data.
|
||||
/// - Parameter closure: The signal's closure.
|
||||
public convenience init(closure: @escaping () -> Void) {
|
||||
self.init { _ in closure() }
|
||||
/// - Parameters:
|
||||
/// - closure: The signal's closure.
|
||||
/// - destroy: The self destruction.
|
||||
public convenience init(closure: @escaping () -> Void, destroy: (() -> Void)? = nil) {
|
||||
self.init(closure: { _ in closure() }, destroy: destroy)
|
||||
}
|
||||
|
||||
/// Initialize the signal data.
|
||||
/// - Parameter closure: The signal's closure.
|
||||
public init(closure: @escaping ([Any]) -> Void) {
|
||||
/// - Parameters:
|
||||
/// - closure: The signal's closure.
|
||||
/// - destroy: The self destruction.
|
||||
public init(closure: @escaping ([Any]) -> Void, destroy: (() -> Void)? = nil) {
|
||||
self.closure = closure
|
||||
self.selfDestruction = destroy
|
||||
}
|
||||
|
||||
/// Connect the signal data to a signal.
|
||||
@ -88,12 +95,19 @@ public class SignalData {
|
||||
} else {
|
||||
callback = unsafeBitCast(handler, to: GCallback.self)
|
||||
}
|
||||
let destroy: GClosureNotify = { data, _ in
|
||||
guard let data else {
|
||||
return
|
||||
}
|
||||
let signalData: SignalData = Unmanaged.fromOpaque(data).takeUnretainedValue()
|
||||
signalData.selfDestruction?()
|
||||
}
|
||||
g_signal_connect_data(
|
||||
pointer,
|
||||
signal,
|
||||
callback,
|
||||
Unmanaged.passUnretained(self).toOpaque().cast(),
|
||||
nil,
|
||||
destroy,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ extension Storage {
|
||||
if let data = fields[name + id] as? SignalData {
|
||||
data.closure = handler
|
||||
} else {
|
||||
let data = SignalData(closure: handler)
|
||||
let data = SignalData(closure: handler) { [self] in fields[name + id] = nil }
|
||||
fields[name + id] = data
|
||||
data.connect(pointer: (pointer ?? opaquePointer)?.cast(), signal: name, argCount: argCount)
|
||||
}
|
||||
|
||||
@ -125,8 +125,10 @@ public struct AlertDialog: AdwaitaWidget {
|
||||
) where Data: ViewRenderData {
|
||||
storage.fields[Self.visibleID + id] = _visible
|
||||
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
|
||||
if let storage = storage.content["extra-child"]?.first, visible {
|
||||
extraChild?.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
|
||||
defer {
|
||||
if let storage = storage.content["extra-child"]?.first, visible {
|
||||
extraChild?.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
}
|
||||
guard updateProperties else {
|
||||
return
|
||||
@ -168,7 +170,6 @@ public struct AlertDialog: AdwaitaWidget {
|
||||
let dialog = storage.content[Self.dialogID + id]?.first?.opaquePointer
|
||||
adw_dialog_close(dialog?.cast())
|
||||
storage.content[Self.dialogID] = []
|
||||
storage.content["extra-child"] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,9 +173,11 @@ public struct PreferencesDialog: AdwaitaWidget {
|
||||
if let storage = storage.content[.mainContent]?.first {
|
||||
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
for (index, page) in pages.enumerated() {
|
||||
if let preferences = storage.content["preferences-\(index)"] {
|
||||
page.update(groups: preferences, data: data, updateProperties: updateProperties)
|
||||
defer {
|
||||
for (index, page) in pages.enumerated() {
|
||||
if let preferences = storage.content["preferences-\(index)"] {
|
||||
page.update(groups: preferences, data: data, updateProperties: updateProperties)
|
||||
}
|
||||
}
|
||||
}
|
||||
guard updateProperties else {
|
||||
|
||||
@ -121,10 +121,12 @@ public struct Window: AdwaitaSceneElement {
|
||||
.storage(data: .init(sceneStorage: storage, appStorage: app), type: AdwaitaMainView.self)
|
||||
adw_application_window_set_content(window.pointer?.cast(), viewStorage.opaquePointer?.cast())
|
||||
storage.content[.mainContent] = [viewStorage]
|
||||
let observeID = "destroy"
|
||||
let data = SignalData {
|
||||
storage.destroy = true
|
||||
} destroy: {
|
||||
window.signals[observeID] = nil
|
||||
}
|
||||
let observeID = "destroy"
|
||||
data.connect(pointer: window.pointer, signal: observeID)
|
||||
window.signals[observeID] = data
|
||||
let template = getTemplate(content: content)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user