Scripts are useful in applications because they can customize the business logic starting from building blocks implemented in the containing application itself. Whether you are embedding scripts in a business application, a videogame or some kind of tool, your first concern is interoperability of script and application and sharing (in a sense) of objects between the twos.
And the basic building blocks in procedural programming are functions.
Let’s catch base with the standard factorial script we’ve used so far:
Ok, so let’s suppose we want the multiplication to be implemented in an API function of the hosting application. In this case there’s obviously no purpose in doing so, but we are here to learn, so let’s pretend it’s a good idea.
This sets the
Mul variable in the global environment to point to the
Mul delegate of the application.
We are casting the delegate to it’s type of
Func<int, int, int> to please the C# compiler here - whatever technique you use to cast the delegate to a
System.Object is ok.
Also, note that we defined the methods to be
static, but in this case there’s no need at all for them to be; instance methods are good to go.
Problem: have an API function which returns a sequence of integers. The script will sum the numbers received and return the total.
Here, too, nothing too difficult. You can see how an
IEnumerator) is converted on the fly to a Lua iterator for the script to run.
Note also how that the scripts contains directly executable code and thus accesses the
DoString time, without needing a
Call .. call. Remember this,
DoFile will execute code contained in the script immediately!
A thing which must be noticed. MoonSharp is able to convert iterators of
System.Collections.IEnumeratortypes. That is, the non-generic variants. If for some reason you implement a generic iterator without implementing the non-generic one, the iterator will not work. All standard collection types and iterator methods like the above one implement the non-generic variants by default, so there’s no need to worry too much.
Problem: have an API function which returns a sequence of integers, this time in a table.
Here, we see how a
List<int> gets automatically converted to a Lua table! Note that the resulting table will be 1-indexed as Lua tables usually are.
We can do better, however. We can directly build a Lua table inside our functions:
You can see how easy is to operate with tables using the
There are two things to notice however:
Tableobject you must have a reference to the executing script
Scriptparameter in a CLR function which is available to the Lua script, MoonSharp will fill it for you. This also happens with the (less likely to be used this way)
CallbackArgumentstypes. Don’t worry if you don’t know what these do, they aren’t needed to get the basics of MoonSharp working!
As a good practice, always keep the
Scriptobject around, if you can. There are some things (like creating tables) which can only be done using the
A table is converted automatically to a
List<T>. For example:
However this can potentially create problems on some platforms (read: iOS). There are a ton of ways around this problem (which you’ll see in other tutorials) but suffice to say that the following works with no issues and is faster to boot:
Another way around, even faster, could have been using a
But here we have to deal with
To understand all of this, we need to dig a little deeper on how MoonSharp maps Lua types to C# types and viceversa.. in the next part.