Skip to content

Commit

Permalink
Cleaner unpacking, without the need to copy the arguments.
Browse files Browse the repository at this point in the history
# Conflicts:
#	Sources/SwiftGodot/Core/GenericSignal.swift
  • Loading branch information
samdeane committed Oct 29, 2024
1 parent 2e13689 commit cf0a6a8
Showing 1 changed file with 30 additions and 7 deletions.
37 changes: 30 additions & 7 deletions Sources/SwiftGodot/Core/GenericSignal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ public class GenericSignal<each T: VariantStorable> {
public func connect(flags: Object.ConnectFlags = [], _ callback: @escaping (_ t: repeat each T) -> Void) -> Object {
let signalProxy = SignalProxy()
signalProxy.proxy = { args in
let popper = ArgumentPopper(args)
callback(repeat popper.pop(as: (each T).self)!)
var index = 0
do {
callback(repeat try args.unpack(as: (each T).self, index: &index))
} catch {
print("Error unpacking signal arguments: \(error)")
}
}

let callable = Callable(object: signalProxy, method: SignalProxy.proxyName)
Expand Down Expand Up @@ -108,12 +112,31 @@ public class SignalProxy: Object {
/// The simple signal is used to raise signals that take no arguments and return no values.
public typealias SimpleSignal = GenericSignal< /* no generic arguments */>

/// Internal helper class to pop arguments from the argument list
class ArgumentPopper {
var arguments: [Variant]
extension Arguments {
enum UnpackError: Error {
case typeMismatch
case missingArgument
}

/// Unpack an argument as a specific type.
/// We throw a runtime error if the argument is not of the expected type,
/// or if there are not enough arguments to unpack.
func unpack<T: VariantStorable>(as type: T.Type, index: inout Int) throws -> T {
if index >= count {
throw UnpackError.missingArgument
}
let argument = self[index]
index += 1
let value: T?
if argument.gtype == .object {
value = T.Representable.godotType == .object ? argument.asObject(Object.self) as? T : nil
} else {
value = T(argument)
}

init(_ arguments: borrowing Arguments) {
self.arguments = Array(arguments)
guard let value else {
throw UnpackError.typeMismatch
}
}

func pop<T: VariantStorable>(as: T.Type) -> T? {
Expand Down

0 comments on commit cf0a6a8

Please sign in to comment.