Engine Abstraction Layer¶
As systems, that are installed from plugins most definetely will have different set of Lua bindings, Gsage Engine has Lua abstraction layer, that can be used to unify interfaces for different kinds of systems.
EAL helps to tie Lua code to the engine entities. Besides that EAL allows extensive code reuse between different objects.
The idea is pretty simple, each engine entity can have defined:
A single
class
type.Several
mixin
s.Each component can also trigger EAL to add more Lua logic.
Defining an Extension¶
Extension is a function that accepts a class prototype as a first parameter.
local function extension(cls)
end
Then it is possible any amount of additional methods in that function.
local function extension(cls)
function cls:moveToOrigin()
self.render:setPosition(0, 0, 0)
end
end
Besides defining custom methods, it is also possible to define setup
and teardown
methods.
They are pretty similar to constructor/destructor methods, but there can be more than one setup
and teardown
.
local function extension(cls)
...
cls.onCreate(function(self)
self.someVariable = 1
end)
cls.onDestroy(function(self)
print(tostring(self.id) .. " was destroyed")
end)
...
end
To add this extension to the system, it is required to call extend
method.
eal:extend({mixin = "extension"}, extension)
Now everything combined will look like that:
local eal = require 'eal.manager'
local function extension(cls)
cls.onCreate(function(self)
self.someVariable = 1
end)
cls.onDestroy(function(self)
print(tostring(self.id) .. " was destroyed")
end)
function cls:moveToOrigin()
self.render:setPosition(0, 0, 0)
end
end
eal:extend({mixin = "extension"}, extension)
In this example, extension is created as a mixin. Then, to use this extension for an entity, it is required to modify it’s JSON data.
{
"id": "something",
"props": {
"mixins": ["extension"] // adding a mixin
}
"render": {
"root": {
}
}
}
After all these manipulations you should be able to use this EAL interface:
local e = eal:getEntity("something")
-- our extension method
e:moveToOrigin()
-- the variable set in set up should be accessible
assert(e.someVariable == 1)
Supported Types of Extensions¶
System¶
System wide extensions.
Allows applying extension for all entities that have a component of a system system
with subtype type
.
Extending EAL:
eal:extend({system="render", type="ogre"}, extension)
There is no need to modify entity data as this extension will be applied system wide:
each entity with component of system render
with subtype ogre
will have this extension applied.
Class¶
When there is no need to stick to any particular system type, but it’s still required to distinguish
different system subtype
, it is better to use the class extension.
Though it is also possible to define a class without a strict requirement of system type.
-- enable this extension only when render system type is "ogre"
eal:extend({class = {name = "camera", requires = {render = "ogre"}}}, extension)
Using it in the entity data:
{
...
"props": {
"class": "camera"
}
...
}
Mixin¶
Mixin allows defining multiple different extensions for a single entity that are not tied to any specific system. It is better to define only the highest level logic in the mixin. Do not create too many mixins as it may hit the performance.
Important
As it is possible to make a composition of extensions of different kinds, it is necessary to know the order they are applied. First go system level extensions. Then class extension. Then mixins in order, defined in the json array.