From 5be45fcf20cddf0f4ac3b335c02d29018e403035 Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Sun, 28 May 2023 11:53:14 -0400 Subject: [PATCH] Add support for additional default values: empty typedarrays, empty dictionaries and optionsets --- Generator/Generator/Arguments.swift | 56 +++++++++++++++++++++++++++-- Generator/Generator/ClassGen.swift | 6 ++-- Generator/Generator/Enums.swift | 36 +++++++++++++++++-- 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/Generator/Generator/Arguments.swift b/Generator/Generator/Arguments.swift index 2d106b972..3df6f3d53 100644 --- a/Generator/Generator/Arguments.swift +++ b/Generator/Generator/Arguments.swift @@ -29,16 +29,17 @@ func getArgumentDeclaration (_ argument: JGodotArgument, eliminate: String, kind var def: String = "" if let dv = argument.defaultValue, dv != "" { + let argumentType = argument.type + // TODO: // - handle creating initializers from enums (builtint) // - empty arrays - // - bitfield defaults // - Structure with initialized values (Color (1,1,1,1)) // - NodePath ("") ctor // - nil values (needs to both turn the value nullable and handle that in the marshal code // - typedarrays, the default values need to be handled one by one, or a general conversion // system needs to be implemented - if !argument.type.starts(with: "Array") && !argument.type.starts(with: "bitfield::") && (!(isStructMap [argument.type] ?? false) || isPrimitiveType(name: argument.type)) && argument.type != "NodePath" && !argument.type.starts(with: "typedarray::") && !argument.type.starts (with: "Dictionary") && dv != "null" { + if !argumentType.starts(with: "Array") && !argumentType.starts(with: "bitfield::") && (!(isStructMap [argumentType] ?? false) || isPrimitiveType(name: argumentType)) && argumentType != "NodePath" && !argumentType.starts(with: "typedarray::") && !argumentType.starts (with: "Dictionary") && dv != "null" { if argument.type == "String" { def = " = \(dv)" } else if argument.type == "StringName" { @@ -50,6 +51,57 @@ func getArgumentDeclaration (_ argument: JGodotArgument, eliminate: String, kind } else { def = " = \(dv)" } + } else { + // Here we add the new conversions, will eventually replace everything + // above, as the do-not-run conditions are becoming large and difficult + // to parse - they were fine to bootstrap, but not for the long term. + + // Handle empty type arrays + if argumentType.starts(with: "typedarray::") { + if dv == "[]" { + def = " = \(getGodotType(argument, kind: kind)) ()" + } else { + print ("Generator: \(argumentType) support for default value: \(dv)") + } + } else if argumentType == "Dictionary" { + if dv == "{}" { + def = " = SwiftGodot.Dictionary ()" + } else { + print ("Generator: \(argumentType) missing support for default value: \(dv)") + } + } else if argumentType.starts(with: "bitfield::") { + if let defIntValue = Int (dv) { + if defIntValue == 0 { + def = " = []" + } else { + // Need to look it up + if let optionType = findEnumDef(name: argumentType) { + var setValues = "" + + for value in optionType.values { + if (defIntValue & value.value) != 0 { + let name = dropMatchingPrefix(optionType.name, value.name) + if setValues != "" { + setValues += ", " + } + setValues += ".\(name)" + } + } + def = " = [\(setValues)]" + } else { + print ("Generator: \(argumentType) could not produce default value for \(dv) because I can not find the type") + } + } + } else { + print ("Generator: bitfield:: with a non-integer default value") + } + } else if argumentType == "Array" { + if dv == "[]" { + def = " = GArray ()" + } else { + print ("Generator: no support for arrays with values: \(dv)") + } + } } } return "\(eliminate)\(godotArgumentToSwift (argument.name)): \(optNeedInOut)\(getGodotType(argument, kind: kind))\(isOptional ? "?" : "")\(def)" diff --git a/Generator/Generator/ClassGen.swift b/Generator/Generator/ClassGen.swift index 9a7894400..e49aaaaff 100644 --- a/Generator/Generator/ClassGen.swift +++ b/Generator/Generator/ClassGen.swift @@ -311,7 +311,8 @@ func generateProperties (_ p: Printer, var getterName = property.getter var gettterArgName = "" guard let method = findMethod (forProperty: property, startAt: cdef, name: property.getter, resolvedName: &getterName, argName: &gettterArgName) else { - print ("GodotBug: \(loc): property declared \(property.getter), but it does not exist with that name") + // Not a bug, but needs to be handled https://github.com/migueldeicaza/SwiftGodot/issues/67 + //print ("GodotBug: \(loc): property declared \(property.getter), but it does not exist with that name") continue } var setterName = property.setter ?? "" @@ -320,7 +321,8 @@ func generateProperties (_ p: Printer, if let psetter = property.setter { setterMethod = findMethod(forProperty: property, startAt: cdef, name: psetter, resolvedName: &setterName, argName: &setterArgName) if setterMethod == nil { - print ("GodotBug \(loc) property declared \(property.setter!) but it does not exist with that name") + // Not a bug, but needs to be handled: https://github.com/migueldeicaza/SwiftGodot/issues/67 + //print ("GodotBug \(loc) property declared \(property.setter!) but it does not exist with that name") continue } } diff --git a/Generator/Generator/Enums.swift b/Generator/Generator/Enums.swift index e61346024..5475157c7 100644 --- a/Generator/Generator/Enums.swift +++ b/Generator/Generator/Enums.swift @@ -7,15 +7,46 @@ import Foundation +// The name of the form 'bitfield::' +func findEnumDef (name: String) -> JGodotGlobalEnumElement? { + guard name.starts(with: "bitfield::") else { + return nil + } + + let full = name.dropFirst(10) + guard let split = full.firstIndex(of: ".") else { + print ("No support for global bitfields for \(name)") + return nil + } + let type = full [full.startIndex..