You can add your own components to Electra using C++ shared libraries, also referred as packages. When the Electra interpreter loads a package, it looks for a single function:
void load(std::vector<ComponentInformation>&)
The purpose of the load function is simple; It takes a reference to a vector of ComponentInformation
objects and populates it with custom components. Let's look at an example:
void load(std::vector<ComponentInformation>& components)
{
components.push_back({
.symbol = U'9',
.directions = {Direction::EAST, Direction::WEST},
.componentType = ComponentType::CLONING,
.workFunc = work_9
});
components.push_back({
.symbol = U'η',
.directions = {Direction::EAST, Direction::WEST},
.componentType = ComponentType::CLONING,
.workFunc = work_h
});
}- The
symbolfield is the Unicode character representation of the component. It overwrites any component with the same symbol. - The
directionsfield is a list of supported directions. - The
componentTypefield specifies the component's type. ThecomponentTypecan take two values:ComponentType::CLONINGorComponentType::NON_CLONING.NON_CLONINGcomponents do not clone the current after they've done their job, like portals. And as you may guess,CLONINGcomponents do clone the current after they've done their job like any other component in Electra. - The
workFuncfield is the function that gets triggered when a current touches it. If it returns false the current dies. Its signature should be,bool(std::vector<std::stack<var_t>>&, Current::Ptr&, std::vector<Current::Ptr>&)
An example program that uses packages can be found here.