Hello, world!

nakst
Let's take a look at what it takes to write a simple "Hello, world!" GUI program for my operating system.

First, we need to write a manifest file.
All we need to do is declare the properties for our main window, and how to build the program.

hello_world/hello_world.manifest
1
2
3
4
5
6
[build]
output = "Hello World.esx";
source = "hello_world/main.cpp";

[window mainWindow]
title = "Hello, world!";


Then, we write the program itself.

hello_world/main.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Include the API header.
#include "../api/os.h"

// Include the automatically-generated manifest header.
#define OS_MANIFEST_DEFINITIONS
#include "../bin/OS/hello_world.manifest.h"

void ProgramEntry() {
	// Create a window using the mainWindow template from the manifest.
	OSObject window = OSCreateWindow(mainWindow);

	// Create a container grid, and make it the window's root grid.
	OSObject grid = OSCreateGrid(1, 1, OS_GRID_STYLE_CONTAINER);
	OSSetRootGrid(window, grid);

	// Create a label, and add it to the grid.
	OSAddControl(grid, 0, 0, OSCreateLabel(OSLiteral("Hello, world!")), OS_CELL_FILL);

	// Finally, process messages from the window manager until the program exits.
	OSProcessMessages();
}


Finally, we add a line to compi‌le‌.‌‌s‌h to build the program.

1
./manifest_parser hello_world/hello_world.manifest bin/OS/hello_world.manifest.h


...and we have a program!

Why did you choose to use manifests files ?

I know there is probably more to it then what you shown, but what's in it could be passed to the compiler as command line parameters. And the title of the window is probably something I would like to set in the code.

I only used manifest files on Android and it never seemed like a good idea to me. But I only did two small "things" so my opinion is not really informed.
@mrmixer

The manifest files were mostly born out of my desire to have a notion of "commands".

For example, the file manager has commands like:
- Navigating to the parent folder
- Navigating to the previous folder
- Bookmarking the current folder
- Opening the selected item
- Create a new folder
- etc...

I want the user to be able to configure the keyboard shortcuts for these, put them into custom menus, use them for automation, and so on, without the program really having to worry about how.

Therefore they are statically declared in manifest files.

e.g. (from the file manager)
1
2
3
4
5
6
[command commandBookmarkFolder]
label = "Bookmark folder";
defaultDisabled = false;
callback = CallbackBookmarkFolder;
checkable = true;
iconID = OS_ICON_BOOKMARK;


And because I had these manifest files, I decided I would also use them for other things, like declaring window templates, build configuration or localisation. (Of course, I haven't implemented all of these things yet!)

Please note that you don't have to use the manifest files for everything. For example, the window template definition in the Hello World program is equivalent to:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
OSWindowSpecification _mainWindow = {
	.width = 800,
	.height = 600,
	.minimumWidth = 200,
	.minimumHeight = 160,
	.flags = 4,
	.title = (char *) "Hello, world!",
	.titleBytes = 13,
	.menubar = nullptr,
	.defaultCommand = nullptr,
};

OSWindowSpecification *mainWindow = &_mainWindow;


But which do you think is simpler? ;)
Is the manifest file only used to generate C code, or is it use by the OS after the building the program ?
Currently the manifest file is only used during building, but it will be used by the OS when I implement the features that need it.