Download Game! Currently 79 players and visitors. Last logged in:PaziOnniferPereTohvu

Blitzer's Blog >> 71763

Back to blogs index
Posted: 17 Aug 2026 14:50 [ permalink ]
TC$mC$ on aivan loistava lisC$ys, ja se sitoo koko arkkitehtuurin
tC$ydellisesti yhteen. Tuot kC$ytC$nnC6ssC$ puhtaan **UNIX-filosofian ja
POSIX-standardin (File Descriptors) suoraan selaimen kC$yttC6liittymC$kerroksee
n**.

TC$mC$ on nerokasta siksi, ettC$ kun jokaisella Window/App -instanssilla on
oma `stdin` (0), `stdout` (1) ja `stderr` (2), kC$yttC6liittymC$komponentit
lakkaavat olemasta vain tyhmiC$ laatikoita ruudulla. NiistC$ tulee
itsenC$isiC$ prosesseja, joiden dataa voidaan putkittaa (pipe) aivan kuten
bashissa: ikkunan A tuloste voidaan ohjata suoraan ikkunan B syC6tteeksi, tai
kopioida takaisin backendiin!

Puretaan tC$mC$ selkeiksi rutiineiksi ja kC$sitteiksi, jotta voimme koodata ne
modulaarisesti:

### 1. Agnostinen API (Syscalls & Intent Router)

Jotta on tC$ysin sama, kutsutaanko rutiinia DevConsolesta, backendin MESH JSON
-paketista vai toisesta sovelluksesta, erotamme API:n kahteen kerrokseen:

* **Kernel Routines:** Itse funktiot (esim. `sys_workspace_create()`,
`sys_app_spawn()`).
* **Intent Router:** Yksi ainoa portti, joka ottaa vastaan JSON-muotoisen
"Intentin" ja ohjaa sen oikealle Kernel-rutiinille.

Kaikki kommunikaatio kulkee Intent Routerin lC$pi. Jos backend lC$hettC$C$
`{"op": "spawn", "target": "clock"}`, se on identtinen sen kanssa, ettC$
kC$yttC$jC$ kirjoittaa selaimeen `Core.intent({op: "spawn", target:
"clock"})`.

### 2. Standard I/O (Tiedostokuvaajat / Descriptors)

MC$C$ritellC$C$n jokaiselle TASK/APP-objektille abstrakti I/O-taulukko (File
Descriptors eli FD).

* `fd[0]` = **stdin** (SyC6te)
* `fd[1]` = **stdout** (Normaali tuloste)
* `fd[2]` = **stderr** (Virhetuloste)
* `fd[3...n]` = Custom-kuvaajat (Esimerkiksi grafiikkapuskurin suora
videostream toiselle ohjelmalle).

TehdC$C$n ytimeen selkeC$t rutiinit nC$iden hallintaan:

* `App.write(fd, data)`: Ohjelma kirjoittaa omaan kuvaajaansa.
* `App.onRead(fd, callback)`: Ohjelma kuuntelee omaan syC6tteeseensC$ tulevaa
dataa.
* **Piping (Ohjaus):** Rutiini `Sys.pipe(app1, 1, app2, 0)`, joka "kytkee
kaapelin" ohjelman 1 `stdout`:n ja ohjelman 2 `stdin`:n vC$lille.

### 3. Globaali Dmesg-puskuri (Root Buffer)

Kuten suunnittelit, tarvitsemme "turvaverkon" kaikelle outputille, jota ei ole
erikseen ohjattu minnekC$C$n (piped).

* Kun App kirjoittaa `fd[1]` tai `fd[2]`, ydin tarkistaa, onko tC$llC$
kuvaajalla tilaajia (subscribers).
* Jos ei ole, data valuu automaattisesti ytimen globaaliin **Root Bufferiin**
(esim. taulukko `MeshOS.dmesg`).
* TC$mC$ rutiini tulostaa datan samalla selaimen `console.log()` /
`console.error()` -virtaan, jolloin ohjelmoija nC$kee sen heti DevToolsista.
* Koska `dmesg` on globaali taulukko, mikC$ tahansa uusi sovellus (esimerkiksi
graafinen "Log Viewer" -ikkuna) voi hakea sieltC$ koko historian sekunnin
murto-osassa `MeshOS.getDmesg()` -kutsulla.

---

### Miten tC$mC$ kootaan ohjelmallisesti?

Jos hahmottelemme tC$mC$n < 150 rivin moduuliksi, se voisi nC$yttC$C$
rakenteellisesti tC$ltC$ (pseudo-konseptina):

```javascript
/ Konseptiluonnos: Process / App I/O
class Process {
  constructor(id, pid) {
    this.id = id;
    this.pid = pid;
    this.fds = {
      0: { type: 'in',  handlers: [] },
      1: { type: 'out', targets: [] }, // Default: tyhjC$ = valuu dmesgiin
      2: { type: 'out', targets: [] }  // Default: tyhjC$ = valuu dmesgiin
    };
  }

  // Ohjelma tulostaa jotain
  write(fd, data) {
    const stream = this.fds[fd];
    if (stream.targets.length === 0 && (fd === 1 || fd === 2)) {
      // Ei ohjausta, menee dmesg-puskuriin!
      MeshOS.Syslog.push({ pid: this.pid, fd, data, ts: Date.now() });
      if (fd === 2) console.error(`[PID ${this.pid}]`, data);
      else console.log(`[PID ${this.pid}]`, data);
    } else {
      // Ohjattu eteenpC$in (Piped)
      stream.targets.forEach(target => target.receive(data));
    }
  }
}

```

TC$mC$ arkkitehtuuri on uskomattoman kestC$vC$. Jos jokin ikkuna kaatuu tai se
poistetaan, I/O-putki vain katkeaa, ja data alkaa taas valua siististi
turvalliseen `dmesg`-puskuriin ilman, ettC$ selain heittC$C$ fatal erroria.

==