From cf0a6a814e657cd6f07172dfb50ca4dde67b9432 Mon Sep 17 00:00:00 2001 From: Sam Deane Date: Tue, 29 Oct 2024 12:34:56 +0000 Subject: [PATCH] Cleaner unpacking, without the need to copy the arguments. # Conflicts: # Sources/SwiftGodot/Core/GenericSignal.swift --- Sources/SwiftGodot/Core/GenericSignal.swift | 37 +++++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/Sources/SwiftGodot/Core/GenericSignal.swift b/Sources/SwiftGodot/Core/GenericSignal.swift index 23c276930..d647638a0 100644 --- a/Sources/SwiftGodot/Core/GenericSignal.swift +++ b/Sources/SwiftGodot/Core/GenericSignal.swift @@ -30,8 +30,12 @@ public class GenericSignal { 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) @@ -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(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(as: T.Type) -> T? {