Skip to content

Global structure

Roy Kakkenberg edited this page Nov 18, 2023 · 1 revision

The new narrowcasting software is somewhat complex in its structure. This is (unfortunately) required to have a maintainable software package. There are many different variables and types of devices into play. The goal of the narrowcasting software is to harmonize all these completely different type of devices and make it easy to set their behaviour.

Outside interfaces

This repository (as the name suggests) serves as the core of the new system. It receives commands from end users and translates these instructions/rules into behaviour for the listening devices. Devices like ARTnet controllers, audio players and kiosk screens all listen to commands from the core. These commands are sent by the core via SocketIO commands. If required, the listeners can also send commands back to the core, for example to indicate that they have finished loading a resource. End users can send instructions to the core by simply using HTTP requests. These are implemented into a visual GUI in the backoffice repository. The backoffice can also listen to SocketIO events to get the latest status about connected listeners. As you can see, this implements the publish-subscribe architecture as much as possible.

Application structure

The application is organized into modules. These modules are independent as much as possible. Each module has a separate concern and some will have their own wiki page. Modules can have dependencies on other modules. This is especially the case for modules like root and lights.

In the root of the ./src folder, the outside interfaces are defined. It is also where the application is globally initialized.

Entities

Each module can define its own entities. The ./src/database.ts file simply imports a list of all entity classes of each module.

The screens, lights and audios are all defined as their own database entity, a so-called SubscribeEntity. Screens and audios are a simple 1-1 mapping from the entity to a listener. Each SubscribeEntity has a reference to their currently used handler, so in the case of a restart each listener gets assigned to the correct handler. Lights are unfortunately quite different, so they will be explained below.

HTTP Controllers

The HTTP controllers are all created using TSOA. This means that controllers are not manually created, but this is done by TSOA instead. If any context objects are therefore required (like managers), they have to be singletons.

Lights

Lights are quite a unique thing. DMX lights differ greatly from one another. First, there are the type of devices like pars (spots) and moving heads. Then, there is what colors they can produce and how they do it. In the case of moving heads, movement is also a factor to take into account. One of the goals of the core is to take away this complexity to make it easy to implement effects. The entities should therefore support such a structure.

To support the structure compared to screens and audio players, there is the LightsController that represents the physical ARTnet controller. However, there should be a sort of grouping of the physical lights connected to each controller. Therefore, sets of lights are grouped together in a LightsGroup. A group can contain zero or more of each type of fixture.

Then, there are the fixtures themselves. To reduce duplication, entities are extended as much as possible. Each physical light is therefore mapped to exactly one digital lights-fixture of one of the three types: LightsPar, LightsMovingHeadRgb, and LightsMovingHeadWheel (for moving heads that do not have RGB lights for coloring, but use a coloring wheel).

Managing entities

To create these SubscribeEntities, each of these has their own controller and corresponding service, which can be found in the ./src/modules/root/ folder.

Handlers

The behaviour of the audio, lights and screens is organized into "handlers". All handlers are managed by the ./src/modules/root/handler-manager. This singleton creates all handler instances and - during initialization time - loads the SubscribeEntities from the database and assigns them to the previous handler. Handlers contain their entities: entities do not have any awareness of the handlers their assigned to.

SubscribeEntities can be assigned to handlers using HTTP requests using the ./src/modules/root/handler-controller.

Clone this wiki locally