You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Sources/Lua/Documentation.docc/Articles/BridgingSwiftToLua.md
+5-3Lines changed: 5 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,7 @@ Basic Swift types are pushed by value -- that is to say they are copied and conv
10
10
11
11
Bridged values on the other hand are represented in Lua using the `userdata` Lua type, which from the Swift side behave as if there was an assignment like `var userdataVar: T? = myval` (where `T` is the type used in the `Metatable`, described below). So for classes, the `userdata` holds an additional reference to the object, and for structs the `userdata` holds a value copy of it. A `__gc` metamethod is automatically generated, which means that when the `userdata` is garbage collected by Lua, the equivalent of `userdataVar = nil` is performed.
12
12
13
-
> Note: While defining metatables for `struct` types is supported, all userdata in Lua are copy-by-reference, so the object will behave more like a class from the Lua side. Overall, `class` types can be a better fit for how the bridging logic behaves.
13
+
> Note: While defining metatables for `struct`(and `enum`) types is supported, all userdata in Lua are copy-by-reference, so the object will behave more like a class from the Lua side. Overall, `class` types can be a better fit for how the bridging logic behaves.
14
14
15
15
As described so far, the `userdata` plays nicely with Lua and Swift object lifetimes and memory management, but does not allow you to do anything useful with it from Lua other than controlling when it goes out of scope. This is where defining a metatable comes in.
Any arguments to the closure are type-checked using using `L.checkArgument<ArgumentType>()`. Anything which exceeds the type inference abilities of `memberfn` can always be written explicitly using `closure`. The full list of helpers that can be used to define fields is defined in ``Metatable/FieldType``. Note there are multiple overloads of `memberfn` to accommodate different numbers of arguments.
75
75
76
+
> Note: The above description skipped some of the nuances that, for example, avoid copying the value when using `.closure` with a struct type, which would entail using `checkUserdata(1)` rather than `checkArgument(1)`. Use `.memberfn` where possible which hides that complexity.
77
+
76
78
## Pushing values into Lua
77
79
78
-
Having defined a metatable for our type, we can use [`push(userdata:)`](doc:Lua/Swift/UnsafeMutablePointer/push(userdata:toindex:)) or [`push(any:)`](doc:Lua/Swift/UnsafeMutablePointer/push(any:toindex:)) to push instances of it on to the Lua stack, at which point we can assign it to a variable just like any other Lua value. Using the example `Foo` class described above, and assuming our Lua code expects a single global value called `foo` to be defined, we could use ``Lua/Swift/UnsafeMutablePointer/setglobal(name:)``:
80
+
Having defined a metatable for our type by calling `register()`, we can use [`push(userdata:)`](doc:Lua/Swift/UnsafeMutablePointer/push(userdata:toindex:)) or [`push(any:)`](doc:Lua/Swift/UnsafeMutablePointer/push(any:toindex:)) to push instances of it on to the Lua stack, at which point we can assign it to a variable just like any other Lua value. Using the example `Foo` class described above, and assuming our Lua code expects a single global value called `foo` to be defined, we could use ``Lua/Swift/UnsafeMutablePointer/setglobal(name:)``:
79
81
80
82
```swift
81
83
let foo =Foo()
@@ -155,7 +157,7 @@ To customize the bridging above and beyond adding fields to the userdata, we can
0 commit comments