53 lines
2.4 KiB
Markdown
53 lines
2.4 KiB
Markdown
# Architecture
|
|
|
|
## File layout
|
|
|
|
```
|
|
player/
|
|
├── build.jai # metaprogram, sets import_path
|
|
├── CLAUDE.md # project context
|
|
├── ai/ # AI-collaboration notes
|
|
├── data/ # fonts, static assets
|
|
├── modules/ # vendored: Jaison, stb_image
|
|
└── src/
|
|
├── main.jai # tiny entry, #loads each index.jai
|
|
├── core/index.jai # app state, window, time
|
|
├── jellyfin/index.jai # http client + endpoints
|
|
├── audio/index.jai # Sound_Player wrapper, queue, FFT
|
|
├── ui/index.jai # theme, fonts, views
|
|
├── gfx/index.jai # custom shaders, textures
|
|
└── util/index.jai # log, helpers
|
|
```
|
|
|
|
## Convention: `index.jai` per folder
|
|
|
|
Each folder has an `index.jai` that `#load`s every other `.jai` file in the folder. `main.jai` only loads the `index.jai` files. This keeps `main.jai` ~10 lines and lets us add a new file by editing one `#load` line.
|
|
|
|
## Convention: one giant `App` struct
|
|
|
|
`core/app.jai` defines `App :: struct { ... }` and a global `app: App;`. Everything that needs to live across frames hangs off `app` — the window handle, fonts, the jellyfin client, the audio player, the UI state, the current view.
|
|
|
|
This is on purpose. We don't want plumbing arguments through five layers. The whole codebase has implicit access to `app`.
|
|
|
|
## Convention: views
|
|
|
|
A "view" is a screen (login, library, now-playing). Each lives in `src/ui/views/<name>_view.jai` and exposes one proc:
|
|
|
|
```jai
|
|
draw_<name>_view :: (dt: float)
|
|
```
|
|
|
|
`app.current_view` is an enum that picks which one runs each frame. Transitions are `app.current_view = .LIBRARY;`.
|
|
|
|
## Convention: HTTP
|
|
|
|
`jellyfin/client.jai` wraps libcurl with a small `http_get` / `http_post` helper that returns a string body + status code. The auth token gets stamped into headers automatically once `auth.login()` succeeds.
|
|
|
|
## Convention: audio
|
|
|
|
`audio/player.jai` owns a single `*Sound_Stream` for the currently playing track plus a queue of pending tracks. `Sound_Player` handles the actual decoding and output.
|
|
|
|
## Convention: gfx
|
|
|
|
`gfx/shaders.jai` keeps GLSL strings inline (compiled via Simp's GL backend). The visualizer is a fullscreen quad with a fragment shader that reads from FFT data uploaded as a 1D texture.
|