8. Using Reflection
The Reflection System is a system that allows to get data about functions, classes, properties and structs.
It contains information about their structure, parameters of functions and other technical and structural data as well as metadata like descriptions and localized display names of the different things.
This data is heavily used internally and also can be accessed from within Lua code.
Reflection Data in Lua
The mentioned findClass
function allows you to search for a class by its name.
It returns an instance of a class containing information about it.
local class = findClass("NetworkCard")
This instance contains functions and properties that allow you to get
information about the class it represents.
It extends from Struct, and it extends from ReflectionBase, the base type of all reflection data classes.
ReflectionBase:
-
name (property)
The internal name of the data object as a string. f.e. the function name you use in Lua. -
displayName (property)
A display name with better and more human-readable text of the object. -
description (property)
A human-readable description explaining what the data object does.
(f.e. functionality of the function, uses of the class)
The "Struct" Class provides functions and properties about a struct specifically.
Like what properties and what functions the Struct it Represents has.
Check the Reference for more details.
The "Class" Class provides the finally additionally information about signals a instance of this class might emit. Check the Reference for more details.
Using Reflection Viewer and Reference
As Reflection Viewer we mean the "Reflection" Tab in the computer case UI or the network manager tool, that shows all available types, functions, etc.
As Reflection Reference we mean the Reflection page in this web documentation.
Both of these, list all the contents of the reflection system language independent.
That’s why you won’t find stuff like the component or event API in here,
because this stuff is language (Lua) dependent.
The reflection viewer can show all data of class and its inherited functions etc.
all on one page, the reflection reference can not.
You can disable this behaviour of the reflection viewer in the bottom right corner.
Let’s try to read the reflection data.
We want to first, read the Recipe of a Constructor and prints its name to the console, after that we want to get a signal whenever Item got outputted and print something.
At first, lets search for a constructor in the reflection data.
You won’t be able to find it in the online documentation,
as it will unnecessarily bloat it, but you can find it in the in-game
reflection viewer.
On the left you can see of which classes the constructor extends from.
On of these is the "Manufacturer" Class. Let’s have a look at it.
This time it is also available on the online documentation:
=== Manufacturer Manufacturer
Parent |
The base class of every machine that uses a recipe to produce something automatically.
==== Functions
===== Get Recipe getRecipe
(Class(Recipe) Recipe recipe
out)
Returns the currently set recipe of the manufacturer.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Recipe
recipe
Class(Recipe) out
The currently set recipe.
===== Get Recipes getRecipes
(Array(Class(Recipe)) Recipes recipes
out)
Returns the list of recipes this manufacturer can get set to and process.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Recipes
recipes
Array(Class(Recipe)) out
The list of avalible recipes.
===== Set Recipe setRecipe
(Class(Recipe) Recipe recipe
, Bool Got Set gotSet
out)
Sets the currently producing recipe of this manufacturer.
Flags |
RuntimeSync |
- Parameters
-
Name Type Description Recipe
recipe
Class(Recipe)
The recipe this manufacturer should produce.
- Return Values
-
Name Type Description Got Set
gotSet
Bool out
True if the current recipe got successfully set to the new recipe.
===== Get Input Inventory getInputInv
(Trace(Inventory) Inventory inventory
out)
Returns the input inventory of this manufacturer.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Inventory
inventory
Trace(Inventory) out
The input inventory of this manufacturer
===== Get Output Inventory getOutputInv
(Trace(Inventory) Inventory inventory
out)
Returns the output inventory of this manufacturer.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Inventory
inventory
Trace(Inventory) out
The output inventory of this manufacturer.
Since we first want to get a recipe lets search for a function or property, that could do that.
You can read a description and other information.
The flags "RuntimeSync" and "RuntimeParallel" show that we can
only use the function in the non-promoted Lua tick state.
What that exactly means will be discussed in a later section.
The title consists of:
Display Name internalName (Parameter, List)
The display name is a human readable name of the function.
The internal name is used f.e. inside lua as function name.
The parameter list are all arguments and return values of the function.
Parameters with the out
keyword are return values.
You can have multiple return values.
Parameters are further down described in the Parameter
and Return Values
section.
We can see that a instance of a manufacturer (which a instance of constructor is),
has a member function getRecipe
that returns a Class Instance of a Recipe.
local manufacturer = component.proxy(...)
local recipe = manufacturer:getRecipe()
You can click on the link of the parameter type to get redirected to the reference of that type.
=== Recipe Recipe
Parent |
A struct that holds information about a recipe in its class. Means don’t use it as object, use it as class type!
==== Properties
===== String Name name
The name of this recipe.
Flags |
ClassProp RuntimeSync RuntimeParallel ReadOnly |
===== Float Duration duration
The duration how much time it takes to cycle the recipe once.
Flags |
ClassProp RuntimeSync RuntimeParallel ReadOnly |
==== Functions
===== Get Products getProducts
(Array(Struct(ItemAmount)) Products products
out)
Returns a array of item amounts, this recipe returns (outputs) when the recipe is processed once.
Flags |
ClassFunc RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Products
products
Array(Struct(ItemAmount)) out
The products of this recipe.
===== Get Ingredients getIngredients
(Array(Struct(ItemAmount)) Ingredients ingredients
out)
Returns a array of item amounts, this recipe needs (input) so the recipe can be processed.
Flags |
ClassFunc RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Ingredients
ingredients
Array(Struct(ItemAmount)) out
The ingredients of this recipe.
Here you can find a couple of functions and properties that have
the ClassFunc
or ClassProp
flag.
This flag describes that it is available when you have a class instance of that type.
We want the name
property as it gives us the name of the recipe.
print(recipe.name)
Now we want to figure out how we can get a signal when an item gets outputted.
Let’s search further one of the parents of our Manufacturer.
=== Actor Actor
Parent |
This is the base class of all things that can exist within the world by them self.
==== Properties
===== Struct(Vector) Location location
The location of the actor in the world.
Flags |
RuntimeSync RuntimeParallel ReadOnly |
===== Struct(Vector) Scale scale
The scale of the actor in the world.
Flags |
RuntimeSync RuntimeParallel ReadOnly |
===== Struct(Rotator) Rotation rotation
The rotation of the actor in the world.
Flags |
RuntimeSync RuntimeParallel ReadOnly |
==== Functions
===== Get Power Connectors getPowerConnectors
(Array(Trace(PowerConnection)) Connectors connectors
out)
Returns a list of power connectors this actor might have.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Connectors
connectors
Array(Trace(PowerConnection)) out
The power connectors this actor has.
===== Get Factory Connectors getFactoryConnectors
(Array(Trace(FactoryConnection)) Connectors connectors
out)
Returns a list of factory connectors this actor might have.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Connectors
connectors
Array(Trace(FactoryConnection)) out
The factory connectors this actor has.
===== Get Pipe Connectors getPipeConnectors
(Array(Trace(PipeConnection)) Connectors connectors
out)
Returns a list of pipe connectors this actor might have.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Connectors
connectors
Array(Trace(PipeConnection)) out
The factory connectors this actor has.
===== Get Inventories getInventories
(Array(Trace(Inventory)) Inventories inventories
out)
Returns a list of inventories this actor might have.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Inventories
inventories
Array(Trace(Inventory)) out
The inventories this actor has.
===== Get Network Connectors getNetworkConnectors
(Array(Trace(ActorComponent)) Connectors connectors
out)
Returns the name of network connectors this actor might have.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Connectors
connectors
Array(Trace(ActorComponent)) out
The factory connectors this actor has.
The actor class has an interesting function getFactoryConnectors
.
Let’s check the return type of it:
=== Factory Connection FactoryConnection
Parent |
A actor component that is a connection point to which a conveyor or pipe can get attached to.
==== Properties
===== Int Type type
Returns the type of the connection. 0 = Conveyor, 1 = Pipe
Flags |
RuntimeSync RuntimeParallel ReadOnly |
===== Int Direction direction
The direction in which the items/fluids flow. 0 = Input, 1 = Output, 2 = Any, 3 = Used just as snap point
Flags |
RuntimeSync RuntimeParallel ReadOnly |
===== Bool Is Connected isConnected
True if something is connected to this connection.
Flags |
RuntimeSync RuntimeParallel ReadOnly |
==== Functions
===== Get Inventory getInventory
(Trace(Inventory) Inventory inventory
out)
Returns the internal inventory of the connection component.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Inventory
inventory
Trace(Inventory) out
The internal inventory of the connection component.
===== Get Connected getConnected
(Trace(Inventory) Connected connected
out)
Returns the connected factory connection component.
Flags |
RuntimeSync RuntimeParallel |
- Return Values
-
Name Type Description Connected
connected
Trace(Inventory) out
The connected factory connection component.
==== Signals
===== Item Transfer ItemTransfer
(Struct(Item) Item item
)
Triggers when the factory connection component transfers an item.
Flags |
|
- Parameters
-
Name Type Description Item
item
Struct(Item)
The transfered item
Well, look at that, it has a ItemTransfer
Signal.
And when looking at the description, it does exactly what we want.
So lets use the information we got from the reflection and write some code that gets a factory connector, and then listen to it.
We don’t know which of the factory connectors the getFactoriesConnector
returns.
They will always be in the same order on a per building type basis.
So we simply have to test which of the connectors is the output connector
for all constructors, and listen to that one.
local connector = manufacturer:getFactoryConnectors()[1]
event.listen(connector)
So, now we can pull events and print the ItemTransfer
event to the console.
while true do
e, s, i = event.pull()
if e == "ItemTransfer" then
print("Transfer!", i)
end
end
Our full code yet would be:
local manufacturer = component.proxy(...)
local recipe = manufacturer:getRecipe()
print(recipe.name)
local connector = manufacturer:getFactoryConnectors()[1]
event.listen(connector)
while true do
e, s, i = event.pull()
if e == "ItemTransfer" then
print("Transfer!", i)
end
end