123 lines
5.9 KiB
Markdown
123 lines
5.9 KiB
Markdown
Use this if you want to know how the OS works.
|
|
|
|
# Network
|
|
|
|
Every computer has a id assigned by the mod. It is a unique number that identifies the computer and cannot be changed.
|
|
The native implementation of the network stack works with channels. If you listen on a channel you will receive all messages sent to that channel.
|
|
Every computer listens to the channel with its id and a brodcast channel.
|
|
The broadcast channel is used for Routing Tables and GPS packets.
|
|
|
|
Network messages can be forwarded by other computers. This is done by the Routing Table. The routing algorithm prefers wire over wireless connections.
|
|
|
|
Packages also have a time-to-live (TTL) value. This is used to prevent packages from being forwarded forever. You will get a response if a package is dropped because of TTL.
|
|
|
|
There is also a concept of protocols. A protocol is used to distinguish between different types of packages.
|
|
A protocol is basically a string and that is used to forward packages to the correct handler. You can use `registerProto` to listen for packages with a specific protocol.
|
|
|
|
There are 2 ways of sending messages to other computers: `sendAndAwait` and `sendAndForget`.
|
|
`sendAndAwait` will wait for a response from the remote computer and return it.
|
|
`sendAndForget` will send the message and return immediately and does not care about the response.
|
|
You can compare it to UDP and TCP.
|
|
|
|
## Usage
|
|
|
|
```haxe
|
|
import net.Net;
|
|
|
|
var data = {"foo": "bar"};
|
|
|
|
Net.instance.sendAndAwait(netID,"protoname",data).map((response)->{
|
|
switch (response){
|
|
case Success(data):
|
|
trace(data);
|
|
case Failure(error):
|
|
trace(error);
|
|
}
|
|
});
|
|
|
|
Net.instance.registerProto("res",(pack: GenericPackage)->{
|
|
var requestPack: Package<MyType> = cast pack; // Try not to use Dynamic
|
|
|
|
requestPack.respond("Hello Back");
|
|
});
|
|
|
|
```
|
|
|
|
# Peripherals
|
|
|
|
Peripherals are devices that are connected to the computer. They can be used to interact with the world.
|
|
Every peripheral has an address and a type. The address can be "back" or "right" to refer to the peripheral on the back or right side of the computer or
|
|
something like "energyCell_0" to refer to something connected via cable. Peripherals can be accessed via the Peripheral class.
|
|
|
|
Also peripherals can be made accessible via the network. More on that later.
|
|
|
|
## Usage
|
|
|
|
```haxe
|
|
var back = Peripheral.getRedstone("back");
|
|
back.setOutput(true);
|
|
|
|
var drive Peripheral.getDrive("drive_0");
|
|
drive.eject();
|
|
```
|
|
|
|
# GUI
|
|
|
|
If you want to write something to the screen you have to create a `WindowContext` via the `WindowManager`. This allows programs to write to the screen without interfering with each other.
|
|
|
|
There are currently 2 types of `WindowContext`: the `BufferedVirtualTermWriter` that stores the state of the screen in a buffer and prints it to the screen
|
|
when it is activeted and the `StatelessVirtualTermWriter` which calls a render method when it is activated. Currently i prefer the `StatelessVirtualTermWriter` because its not so heavy on the RAM but both work.
|
|
|
|
They both can be used just like the [nativ implmentation](https://tweaked.cc/module/term.html).
|
|
|
|
## Usage
|
|
|
|
```haxe
|
|
var ctx = WindowManager.createNewBufferedContext();
|
|
ctx.setCursorPos(0, 0);
|
|
ctx.setCursorBlink(false);
|
|
ctx.setBackgroundColor(Blue);
|
|
ctx.setForegroundColor(White);
|
|
ctx.write("Hello world!");
|
|
```
|
|
|
|
## Under the hood
|
|
|
|
There are a number of interfaces and classes that needs to be explained to understand how the GUI works.
|
|
|
|
`TermWriteable` is an interface that allows the usage of the normal CC terminal write methods. Stuff like `write`, `setCursorPos` and `setCursorBlink` are defined here. This is of course implemented by the physical screens and the main terminal.
|
|
|
|
Most of the time you will not write directory to a real screen but to a `VirtualTermWriter` which extends `TermWriteable` with some more methods like `enable`
|
|
and `setTarget`. The `setTarget` is used as the proxy target of a `VirtualTermWriter` and with `enable` and `disable` you can enable and disable the forwarding of the write methods to the target.
|
|
|
|
The `StatelessVirtualTermWriter` and `BufferedVirtualTermWriter` are both `VirtualTermWriter`. They can have a real output as a target. Or they can have another `VirtualTermWriter` as target like the `BufferedVirtualTermWriter` which uses a `TermBuffer` as an intermediate target.
|
|
|
|
All of that is just for printing to the screen. If you want to read input you have to use the `WindowContext` which is a `TermWriteable`.
|
|
`WindowContext` also handles events like `onClick` or `onKey`. This is need so that the right program gets the input depending on the active window on the
|
|
screen or terminal.
|
|
|
|
All of the `WindowContext` are managed by the `WindowManager`. The `WindowManager` also delegates the events to the right `WindowContext`.
|
|
|
|
## GUI helper classes
|
|
|
|
Because we want a more abstract way of writing to the screen we have some "helper" classes. I call them "helper" but they a very essential to the GUI.
|
|
|
|
First there is the `Pixel` class which is nothing more that a char and a foreground and background color.
|
|
|
|
A collection of `Pixel` is called a `Canvas` which is nothing more than a 2D array of `Pixel` with some functions strapped to it.
|
|
|
|
# Proceses
|
|
|
|
The concept of processes tryes to encapsulate programs. A process is basically an interface with the `run(handle: ProcessHandle)` method.
|
|
The idea is that you can register all you disposable resources in the handle and they will be disposed when the process is killed or crashes.
|
|
|
|
A process can be used as a command on the terminal or as a service. See [bin/HelloWorld.hx](../src/bin/HelloWorld.hx) for an example.
|
|
Basically everything that runs and is not part of the kernel is a process.
|
|
|
|
In order for you program to be used it needs to be registered in the `BinStore` and the `DCEHack` manually.
|
|
|
|
# EndOfLoop
|
|
|
|
You can imagine the whole runtime like the event loop is JS. The `EndOfLoop` class is used to register callbacks that are called at the end of the loop.
|
|
This is like the `setTimeout(0, callback)` in JS.
|