Contact Us

CATEGORIES

Whoops…Nothing found

Try other keywords in your search

Module Style Guide

 5 Minutes

 0 Likes

 295 Views

This is a guide on how to create modules according to the internal specifications and which things should be taken into account, it is made to provide a certain level of minimum quality that should be adhered to from now on.

There is also a Lua Style Guide, but this is not enforced in the review process
See Control Lua Style Guide.

This guide below is used as reference for Review Process.


Modules in context of the node structure.

There are different possibilities how a module can be structured to work in a bigger scope in the node based system.

This concept can be explained on a workflow example, let's assume we want to use a function that takes a number as input and is unable to handle strings. We have now three possibilities how to handle this with one or more modules:

  1. sendText Module-> toNumber Module -> numberNeeded(number) (Okay)
  2. sendNumber -> numberNeeded(number) (Good)
  3. sendValue (Select type in inspector) -> numberNeeded(number) (Bad)

     

All different ways are possible and allowed, we prefer option 2, it is the simplest way with the least amount of clicks needed. 


Properties

See also Property Builder

Naming

The name of properties should be easy to read and preferably self-explanatory for the user, no programming naming schema should be used.

Input fields

Input fields should catch simple input errors.
E.g. Check IP addresses if they can be a valid address.

Make sure to uninit and init a module when new values are entered!

These should be used as much as possible to create a satisfying user experience.
Every Button which requires an uninit, init to set a value should do that. E.g. If a new ip address is entered, the uninit and then the init should be executed.

Images

Images can be inserted into the properties, but please pay attention to the resolution, as too large files will make the Pixera installer larger than absolutely necessary, which we want to avoid.

These are used as standard only for the author's logo.

Description

ALWAYS CREATE A SHORT DESCRIPTION IN THE PROPERTIES
Create a short description to describe the use of the module, also mention important limitations and pitfalls here.

Groups

Property Groups

Property groups should be created if needed, especially if many properties can be set. Otherwise, the module becomes too messy. See Property Builder.
Good Example:

Properties at the time of export.

Keep in mind that the current state of Properties is saved in the installer. 
If, for example, paths are entered on the local system, these are unusable for the user and may also contain confidential information. Such properties should therefore be replaced with a “select” or a description. This string can be checked in the code with an if statement so that no errors occurs on autoinit. 

Author | Logo | URL | Version

This part should be included in every Module.

Order of Properties

The following order should be followed.

  1. The first part of the properties is defined in PIXERA, the user is unable to change this.
  2. Auto Init should be on top of the module properties.
  3. The module specific custom part of the properties.
  4. Author | Logo | URL | Version


Actions

Slot Style

Define in and out, make it as clean as possible be conservative with open connection points, make it as self explaining as possible, actions that should only display something and are not designed to execute a callRef should also not allow a connection. This should make it easier for the user to find their way around a module.

An Example:

  1. ref, this one must not have any forwarding as ref actions are returned collectively.
  2. init, this does not need to be looped through any further, as it makes little sense to connect the init in a loop.
  3. uninit, this does not need to be looped through any further as it makes little sense to connect the init in a loop.
  4. Time, The “Time” action is only used as a display, this should not be connected by design.

It is also possible to use “Out” connections on the left side of actions, these work in exactly the same way as the “Out” connections on the right side. However, such connections should be avoided as those makes it harder for the user to work with.

See pixc.callRefs for more information on how those can be used to get information from further connected nodes.

Action names

There are no exact specifications as to how action names must be named, the basic principle is camelCase, but all others are okay.
UpperCamelCase is also allowed here.

TIPP

snake_case will be displayed without the character “_” in action names.

 

 

Actions with Attributes

Be careful with these, only use when necessary, these don't work with direct API!
Values from these actions are saved in the project, these can be used to use data across the project, so that they are available again when the project is restarted if the project has been saved.
 

Warning

To save the current values, the project must be saved.

 

 

init

This action can be called automatically, this can be used to load all necessary values for the function of the module or to establish connections.

uninit

This action can is called automatically, this can be used to unload all required values for the function of the module or to disconnect connections. Uninit is called before the Control Lua Core is reloaded.

return

Since actions are nothing more than functions, returns can be used as normal, Lua Basic Overview. In the interaction of the pixc.callRefs behave in such a way that first all functions which are connected via reference are called, the returns of these functions are returned collectively to the function call, see pixc.callRefs, this is also providing the functionality for the ref() action.

callRefs

It is generally better to design modules in such a way that they are not directly dependent on node connections but also function standalone.
See pixc.callRefs for more information.

Hidden Actions

these are to be used to make modules cleaner and easier to understand for the user, see Hidden Actions

Hidden Actions


Self Learning Modules

To make modules as simple as possible for the user, we try to make the setup in the properties as simple as possible. In most new modules, the actions are already created automatically using Dynamic rebuild. The teach in functionalities are also based on this. 
This should continue to be used as much as possible to make usability as good as possible.

We are actively working towards enabling a simple setup for the user, which favors modules generating actions on their own.
As an example, we have here the Midi module, in which actions can be created automatically to the last received notes:

If these functionalities are used, it is also important to create a clean button for them.


ref() action

The ref action is used to return self() in the node system, everything that contains this action is normally “return self()”. This functionality is used as an example by the Multiprojector and PJLink modules. Read how this return works with the node system.

The pixc.callRefs() is executed as a return in the toProjectors() action to return the object from the connected object.
In the MultiProjector module, all connected objects are then called with the same name. It is therefore also important that the actions have the same name as called.

 

ref() actions should be added when it comes to more complex modules, for example, a toBool Module does not need this action. 

It makes sense if several devices are to be controlled at the same time, especially 3rd party devices and more complex modules, even if they are only helpers. If in doubt, include the ref() action!


Nil Value checks

The most common reason why errors occur in Lua is when variables have no value (nil)

Make sure that you catch basic errors with nil checks, this is very important for the stability of the modules.

local test

if test == nil then
	pixc.log(self().." Test is nil, used default")
	test = 5
end

test = test + 5

Requirements / Imports

Avoid loading requirements multiple times.

if self.helper == nil then
	require "pixcHelper"
	self.helper = createPixcHelper(pixc,self())
end

Tipp

Intellisense can be very helpful in this case:

 

 


Log prints

  • pixc.log()
  • pixc.warning()
  • pixc.error()

If pix.error() is used, the log symbol is displayed in color for the user, so you can symbolize to the user that something is wrong with important entries

 

Take care that no unnecessary log prints are made, i.e. the log should not be cluttered. All log prints made during development should be commented out or deleted. Debug actions can be included if necessary, but these can be hidden. See Hidden Actions 

Write the name of the module in the log you can do this with “self()”, otherwise it will be difficult to localize the source of the error in larger control projects.

local test

if test == nil then
	pixc.log(self()..": test is nil, used default")
	test = 5
end

test = test + 5

 

Some variables are created as hidden local variables in each action.

Starting from version 2.1.70, currentActionName and currentActionFullName are also included.

local test
-- better
if test == nil then
	pixc.log(currentActionFullName..": test is nil, used default")
	test = 5
end

test = test + 5

 

Expected Prints and Errors

In some cases log prints are expected, e.g. on import of a module and there is no selection made in the properties yet. 
There should be a meaningful log print in such cases, as example: “Please do the setup (module name) in its properties”

This Log message can be set as an error type log to make sure that the user us informed with the colored log icon.


Exports

At the time of exporting the module, the size of the module in the workspace must be taken into account. this is saved in the json module and generated in this size during import.

Good:



Bad:


Don'ts

  • Avoid Aux Directory
  • Avoid “Out” Node connections on the left side of a module: 
    • Bad:
    • Good:

 

Pixera 2.0.172 | 17. September 2024 | J.B.

Was this article helpful?