Class Mechanism
Poly uses Lua metatables to simulate a class mechanism. The following example class illustrates Poly’s Class API:
1-- require Poly's Class API
2local Class = require('__poly__.Class')
3
4-- == Define a new class called ExampleClass ======================================
5local ExampleClass = Class:new('examples.ExampleClass')
6
7-- define ExampleClass's "new" function (a.k.a. its constructor)
8function ExampleClass:new(param1, param2)
9 -- return a new object of this class (metatable is automatically set by Poly)
10 return {
11 attr1 = param1,
12 attr2 = param2
13 }
14end
15
16-- define a class method, e.g., a setter for attr1
17function ExampleClass:set_attr1(attr1)
18 self.attr1 = attr1
19end
20
21-- create a new object of ExampleClass
22local my_example_object = ExampleClass:new(1, 'foo')
23-- call class method 'set_attr1' with argument 5 on my_example_object
24my_example_object:set_attr1(5)
25
26
27-- == Define a new class that is derived from ExampleClass ========================
28local DerivedClass = Class:new('examples.DerivedClass', ExampleClass)
29
30-- override "new" of ExampleClass
31function DerivedClass:new()
32 -- call super class constructor
33 return ExampleClass:new(2, 'bar')
34end
35
36-- create a new object of DerivedClass
37local my_derived_object = DerivedClass:new()
38-- call inherited class method 'set_attr1' with argument 10 on my_derived_object
39my_derived_object:set_attr1(10)
Some additional notes on the Class API:
The class method
new
is a special member function. It is the class’ constructor and, if defined, has to return a new instance of the class. It can optionally take arguments. You do not have to set instance’s metatable yourself, Poly takes care of that for you.To make the class mechanism work, all calls to member and static member functions of a class have to use the colon notation, e.g.,
ExampleClass:new(1, 'foo')
andmy_example_object:set_attr1(5)
. Definitions of class methods have to use the colon notation as well, e.g.,function ExampleClass:set_attr1(attr1) ...
.The first parameter to
Class:new
is the class’ identifier. It can be any unique string, but usually should be the class’ name prefixed with the class’ path, e.g.,examples.ExampleClass
in this example, because example class is defined in a file in theexamples
folder. Adding the class’ path as prefix allows to have multiple classes with the same name.The
Class:new
function takes an optional second argumentbase_class
. This allows for class inheritance, when passing another previously defined class. The derived class provides all functions of the base class. Defining functions in the derived class overrides the corresponding function in the base class. Note that when overriding thenew
function, you are responsible for correctly initializing the base class object, e.g., by calling the base class constructor.Poly may persist class instances in Factorio’s
global
table, e.g. for event handling, so it is generally a good idea to only store compatible types in class instances, e.g. numbers, strings, LuaGuiElements, and not functions, for example.