Skip to content

Commit

Permalink
Use callv to call emit_signal
Browse files Browse the repository at this point in the history
  • Loading branch information
samdeane committed Dec 18, 2024
1 parent c3c4bf1 commit 960224f
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 66 deletions.
8 changes: 2 additions & 6 deletions Generator/Generator/MethodGen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ enum GeneratedMethodKind {
case utilityFunction
}

/// The list of static method names to make public.
/// Most of the names are kept fileprivate.
let publicMethodNames = ["method_get_class", "method_emit_signal"]

// To test the design, will use an external file later
// determines whether the className/method returns an optional reference type
func isReturnOptional (className: String, method: String) -> Bool {
Expand Down Expand Up @@ -501,8 +497,8 @@ func generateMethod(_ p: Printer, method: MethodDefinition, className: String, c
let inlineAttribute: String?
let documentationVisibilityAttribute: String?
if let methodHash = method.optionalHash {
let staticVarVisibility = publicMethodNames.contains(bindName) ? "" : "fileprivate "
assert (!method.isVirtual)
let staticVarVisibility = if bindName != "method_get_class" { "fileprivate " } else { "" }
assert(!method.isVirtual)
switch generatedMethodKind {
case .classMethod:
p.staticVar(visibility: staticVarVisibility, name: bindName, type: "GDExtensionMethodBindPtr") {
Expand Down
45 changes: 0 additions & 45 deletions Sources/SwiftGodot/Core/RawCall.swift

This file was deleted.

28 changes: 13 additions & 15 deletions Sources/SwiftGodot/Core/SignalWithArguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//

/// Simple signal without arguments.
public typealias SimpleSignal = SignalWithArguments< /* no args */ >
public typealias SimpleSignal = SignalWithArguments< /* no args */>

/// Signal support.
/// Use the ``connect(flags:_:)`` method to connect to the signal on the container object,
Expand Down Expand Up @@ -86,16 +86,14 @@ public class SignalWithArguments<each T: VariantStorable> {
// (t, as opposed to T), doesn't seem to support this pattern.
//
// The only thing we can do with them is iterate them,
// which means that we can build up an array of them, but then
// we need an alterative form of emitSignal that takes its arguments
// as an array rather than as variadically.
//
// This variant is defined in RawCall.swift - but I wonder if there's a better way?
var args = [Variant(signalName)]
// which means that we can build up an array of them, so we
// then use callv to call the emit_signal method.
let args = GArray()
args.append(Variant(signalName))
for arg in repeat each t {
args.append(Variant(arg))
}
let result = target.emitSignal(args)
let result = target.callv(method: "emit_signal", argArray: args)
guard let result else { return .ok }
guard let errorCode = Int(result) else { return .ok }
return GodotError(rawValue: Int64(errorCode))!
Expand All @@ -122,43 +120,43 @@ extension Arguments {
enum UnpackError: Error {
/// The argument could not be coerced to the expected type.
case typeMismatch

/// The argument was nil.
case nilArgument
}

/// 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 unwrap<T: VariantStorable>(ofType type: T.Type, index: inout Int) throws -> T {
let argument = try optionalVariantArgument(at: index)
index += 1

// if the argument was nil, throw error
guard let argument else {
throw UnpackError.nilArgument
}

// NOTE:
// Ideally we could just call T.unpack(from: argument) here.
// Unfortunately, T.unpack is dispatched statically, but we don't
// have the full dynamic type information for T when we're compiling.
// The only thing we know about type T is that it conforms to VariantStorable.
// We don't know if inherits from Object, so the compiler will always pick the
// default non-object implementation of T.unpack.

// try to unpack the variant as the expected type
let value: T?
if (argument.gtype == .object) && (T.Representable.godotType == .object) {
value = argument.asObject(Object.self) as? T
} else {
value = T(argument)
}

guard let value else {
throw UnpackError.typeMismatch
}

return value
}
}

0 comments on commit 960224f

Please sign in to comment.