Skip to main content

Programs in several files

A JARU program can live in a single .aru file or be split into several: the main file and the ones it brings in with import. The VM modules (Display, Sprite, GPIO…) are not files of yours: you open them with use.

useimport
What it bringsA VM module: use DisplayA file of yours: import "Player.aru"
When it takes effectWhen the program reaches its lineWhen compiling: the file runs before the main one
If repeatedNothing happensThe file goes in only once
If it does not existIt does not compile: Module not found.It does not compile: Imported file not found

use​

use opens VM modules so that the program can use them. Several fit on one line, separated by commas. They are written with their capital letters: use display does not compile. The list of modules is in The API.

use Display, Input
use Math

println(Math.max(3, 8)) // 8
  • The module exists from the line of the use. use is a statement like any other: it takes effect when the program reaches it. If you use the module before it, or without any use, the program compiles, but it stops at that line with ERR_MODULE_NOT_FOUND. Put the use lines at the top of the file.

    println(Math.abs(-5))   // stops here: Module 'Math' not found or not imported.
    use Math
  • A repeated use does nothing: the module opens once, even if several lines or several files ask for it.

  • A use works for the whole program: once it has run, the module can be used from any file. Even so, put in each file the use lines of what it uses: the code of an imported file runs before the main file's use lines (see Execution order).

  • use Display also opens Draw and Bitmap.

import​

import brings in the code of another .aru file of yours. The name goes in quotes, and the extension can be left out: import "Score" is the same as import "Score.aru".

Code/Score.aru
var points = 0

func addPoints(n)
points = points + n
end
Code/Game.aru
import "Score.aru"

addPoints(10)
addPoints(5)
println("Points: ", points) // Points: 15
  • The path is relative to the folder of the file that has the import, not to the project's. From Code/Game.aru, import "Levels/Level1.aru" brings Code/Levels/Level1.aru; and from that one, import "../Common.aru" brings Code/Common.aru. Separate the folders with /.
  • If the file does not exist, it does not compile. The error says Fatal Error: Imported file not found: and the path it looked for.
  • A circular import does not compile. If a file ends up importing itself (A.aru imports B.aru, and B.aru imports A.aru), the error comes out on the import that closes the loop and says circular import:. Move what the two files share to a third one that both import.
  • Each file goes in only once, even if several files import it or write it with and without the extension. Two rooms, for example, can import the same file without trouble.
  • There is no conditional import. An import inside an if or a function brings the file in all the same, and its code runs at the start, like the others.

All the files make up a single program:

  • The variables, constants, functions and classes of a file are seen by all the others.
  • Two var or two const with the same name in two files do not compile: Var symbol previously declared 'x'.
  • Two functions with the same name do compile, without any warning: the last one that ran wins. Give them different names, for example with the file's name in front: ScoreInit, PlayerInit.

Execution order​

Everything the main file imports runs before its first line, even if the import is at the end. The order is this:

  1. Each file, after the ones it imports itself.
  2. The import lines of one file, in the order they are written.
  3. The main file, last.

With these four files:

Code/Game.aru (the main one)
println("Game: first line")
import "Screen.aru"
import "Score.aru"
println("Game: last line")
Code/Screen.aru
import "Colors.aru"
println("Screen")
Code/Score.aru
import "Colors.aru"
println("Score")
Code/Colors.aru
println("Colors")

The program prints:

Colors
Screen
Score
Game: first line
Game: last line

Colors.aru comes out once, even though two files import it, and before the first one that imports it.

What this means:

  • The loose code of an imported file runs when the program starts: its println calls, its variables with their initial value, whatever it loads. If you want to decide when that happens, put it in a function and call it from the main file. That is what the scene editor does: each room's .gen.aru only declares things, and the room loads when your game calls its load function (see The code it generates).
  • For something to happen before everything else, such as opening the screen, put it in a small file and make it the first import of the main file.
  • The main file's functions do not exist while the imported files run: a function exists from the moment the program goes through its declaration. An imported file can use them inside its own functions, as long as those are called later; if it calls them before, the program stops with ERR_NAME_NOT_FOUND.
  • An error in the loose code of an imported file says <main>(), like one in the main file, with the line in its own file. If that line does not match the main file, look in the files it imports.

The main file​

The main file is the one the IDE compiles: the one in the Main File list of the explorer, which Set Main in its menu also chooses (see Projects). If none is chosen, the IDE compiles the active tab of the code editor. The project keeps it in its .jpr, under the mainfilename key.

  • Only the main file and what it imports go into the program, directly or indirectly. A .aru in the Code folder that nobody imports is not compiled.
  • The compiled program is named after the main file: Build/flash/<main>.jxr (see Your first program).
  • To see a large program split into files, open the EasyRender example, one of those installed with JARU IDE: it has eleven files, and EasyRender.aru imports World.aru, which imports the rest.