How To Make A Unit - Part 2

Light And Switch - Import / Export

Note

This article is part of a series. If you haven't completed part one, we recommend you do so before continuing with this one.

We're going to use the unit you created in the previous chapter and modify it to have the Import / Export functionality.

How Does Import / Export Work

At some point during the program a user might decide to copy-and-paste your unit. We therefore want some way to clone a unit so that the pasted one is exactly the same as the copied one. A lot of this process is already handled by Alchemy, but the internal configuration is left up to the designer of the unit to handle. This is where the "Import/Export" interface comes in.

During the process of copying a unit, Alchemy will collect all relevant information (unit type, position, connections, etc.) and also collect the unit's "exportable" data. "exportable" data is data held in Alchemy on a per-unit basis, which can be updated using the "UpdateExportableData" command. Upon pasting, Alchemy creates the unit then runs the "import" method providing the same "exportable" data that was collected before.

Alchemy only stipulates that this data is a string, meaning that any format can be used so long as it is representable in string form. The collection and encoding of this data and the updating of the Alchemy held "exportable" data is the responsibility of the unit's designer, as is the correct decoding and distribution of this data.

The same "Import/Export" system is also used for saving/loading a project file.

Let's Do It

All you have to do is modify the main.ts file to look like this

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
import apiConsole from "../typescript-deno-0.3.3-0.1.0/index.ts";
 
let state = false;
 
function updateExportableData() {
	apiConsole.unit.updateExportableData(
		JSON.stringify(state)
	);
}
 
apiConsole.unit.setImportListener(({dataString}) => {
	state = JSON.parse(dataString) as boolean;
	apiConsole.interface.glowbox.onOff(0, true,  state);
	if(state) {
		apiConsole.interface.checkbox.check(1, true);
	} else {
		apiConsole.interface.checkbox.uncheck(1, true);
	}
});
 
apiConsole.unit.setMouseEventListener(({ event }) => {
	if(event.type === "checkbox") {
		state = event.content === "checked";
		apiConsole.interface.glowbox.onOff(0, true,  state);
		updateExportableData();
	}
});

Its a pretty simple change, but lets step through it

Our code journey starts at line 2, where we define the state of the unit. In this case the unit is very simple, so the state only needs to hold a boolean value representing whether the light is on or off.

There are two actions that must be accounted for

  • importing - receiving a state from Alchemy
  • exporting - sending a new state off to Alchemy to be stored

Lets start with Exporting first

Lines 4 through 8 are where we define a function to handle the process of updating the Alchemy-stored state. We can see it calling the console's unit-function "updateExportableData" and providing it with a Json stringified version of the boolean state we set up earlier.

The function is used on line 24, within the mouse event callback function, just after the state boolean and glowbox are set. This way, whenever the state of the unit is changed, the unit immediately updates the Alchemy-stored state.

Now for Importing

Lines 10 through 18 handle the importing. Here we see the listener for the import event "setImportListener" is given a callback, which takes "dataString" as an argument. This "dataString" is the very same Json stringified boolean we sent to Alchemy with the "updateExportableData", so decoding it is just a simple case of running the Json "parse" command.

Once we have the state decoded, we simply update the boolean value, glowbox and checkbox.

Done!

Congratulations! You've gotten import and export working!

It really is that simple. Alchemy will store whatever string you give it, so you have total freedom to encode your data in whatever way you see fit.

In the next chapter, we're going to look at Undo and Redo