Ports - Part 1

Light And Port

Introduction

In this tutorial, we will be looking at the use of ports. As you will discover, ports are a very simple part and act in a manor consistent with other parts. In this Part 1, we will create a unit that has a boolean port and use signals that this port receives to light a glowbox.

The Unit Description

First things first, lets create a unit. Nothing too complicated, just a simple rectangle with a port and a glowbox.

Note

We will be using the Deno runtime to run a typescript program. You can learn about how to set this up in the How To Make A Unit tutorial

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{
	"modelName": "light_and_port",
	"printName": "Light & Port",
	"space": [
		{"x": 0.0, "y": 0.0},
		{"x": 0.0, "y": 50.0},
		{"x": 50.0, "y": 50.0},
		{"x": 50.0, "y": 0.0}
	],
	"collisionActive": true,
	"executable": {
		"mac": "../deno",
		"win": "../deno.exe",
		"args": ["run", "--allow-read", "main.ts"]
	},
	"base": [
		{
			"name": "backing",
			"attribute": {
				"type": "rectangle",
				"content": {
					"width": 50.0,
					"height": 50.0,
					"colour": {"r": 0.5, "g": 0.5, "b": 1.0}
				}
			}
		}
	],
	"parts": {
		"back": [
			{
				"name": "port",
				"attribute": {
					"type": "booleanPort",
					"content": {
						"x": 50.0,
						"y": 10.0,
						"width": 15.0
					}
				}
			}
		],
		"front": [
			{
				"name": "light",
				"attribute": {
					"type": "glowboxCircle",
					"content": {
						"x": 25.0,
						"y": 25.0,
						"radius": 15.0
					}
				}
			}
		]
	}
}

Show More

The Inner Workings

The code controlling all this is really very simple. Port events come as a "Process Event" thus we must create a callback for the "setProcessEventListener". The object provided by the "setProcessEventListener" is a standard Part Event so we must filter this for the Port type.

A Port event can have many types corresponding to the many things that can happen to a port. One of these events is a port receiving a message. Every other type is related to a user action. You can see the full list here.

Note

A "message" event is essentially an update of the state of the signal being transmitted by the other end of the connection. The illusion is that these connections are "charged" much like a wire in real life.

Of course the wire isn't real in this virtual world, so some smoke-and-mirrors are required to maintain this illusion. As such a "message" event will always follow a "gainedConnection" event, allowing you to adjust to the state of the connection when a connection is made.

This is only true for the Boolean and F32 port types. Datagrams are treated like packets over a network, so if the connection is not made when a datagram is sent, then it is simply lost. Audio connections will never receive "messages" as they are only used to manage audio connections in the audio rendering engine.

What we must write, is a handler that filters for the Port event type, then lights the glowbox if the received message is "true" and dim the glowbox if it is "false". We must also account for the circumstance in which the connection is lost, at which point we must dim the glowbox.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import apiConsole from "../typescript-deno-0.3.3-0.1.0/index.ts";
 
apiConsole.unit.setProcessEventListener(({event}) => {
	if(event.type === "port") {
		const portEvent = event.content;
 
		switch(portEvent.type) {
			case "message":
				const portMessageEvent = portEvent.content;
				if(portMessageEvent.type === "boolean") {
					const portBooleanMessageEvent = portMessageEvent.content;
					apiConsole.interface.glowbox.onOff(0, true, portBooleanMessageEvent);
				}
			break;
			case "lostConnection":
				apiConsole.interface.glowbox.onOff(0, true, false);
			break;
		}
	}
});

To set up the callback, we use the "setProcessEventListener" providing it with our callback function. This function takes a Part Event object.

On line 3 we check to see if it it of the correct type, and if so we unwrap the content on line 4, garnering us the PortEvent. We then use a switch statement on lines 6 through 18 to handle two events; "message" and "lostConnection".

The "message" case is very straightforward. We unwrap the content on line 8, check to see if its of the correct type (a boolean) on line 9, then unwrap that to uncover the value itself on line 10. This value is then passed straight through to the glowbox's "onOff" command on line 11.

The "lostConnection" event is even simpler, we just run the same "onOff" command but with the value argument set to 'false'.

Done!

All going well, you should have something that looks like this

Playing around with the connection, it should disactivate the glowbox when the connection is broken and reactive when the connection is made again (when the boolean signal is active, of course)

In the next chapter we'll look into how to send signals.