# Playbit API reference

This page contains the runtime, playbit-c, and playbit-ui API reference.

It's also [available as markdown](api.md).

# Runtime types

## Type aliases

### `PBSysAudioBuffer`

```c
typedef i64 PBSysAudioBuffer;
```

`Handle` to the sound mixer buffer and sound handles (u32 id, gen)

### `PBSysAudioSound`

```c
typedef i64 PBSysAudioSound;
```

### `PBSysCanvasGradientFlags`

```c
typedef u32 PBSysCanvasGradientFlags;
```

GRADIENT cmd.flags. HUE_LONGER selects the longer hue arc between adjacent
stops (OKLCH space only; default is the shorter arc).

### `PBSysCanvasMaskFlags`

```c
typedef u32 PBSysCanvasMaskFlags;
```

PBSysCanvasMaskFlags select how mask coverage is computed from the mask's
rendered pixels. Default (0) uses the alpha channel.

### `PBSysCanvasStrokeFlags`

```c
typedef u32 PBSysCanvasStrokeFlags;
```

### `PBSysCursorStyleFlags`

```c
typedef u64 PBSysCursorStyleFlags;
```

### `PBSysDate`

```c
typedef i64 PBSysDate;
```

PBSysDate represents a point in "real" time (microseconds since 1970-01-01 00:00:00 UTC.)
Range limit: [290309 BCE, Dec 22, 19:59:05 UTC - 294247, Jan 10, 04:00:54 UTC]

### `PBSysDuration`

```c
typedef i64 PBSysDuration;
```

PBSysDuration represents a duration of time, measured in nanoseconds.

### `PBSysFileMode`

```c
typedef u16 PBSysFileMode;
```

### `PBSysGuiPrefsFlags`

```c
typedef u64 PBSysGuiPrefsFlags;
```

### `PBSysGuiPresentation`

```c
typedef i64 PBSysGuiPresentation;
```

### `PBSysHandle`

```c
typedef i32 PBSysHandle;
```

PBSysHandle represents a handle to a runtime object.
A handle can be thought of as a session or connection to a particular runtime object.
Note: negative values signifies `PBSysErr` and are invalid as handles.

### `PBSysHandleName`

```c
typedef u16 PBSysHandleName;
```

PBSysHandleName names special well-defined objects

### `PBSysNetTransportFlags`

```c
typedef u32 PBSysNetTransportFlags;
```

### `PBSysNetTransportStreamFlags`

```c
typedef u64 PBSysNetTransportStreamFlags;
```

PBSysNetTransportStreamFlags control behavior of `PBSysNetTransportOpenStream`

### `PBSysObjectId`

```c
typedef u32 PBSysObjectId;
```

PBSysObjectId uniquely identifies a system object

### `PBSysRights`

```c
typedef u32 PBSysRights;
```

PBSysRights are associated with handles and convey privileges to perform actions on either the associated handle or the object associated with the handle.

### `PBSysSignals`

```c
typedef u32 PBSysSignals;
```

PBSysSignals is a bitset of signals.
- Bits 1 through 24 are reserved for the system.
- Bits 25 through 32 are reserved for user-defined signals.

### `PBSysTextureCreateFlags`

```c
typedef u32 PBSysTextureCreateFlags;
```

### `PBSysTime`

```c
typedef u64 PBSysTime;
```

PBSysTime represents a point in system time (nanoseconds in monotonic-clock space)

### `PBSysWindowCreateTextureFlags`

```c
typedef PBSysTextureCreateFlags PBSysWindowCreateTextureFlags;
```

PBSysWindowCreateTextureFlags is deprecated; use `PBSysTextureCreateFlags`

### `PBSysWindowFullScreenFlags`

```c
typedef u64 PBSysWindowFullScreenFlags;
```

### `PBSysWindowOpenSurfaceCanvasFlags`

```c
typedef u64 PBSysWindowOpenSurfaceCanvasFlags;
```

### `PBSysWindowRenderFlags`

```c
typedef u64 PBSysWindowRenderFlags;
```

### `PBSysWindowSetRectFlags`

```c
typedef u64 PBSysWindowSetRectFlags;
```

### `PBSysWindowStyle`

```c
typedef u64 PBSysWindowStyle;
```

### `PBTextPlanLayoutFlags`

```c
typedef u32 PBTextPlanLayoutFlags;
```

## Function pointers

### `PBSysThreadEntry`

```c
typedef void (*PBSysThreadEntry)(uint64_t, uint64_t);
```

PBSysThreadEntry

## Enums

### `PBSysAudioSoundPlaybackFlags`

```c
typedef enum PB_ENUM_TYPE(u64) {
    PBSysAudioSoundPlaybackFlag_RESUME = 1 << 0,      // resume (instead of pause)
    PBSysAudioSoundPlaybackFlag_RESUME_LOOP = 1 << 1, // restart playback when end is reached
} PBSysAudioSoundPlaybackFlags;
```

PBSysAudioSoundPlaybackFlags describe possible flags for `PBSysAudioSoundPlayback`

### `PBSysCallOp`

```c
typedef enum PBSysCallOp PB_ENUM_TYPE(uint32_t){
    PBSysCallOp_None = 0, // invalid
    PBSysCallOp_AudioBufferCreate = 117,
    PBSysCallOp_AudioBufferCreateFromFile = 121,
    PBSysCallOp_AudioBufferDestroy = 118,
    PBSysCallOp_AudioBufferPlay = 119,
    PBSysCallOp_AudioBufferPlayAfter = 165,
    PBSysCallOp_AudioBufferUpload = 167,
    PBSysCallOp_AudioOutputInit = 122,
    PBSysCallOp_AudioSetVolume = 120,
    PBSysCallOp_AudioSoundGetPosition = 166,
    PBSysCallOp_AudioSoundIsPlaying = 168,
    PBSysCallOp_AudioSoundPlayback = 174,
    PBSysCallOp_AudioSoundSeek = 172,
    PBSysCallOp_AudioSoundTell = 173,
    PBSysCallOp_CanvasCreateTexture = 157,
    PBSysCallOp_CanvasCreateTextureFromData = 158,
    PBSysCallOp_CanvasOpen = 159,
    PBSysCallOp_CanvasRender = 155,
    PBSysCallOp_CanvasResize = 162,
    PBSysCallOp_ChannelCreate = 65,
    PBSysCallOp_ChannelDisableWrite = 68,
    PBSysCallOp_ChannelRead = 66,
    PBSysCallOp_ChannelWrite = 67,
    PBSysCallOp_ClockMonotonic = 56,
    PBSysCallOp_ClockRead = 25,
    PBSysCallOp_ClockReadInfo = 60,
    PBSysCallOp_EventPoll = 58,
    PBSysCallOp_FileListOpen = 98,
    PBSysCallOp_FileOpen = 103,
    PBSysCallOp_FileRead = 104,
    PBSysCallOp_FileWrite = 105,
    PBSysCallOp_FileListNext = 102,
    PBSysCallOp_FilePanelGetResult = 143,
    PBSysCallOp_GuiPrefsGet = 170,
    PBSysCallOp_GuiPresentationGet = 135,
    PBSysCallOp_GuiPresentationSet = 136,
    PBSysCallOp_HandleClose = 70,
    PBSysCallOp_HandleDuplicate = 71,
    PBSysCallOp_HandleList = 77,
    PBSysCallOp_HidDeviceInfoGet = 150,
    PBSysCallOp_HidDeviceName = 149,
    PBSysCallOp_HidDeviceSetPlayerIndex = 148,
    PBSysCallOp_NetDecrypt = 131,
    PBSysCallOp_NetDecryptAsymmetric = 141,
    PBSysCallOp_NetEncrypt = 130,
    PBSysCallOp_NetEncryptAsymmetric = 142,
    PBSysCallOp_NetSessionOpen = 90,
    PBSysCallOp_NetTransportOpen = 132,
    PBSysCallOp_NetSessionId = 93,
    PBSysCallOp_NetSessionOpenStream = 91,
    PBSysCallOp_NetTransportOpenStream = 133,
    PBSysCallOp_NetTransportSetKeepAlive = 134,
    PBSysCallOp_ObjectFeatures = 153,
    PBSysCallOp_ObjectObserve = 57,
    PBSysCallOp_ObjectSignal = 55,
    PBSysCallOp_StreamOpenPipePair = 92,
    PBSysCallOp_StreamRead = 46,
    PBSysCallOp_StreamStatsRead = 94,
    PBSysCallOp_StreamWrite = 28,
    PBSysCallOp_TextplanGetCaretBounds = 81,
    PBSysCallOp_TextplanGetSelectionRects = 83,
    PBSysCallOp_TextplanGetSize = 38,
    PBSysCallOp_TextplanHitTest = 82,
    PBSysCallOp_TextplanLayout = 40,
    PBSysCallOp_TextplanMoveSelection = 85,
    PBSysCallOp_TextplanMoveSelectionToPoint = 84,
    PBSysCallOp_TextplanMoveSelectionVertical = 88,
    PBSysCallOp_TextureGetHeight = 145,
    PBSysCallOp_TextureGetWidth = 146,
    PBSysCallOp_TextureWrite = 106,
    PBSysCallOp_ThreadEnterMain = 59,
    PBSysCallOp_ThreadExit = 30,
    PBSysCallOp_ThreadExitProcess = 31,
    PBSysCallOp_ThreadExitStatus = 47,
    PBSysCallOp_ThreadHostControllerConnect = 79,
    PBSysCallOp_ThreadHostControllerRequest = 163,
    PBSysCallOp_ThreadLogWrite = 32,
    PBSysCallOp_ThreadNetConnect = 42,
    PBSysCallOp_ThreadRead = 76,
    PBSysCallOp_ThreadReadRandom = 139,
    PBSysCallOp_ThreadStart = 33,
    PBSysCallOp_ThreadWGpuOp = 160,
    PBSysCallOp_ThreadWGpuOpAsync = 161,
    PBSysCallOp_ThreadWindowCreate = 41,
    PBSysCallOp_ThreadWrite = 75,
    PBSysCallOp_WindowClipboardReadText = 107,
    PBSysCallOp_WindowClipboardWriteText = 108,
    PBSysCallOp_WindowCopyTitle = 126,
    PBSysCallOp_WindowCreateTexture = 109,
    PBSysCallOp_WindowCreateTextureFromData = 110,
    PBSysCallOp_WindowFilePanelCreate = 144,
    PBSysCallOp_WindowFrameSyncEnable = 63,
    PBSysCallOp_WindowFullScreenGet = 137,
    PBSysCallOp_WindowFullScreenSet = 138,
    PBSysCallOp_WindowInfoGet = 64,
    PBSysCallOp_WindowOpenSurfaceCanvas = 156,
    PBSysCallOp_WindowSetCursor = 151,
    PBSysCallOp_WindowSetRect = 87,
    PBSysCallOp_WindowSetRenderFlags = 152,
    PBSysCallOp_WindowSetStyle = 127,
    PBSysCallOp_WindowSetTitle = 80,
    PBSysCallOp_WindowSizeLimitsSet = 128,
    PBSysCallOp_WindowTextplanCreate = 36,
    PBSysCallOp_WindowTextplanCreate2 = 154,
    PBSysCallOp_WindowWorkspaceOpenURL = 171,
    PBSysCallOp_READ = 9,               // legacy
    PBSysCallOp_CURSOR = 14,            // legacy
    PBSysCallOp_RES_CREATE = 15,        // legacy
    PBSysCallOp_RES_MUTATE = 16,        // legacy
    PBSysCallOp_RES_ADVERTISE_NEW = 17, // legacy
    PBSysCallOp_TAKE_ROOT_CAP = 18,     // legacy
    PBSysCallOp_OPEN = 19,              // legacy
} PBSysCallOp;
```

PBSysCallOp defines all syscall operations

### `PBSysCanvasBlendMode`

```c
typedef enum PBSysCanvasBlendMode PB_ENUM_TYPE(u16){
    PBSysCanvasBlendMode_NORMAL = 0,
    PBSysCanvasBlendMode_DARKEN,
    PBSysCanvasBlendMode_MULTIPLY,
    PBSysCanvasBlendMode_PLUS_DARKER,
    PBSysCanvasBlendMode_COLOR_BURN,
    PBSysCanvasBlendMode_LIGHTEN,
    PBSysCanvasBlendMode_SCREEN,
    PBSysCanvasBlendMode_PLUS_LIGHTER,
    PBSysCanvasBlendMode_COLOR_DODGE,
    PBSysCanvasBlendMode_OVERLAY,
    PBSysCanvasBlendMode_SOFT_LIGHT,
    PBSysCanvasBlendMode_HARD_LIGHT,
    PBSysCanvasBlendMode_DIFFERENCE,
    PBSysCanvasBlendMode_EXCLUSION,
    PBSysCanvasBlendMode_HUE,
    PBSysCanvasBlendMode_SATURATION,
    PBSysCanvasBlendMode_COLOR,
    PBSysCanvasBlendMode_LUMINOSITY,
    PBSysCanvasBlendMode_MAX_ = PBSysCanvasBlendMode_LUMINOSITY,
} PBSysCanvasBlendMode;
```

PBSysCanvasBlendMode is a Figma-style color blend mode, applied when a
group is composited into its parent.

### `PBSysCanvasCmdKind`

```c
typedef enum PBSysCanvasCmdKind PB_ENUM_TYPE(u16){
    PBSysCanvasCmdKind_INVALID = 0,
    PBSysCanvasCmdKind_RECT,           // PBSysCanvasCmdRect
    PBSysCanvasCmdKind_ROUNDED_RECT,   // PBSysCanvasCmdRoundedRect
    PBSysCanvasCmdKind_STROKE_RECT,    // PBSysCanvasCmdStrokeRect
    PBSysCanvasCmdKind_COMPLEX_RECT,   // PBSysCanvasCmdComplexRect
    PBSysCanvasCmdKind_GRADIENT_RECT,  // PBSysCanvasCmdGradientRect
    PBSysCanvasCmdKind_TEXT,           // PBSysCanvasCmdText
    PBSysCanvasCmdKind_CLIP_PUSH,      // PBSysCanvasCmdClipPush
    PBSysCanvasCmdKind_CLIP_POP,       // PBSysCanvasCmdClipPop
    PBSysCanvasCmdKind_TEXTURE_SET,    // PBSysCanvasCmdTextureSet
    PBSysCanvasCmdKind_TRANSFORM_PUSH, // PBSysCanvasCmdTransformPush
    PBSysCanvasCmdKind_TRANSFORM_POP,  // PBSysCanvasCmdTransformPop
    PBSysCanvasCmdKind_GROUP_PUSH,     // PBSysCanvasCmdGroupPush
    PBSysCanvasCmdKind_GROUP_POP,      // PBSysCanvasCmdGroupPop
    PBSysCanvasCmdKind_GROUP_MASK,     // PBSysCanvasCmdGroupMask
    PBSysCanvasCmdKind_GRADIENT,       // PBSysCanvasCmdGradient
    PBSysCanvasCmdKind_MESH_GRADIENT,  // PBSysCanvasCmdMeshGradient
} PBSysCanvasCmdKind;
```

### `PBSysCanvasFeature`

```c
typedef enum PBSysCanvasFeature {
    PBSysCanvasFeature_HDR, // supports >1.0 color values for extended dynamic range
} PBSysCanvasFeature;
```

PBSysCanvasFeature defines features of canvas objects.
These constants are bit positions of the bitmask returned by `PBSysObjectFeatures`

### `PBSysCanvasGradientKind`

```c
typedef enum PBSysCanvasGradientKind PB_ENUM_TYPE(u16){
    PBSysCanvasGradientKind_LINEAR = 0, // p0 -> p1 is the ramp axis
    PBSysCanvasGradientKind_RADIAL = 1, // p0 = center, |p1 - p0| = the t=1 radius
    PBSysCanvasGradientKind_CONIC = 2,  // p0 = center, atan2(p1 - p0) = the t=0 angle
    PBSysCanvasGradientKind_MAX_ = PBSysCanvasGradientKind_CONIC,
} PBSysCanvasGradientKind;
```

PBSysCanvasGradientKind selects the geometry of a GRADIENT command's ramp.

### `PBSysCanvasGradientSpace`

```c
typedef enum PBSysCanvasGradientSpace PB_ENUM_TYPE(u16){
    PBSysCanvasGradientSpace_LINEAR_P3 = 0, // working space (cheapest)
    PBSysCanvasGradientSpace_OKLAB = 1,     // perceptual; CSS oklab behavior
    PBSysCanvasGradientSpace_OKLCH = 2,     // polar OKLab; hue-arc interpolation
    PBSysCanvasGradientSpace_MAX_ = PBSysCanvasGradientSpace_OKLCH,
} PBSysCanvasGradientSpace;
```

PBSysCanvasGradientSpace selects the color space stops are interpolated in.
Colors are always submitted as wire colors (linear P3); the runtime
converts them to the interpolation space.

### `PBSysCanvasGradientSpread`

```c
typedef enum PBSysCanvasGradientSpread PB_ENUM_TYPE(u16){
    PBSysCanvasGradientSpread_PAD = 0,     // clamp to the edge stops
    PBSysCanvasGradientSpread_REPEAT = 1,  // fract(t)
    PBSysCanvasGradientSpread_REFLECT = 2, // triangle wave
    PBSysCanvasGradientSpread_MAX_ = PBSysCanvasGradientSpread_REFLECT,
} PBSysCanvasGradientSpread;
```

PBSysCanvasGradientSpread defines ramp behavior outside t in [0, 1].

### `PBSysCanvasTextFlags`

```c
typedef enum PB_ENUM_TYPE(u32) {
    PBSysCanvasTextFlag_OVERRIDE_COLOR = 1u << 0,
} PBSysCanvasTextFlags;
```

### `PBSysChannelFlags`

```c
enum PBSysChannelFlags PB_ENUM_TYPE(uint32_t){
    PBSysChannel_DUPLEX = 1u << 0,           // created handles support both reading and writing
    PBSysChannel_MULTIPLE_WRITERS = 1u << 1, // support multiple concurrent threads writing
    PBSysChannel_MULTIPLE_READERS = 1u << 2, // support multiple concurrent threads reading
};
```

### `PBSysChannelSignals`

```c
typedef enum PB_ENUM_TYPE(uint32_t) {
    PBSysChannelSignal_READABLE = 1u << 0,       // there are entries to read
    PBSysChannelSignal_WRITABLE = 1u << 1,       // there's space for writing at least one entry
    PBSysChannelSignal_WRITE_DISABLED = 1u << 2, // writing has been closed
} PBSysChannelSignals;
```

### `PBSysClockSignals`

```c
typedef enum PB_ENUM_TYPE(uint32_t) {
    PBSysClockSignal_TIME_ZONE = 1u << 0, // time zone changed (pulse)
} PBSysClockSignals;
```

PBSysClockSignals describe signals available for clocks (in addition to USER signals)

### `PBSysCursorStyle`

```c
typedef enum PBSysCursorStyle PB_ENUM_TYPE(uint16_t){
    PBSysCursorStyle_DEFAULT = 0,
    PBSysCursorStyle_ARROW = 1,
    PBSysCursorStyle_TEXT = 2,
    PBSysCursorStyle_TEXT_VERTICAL = 3,
    PBSysCursorStyle_POINTING_HAND = 4,
    PBSysCursorStyle_CLOSED_HAND = 5,
    PBSysCursorStyle_OPEN_HAND = 6,
    PBSysCursorStyle_RESIZE_N = 10,     // ↑ up
    PBSysCursorStyle_RESIZE_NE = 20,    // ↗ up right
    PBSysCursorStyle_RESIZE_E = 8,      // → right
    PBSysCursorStyle_RESIZE_SE = 21,    // ↘ down right
    PBSysCursorStyle_RESIZE_S = 11,     // ↓ down
    PBSysCursorStyle_RESIZE_SW = 22,    // ↙ down left
    PBSysCursorStyle_RESIZE_W = 7,      // ← left
    PBSysCursorStyle_RESIZE_NW = 23,    // ↖ up left
    PBSysCursorStyle_RESIZE_W_E = 9,    // ↔︎ left & right
    PBSysCursorStyle_RESIZE_N_S = 12,   // ↕︎ up & down
    PBSysCursorStyle_RESIZE_NE_SW = 24, // ⤢ up right & down left
    PBSysCursorStyle_RESIZE_NW_SE = 25, // ⤡ up left & down right
    PBSysCursorStyle_MOVE_N = 26,       // ↑ move a horizontal divider line upwards
    PBSysCursorStyle_MOVE_S = 27,       // ↓ move a horizontal divider line downwards
    PBSysCursorStyle_MOVE_N_S = 28,     // ↕︎ move a horizontal divider line up or down
    PBSysCursorStyle_MOVE_W = 29,       // ← move a vertical divider line leftwards
    PBSysCursorStyle_MOVE_E = 30,       // → move a vertical divider line rightwards
    PBSysCursorStyle_MOVE_W_E = 31,     // ↔︎ move a vertical divider line left or right
    PBSysCursorStyle_MOVE_N_S_W_E = 32, // + move two intersecting divider lines
    PBSysCursorStyle_CROSSHAIR = 13,
    PBSysCursorStyle_DISAPPEARING_ITEM = 14,
    PBSysCursorStyle_NOT_ALLOWED = 15,
    PBSysCursorStyle_DRAG_LINK = 16,
    PBSysCursorStyle_DRAG_COPY = 17,
    PBSysCursorStyle_CONTEXT_MENU = 18,
    PBSysCursorStyle_CUSTOM_IMAGE = 19,

    // deprecated names (August 2026, version 0.5)
    PBSysCursorStyle_RESIZE_LEFT = PBSysCursorStyle_RESIZE_W,
    PBSysCursorStyle_RESIZE_RIGHT = PBSysCursorStyle_RESIZE_E,
    PBSysCursorStyle_RESIZE_LEFT_RIGHT = PBSysCursorStyle_RESIZE_W_E,
    PBSysCursorStyle_RESIZE_UP = PBSysCursorStyle_RESIZE_N,
    PBSysCursorStyle_RESIZE_DOWN = PBSysCursorStyle_RESIZE_S,
    PBSysCursorStyle_RESIZE_UP_DOWN = PBSysCursorStyle_RESIZE_N_S,
} PBSysCursorStyle;
```

deprecated names (August 2026, version 0.5)

### `PBSysCursorStyleFlag`

```c
enum PBSysCursorStyleFlag PB_ENUM_TYPE(PBSysCursorStyleFlags){
    PBSysCursorStyleFlag_HIDDEN = 1 << 0,
};
```

### `PBSysErr`

```c
typedef enum PB_ENUM_TYPE(int32_t) {
    PBSysErr_NONE = 0,            // no error
    PBSysErr_INVALID = -1,        // invalid data
    PBSysErr_NO_MEM = -2,         // cannot allocate memory
    PBSysErr_BAD_HANDLE = -3,     // invalid handle
    PBSysErr_BAD_NAME = -4,       // invalid or misformed name
    PBSysErr_NOT_FOUND = -5,      // resource not found
    PBSysErr_NAME_TOO_LONG = -6,  // name too long
    PBSysErr_CANCELED = -7,       // operation canceled
    PBSysErr_NOT_SUPPORTED = -8,  // not supported
    PBSysErr_EXISTS = -9,         // already exists
    PBSysErr_END = -10,           // end of resource
    PBSysErr_ACCESS_DENIED = -11, // access denied
    PBSysErr_AGAIN = -12,         // temporarily unavailable
    PBSysErr_DEFERRED = -13,      // operation deferred
    PBSysErr_ALREADY = -14,       // operation already in progress
    PBSysErr_IO_ERR = -15,        // I/O error
    PBSysErr_BAD_ADDRESS = -16,   // bad address

    /*
    PBSysErr_SHOULD_WAIT indicates that the operation cannot currently be performed but could succeed if the caller waits for a prerequisite to be satisfied. For example, waiting for a thread to terminate before reading its exit status.
    */
    PBSysErr_SHOULD_WAIT = -17,

    PBSysErr_TIMEOUT = -18, // deadline reached

    // PBSysErr_BUFFER_TOO_SMALL indicates that a caller-provided buffer is too small
    PBSysErr_BUFFER_TOO_SMALL = -19,

    PBSysErr_BAD_MODE = -20,  // unsupported or invalid mode
    PBSysErr_TOO_LARGE = -21, // value too large, e.g. overflow or limit
    PBSysErr_BUSY = -22,      // resource busy

    PBSysErr_UNKNOWN = -2000000000, // unknown or internal error
} PBSysErr;
```

PBSysErr defines error codes

### `PBSysEventType`

```c
typedef enum PBSysEventType PB_ENUM_TYPE(u16){
    PBSysEventType_INVALID = 0,

    // signal
    PBSysEventType_SIGNAL,

    // pointer
    PBSysEventType_POINTER_ENTER, // pointer started being "in" the surface/window
    PBSysEventType_POINTER_LEAVE, // pointer left the surface/window
    PBSysEventType_POINTER_DOWN,
    PBSysEventType_POINTER_UP,
    PBSysEventType_POINTER_MOVE,
    PBSysEventType_POINTER_CANCEL, // system canceled a sequence (e.g. OS interruption)

    // scroll
    PBSysEventType_SCROLL,

    // gesture
    PBSysEventType_GESTURE_PAN,    // translation (typically dp)
    PBSysEventType_GESTURE_PINCH,  // scale factor (relative)
    PBSysEventType_GESTURE_ROTATE, // radians (relative)

    // keyboard
    PBSysEventType_KEY_DOWN,
    PBSysEventType_KEY_UP,

    // file panels
    PBSysEventType_FILE_PANEL_CLOSED,

    // gamepad
    PBSysEventType_GAMEPAD_CONNECTED,
    PBSysEventType_GAMEPAD_DISCONNECTED,
    PBSysEventType_GAMEPAD_BUTTON_DOWN,
    PBSysEventType_GAMEPAD_BUTTON_UP,
    PBSysEventType_GAMEPAD_AXIS_MOVE,

    // webgpu
    PBSysEventType_WGPU_CALLBACK,
} PBSysEventType;
```

PBSysEventType defines the type of a `PBSysEvent` entry

### `PBSysFileListEntryType`

```c
typedef enum PBSysFileListEntryType PB_ENUM_TYPE(u8){
    PBSysFileListEntryType_UNKNOWN = 0,   // underlying filesyestem does not report types
    PBSysFileListEntryType_DIR = 1,       // directory
    PBSysFileListEntryType_FILE = 2,      // regular file
    PBSysFileListEntryType_LINK = 3,      // symbolic link
    PBSysFileListEntryType_SOCKET = 4,    // local socket
    PBSysFileListEntryType_SPECIAL = 100, // none of the above (e.g. fifo, char dev. etc.)
} PBSysFileListEntryType;
```

### `PBSysFileModes`

```c
enum PBSysFileModes PB_ENUM_TYPE(PBSysFileMode){
    PBSysFileMode_USER_R = 0400,    // user (file owner) has read permission
    PBSysFileMode_USER_W = 0200,    // user has write permission
    PBSysFileMode_USER_X = 0100,    // user has execute permission
    PBSysFileMode_USER_RW = 0600,   // user has read and write permissions
    PBSysFileMode_USER_RWX = 0700,  // user has read, write, and execute permissions
    PBSysFileMode_GROUP_R = 0040,   // group has read permission
    PBSysFileMode_GROUP_W = 0020,   // group has write permission
    PBSysFileMode_GROUP_X = 0010,   // group has execute permission
    PBSysFileMode_GROUP_RW = 0060,  // group has read and write execute permissions
    PBSysFileMode_GROUP_RWX = 0070, // group has read, write, and execute permissions
    PBSysFileMode_OTHER_R = 0004,   // others have read permission
    PBSysFileMode_OTHER_W = 0002,   // others have write permission
    PBSysFileMode_OTHER_X = 0001,   // others have execute permission
    PBSysFileMode_OTHER_RW = 0006,  // others have read and write execute permissions
    PBSysFileMode_OTHER_RWX = 0007, // others have read, write, and execute permissions
};
```

### `PBSysFileOpenFlags`

```c
typedef enum PBSysFileOpenFlags PB_ENUM_TYPE(u64){
    PBSysFileOpenFlag_READ = 1 << 0,                               // give file PBSysRight_READ
    PBSysFileOpenFlag_WRITE = 1 << 1,                              // give file PBSysRight_WRITE
    PBSysFileOpenFlag_APPEND = (1 << 2) | PBSysFileOpenFlag_WRITE, // open in append mode
    PBSysFileOpenFlag_TRUNCATE = 1 << 3, // truncate to length 0 (only valid with WRITE)

    PBSysFileOpenFlag_EXCLUSIVE = 1 << 6, // fail if file exists (only valid with CREATE)
    PBSysFileOpenFlag_CREATE = 1 << 7,    // create file if it does not exist

    // PBSysFileOpenFlag_MODE_MASK masks mode bits in flags, for use with CREATE flag
    PBSysFileOpenFlag_MODE_MASK = 0xffff << 8,
    PBSysFileOpenFlag_MODE_USER_R = PBSysFileMode_USER_R << 8,
    PBSysFileOpenFlag_MODE_USER_W = PBSysFileMode_USER_W << 8,
    PBSysFileOpenFlag_MODE_USER_X = PBSysFileMode_USER_X << 8,
    PBSysFileOpenFlag_MODE_USER_RW = PBSysFileMode_USER_RW << 8,
    PBSysFileOpenFlag_MODE_USER_RWX = PBSysFileMode_USER_RWX << 8,
    PBSysFileOpenFlag_MODE_GROUP_R = PBSysFileMode_GROUP_R << 8,
    PBSysFileOpenFlag_MODE_GROUP_W = PBSysFileMode_GROUP_W << 8,
    PBSysFileOpenFlag_MODE_GROUP_X = PBSysFileMode_GROUP_X << 8,
    PBSysFileOpenFlag_MODE_GROUP_RW = PBSysFileMode_GROUP_RW << 8,
    PBSysFileOpenFlag_MODE_GROUP_RWX = PBSysFileMode_GROUP_RWX << 8,
    PBSysFileOpenFlag_MODE_OTHER_R = PBSysFileMode_OTHER_R << 8,
    PBSysFileOpenFlag_MODE_OTHER_W = PBSysFileMode_OTHER_W << 8,
    PBSysFileOpenFlag_MODE_OTHER_X = PBSysFileMode_OTHER_X << 8,
    PBSysFileOpenFlag_MODE_OTHER_RW = PBSysFileMode_OTHER_RW << 8,
    PBSysFileOpenFlag_MODE_OTHER_RWX = PBSysFileMode_OTHER_RWX << 8,
} PBSysFileOpenFlags;
```

`PBSysFileOpenFlag_MODE_MASK` masks mode bits in flags, for use with CREATE flag

### `PBSysFileReadFlags`

```c
typedef enum PBSysFileReadFlags PB_ENUM_TYPE(u64){
    PBSysFileReadFlag_SYNC = 1 << 0, // blocking read
} PBSysFileReadFlags;
```

### `PBSysFileWriteFlags`

```c
typedef enum PBSysFileWriteFlags PB_ENUM_TYPE(u64){
    PBSysFileWriteFlag_SYNC = 1 << 0, // blocking write
} PBSysFileWriteFlags;
```

### `PBSysGamepadAxis`

```c
typedef enum PBSysGamepadAxis PB_ENUM_TYPE(u16){
    PBSysGamepadAxis_LEFT_X = 0,   PBSysGamepadAxis_LEFT_Y,        PBSysGamepadAxis_RIGHT_X,
    PBSysGamepadAxis_RIGHT_Y,      PBSysGamepadAxis_DPAD_X,        PBSysGamepadAxis_DPAD_Y,
    PBSysGamepadAxis_LEFT_TRIGGER, PBSysGamepadAxis_RIGHT_TRIGGER, PBSysGamepadAxis_COUNT,
} PBSysGamepadAxis;
```

### `PBSysGamepadButton`

```c
typedef enum PBSysGamepadButton PB_ENUM_TYPE(u16){
    PBSysGamepadButton_A = 0,
    PBSysGamepadButton_B,
    PBSysGamepadButton_X,
    PBSysGamepadButton_Y,
    PBSysGamepadButton_LEFT_SHOULDER,
    PBSysGamepadButton_RIGHT_SHOULDER,
    PBSysGamepadButton_LEFT_TRIGGER,
    PBSysGamepadButton_RIGHT_TRIGGER,
    PBSysGamepadButton_LEFT_THUMBSTICK,
    PBSysGamepadButton_RIGHT_THUMBSTICK,
    PBSysGamepadButton_MENU,
    PBSysGamepadButton_OPTIONS,
    PBSysGamepadButton_HOME,
    PBSysGamepadButton_COUNT,
} PBSysGamepadButton;
```

### `PBSysGesturePhase`

```c
typedef enum PBSysGesturePhase PB_ENUM_TYPE(u8){
    PBSysGesturePhase_CHANGED = 0, // default if platform doesn't provide phases
    PBSysGesturePhase_BEGAN = 1,
    PBSysGesturePhase_ENDED = 2,
} PBSysGesturePhase;
```

### `PBSysGuiPrefsFlag`

```c
typedef enum PB_ENUM_TYPE(PBSysGuiPrefsFlags) {
    PBSysGuiPrefsFlag_BRIGHT = 1u << 0,
    PBSysGuiPrefsFlag_DARK = 1u << 1,
    PBSysGuiPrefsFlag_HIGH_CONTRAST = 1u << 2,
    PBSysGuiPrefsFlag_AUTOHIDE_SCROLLBARS = 1u << 3, // scrollbars visible only when scrolling
} PBSysGuiPrefsFlag;
```

### `PBSysGuiPresentationFlag`

```c
typedef enum PB_ENUM_TYPE(PBSysGuiPresentation) {
    PBSysGuiPresentation_DEFAULT = 0,
    PBSysGuiPresentation_HIDE_DOCK = 1 << 1,                 // dock is disabled
    PBSysGuiPresentation_AUTOHIDE_MENU_BAR = 1 << 2,         // Menu bar appears when moused to
    PBSysGuiPresentation_HIDE_MENU_BAR = 1 << 3,             // Menu bar is disabled
    PBSysGuiPresentation_DISABLE_PROCESS_SWITCHING = 1 << 4, // Cmd+Tab UI is disabled
    PBSysGuiPresentation_DISABLE_FORCE_QUIT = 1 << 5,        // Cmd+Tab UI is disabled
    PBSysGuiPresentation_DISABLE_LOGOUT = 1 << 6,            // Restart/Shut Down/Log Out disabled
    PBSysGuiPresentation_DISABLE_CURSOR_HIGHLIGHT = 1 << 7,  // disable "Shake mouse to locate"
    PBSysGuiPresentation_FULLSCREEN = 1 << 8, // app is in full-screen mode (read only flag)

    PBSysGuiPresentation_KIOSK =
        PBSysGuiPresentation_HIDE_DOCK | PBSysGuiPresentation_HIDE_MENU_BAR
        | PBSysGuiPresentation_DISABLE_PROCESS_SWITCHING | PBSysGuiPresentation_DISABLE_FORCE_QUIT
        | PBSysGuiPresentation_DISABLE_LOGOUT,
} PBSysGuiPresentationFlag;
```

### `PBSysGuiSignals`

```c
typedef enum PB_ENUM_TYPE(PBSysSignals) {
    // PBSysGuiSignal_PRESENTATION is pulsed when the application's presentation flags changes
    PBSysGuiSignal_PRESENTATION = 1u << 0, // pulse

    // PBSysGuiSignal_PREFS is pulsed when the system UI preferences change.
    // Read the current preferences with PBSysGuiPrefsGet.
    PBSysGuiSignal_PREFS = 1u << 1, // pulse
} PBSysGuiSignals;
```

`PBSysGuiSignal_PRESENTATION` is pulsed when the application's presentation flags changes

### `PBSysHandleListFilter`

```c
typedef enum PB_ENUM_TYPE(u8) {
    PBSysHandleListFilter_BY_NAME = 1,        // predicate is of type PBSysHandleName
    PBSysHandleListFilter_BY_OBJECT_ID = 2,   // predicate is of type PBSysObjectId
    PBSysHandleListFilter_BY_OBJECT_TYPE = 3, // predicate is of type PBSysObjectType
    PBSysHandleListFilter_BY_HANDLE = 4,      // predicate is of type PBSysHandle
} PBSysHandleListFilter;
```

PBSysHandleListFilter are possible filters

### `PBSysHandleListFlags`

```c
typedef enum PB_ENUM_TYPE(u64) {
    PBSysHandleList_FILTER = 0xff, // mask for a PBSysHandleListFilter_ value
} PBSysHandleListFlags;
```

PBSysHandleListFlags are flags for `PBSysHandleList`

### `PBSysHidDeviceFlags`

```c
typedef enum PBSysHidDeviceFlags PB_ENUM_TYPE(u32){
    PBSysHidDevice_HAS_PLAYER_INDEX = 1u << 0, // device can indicate a logical player number
    PBSysHidDevice_HAS_HAPTICS = 1u << 1,      // device supports haptic feedback
} PBSysHidDeviceFlags;
```

### `PBSysHidDeviceType`

```c
typedef enum PBSysHidDeviceType PB_ENUM_TYPE(u16){
    PBSysHidDeviceType_NONE,
    PBSysHidDeviceType_GAMEPAD,
} PBSysHidDeviceType;
```

### `PBSysHidHapticsLocality`

```c
typedef enum PBSysHidHapticsLocality PB_ENUM_TYPE(u32){
    PBSysHidHaptics_DEFAULT = 1u << 0,      PBSysHidHaptics_ALL = 1u << 1,
    PBSysHidHaptics_HANDLES = 1u << 2,      PBSysHidHaptics_LEFT_HANDLE = 1u << 3,
    PBSysHidHaptics_RIGHT_HANDLE = 1u << 4, PBSysHidHaptics_TRIGGERS = 1u << 5,
    PBSysHidHaptics_LEFT_TRIGGER = 1u << 6, PBSysHidHaptics_RIGHT_TRIGGER = 1u << 7,
} PBSysHidHapticsLocality;
```

### `PBSysKeyboardFlags`

```c
typedef enum PBSysKeyboardFlags PB_ENUM_TYPE(u16){
    PBSysKeyboardFlag_REPEAT = 1u << 0, // i.e. key is being held down
} PBSysKeyboardFlags;
```

### `PBSysKeyboardKey`

```c
typedef enum PBSysKeyboardKey PB_ENUM_TYPE(u16){
    PBSysKeyboardKey_None = 0x0000,

    // ASCII / Unicode printable (match codepoint)
    PBSysKeyboardKey_Space = 0x0020,
    PBSysKeyboardKey_Quote = 0x0027,
    PBSysKeyboardKey_Comma = 0x002C,
    PBSysKeyboardKey_Minus = 0x002D,
    PBSysKeyboardKey_Period = 0x002E,
    PBSysKeyboardKey_Slash = 0x002F,

    PBSysKeyboardKey_0 = 0x0030,
    PBSysKeyboardKey_1 = 0x0031,
    PBSysKeyboardKey_2 = 0x0032,
    PBSysKeyboardKey_3 = 0x0033,
    PBSysKeyboardKey_4 = 0x0034,
    PBSysKeyboardKey_5 = 0x0035,
    PBSysKeyboardKey_6 = 0x0036,
    PBSysKeyboardKey_7 = 0x0037,
    PBSysKeyboardKey_8 = 0x0038,
    PBSysKeyboardKey_9 = 0x0039,

    PBSysKeyboardKey_Semicolon = 0x003B,
    PBSysKeyboardKey_Equal = 0x003D,

    PBSysKeyboardKey_A = 0x0041,
    PBSysKeyboardKey_B = 0x0042,
    PBSysKeyboardKey_C = 0x0043,
    PBSysKeyboardKey_D = 0x0044,
    PBSysKeyboardKey_E = 0x0045,
    PBSysKeyboardKey_F = 0x0046,
    PBSysKeyboardKey_G = 0x0047,
    PBSysKeyboardKey_H = 0x0048,
    PBSysKeyboardKey_I = 0x0049,
    PBSysKeyboardKey_J = 0x004A,
    PBSysKeyboardKey_K = 0x004B,
    PBSysKeyboardKey_L = 0x004C,
    PBSysKeyboardKey_M = 0x004D,
    PBSysKeyboardKey_N = 0x004E,
    PBSysKeyboardKey_O = 0x004F,
    PBSysKeyboardKey_P = 0x0050,
    PBSysKeyboardKey_Q = 0x0051,
    PBSysKeyboardKey_R = 0x0052,
    PBSysKeyboardKey_S = 0x0053,
    PBSysKeyboardKey_T = 0x0054,
    PBSysKeyboardKey_U = 0x0055,
    PBSysKeyboardKey_V = 0x0056,
    PBSysKeyboardKey_W = 0x0057,
    PBSysKeyboardKey_X = 0x0058,
    PBSysKeyboardKey_Y = 0x0059,
    PBSysKeyboardKey_Z = 0x005A,

    PBSysKeyboardKey_LeftBracket = 0x005B,
    PBSysKeyboardKey_Backslash = 0x005C,
    PBSysKeyboardKey_RightBracket = 0x005D,
    PBSysKeyboardKey_Grave = 0x0060,

    // Unicode symbols
    PBSysKeyboardKey_Escape = 0x238B,    // ESC
    PBSysKeyboardKey_Enter = 0x23CE,     // RETURN SYMBOL
    PBSysKeyboardKey_Tab = 0x21E5,       // TAB
    PBSysKeyboardKey_Backspace = 0x232B, // ERASE TO THE LEFT
    PBSysKeyboardKey_Insert = 0x2380,    // INSERT
    PBSysKeyboardKey_Delete = 0x2326,    // ERASE TO THE RIGHT
    PBSysKeyboardKey_Left = 0x2190,
    PBSysKeyboardKey_Right = 0x2192,
    PBSysKeyboardKey_Down = 0x2193,
    PBSysKeyboardKey_Up = 0x2191,
    PBSysKeyboardKey_PageUp = 0x21DE,
    PBSysKeyboardKey_PageDown = 0x21DF,
    PBSysKeyboardKey_Home = 0x21F1,
    PBSysKeyboardKey_End = 0x21F2,

    PBSysKeyboardKey_CapsLock = 0x21EA,
    PBSysKeyboardKey_LeftShift = 0x21E7,
    PBSysKeyboardKey_LeftCtrl = 0x2303,
    PBSysKeyboardKey_LeftAlt = 0x2325,
    PBSysKeyboardKey_LeftSuper = 0x2318,

    PBSysKeyboardKey_MediaNext = 0x23ED,
    PBSysKeyboardKey_MediaPrev = 0x23EE,
    PBSysKeyboardKey_MediaPlay = 0x23F5,
    PBSysKeyboardKey_MediaStop = 0x23F9,

    // Private use area (0xE000-0xEFFF)
    PBSysKeyboardKey_World1 = 0xE000,
    PBSysKeyboardKey_World2 = 0xE001,

    PBSysKeyboardKey_ScrollLock = 0xE010,
    PBSysKeyboardKey_NumLock = 0xE011,
    PBSysKeyboardKey_PrintScreen = 0xE012,
    PBSysKeyboardKey_Pause = 0xE013,

    PBSysKeyboardKey_F1 = 0xE100,
    PBSysKeyboardKey_F2 = 0xE101,
    PBSysKeyboardKey_F3 = 0xE102,
    PBSysKeyboardKey_F4 = 0xE103,
    PBSysKeyboardKey_F5 = 0xE104,
    PBSysKeyboardKey_F6 = 0xE105,
    PBSysKeyboardKey_F7 = 0xE106,
    PBSysKeyboardKey_F8 = 0xE107,
    PBSysKeyboardKey_F9 = 0xE108,
    PBSysKeyboardKey_F10 = 0xE109,
    PBSysKeyboardKey_F11 = 0xE10A,
    PBSysKeyboardKey_F12 = 0xE10B,
    PBSysKeyboardKey_F13 = 0xE10C,
    PBSysKeyboardKey_F14 = 0xE10D,
    PBSysKeyboardKey_F15 = 0xE10E,
    PBSysKeyboardKey_F16 = 0xE10F,
    PBSysKeyboardKey_F17 = 0xE110,
    PBSysKeyboardKey_F18 = 0xE111,
    PBSysKeyboardKey_F19 = 0xE112,
    PBSysKeyboardKey_F20 = 0xE113,
    PBSysKeyboardKey_F21 = 0xE114,
    PBSysKeyboardKey_F22 = 0xE115,
    PBSysKeyboardKey_F23 = 0xE116,
    PBSysKeyboardKey_F24 = 0xE117,

    PBSysKeyboardKey_Numpad0 = 0xE200,
    PBSysKeyboardKey_Numpad1 = 0xE201,
    PBSysKeyboardKey_Numpad2 = 0xE202,
    PBSysKeyboardKey_Numpad3 = 0xE203,
    PBSysKeyboardKey_Numpad4 = 0xE204,
    PBSysKeyboardKey_Numpad5 = 0xE205,
    PBSysKeyboardKey_Numpad6 = 0xE206,
    PBSysKeyboardKey_Numpad7 = 0xE207,
    PBSysKeyboardKey_Numpad8 = 0xE208,
    PBSysKeyboardKey_Numpad9 = 0xE209,
    PBSysKeyboardKey_NumpadDot = 0xE20A,
    PBSysKeyboardKey_NumpadDivide = 0xE20B,
    PBSysKeyboardKey_NumpadMultiply = 0xE20C,
    PBSysKeyboardKey_NumpadSubtract = 0xE20D,
    PBSysKeyboardKey_NumpadAdd = 0xE20E,
    PBSysKeyboardKey_NumpadEnter = 0xE20F,
    PBSysKeyboardKey_NumpadEquals = 0xE210,
    PBSysKeyboardKey_NumpadClear = 0xE211,

    PBSysKeyboardKey_RightShift = 0xE300,
    PBSysKeyboardKey_RightCtrl = 0xE301,
    PBSysKeyboardKey_RightAlt = 0xE302,
    PBSysKeyboardKey_RightSuper = 0xE303,

    PBSysKeyboardKey_Menu = 0xE310,

    PBSysKeyboardKey_VolumeUp = 0xE320,
    PBSysKeyboardKey_VolumeDown = 0xE321,
    PBSysKeyboardKey_Mute = 0xE322,

    PBSysKeyboardKey_COUNT
} PBSysKeyboardKey;
```

ASCII / Unicode printable (match codepoint)

### `PBSysKeyboardModifiers`

```c
typedef enum PBSysKeyboardModifiers PB_ENUM_TYPE(u16){
    PBSysKeyboardModifier_SHIFT = 1u << 0,     // shift
    PBSysKeyboardModifier_CTRL = 1u << 1,      // control
    PBSysKeyboardModifier_ALT = 1u << 2,       // aka "option" on mac
    PBSysKeyboardModifier_META = 1u << 3,      // aka "command", "windows key", "super"
    PBSysKeyboardModifier_CAPS_LOCK = 1u << 4, // caps lock
    PBSysKeyboardModifier_FN = 1u << 5,        // "function"
} PBSysKeyboardModifiers;
```

### `PBSysMouseButton`

```c
typedef enum PBSysMouseButton PB_ENUM_TYPE(u16){
    PBSysMouseButton_Left = 0,
    PBSysMouseButton_Right = 1,
    PBSysMouseButton_Middle = 2,
    PBSysMouseButton_X1 = 3,
    PBSysMouseButton_X2 = 4,
    // NOTE: unnamed buttons here
    PBSysMouseButton_COUNT = 16,
} PBSysMouseButton;
```

NOTE: unnamed buttons here

### `PBSysNetFeature`

```c
typedef enum PBSysNetFeature PB_ENUM_TYPE(u64){
    PBSysNetFeature_TCP,  // PBSysNetTransportOpen supports "tcp:" URI
    PBSysNetFeature_UDP,  // PBSysNetTransportOpen supports "udp:" URI
    PBSysNetFeature_QUIC, // PBSysNetTransportOpen supports "quic:" URI
} PBSysNetFeature;
```

PBSysNetFeature defines feature keys of net objects, for use with `PBSysObjectFeatures`

### `PBSysNetSessionSignals`

```c
typedef enum PB_ENUM_TYPE(PBSysSignals) {
    /*
    PBSysNetSessionSignal_AVAILABLE means the session's underlying AP transport is connected. The runtime may still be authenticating the session while this signal is active without `PBSysNetSessionSignal_READY`.
    */
    PBSysNetSessionSignal_AVAILABLE = 1u << 4,

    /*
    PBSysNetSessionSignal_READY means the session is authenticated and its AP streams may become writable. When this signal is active, `PBSysNetSessionSignal_AVAILABLE` is also active.
    */
    PBSysNetSessionSignal_READY = 1u << 0,
} PBSysNetSessionSignals;
```

    PBSysNetSessionSignal_AVAILABLE means the session's underlying AP transport is connected. The runtime may still be authenticating the session while this signal is active without `PBSysNetSessionSignal_READY`.

### `PBSysNetTransportFlag`

```c
typedef enum PB_ENUM_TYPE(PBSysNetTransportFlags) {
    PBSysNetTransportFlag_TLS = 1u << 0, // enable TLS (DTLS for UDP)
} PBSysNetTransportFlag;
```

### `PBSysNetTransportSignals`

```c
typedef enum PB_ENUM_TYPE(PBSysSignals) {
    PBSysNetTransportSignal_READY = 1u << 0,  // connection is established and active
    PBSysNetTransportSignal_CLOSED = 1u << 1, // connection is closed
} PBSysNetTransportSignals;
```

PBSysNetTransportSignals describe signals available for network-transport objects

### `PBSysNetTransportStreamFlag`

```c
typedef enum PB_ENUM_TYPE(PBSysNetTransportStreamFlags) {
    PBSysNetTransportStream_READ = 1u << 0,  // create a stream that can be read from
    PBSysNetTransportStream_WRITE = 1u << 1, // create a stream that can be written to
    PBSysNetTransportStream_RW = PBSysNetTransportStream_READ | PBSysNetTransportStream_WRITE,

    /*
    PBSysNetTransportStream_UNRELIABLE requests an unreliable stream. For QUIC this maps to QUIC DATAGRAM frames, where each write sends one datagram and each read receives one datagram. The flag is ignored for inherently unreliable protocols like UDP. Setting this flag for TCP causes PBSysNetTransportOpenStream to fail with PBSysErr_NOT_SUPPORTED.
    */
    PBSysNetTransportStream_UNRELIABLE = 1u << 2,
} PBSysNetTransportStreamFlag;
```

    PBSysNetTransportStream_UNRELIABLE requests an unreliable stream. For QUIC this maps to QUIC DATAGRAM frames, where each write sends one datagram and each read receives one datagram. The flag is ignored for inherently unreliable protocols like UDP. Setting this flag for TCP causes PBSysNetTransportOpenStream to fail with PBSysErr_NOT_SUPPORTED.

### `PBSysObjectType`

```c
typedef enum PBSysObjectType PB_ENUM_TYPE(uint16_t){
    PBSysObject_None = 0, // invalid
    PBSysObject_Audio = 16,
    PBSysObject_Canvas = 22,
    PBSysObject_Channel = 7,
    PBSysObject_Clock = 1,
    PBSysObject_File = 12,
    PBSysObject_FileList = 14,
    PBSysObject_FilePanel = 20,
    PBSysObject_Gui = 8,
    PBSysObject_Hid = 21,
    PBSysObject_Net = 9,
    PBSysObject_NetSession = 10,
    PBSysObject_NetTransport = 19,
    PBSysObject_Stream = 2,
    PBSysObject_Textplan = 3,
    PBSysObject_Texture = 15,
    PBSysObject_Thread = 4,
    PBSysObject_Window = 6,
} PBSysObjectType;
```

PBSysObjectType expresses a type of object

### `PBSysPointerFlags`

```c
typedef enum PBSysPointerFlags PB_ENUM_TYPE(u16){
    PBSysPointerFlag_PRIMARY = 1u << 0,    // primary pointer for this device
    PBSysPointerFlag_IN_CONTACT = 1u << 1, // touch/pen in contact
    PBSysPointerFlag_ERASER = 1u << 2,     // pen eraser side/end
    PBSysPointerFlag_INVERTED = 1u << 3,   // if a platform reports pen inversion
    PBSysPointerFlag_COALESCED = 1u << 4,  // if event is a coalesced/aggregated update
    PBSysPointerFlag_PREDICTED = 1u << 5,  // if predicted (some systems provide)
} PBSysPointerFlags;
```

### `PBSysPointerKind`

```c
typedef enum PBSysPointerKind PB_ENUM_TYPE(u8){
    PBSysPointerKind_MOUSE = 1,
    PBSysPointerKind_TOUCH = 2,
    PBSysPointerKind_TRACKPAD = 3, // used mainly for scroll/gesture sources
    PBSysPointerKind_PEN = 4,
} PBSysPointerKind;
```

### `PBSysRightsBits`

```c
enum PBSysRightsBits PB_ENUM_TYPE(PBSysRights){
    PBSysRight_NONE = 0u,

    PBSysRight_TRANSFER = 1u << 0,
    PBSysRight_DUPLICATE = 1u << 1,
    PBSysRight_READ = 1u << 4,
    PBSysRight_WRITE = 1u << 5,
    PBSysRight_MANAGE_PROCESS = 1u << 6, // start & terminate process
    PBSysRight_MANAGE_THREAD = 1u << 7,  // start & terminate threads
    PBSysRight_NETWORK = 1u << 8,        // can connect to networks [DEPRECATED]
    PBSysRight_OBSERVE = 1u << 9,        // can observe signals
    PBSysRight_SIGNAL = 1u << 10,        // can manage user signals

    PBSysRight_SAME_RIGHTS = 1u << 31,
};
```

### `PBSysScrollFlags`

```c
typedef enum PBSysScrollFlags PB_ENUM_TYPE(u16){
    PBSysScrollFlag_PRECISE = 1u << 0,    // high-resolution scrolling (trackpad)
    PBSysScrollFlag_INVERTED = 1u << 1,   // "natural" direction applied or not
    PBSysScrollFlag_UNIT_LINES = 1u << 2, // deltas are in lines (vs pixels/dp)
    PBSysScrollFlag_UNIT_PAGES = 1u << 3, // deltas are pages
} PBSysScrollFlags;
```

### `PBSysScrollPhase`

```c
typedef enum PBSysScrollPhase PB_ENUM_TYPE(u8){
    PBSysScrollPhase_CHANGED = 0, // default if platform doesn't provide phases
    PBSysScrollPhase_BEGAN = 1,
    PBSysScrollPhase_ENDED = 2,
    PBSysScrollPhase_MOMENTUM = 3, // inertia phase (macOS trackpad, iOS)
} PBSysScrollPhase;
```

### `PBSysStreamSignals`

```c
typedef enum PB_ENUM_TYPE(uint32_t) {
    PBSysStreamSignal_READABLE = 1u << 0,
    PBSysStreamSignal_WRITABLE = 1u << 1,
    PBSysStreamSignal_PEER_CLOSED = 1u << 2,
    PBSysStreamSignal_PEER_WRITE_DISABLED = 1u << 3,
    PBSysStreamSignal_WRITE_DISABLED = 1u << 4,
} PBSysStreamSignals;
```

PBSysStreamSignals describe signals available for streams (in addition to USER signals)

### `PBSysStreamWriteFlags`

```c
typedef enum PBSysStreamWriteFlags PB_ENUM_TYPE(u32){
    PBSysStreamWrite_SYNC = 1, // complete write immediately or fail with PBSysErr_AGAIN
} PBSysStreamWriteFlags;
```

PBSysStreamWriteFlags are flags for `PBSysStreamWrite`

### `PBSysTextAttributeType`

```c
typedef enum PBSysTextAttributeType {
    PBSysTextAttribute_VARIABLE_AXIS = 1,       // see PBSysTextAttributeValueFeature feature
    PBSysTextAttribute_OTYPE_FEATURE = 2,       // see PBSysTextAttributeValueFeature feature
    PBSysTextAttribute_LIGATURES = 3,           // see PBSysTextAttributeValueBool b
    PBSysTextAttribute_SUPERSCRIPT = 4,         // see PBSysTextAttributeValueBool b
    PBSysTextAttribute_SUBSCRIPT = 5,           // see PBSysTextAttributeValueBool b
    PBSysTextAttribute_SMALL_CAPS = 6,          // see PBSysTextAttributeValueBool b
    PBSysTextAttribute_NUMERALS = 7,            // see PBSysTextAttributeValueNumerals numerals
    PBSysTextAttribute_KERNING = 8,             // see PBSysTextAttributeValueBool b
    PBSysTextAttribute_ITALICS = 9,             // see PBSysTextAttributeValueBool b
    PBSysTextAttribute_UNDERLINE = 10,          // see PBSysTextAttributeValueDecoration decoration
    PBSysTextAttribute_STRIKE_THROUGH = 11,     // see PBSysTextAttributeValueDecoration decoration
    PBSysTextAttribute_FONT_FAMILY = 12,        // see u32 u
    PBSysTextAttribute_SIZE = 13,               // see f32 f
    PBSysTextAttribute_WEIGHT = 14,             // see f32 f
    PBSysTextAttribute_STRETCH = 15,            // see f32 f
    PBSysTextAttribute_CHARACTER_SPACING = 16,  // see f32 f
    PBSysTextAttribute_OUTLINE_THICKNESS = 17,  // see f32 f
    PBSysTextAttribute_COLOR = 18,              // see u64 color
    PBSysTextAttribute_OUTLINE_COLOR = 20,      // see u64 color
    PBSysTextAttribute_SHADOW_COLOR = 21,       // see u64 color
    PBSysTextAttribute_SHADOW_BLUR_RADIUS = 22, // see f32 f
    PBSysTextAttribute_SHADOW_OFFSET_X = 23,    // see f32 f
    PBSysTextAttribute_SHADOW_OFFSET_Y = 24,    // see f32 f
    PBSysTextAttribute_ALIGNMENT = 26,          // see PBSysTextAttributeValueAlignment alignment
    PBSysTextAttribute_DIRECTION = 27,          // see PBSysTextAttributeValueDirection direction
    PBSysTextAttribute_LINE_HEIGHT_MULTIPLIER = 31, // see f32 f
    PBSysTextAttribute_TAB_SIZE = 33,               // see f32 f
} PBSysTextAttributeType;
```

### `PBSysTextAttributeValueAlignment`

```c
typedef enum PBSysTextAttributeValueAlignment PB_ENUM_TYPE(u32){
    PBSysTextAttributeValueAlignment_START = 0u,
    PBSysTextAttributeValueAlignment_END = 1u,
    PBSysTextAttributeValueAlignment_CENTER = 2u,
    PBSysTextAttributeValueAlignment_JUSTIFY = 3u,
} PBSysTextAttributeValueAlignment;
```

### `PBSysTextAttributeValueBool`

```c
typedef enum PBSysTextAttributeValueBool PB_ENUM_TYPE(u32){
    PBSysTextAttributeValueBool_OFF = 0u,
    PBSysTextAttributeValueBool_ON = 1u,
    PBSysTextAttributeValueBool_ON_NO_SYNTHESIS = 2u,
} PBSysTextAttributeValueBool;
```

### `PBSysTextAttributeValueDecorationStyle`

```c
typedef enum PBSysTextAttributeValueDecorationStyle PB_ENUM_TYPE(u32){
    PBSysTextAttributeValueDecorationStyle_OFF = 0u,
    PBSysTextAttributeValueDecorationStyle_SINGLE = 1u,
    PBSysTextAttributeValueDecorationStyle_DOUBLE = 2u,
    PBSysTextAttributeValueDecorationStyle_DOTTED = 3u,
    PBSysTextAttributeValueDecorationStyle_DASHED = 4u,
    PBSysTextAttributeValueDecorationStyle_DOT_DASH = 5u,
    PBSysTextAttributeValueDecorationStyle_WAVY = 6u,
    PBSysTextAttributeValueDecorationStyle_BELOW = 7u,
} PBSysTextAttributeValueDecorationStyle;
```

### `PBSysTextAttributeValueDirection`

```c
typedef enum PBSysTextAttributeValueDirection PB_ENUM_TYPE(u32){
    PBSysTextAttributeValueDirection_DEFAULT = 0u,
} PBSysTextAttributeValueDirection;
```

### `PBSysTextAttributeValueNumerals`

```c
typedef enum PBSysTextAttributeValueNumerals PB_ENUM_TYPE(u32){
    PBSysTextAttributeValueNumerals_LINING = 0u,
    PBSysTextAttributeValueNumerals_TABULAR = 1u,
    PBSysTextAttributeValueNumerals_OLD_STYLE = 2u,
} PBSysTextAttributeValueNumerals;
```

### `PBSysTextureFormat`

```c
typedef enum PB_ENUM_TYPE(u32) {
    PBSysTextureFormat_UNKNOWN,
    PBSysTextureFormat_RGBA8,
    PBSysTextureFormat_BGRA8,
    PBSysTextureFormat_RGBAF16,
} PBSysTextureFormat;
```

PBSysTextureFormat describes the pixel format of a texture.

RGBA8 and BGRA8 are 4 bytes per pixel, display-encoded Display P3 (the sRGB transfer curve over P3 primaries); the renderer linearizes on sample. RGBAF16 is 8 bytes per pixel, four binary16 channels in R,G,B,A memory order holding linear-light extended Display P3 — the renderer's working space, so texels pass through unchanged and can express HDR (>1.0) and out-of-gamut (negative) values. An RGBAF16 texel is exactly the bits of a PBColor (PBColor.u64 / a wire color).

### `PBSysThreadFeature`

```c
typedef enum PBSysThreadFeature {
    PBSysThreadFeature_EXIT_MAIN, // can exit main thread (i.e. unavailable on Web)
    PBSysThreadFeature_START,     // can start threads
} PBSysThreadFeature;
```

PBSysThreadFeature defines feature keys of thread objects.
These constants are bit positions of the bitmask returned by `PBSysObjectFeatures`

### `PBSysThreadFlags`

```c
typedef enum PB_ENUM_TYPE(u64) {
    PBSysThread_NOGUI = 1u << 0, // disable GUI (only has an effect on the main thread)
    PBSysThread_AUDIO = 1u << 1, // thread produces audio output
} PBSysThreadFlags;
```

PBSysThreadFlags are flags for PBSysThreadEnter and `PBSysThreadStart`

### `PBSysThreadSignals`

```c
typedef enum PB_ENUM_TYPE(uint32_t) {
    PBSysThreadSignal_RUNNING = 1u << 0,
    PBSysThreadSignal_TERMINATED = 1u << 1,
    PBSysThreadSignal_WRITABLE = 1u << 2, // room for writing at least one message
    PBSysThreadSignal_READABLE = 1u << 3, // at least one message can be read
} PBSysThreadSignals;
```

PBSysThreadSignals describe signals available for threads (in addition to USER signals)

### `PBSysWindowFullScreenFlag`

```c
typedef enum PB_ENUM_TYPE(PBSysWindowFullScreenFlags) {
    PBSysWindowFullScreenFlag_ENABLE = 1 << 0, // enable full-screen (absense means disabled)
} PBSysWindowFullScreenFlag;
```

### `PBSysWindowOpenSurfaceCanvasFlag`

```c
typedef enum PB_ENUM_TYPE(PBSysWindowOpenSurfaceCanvasFlags) {
    /*
    PBSysWindowOpenSurfaceCanvasFlag_WEBGPU opens the window surface canvas for direct guest WebGPU rendering.
    */
    PBSysWindowOpenSurfaceCanvasFlag_WEBGPU = 1 << 0,
} PBSysWindowOpenSurfaceCanvasFlag;
```

    PBSysWindowOpenSurfaceCanvasFlag_WEBGPU opens the window surface canvas for direct guest WebGPU rendering.

### `PBSysWindowRenderFlag`

```c
enum PBSysWindowRenderFlag PB_ENUM_TYPE(PBSysWindowRenderFlags){
    /*
    PBSysWindowRenderFlag_PRESENT_IMMEDIATE disables display- and/or OS compositor-synchronized rendering.

    In certain scenarios this can significantly reduce latency, for example when dragging a UI element on the screen where the OS mouse cursor would be ahead of the dragged element by a few frames.

    However, enabling this may lead to visual artifacts like "tearing" if you render outside of FRAME_SYNC signals, or if your rendering is taking too long during GPU framebuffer presentation/flip.
    */
    PBSysWindowRenderFlag_PRESENT_IMMEDIATE = 1 << 0,
};
```

`PBSysWindowRenderFlag_PRESENT_IMMEDIATE` disables display- and/or OS compositor-synchronized rendering.

    In certain scenarios this can significantly reduce latency, for example when dragging a UI element on the screen where the OS mouse cursor would be ahead of the dragged element by a few frames.

    However, enabling this may lead to visual artifacts like "tearing" if you render outside of FRAME_SYNC signals, or if your rendering is taking too long during GPU framebuffer presentation/flip.

### `PBSysWindowSignals`

```c
typedef enum PB_ENUM_TYPE(PBSysSignals) {
    // PBSysWindowSignal_RESIZE is pulsed when the window's size and/or pixel density changes
    PBSysWindowSignal_RESIZE = 1u << 0, // pulse

    // PBSysWindowSignal_MOVE is pulsed when the window's position on screen change
    PBSysWindowSignal_MOVE = 1u << 1, // pulse

    /*
    PBSysWindowSignal_FRAME_SYNC is pulsed when the window's display finished presenting a frame. You can retrieve the estimated presentation time of the next frame via frameTime from PBSysWindowInfoGet.
    */
    PBSysWindowSignal_FRAME_SYNC = 1u << 2,

    /*
    PBSysWindowSignal_REPAINT is pulsed when the window's content need to be drawn again. This signal is only used on hosts which does not retain the window contents when a window is not displayed on screen.
    */
    PBSysWindowSignal_REPAINT = 1u << 3, // pulse

    // PBSysWindowSignal_KEY is active when the window is the key window of the application
    PBSysWindowSignal_KEY = 1u << 4,

    // PBSysWindowSignal_FULLSCREEN is active when the window is in full-screen mode
    PBSysWindowSignal_FULLSCREEN = 1u << 5,
} PBSysWindowSignals;
```

`PBSysWindowSignal_RESIZE` is pulsed when the window's size and/or pixel density changes

### `PBTextPlanLayoutFlag`

```c
enum PBTextPlanLayoutFlag PB_ENUM_TYPE(PBTextPlanLayoutFlags){

    // PBTextPlanLayout_PREFORMATTED prevents trimming of trailing/leading/duplicate whitespace
    PBTextPlanLayout_PREFORMATTED = 1u << 0,

    // PBTextPlanLayout_ONE_LINE: Text is placed on a single line; newline characters are ignored
    PBTextPlanLayout_ONE_LINE = 1u << 1,

    /*
    PBTextPlanLayout_ALWAYS_SET_HEIGHT: The computed height (see PBSysTextplanGetSize) will be set to the height of the single line, even if the input text is an empty string.

    Implied by PBTextPlanLayout_ONE_LINE.
    */
    PBTextPlanLayout_ALWAYS_SET_HEIGHT = 1u << 2,

    PBTextPlanLayout_REPLACE_WITH_BULLETS = 1u << 3,
};
```

`PBTextPlanLayout_PREFORMATTED` prevents trimming of trailing/leading/duplicate whitespace

## Constants

| Name | Value |
| --- | --- |
| `PBSysCanvasGradientFlag_HUE_LONGER` | `1` |
| `PBSysCanvasMaskFlag_INVERT` | `2` |
| `PBSysCanvasMaskFlag_LUMINANCE` | `1` |
| `PBSysCanvasStrokeFlag_INSIDE` | `1` |
| `PBSysCanvasStrokeFlag_OUTSIDE` | `2` |
| `PBSysHandle_INVALID` | `0` |
| `PBSysHandle_SELF_THREAD` | `1` |
| `PBSysHandleName_CONSOLE` |  |
| `PBSysHandleName_NONE` | `0` |
| `PBSysHandleName_USER_MAX` | `32767` |
| `PBSysNetSessionChannelIdMaxLen` | `64` |
| `PBSysNetSessionIdMaxLen` | `64` |
| `PBSysObjectId_MAIN_THREAD` | `1` |
| `PBSysObjectId_ROOT_FS` | `2` |
| `PBSysObjectObserve_ADD` | `2` |
| `PBSysObjectObserve_ONCE` | `1` |
| `PBSysSignal_ALL` | `4294967295` |
| `PBSysSignal_SYSTEM_ALL` | `16777215` |
| `PBSysSignal_USER_0` | `16777216` |
| `PBSysSignal_USER_1` | `33554432` |
| `PBSysSignal_USER_2` | `67108864` |
| `PBSysSignal_USER_3` | `134217728` |
| `PBSysSignal_USER_4` | `268435456` |
| `PBSysSignal_USER_5` | `536870912` |
| `PBSysSignal_USER_6` | `1073741824` |
| `PBSysSignal_USER_7` | `2147483648` |
| `PBSysSignal_USER_ALL` | `4278190080` |
| `PBSysTextplanSelectionAdjustment_ALL_GRANULARITY` | `4` |
| `PBSysTextplanSelectionAdjustment_BACKWARDS` | `8` |
| `PBSysTextplanSelectionAdjustment_DELETE_AFTERWARDS` | `64` |
| `PBSysTextplanSelectionAdjustment_IN_LINE_GRANULARITY` | `32` |
| `PBSysTextplanSelectionAdjustment_LINE_ENDS_GRANULARITY` | `128` |
| `PBSysTextplanSelectionAdjustment_LINE_GRANULARITY` | `2` |
| `PBSysTextplanSelectionAdjustment_MAKE_SELECTION` | `16` |
| `PBSysTextplanSelectionAdjustment_TO_MOUSE_RIGHT_CLICK` | `2147483648` |
| `PBSysTextplanSelectionAdjustment_WORD_GRANULARITY` | `1` |
| `PBSysTextureCreateFlag_NEAREST` | `2` |
| `PBSysTextureCreateFlag_RENDER_ATTACHMENT` | `16` |
| `PBSysTextureCreateFlag_STREAMING` | `1` |
| `PBSysTextureCreateFlag_WRAP_U` | `4` |
| `PBSysTextureCreateFlag_WRAP_V` | `8` |
| `PBSysWindowCreateTextureFlag_NEAREST` | `2` |
| `PBSysWindowCreateTextureFlag_RENDER_ATTACHMENT` | `16` |
| `PBSysWindowCreateTextureFlag_STREAMING` | `1` |
| `PBSysWindowCreateTextureFlag_WRAP_U` | `4` |
| `PBSysWindowCreateTextureFlag_WRAP_V` | `8` |
| `PBSysWindowSetRectFlag_ANIMATE` | `8` |
| `PBSysWindowSetRectFlag_CENTER` | `16` |
| `PBSysWindowSetRectFlag_ORIGIN` | `2` |
| `PBSysWindowSetRectFlag_OUTER` | `1` |
| `PBSysWindowSetRectFlag_SIZE` | `4` |
| `PBSysWindowStyle_CLOSABLE` | `2` |
| `PBSysWindowStyle_FULLSIZE_CONTENT` | `64` |
| `PBSysWindowStyle_HIDDEN_TITLE` | `32` |
| `PBSysWindowStyle_MINIMIZABLE` | `4` |
| `PBSysWindowStyle_RESIZABLE` | `8` |
| `PBSysWindowStyle_THEME_BRIGHT` | `128` |
| `PBSysWindowStyle_THEME_DARK` | `256` |
| `PBSysWindowStyle_TITLEBAR` | `1` |
| `PBSysWindowStyle_TRANSPARENT_TITLEBAR` | `16` |

## Structs

### `PBSys2DTransform`

```c
typedef struct PBSys2DTransform {
    PBSysVec2 x; // local +x basis vector in pixels
    PBSysVec2 y; // local +y basis vector in pixels
    PBSysVec2 o; // origin in framebuffer pixels
} PBSys2DTransform;
```

### `PBSysBuf`

```c
typedef struct PBSysBuf {
    const uint8_t* nullable bytes;
    size_t                  len;
} PBSysBuf;
```

### `PBSysCanvasAABB`

```c
typedef struct PBSysCanvasAABB {
    f32 x1, y1;
    f32 x2, y2;
} PBSysCanvasAABB;
```

### `PBSysCanvasCmd`

```c
typedef struct PBSysCanvasCmd {
    u16 size;  // total command size in bytes
    u16 kind;  // PBSysCanvasCmdKind
    u32 flags; // kind-specific; must be 0 unless documented
} PB_ATTR_ALIGNED(8) PBSysCanvasCmd;
```

### `PBSysCanvasCmdClipPop`

```c
typedef struct PBSysCanvasCmdClipPop {
    PBSysCanvasCmd cmd;
} PBSysCanvasCmdClipPop;
```

### `PBSysCanvasCmdClipPush`

```c
typedef struct PBSysCanvasCmdClipPush {
    PBSysCanvasCmd cmd;
    i32            x1, y1;
    i32            x2, y2;
} PBSysCanvasCmdClipPush;
```

### `PBSysCanvasCmdComplexRect`

```c
typedef struct PBSysCanvasCmdComplexRect {
    PBSysCanvasCmd  cmd;
    PBSysCanvasAABB bounds;
    u64             fillColor;       // wire color (see above)
    f32             cornerRadius[4]; // (tl, tr, br, bl) px; finite and >= 0
    u64             strokeColor;     // wire color (see above)
    f32             strokeWidth;     // px
    u32             strokeFlags;     // 1=stroke_inside, 2=stroke_outside
    f32             blur;            // px
    f32             uvMinX, uvMinY;
    f32             uvMaxX, uvMaxY;
} PBSysCanvasCmdComplexRect;
```

### `PBSysCanvasCmdGradient`

```c
typedef struct PBSysCanvasCmdGradient {
    PBSysCanvasCmd          cmd; // cmd.flags is a PBSysCanvasGradientFlags value
    PBSysCanvasAABB         bounds;
    f32                     cornerRadius[4]; // (tl, tr, br, bl) px; finite and >= 0
    u16                     kind;            // PBSysCanvasGradientKind
    u16                     space;           // PBSysCanvasGradientSpace
    u16                     spread;          // PBSysCanvasGradientSpread
    u16                     stopCount;       // 2..16
    f32                     p0[2];           // see PBSysCanvasGradientKind
    f32                     p1[2];
    PBSysCanvasGradientStop stops[]; // stopCount entries
} PBSysCanvasCmdGradient;
```

### `PBSysCanvasCmdGradientRect`

```c
typedef struct PBSysCanvasCmdGradientRect {
    PBSysCanvasCmd  cmd; // flags bits 0..1: PBSysCanvasGradientSpace (OKLCH not allowed)
    PBSysCanvasAABB bounds;
    u64             fillColors[4];   // tl, tr, bl, br
    f32             cornerRadius[4]; // (tl, tr, br, bl) px; finite and >= 0
} PBSysCanvasCmdGradientRect;
```

### `PBSysCanvasCmdGroupMask`

```c
typedef struct PBSysCanvasCmdGroupMask {
    PBSysCanvasCmd cmd; // cmd.flags is a PBSysCanvasMaskFlags value
} PBSysCanvasCmdGroupMask;
```

### `PBSysCanvasCmdGroupPop`

```c
typedef struct PBSysCanvasCmdGroupPop {
    PBSysCanvasCmd cmd; // cmd.flags must be 0
} PBSysCanvasCmdGroupPop;
```

### `PBSysCanvasCmdGroupPush`

```c
typedef struct PBSysCanvasCmdGroupPush {
    PBSysCanvasCmd cmd;        // cmd.flags must be 0
    u16            blendMode;  // PBSysCanvasBlendMode
    u16            _reserved;  // must be 0
    f32            opacity;    // 0..1
    f32            blur;       // gaussian blur radius in px, 0..100 (0 = none)
    u32            _reserved2; // must be 0
} PBSysCanvasCmdGroupPush;
```

### `PBSysCanvasCmdMeshGradient`

```c
typedef struct PBSysCanvasCmdMeshGradient {
    PBSysCanvasCmd       cmd; // flags must be 0
    PBSysCanvasAABB      bounds;
    f32                  cornerRadius[4]; // (tl, tr, br, bl) px; finite and >= 0
    u16                  space;           // PBSysCanvasGradientSpace (OKLCH not allowed)
    u16                  pointCount;      // 2..16
    f32                  falloff;         // IDW sharpness, clamped to [0.5, 8]; 2.0 = default look
    PBSysCanvasMeshPoint points[];        // pointCount entries
} PBSysCanvasCmdMeshGradient;
```

### `PBSysCanvasCmdRect`

```c
typedef struct PBSysCanvasCmdRect {
    PBSysCanvasCmd  cmd;
    PBSysCanvasAABB bounds;
    u64             fillColor; // wire color (see above)
} PBSysCanvasCmdRect;
```

### `PBSysCanvasCmdRoundedRect`

```c
typedef struct PBSysCanvasCmdRoundedRect {
    PBSysCanvasCmd  cmd;
    PBSysCanvasAABB bounds;
    u64             fillColor;       // wire color (see above)
    f32             cornerRadius[4]; // (tl, tr, br, bl) px; finite and >= 0
} PBSysCanvasCmdRoundedRect;
```

### `PBSysCanvasCmdStrokeRect`

```c
typedef struct PBSysCanvasCmdStrokeRect {
    PBSysCanvasCmd  cmd; // cmd.flags is a PBSysCanvasStrokeFlags value
    PBSysCanvasAABB bounds;
    f32             cornerRadius[4]; // (tl, tr, br, bl) px; finite and >= 0
    u64             strokeColor;     // wire color (see above)
    f32             strokeWidth;     // px
} PBSysCanvasCmdStrokeRect;
```

### `PBSysCanvasCmdText`

```c
typedef struct PBSysCanvasCmdText {
    PBSysCanvasCmd       cmd;
    PBSysCanvasAABB      bounds; // x1,y1 is text origin; x2,y2 reserved for future bounds use
    PBSysHandle          textPlan;
    PBSysCanvasTextFlags flags;
    u64                  fillColor; // wire color (see above)
} PBSysCanvasCmdText;
```

### `PBSysCanvasCmdTextureSet`

```c
typedef struct PBSysCanvasCmdTextureSet {
    PBSysCanvasCmd cmd;
    PBSysHandle    texture; // PBSysHandle_INVALID clears to default
    u32            _reserved;
} PBSysCanvasCmdTextureSet;
```

### `PBSysCanvasCmdTransformPop`

```c
typedef struct PBSysCanvasCmdTransformPop {
    PBSysCanvasCmd cmd;
} PBSysCanvasCmdTransformPop;
```

### `PBSysCanvasCmdTransformPush`

```c
typedef struct PBSysCanvasCmdTransformPush {
    PBSysCanvasCmd   cmd;
    PBSys2DTransform transform;
} PBSysCanvasCmdTransformPush;
```

### `PBSysCanvasGradientStop`

```c
typedef struct PBSysCanvasGradientStop {
    f32 offset;    // position along the ramp in [0, 1]; ascending, ties = hard stop
    u32 _reserved; // must be 0
    u64 color;     // wire color (see above)
} PBSysCanvasGradientStop;
```

### `PBSysCanvasMeshPoint`

```c
typedef struct PBSysCanvasMeshPoint {
    f32 x, y;      // local px, relative to bounds top-left, pre-transform
    f32 weight;    // per-point influence multiplier, finite and > 0 (1.0 = default)
    u32 _reserved; // must be 0
    u64 color;     // wire color (see above)
} PBSysCanvasMeshPoint;
```

### `PBSysClockInfo`

```c
typedef struct PBSysClockInfo {
    char timeZoneName[63]; // IANA time zone identifier (e.g. "")
    u8   timeZoneNameLen;  // length of timeZoneName
} PBSysClockInfo;
```

### `PBSysEvent`

```c
typedef struct PBSysEvent {
    u16           size;     // size of the event
    u16           type;     // PBSysEventType
    PBSysObjectId objectId; // originating object ID, e.g. window (0 means "unknown")
} PB_ATTR_ALIGNED(8) PBSysEvent;
```

### `PBSysFileId`

```c
typedef struct PBSysFileId {
    u8 data[32];
} PBSysFileId;
```

### `PBSysFileListEntry`

```c
typedef struct PBSysFileListEntry {
    u64                    id; // file's unique ID within the file system (inode ID or similar)
    PBSysFileListEntryType type;
} PBSysFileListEntry;
```

### `PBSysFilePanelEvent`

```c
typedef struct PBSysFilePanelEvent {
    PBSysEvent  event;
    PBSysHandle handle;
} PBSysFilePanelEvent;
```

### `PBSysGamepadEvent`

```c
typedef struct PBSysGamepadEvent {
    PBSysInputEvent inputEvent;
    u16 control; // PBSysGamepadButton for button events, PBSysGamepadAxis for axis events
    u16 flags;   // currently unused
    f32 value;   // scalar value for changed control
    f32 x;       // x axis for 2D controls, otherwise 0
    f32 y;       // y axis for 2D controls, otherwise 0
} PBSysGamepadEvent;
```

### `PBSysGestureEvent`

```c
typedef struct PBSysGestureEvent {
    PBSysInputEvent   inputEvent;
    PBSysGesturePhase phase;
    u8                _reserved;
    u16               flags;    // currenty unused
    f32               x, y;     // gesture center in window coords (dp) if known
    f32               dx, dy;   // pan delta (dp) for PAN; else 0
    f32               scale;    // relative scale delta for PINCH (1.0 means no change; e.g. 1.02)
    f32               rotation; // relative rotation delta in radians for ROTATE
} PBSysGestureEvent;
```

### `PBSysGuiPrefs`

```c
typedef struct {
    PBSysGuiPrefsFlags flags;
    u64                selectionColor; // wire color; i.e. background of text selection
    u64                accentColor;    // wire color; for things like macOS window controls
} PBSysGuiPrefs;
```

### `PBSysHandleInfo`

```c
typedef struct PBSysHandleInfo {
    PBSysHandle     handle;
    PBSysRights     rights;
    PBSysHandleName name;
    PBSysObjectType objectType;
    PBSysObjectId   objectId;
} PBSysHandleInfo;
```

### `PBSysHandlePair`

```c
typedef struct PBSysHandlePair {
    PBSysHandle a, b;
} PBSysHandlePair;
```

### `PBSysHidDeviceInfo`

```c
typedef struct PBSysHidDeviceInfo {
    PBSysHidDeviceType  type;
    PBSysHidDeviceFlags flags;
    u32                 gamepadAxisMask;     // PBSysGamepadAxis bits
    u32                 gamepadButtonMask;   // PBSysGamepadButton bits
    u32                 hapticsLocalityMask; // PBSysHidHapticsLocality bits
} PBSysHidDeviceInfo;
```

### `PBSysInputEvent`

```c
typedef struct PBSysInputEvent {
    PBSysEvent event;
    PBSysTime  timestamp; // time the event occurred
    u32        clientId;  // originating client ID (0 for "local")
    u32        deviceId;  // stable per HID
    u16        modifiers; // PBSysKeyboardModifiers
    u16        _reserved;
} PBSysInputEvent;
```

### `PBSysKeyboardEvent`

```c
typedef struct PBSysKeyboardEvent {
    PBSysInputEvent  inputEvent;
    PBSysKeyboardKey keyCode;    // logical code for the key, i.e. "the A key"
    PBSysKeyboardKey deviceCode; // physical key, i.e. "3rd key on 4th row"
    u32              text[8];    // Unicode representation
    u8               textLen;    // number of codepoints in text array
    u8               _reserved;  //
    u16              flags;      // PBSysKeyboardFlags
} PBSysKeyboardEvent;
```

### `PBSysNetSessionConfig`

```c
typedef struct PBSysNetSessionConfig {
    u64                flags;         // unused, set to 0
    u64                authId;        // local auth state key. Use 0 for default.
    const u8* nullable serverAddr;    // "host:port" as UTF-8 text. Leave empty for default.
    u32                serverAddrLen; // number of bytes at serverAddr
} PBSysNetSessionConfig;
```

### `PBSysNetTransportConfig`

```c
typedef struct PBSysNetTransportConfig {
    /*
    idleTimeoutMs determines how long a connection may stay idle without I/O happening, in milliseconds. Once a connection has been idle for idleTimeoutMs, it's closed (assuming keep-alive is disabled.) A timeout of `0` means "default."
    */
    u32 idleTimeoutMs;

    PBSysNetTransportFlags flags;

    /*
    alpn is "Application-Layer Protocol Negotiation" for TLS and QUIC. A semicolon-separated ALPN list, in priority order.
    Required to be non-zero for QUIC.
    Currently only one ALPN is supported.
    */
    const u8* nullable alpn;
    u32                alpnLen;

    // sni is "Server Name Indication" for TLS and QUIC
    const u8* nullable sni;
    u32                sniLen;

    // certPem is a PEM-encoded root certificate for TLS and QUIC peer verification
    const u8* nullable certPem;
    u32                certPemLen;
} PBSysNetTransportConfig;
```

### `PBSysPenPointerEvent`

```c
typedef struct PBSysPenPointerEvent {
    PBSysPointerEvent pointerEvent;
    f32               pressure;           // [0..1]
    f32               tangentialPressure; // [0..1] barrel pressure (pen)
    f32               tiltX, tiltY;       // [-1, +1] 0 = perpendicular
    f32               twist;              // degrees [0, 359]; barrel rotation (pen)
    f32               width, height;      // contact ellipse in dp (touch/pen)
    f32               altitudeAngle;      // [0, π/2] radians (0 = parallel, π/2 = perpendicular)
    f32               azimuthAngle;       // [0, π/2] radians, direction in the screen plane
} PBSysPenPointerEvent;
```

### `PBSysPointerEvent`

```c
typedef struct PBSysPointerEvent {
    PBSysInputEvent  inputEvent;
    u32              pointerId;  // logical; stable per active contact/stream
    u16              flags;      // PBSysPointerFlags
    u16              buttons;    // current button bitmask (mouse/pen)
    u8               button;     // "changed" button for DOWN/UP/CLICK (0 if n/a)
    PBSysPointerKind kind;       //
    u8               clickCount; // for CLICK (and optionally DOWN/UP if platform provides)
    u8               _reserved;  //
    f32              x, y;       // position in window coords (dp)
    f32              dx, dy;     // delta since last event for this pointerId (dp). 0 if unknown.
} PBSysPointerEvent;
```

### `PBSysPositionedTextAttribute`

```c
typedef struct PBSysPositionedTextAttribute {
    u32                start;
    PBSysTextAttribute attribute;
} PBSysPositionedTextAttribute;
```

### `PBSysScrollEvent`

```c
typedef struct PBSysScrollEvent {
    PBSysInputEvent  inputEvent;
    PBSysPointerKind kind;
    PBSysScrollPhase phase;
    u16              flags;  // PBSysScrollFlags
    f32              x, y;   // focus point in window coords if known, else 0
    f32              dx, dy; // scroll delta (dp or lines/pages depending on flags)
    f32              wheelZ; // optional for 3D wheels; else 0
} PBSysScrollEvent;
```

### `PBSysSignalEvent`

```c
typedef struct PBSysSignalEvent {
    PBSysEvent      event;
    PBSysHandle     handle;
    PBSysSignals    signals;
    PBSysSignals    pulseSignals;
    PBSysObjectType objectType;
    u16             _reserved;
} PBSysSignalEvent;
```

### `PBSysStr`

```c
typedef struct PBSysStr {
    uint32_t len;
    uint8_t  bytes[];
} PBSysStr;
```

### `PBSysStreamStats`

```c
typedef struct PBSysStreamStats {
    PBSysTime timestamp; // time at which the statistics were gathered

    /*
    bytesReceived indicates the number of bytes received by this stream, up to the first missing byte. The number does not include any network or transport overhead, and can only increase over time.
    */
    u64 bytesReceived;

    /*
    bytesRead indicates the number of bytes the application has read from this stream. This number can only increase, and is always less than or equal to bytesReceived.
    */
    u64 bytesRead;
} PBSysStreamStats;
```

### `PBSysTextAttribute`

```c
typedef struct PBSysTextAttribute {
    PBSysTextAttributeType type;
    union {
        /*
        feature is used by PBSysTextAttribute_VARIABLE_AXIS, PBSysTextAttribute_OTYPE_FEATURE
        */
        PBSysTextAttributeValueFeature feature;

        /*
        b is used by PBSysTextAttribute_LIGATURES, PBSysTextAttribute_SUPERSCRIPT, PBSysTextAttribute_SUBSCRIPT, PBSysTextAttribute_SMALL_CAPS, PBSysTextAttribute_KERNING, PBSysTextAttribute_ITALICS
         */
        PBSysTextAttributeValueBool b;

        PBSysTextAttributeValueNumerals numerals; // used by PBSysTextAttribute_NUMERALS
        u32                             u;        // used by PBSysTextAttribute_FONT_FAMILY

        /*
        decoration is used by PBSysTextAttribute_UNDERLINE, PBSysTextAttribute_STRIKE_THROUGH
        */
        PBSysTextAttributeValueDecoration decoration;

        /*
        f is used by PBSysTextAttribute_SIZE, PBSysTextAttribute_WEIGHT, PBSysTextAttribute_STRETCH, PBSysTextAttribute_CHARACTER_SPACING, PBSysTextAttribute_OUTLINE_THICKNESS, PBSysTextAttribute_SHADOW_BLUR_RADIUS, PBSysTextAttribute_SHADOW_OFFSET_X, PBSysTextAttribute_SHADOW_OFFSET_Y, PBSysTextAttribute_LINE_HEIGHT_MULTIPLIER, PBSysTextAttribute_TAB_SIZE
        */
        f32 f;

        /*
        color is used by PBSysTextAttribute_COLOR, PBSysTextAttribute_OUTLINE_COLOR, PBSysTextAttribute_SHADOW_COLOR
        */
        u64 color;

        PBSysTextAttributeValueAlignment alignment; // used by PBSysTextAttribute_ALIGNMENT
        PBSysTextAttributeValueDirection direction; // used by PBSysTextAttribute_DIRECTION
    };
} PBSysTextAttribute;
```

### `PBSysTextAttributeValueDecoration`

```c
typedef struct PBSysTextAttributeValueDecoration {
    PBSysTextAttributeValueDecorationStyle style;
    u64                                    color;
} PBSysTextAttributeValueDecoration;
```

### `PBSysTextAttributeValueFeature`

```c
typedef struct PBSysTextAttributeValueFeature {
    u32 tag;
    u32 value;
} PBSysTextAttributeValueFeature;
```

### `PBSysTextplanSelection`

```c
typedef struct PBSysTextplanSelection {
    u64 anchor;
    u64 caret;
    u64 lastDown;
} PBSysTextplanSelection;
```

### `PBSysTextplanSelectionRect`

```c
typedef struct PBSysTextplanSelectionRect {
    i32 x, y;
    i32 width, height;
} PBSysTextplanSelectionRect;
```

### `PBSysThreadConfig`

```c
typedef struct PBSysThreadConfig {
    PBSysThreadEntry entry;
    u64              arg1, arg2;

    // thread stack memory
    void* stack;
    u32   stackSize;

    /*
    rights for the new thread's SELF_THREAD handle. Usually you want this to be PBSysRight_SAME_RIGHTS
    */
    PBSysRights rights;

    // handles to be transferred from the caller to the new thread
    const PBSysHandle* nullable transferHandles;
    u32                         transferHandlesCount;
} PBSysThreadConfig;
```

### `PBSysVec2`

```c
typedef struct PBSysVec2 {
    f32 x, y;
} PBSysVec2;
```

### `PBSysWindowConfig`

```c
typedef struct PBSysWindowConfig {
    f32                x, y;          // location on screen in dp (-1 = default location)
    f32                width, height; // content size in dp (0 = default size)
    const u8* nullable title;         // UTF-8 text
    u32                titleLen;      // number of bytes at 'title'
    u64                _reserved[4];
} PBSysWindowConfig;
```

### `PBSysWindowInfo`

```c
typedef struct PBSysWindowInfo {
    f32 x, y;                        // position of top-left corner on screen, in dp
    f32 width, height;               // size of window in dp (including OS decorations)
    f32 minWidth, minHeight;         // lower limit of width & height
    f32 maxWidth, maxHeight;         // upper limit of width & height
    f32 contentX, contentY;          // offset of content relative to the window frame
    f32 contentWidth, contentHeight; // size of window contents in dp
    f32 dpScale;                     // number of pixels per dp
    /*
    pxPerInch is the physical pixel density of the display the window is
    currently on (pixels per inch). 0 when unknown (e.g. web, or displays
    that do not report a physical size). 0 is reported rather than a guess
    so that measured density stays distinguishable from the fallback;
    PBWindowPxPerInch applies the documented fallback (96 * dpScale, the
    CSS reference density) for callers that just want a usable number.
    */
    f32              pxPerInch;
    PBSysWindowStyle style;
    PBSysTime        frameTime; // estimated presentation time of next frame
} PBSysWindowInfo;
```

### `PBWindowWorkspaceOpenURLConfig`

```c
typedef struct PBWindowWorkspaceOpenURLConfig {
    // Currently, no flags are defined.
    u32 flags;
} PBWindowWorkspaceOpenURLConfig;
```

# Runtime system calls

## Audio

### PBSysAudioBufferCreate

```c
PBSysAudioBuffer PBSysAudioBufferCreate(PBSysHandle audio,
                                        const void* data,
                                        usize       dataSize,
                                        u32         numChannels,
                                        u32         sampleRate,
                                        u32         totalSampleCount);
```

PBSysAudioBufferCreate creates a new `audio` buffer and uploads it to the sound mixer.

- Required rights: `PBSysRight_WRITE`

### PBSysAudioBufferCreateFromFile

```c
PBSysAudioBuffer PBSysAudioBufferCreateFromFile(PBSysHandle audio,
                                                const void* data,
                                                usize       dataSize,
                                                u64         flags);
```

PBSysAudioBufferCreateFromFile creates an `audio` buffer from a file.

At the present moment, we only support raw WAV file `data`. This function will be extended in the future to support more formats.

- Parameters:
  - `flags`: Unused. Pass `0`.
- Required rights: `PBSysRight_WRITE`

### PBSysAudioBufferDestroy

```c
PBSysErr PBSysAudioBufferDestroy(PBSysHandle      audio,
                                 PBSysAudioBuffer buffer);
```

PBSysAudioBufferDestroy destroys an `audio` `buffer` (and frees the associated memory with it).

- Required rights: `PBSysRight_WRITE`

### PBSysAudioBufferPlay

```c
PBSysAudioSound PBSysAudioBufferPlay(PBSysHandle      audio,
                                     PBSysAudioBuffer buffer,
                                     u64              flags);
```

PBSysAudioBufferPlay starts playing an instance of an `audio` `buffer`.

- Parameters:
  - `buffer`: The `buffer` to play
  - `flags`: Unused. Pass `0`.
- Returns: the handle to the playing sound in the sound mixer.
- Required rights: `PBSysRight_WRITE`

### PBSysAudioBufferPlayAfter

```c
PBSysAudioSound PBSysAudioBufferPlayAfter(PBSysHandle      audio,
                                          PBSysAudioBuffer buffer,
                                          PBSysAudioSound  playingSound);
```

PBSysAudioBufferPlayAfter creates a new sound from `buffer`, like `PBSysAudioBufferPlay`, but
instead of starting it right away, schedules it to start playing seamlessly (gaplessly) the
moment `playingSound` finishes. Callers can chain further buffers onto the sound this returns
to keep streaming `audio` as a sequence of small buffers rendered just-in-time.

If `playingSound` isn`t currently playing (e.g. it already finished), there`s nothing to wait
for, so the new sound starts playing immediately instead.

- Returns: the handle to the (possibly not yet started) sound in the sound mixer.
- Required rights: `PBSysRight_WRITE`

### PBSysAudioBufferUpload

```c
PBSysErr PBSysAudioBufferUpload(PBSysHandle      audio,
                                PBSysAudioBuffer buffer,
                                const void*      data,
                                usize            dataSize,
                                u32              numChannels,
                                u32              sampleRate,
                                u32              totalSampleCount);
```

PBSysAudioBufferUpload replaces the sample `data` of an existing, no-longer-playing `audio` `buffer`
in place, without allocating a new `buffer` or sound-mixer slot. Intended for a small fixed ring
of buffers used to stream `audio`, where each `buffer` is refilled and re-queued (via
`PBSysAudioBufferPlayAfter`) only after `PBSysAudioSoundIsPlaying` reports its previous sound has
finished.

It is a caller error to upload into a `buffer` that a currently-playing (or not-yet-finished,
queued) sound still references.

- Required rights: `PBSysRight_WRITE`

### PBSysAudioOutputInit

```c
bool PBSysAudioOutputInit(PBSysHandle audio);
```

Inits the `audio` output backend for sound playback (globally).
It has been observed that sometimes this can take a little while (e.g. ~200ms when using bluetooth headphones on MacOS).
As such, you should call this at the start of your program if you intend to play `audio`.

- Required rights: `PBSysRight_WRITE`

### PBSysAudioSetVolume

```c
void PBSysAudioSetVolume(PBSysHandle audio,
                         f32         volume);
```

PBSysAudioSetVolume sets the global `volume` of the sound mixer.

- Parameters:
  - `volume`: Normalized value in the range `[0.0–1.0]` (0–100%)
- Required rights: `PBSysRight_WRITE`

### PBSysAudioSoundGetPosition

```c
u64 PBSysAudioSoundGetPosition(PBSysHandle     audio,
                               PBSysAudioSound sound);
```

PBSysAudioSoundGetPosition returns the current playback position, in sample frames, of `sound`
within its buffer. This reflects what the mixer has actually consumed as of the last `audio`
callback, i.e. what's truly audible right now -- not merely queued or rendered ahead of time.

Returns 0 if `sound` is invalid or hasn't started playing yet.

- Required rights: `PBSysRight_READ`

### PBSysAudioSoundIsPlaying

```c
bool PBSysAudioSoundIsPlaying(PBSysHandle     audio,
                              PBSysAudioSound sound);
```

PBSysAudioSoundIsPlaying returns true if `sound` is the one currently being mixed into the
output right now, according to the mixer itself -- not a locally-predicted end time. A `sound`
that hasn't started yet (waiting on a `PBSysAudioBufferPlayAfter` predecessor) or that has already
finished playing both report false.

Intended for driving gapless streaming playback: poll this instead of guessing when a queued
buffer will finish, and recycle/refill it (see `PBSysAudioBufferUpload`) once it reports false.

- Required rights: `PBSysRight_READ`

### PBSysAudioSoundPlayback

```c
PBSysErr PBSysAudioSoundPlayback(PBSysHandle                  audio,
                                 PBSysAudioSound              sound,
                                 f32                          speed,
                                 PBSysAudioSoundPlaybackFlags flags);
```

PBSysAudioSoundPlayback controls playback of a `sound`.

- `PBSysAudioSoundPlayback( … , PBSysAudioSoundPlaybackFlag_RESUME)` resumes playback; stops playing when end of `sound` is reached.
- `PBSysAudioSoundPlayback( … , PBSysAudioSoundPlaybackFlag_RESUME_LOOP)` resumes playback, loop around and restarts playback when end of `sound` is reached.
- `PBSysAudioSoundPlayback( … , 0)` pauses playback.

- Parameters:
  - `speed`: Playback `speed`. (1.0 = 1x, 2.0 = 2x and so on.) Currently only `1.0` is supported.
  - `flags`: Set to `0` to pause playback.
- Required rights: `PBSysRight_WRITE`

### PBSysAudioSoundSeek

```c
PBSysErr PBSysAudioSoundSeek(PBSysHandle     audio,
                             PBSysAudioSound sound,
                             f32             position,
                             u64             flags);
```

PBSysAudioSoundSeek changes the playback `position`.

- Parameters:
  - `position`: Normalized `position` to seek to, clamped to `[0.0–1.0]`.
  - `flags`: Unused. Pass `0`.
- Required rights: `PBSysRight_WRITE`

### PBSysAudioSoundTell

```c
f32 PBSysAudioSoundTell(PBSysHandle     audio,
                        PBSysAudioSound sound,
                        u64             flags);
```

PBSysAudioSoundTell returns the current playback position.

- Parameters:
  - `flags`: Unused. Pass `0`.
- Returns: Normalized playback position (`[0.0–1.0]`), i.e. `0.0` = not started, `1.0` = ended. Returns `<0.0` if `audio` handle does not have `PBSysRight_READ` rights.
- Required rights: `PBSysRight_READ`

## Canvas

### PBSysCanvasCreateTexture

```c
PBSysHandle PBSysCanvasCreateTexture(PBSysHandle             canvas,
                                     PBSysTextureFormat      format,
                                     u32                     widthInPx,
                                     u32                     heightInPx,
                                     PBSysTextureCreateFlags flags);
```

PBSysCanvasCreateTexture creates a GPU texture associated with a `canvas`.
The texture can be uploaded to via `PBSysTextureWrite` and set as the active texture
with `PBSysCanvasCmdTextureSet`.

- Parameters:
  - `format`: pixel `format`
  - `widthInPx`: texture width in pixels
  - `heightInPx`: texture height in pixels
  - `flags`: `PBSysTextureCreateFlags`
- Required rights: none

### PBSysCanvasCreateTextureFromData

```c
PBSysHandle PBSysCanvasCreateTextureFromData(PBSysHandle             canvas,
                                             PBSysTextureFormat      format,
                                             const void*             data,
                                             u64                     dataSize,
                                             PBSysTextureCreateFlags flags);
```

PBSysCanvasCreateTextureFromData decodes image `data` and creates a GPU texture in one step.
Supported encoded formats include PNG, JPEG, WebP, GIF, BMP, and TGA.

- Parameters:
  - `format`: destination pixel `format`
  - `data`: encoded image bytes
  - `dataSize`: size of `data` in bytes
  - `flags`: `PBSysTextureCreateFlags`
- Required rights: none

### PBSysCanvasOpen

```c
PBSysHandle PBSysCanvasOpen(u32 widthInPx,
                            u32 heightInPx,
                            u64 flags);
```

PBSysCanvasOpen creates a fixed-size offscreen canvas.

The returned canvas can be rendered to with `PBSysCanvasRender` and composited into another canvas with `PBSysCanvasCmdTextureSet`.

- Parameters:
  - `widthInPx`: horizontal size in pixels
  - `heightInPx`: vertical size in pixels
  - `flags`: Unused. Pass 0
- Required rights: none

### PBSysCanvasRender

```c
PBSysErr PBSysCanvasRender(PBSysHandle           canvas,
                           u64                   backgroundColor,
                           const PBSysCanvasCmd* cmds,
                           u32                   cmdsSize,
                           u64                   flags);
```

PBSysCanvasRender submits renderer commands to a `canvas`

- Parameters:
  - `canvas`: to render to
  - `backgroundColor`: clears the `canvas` before rendering; wire color format
  - `cmds`: command queue
  - `cmdsSize`: size in bytes of `cmds`
  - `flags`: Unused. Pass 0.
- Required rights: `PBSysRight_WRITE`

### PBSysCanvasResize

```c
PBSysErr PBSysCanvasResize(PBSysHandle canvas,
                           u32         widthInPx,
                           u32         heightInPx,
                           u64         flags);
```

PBSysCanvasResize changes the size of an offscreen `canvas`.

Previous `canvas` contents are discarded. Render again after resizing.

- Parameters:
  - `canvas`: offscreen `canvas` to resize
  - `widthInPx`: new horizontal size in pixels
  - `heightInPx`: new vertical size in pixels
  - `flags`: Unused. Pass 0
- Required rights: `PBSysRight_WRITE`

## Channel

### PBSysChannelCreate

```c
PBSysHandle PBSysChannelCreate(u32          entSize,
                               u32          cap,
                               u32          maxCap,
                               PBSysHandle* readHandleOut,
                               u64          flags);
```

PBSysChannelCreate creates a channel which supports writing entries of `entSize` bytes.

If the `PBSysChannel_DUPLEX` flag is set, the returned handles will have both `PBSysRight_READ` and `PBSysRight_WRITE`. `PBSysChannel_DUPLEX` is implied if `readHandleOut` is NULL.

If the `PBSysChannel_MULTIPLE_WRITERS` flag is set, the returned handle will have `PBSysRight_DUPLICATE`. Similarly, if the `PBSysChannel_MULTIPLE_READERS` flag is set, a handle returned in `readHandleOut` will have `PBSysRight_DUPLICATE`.

- Parameters:
  - `readHandleOut`: If not NULL, a second handle is returned with `PBSysRight_READ`.
  - `cap`: Initial capacity of the internal buffer, in number of entries. I.e. the total amount of memory allocated for the internal buffer is at least `entSize`*cap bytes.
  - `maxCap`: Limits how much the internal buffer can grow. If `maxCap` is <= `cap`, a fixed size is used.
- Returns: A handle to the channel with `PBSysRight_WRITE`.
- Required rights: none

### PBSysChannelDisableWrite

```c
PBSysErr PBSysChannelDisableWrite(PBSysHandle channel);
```

PBSysChannelDisableWrite disables the ability to write to the `channel`, while reading remains possible. This is useful for "graceful shutdown" of channels; preventing new data from being produces while allowing queued data to be flushed.

- Required rights: `PBSysRight_WRITE`

### PBSysChannelRead

```c
i32 PBSysChannelRead(PBSysHandle channel,
                     void*       dstEnts,
                     u32         dstEntSize,
                     u32         dstEntsCap,
                     u64         flags);
```

PBSysChannelRead reads up to `dstEntsCap` entries from a `channel`.

Panics if srcEntSize is different than the entSize the `channel` was created with.

- Parameters:
  - `dstEnts`: Must be an array of `dstEntsCap` number of entries, `dstEntSize` bytes each.
  - `flags`: Should be 0.
- Returns: The number of entries read. 0 if there were no entries to be read or if `dstEntsCap` == 0. `PBSysErr_END` if the `channel` is closed.
- Required rights: `PBSysRight_READ`

### PBSysChannelWrite

```c
i32 PBSysChannelWrite(PBSysHandle channel,
                      const void* srcEnts,
                      u32         srcEntSize,
                      u32         srcEntsCap,
                      u64         flags);
```

PBSysChannelWrite writes up to `srcEntsCap` entries to a `channel`.

Panics if `srcEntSize` is different than the entSize the `channel` was created with.

- Parameters:
  - `srcEnts`: Must be an array of `srcEntsCap` number of entries, `srcEntSize` bytes each.
  - `flags`: Should be 0.
- Returns: The number of entries written. 0 if the `channel` is full or `srcEntsCap` == 0. `PBSysErr_END` if the `channel` is closed for writing.
- Required rights: `PBSysRight_WRITE`

## Clock

### PBSysClockMonotonic

```c
PBSysTime PBSysClockMonotonic();
```

PBSysClockMonotonic returns the current system time

- Required rights: none

### PBSysClockRead

```c
PBSysDate PBSysClockRead(PBSysHandle clock);
```

PBSysClockRead returns the current "real" (calendar) time in UTC. On error, a `PBSysErr` is returned as a negative value. Thus, this function never returns a time value earlier than 1970-01-01 00:00:00.

- Required rights: `PBSysRight_READ`

### PBSysClockReadInfo

```c
PBSysErr PBSysClockReadInfo(PBSysHandle     clock,
                            PBSysClockInfo* info,
                            u32             infoSize);
```

PBSysClockReadInfo retrieves information about a `clock`

- Required rights: `PBSysRight_READ`

## Event

### PBSysEventPoll

```c
i32 PBSysEventPoll(PBSysEvent* events,
                   u32         eventsSize,
                   u64         deadline,
                   u64         deadlineLeeway);
```

PBSysEventPoll retrieves `events` from the runtime, suspending the calling thread if needed.

- Parameters:
  - `events`: Buffer to be populated with produced `events`.
  - `eventsSize`: Total number of bytes available at `events`. Note that this is not the number of `PBSysEvent` structs but bytes of memory. The size of a `PBSysEvent` is variable. Generally this should be at least a kilobyte since IME input `events` may be arbitrarily large. In most cases single `events` are small; tens of bytes.
  - `deadline`: When to time out. If `deadline` is U64_MAX, it will wait indefinitely until at least one event can be returned or an error occurs. If `deadline` is 0, this function only checks for available `events` without blocking.
  - `deadlineLeeway`: Precision request in nanoseconds; how much `deadline` is willing to fluctuate.
- Returns: The number of `events` written (not the number of bytes.) 0 if `deadline` was reached, when `deadline` > 0. 0 if there were no `events` available, when `deadline` == 0 or eventsCap == 0. `PBSysErr_END` if the current thread is exiting (even pipeline shut down.) `PBSysErr_NO_MEM` if `eventsSize` is too small for a single event.
- Required rights: none

## FileList

### PBSysFileListNext

```c
i32 PBSysFileListNext(PBSysHandle         fileList,
                      u8*                 name,
                      u32                 nameCap,
                      PBSysFileListEntry* entry,
                      u32                 entrySize,
                      u64                 flags);
```

PBSysFileListNextName read the `name` of the next `entry` in a directory listing.

- Parameters:
  - `fileList`: `Handle` to object of type `PBSysObject_FileList`
  - `name`: Buffer in which to write `name` of next `entry`
  - `nameCap`: Capacity of `name`, in bytes
  - `entry`: Optional buffer in which to write additional information about the next `entry`
  - `entrySize`: Size in bytes of `entry`
- Returns: Total number of bytes written to `name` `PBSysErr_END` when the end of the list has been reached. `PBSysErr_BUFFER_TOO_SMALL` if `name` was too short, in which can you can try again with larger `nameCap` `PBSysErr` as a negative value on error.
- Required rights: `PBSysRight_READ`

## File

### PBSysFileListOpen

```c
PBSysHandle PBSysFileListOpen(PBSysHandle dir,
                              const u8*   path,
                              u32         pathLen,
                              u64         flags);
```

PBSysFileListOpen begins a list operation of the directory `dir`/`path`, or `dir` if `pathLen` is `0`. Call `PBSysFileListNext` to retrieve entries and `PBSysHandleClose` when done.

- Parameters:
  - `path`: Path as UTF-8 text
  - `pathLen`: Size in bytes of `path`. May be 0 to mean "dir"
  - `flags`: Unused. Pass 0.
- Returns: a handle to an object of type `PBSysObject_FileList`
- Required rights: none

### PBSysFileOpen

```c
PBSysHandle PBSysFileOpen(PBSysHandle dir,
                          const u8*   path,
                          u32         pathLen,
                          u64         flags);
```

PBSysFileOpen opens a file or directory that's contained within a directory denoted by `dir`.

The effective rights given to the opened file must be the same or a subset of the rights given to the `fs` handle. I.e. on a read-only filesystem you cannot pass `PBSysFileOpenFlag_WRITE`.

The resulting handle is given `PBSysRight_TRANSFER` and `PBSysRight_DUPLICATE`, in addition to `PBSysRight_READ` and/or `PBSysRight_WRITE` as defined by `flags`.

- Parameters:
  - `dir`: Parent directory, an object of type `PBSysObject_File`
  - `path`: Path as UTF-8 text
  - `pathLen`: Size in bytes of `path`. Must be >0
  - `flags`: Bits of `PBSysFileOpenFlags`
- Returns: `Handle` to a `PBSysObject_File` object that represents the item at `path`, or `PBSysErr` (negative value) on error
- Required rights: `PBSysRight_READ`

### PBSysFileRead

```c
i64 PBSysFileRead(PBSysHandle     file,
                  const PBSysBuf* bufs,
                  u32             bufCount,
                  u32             flags);
```

PBSysFileRead reads bytes from a `file` at its current read cursor into one or more buffers.

Note: Currently only synchronous reads are supported. Returns `PBSysErr_NOT_SUPPORTED` unless `PBSysFileReadFlag_SYNC` is set.

- Parameters:
  - `flags`: Bits of `PBSysFileReadFlags`
- Required rights: `PBSysRight_READ`

### PBSysFileWrite

```c
i64 PBSysFileWrite(PBSysHandle     file,
                   const PBSysBuf* bufs,
                   u32             bufCount,
                   u32             flags);
```

PBSysFileWrite writes bytes from one or more buffers to a `file` at the `file`'s current write cursor.

Note: Currently only synchronous writes are supported. Returns `PBSysErr_NOT_SUPPORTED` unless `PBSysFileWriteFlag_SYNC` is set.

- Parameters:
  - `flags`: Bits of `PBSysFileWriteFlags`
- Required rights: `PBSysRight_WRITE`

## FilePanel

### PBSysFilePanelGetResult

```c
i64 PBSysFilePanelGetResult(PBSysHandle window,
                            u8*         buffer,
                            u64         bufferSize);
```

PBSysFilePanelGetResult reads the selected file path from the file panel. Zero is returned if the panel was canceled.

- Required rights: `PBSysRight_READ`

## Gui

### PBSysGuiPrefsGet

```c
PBSysErr PBSysGuiPrefsGet(PBSysHandle    gui,
                          PBSysGuiPrefs* config,
                          u32            configSize);
```

PBSysGuiPrefsGet reads the current system UI preferences (e.g. dark mode, high contrast etc.)

- Required rights: none

### PBSysGuiPresentationGet

```c
PBSysGuiPresentation PBSysGuiPresentationGet(PBSysHandle gui);
```

PBSysGuiPresentationGet reads the app's current presentation configuration

- Returns: Flags as a positive integer or `PBSysErr_ACCESS_DENIED`
- Required rights: `PBSysRight_READ`

### PBSysGuiPresentationSet

```c
PBSysGuiPresentation PBSysGuiPresentationSet(PBSysHandle          gui,
                                             PBSysGuiPresentation flags);
```

PBSysGuiPresentationSet configures the app's presentation

- Returns: previous value as a positive integer or `PBSysErr_ACCESS_DENIED`
- Required rights: `PBSysRight_WRITE`

## Handle

### PBSysHandleClose

```c
PBSysErr PBSysHandleClose(PBSysHandle handle);
```

PBSysHandleClose closes a `handle`. The `handle` is invalid after this call.

- Required rights: none

### PBSysHandleDuplicate

```c
PBSysHandle PBSysHandleDuplicate(PBSysHandle     handle,
                                 PBSysRights     rights,
                                 PBSysHandleName name);
```

PBSysHandleDuplicate creates a new `handle` to the object referred to by `handle`. `rights` controls what `rights` are given and can only be same or less than the `rights` granted to `handle`. Use `PBSysRight_SAME_RIGHTS` for "same rights." Note: The new `handle` is unconditionally given `PBSysRight_TRANSFER`.

- Returns: A negative value as PBSysError on error.
- Required rights: `PBSysRight_DUPLICATE`

### PBSysHandleList

```c
i32 PBSysHandleList(PBSysHandleInfo* handles,
                    u32              handlesCap,
                    u32              handleSize,
                    u64              flags,
                    u64              predicate);
```

PBSysHandleList returns information about `handles` held by the calling thread. Writes up to `handlesCap` entries to `handles`.

`flags` are bits of `PBSysHandleListFlags`.

If `flags` contain a filter; a `PBSysHandleListFilter` value in the bits `PBSysHandleList_FILTER`, then `predicate` is a value for the filter. Only `handles` matching the filter are returned.

- Returns: The total number of `handles`, which might be more than `handlesCap`. <0 if an error occurred, as a `PBSysErr`.
- Required rights: none

## Hid

### PBSysHidDeviceInfoGet

```c
PBSysErr PBSysHidDeviceInfoGet(PBSysHandle         hid,
                               u32                 deviceId,
                               PBSysHidDeviceInfo* info,
                               u32                 infoSize,
                               u32                 flags);
```

PBSysHidDeviceInfoGet retrieves general information about a device.

- Parameters:
  - `deviceId`: HID device to query
  - `info`: result storage
  - `infoSize`: size of `PBSysHidDeviceInfo`, for ABI compatibility
  - `flags`: Unused. Pass 0
- Required rights: `PBSysRight_READ`

### PBSysHidDeviceName

```c
i32 PBSysHidDeviceName(PBSysHandle hid,
                       u32         deviceId,
                       u8*         buf,
                       u32         bufCap,
                       u32         flags);
```

PBSysHidDeviceName retrieves a human-readable name describing a device, as UTF-8 text.

- Parameters:
  - `deviceId`: HID device to read name of
  - `buf`: storage for name
  - `bufCap`: size of `buf`, in bytes
  - `flags`: Unused. Pass 0
- Returns: Number of bytes that would have been copied into `buf` as if `bufCap` was infinitely large, or `PBSysErr` as a negative value on error
- Required rights: `PBSysRight_READ`

### PBSysHidDeviceSetPlayerIndex

```c
PBSysErr PBSysHidDeviceSetPlayerIndex(PBSysHandle hid,
                                      u32         deviceId,
                                      u32         playerIndex,
                                      u32         flags);
```

PBSysHidDeviceSetPlayerIndex assigns a logical player number to an HID device. On devices with player indicators, this may update the matching indicator.

- Parameters:
  - `deviceId`: HID device to assign the player index to
  - `playerIndex`: 0 for "unset", 1, 2, 3 or 4 for player 1, 2, 3 or 4
  - `flags`: Unused. Pass 0
- Required rights: `PBSysRight_WRITE`

## Net

### PBSysNetDecrypt

```c
PBSysErr PBSysNetDecrypt(PBSysHandle net,
                         const u8*   inBuf,
                         u32         inBufLen,
                         const u8*   keyBuf,
                         u32         keyBufLen,
                         u8*         outBuf,
                         u32         outBufLen);
```

Private API.

- Required rights: none

### PBSysNetDecryptAsymmetric

```c
PBSysErr PBSysNetDecryptAsymmetric(PBSysHandle net,
                                   const u8*   inBuf,
                                   u32         inBufLen,
                                   const u8*   privateKeyBuf,
                                   u32         privateKeyBufLen,
                                   u8*         outBuf,
                                   u32         outBufLen);
```

Private API.

- Required rights: none

### PBSysNetEncrypt

```c
PBSysErr PBSysNetEncrypt(PBSysHandle net,
                         const u8*   inBuf,
                         u32         inBufLen,
                         const u8*   keyBuf,
                         u32         keyBufLen,
                         u8*         outBuf,
                         u32         outBufLen);
```

Private API.

- Required rights: none

### PBSysNetEncryptAsymmetric

```c
PBSysErr PBSysNetEncryptAsymmetric(PBSysHandle net,
                                   const u8*   inBuf,
                                   u32         inBufLen,
                                   const u8*   publicKeyBuf,
                                   u32         publicKeyBufLen,
                                   u8*         outBuf,
                                   u32         outBufLen);
```

Private API.

- Required rights: none

### PBSysNetSessionOpen

```c
PBSysHandle PBSysNetSessionOpen(PBSysHandle                  net,
                                const u8*                    sessionId,
                                u32                          sessionIdLen,
                                const PBSysNetSessionConfig* config,
                                u32                          configSize);
```

PBSysNetSessionOpen opens a Playbit network session

- Parameters:
  - `net`: Networking capability (handle to an object of type `PBSysObject_Net`)
  - `sessionId`: Session identifier, unique within app-id namespace
  - `sessionIdLen`: Size in bytes of `sessionId`
  - `config`: Configuration
  - `configSize`: Size in bytes of struct in `config` parameter
- Returns: `Handle` to a `NetSession` object, or `PBSysErr` (negative value) on error. Opening a `NetSession` starts or attaches to the underlying AP connection asynchronously.
- Required rights: none

### PBSysNetTransportOpen

```c
PBSysHandle PBSysNetTransportOpen(PBSysHandle                    net,
                                  const u8*                      uri,
                                  u32                            uriLen,
                                  const PBSysNetTransportConfig* config,
                                  u32                            configSize);
```

PBSysNetTransportOpen opens a connection to a network endpoint.

URIs have the form `protocol:node`, i.e.

quic:host:port QUIC transport
tcp:host:port  TCP/IP socket
udp:host:port  UDP/IP socket

The underlying implementation may not support the requested protocol.

The object to which a handle is returned will have its `PBSysNetTransportSignal_READY` activated when the connection has been established.

- Parameters:
  - `net`: Networking capability (handle to an object of type `PBSysObject_Net`)
  - `uri`: URI.
  - `uriLen`: Size in bytes of `uri`
  - `config`: Configuration
  - `configSize`: Size in bytes of struct in `config` parameter
- Returns: `Handle` to a `NetTransport` object on success, or `PBSysErr` (negative value) on error. `PBSysErr_NOT_SUPPORTED` if the protocol type requested in `uri` is not supported.
- Required rights: none

## NetSession

### PBSysNetSessionId

```c
PBSysErr PBSysNetSessionId(PBSysHandle netSession,
                           u8*         sessionIdBuf,
                           u32         sessionIdBufCap);
```

PBSysNetSessionId copies the session identifier bytes of a network session.

- Parameters:
  - `netSession`: Network session, handle to a `NetSession` object
  - `sessionIdBuf`: Destination buffer for the session identifier bytes
  - `sessionIdBufCap`: Size in bytes of `sessionIdBuf`
- Returns: 0 on success, `PBSysErr_BUFFER_TOO_SMALL` if `sessionIdBufCap` is too small, or `PBSysErr` on failure.
- Required rights: `PBSysRight_READ`

### PBSysNetSessionOpenStream

```c
PBSysHandle PBSysNetSessionOpenStream(PBSysHandle netSession,
                                      const u8*   channelId,
                                      u32         channelIdLen,
                                      u64         flags);
```

PBSysNetSessionOpenStream opens a stream for a channel in a network session.

- Parameters:
  - `netSession`: Network session, handle to a `NetSession` object
  - `channelId`: `Channel` identifier, unique within the network session
  - `channelIdLen`: Size in bytes of `channelId`
  - `flags`: Reserved. Must be 0.
- Returns: `Handle` to a `Stream` object, or `PBSysErr` (negative value) on error. The stream may become writable later, after the underlying session is authenticated and ready.
- Required rights: none

## NetTransport

### PBSysNetTransportOpenStream

```c
PBSysHandle PBSysNetTransportOpenStream(PBSysHandle                  netTransport,
                                        PBSysNetTransportStreamFlags flags);
```

PBSysNetTransportOpenStream opens a stream within a network transport.

The returned stream will have its `PBSysStreamSignal_WRITABLE` activated when the connection has been established and the stream is ready. If `PBSysNetTransportStream_WRITE` is not present in `flags`, `PBSysStreamSignal_WRITABLE` will never become active. For QUIC, `PBSysNetTransportStream_WRITE` without `PBSysNetTransportStream_READ` opens a locally initiated unidirectional stream. QUIC READ-only streams are not currently supported.

- Parameters:
  - `netTransport`: Network transport, handle to a `NetTransport` object
  - `flags`: `PBSysNetTransportStreamFlags`
- Returns: `Handle` to a `Stream` object, or `PBSysErr` (negative value) on error.
- Required rights: `PBSysRight_WRITE`

### PBSysNetTransportSetKeepAlive

```c
PBSysErr PBSysNetTransportSetKeepAlive(PBSysHandle netTransport,
                                       i64         intervalNsec);
```

PBSysNetTransportSetKeepAlive configures a transport's keep-alive interval. When keep-alive is enabled, a transport stays open even across long periods of no I/O. When keep-alive is disabled, a transport connection closes after idleTimeoutMs (as configured by `PBSysNetTransportConfig`.)

Setting `intervalNsec` to a negative value means "enable keep-alive with implemention-default interval" while setting `intervalNsec` to 0 means "disable keep-alive."

Keep-alive is disabled by default.

- Parameters:
  - `intervalNsec`: How long between keep-alive pings in nanoseconds.
- Required rights: none

## Object

### PBSysObjectFeatures

```c
u64 PBSysObjectFeatures(PBSysHandle handle);
```

PBSysObjectFeatures returns a bitmap of features available for the object referred to by `handle`.

The bit positions in the resulting bitmap is object-type dependant.

- Returns: bitmap of available features
- Required rights: none

### PBSysObjectObserve

```c
PBSysErr PBSysObjectObserve(PBSysHandle  handle,
                            PBSysSignals signals,
                            u32          flags);
```

PBSysObjectObserve configures signal observation of the object referred to by `handle`.

Signal observation is "level" triggered by default, meaning that whenever an observed signal becomes active, a `PBSysSignalEvent` is produced, until you cancel observation by calling this function with `signals`=0. By setting the `PBSysObjectObserve_ONCE` flag, the behavior changes to be "edge" triggered, where one PBSysObjectObserve call yields just one signal event. If you want to keep observing an object after a signal event in "edge" triggered mode, you need to issue another call to PBSysObjectObserve. ONCE is manily useful for one-off observers of e.g. single-fire timers or threads.

Setting `signals` to 0 has the effect of canceling observation. If `PBSysObjectObserve_ADD` is set in `flags`, setting `signals` to 0 is an error (`PBSysErr_INVALID`).

This function may be called multiple times to modify what `signals` are observed.

- Required rights: `PBSysRight_OBSERVE`

### PBSysObjectSignal

```c
PBSysErr PBSysObjectSignal(PBSysHandle  handle,
                           PBSysSignals disableUserSignals,
                           PBSysSignals enableUserSignals,
                           PBSysSignals pulseUserSignals);
```

PBSysObjectSignal clear and/or sets user signals for `handle`.

First `disableUserSignals` are applied then `enableUserSignals`.

- Returns: `PBSysErr_INVALID` if any non-user (i.e. system) signals are included in the bitmasks.
- Required rights: none

## Stream

### PBSysStreamOpenPipePair

```c
PBSysErr PBSysStreamOpenPipePair(PBSysHandle* handlesOut,
                                 u32          bufferSize,
                                 u64          flags);
```

PBSysStreamOpenPipePair creates two connected duplex byte streams.

Writes to one handle become readable from the other handle and vice versa.

- Parameters:
  - `handlesOut`: Receives the two created stream handles on success.
  - `bufferSize`: Per-direction buffer capacity in bytes. 0 uses an implementation default.
  - `flags`: Must be 0.
- Required rights: none

### PBSysStreamRead

```c
i64 PBSysStreamRead(PBSysHandle     stream,
                    const PBSysBuf* bufs,
                    u32             bufCount,
                    u32             flags);
```

PBSysStreamRead reads bytes from a `stream` into one or more buffers.

- Parameters:
  - `flags`: Unused. Pass 0
- Required rights: `PBSysRight_READ`

### PBSysStreamStatsRead

```c
PBSysErr PBSysStreamStatsRead(PBSysHandle       stream,
                              PBSysStreamStats* stats,
                              u32               statsSize,
                              u64               flags);
```

PBSysStreamStatsRead retrieves statistics for a `stream`.

- Parameters:
  - `stats`: Storage location for results
  - `statsSize`: Capacity of `stats` in bytes
  - `flags`: Unused. Pass 0.
- Required rights: none

### PBSysStreamWrite

```c
i64 PBSysStreamWrite(PBSysHandle     stream,
                     const PBSysBuf* bufs,
                     u32             bufCount,
                     u32             flags);
```

PBSysStreamWrite writes bytes from one or more buffers to a `stream`.

- Parameters:
  - `flags`: Bits of `PBSysStreamWriteFlags`
- Required rights: `PBSysRight_WRITE`

## Textplan

### PBSysTextplanGetCaretBounds

```c
u64 PBSysTextplanGetCaretBounds(PBSysHandle textPlan,
                                u64         caretTextIndex);
```

- Required rights: none

### PBSysTextplanGetSelectionRects

```c
u64 PBSysTextplanGetSelectionRects(PBSysHandle                 textPlan,
                                   u64                         selectionStart,
                                   u64                         selectionEnd,
                                   PBSysTextplanSelectionRect* rects,
                                   u32                         rectsCap,
                                   u32                         rectSize);
```

PBSysTextplanGetSelectionRects retrieves line-wise selection rectangles relative to the text plan
origin.

- Parameters:
  - `textPlan`: the text plan object
  - `selectionStart`: one end of the selection range
  - `selectionEnd`: the other end of the selection range
  - `rects`: output buffer, or NULL to query the count only
  - `rectsCap`: number of entries available in `rects`
  - `rectSize`: size of one entry in `rects`, usually sizeof(`PBSysTextplanSelectionRect`)
- Returns: the total number of selection rectangles for the requested range
- Required rights: `PBSysRight_READ`

### PBSysTextplanGetSize

```c
u64 PBSysTextplanGetSize(PBSysHandle textPlan);
```

PBSysTextplanGetSize: Get the size of a text plan's layout.

`textPlan`: The text plan object.

Return value: The width and height of the plan. The macros PBTextplanWidthOfSize and PBTextplanHeightOfSize can be used to extract the two values from the return value of the function.
The returned width is the width of the widest line in the plan in pixels.
The returned height is the distance from the top of the first line to the bottom of the last line in pixels.

This function gives no information about where text glyphs may actually be drawn.
Glyphs can extend outside the boundaries of the line on which they are placed.

You must call `PBSysTextplanLayout` before calling this function.

- Required rights: `PBSysRight_READ`

### PBSysTextplanHitTest

```c
u64 PBSysTextplanHitTest(PBSysHandle textPlan,
                         i32         x,
                         i32         y);
```

- Required rights: none

### PBSysTextplanLayout

```c
i64 PBSysTextplanLayout(PBSysHandle           textPlan,
                        PBTextPlanLayoutFlags flags,
                        i32                   width,
                        i32                   height);
```

PBSysTextplanLayout lays a text document into a rectangular bounding box.

If the system detects that the new bounding box will not affect the existing layout in the text plan, this function will do nothing.

This function performs text shaping and then places the resulting glyphs into lines.
If a line were to go off the right side of the box, it will either be truncated with an ellipsis character or wrap to a new line, depending on whether `PBTextPlanLayout_ONE_LINE` is set.

Once this function has been called, you can use the other text plan functions.

- Parameters:
  - `textPlan`: The text plan to contain the resulting layout.
  - `flags`: Flags bitwise OR-ed together controlling the text layout operation.
  - `width`: The `width` of the rectangular bounding box in pixels. Set to 0 for infinite space (and thus preventing line wrapping or truncation).
  - `height`: The `height` of the rectangular bounding box in pixels. Set to 0 for infinite space.
- Required rights: `PBSysRight_WRITE`

### PBSysTextplanMoveSelection

```c
bool PBSysTextplanMoveSelection(PBSysHandle             textPlan,
                                u32                     mode,
                                PBSysTextplanSelection* selection,
                                u32                     selectionSize);
```

PBSysTextplanMoveSelection updates a `selection` using `selection`-adjustment flags without hit
testing a point.

- Parameters:
  - `textPlan`: the text plan object
  - `mode`: a bitwise OR of PBSysTextplanSelectionAdjustment_* flags
  - `selection`: in-out `selection` state containing anchor, caret, and lastDown
  - `selectionSize`: size of *selection, usually sizeof(`PBSysTextplanSelection`)
- Returns: true if the `selection` changed
- Required rights: `PBSysRight_READ`

### PBSysTextplanMoveSelectionToPoint

```c
bool PBSysTextplanMoveSelectionToPoint(PBSysHandle             textPlan,
                                       u32                     mode,
                                       i32                     x,
                                       i32                     y,
                                       PBSysTextplanSelection* selection,
                                       u32                     selectionSize);
```

PBSysTextplanMoveSelectionToPoint updates a `selection` by hit-testing a point and applying
`selection`-adjustment flags.

- Parameters:
  - `textPlan`: the text plan object
  - `mode`: a bitwise OR of PBSysTextplanSelectionAdjustment_* flags
  - `x`: point `x` in px relative to the text plan origin
  - `y`: point `y` in px relative to the text plan origin
  - `selection`: in-out `selection` state containing anchor, caret, and lastDown
  - `selectionSize`: size of *selection, usually sizeof(`PBSysTextplanSelection`)
- Returns: true if the `selection` changed
- Required rights: `PBSysRight_READ`

### PBSysTextplanMoveSelectionVertical

```c
bool PBSysTextplanMoveSelectionVertical(PBSysHandle             textPlan,
                                        i32                     preferredX,
                                        bool                    upwards,
                                        bool                    extend,
                                        PBSysTextplanSelection* selection,
                                        u32                     selectionSize);
```

PBSysTextplanMoveSelectionVertical moves a `selection` up or down by one visual line while
preserving a preferred x position.

- Parameters:
  - `textPlan`: the text plan object
  - `preferredX`: x in px relative to the text plan origin used to preserve column intent
  - `upwards`: true to move up one visual line, false to move down
  - `extend`: true to `extend` the current `selection` instead of collapsing to the moved caret
  - `selection`: in-out `selection` state containing anchor, caret, and lastDown
  - `selectionSize`: size of *selection, usually sizeof(`PBSysTextplanSelection`)
- Returns: true if the `selection` changed
- Required rights: `PBSysRight_READ`

## Texture

### PBSysTextureGetHeight

```c
u32 PBSysTextureGetHeight(PBSysHandle texture);
```

`PBSysTextureGetWidth` returns the height of a `texture`, in pixels.

- Required rights: `PBSysRight_READ`

### PBSysTextureGetWidth

```c
u32 PBSysTextureGetWidth(PBSysHandle texture);
```

PBSysTextureGetWidth returns the width of a `texture`, in pixels.

- Required rights: `PBSysRight_READ`

### PBSysTextureWrite

```c
PBSysErr PBSysTextureWrite(PBSysHandle texture,
                           u32         originXInPx,
                           u32         originYInPx,
                           const void* pixels,
                           u64         pixelSize,
                           u32         widthInPx,
                           u32         heightInPx);
```

PBSysTextureWrite uploads pixel data to a region of a `texture`.
Pixels must be in the format the `texture` was created with, row-major.

- Parameters:
  - `originXInPx`: x offset within the `texture`
  - `originYInPx`: y offset within the `texture`
  - `pixels`: pointer to pixel data
  - `pixelCount`: number of bytes at `pixels` (must be >= `widthInPx` * `heightInPx` * bytes per pixel)
  - `widthInPx`: width of the upload region
  - `heightInPx`: height of the upload region
- Required rights: `PBSysRight_WRITE`

## Thread

### PBSysThreadEnterMain

```c
void PBSysThreadEnterMain(u64 flags);
```

PBSysThreadEnterMain

- Parameters:
  - `flags`: are bits of PBSysThread_
- Required rights: none

### PBSysThreadExit

```c
PBSysErr PBSysThreadExit(PBSysHandle thread,
                         i32         status);
```

PBSysThreadExit stops a `thread` and sets its exit `status`.

- Required rights: `PBSysRight_MANAGE_THREAD`

### PBSysThreadExitProcess

```c
PBSysErr PBSysThreadExitProcess(PBSysHandle thread,
                                i32         status);
```

PBSysThreadExitProcess terminated the process.

- Required rights: `PBSysRight_MANAGE_PROCESS`

### PBSysThreadExitStatus

```c
i32 PBSysThreadExitStatus(PBSysHandle thread);
```

PBSysThreadExitStatus returns the exit status of `thread`.

- Returns: `PBSysErr` on error.
- Required rights: `PBSysRight_MANAGE_THREAD`

### PBSysThreadHostControllerConnect

```c
PBSysHandle PBSysThreadHostControllerConnect(PBSysHandle thread);
```

Note: Draft API; arguments will change

- Required rights: none

### PBSysThreadHostControllerRequest

```c
i64 PBSysThreadHostControllerRequest(PBSysHandle thread,
                                     const u8*   buf,
                                     u32         bufLen);
```

Note: Draft API; arguments will change

- Required rights: none

### PBSysThreadLogWrite

```c
PBSysErr PBSysThreadLogWrite(PBSysHandle     thread,
                             const PBSysBuf* bufs,
                             u32             bufCount,
                             u32             flags);
```

PBSysThreadLogWrite writes one log message to the runtime log sink for a `thread`.

- Required rights: none

### PBSysThreadNetConnect

```c
PBSysHandle PBSysThreadNetConnect(PBSysHandle thread,
                                  u32         ipAddr,
                                  u16         tcpPort);
```

Note: Draft API; arguments will change

- Required rights: `PBSysRight_NETWORK`

### PBSysThreadRead

```c
PBSysErr PBSysThreadRead(void*        data,
                         u32*         dataSizeInOut,
                         PBSysHandle* handles,
                         u32*         handlesCountInOut,
                         u64          flags);
```

PBSysThreadRead receives a message sent to the calling thread.

Messages may contain both byte `data` and handle payloads and may only be read in their entirety. Partial reads are not possible.

- Parameters:
  - `data`: is a buffer to place read `data` into
  - `dataSizeInOut`: in: capacity of `data`, out: bytes read
  - `handles`: to accept ownership of, transferred from sender thread
  - `handlesCountInOut`: in: capacity of `handles`, out: `handles` received
  - `flags`: are currently unused; pass 0.
- Required rights: none

### PBSysThreadReadRandom

```c
PBSysErr PBSysThreadReadRandom(PBSysHandle thread,
                               u8*         buf,
                               u32         bufLen);
```

PBSysThreadReadRandom gets high-quality random bytes.

- Parameters:
  - `buf`: The output buffer.
  - `bufLen`: Size in bytes of `buf`. Must be no more than 100 bytes.
- Required rights: none

### PBSysThreadStart

```c
PBSysHandle PBSysThreadStart(PBSysHandle              parentThread,
                             u64                      flags,
                             const PBSysThreadConfig* config,
                             u64                      configSize);
```

PBSysThreadStart starts a new thread.

- Required rights: `PBSysRight_MANAGE_THREAD`

### PBSysThreadWGpuOp

```c
i64 PBSysThreadWGpuOp(PBSysWgpuOp op,
                      const void* inPtr,
                      usize       inPtrSize,
                      void*       outPtr,
                      usize       outPtrSize);
```

PBSysThreadWGpuOp issues a WebGPU operation on the calling thread

- Required rights: none

### PBSysThreadWGpuOpAsync

```c
i64 PBSysThreadWGpuOpAsync(PBSysWgpuOp op,
                           const void* inPtr,
                           usize       inPtrSize,
                           void*       outPtr,
                           usize       outPtrSize);
```

PBSysThreadWGpuOpAsync issues a WebGPU operation on the calling thread that may need to suspend on
web runtimes.

- Required rights: none

### PBSysThreadWindowCreate

```c
PBSysHandle PBSysThreadWindowCreate(PBSysHandle              thread,
                                    const PBSysWindowConfig* config,
                                    usize                    configSize);
```

PBSysThreadWindowCreate creates a window associated with a `thread`.

- Required rights: `PBSysRight_WRITE`

### PBSysThreadWrite

```c
PBSysErr PBSysThreadWrite(PBSysHandle        thread,
                          const void*        data,
                          u32                dataSize,
                          const PBSysHandle* handles,
                          u32                handlesCount,
                          u64                flags);
```

PBSysThreadWrite sends a message to a `thread`. `data` is copied.

- Parameters:
  - `data`: to be written
  - `dataSize`: is the number of bytes at `data`
  - `handles`: to transfer ownership of to receiver `thread`
  - `handlesCount`: is the number of `handles` at `handles`
  - `flags`: are currently unused; pass 0.
- Required rights: `PBSysRight_WRITE`

## Window

### PBSysWindowClipboardReadText

```c
i64 PBSysWindowClipboardReadText(PBSysHandle window,
                                 u8*         buffer,
                                 u64         bufferSize);
```

`PBSysWindowClipboardWriteText` reads the text from the clipboard.

- Required rights: `PBSysRight_READ`

### PBSysWindowClipboardWriteText

```c
PBSysErr PBSysWindowClipboardWriteText(PBSysHandle window,
                                       const u8*   text,
                                       u64         textSize);
```

PBSysWindowClipboardWriteText sets the `text` on the clipboard.

- Required rights: `PBSysRight_WRITE`

### PBSysWindowCopyTitle

```c
i32 PBSysWindowCopyTitle(PBSysHandle window,
                         u8*         buf,
                         u32         bufCap,
                         u64         flags);
```

PBSysWindowCopyTitle retrieves the title of a `window`.

- Parameters:
  - `buf`: Destination to write UTF-8 bytes
  - `bufCap`: Capacity of `buf`, in bytes
- Required rights: `PBSysRight_READ`

### PBSysWindowCreateTexture

```c
PBSysHandle PBSysWindowCreateTexture(PBSysHandle             window,
                                     PBSysTextureFormat      format,
                                     u32                     widthInPx,
                                     u32                     heightInPx,
                                     PBSysTextureCreateFlags flags);
```

PBSysWindowCreateTexture creates an RGBA8 texture associated with a `window`.
The texture can be uploaded to via `PBSysTextureWrite` and set as the active texture
for shape draw calls via a TEXTURE_SET renderer instruction.

> **DEPRECATED** Use `PBSysCanvasCreateTexture` instead

- Parameters:
  - `format`: must be `PBSysTextureFormat_RGBA8`
  - `flags`: `PBSysTextureCreateFlags` (e.g. STREAMING for frequently updated textures)
- Required rights: none

### PBSysWindowCreateTextureFromData

```c
PBSysHandle PBSysWindowCreateTextureFromData(PBSysHandle             window,
                                             PBSysTextureFormat      format,
                                             const void*             data,
                                             u64                     dataSize,
                                             PBSysTextureCreateFlags flags);
```

PBSysWindowCreateTextureFromData decodes image `data` and creates a GPU texture in one step.
Supported formats: PNG, JPEG, WebP, GIF, BMP, TGA.
Pixels are always decoded to RGBA8. The `format` parameter must be `PBSysTextureFormat_RGBA8`.

> **DEPRECATED** Use `PBSysCanvasCreateTextureFromData` instead

- Parameters:
  - `data`: pointer to encoded image bytes (e.g. a PNG file loaded into memory)
  - `dataSize`: number of bytes at `data`
  - `flags`: `PBSysTextureCreateFlags`
- Required rights: none

### PBSysWindowFilePanelCreate

```c
PBSysHandle PBSysWindowFilePanelCreate(PBSysHandle window,
                                       bool        save);
```

PBSysWindowFilePanelCreate shows a file panel to the user.

- Parameters:
  - `save`: True for a `save`-file panel, false for an open-file panel.
- Required rights: `PBSysRight_WRITE`

### PBSysWindowFrameSyncEnable

```c
PBSysErr PBSysWindowFrameSyncEnable(PBSysHandle window,
                                    u64         flags);
```

PBSysWindowFrameSyncEnable controls the production of FRAME_SYNC pulses.

Programs must render their initial frame explicitly (with `PBSysCanvasRender`),
not in response to a FRAME_SYNC signal: a `window` is only revealed after its
first frame has been rendered, and the platform's frame-sync driver may not
deliver signals for a `window` that has not been revealed yet. After the first
frame, FRAME_SYNC signals pace subsequent frames.

- Parameters:
  - `flags`: should be 0 (disable) or 1 (enable).
- Required rights: `PBSysRight_WRITE`

### PBSysWindowFullScreenGet

```c
PBSysWindowFullScreenFlags PBSysWindowFullScreenGet(PBSysHandle window);
```

PBSysWindowFullScreenGet returns the current full-screen state of a `window`

- Required rights: `PBSysRight_READ`

### PBSysWindowFullScreenSet

```c
PBSysErr PBSysWindowFullScreenSet(PBSysHandle                window,
                                  PBSysWindowFullScreenFlags flags);
```

`PBSysWindowFullScreenGet` configures full-screen state of a `window`

- Required rights: `PBSysRight_WRITE`

### PBSysWindowInfoGet

```c
PBSysErr PBSysWindowInfoGet(PBSysHandle      window,
                            PBSysWindowInfo* info,
                            u64              infoSize);
```

PBSysWindowInfoGet retrieves latest `window` metrics and timing hints.

- Required rights: `PBSysRight_READ`

### PBSysWindowOpenSurfaceCanvas

```c
PBSysHandle PBSysWindowOpenSurfaceCanvas(PBSysHandle                       window,
                                         PBSysWindowOpenSurfaceCanvasFlags flags);
```

PBSysWindowOpenSurfaceCanvas returns a handle to the canvas for a `window`'s drawable surface.

The rights given to the returned canvas handle depends on the rights of the `window` handle; if the `window` handle only has READ rights, then the returned handle also only has READ rights.

- Parameters:
  - `flags`: Pass 0 to use the default Playbit canvas renderer. Pass `PBSysWindowOpenSurfaceCanvasFlag_WEBGPU` to use the canvas as a WebGPU surface source. These modes are exclusive.
- Required rights: `PBSysRight_READ`

### PBSysWindowSetCursor

```c
PBSysErr PBSysWindowSetCursor(PBSysHandle           window,
                              PBSysCursorStyle      style,
                              PBSysHandle           image,
                              PBSysCursorStyleFlags flags);
```

PBSysWindowSetCursor sets the appearance of the mouse cursor.

- Parameters:
  - `style`: determines how the cursor is presented.
  - `image`: should be the handle of an `image` if `style` is `PBSysCursorStyle_CUSTOM_IMAGE`, otherwise the `image` parameter is ignored and should be 0.
- Required rights: `PBSysRight_WRITE`

### PBSysWindowSetRect

```c
PBSysErr PBSysWindowSetRect(PBSysHandle             window,
                            f32                     x,
                            f32                     y,
                            f32                     width,
                            f32                     height,
                            PBSysWindowSetRectFlags flags);
```

PBSysWindowSetRect sets the position and size of a `window`. The actual size of the `window` may be larger if the size is smaller than the minimum possible `window` size, according to the host OS.

`x` & `y` sets the position on screen of the top-left corner of the `window`, with a top-left origin. `x` and `y` are ignored if `PBSysWindowSetRectFlag_CENTER` is set.

- Parameters:
  - `x`: dp
  - `y`: dp
  - `width`: dp
  - `height`: dp
- Required rights: `PBSysRight_WRITE`

### PBSysWindowSetRenderFlags

```c
PBSysErr PBSysWindowSetRenderFlags(PBSysHandle            window,
                                   PBSysWindowRenderFlags flags);
```

PBSysWindowSetRenderFlags controls behavior of `window` rendering.

- Required rights: `PBSysRight_WRITE`

### PBSysWindowSetStyle

```c
PBSysErr PBSysWindowSetStyle(PBSysHandle      window,
                             PBSysWindowStyle style,
                             u64              flags);
```

PBSysWindowSetStyle sets the `style` of a `window`.

- Required rights: `PBSysRight_WRITE`

### PBSysWindowSetTitle

```c
PBSysErr PBSysWindowSetTitle(PBSysHandle window,
                             const u8*   text,
                             u64         textLen);
```

PBSysWindowSetTitle sets the title of a `window`.

- Parameters:
  - `text`: UTF-8 bytes
  - `textLen`: Number of bytes at `text`
- Required rights: `PBSysRight_WRITE`

### PBSysWindowSizeLimitsSet

```c
PBSysErr PBSysWindowSizeLimitsSet(PBSysHandle window,
                                  f32         minWidth,
                                  f32         minHeight,
                                  f32         maxWidth,
                                  f32         maxHeight,
                                  u64         flags);
```

PBSysWindowSizeLimits sets lower and upper frame size limits.

Use negative numbers to keep values unchanged.

- Required rights: `PBSysRight_WRITE`

### PBSysWindowTextplanCreate

```c
PBSysHandle PBSysWindowTextplanCreate(PBSysHandle window,
                                      const u8*   text,
                                      u64         textSize,
                                      u32         fontFamily,
                                      u32         size,
                                      u32         weight,
                                      u32         color);
```

PBSysWindowTextplanCreate creates a `text` plan object associated with a `window`.

> **DEPRECATED** Use `PBSysWindowTextplanCreate2` instead

- Parameters:
  - `fontFamily`: 0 = sans, 1 = mono
  - `size`: fixed point; 1.0 = 64
  - `weight`: between 1 and 999
  - `color`: 0xRRGGBBAA
- Required rights: `PBSysRight_WRITE`

### PBSysWindowTextplanCreate2

```c
PBSysHandle PBSysWindowTextplanCreate2(PBSysHandle                         window,
                                       const u8*                           text,
                                       u64                                 textSize,
                                       const PBSysPositionedTextAttribute* attributes,
                                       u32                                 attributeSize,
                                       u32                                 attributesLen);
```

PBSysWindowTextplanCreate2 creates a `text` plan object associated with a `window`.
The styling `attributes` are specified as an array.

- Parameters:
  - `text`: encoded as UTF-8 data
  - `textSize`: size in bytes of `text`
  - `attributes`: `attributes`. Must not be NULL
  - `attributeSize`: size of one `PBSysPositionedTextAttribute`, for ABI compatibility
  - `attributesLen`: number of `attributes` at `attributes`. Must be at least 1.
- Required rights: `PBSysRight_WRITE`

### PBSysWindowWorkspaceOpenURL

```c
PBSysErr PBSysWindowWorkspaceOpenURL(PBSysHandle                           window,
                                     const u8*                             url,
                                     u64                                   urlSize,
                                     const PBWindowWorkspaceOpenURLConfig* config,
                                     u64                                   configSize);
```

PBSysWindowWorkspaceOpenURL opens a URL in user's workspace with the provided configuration settings.
By default, the default application will be launched or activated to open the URL.

- Required rights: `PBSysRight_READ`

# Playbit API reference

---
`#include <playbit/audio.h>`

### PBAudio

```c
typedef struct {
    PBSysHandle handle;
} PBAudio;
```

### PBAudioBuffer

```c
typedef struct {
    PBSysAudioBuffer id;
} PBAudioBuffer;
```

### PBAudioSound

```c
typedef struct {
    PBSysAudioSound id;
} PBAudioSound;
```

### PBAudioMain

```c
PBAudio PBAudioMain();
```

Call this to get the main audio handle.
Also calls `PBAudioInit` exactly _once_ if it has not yet been called.


### PBAudioInit

```c
bool PBAudioInit();
```

Inits the audio output backend for sound playback (globally).


### PBAudioSetVolume

```c
void PBAudioSetVolume(PBAudio audio,
                      f32     volume);
```

Sets the global `volume` of the sound mixer.

- `volume`: Normalized value in the range `[0.0-1.0]` (0-100%)

### PBAudioBufferCreate

```c
PBAudioBuffer PBAudioBufferCreate(PBAudio     audio,
                                  const void* data,
                                  usize       dataSize,
                                  u32         numChannels,
                                  u32         sampleRate,
                                  u32         totalSampleCount);
```

Creates an `audio` buffer from a interleaved 2-channel f32 buffer at 44100 hz.
At the present moment, that is the only format that is supported.
This function will be extended in the future to support more formats.


### PBAudioBufferCreateFromFile

```c
PBAudioBuffer PBAudioBufferCreateFromFile(PBAudio     audio,
                                          const void* data,
                                          usize       dataSize);
```


### PBAudioBufferDestroy

```c
PBSysErr PBAudioBufferDestroy(PBAudio       audio,
                              PBAudioBuffer buffer);
```


### PBAudioBufferPlay

```c
PBAudioSound PBAudioBufferPlay(PBAudio       audio,
                               PBAudioBuffer buffer);
```

Starts playing an instance of an `audio` `buffer` at 1x speed.


### PBAudioBufferPlayAfter

```c
PBAudioSound PBAudioBufferPlayAfter(PBAudio       audio,
                                    PBAudioBuffer buffer,
                                    PBAudioSound  playingSound);
```


### PBAudioBufferUpload

```c
PBSysErr PBAudioBufferUpload(PBAudio       audio,
                             PBAudioBuffer buffer,
                             const void*   data,
                             usize         dataSize,
                             u32           numChannels,
                             u32           sampleRate,
                             u32           totalSampleCount);
```

Replaces the sample `data` of an existing, no-longer-playing `audio` `buffer` in place, without
allocating a new `buffer`. Intended for a small fixed ring of buffers used to stream `audio`, where
each `buffer` is refilled and re-queued (via `PBAudioBufferPlayAfter`) only after
`PBAudioSoundIsPlaying` reports its previous sound has finished.

It is a caller error to upload into a `buffer` that a currently-playing (or not-yet-finished,
queued) sound still references.


### PBAudioSoundResume

```c
PBSysErr PBAudioSoundResume(PBAudio      audio,
                            PBAudioSound sound,
                            bool         loop);
```

Resumes a paused (or still-playing) `sound`.
If `loop` is true, playback restarts from the beginning when the end of the
`sound` is reached; otherwise playback stops at the end.
Fails if the `sound` has ended (its handle has expired) — start a new instance
with `PBAudioBufferPlay` in that case.


### PBAudioSoundPause

```c
PBSysErr PBAudioSoundPause(PBAudio      audio,
                           PBAudioSound sound);
```

Pauses a playing `sound`. Resume with `PBAudioSoundResume`.


### PBAudioSoundTell

```c
f32 PBAudioSoundTell(PBAudio      audio,
                     PBAudioSound sound);
```

Returns the current playback position, normalized to `[0.0-1.0]`.
1.0 means the `sound` ended (an expired `sound` handle also reads as 1.0).


### PBAudioSoundSeek

```c
void PBAudioSoundSeek(PBAudio      audio,
                      PBAudioSound sound,
                      f32          position);
```

Sets the playback `position`, normalized and clamped to `[0.0-1.0]`.
Seeking a `sound` that already ended is a no-op.


### PBAudioSoundGetPosition

```c
u64 PBAudioSoundGetPosition(PBAudio      audio,
                            PBAudioSound sound);
```

Returns the current playback position, in sample frames, of `sound` within its buffer. This
reflects what the mixer has actually consumed as of the last `audio` callback, i.e. what's truly
audible right now -- not merely queued or rendered ahead of time.

Returns 0 if `sound` is invalid or hasn't started playing yet.


### PBAudioSoundIsPlaying

```c
bool PBAudioSoundIsPlaying(PBAudio      audio,
                           PBAudioSound sound);
```

Returns true if `sound` is the one currently being mixed into the output right now, according
to the mixer itself -- not a locally-predicted end time. A `sound` that hasn't started yet
(waiting on a `PBAudioBufferPlayAfter` predecessor) or that has already finished playing both
report false.

Intended for driving gapless streaming playback: poll this instead of guessing when a queued
buffer will finish, and recycle/refill it (see `PBAudioBufferUpload`) once it reports false.

# Playbit API reference

- [`PBArray`](#playbit/array.h) provides dynamically-growable arrays (aka buffers)
- [`PBHashTable`](#playbit/hashtable.h) provides building blocks for dictionaries and sets
- `PBPool` and `PBSlotTable` maps data to dense indices

---
`#include <playbit/array.h>`

Define an array type with `PBArrayType(ElementType)` and operate on it via "method" macros.

Example use:

    typedef struct {
        int a, b;
    } Foo;
    typedef PBArrayType(Foo) FooArray;

Type generated by `PBArrayType(T)`:

    struct {
        T* nullable v;
        usize       len;
        usize       cap;
    }

Predefined array types:

- `PBI8Array` with element type `i8`
- `PBI16Array` with element type `i16`
- `PBI32Array` with element type `i32`
- `PBI64Array` with element type `i64`
- `PBU8Array` with element type `u8`
- `PBU16Array` with element type `u16`
- `PBU32Array` with element type `u32`
- `PBU64Array` with element type `u64`
- `PBF32Array` with element type `f32`
- `PBF64Array` with element type `f64`
- `PBPtrArray` with element type `void*`

### PBI8Array

```c
typedef PBArrayType(i8) PBI8Array;
```

### PBI16Array

```c
typedef PBArrayType(i16) PBI16Array;
```

### PBI32Array

```c
typedef PBArrayType(i32) PBI32Array;
```

### PBI64Array

```c
typedef PBArrayType(i64) PBI64Array;
```

### PBU8Array

```c
typedef PBArrayType(u8) PBU8Array;
```

### PBU16Array

```c
typedef PBArrayType(u16) PBU16Array;
```

### PBU32Array

```c
typedef PBArrayType(u32) PBU32Array;
```

### PBU64Array

```c
typedef PBArrayType(u64) PBU64Array;
```

### PBF32Array

```c
typedef PBArrayType(f32) PBF32Array;
```

### PBF64Array

```c
typedef PBArrayType(f64) PBF64Array;
```

### PBPtrArray

```c
typedef PBArrayType(void*) PBPtrArray;
```

### PBArrayStructStaticAssertLayout

```c
#define PBArrayStructStaticAssertLayout(STRUCT_TYPE)
```

PBArrayStructStaticAssertLayout is a helper for custom-defined array structs that need to
be ABI compatible with PBArray functions.
Example:
typedef struct {
const void* nullable ptr;
usize                len;
usize                cap;
} MyArray;
PBArrayStructStaticAssertLayout(MyArray);


### PBAnyArray

```c
typedef PBArrayType(void*) PBAnyArray;
```

PBAnyArray represents "an array of unknown/any type" The field name is intentionally different from other types to catch mistakes.

### PBAnyArrayResize

```c
bool PBAnyArrayResize(PBAnyArray* a,
                      usize       elemSize,
                      PBMem       ma,
                      usize       newCap,
                      u32         maFlags);
```

PBAnyArrayResize resizes capacity to hold at least `newCap` elements.

If `newCap` is smaller than current length, length is truncated.


### PBAnyArrayRemove

```c
void PBAnyArrayRemove(PBAnyArray* arg,
                      usize       elemSize,
                      usize       start,
                      usize       len);
```

PBAnyArrayRemove removes `len` elements starting at index `start`.


### PBAnyArrayAlloc

```c
void* PBAnyArrayAlloc(PBAnyArray* arg,
                      usize       elemSize,
                      PBMem       arg,
                      usize       len);
```

PBAnyArrayAlloc appends `len` uninitialized elements and returns pointer to the first one.

- Returns: NULL if capacity growth fails or if `len==0`.

### PBAnyArrayAllocAt

```c
void* PBAnyArrayAllocAt(PBAnyArray* arg,
                        usize       elemSize,
                        PBMem       arg,
                        usize       i,
                        usize       len);
```

PBAnyArrayAllocAt inserts `len` uninitialized elements at index `i`.

- Returns: NULL if capacity growth fails.

### PBAnyArrayReserve

```c
bool PBAnyArrayReserve(PBAnyArray* arg,
                       usize       elemSize,
                       PBMem       arg,
                       usize       nitems);
```

PBAnyArrayReserve ensures at least `nitems` spare capacity beyond current length.


### PBAnyArrayReserveExact

```c
bool PBAnyArrayReserveExact(PBAnyArray* arg,
                            usize       elemSize,
                            PBMem       arg,
                            usize       nitems);
```

PBAnyArrayReserveExact grows capacity to satisfy `nitems` spare slots without geometric extra growth.


### PBAnyArrayGrow

```c
bool PBAnyArrayGrow(PBAnyArray* a,
                    usize       elemSize,
                    PBMem       ma,
                    usize       minavail);
```

PBAnyArrayGrow grows by at least `minavail` additional slots.


### PBAnyArrayFree

```c
void PBAnyArrayFree(PBAnyArray* a,
                    usize       elemSize,
                    PBMem       ma);
```

PBAnyArrayFree releases backing storage for `a`.


### PBAnyArrayInsert

```c
bool PBAnyArrayInsert(PBAnyArray* arg,
                      usize       elemSize,
                      PBMem       ma,
                      usize       i,
                      const void* src,
                      usize       len);
```

PBAnyArrayInsert inserts `len` elements copied from `src` at index `i`.

- `elemSize`: size of one element. Must be `>0`.
- `ma`: memory allocator to use in case array needs to grow. Must be same allocator used for all memory operations on this array.
- `i`: Index at which to insert elements. `i=0` means "insert at beginning", `i=len` means insert at end. Value must be `<=len`.
- `src`: Pointer to elements to copy into the array
- `len`: Number of element at `src`. Must be `>0`.
- Returns: true on success, false on allocation failure.

### PBAnyArrayMove

```c
macro void PBAnyArrayMove(PBAnyArray* a, usize elemSize, usize dst, usize start, usize end)
```


### PBAnyArrayRot

```c
void PBAnyArrayRot(usize stride,
                   void* v,
                   usize first,
                   usize mid,
                   usize last);
```

PBAnyArrayRot rotates range [`first`,`last`) around pivot `mid` for elements of size `stride` bytes.


### PBAnyArrayRot32

```c
void PBAnyArrayRot32(const u32* v,
                     usize      first,
                     usize      mid,
                     usize      last);
```

PBAnyArrayRot32 rotates range [`first`,`last`) around `mid` for arrays of u32 elements.


### PBAnyArrayRot64

```c
void PBAnyArrayRot64(const u64* v,
                     usize      first,
                     usize      mid,
                     usize      last);
```

PBAnyArrayRot64 rotates range [`first`,`last`) around `mid` for arrays of u64 elements.


### PBAnyArray_INIT_WITH_STORAGE

```c
macro void PBAnyArray_INIT_WITH_STORAGE(T* structPtr, NAME arrayField, NAME storageField)
```

PBAnyArray_INIT_WITH_STORAGE allows initializing struct-member arrays with external storage. This is particularly useful when the common case is know up front and space can be allocated ahead of time. When the array needs to grow, the array implementation will check for storage pointing to directly before itself to determine if it owns that memory or not.

Initial storage must be located directly before the array struct. The array implementation relies on this to avoid free'ing your storage as the array grows.

Example:

    struct MyThing {
        int x;
    };
    struct MyThings {
        MyThing              thingsStorage[4];
        PBArrayType(MyThing) things;
    };
    void example(void) {
        MyThings m = { 0 };
        PBAnyArray_INIT_WITH_STORAGE(&m, things, thingsStorage);
    }


### PBArrayInit

```c
macro void PBArrayInit(ArrayType* array)
```

Initializes `array` to zero in preparation for use.


### PBArrayFrom

```c
macro ArrayType PBArrayFrom(ArrayType, PBMem ma, T* src, usize len)
```

- Returns: an instance of `ArrayType` pre-populated with `len` items pointed to by `src`.

### PBArrayFree

```c
macro void PBArrayFree(ArrayType* array, PBMem ma)
```

Frees the backing memory associated with the `array` instance pointed to by `array`.


### PBArrayClear

```c
macro void PBArrayClear(ArrayType* array)
```

Resets length of the `array` pointed to by `array` to zero.


### PBArrayAt

```c
macro T PBArrayAt(ArrayType* array, usize at)
```

- Returns: a copy of the item stored in `array` `at` index `at`.

### PBArrayRefAt

```c
macro T* PBArrayRefAt(ArrayType* array, usize at)
```

- Returns: a pointer to the item stored in `array` `at` index `at`.

### PBArrayPush

```c
macro bool PBArrayPush(ArrayType* array, PBMem ma, T item)
```

Pushes `item` onto the end of the `array` pointed to by `array`.

- Returns: `false` if capacity growth fails.

### PBArrayPop

```c
macro T PBArrayPop(ArrayType* array)
```

Removes the last item in the `array`.

- Returns: the last item in the `array`.

### PBArrayAlloc

```c
macro T* PBArrayAlloc(ArrayType* array, PBMem ma, usize len)
```

Appends `len` uninitialized elements to the `array` pointed to by `array`.

- Returns: NULL if capacity growth fails, otherwise a pointer to first new item.

### PBArrayAllocAt

```c
macro T* PBArrayAllocAt(ArrayType* array, PBMem ma, usize at, usize len)
```

Inserts `len` uninitialized elements into the `array` pointed to by `array` `at` index `at`.

- Returns: NULL if capacity growth fails, otherwise a pointer to first new item.

### PBArrayResize

```c
macro bool PBArrayResize(ArrayType* array, PBMem ma, usize newCap, u32 maFlags)
```

Resizes capacity to hold at least `newCap` elements. If `newCap` is smaller than current length, length is truncated.

- Returns: `false` if capacity growth fails.

### PBArrayReserve

```c
macro bool PBArrayReserve(ArrayType* array, PBMem ma, usize nItems)
```

Ensures at least `nItems` spare capacity beyond current length.

- Returns: `false` if capacity growth fails.

### PBArrayReserveExact

```c
macro bool PBArrayReserveExact(ArrayType* array, PBMem ma, usize nItems)
```

Grows capacity to satisfy `nItems` spare slots without geometric extra growth.

- Returns: `false` if capacity growth fails.

### PBArrayShrinkwrap

```c
macro bool PBArrayShrinkwrap(ArrayType* array, PBMem ma)
```

Resizes memory so that cap=len. Note that cap>len might still be true depending on the memory allocator's implementation.

- Returns: `false` on failure.

### PBArrayAppend

```c
macro bool PBArrayAppend(ArrayType* array, PBMem ma, T* src, usize srcLen)
```

Pushes `srcLen` items from `src` to the end of the `array` pointed to by `array`.

- Returns: `false` on failure.

### PBArrayInsert

```c
macro bool PBArrayInsert(ArrayType* array, PBMem ma, usize at, T* src, usize srcLen)
```

Inserts `srcLen` items from `src` into the `array` pointed to by `array` starting `at` index `at`.

- Returns: `false` on failure.

### PBArrayRemove

```c
macro void PBArrayRemove(ArrayType* array, usize start, usize len)
```

Removes `len` items from the `array` pointed to by `array` starting at index `start`.


### PBArrayMove

```c
macro void PBArrayMove(ArrayType* array, usize dstPos, usize start, usize end)
```

Moves the items within the `array` pointed at by `array` between [`start`, `end`) to the new index `dstPos`.


### PBArrayEq

```c
macro bool PBArrayEq(ArrayType* array, T* ptr, usize ptrLen)
```

- Returns: true if `ptrLen` equals `array`'s length and all the bytes in the array equal those pointed to by `ptr`.

### PBArrayCmp

```c
macro int PBArrayCmp(ArrayType* array, T* ptr, usize ptrLen)
```

- Returns: <0 if the contents of `array` is bytewise less than the contents of `ptr`, >1 if `ptr` < `array`, 0 if `array` == `ptr`.

### PBArrayFromSlice

```c
macro ArrayType PBArrayFromSlice(ArrayType, PBMem ma, SliceType slice)
```

- Returns: a new array of type `ArrayType` with a copy of the items in `slice`.

### PBArraySlice

```c
macro SliceType PBArraySlice(SliceType, ArrayType* array, usize start, usize rangeLen)
```

- Returns: a new slice of type `SliceType` referencing the items in `array` starting at index `start` and with `rangeLen` length.

---
`#include <playbit/buf.h>`

### PBBuf

```c
typedef PBArrayType(u8) PBBuf;
```

PBBuf is a growable byte buffer, binary compatible with PBU8Array

### PBBufAppendCStr

```c
bool PBBufAppendCStr(PBBuf*      buf,
                     PBMem       ma,
                     const char* cstr);
```

PBBufAppendCStr appends `cstr` to end of `buf`

- Returns: false if buffer could no grow to accommodate `cstr`

### PBBufSlice

```c
macro PBU8Slice PBBufSlice(PBBuf buf[, usize start[, usize len]])
```

Returns a slice of a buffer.


### PBBufFromStrSlice

```c
PBBuf PBBufFromStrSlice(PBMem      ma,
                        PBStrSlice source);
```

PBBufFromStrSlice copies `source` to a newly allocated buffer


### PBBufCStr

```c
char* PBBufCStr(PBBuf* buf,
                PBMem  ma);
```

PBBufCStr inserts a trailing \0, but does not increment len. Thus, the \0 byte will be overwritten by future modifications.

- Returns: a pointer to `buf`->v, or NULL if memory could not be allocated.

### PBBufAppendHex

```c
bool PBBufAppendHex(PBBuf*    buf,
                    PBMem     ma,
                    const u8* bytes,
                    usize     len);
```

PBBufAppendHex appends hexadecimal encoding of `bytes` to `buf`. `buf->len` will be extended by `len * 2`.

- Returns: true on success, false if memory could not be allocated

### PBBufOf

```c
PBBuf PBBufOf(PBMem       ma,
              const void* value,
              ...);
```

PBBufOf allocates a copy of `value` using memory allocator `ma`.
It's implemented as a generic macro, with the following effective signature:
`PBBuf` PBBufOf<T is `PBStrSlice`|`PBStr`|`PBBuf`|const char*>(T v[, usize start, [usize len]])
The caller should check for OOM, e.g.
if (buf.len == 0 && from.len > 0)
panic("OOM");


### PBBufEq

```c
#define PBBufEq …
```

PBBufEq is implemented as a generic macro, with the following effective signature:
bool PBBufEq<A is convertible to `PBStrSlice`, B is convertible to `PBStrSlice`>(A a, B b)

- Returns: true if a is equal to b.

### PBBuf_INIT_WITH_STORAGE

```c
#define PBBuf_INIT_WITH_STORAGE …
```

void PBBuf_INIT_WITH_STORAGE(T* structPtr, NAME bufField, NAME storageField)

PBBuf_INIT_WITH_STORAGE allows initializing struct-member buffer with external storage. This is particularly useful when the common case is know up front and space can be allocated ahead of time. When the buffer needs to grow, the buffer implementation will check for storage pointing to directly before itself to determine if it owns that memory or not.

Initial storage `storageField` must be located directly before the `PBBuf` `bufField` in your struct. The buffer implementation relies on this to avoid free'ing your storage as the buffer grows.

Example:

    struct MyFormatter {
        u8    bufStorage[64];
        PBBuf buf;
    };
    void example(void) {
        MyFormatter formatter = { 0 };
        PBAnyArray_INIT_WITH_STORAGE(&formatter, buf, bufStorage);
    }

---
`#include <playbit/ringbuf.h>`

### PBRingBuf

```c
typedef struct PBRingBuf {
    u8* nullable v;
    usize        cap;
    usize        off;
    usize        len;
} PBRingBuf;
```

### PBRingBufEnsureWriteCapacity

```c
bool PBRingBufEnsureWriteCapacity(PBRingBuf* rb,
                                  PBMem      ma,
                                  usize      minLen,
                                  usize      align);
```


### PBRingBufWriteReserve

```c
u8* PBRingBufWriteReserve(PBRingBuf* rb,
                          PBMem      ma,
                          usize      minLen,
                          usize      align);
```

PBRingBufWriteReserve returns contiguous space for at least `minLen` bytes at the logical tail.
The caller must follow with `PBRingBufProduce` after writing bytes into the returned storage.
The returned pointer is aligned to `align`, which must be 0, 1, or a power of two.

- Returns: NULL on allocation failure.

### PBRingBufProduce

```c
void PBRingBufProduce(PBRingBuf* rb,
                      usize      n);
```

PBRingBufProduce makes `n` newly written bytes visible at the tail.
The caller must have previously reserved enough space with `PBRingBufWriteReserve`.


### PBRingBufConsume

```c
usize PBRingBufConsume(PBRingBuf* rb,
                       usize      n);
```

PBRingBufConsume removes up to `n` bytes from the logical head.

- Returns: Number of bytes consumed.

---
`#include <playbit/hashtable.h>`

Fundamental hash table

### PBHashTableEqFn

```c
typedef bool (*PBHashTableEqFn)(const void * _Nonnull, const void * _Nonnull);
```

### PBHashTableHashFn

```c
typedef usize (*PBHashTableHashFn)(usize, const void * _Nonnull);
```

### PBHashTable

```c
typedef struct PBHashTable {
    PBMem ma;
    usize seed; // hash seed passed to hashfn
    usize cap;  // capacity
    usize load; // current number of entries stored in the table
    void* entries;
} PBHashTable;
```

### PBHashTableInit

```c
bool PBHashTableInit(PBHashTable* arg,
                     int          ma,
                     usize        entsize,
                     usize        capHint);
```

PBHashTableInit initializes ht with capacity hint `capHint`.

- Returns: false on allocation failure.

### PBHashTableFree

```c
void PBHashTableFree(PBHashTable* ht);
```

PBHashTableFree releases all memory owned by `ht`.


### PBHashTableClear

```c
void PBHashTableClear(PBHashTable* ht,
                      usize        entsize);
```

PBHashTableClear removes all entries from the hashtable


### PBHashTableAssign

```c
void* PBHashTableAssign(PBHashTable*      ht,
                        usize             entsize,
                        PBHashTableHashFn hashfn,
                        PBHashTableEqFn   eqfn,
                        const void*       keyEntry,
                        bool*             added);
```

PBHashTableAssign returns a pointer to the entry, or NULL if out of memory. If an entry equivalent to keyent is found, `*added` is set to false. Otherwise a new entry is inserted and keyent is copied to it, `*added` is true.


### PBHashTableLookup

```c
void* PBHashTableLookup(const PBHashTable* ht,
                        usize              entsize,
                        PBHashTableHashFn  hashfn,
                        PBHashTableEqFn    eqfn,
                        const void*        keyEntry);
```

PBHashTableLookup returns a pointer to an entry equivalent to keyent, or NULL if not found.


### PBHashTableDelete

```c
bool PBHashTableDelete(PBHashTable*      ht,
                       usize             entsize,
                       PBHashTableHashFn hashfn,
                       PBHashTableEqFn   eqfn,
                       const void*       keyent);
```

PBHashTableDelete removes an entry equivalent to `keyent`.

Optimization detail: if `keyent` is a pointer to an entry in `ht`, for example from `PBHashTableLookup`, no additional lookup is performed internally.

- Returns: false if not found.

### PBHashTableIter

```c
#define PBHashTableIter(ht, entryp)
```

PBHashTableIter iterates over entries of a hash table (in undefined order.)
To begin iteration, set *entryp=NULL.
Example:
for (const MyEntry* entry = NULL; PBHashTableIter(&`ht`, &entry);) {
print(">> %u", entry->value);
bool PBHashTableIter(const `PBHashTable`* `ht`, T** `entryp`)


### PBHashTableIterx

```c
bool PBHashTableIterx(const PBHashTable* ht,
                      usize              entsize,
                      const void*        entryp);
```

PBHashTableIterx advances iteration of `ht` in unspecified order.

Set *entryp = NULL before first call. Returns false when iteration is complete.

---
`#include <playbit/pool.h>`

PBPool maps data to dense indices. It's like a slab allocator that uses u32 integers as addresses. Think "file descriptor allocator" rather than "virtual-memory allocator." Tries to be cache friendly by using the smallest free index during allocation.

Note: PBSlotTable (slot_table.h) may be a more fitting container if you need stable addresses (pointers) for entries. Pointers to entries of a PBPool are only valid until the next modification of the pool.

### PBPool

```c
typedef struct PBPool {
    u32 cap;      // capacity, a multiple of 64
    u32 maxidx;   // max allocated index
    u64 freebm[]; // bitmap; bit=1 means entries[bit] is free
    // TYPE entries[];
} PBPool;
```

### PBPoolCreate

```c
bool PBPoolCreate(PBPool* pp,
                  usize   elemSize,
                  PBMem   ma,
                  u32     cap);
```

PBPoolCreate creates a new pool. `*pp` is assumed to be NULL.

- Returns: false if memory could not be allocated.

### PBPoolFree

```c
void PBPoolFree(PBPool* p,
                int     ma);
```

PBPoolFree recycles the memory of `p` back to memory allocator `ma`.


### PBPoolEntryAlloc

```c
void* PBPoolEntryAlloc(PBPool* pp,
                       usize   elemSize,
                       int     ma,
                       u32*    idxOut);
```

PBPoolEntryAlloc allocates an entry with the lowest index in the pool `*pp`. If the pool is full, the pool's memory at `*pp` is resized (and likely moved). The returned pointer (address) is valid until the next modification of the pool. Use `PBPoolEntryFree` to recycle an allocated entry.

- Returns: NULL if memory allocation failed.

### PBPoolEntryAllocIfRoom

```c
void* PBPoolEntryAllocIfRoom(PBPool* p,
                             usize   elemSize,
                             int     ma,
                             u32*    idxOut);
```

PBPoolEntryAllocIfRoom allocates an entry with the lowest index in the pool `*pp`. The returned pointer (address) is valid until the next modification of the pool. Use `PBPoolEntryFree` to recycle an allocated entry.

- Returns: NULL if the pool is full (does not grow pool memory like `PBPoolEntryAlloc`.)

### PBPoolEntryFree

```c
void PBPoolEntryFree(PBPool* p,
                     u32     idx);
```

PBPoolEntryFree frees the entry at `idx`. Panics if `idx` is out of bounds or points to an already free entry.


### PBPoolEntryFreeAll

```c
void PBPoolEntryFreeAll(PBPool* p);
```

PBPoolEntryFreeAll frees all entries of the pool in one very cheap operation.


### PBPoolEntryIsFree

```c
bool PBPoolEntryIsFree(const PBPool* p,
                       u32           idx);
```

PBPoolEntryIsFree returns true when `idx` currently refers to a free slot.

- Returns: false for `idx==0` or `idx` beyond current capacity.

### PBPoolEntries

```c
u8* PBPoolEntries(const PBPool* p);
```

PBPoolEntries returns a pointer to the array of entries. You can index directly into this with: `MyEntry* entry = &((MyEntry*)PBPoolEntries(p))[idx-1]` The returned array is valid until the next modification of the pool.


### PBPoolEntry

```c
void* PBPoolEntry(const PBPool* p,
                  usize         elemSize,
                  u32           idx);
```

PBPoolEntry accesses entry with index `idx`.
Panics if `idx` is out of bounds.

- Returns: pointer to entry `idx`. The returned pointer (address) is valid until the next modification of the pool.

### PBPoolFindEntry

```c
u32 PBPoolFindEntry(const PBPool* p,
                    usize         elemSize,
                    const void*   entryPtr);
```

PBPoolFindEntry performs a reverse lookup, finding the idx for an entry with identical bytes of memory as the memory at `entryPtr`. Basically a linear scan with memcmp.

- Returns: 0 when no matching entry exists.

### PBPoolIdxIsDead

```c
bool PBPoolIdxIsDead(const PBPool* p,
                     u32           idx);
```

PBPoolIdxIsDead reports whether `idx` has never been allocated in the current lifetime of `p`

---
`#include <playbit/slot_table.h>`

PBSlotTable maps data to dense indices.
It's like a slab allocator that uses u32 integers as addresses.
Think "file descriptor allocator" rather than "virtual-memory allocator."

Tries to be cache friendly by using the smallest free index during allocation.

PBSlotTable is an evolution of PBPool with the main difference being stable pointers, i.e. a pointer returned by PBSlotTableGet remains valid for the lifetime of the table, even when the table grows. PBPool does not have the same guarantee.

### PBSlotTableCreate

```c
#define PBSlotTableCreate(T, ma, cap)
```

PBSlotTableCreate creates a new table with initial capacity for `cap` entries of `elemSize` size.

Note that the table is implemented as a list of blocks of entries, each holding `cap` entries. This means that `cap` should be a reasonably large number. `cap` will be rounded up to the nearest multiple of 64.

`PBSlotTable`* nullable PBSlotTableCreate(type `T`, `PBMem` `ma`, u32 `cap`)

- Returns: NULL if memory could not be allocated.

### PBSlotTableFree

```c
void PBSlotTableFree(PBSlotTable* table,
                     PBMem        ma);
```

PBSlotTableFree frees `table` back to memory allocator `ma`


### PBSlotTableAdd

```c
#define PBSlotTableAdd(T, table, ma, idxOut)
```

PBSlotTableAdd allocates an entry with the lowest index in the `table`.

On success, the returned memory region is zeroed and guaranteed to remain valid until either the entry is freed by a call to `PBSlotTableDel`, the `table` is cleared with `PBSlotTableClear` or the `table` is freed. I.e. even when the `table` grows, to accommodate more entires, the address of existing entries remain valid. This is a really useful invariant when you want to hold on to pointers.

`T` PBSlotTableAdd(type `T`, `PBSlotTable`* `table`, `PBMem` `ma`, u32* `idxOut`)

- Returns: NULL if memory allocation failed.

### PBSlotTableDel

```c
void PBSlotTableDel(PBSlotTable* table,
                    u32          idx);
```

PBSlotTableDel frees the entry at `idx`.


### PBSlotTableGet

```c
#define PBSlotTableGet(T, table, idx)
```

PBSlotTableGet accesses entry with index `idx`.

`T`* PBSlotTableGet(type `T`, `PBSlotTable`* `table`, u32 `idx`)


### PBSlotTableIsUsed

```c
bool PBSlotTableIsUsed(PBSlotTable* table,
                       u32          idx);
```

PBSlotTableIsUsed returns true if entry at `idx` is in use (i.e. is not free.)
Note: Returns true if `idx` is out of bounds (rather than panicing.)


### PBSlotTableClear

```c
void PBSlotTableClear(PBSlotTable* table);
```

PBSlotTableClear frees all entries in one efficient operation.


### PBSlotTableBlock

```c
struct PBSlotTableBlock {
    PBSlotTableBlock* nullable next;
    u8                         entries[];
};
```

### PBSlotTable

```c
struct PBSlotTable {
    u32              cap;      // capacity of entire table
    u32              blockCap; // capacity of one block
    u32              maxidx;   // max allocated index
    u64*             freebm;   // bitmap; bit=1 means entries[bit] is free
    PBSlotTableBlock block;
};
```

### PBSlotTableCreate1

```c
PBSlotTable* PBSlotTableCreate1(usize elemSize,
                                PBMem ma,
                                u32   cap);
```

PBSlotTableCreate1 is the size-based worker behind PBSlotTableCreate.


### PBSlotTableAdd1

```c
void* PBSlotTableAdd1(PBSlotTable* table,
                      usize        elemSize,
                      PBMem        ma,
                      u32*         idxOut);
```

PBSlotTableAdd1 is the size-based worker behind PBSlotTableAdd.


### PBSlotTableGet1

```c
void* PBSlotTableGet1(PBSlotTable* table,
                      usize        elemSize,
                      u32          idx);
```

PBSlotTableGet1 is the size-based worker behind PBSlotTableGet.

---
`#include <playbit/queue.h>`

A ring buffer, aka circular buffer aka FIFO.
Note: PBQueue is not thread safe; single producer, single consumer only.

### PBQueueAny

```c
typedef PBQueue(void) PBQueueAny;
```

### PBQueueAnyInit

```c
PBSysErr PBQueueAnyInit(PBQueueAny* q,
                        u32         entrySize,
                        PBMem       ma,
                        u32         cap);
```

PBQueueAnyInit initializes `q` with usable capacity `cap` entries of size `entrySize`.


### PBQueueAnyFree

```c
void PBQueueAnyFree(PBQueueAny* q,
                    PBMem       ma);
```

PBQueueAnyFree releases storage owned by `q`.


### PBQueueAnyLen

```c
u32 PBQueueAnyLen(const PBQueueAny* q);
```

PBQueueAnyLen returns number of queued entries currently available to pop/remove.


### PBQueueAnyPushIfRoom

```c
void* PBQueueAnyPushIfRoom(PBQueueAny* q,
                           u32         entrySize);
```

PBQueueAnyPushIfRoom reserves one entry slot at tail without growing `q`.

- Returns: NULL if queue is full.

### PBQueueAnyPush

```c
void* PBQueueAnyPush(PBQueueAny* q,
                     u32         entrySize,
                     PBMem       ma);
```

PBQueueAnyPush reserves one entry slot at tail, growing `q` when necessary.

- Returns: NULL on allocation failure.

### PBQueueAnyPop

```c
void* PBQueueAnyPop(PBQueueAny* q,
                    u32         entrySize);
```

PBQueueAnyPop removes one entry from head and returns pointer to its storage.

- Returns: NULL if queue is empty.

### PBQueueAnyPopMany

```c
u32 PBQueueAnyPopMany(PBQueueAny* q,
                      u32         entrySize,
                      void*       dst,
                      u32         dstCap);
```

PBQueueAnyPopMany pops up to `dstCap` entries from head into `dst`.

- Returns: Number of entries copied and removed.

### PBQueueAnyRemove

```c
u32 PBQueueAnyRemove(PBQueueAny* q,
                     u32         limit);
```

PBQueueAnyRemove removes up to `limit` newest entries from tail.

- Returns: Number of entries removed.

### PBQueueIter

```c
typedef struct PBQueueIter {
    u32 i;         // current index
    u32 remaining; // entries left
} PBQueueIter;
```

### PBQueueAnyIterCreate

```c
PBQueueIter PBQueueAnyIterCreate(const PBQueueAny* q,
                                 u32               entrySize);
```

PBQueueAnyIterCreate snapshots iteration state for `q` at this instant.

Later pushes or pops do not update this iterator; iteration walks the queued entries visible when the iterator was created.


### PBQueueAnyIterNext

```c
void* PBQueueAnyIterNext(const PBQueueAny* q,
                         PBQueueIter*      it,
                         u32               entrySize);
```

---
`#include <playbit/vector.h>`

Multi-dimensional vector types with SIMD acceleration.

These types are special N dimensional vector types which directly maps to target-CPU-agnostic SIMD types. They enables efficient SIMD operations and is usable in general-purpose code.

Vector types may not be available for all compilation targets: `PB_HAS_VECTOR_TYPES` is set to `1` if vector types are supported, `0` if not.

These types allow element access via:
- the array subscript operator `[index]`
- `sN` where `N` is a hexadecimal value
- `x`, `y`, `z`, `w` for graphics-style indexing

```c
StaticExpect(PB_HAS_VECTOR_TYPES, "vector type support");
PBF32x4 v = {1.1, 2.2, 3.3, 4.4};
expect(v.x == 1.1f); expect(v[0] == 1.1f);
expect(v.y == 2.2f); expect(v[1] == 2.2f);
expect(v.z == 3.3f); expect(v[2] == 3.3f);
expect(v.w == 4.4f); expect(v[3] == 4.4f);
```

Note that all these types have at least 16 byte alignment. Use `alignof(T or expr)` to access actual alignment.

### PBU16x4

```c
typedef u16 __attribute__((ext_vector_type(4))) PBU16x4;
```

### PBF32x2

```c
typedef f32 __attribute__((ext_vector_type(2))) PBF32x2;
```

### PBF32x3

```c
typedef f32 __attribute__((ext_vector_type(3))) PBF32x3;
```

### PBF32x4

```c
typedef f32 __attribute__((ext_vector_type(4))) PBF32x4;
```

### PBF32x6

```c
typedef f32 __attribute__((ext_vector_type(6))) PBF32x6;
```

### PBF32x8

```c
typedef f32 __attribute__((ext_vector_type(8))) PBF32x8;
```

### PBF32x16

```c
typedef f32 __attribute__((ext_vector_type(16))) PBF32x16;
```

### PBF32x32

```c
typedef f32 __attribute__((ext_vector_type(32))) PBF32x32;
```

### PBF32x64

```c
typedef f32 __attribute__((ext_vector_type(64))) PBF32x64;
```

### PBF16x2

```c
typedef f16 __attribute__((ext_vector_type(2))) PBF16x2;
```

### PBF16x3

```c
typedef f16 __attribute__((ext_vector_type(3))) PBF16x3;
```

### PBF16x4

```c
typedef f16 __attribute__((ext_vector_type(4))) PBF16x4;
```

### PBF16x6

```c
typedef f16 __attribute__((ext_vector_type(6))) PBF16x6;
```

### PBF16x8

```c
typedef f16 __attribute__((ext_vector_type(8))) PBF16x8;
```

### PBF16x16

```c
typedef f16 __attribute__((ext_vector_type(16))) PBF16x16;
```

### PBF16x32

```c
typedef f16 __attribute__((ext_vector_type(32))) PBF16x32;
```

### PBF16x64

```c
typedef f16 __attribute__((ext_vector_type(64))) PBF16x64;
```

### PBF16x128

```c
typedef f16 __attribute__((ext_vector_type(128))) PBF16x128;
```

# Playbit API reference

Foundational types and functions.

The `playbit/base.h` header defines the following primitive types and limit constants:

```c
i8      = int8_t       u8      = uint8_t
i16     = int16_t      u16     = uint16_t      f16     = _Float16
i32     = int32_t      u32     = uint32_t      f32     = float
i64     = int64_t      i64     = int64_t       f64     = double
isize   = long         usize   = size_t
intptr  = intptr_t     uintptr = uintptr_t

I8_MIN                 I8_MAX                  U8_MAX
I16_MIN                I16_MAX                 U16_MAX
I32_MIN                I32_MAX                 U32_MAX
I64_MIN                I64_MAX                 U64_MAX
ISIZE_MIN              ISIZE_MAX               USIZE_MAX
```

`playbit/base.h` includes `playbit/sys/compiler.h` from the [runtime API](../../runtime/api.md), which provides the following:

- `PB_API_BEGIN` sets `extern "C"` if needed and configures nullability diagnostics
- `PB_API_END` restores state altered by `PB_API_BEGIN`
- `PB_ATTR_ALIGNED(N)` is `__attribute__((__aligned__(N)))` when supported
- [`PB_ENUM_TYPE(T)`](/runtime/api.html#pb_enum_type) is `:T` when supported

---
`#include <playbit/base.h>`

### PB_SHORT_NAMES

```c
#define PB_SHORT_NAMES 1|0
```

PB_SHORT_NAMES is 1 if alternate short names should be defined for canoncial names. For example `print` as an alias for `PBPrintf`

To disable short names, set `CFLAGS=-DPB_SHORT_NAMES=0` when compiling or `#define PB_SHORT_NAMES 0` before including any playbit headers.


### PB_HAS_VECTOR_TYPES

```c
#define PB_HAS_VECTOR_TYPES 1|0
```

PB_HAS_VECTOR_TYPES is 1 if target-agnostic SIMD vector types are available (vector.h)


### PB_UNREACHABLE

```c
macro PB_UNREACHABLE()
```

tells the compiler that code at and beyond this point can't be reached. If this is violated, the process is crashed (with stack trace in DEBUG builds.)


### PB_MUSTTAIL

```c
#define PB_MUSTTAIL attribute
```

    Note on `!defined(__wasm__)`: clang 13 claims to have this attribute for wasm targets but it's actually not implemented and causes an error.


### PB_NORETURN

```c
#define PB_NORETURN …
```

PB_NORETURN is an attribute that tells the compiler that a function never returns.

- The compiler is free to perform optimizations which would cause UB if the function would actually return
- Affects static analysis

Note: `_Noreturn` is deprecated in C23, replaced by `[[noreturn]]`


### PB_UNUSED

```c
#define PB_UNUSED attribute
```

PB_UNUSED is an attribute that tells the compiler that the function or local is intentionally unused


### PB_LIKELY

```c
macro PB_LIKELY(integralexpr)->bool
```


### PB_UNLIKELY

```c
macro PB_UNLIKELY(integralexpr)->bool
```


### PB_CPU_CACHE_LINE_SIZE

```c
#define PB_CPU_CACHE_LINE_SIZE u32
```

PB_CPU_CACHE_LINE_SIZE defines the CPU L1 cache line size


### PB_LIBC

```c
#define PB_LIBC …
```

PB_LIBC is 1 if compiling with libc, 0 if not


### PB_NO_GUI

```c
#define PB_NO_GUI 1|0
```

PB_NO_GUI is 1 if GUI is disabled


### PB_SMT

```c
#define PB_SMT 1|0
```

PB_SMT is 1 if compiling with multi-threading support, 0 if not


### PB_FMT_ATTR

```c
macro PB_FMT_ATTR(archetype, string-index, first-to-check)
```

`archetype` determines how the format string is interpreted, and should be printf, scanf, strftime or strfmon. string-`index` specifies which argument is the format string argument (starting from 1), while first-to-`check` is the number of the first argument to `check` against the format string. For functions where the arguments are not available to be checked (such as vprintf), specify the third parameter as zero.


### PB_PLUS_ONE

```c
#define PB_PLUS_ONE(...)
```

PB_PLUS_ONE can be used to define count of enums, e.g. `enum { FOO_COUNT = (0lu FOR_EACH_FOO(PB_PLUS_ONE)) };`


### PB_VARG_DISPATCH

```c
#define PB_VARG_DISPATCH(a, ...)
```

PB_VARG_DISPATCH allows writing functions with compile-time variable-count arguments


### PB_VARG_COUNT

```c
#define PB_VARG_COUNT(...)
```

PB_VARG_COUNT counts macro variable arguments


### PB_CONCAT

```c
#define PB_CONCAT(a, b)
```

PB_CONCAT concatenates preprocessor values


### PB_LOCAL_UNIQUE_ID

```c
#define PB_LOCAL_UNIQUE_ID …
```

PB_LOCAL_UNIQUE_ID is a portable version of `__COUNTER__`


### PB_UNIQUE_NAME

```c
macro NAME PB_UNIQUE_NAME(NAME)
```

yields a name unique to the entire translation unit, useful for `__cleanup__`


### PB_TMPID

```c
macro NAME PB_TMPID(NAME)
```

yields a local name unique to the current line, useful in `({ ... })` macros


### PB_UNAVAILABLE

```c
macro void PB_UNAVAILABLE(const char* message)
```

marks a symbol as unavailable under the current build configuration


### PB_GUEST

```c
#define PB_GUEST 1|0
```

PB_GUEST is 1 if playbit-c is full-featured, or 0 for "core" version


### PB_GUEST_ONLY

```c
#define PB_GUEST_ONLY …
```

PB_GUEST_ONLY limits a function, type or data to availability in guests only, i.e. unavailable in the "core" version of playbit-c


### PB_GUESTFN

```c
#define PB_GUESTFN …
```

PB_GUESTFN decorates functions which are only avilable in full-featured "guest" versions of playbit-c


### PBMustCheck_UNLIKELY

```c
bool PBMustCheck_UNLIKELY(bool unlikely);
```

PBMustCheck_UNLIKELY wraps PB_UNLIKELY with `warn_unused_result` so ignored overflow and bounds checks become compiler warnings.


### PBBitsCountLeadingZeroes

```c
macro int PBBitsCountLeadingZeroes(ANYINT x)
```

counts leading zeroes in `x`, starting at the most significant bit position. Result is undefined if `x` is 0.


### PBBitsFindFirstSet

```c
macro int PBBitsFindFirstSet(ANYINT x)
```

returns one plus the index of the least significant 1-bit of `x`, or if `x` is zero, returns zero.


### PBBitsFindLastSet

```c
macro u32 PBBitsFindLastSet(ANYINT n)
```

finds the last set bit. e.g.

```
PBBitsFindLastSet(0b1111111111111111) = 16
PBBitsFindLastSet(0b1000000000000000) = 16
PBBitsFindLastSet(0b1000000000000000) = 16
PBBitsFindLastSet(0b1000) = 4
```


### PBBitWidth

```c
macro u32 PBBitWidth(ANYINT x)
```

returns the number of bits needed to represent `x`. i.e., the position of the most significant set bit plus one.


### PBILog2

```c
macro int PBILog2(ANYINT x)
```

calculates the log of base 2, rounding down. e.g.

```
PBILog2(15) = 3
PBILog2(16) = 4
```

Result is undefined if `x` is 0.


### PBIsPow2

```c
macro bool PBIsPow2(T x)
```

returns true if `x` is a power-of-two value


### PBAlign2

```c
macro T PBAlign2<T>(T n, T a)
```

rounds up n to closest boundary a (a must be a power of two) If n is 0, the result is 0.


### PB_ALIGN2

```c
macro T PB_ALIGN2<T>(T n, T a)
```

Constant-expression version of PBAlign2


### PBIsAlign2

```c
macro bool PBIsAlign2(T x, anyuint a)
```

returns true if `x` is aligned to `a`


### PBPow2Floor

```c
macro ANYINT PBPow2Floor(ANYINT x)
```

rounds down `x` to nearest power of two. Returns 1 if `x` is 0.


### PB_POW2_FLOOR

```c
macro ANYINT PB_POW2_FLOOR(ANYINT x)
```

Constant-expression implementation of PBPow2Floor. When used as a constant expression, compilation fails if `x` is 0.

- `x`: evaluated multiple times

### PBPow2Ceil

```c
macro ANYINT PBPow2Ceil(ANYINT x)
```

rounds up `x` to nearest power of two.

- Returns: 1 when `x` is 0. 0 when `x` is larger than the max pow2 for `x`'s type (e.g. >0x80000000 for u32)

### PB_POW2_CEIL

```c
macro ANYINT PB_POW2_CEIL(ANYINT x)
```

Constant-expression implementation of PBPow2Ceil.

- `x`: evaluated multiple times

### PBIDivCeil

```c
macro T PBIDivCeil(T x, ANYINT divisor)
```

divides `x` by `divisor`, rounding up. If `x` is zero, returns max value of `x` (wraps.)


### PB_IDIV_CEIL

```c
macro T PB_IDIV_CEIL(T x, ANYINT divisor)
```

Constant-expression implementation of PBIDivCeil.

- `divisor`: evaluated multiple times

### PBRangesOverlap

```c
macro bool PBRangesOverlap(ANYNUM aStart, ANYNUM aEnd, ANYNUM bStart, ANYNUM bEnd)
```

PBRangesOverlap returns true if two ranges overlap


### PBPanic

```c
macro void PBPanic(const char* format, ...)
```

prints a message to stderr and aborts the process, including a stack trace when available.


### PBPanicv

```c
macro void PBPanicv(const char* format, va_args args)
```

prints a message to stderr and aborts the process, including a stack trace when available.


### PBPanicOnErr

```c
macro T PBPanicOnErr(T exprWithSysErrResult)
```


### PB_DEBUG

```c
#define PB_DEBUG 1|0
```

PB_DEBUG is 1 in debug builds, else 0


### PBIsType

```c
macro bool PBIsType(ANY value, TYPE type)
```

Returns true at compile time if the `type` of `value` is assignable to a local of `type`


### PBIsSameType

```c
macro bool PBIsSameType(TYPE a, TYPE b)
```

Returns true at compile time if `a` value of type `a` is assignable to `a` local of type `b`


### PBTypeIsConst

```c
macro bool PBTypeIsConst(TYPE type)
```

Returns true at compile time if `type` has a `const` qualifier


### PBExpect

```c
macro void PBExpect(ANY truthyValue)
```

Calls PBPanic if `truthyValue` is false


### PBExpectf

```c
macro void PBExpectf(ANY truthyValue, const char* message, ...)
```

Calls PBPanic if `truthyValue` is false alond with a custom `message`


### PBExpectNull

```c
macro void PBExpectNull(ANY e)
```

Calls PBPanic if `e != NULL`


### PBExpectNotNull

```c
macro T PBExpectNotNull<T>(T e)
```

Calls PBPanic if `e == NULL`, otherwise `e` is returned


### PBExpectInMemRegion

```c
macro void PBExpectInMemRegion(const void* validRegion, usize validRegionSize, const void* subject, usize subjectSize)
```

asserts that the memory region `[subject, subject+subjectSize)` is fully contained in
`[validRegion, validRegion+validRegionSize)`. Calls PBPanic if not.


### PBExpectInBounds

```c
macro void PBExpectInBounds(T index, T startIndex, T endIndex)
```

Calls PBPanic if `index` is outside the range `[startIndex .. endIndex)`


### PBStaticExpectIsType

```c
macro void PBStaticExpectIsType(EXPR value, TYPE type)
```

Issues compilation error if the `type` of `value` is not assignable as `type`


### PBExpectationFailure

```c
macro void PBExpectationFailure(const char* message, ...)
```

Calls PBPanic with `"Expect assertion failed: "` plus `message`


### PBOpt

```c
macro type PBOpt(T)
```

returns a struct type `struct { PBSysErr err; T ok; }` used for optional results of type `T`


### PBOptOk

```c
macro T PBOptOk(PBOpt(T) opt)
```

panics if opt.err != 0, returns opt.ok.


### PBSysCallOpStr

```c
const char* PBSysCallOpStr(PBSysCallOp arg);
```

PBSysCallOpStr returns a symbolic string.
I.e. PBSysCallOpStr(`PBSysCallOp_HandleClose`) => "HandleClose"


### PBSysErrStr

```c
const char* PBSysErrStr(PBSysErr arg);
```

PBSysErrStr returns a symbolic string


### PBSysObjectTypeStr

```c
const char* PBSysObjectTypeStr(PBSysObjectType arg);
```

PBSysObjectTypeStr returns a symbolic string


### PBSysEventTypeStr

```c
const char* PBSysEventTypeStr(PBSysEventType arg);
```

PBSysEventTypeStr returns a symbolic string


### PBSysFileListEntryTypeStr

```c
const char* PBSysFileListEntryTypeStr(PBSysFileListEntryType arg);
```

PBSysFileListEntryTypeStr returns a symbolic string


### PBSysEventStr

```c
u32 PBSysEventStr(const PBSysEvent* event,
                  char*             buf,
                  u32               bufCap);
```

PBSysEventStr writes a string representation of a `PBSysEvent` to `buf`.

- Returns: the number of bytes that would be written to `buf`, excluding NUL terminator, as if `bufCap` was inifinite.

### PBSysRightsStr

```c
u32 PBSysRightsStr(PBSysRights rights,
                   char*       buf,
                   u32         bufCap);
```

PBSysRightsStr writes a short string representation of all bits in `rights` to `buf`.

- Returns: the number of bytes that would be written to `buf`, excluding NUL terminator, as if `bufCap` was inifinite.

### PBSysErrOfErrno

```c
PBSysErr PBSysErrOfErrno(int errno_val);
```

PBSysErrOfErrno returns a `PBSysErr` value for a libc errno value.

- Returns: `PBSysErr_UNKNOWN` if using playbit-c library without libc support (PB_LIBC=0)

### PBStr

```c
typedef struct PBStr {
    u8* nullable v;
    usize        len;
} PBStr;
```

PBStr represents a fixed-size "owned" array of bytes interpreted as UTF-8 text

### PBStrSlice

```c
typedef struct PBStrSlice {
    const u8* nullable v;
    usize              len;
} PBStrSlice;
```

PBStrSlice is a view into an array of bytes interpreted as UTF-8 text

### PBU8Slice

```c
typedef struct PBU8Slice {
    const u8* nullable v;
    usize              len;
} PBU8Slice;
```

PBU8Slice is a view into an array of bytes

### PBPoint

```c
typedef struct PBPoint {
    f32 x, y;
} PBPoint;
```

PBPoint defines a two-dimensional location

### PBSize

```c
typedef struct PBSize {
    f32 width, height;
} PBSize;
```

PBSize defines a two-dimensional size

### PBRect

```c
typedef struct PBRect {
    PBPoint origin;
    PBSize  size;
} PBRect;
```

PBRect defines a two-dimensional rectangle

### PBPointOf

```c
macro PBPoint PBPointOf(f32 x, f32 y)
```

Constructs a `PBPoint`


### PBSizeOf

```c
macro PBSize PBSizeOf(f32 width, f32 height)
```

Constructs a `PBSize`


### PBRectOf

```c
macro PBRect PBRectOf(f32 x, f32 y, f32 width, f32 height)
```

Constructs a `PBRect`


### PBMinF32

```c
f32 PBMinF32(f32 a,
             f32 b);
```

PBMinF32 returns the smaller of `a` and `b` as f32.
On targets with wasm min/max builtins they preserve IEEE min/max semantics for NaN handling.


### PBMaxF32

```c
f32 PBMaxF32(f32 a,
             f32 b);
```

PBMaxF32 returns the larger of `a` and `b` as f32.
On targets with wasm min/max builtins they preserve IEEE min/max semantics for NaN handling.


### PBMinF64

```c
f64 PBMinF64(f64 a,
             f64 b);
```

PBMinF64 returns the smaller of `a` and `b` as f64.
On targets with wasm min/max builtins they preserve IEEE min/max semantics for NaN handling.


### PBMaxF64

```c
f64 PBMaxF64(f64 a,
             f64 b);
```

PBMaxF64 returns the larger of `a` and `b` as f64.
On targets with wasm min/max builtins they preserve IEEE min/max semantics for NaN handling.


### PBMin

```c
macro T PBMin(T a, T b) returns the smaller value of the arguments
```


### PBMax

```c
macro T PBMax(T a, T b) returns the larger value of the arguments
```


### PBCheckOverflowAdd

```c
macro PBCheckOverflowAdd(T a, T b, T* dst) -> bool didOverflow
```


### PBExpectNoOverflowAdd

```c
#define PBExpectNoOverflowAdd(a, b, dst)
```

void PBExpectNoOverflow…(T `a`, T `b`, T* `dst`)
TODO: consider using __builtin_add_overflow_p et al. instead

---
`#include <playbit/console.h>`

### PBConsole

```c
PBStream PBConsole();
```

PBConsole returns the console stream.
If there's no console capability, `stream.handle` is `PBSysHandle_INVALID`


### PBConsoleWrite

```c
i64 PBConsoleWrite(const u8* bytes,
                   usize     bytesLen);
```

PBConsoleWrite writes `bytes` verbatim to the console. The write is blocking and is implemented as `PBStreamWritev(PBConsole(), bytes, PBSysStreamWrite_SYNC)`

- Returns: Number of `bytes` written or `PBSysErr` as negative value

---
`#include <playbit/log.h>`

### PBLog

```c
void PBLog(const char* format, ...);
```

PBLog writes a log message (stderr on platforms with stdio)


### PBLogv

```c
void PBLogv(const char* format,
            va_list     arg);
```

PBLogv writes a log message like `PBLog`, using a va_list.


### PBLogWrite

```c
PBSysErr PBLogWrite(PBSysBuf* bufv,
                    u32       bufc);
```

PBLogWrite writes a log message

---
`#include <playbit/handle.h>`

### PBHandleList

```c
i32 PBHandleList(PBSysHandleInfo* handles,
                 u32              handlesCap);
```

PBHandleList returns information about `handles` held by the calling thread. Writes up to `handlesCap` entries to `handles`.

- Returns: the total number of `handles`, which might be more than `handlesCap`.

### PBHandleFindByName

```c
i32 PBHandleFindByName(PBSysHandleInfo* handles,
                       u32              handlesCap,
                       PBSysHandleName  name);
```

PBHandleFindByName returns information about `handles` whose `name` matches `name`.
Writes up to `handlesCap` entries to `handles`.

- Returns: the total number of `handles`, which might be more than `handlesCap`.

### PBHandleGetInfo

```c
PBSysErr PBHandleGetInfo(PBSysHandle      handle,
                         PBSysHandleInfo* info);
```

PBHandleGetInfo retrieves `info` about `handle`


### PBHandleGetRights

```c
PBSysRights PBHandleGetRights(PBSysHandle handle);
```

PBHandleGetRights returns the rights given to `handle`

---
`#include <playbit/signal.h>`

### PBObserve

```c
void PBObserve(PBSysHandle  handle,
               PBSysSignals signals);
```

PBObserve sets what `signals` are to be observed for the object referred to by `handle`.


### PBObserveOnce

```c
void PBObserveOnce(PBSysHandle  handle,
                   PBSysSignals signals);
```

PBObserveOnce sets what `signals` are to be observed for the object referred to by `handle`, configured to produce a SIGNAL even just once (edge triggered.)


### PBSignal

```c
void PBSignal(PBSysHandle  handle,
              PBSysSignals disableUserSignals,
              PBSysSignals enableUserSignals,
              PBSysSignals pulseUserSignals);
```

PBSignal manages user signals for the object referred to by `handle`. Signal masks must only contain user bits (PBSysSignal_USER_*). This function panics if
- `handle` is invalid, or
- `handle` does not have `PBSysRight_SIGNAL` rights, or
- any signal mask contains non-user signals (`PBSysSignal_SYSTEM_ALL`)

---
`#include <playbit/printf.h>`

### PBSnprintf

```c
u32 PBSnprintf(char*       buf,
               u32         bufCap,
               const char* fmt,
               ...);
```

PBSnprintf formats strings using printf-style formatting.

- Returns: the number of bytes that would be written to `buf`, excluding NUL terminator, as if `bufCap` was inifinite.

### PBVsnprintf

```c
u32 PBVsnprintf(char*       buf,
                u32         bufCap,
                const char* fmt,
                va_list     args);
```

PBVsnprintf works like `PBSnprintf` but takes a va_list as input.


### PBFprintf

```c
void PBFprintf(PBStream    arg,
               const char* fmt,
               ...);
```

PBFprintf and `PBVfprintf` writes a formatted string to a stream


### PBVfprintf

```c
void PBVfprintf(PBStream    arg,
                const char* fmt,
                va_list     args);
```

PBVfprintf writes formatted output to a stream using va_list `args`.


### PBPrintf

```c
void PBPrintf(const char* fmt, ...);
```

PBPrintf writes formatted output to `PBConsole`.


### PBVprintf

```c
void PBVprintf(const char* fmt,
               va_list     arg);
```

PBVprintf writes formatted output to `PBConsole` using va_list.


### PBPrint

```c
void PBPrint(const char* cstr);
```

PBPrint writes a null-terminated string to `PBConsole`


### PBPrintfln

```c
macro void PBPrintfln(const char* fmt, ...)
```

writes formatted output to `PBConsole`() with a trailing linebreak.
Prefer to use the short name alias `print`.

---
`#include <playbit/random.h>`

### PBRand

```c
u64 PBRand();
```

PBRand returns the next pseudo-random number


### PBRandSeed

```c
void PBRandSeed(u64 seed);
```

PBRandSeed sets the deterministic `seed` used by `PBRand`.

---
`#include <playbit/stream.h>`

Streams are byte-oriented duplex or simplex pipes. Reads and writes may be partial.

Streams activate the following singals:

- `PBSysStreamSignal_READABLE` when there's at least one byte available to read
- `PBSysStreamSignal_WRITABLE` when there's room to write at least one byte
- `PBSysStreamSignal_PEER_CLOSED` when the other end of the stream closed reading & writing
- `PBSysStreamSignal_PEER_WRITE_DISABLED` when the other end of the stream closed writing
- `PBSysStreamSignal_WRITE_DISABLED` when the local end of the stream closed writing

See `#include <playbit/sys/syscalls/stream.h>` for complete list

### PBStream

```c
typedef struct {
    PBSysHandle handle;
} PBStream;
```

### PBStreamOpenPipePair

```c
PBSysErr PBStreamOpenPipePair(PBStream* pairOut,
                              u32       bufferSize,
                              u64       flags);
```

PBStreamOpenPipePair creates two connected duplex streams.

Writes to one stream become readable from the other stream and vice versa.

- `pairOut`: Receives the two created streams on success.
- `bufferSize`: Per-direction buffer capacity in bytes. 0 uses an implementation default.
- `flags`: Must be 0.
- Returns: 0 on success or a `PBSysErr` on failure.

### PBStreamRead

```c
i64 PBStreamRead(PBStream stream,
                 void*    dst,
                 usize    nbyte);
```

PBStreamRead reads up to `nbyte` bytes into `dst`.

- Returns: Number of bytes read or negative `PBSysErr`.

### PBStreamReadv

```c
i64 PBStreamReadv(PBStream        stream,
                  const PBSysBuf* bufs,
                  u32             bufCount,
                  u32             flags);
```

PBStreamReadv performs vectored read into `bufs`.

- Returns: Number of bytes read or negative `PBSysErr`.

### PBStreamWrite

```c
i64 PBStreamWrite(PBStream    stream,
                  const void* src,
                  usize       nbyte);
```

PBStreamWrite writes `nbyte` bytes from `src`.

- Returns: Number of bytes written or negative `PBSysErr`.

### PBStreamWritev

```c
i64 PBStreamWritev(PBStream        stream,
                   const PBSysBuf* bufs,
                   u32             bufCount,
                   u32             flags);
```

PBStreamWritev performs vectored write from `bufs`.

- Returns: Number of bytes written or negative `PBSysErr`.

### PBStreamClose

```c
PBSysErr PBStreamClose(PBStream stream);
```

PBStreamClose closes `stream` handle.

---
`#include <playbit/binsearch.h>`

### PBBinSearchLessFn

```c
typedef bool (*PBBinSearchLessFn)(const void * _Nonnull, const void * _Nonnull);
```

### PBBinSearchLowerBound

```c
usize PBBinSearchLowerBound(const void*       element,
                            const void*       array,
                            usize             stride,
                            usize             begin,
                            usize             end,
                            PBBinSearchLessFn lessFn);
```

PBBinSearchLowerBound finds the lower bound of some `element` in a sorted `array`.

I.e. the leftmost position we could insert `element` into the `array` while keeping it sorted.
Alternatively phrased: this is the number of elements strictly less than `element` in the `array`.
Note: inline so that generated code can avoid indirect calls to `lessFn`, inlining it.

---
`#include <playbit/math.h>`

### PBAbs

```c
macro T PBAbs(T x)
```

Returns sign-normalized (positive) value of `x`


### PBRound

```c
macro T PBRound(T x)
```

Round `x` to nearest whole number.


### PBFloor

```c
macro T PBFloor(T x)
```

PBFloor rounds `x` toward negative infinity.


### PBCeil

```c
macro T PBCeil(T x)
```

PBCeil rounds `x` toward positive infinity.


### PBClamp

```c
macro T PBClamp(T value, T min, T max)
```

PBClamp clamps v to the inclusive range `[min,max]`.


### PBMod

```c
macro f32 PBMod(f32 x, f32 y)
```

PBMod returns floating-point remainder of `x / y`.


### PBLerp

```c
macro f32 PBLerp(f32 a, f32 b, f32 t)
```

PBLerp linearly interpolates from `a` to `b` by parameter `t`.


### PBUnlerp

```c
macro f32 PBUnlerp(f32 a, f32 b, f32 v)
```

PBUnlerp computes interpolation parameter t for value `v` in range `[a,b]`.


### PBRemap

```c
macro f32 PBRemap(f32 inMin, f32 inMax, f32 outMin, f32 outMax, f32 v)
```

PBRemap maps `v` from input range `[inMin,inMax]` to output range `[outMin,outMax]`.


### PBSin

```c
macro T PBSin(T x)
```

PBSin computes sine of `x` (radians).


### PBCos

```c
macro T PBCos(T x)
```

PBCos computes cosine of `x` (radians).


### PBPow

```c
macro T PBPow(T x, T y)
```

PBPow computes `x` raised to the power `y` (`x^y`).


### PBSqrt

```c
macro T PBSqrt(T x)
```

PBSqrt computes square root of `x`.


### PBSign

```c
macro T PBSign(T x)
```

PBSign returns -1, 0 or +1 depending on `x`.


### PBAbsF32

```c
f32 PBAbsF32(f32 x);
```

PBAbsF32 returns the absolute value of `x`


### PBRoundF32

```c
f32 PBRoundF32(f32 x);
```

PBRoundF32 rounds `x` to nearest integer value (as f32).


### PBFloorF32

```c
f32 PBFloorF32(f32 x);
```

PBFloorF32 rounds `x` toward negative infinity.


### PBCeilF32

```c
f32 PBCeilF32(f32 x);
```

PBCeilF32 rounds `x` toward positive infinity.


### PBClampF32

```c
f32 PBClampF32(f32 v,
               f32 minValue,
               f32 maxValue);
```

PBClampF32 clamps `v` to the inclusive range `[minValue,maxValue]`.


### PBSignF32

```c
f32 PBSignF32(f32 x);
```

PBSignF32 returns -1, 0 or +1 depending on `x`.


### PBModF32

```c
f32 PBModF32(f32 x,
             f32 y);
```

PBModF32 returns floating-point remainder of `x / y`.


### PBLerpF32

```c
f32 PBLerpF32(f32 a,
              f32 b,
              f32 t);
```

PBLerpF32 linearly interpolates from `a` to `b` by parameter `t`.


### PBUnlerpF32

```c
f32 PBUnlerpF32(f32 a,
                f32 b,
                f32 v);
```

PBUnlerpF32 computes interpolation parameter t for value `v` in range `[a,b]`.


### PBRemapF32

```c
f32 PBRemapF32(f32 inMin,
               f32 inMax,
               f32 outMin,
               f32 outMax,
               f32 v);
```

PBRemapF32 maps `v` from input range `[inMin,inMax]` to output range `[outMin,outMax]`.


### PBSinF32

```c
f32 PBSinF32(f32 x);
```

PBSinF32 computes sine of `x` (radians).


### PBCosF32

```c
f32 PBCosF32(f32 x);
```

PBCosF32 computes cosine of `x` (radians).


### PBF32IsZero

```c
bool PBF32IsZero(f32 x);
```

PBF32IsZero returns true when |`x`| is smaller than PB_F32_EPSILON.


### PBPowF32

```c
f32 PBPowF32(f32 x,
             f32 y);
```

PBPowF32 computes `x` raised to the power `y` (`x^y`)


### PBSqrtF32

```c
f32 PBSqrtF32(f32 x);
```

PBSqrtF32 computes square root of `x`.


### PBVector2

```c
union PBVector2 {
    struct {
        f32 x, y;
    };
    f32 e[2];
};
```

### PBVector4

```c
union PBVector4 {
    struct {
        f32 x, y, z, w;
    };
    f32 e[4];
};
```

### PBRectangle

```c
union PBRectangle {
    struct {
        PBVector2 p0, p1;
    };
    struct {
        f32 x0, y0, x1, y1;
    };
    f32 e[4];
};
```

### PBVector2Make

```c
PBVector2 PBVector2Make(f32 x,
                        f32 y);
```

PBVector2Make constructs a 2D vector.


### PBVector2IsZero

```c
bool PBVector2IsZero(PBVector2 v);
```

PBVector2IsZero reports whether both vector components are near-zero.


### PBVector2Add

```c
PBVector2 PBVector2Add(PBVector2 a,
                       PBVector2 b);
```

PBVector2Add adds two PBVector2s.


### PBVector2Sub

```c
PBVector2 PBVector2Sub(PBVector2 a,
                       PBVector2 b);
```

PBVector2Sub subtracts two `PBVector2` types (`a` - `b`).


### PBVector2Mul

```c
PBVector2 PBVector2Mul(PBVector2 a,
                       PBVector2 b);
```

PBVector2Mul multiplies two `PBVector2` types (`a` * `b`).


### PBVector2Div

```c
PBVector2 PBVector2Div(PBVector2 a,
                       PBVector2 b);
```

PBVector2Div divides one `PBVector2` by another (`a` / `b`).


### PBVector2AddF

```c
PBVector2 PBVector2AddF(PBVector2 a,
                        f32       b);
```

PBVector2AddF adds `a` `PBVector2` by `a` scalar value (`a`.x + `b`, `a`.y + `b`).


### PBVector2SubF

```c
PBVector2 PBVector2SubF(PBVector2 a,
                        f32       b);
```

PBVector2SubF subtracts `a` `PBVector2` by `a` scalar value (`a`.x - `b`, `a`.y - `b`).


### PBVector2MulF

```c
PBVector2 PBVector2MulF(PBVector2 a,
                        f32       b);
```

PBVector2MulF multiplies `a` `PBVector2` by `a` scalar value (`a`.x * `b`, `a`.y * `b`).


### PBVector2DivF

```c
PBVector2 PBVector2DivF(PBVector2 a,
                        f32       b);
```

`PBVector2MulF` divides `a` `PBVector2` by `a` scalar value (`a`.x / `b`, `a`.y / `b`).


### PBVector2Dot

```c
f32 PBVector2Dot(PBVector2 a,
                 PBVector2 b);
```

PBVector2Dot returns the dot product of two vectors.


### PBVector2Length

```c
f32 PBVector2Length(PBVector2 a);
```

PBVector2Length returns the length of the vector (e.g. sqrt(`a` * `a`)).


### PBVector2Normalize

```c
PBVector2 PBVector2Normalize(PBVector2 a);
```

PBVector2Normalize returns the normalized vector (guards against divide by 0).


### PBVector2Lerp

```c
PBVector2 PBVector2Lerp(PBVector2 a,
                        PBVector2 b,
                        f32       t);
```

PBVector2Lerp linearly interpolates from `a` to `b` by parameter `t`.


### PBVector4Make

```c
PBVector4 PBVector4Make(f32 x,
                        f32 y,
                        f32 z,
                        f32 w);
```

PBVector4Make constructs a 4D vector.


### PBVector4IsZero

```c
bool PBVector4IsZero(PBVector4 v);
```

PBVector4IsZero reports whether all vector components are near-zero.


### PBVector4MulF

```c
PBVector4 PBVector4MulF(PBVector4 v,
                        f32       f);
```

PBVector4MulF multiplies all components of `v` by scalar `f`.


### PBRectangleMake

```c
PBRectangle PBRectangleMake(f32 x0,
                            f32 y0,
                            f32 x1,
                            f32 y1);
```

PBRectangleMake constructs rectangle from two corners.


### PBRectangleFromV2

```c
PBRectangle PBRectangleFromV2(PBVector2 p0,
                              PBVector2 p1);
```

`PBRectangleMake` constructs rectangle from two corner points.


### PBRectangleOfRect

```c
PBRectangle PBRectangleOfRect(PBRect rect);
```

PBRectangleOfRect converts a `PBRect` to a `PBRectangle`


### PBRectangleOfSize

```c
PBRectangle PBRectangleOfSize(PBSize size);
```

PBRectangleOfSize converts a `PBSize` to a `PBRectangle` positioned at 0,0


### PBRectangleEquals

```c
bool PBRectangleEquals(PBRectangle a,
                       PBRectangle b);
```

PBRectangleEquals returns true if two rectangles are equal.


### PBRectangleIsZero

```c
bool PBRectangleIsZero(PBRectangle a);
```

PBRectangleIsZero returns true if the rectangle is nearly zero.


### PBRectangleSize

```c
PBVector2 PBRectangleSize(PBRectangle r);
```

PBRectangleSize returns width/height vector of rectangle `r`.


### PBRectangleWidth

```c
f32 PBRectangleWidth(PBRectangle r);
```

PBRectangleWidth returns horizontal extent of `r`.


### PBRectangleHeight

```c
f32 PBRectangleHeight(PBRectangle r);
```

PBRectangleHeight returns vertical extent of `r`.


### PBRectangleScale

```c
PBRectangle PBRectangleScale(PBRectangle r,
                             f32         sx,
                             f32         sy);
```

PBRectangleScale scales rectangle coordinates by (`sx`,`sy`).


### PBRectangleCutRight

```c
PBRectangle PBRectangleCutRight(PBRectangle r,
                                f32         right);
```

PBRectangleCutRight trims `right` side by `right` units.


### PBRectangleHitTest

```c
bool PBRectangleHitTest(PBRectangle r,
                        PBVector2   pos);
```

PBRectangleHitTest reports whether `pos` lies inside `r`.


### PBRectangleClip

```c
PBRectangle PBRectangleClip(PBRectangle a,
                            PBRectangle b);
```

PBRectangleClip returns intersection of rectangles `a` and `b`.


### PBRectangleIntersects

```c
bool PBRectangleIntersects(PBRectangle r0,
                           PBRectangle r1);
```

PBRectangleIntersects returns true when `r0` and `r1` overlap.

---
`#include <playbit/f16.h>`

### PBF16

```c
typedef struct PBF16 {
    u16 bits;
} PBF16;
```

PBF16 is an IEEE 754 binary16 ("half") value stored as raw bits. A plain bits struct rather than _Float16 because not every target compiler supports _Float16 (wasm32 clang does not). Conversions use a single hardware instruction where _Float16 is available and a portable softfloat otherwise; both produce identical bits (round-to-nearest-even).

### PBF16FromF32

```c
PBF16 PBF16FromF32(f32 x);
```

PBF16FromF32 converts `x` to binary16 with round-to-nearest-even. Never produces Inf or NaN: NaN becomes 0, values beyond ±65504 clamp to ±65504.


### PBF16ToF32

```c
f32 PBF16ToF32(PBF16 h);
```

PBF16ToF32 converts a binary16 value to f32 (exact).


### PBF16BitsFromF32Portable

```c
u16 PBF16BitsFromF32Portable(f32 x);
```

PBF16BitsFromF32Portable is the portable (softfloat) reference implementation of `PBF16FromF32`, exposed for tests. Requires finite input.


### PBF16BitsToF32Portable

```c
f32 PBF16BitsToF32Portable(u16 bits);
```

PBF16BitsToF32Portable is the portable reference implementation of `PBF16ToF32`, exposed for tests.

---
`#include <playbit/slice.h>`

Define a slice type with `PBSliceType(ElementType)` and operate on it via "method" macros.

Example use:

    typedef struct {
        int a, b;
    } Foo;
    typedef PBSliceType(Foo) FooSlice;

Type generated by `PBSliceType(T)`:

    struct {
        const T* nullable v;
        usize             len;
    }

Predefined slice types:

- `PBI8Slice` with element type `i8`
- `PBI16Slice` with element type `i16`
- `PBI32Slice` with element type `i32`
- `PBI64Slice` with element type `i64`
- `PBU8Slice` with element type `u8`
- `PBU16Slice` with element type `u16`
- `PBU32Slice` with element type `u32`
- `PBU64Slice` with element type `u64`
- `PBF32Slice` with element type `f32`
- `PBF64Slice` with element type `f64`
- `PBPtrSlice` with element type `void*`

### PBI8Slice

```c
typedef PBSliceType(i8) PBI8Slice;
```

### PBI16Slice

```c
typedef PBSliceType(i16) PBI16Slice;
```

### PBI32Slice

```c
typedef PBSliceType(i32) PBI32Slice;
```

### PBI64Slice

```c
typedef PBSliceType(i64) PBI64Slice;
```

### PBU16Slice

```c
typedef PBSliceType(u16) PBU16Slice;
```

### PBU32Slice

```c
typedef PBSliceType(u32) PBU32Slice;
```

### PBU64Slice

```c
typedef PBSliceType(u64) PBU64Slice;
```

### PBF32Slice

```c
typedef PBSliceType(f32) PBF32Slice;
```

### PBF64Slice

```c
typedef PBSliceType(f64) PBF64Slice;
```

### PBPtrSlice

```c
typedef PBSliceType(void*) PBPtrSlice;
```

### PBSliceFrom

```c
macro SliceType PBSliceFrom(SliceType, T* nullable values, usize len)
```

- Returns: an instance of `SliceType` pointed to `len` items pointed to by `values`.

### PBSliceSlice

```c
macro SliceType PBSliceSlice(SliceType slice, usize start, usize len)
```

- Returns: a new `slice` referencing the items in `slice` starting at index `start` and with `len` length.

### PBSliceAt

```c
macro T PBSliceAt(SliceType slice, usize index)
```

- Returns: a copy of the item pointed to by `slice` at `index` `index`.

### PBSliceRefAt

```c
macro T* nullable PBSliceRefAt(SliceType slice, usize index)
```

- Returns: a pointer to the item pointed to by `slice` at `index` `index`.

### PBSliceEq

```c
macro bool PBSliceEq(SliceType slice, SliceType otherSlice)
```

- Returns: true if both slices' lengths are equal and all the bytes pointed to by `slice` equal those pointed to by `otherSlice`.

### PBSliceCmp

```c
macro int PBSliceCmp(SliceType slice, SliceType otherSlice)
```

- Returns: <0 if the contents pointed to by `slice` is bytewise less than the contents pointed to by `otherSlice`, >1 if `otherSlice` < `slice`, 0 if `slice` == `otherSlice`.

---
`#include <playbit/string.h>`

### PBStrSliceLike

```c
typedef const void * PBStrSliceLike;
```

PBStrSliceLike is a symbolic type, representing all types that PBStrSliceOf and similar generic functions accept as a source.

### PBStrLit

```c
macro PBStrSlice PBStrLit(const char stringLiteral[])
```

Creates a compile-time constant `PBStrSlice` from a C-string literal


### PBStrFree

```c
void PBStrFree(PBStr str,
               PBMem ma);
```

PBStrFree releases the memory of `str` back to memory allocator `ma`


### PBStrFrom

```c
PBStr PBStrFrom(PBMem          ma,
                PBStrSliceLike value);
```

PBStrFrom makes a copy of bytes at `value` as a `PBStr`, with a terminating NUL byte.

It's implemented as a generic macro, with the following effective signature:
`PBStr` PBStrFrom<T is convertible to `PBStrSlice`>(T `value`)

- Returns: `{ .v=NULL, .len=0 }` if memory could not be allocated.

### PBStrFromSlice

```c
PBStr PBStrFromSlice(PBMem      ma,
                     PBStrSlice value);
```

`PBStrFrom` makes a copy of bytes at `value` as a `PBStr`, with a terminating NUL byte.

- Returns: `{ .v=NULL, .len=0 }` if memory could not be allocated.

### PBStrFmt

```c
PBStr PBStrFmt(PBMem       ma,
               const char* format,
               ...);
```

PBStrFmt makes a string with printf-like formatting, with a terminating NUL byte.

- Returns: `{ .v=NULL, .len=0 }` if memory could not be allocated.

### PBStrFmtv

```c
PBStr PBStrFmtv(PBMem       ma,
                const char* format,
                va_list     va);
```

PBStrFmtv is the va_list variant of `PBStrFmt`.

- Returns: `{ .v=NULL, .len=0 }` if memory could not be allocated.

### PBStrJoin

```c
PBStr PBStrJoin(PBMem          ma,
                PBStrSliceLike glue,
                PBStrSliceLike value1,
                ...);
```

PBStrJoin concatenates byte arrays together with `glue` placed in between each value, with a terminating NUL byte.

- Returns: `{ .v=NULL, .len=0 }` if memory could not be allocated.

### PBStrJoinSlice

```c
PBStr PBStrJoinSlice(PBMem             ma,
                     PBStrSliceLike    glue,
                     const PBStrSlice* values,
                     usize             n);
```

PBStrJoinSlice joins `n` `values` with `glue` between each value, with a terminating NUL byte.

- Returns: `{ .v=NULL, .len=0 }` if memory could not be allocated.

### PBStrCat

```c
PBStr PBStrCat(PBMem          ma,
               PBStrSliceLike value1,
               ...);
```

PBStrCat concatenates byte arrays together, with a terminating NUL byte. It`s equivalent to PBStrJoint with empty `glue'.

- Returns: `{ .v=NULL, .len=0 }` if memory could not be allocated.

### PBStrAssign

```c
bool PBStrAssign(PBStr*         str,
                 PBMem          ma,
                 PBStrSliceLike newValue);
```

PBStrAssign replaces the value of `str` with `newValue`, reusing the existing memory of `str` if possible. Adds a terminating NUL byte to `str`.

- Returns: true on success or false if memory allocation failed

### PBStrAssignFromSlice

```c
bool PBStrAssignFromSlice(PBStr*     str,
                          PBMem      ma,
                          PBStrSlice newValue);
```

PBStrAssignFromSlice replaces the value of `str` with `newValue`, reusing the existing memory of `str` if possible. Adds a terminating NUL byte to `str`.

- Returns: true on success or false if memory allocation failed

### PBStrIndexOfStr

```c
i64 PBStrIndexOfStr(PBStrSlice s,
                    PBStrSlice substr);
```

PBStrIndexOfStr returns offset of first occurrance of `substr` in `s`, or `-1` if not found


### PBStrLastIndexOfStr

```c
i64 PBStrLastIndexOfStr(PBStrSlice s,
                        PBStrSlice substr);
```

`PBStrIndexOfStr` returns offset of last occurrance of `substr` in `s`, or `-1` if not found


### PBStrIndexOfByte

```c
i64 PBStrIndexOfByte(PBStrSlice s,
                     u8         byte);
```

`PBStrIndexOfStr` returns offset of first occurrance of `byte` in `s`, or `-1` if not found


### PBStrLastIndexOfByte

```c
i64 PBStrLastIndexOfByte(PBStrSlice s,
                         u8         byte);
```

`PBStrIndexOfStr` returns offset of last occurrance of `byte` in `s`, or `-1` if not found


### PBStr_FMT

```c
#define PBStr_FMT const char*
```

PBStr_FMT is used in printf format as the pattern for a `PBStr`-like value, like `PBStrSlice`


### PBStr_FMT_ARG

```c
#define PBStr_FMT_ARG(pbStr)
```

PBStr_FMT is used in printf arguments for a matching PBStr_FMT, with a `PBStr`-like value


### PBStrSliceOf

```c
PBStrSlice PBStrSliceOf(const void* value, ...);
```

PBStrSliceOf constructs a slice of a `value`. It's implemented as a generic macro, with the following effective signature: `PBStrSlice` PBStrSliceOf<T is convertible to `PBStrSlice`>( T `value` [, usize start [, usize len]]) Types convertible to `PBStrSlice`:
- `PBStrSlice`
- `PBU8Slice`
- `PBBuf`
- `PBU8Array`
- const `PBStr`
- const char* (NUL-terminated "C string")


### PBStrSliceOfStrSlice

```c
PBStrSlice PBStrSliceOfStrSlice(PBStrSlice other);
```

`PBStrSliceOf`… constructs a slice of a value (type-specific constructors)


### PBStrSliceOfStrSlice2

```c
PBStrSlice PBStrSliceOfStrSlice2(PBStrSlice other,
                                 usize      start,
                                 usize      len);
```


### PBStrSliceOfStrSlice3

```c
PBStrSlice PBStrSliceOfStrSlice3(PBStrSlice other,
                                 usize      start,
                                 usize      end);
```


### PBStrSliceOfU8Slice

```c
PBStrSlice PBStrSliceOfU8Slice(PBU8Slice other);
```


### PBStrSliceOfU8Slice2

```c
PBStrSlice PBStrSliceOfU8Slice2(PBU8Slice other,
                                usize     start,
                                usize     len);
```


### PBStrSliceOfCStr

```c
PBStrSlice PBStrSliceOfCStr(const char* str);
```


### PBStrSliceOfCStr2

```c
PBStrSlice PBStrSliceOfCStr2(const char* str,
                             usize       start,
                             usize       len);
```


### PBStrSliceOfStr

```c
PBStrSlice PBStrSliceOfStr(const PBStr str);
```


### PBStrSliceOfStr2

```c
PBStrSlice PBStrSliceOfStr2(PBStr str,
                            usize start,
                            usize len);
```


### PBStrSliceOfU8Array

```c
PBStrSlice PBStrSliceOfU8Array(PBU8Array other);
```


### PBStrSliceOfU8Array2

```c
PBStrSlice PBStrSliceOfU8Array2(PBU8Array other,
                                usize     start,
                                usize     len);
```


### PBStrSliceOfU8Arrayp

```c
PBStrSlice PBStrSliceOfU8Arrayp(const PBU8Array* other);
```


### PBStrSliceOfU8Arrayp2

```c
PBStrSlice PBStrSliceOfU8Arrayp2(const PBU8Array* other,
                                 usize            start,
                                 usize            len);
```


### PBStrSliceOfBuf

```c
PBStrSlice PBStrSliceOfBuf(PBBuf other);
```


### PBStrSliceOfBuf2

```c
PBStrSlice PBStrSliceOfBuf2(PBBuf other,
                            usize start,
                            usize len);
```


### PBStrSliceOfBufp

```c
PBStrSlice PBStrSliceOfBufp(const PBBuf* other);
```


### PBStrSliceOfBufp2

```c
PBStrSlice PBStrSliceOfBufp2(const PBBuf* other,
                             usize        start,
                             usize        len);
```


### PBStrSliceOfBytes

```c
PBStrSlice PBStrSliceOfBytes(const u8* bytes,
                             usize     len);
```

PBStrSliceOfBytes is a helper for (`PBStrSlice`){`bytes`,`len`}


### PBStrEq

```c
#define PBStrEq(a, b)
```

PBStrEq returns true if `a` is equal to `b`.
It's implemented as `a` generic macro, with the following effective signature:
bool PBStrEq<A is convertible to `PBStrSlice`, B is convertible to `PBStrSlice`>(A `a`, B `b`)


### PBStrSliceEq

```c
#define PBStrSliceEq …
```

bool PBStrSliceEq(`PBStrSlice` a, `PBStrSlice` b)
Returns true if a and b are identical (contains the same byte sequence)


### PBStrSliceTrim

```c
PBStrSlice PBStrSliceTrim(PBStrSlice s);
```

PBStrSliceTrim returns `s` without leading or trailing whitespace


### PBStrSliceTrimStart

```c
PBStrSlice PBStrSliceTrimStart(PBStrSlice s);
```

PBStrSliceTrimStart returns `s` without leading whitespace


### PBStrSliceTrimEnd

```c
PBStrSlice PBStrSliceTrimEnd(PBStrSlice s);
```

PBStrSliceTrimEnd returns `s` without trailing whitespace


### PBStrSliceParseInt

```c
bool PBStrSliceParseInt(PBStrSlice input,
                        u32        base,
                        i64*       result);
```

PBStrSliceParseInt parses all of `input` as a signed integer in `base` 2..36


### PBStrSliceParseUInt

```c
bool PBStrSliceParseUInt(PBStrSlice input,
                         u32        base,
                         u64*       result);
```

PBStrSliceParseUInt parses all of `input` as an unsigned integer in `base` 2..36


### PBIntOfStr

```c
i64 PBIntOfStr(PBStrSlice s);
```

PBIntOfStr parses `s` as a signed integer in base 10, ignoring whitespace.

It'`s` equivalent to:

    i64 result = 0;
    PBStrSliceParseInt(PBStrSliceTrim(s), 10, &result);


### PBExpectStrEq

```c
macro void PBExpectStrEq<A convertible_to PBStrSlice, B convertible_to PBStrSlice>(A a, B b)
```

checks if a == b (bytewise)


### PBCheckStrSliceEq

```c
void PBCheckStrSliceEq(PBStrSlice a,
                       PBStrSlice b);
```

PBCheckStrSliceEq panics if `a` and `b` are not equal


### PBStrSlicePrintv

```c
PBStrSlice PBStrSlicePrintv(PBArena*    arena,
                            const char* fmt,
                            va_list     args);
```

Prints a string into an `arena` (the result is always null-terminated)


### PBStrSlicePrint

```c
PBStrSlice PBStrSlicePrint(PBArena*    arena,
                           const char* fmt,
                           ...);
```

PBStrSlicePrint is the va_args variant of `PBStrSlicePrintv`.


### PB_STR

```c
macro PBStrSlice PB_STR(const char* cstr)
```

DEPRECATED: use PBStrLit for literals, or `PBStrSliceOf` for runtime-defined C strings


### PBStrSliceOfStrp

```c
PBStrSlice PBStrSliceOfStrp(const PBStr* str);
```

PBStrSliceOfStrp returns a borrowed view of *str.


### PBStrSliceOfStrp2

```c
PBStrSlice PBStrSliceOfStrp2(const PBStr* str,
                             usize        start,
                             usize        len);
```

PBStrSliceOfStrp2 returns a subslice view of *str starting at `start`.

---
`#include <playbit/sysbuf.h>`

### PBSysBufAdvance

```c
bool PBSysBufAdvance(PBSysBuf* bufvPtr,
                     u32*      bufcPtr,
                     i64       nbytes);
```

PBSysBufAdvance "removes" the first `nbytes` bytes from a list of `PBSysBuf` buffers. This is a helper function meant to be used when reading or writing chains of buffers. Caution: This function modifies buffers at *bufvPtr, updating their `bytes` and `len` fields. Returns true if *bufcPtr reached zero; i.e. buffers are empty.

Example:

```c
void Write(PBSysHandle stream, PBSysBuf* bufv, u32 bufc) {
    i64 nbytesWritten = PBSysStreamWrite(stream, bufv, bufc, 0);
    if (nbytesWritten > 0) {
        if (SysBufAdvance(&bufv, &bufc, nbytesWritten)) {
            // everything has been written
        }
    } else {
        // handle error
    }
}
```

---
`#include <playbit/hash.h>`

### PBHashImpl

```c
typedef enum PBHashImpl {
    PBHashImpl_NONE,
    PBHashImpl_BLAKE3,
} PBHashImpl;
```

### PBHashBlake3_CHUNK_LEN

```c
const int PBHashBlake3_CHUNK_LEN = 1024;
```

ideal max size for `PBHasherUpdate`


### PBHashBlake3_OUT_LEN

```c
const int PBHashBlake3_OUT_LEN = 32;
```

number of bytes returned by `PBHasherFinalize`


### PBHashBlake3_HASHER_SIZE

```c
const int PBHashBlake3_HASHER_SIZE = 1928;
```

bytes needed for `PBHasherEmplace`


### PBHasherCreate

```c
PBHasher* PBHasherCreate(PBMem      ma,
                         PBHashImpl impl);
```

PBHasherCreate allocates and initializes a new hasher using the provided implementation.

- Returns: NULL if enough memory could not be allocated

### PBHasherFree

```c
void PBHasherFree(PBHasher* hasher);
```

PBHasherFree frees the memory of a `hasher` allocated with `PBHasherCreate`


### PBHasherEmplace

```c
usize PBHasherEmplace(void*      mem,
                      usize      memSize,
                      PBHashImpl impl);
```

PBHasherEmplace initializes a hasher at `mem`

- `mem`: start of memory where to initialize a hasher. It's only valid to provide NULL if `memSize` is `0`.
- `memSize`: capacity of the memory region starting at `mem`
- `impl`: hash implementation to use
- Returns: number of bytes required for the requested hasher. If the returned value is larger than `memSize`, the function failed.

### PBHasherUpdate

```c
void PBHasherUpdate(PBHasher*   hasher,
                    const void* input,
                    usize       inputSize);
```

PBHasherUpdate feeds `input` data to the `hasher`


### PBHasherFinalize

```c
usize PBHasherFinalize(PBHasher* hasher,
                       u8*       output,
                       usize     outputCap);
```

PBHasherFinalize computes the final hash.

Note: Blake3 uses a fixed hash size of `PBHashBlake3_OUT_LEN` bytes.

- `output`: Where to write the hash. It's only valid to provide NULL if `outputCap` is `0`.
- `outputCap`: capacity of `output` in bytes.
- Returns: number of bytes that would have been written to `output` if `outputCap` was inifinitely large.

### PBHasherReset

```c
void PBHasherReset(PBHasher* hasher);
```

PBHasherReset recycles the internal state of a `hasher` so it can be reused


### PBHashRapidHash

```c
u64 PBHashRapidHash(const void* data,
                    usize       dataSize);
```

PBHashRapidHash computes a hash of `data` using the rapidhash hash implementation, a successor to wyhash with very good distribution and speed.


### PBHashRapidHashSeeded

```c
u64 PBHashRapidHashSeeded(const void* data,
                          usize       dataSize,
                          u64         seed);
```

PBHashRapidHashSeeded works like `PBHashRapidHash` but allows setting a `seed` to alter hashing


### PBHashRapidMix

```c
u64 PBHashRapidMix(u64 a,
                   u64 b);
```

PBHashRapidMix mixes two integers together using multiply and xor


### PBHashBytes

```c
u64 PBHashBytes(const void* data,
                usize       dataSize);
```

PBHashBytes computes a non-cryptographic hash of `data`. Currently an alias of `PBHashRapidHash`, but may change in the future if a more suitable hash algorithm comes along.


### PBHashBytesSeeded

```c
u64 PBHashBytesSeeded(const void* data,
                      usize       dataSize,
                      u64         seed);
```

PBHashBytesSeeded works like `PBHashBytes` but allows setting a `seed` to alter hashing


### PBHashMix

```c
u64 PBHashMix(u64 a,
              u64 b);
```

PBHashMix mixes two integers together

---
`#include <playbit/json.h>`

### PBJsonType

```c
typedef enum PBJsonType : u8 {
    PBJsonType_NULL,
    PBJsonType_BOOL,
    PBJsonType_NUMBER,
    PBJsonType_STRING,
    PBJsonType_ARRAY,
    PBJsonType_OBJECT,
} PBJsonType;
```

### PBJsonValue

```c
struct PBJsonValue {
    PBJsonType            type;
    PBStrSlice            key;  // member name when the parent is an object
    PBJsonValue* nullable next; // next sibling
    union {
        bool       b;   // BOOL
        f64        num; // NUMBER
        PBStrSlice str; // STRING
        struct {
            PBJsonValue* nullable first;
            u32                   len;
        } children; // ARRAY, OBJECT
    };
};
```

PBJsonValue is one node of a parsed document.

Children of arrays and objects form a singly-linked list in document order;
`key` is set on the members of an object and empty otherwise.

### PBJsonParse

```c
PBJsonValue* PBJsonParse(PBMem       ma,
                         PBStrSlice  src,
                         usize*      errOffset,
                         const char* errMsg);
```

PBJsonParse parses a complete JSON document.

- `ma`: allocator used for the returned tree; a reset frees the document
- `src`: document text; must outlive the returned tree
- `errOffset`: if non-NULL, set to the byte offset of a syntax error
- `errMsg`: if non-NULL, set to a static description of a syntax error
- Returns: NULL if `src` is not valid JSON or memory could not be allocated

### PBJsonObjGet

```c
PBJsonValue* PBJsonObjGet(const PBJsonValue* obj,
                          PBStrSlice         key);
```

PBJsonObjGet looks up a member of an object.

- Returns: NULL if `obj` is NULL, is not an object, or has no such member

### PBJsonForEach

```c
#define PBJsonForEach(ITERVAR, VALUE)
```

PBJsonForEach iterates the children of an array or object.
PBJsonForEach(item, arrayValue) { ... }


### PBJsonGetNum

```c
bool PBJsonGetNum(const PBJsonValue* v,
                  f64                fallback,
                  f64*               out);
```

PBJsonGetNum reads a number, tolerating absence.

- Returns: false if `v` is present but is not a number (`out` is left untouched)

### PBJsonGetBool

```c
bool PBJsonGetBool(const PBJsonValue* v,
                   bool               fallback,
                   bool*              out);
```

PBJsonGetBool reads a boolean; see `PBJsonGetNum` for the return contract


### PBJsonGetStr

```c
bool PBJsonGetStr(const PBJsonValue* v,
                  PBStrSlice         fallback,
                  PBStrSlice*        out);
```

PBJsonGetStr reads a string; see `PBJsonGetNum` for the return contract


### PBJsonWriterFlags

```c
typedef u32 PBJsonWriterFlags;
```

### PBJsonWriterFlag

```c
enum PBJsonWriterFlag {
    PBJsonWriterFlag_PRETTY = 1u << 0, // indent with two spaces and add newlines
};
```

### PBJsonWriter_MAX_DEPTH

```c
#define PBJsonWriter_MAX_DEPTH int
```

PBJsonWriter_MAX_DEPTH is the deepest nesting the writer can track


### PBJsonWriter

```c
typedef struct PBJsonWriter {
    PBBuf*            buf;
    PBMem             ma;
    u64               stack; // bit per level: 1 = object, 0 = array
    u32               depth;
    PBJsonWriterFlags flags;
    bool              needComma;
    bool              afterKey; // suppresses indentation of a member's value
    bool              oom;      // sticky
} PBJsonWriter;
```

PBJsonWriter appends JSON to a PBBuf.

Allocation failures are recorded rather than reported per call; check the
result of PBJsonWriterFinish once, when the document is complete.

### PBJsonWriterInit

```c
void PBJsonWriterInit(PBJsonWriter*     w,
                      PBBuf*            buf,
                      PBMem             ma,
                      PBJsonWriterFlags flags);
```

PBJsonWriterInit prepares a writer which appends to `buf`


### PBJsonWriterFinish

```c
bool PBJsonWriterFinish(PBJsonWriter* w);
```

PBJsonWriterFinish completes the document.

- Returns: false if any write failed to allocate, or if a container was left open

### PBJsonObjBegin

```c
void PBJsonObjBegin(PBJsonWriter* w);
```


### PBJsonObjEnd

```c
void PBJsonObjEnd(PBJsonWriter* w);
```


### PBJsonArrBegin

```c
void PBJsonArrBegin(PBJsonWriter* w);
```


### PBJsonArrEnd

```c
void PBJsonArrEnd(PBJsonWriter* w);
```


### PBJsonKey

```c
void PBJsonKey(PBJsonWriter* w,
               PBStrSlice    key);
```

PBJsonKey writes a member name; the next value written becomes its value


### PBJsonStr

```c
void PBJsonStr(PBJsonWriter* w,
               PBStrSlice    value);
```


### PBJsonInt

```c
void PBJsonInt(PBJsonWriter* w,
               i64           value);
```


### PBJsonUInt

```c
void PBJsonUInt(PBJsonWriter* w,
                u64           value);
```


### PBJsonBool

```c
void PBJsonBool(PBJsonWriter* w,
                bool          value);
```


### PBJsonNull

```c
void PBJsonNull(PBJsonWriter* w);
```


### PBJsonNum

```c
void PBJsonNum(PBJsonWriter* w,
               f64           value);
```

PBJsonNum writes a number. Values which are exactly integral are written
without a fractional part. Infinities and NaN are written as null, since JSON
cannot represent them.


### PBJsonNumF32

```c
void PBJsonNumF32(PBJsonWriter* w,
                  f32           value);
```

PBJsonNumF32 writes a f32 using only as many digits as it needs

# Playbit API reference

The file system APIs allow for arbitrary file system access on the host system. These APIs do not yet apply any restrictions or sandboxing on modification or manipulation of any files accessible by the current host OS user.

---
`#include <playbit/file.h>`

### PBFile

```c
typedef struct PBFile {
    PBSysHandle handle;
} PBFile;
```

PBFile represents a file or directory on a file system

### PBFileMode

```c
typedef u16 PBFileMode;
```

PBFile represents a file or directory on a file system

### PBFileModes

```c
enum PBFileModes PB_ENUM_TYPE(PBFileMode){
    PBFileMode_USER_R = 0400,    // user (file owner) has read permission
    PBFileMode_USER_W = 0200,    // user has write permission
    PBFileMode_USER_X = 0100,    // user has execute permission
    PBFileMode_USER_RW = 0600,   // user has read and write permissions
    PBFileMode_USER_RWX = 0700,  // user has read, write, and execute permissions
    PBFileMode_GROUP_R = 0040,   // group has read permission
    PBFileMode_GROUP_W = 0020,   // group has write permission
    PBFileMode_GROUP_X = 0010,   // group has execute permission
    PBFileMode_GROUP_RW = 0060,  // group has read and write execute permissions
    PBFileMode_GROUP_RWX = 0070, // group has read, write, and execute permissions
    PBFileMode_OTHER_R = 0004,   // others have read permission
    PBFileMode_OTHER_W = 0002,   // others have write permission
    PBFileMode_OTHER_X = 0001,   // others have execute permission
    PBFileMode_OTHER_RW = 0006,  // others have read and write execute permissions
    PBFileMode_OTHER_RWX = 0007, // others have read, write, and execute permissions
};
```

### PBFileOpenFlags

```c
typedef u32 PBFileOpenFlags;
```

PBFileOpenFlags changes behavior of PBFileOpen

### PBFileOpenFlag

```c
typedef enum PB_ENUM_TYPE(PBFileOpenFlags) {
    PBFileOpen_READ = PBSysFileOpenFlag_READ,           // give file PBSysRight_READ
    PBFileOpen_WRITE = PBSysFileOpenFlag_WRITE,         // give file PBSysRight_WRITE
    PBFileOpen_APPEND = PBSysFileOpenFlag_APPEND,       // open in append mode
    PBFileOpen_TRUNCATE = PBSysFileOpenFlag_TRUNCATE,   // truncate to length 0
    PBFileOpen_EXCLUSIVE = PBSysFileOpenFlag_EXCLUSIVE, // fail if file exists
    PBFileOpen_CREATE = PBSysFileOpenFlag_CREATE,       // create file if it does not exist

    // PBFileOpen_MODE_ bits are used when creating files
    PBFileOpen_MODE_MASK = PBSysFileOpenFlag_MODE_MASK,

    PBFileOpen_MODE_USER_R = PBSysFileOpenFlag_MODE_USER_R,     // user (owner) has read permission
    PBFileOpen_MODE_USER_W = PBSysFileOpenFlag_MODE_USER_W,     // user has write permission
    PBFileOpen_MODE_USER_X = PBSysFileOpenFlag_MODE_USER_X,     // user has execute permission
    PBFileOpen_MODE_USER_RW = PBSysFileOpenFlag_MODE_USER_RW,   // user has r+w permissions
    PBFileOpen_MODE_USER_RWX = PBSysFileOpenFlag_MODE_USER_RWX, // user has r+w+x permissions

    PBFileOpen_MODE_GROUP_R = PBSysFileOpenFlag_MODE_GROUP_R,     // group has read permission
    PBFileOpen_MODE_GROUP_W = PBSysFileOpenFlag_MODE_GROUP_W,     // group has write permission
    PBFileOpen_MODE_GROUP_X = PBSysFileOpenFlag_MODE_GROUP_X,     // group has execute permission
    PBFileOpen_MODE_GROUP_RW = PBSysFileOpenFlag_MODE_GROUP_RW,   // group has r+w permissions
    PBFileOpen_MODE_GROUP_RWX = PBSysFileOpenFlag_MODE_GROUP_RWX, // group has r+w+x permissions

    PBFileOpen_MODE_OTHER_R = PBSysFileOpenFlag_MODE_OTHER_R,     // others have read permission
    PBFileOpen_MODE_OTHER_W = PBSysFileOpenFlag_MODE_OTHER_W,     // others have write permission
    PBFileOpen_MODE_OTHER_X = PBSysFileOpenFlag_MODE_OTHER_X,     // others have execute permission
    PBFileOpen_MODE_OTHER_RW = PBSysFileOpenFlag_MODE_OTHER_RW,   // others have r+w permissions
    PBFileOpen_MODE_OTHER_RWX = PBSysFileOpenFlag_MODE_OTHER_RWX, // others have r+w+x permissions

    // aliases
    PBFileOpen_R = PBFileOpen_READ,
    PBFileOpen_W = PBFileOpen_WRITE,
    PBFileOpen_RW = PBFileOpen_READ | PBFileOpen_WRITE,
} PBFileOpenFlag;
```

### PBFileSystemRoot

```c
PBFile PBFileSystemRoot();
```

PBFileSystemRoot returns the default/initial file system provided to the current thread when it was started.


### PBFileOpen

```c
PBSysErr PBFileOpen(PBFile*         result,
                    PBFile          at,
                    PBStrSlice      path,
                    PBFileOpenFlags flags);
```

PBFileOpen opens a file `at` `path` relative to parent directory `at`, or to file `at` if `path` is empty.


### PBFileCreate

```c
PBSysErr PBFileCreate(PBFile*    result,
                      PBFile     at,
                      PBStrSlice path,
                      PBFileMode mode);
```

PBFileCreate creates a new file, failing if one exists. It's a convenience function over `PBFileOpen` with `PBFileOpen_WRITE | PBFileOpen_CREATE | PBFileOpen_EXCLUSIVE` added to flags along with `mode`

- Returns: `PBSysErr_EXISTS` if file already exists

### PBFileCreateOrTruncate

```c
PBSysErr PBFileCreateOrTruncate(PBFile*    result,
                                PBFile     at,
                                PBStrSlice path,
                                PBFileMode mode);
```

PBFileCreateOrTruncate creates a new file, or truncates an existing one to length 0. It's a convenience function over `PBFileOpen` with `PBFileOpen_WRITE | PBFileOpen_CREATE | PBFileOpen_TRUNCATE` added to flags along with `mode`


### PBFileOpenOrPanic

```c
PBFile PBFileOpenOrPanic(PBFile          at,
                         PBStrSlice      path,
                         PBFileOpenFlags flags);
```

PBFileOpenOrPanic works like `PBFileOpen` but panics on error


### PBFileCreateOrPanic

```c
PBFile PBFileCreateOrPanic(PBFile     at,
                           PBStrSlice path,
                           PBFileMode mode);
```

PBFileCreateOrPanic works like `PBFileCreate` but panics on error


### PBFileCreateOrTruncateOrPanic

```c
PBFile PBFileCreateOrTruncateOrPanic(PBFile     at,
                                     PBStrSlice path,
                                     PBFileMode mode);
```

PBFileCreateOrTruncateOrPanic works like `PBFileCreateOrTruncate` but panics on error


### PBFileClose

```c
void PBFileClose(PBFile* file);
```

PBFileClose closes `file`->handle and sets it to `PBSysHandle_INVALID`


### PBFileRead

```c
i64 PBFileRead(PBFile file,
               u8*    buf,
               usize  bufCap);
```

PBFileRead reads from `file` into `buf`.

- Returns: number of bytes read into `buf`, or `PBSysErr` as a negative value

### PBFileReadv

```c
i64 PBFileReadv(PBFile          file,
                const PBSysBuf* bufs,
                u32             bufCount);
```

PBFileReadv reads from `file` into `bufs`.

- Returns: number of bytes read into `bufs`, or `PBSysErr` as a negative value

### PBFileReadAll

```c
PBSysErr PBFileReadAll(PBFile file,
                       PBBuf* buf,
                       PBMem  ma);
```

PBFileReadAll reads an entire `file` into a buffer allocated in `ma`


### PBFileWrite

```c
i64 PBFileWrite(PBFile    file,
                const u8* buf,
                usize     bufLen);
```

PBFileWrite writes to `file` from `buf`.

- Returns: number of bytes written from `buf`, or `PBSysErr` as a negative value

### PBFileWritev

```c
i64 PBFileWritev(PBFile          file,
                 const PBSysBuf* bufs,
                 u32             bufCount);
```

PBFileWritev writes to `file` from `bufs`.

- Returns: number of bytes written from `bufs`, or `PBSysErr` as a negative value

### PBFileModeOfFlags

```c
PBFileMode PBFileModeOfFlags(PBFileOpenFlags flags);
```

PBFileModeOfFlags extracts mode from `flags`


### PBFileOpenFlagsOfMode

```c
PBFileOpenFlags PBFileOpenFlagsOfMode(PBFileMode mode);
```

PBFileOpenFlagsOfMode creates flags with `PBFileOpen_MODE_` bits set

---
`#include <playbit/dir_iterator.h>`

### PBDirIterator

```c
typedef struct PBDirIterator {
    PBMem              ma;
    PBSysHandle        handle;
    PBSysFileListEntry info; // information about the current entry
    union {
        PBStrSlice name; // name of the current entry
        PBBuf      nameBuf;
    };
} PBDirIterator;
```

PBDirIterator represents a directory iterator

### PBDirIteratorOpen

```c
PBSysErr PBDirIteratorOpen(PBDirIterator* dirIterator,
                           PBFile         dir,
                           PBStrSlice     subdirPath,
                           PBMem          ma);
```

PBDirIteratorOpen opens a directory iterator at `dir/subdirPath`, or `dir` if `subdirPath.len == 0`


### PBDirIteratorOpenOrPanic

```c
PBDirIterator PBDirIteratorOpenOrPanic(PBFile     dir,
                                       PBStrSlice subdirPath,
                                       PBMem      ma);
```

PBDirIteratorOpenOrPanic works like `PBDirIteratorOpen` but panics on error


### PBDirIteratorNext

```c
bool PBDirIteratorNext(PBDirIterator* dirIterator);
```

PBDirIteratorNextName advances the iterator and retrieves the name of the next entry. The name is appended to `buf`, allocating memory with `ma`. The order of iteration is undefined and depends on the underlying filesystem and operating system.

Example of listing names of all files in the directory "foo/bar" at the file system root:

    PBFile        root = PBFileSystemRoot();
    PBDirIterator it = PBDirIteratorOpenOrPanic(root, PBStrSliceOf("foo/bar"), kMemGPA);
    while (PBDirIteratorNext(&it))
        print("%.*s", (int)it.name.len, (const char*)it.name.v);
    PBDirIteratorClose(&it);

- Returns: true if a name was appended to buf, false if there are no more entries or if a filesystem error occurred.

### PBDirIteratorClose

```c
void PBDirIteratorClose(PBDirIterator* dirIterator);
```

PBDirIteratorClose closes `dirIterator`->handle and sets it to `PBSysHandle_INVALID`

# Playbit API reference

---
`#include <playbit/color.h>`

### PBColor

```c
typedef union PBColor {
    struct {
        PBF16 r, g, b, a; // rgba16float texel order; little endian u64 = 0xAAAABBBBGGGGRRRR
    };
    u16 channel[4];
    u64 u64;
} PBColor;
```

PBColor is a color with opacity (alpha) in the canvas working space: linear-light extended Display P3. Channels are binary16 in r,g,b,a memory order — the same layout as an rgba16float texel, so the u64 view is both the canvas wire format and PBSysTextureFormat_RGBAF16 pixel data (the little-endian u64 reads 0xAAAABBBBGGGGRRRR). 1.0 (0x3C00) is SDR white / full SDR primary; values above 1.0 are HDR (EDR headroom), negative RGB values express colors outside the P3 gamut. Alpha is in [0, 1]; constructors clamp it.

Rules:

- RGB channels must be finite. Inf/NaN color words produce undefined rendering (the renderer validates in debug builds only). All PBColor constructors sanitize, so this only concerns hand-built u64 words.
- The render target is also binary16, so an unblended fill stores exactly the channel bits of its PBColor (bit-exact wire == framebuffer).

Three kinds of constructors, named by what the channel values mean:

- PBColorRgb/PBColorRgba: SDR working-space values — linear-light P3 in [0, 1] (clamped).
- PBColorRgbHDR/PBColorRgbaHDR: working-space values without the SDR ceiling — linear-light P3, >1.0 is HDR, negative is out-of-gamut.
- PBColorRgbSrgb/PBColorRgbaSrgb (and the *U32 hex forms): sRGB display values — what a browser or design tool shows for those numbers. These decode the sRGB transfer function AND convert sRGB→P3 primaries, so PBColorRgbSrgbU32(0xFF0000) renders like CSS #F00, not like the (more saturated) full P3 red primary.

### PBColorF32

```c
typedef struct PBColorF32 {
    f32 r, g, b, a;
} PBColorF32;
```

PBColorF32 is an unpacked f32 view of a color (same meaning as PBColor channels: linear-light extended Display P3), for arithmetic.

### PBHsvColor

```c
typedef struct PBHsvColor {
    f32 h, s, v, a;
} PBHsvColor;
```

PBHsvColor is a color in HSV(A) representation, all fields in [0, 1]. Hue, saturation and value are computed over transfer-encoded P3 channel values (display values, like a color picker shows).

### PBColorR

```c
f32 PBColorR(PBColor c);
```

PBColorR returns the red channel as f32 (linear P3).


### PBColorG

```c
f32 PBColorG(PBColor c);
```

PBColorG returns the green channel as f32 (linear P3).


### PBColorB

```c
f32 PBColorB(PBColor c);
```

PBColorB returns the blue channel as f32 (linear P3).


### PBColorA

```c
f32 PBColorA(PBColor c);
```

PBColorA returns the alpha channel as f32.


### PBColorUnpack

```c
PBColorF32 PBColorUnpack(PBColor c);
```

PBColorUnpack expands the channels to f32.


### PBColorPack

```c
PBColor PBColorPack(PBColorF32 c);
```

PBColorPack builds a color from working-space (linear P3) channel values. Sanitizes: NaN→0, RGB clamped to ±65504, alpha clamped to [0, 1].


### PBColorRgb

```c
PBColor PBColorRgb(f32 r,
                   f32 g,
                   f32 b);
```

PBColorRgb constructs an opaque color from SDR working-space values: linear-light P3, all channels clamped to [0, 1].


### PBColorRgba

```c
PBColor PBColorRgba(f32 r,
                    f32 g,
                    f32 b,
                    f32 a);
```

PBColorRgba constructs an RGBA color from SDR working-space values: linear-light P3, all channels clamped to [0, 1].


### PBColorRgbHDR

```c
PBColor PBColorRgbHDR(f32 r,
                      f32 g,
                      f32 b);
```

PBColorRgbHDR constructs an opaque color from working-space (linear P3) values without the SDR ceiling: >1.0 is HDR, negative is out-of-gamut. Sanitized like `PBColorPack`.


### PBColorRgbaHDR

```c
PBColor PBColorRgbaHDR(f32 r,
                       f32 g,
                       f32 b,
                       f32 a);
```

PBColorRgbaHDR constructs an RGBA color from working-space (linear P3) values without the SDR ceiling: >1.0 is HDR, negative is out-of-gamut. Sanitized like `PBColorPack`.


### PBColorRgbSrgb

```c
PBColor PBColorRgbSrgb(f32 r,
                       f32 g,
                       f32 b);
```

PBColorRgbSrgb constructs an opaque color from sRGB display values in [0, 1] (sRGB transfer decode + sRGB→P3 gamut conversion).


### PBColorRgbaSrgb

```c
PBColor PBColorRgbaSrgb(f32 r,
                        f32 g,
                        f32 b,
                        f32 a);
```

PBColorRgbaSrgb constructs an RGBA color from sRGB display values in [0, 1] (sRGB transfer decode + sRGB→P3 gamut conversion).


### PBColorRgbSrgbU32

```c
PBColor PBColorRgbSrgbU32(u32 rgb);
```

PBColorRgbSrgbU32 converts sRGB 0xRRGGBB to an opaque color.


### PBColorRgbaSrgbU32

```c
PBColor PBColorRgbaSrgbU32(u32 rgba);
```

PBColorRgbaSrgbU32 converts sRGB 0xRRGGBBAA to an RGBA color.


### PBColorWithAlpha

```c
PBColor PBColorWithAlpha(PBColor c,
                         f32     a);
```

PBColorWithAlpha returns `c` with its alpha replaced (clamped to [0, 1]).


### PBColorIsZero

```c
bool PBColorIsZero(PBColor c);
```

PBColorIsZero reports whether all channels are exactly (+)zero.


### PBColorEquals

```c
bool PBColorEquals(PBColor c0,
                   PBColor c1);
```

PBColorEquals compares channel bits exactly.


### PBColorToU64

```c
u64 PBColorToU64(PBColor x);
```

PBColorToU64 packs the color for the canvas syscall ABI. `PBColor`, the wire format and the `PBSysTextureFormat_RGBAF16` texel format are the same bits, so this is the identity; it exists for call sites that predate the f16 pipeline.


### PBColorToU32

```c
u32 PBColorToU32(PBColor x);
```

PBColorToU32 packs to 8-bit channels as 0xAARRGGBB. The RGB bytes are display-encoded P3, i.e. the transfer function is applied but no gamut conversion (the 8-bit texture pipeline treats bytes as P3-native, NOT sRGB), so PBColorToU32(`PBColorRgbSrgbU32`(h)) does not round-trip h.


### PBColorToRGBA8

```c
u32 PBColorToRGBA8(PBColor x);
```

PBColorToRGBA8 packs to 8-bit channels in R,G,B,A memory byte order (for `PBSysTextureFormat_RGBA8` texture data). The RGB bytes are display-encoded P3, like `PBColorToU32`.


### PBColorFromRGBA8

```c
PBColor PBColorFromRGBA8(u32 x);
```

PBColorFromRGBA8 is the inverse of `PBColorToRGBA8`.


### PBColorToPackedRGBA

```c
u32 PBColorToPackedRGBA(PBColor x);
```

PBColorToPackedRGBA packs to 8-bit channels as 0xRRGGBBAA. The RGB bytes are display-encoded P3, like `PBColorToU32`.


### PBColorToHSV

```c
PBHsvColor PBColorToHSV(PBColor rgb);
```

PBColorToHSV converts to HSV(A), computed over the transfer-encoded P3 channel values (display values, like a color picker shows).


### PBHsvColorToRGB

```c
PBColor PBHsvColorToRGB(PBHsvColor hsv);
```

PBHsvColorToRGB is the inverse of `PBColorToHSV`.


### PBColorSrgbDecode

```c
f32 PBColorSrgbDecode(f32 encoded);
```

PBColorSrgbDecode applies the inverse sRGB transfer function (which Display P3 shares) to one channel value in [0, 1]: `encoded` -> linear.


### PBColorSrgbEncode

```c
f32 PBColorSrgbEncode(f32 linear);
```

PBColorSrgbEncode applies the sRGB transfer function (which Display P3 shares) to one channel value in [0, 1]: `linear` -> encoded.


### PBColor_Black

```c
#define PBColor_Black((PBColor)
```

PBColor_Black is opaque black: `PBColorRgb(0, 0, 0)` (same color in every space)


### PBColor_White

```c
#define PBColor_White((PBColor)
```

PBColor_White is opaque white: `PBColorRgb(1, 1, 1)` (same color in every space)


### PBColor_Red

```c
#define PBColor_Red((PBColor)
```

PBColor_Red is the opaque P3 red primary: `PBColorRgb(1, 0, 0)`


### PBColor_Green

```c
#define PBColor_Green((PBColor)
```

PBColor_Green is the opaque P3 green primary: `PBColorRgb(0, 1, 0)`


### PBColor_Blue

```c
#define PBColor_Blue((PBColor)
```

PBColor_Blue is the opaque P3 blue primary: `PBColorRgb(0, 0, 1)`


### PBColor_Magenta

```c
#define PBColor_Magenta((PBColor)
```

PBColor_Magenta is opaque P3 magenta: `PBColorRgb(1, 0, 1)`


### PBColor_Yellow

```c
#define PBColor_Yellow((PBColor)
```

PBColor_Yellow is opaque P3 yellow: `PBColorRgb(1, 1, 0)`


### PBColor_Cyan

```c
#define PBColor_Cyan((PBColor)
```

PBColor_Cyan is opaque P3 cyan: `PBColorRgb(0, 1, 1)`


### PBColor_Red_sRGB

```c
#define PBColor_Red_sRGB((PBColor)
```

PBColor_Red_sRGB is opaque sRGB red: `PBColorRgbSrgb(1, 0, 0)`


### PBColor_Green_sRGB

```c
#define PBColor_Green_sRGB((PBColor)
```

PBColor_Green_sRGB is opaque sRGB green: `PBColorRgbSrgb(0, 1, 0)`


### PBColor_Blue_sRGB

```c
#define PBColor_Blue_sRGB((PBColor)
```

PBColor_Blue_sRGB is opaque sRGB blue: `PBColorRgbSrgb(0, 0, 1)`


### PBColor_Magenta_sRGB

```c
#define PBColor_Magenta_sRGB((PBColor)
```

PBColor_Magenta_sRGB is opaque sRGB magenta: `PBColorRgbSrgb(1, 0, 1)`


### PBColor_Yellow_sRGB

```c
#define PBColor_Yellow_sRGB((PBColor)
```

PBColor_Yellow_sRGB is opaque sRGB yellow: `PBColorRgbSrgb(1, 1, 0)`


### PBColor_Cyan_sRGB

```c
#define PBColor_Cyan_sRGB((PBColor)
```

PBColor_Cyan_sRGB is opaque sRGB cyan: `PBColorRgbSrgb(0, 1, 1)`

---
`#include <playbit/draw.h>`

### PBUIFont

```c
struct PBUIFont {
    PBStrSlice family; // font family name (e.g. PBStrLit("Inter"))
    f32        size;   // font size in pixels (e.g. 16.0)
    f32        weight; // font weight between 100-900
};
```

### PBTextCacheEntry

```c
struct PBTextCacheEntry {
    u64 hash;
    // key
    u8* text; // copied into cache arena
    u32 textLen;
    u8* fontFamily; // copied into cache arena
    u32 fontFamilyLen;
    u32 fontSize; // scaled 26.6 fixed point
    u32 weight;
    u32 color;
    f32 maxWidth;
    f32 maxHeight;
    u32 flags;
    // value
    PBSysHandle plan;
    PBVector2   size;
    u64         lastFrame;
    bool        sticky;
};
```

### PBTextCache

```c
struct PBTextCache {
    PBArena*          arena; // owns entry array
    PBTextCacheEntry* entries;
    u64               capacity; // power of two
    u64               count;
    u64               frame; // incremented each PBTextCacheNextFrame()
    // context required to create plans
    PBWindow window;
};
```

### PBRender

```c
struct PBRender {
    PBArena* arena;
    u8*      cmds;
    u32      cmdsSize;
    u32      cmdsCap;
};
```

### PBDrawContext

```c
struct PBDrawContext {
    PBArena*    arena;
    PBRender    render;
    PBTextCache textCache;

    PBWindow    window;
    PBSysHandle canvas;
    f32         scale;
    u32         clipDepth;
    PBColor     backgroundColor;
};
```

### PBTexture

```c
struct PBTexture {
    PBSysHandle handle;
};
```

### PBStrokeType

```c
typedef enum PB_ENUM_TYPE(uint32_t) {
    PBStrokeType_CENTER = 0,
    PBStrokeType_INNER = 1,
    PBStrokeType_OUTER = 2,
} PBStrokeType;
```

### PBTextplanWidthOfSize

```c
#define PBTextplanWidthOfSize(x)
```

`PBSysTextplanGetSize` result macros


### PBTextureCreate

```c
PBTexture PBTextureCreate(PBWindow                window,
                          PBSysTextureFormat      format,
                          u32                     width,
                          u32                     height,
                          PBSysTextureCreateFlags flags);
```

PBTextureCreate creates a GPU texture for `window` with the given `format`, dimensions, and `flags`.
Returns a texture with an invalid handle if the GPU is not yet ready; check with `PBTextureIsValid`.


### PBTextureCreateFromData

```c
PBTexture PBTextureCreateFromData(PBWindow                window,
                                  const void*             data,
                                  u64                     dataSize,
                                  PBSysTextureCreateFlags flags);
```

PBTextureCreateFromData decodes encoded image bytes (PNG, JPEG, WebP, GIF, BMP, TGA) and
creates an upload-ready GPU texture in one call, with no guest-side pixel buffer.
Returns a texture with an invalid handle on failure; check with `PBTextureIsValid`.


### PBTextureIsValid

```c
bool PBTextureIsValid(PBTexture texture);
```

PBTextureIsValid returns true if the `texture` handle is valid (i.e. successfully created).


### PBTextureWrite

```c
void PBTextureWrite(PBTexture   texture,
                    u32         originX,
                    u32         originY,
                    const void* pixels,
                    u64         pixelSize,
                    u32         width,
                    u32         height);
```

PBTextureWrite uploads a pixel region to the `texture` starting at (`originX`, `originY`).
`pixels` must point to at least `pixelSize` bytes covering a `width` x `height` region.


### PBTextureDestroy

```c
void PBTextureDestroy(PBTexture* texture);
```

PBTextureDestroy releases the `texture`'s GPU resources and invalidates the handle.


### PBDrawSetGlobal

```c
void PBDrawSetGlobal(PBDrawContext* ctx);
```

PBDrawSetGlobal sets the thread-local draw context used by PBDraw* calls.


### PBDrawGetGlobal

```c
PBDrawContext* PBDrawGetGlobal();
```

PBDrawGetGlobal returns the active thread-local draw context.


### PBDrawInit

```c
void PBDrawInit(PBDrawContext* ctx,
                PBArena*       arena,
                PBWindow       window);
```

PBDrawInit initializes draw/render/text-cache state for `window`.


### PBDrawBeginFrame

```c
void PBDrawBeginFrame(PBWindow window);
```

PBDrawBeginFrame starts a frame and refreshes `window` scale and per-frame draw state.


### PBDrawEndFrame

```c
void PBDrawEndFrame();
```

PBDrawEndFrame submits queued commands and advances text-cache frame lifetime.


### PBDrawSetScale

```c
void PBDrawSetScale(f32 scale);
```

PBDrawSetScale sets the drawing `scale` for the current frame. By default, the `scale` is set to the window's `scale` (drawing is in dps, not pixels).


### PBDrawSetBackgroundColor

```c
void PBDrawSetBackgroundColor(PBColor color);
```

PBDrawSetBackgroundColor sets the background `color`.


### PBDrawGetScale

```c
f32 PBDrawGetScale();
```

PBDrawGetScale gets the drawing scale for the current frame.


### PBDrawRect

```c
void PBDrawRect(PBRectangle bounds,
                PBColor     color);
```

PBDrawRect enqueues a filled rectangle with square corners.


### PBDrawRectExt

```c
void PBDrawRectExt(PBRectangle bounds,
                   PBColor     color,
                   PBVector4   cornerRadius);
```

PBDrawRectExt enqueues a filled rectangle with per-corner radius.


### PBDrawRectExt2

```c
void PBDrawRectExt2(PBRectangle bounds,
                    PBColor     colorTopLeft,
                    PBColor     colorTopRight,
                    PBColor     colorBottomRight,
                    PBColor     colorBottomLeft,
                    PBVector4   cornerRadius);
```

`PBDrawRectExt` enqueues a filled rectangle with per-corner color and radius.


### PBDrawRectOutline

```c
void PBDrawRectOutline(PBRectangle  bounds,
                       PBStrokeType type,
                       PBColor      strokeColor,
                       f32          strokeWidth,
                       PBVector4    cornerRadius);
```


### PBDrawRectInset

```c
void PBDrawRectInset(PBRectangle bounds,
                     PBColor     strokeColor,
                     f32         strokeWidth,
                     PBVector4   cornerRadius);
```

PBDrawRectInset enqueues an inset rectangle stroke with configurable width and corner radius.


### PBDrawRectWithStroke

```c
void PBDrawRectWithStroke(PBRectangle bounds,
                          PBColor     fillColor,
                          PBColor     strokeColor,
                          f32         strokeWidth,
                          PBVector4   cornerRadius);
```

PBDrawRectWithStroke enqueues an rectangle with both a fill and inset stroke with configurable width and corner radius.


### PBDrawText

```c
void PBDrawText(PBUIFont    font,
                PBStrSlice  text,
                PBColor     color,
                PBRectangle bounds);
```

PBDrawText enqueues `text` rendering into `bounds` using `font` and `color`. Text is assumed to be single-line `text`.


### PBDrawTextAlign

```c
void PBDrawTextAlign(PBUIFont    font,
                     PBStrSlice  text,
                     PBColor     color,
                     PBRectangle bounds,
                     PBVector2   alignment,
                     bool        multiline);
```

PBDrawTextAlign enqueues `text` rendering aligned within the bounding rectangle.
`alignment` is a `PBVector2` where (0,0)=top-left, (0.5,0.5)=center, (1,1)=bottom-right.
If `multiline` is true, `text` wraps within the `bounds` width.


### PBDrawTextLine

```c
void PBDrawTextLine(PBUIFont   font,
                    PBStrSlice text,
                    PBColor    color,
                    PBVector2  pos,
                    f32        maxWidth);
```

PBDrawTextLine draws a single line of `text`. Optionally you can specify `maxWidth` and maxHeight (or use 0 if none is desired).


### PBDrawTextMultiline

```c
void PBDrawTextMultiline(PBUIFont   font,
                         PBStrSlice text,
                         PBColor    color,
                         PBVector2  pos,
                         f32        maxWidth,
                         f32        maxHeight);
```

PBDrawTextMultiline draws multiple lines of `text`. Optionally you can specify `maxWidth` and `maxHeight` (or use 0 if none is desired).


### PBDrawTextWithPlan

```c
void PBDrawTextWithPlan(PBSysHandle plan,
                        PBRectangle bounds);
```

PBDrawTextWithPlan enqueues text rendering into `bounds` using an existing text `plan`.
The text `plan` must not be released until the frame is complete.


### PBDrawTextWithPlanAndOverrideColor

```c
void PBDrawTextWithPlanAndOverrideColor(PBSysHandle plan,
                                        PBRectangle bounds,
                                        PBColor     color);
```

PBDrawTextWithPlanAndOverrideColor enqueues text rendering into `bounds` using an existing text `plan`; the text is drawn is the specified `color`, rather than the `color` specified when the text `plan` was created.
The text `plan` must not be released until the frame is complete.


### PBDrawMeasureText

```c
PBVector2 PBDrawMeasureText(PBUIFont   font,
                            PBStrSlice text,
                            f32        maxWidth);
```

PBDrawMeasureText returns measured `text` size for the given `font` and max width constraint (in dps).


### PBDrawPushClip

```c
void PBDrawPushClip(PBRectangle bounds);
```

PBDrawPushClip pushes a clip rectangle onto the clip stack, restricting rendering to `bounds`.


### PBDrawPopClip

```c
void PBDrawPopClip();
```

PBDrawPopClip pops the most recently pushed clip rectangle from the clip stack.


### PBDrawResetClip

```c
void PBDrawResetClip();
```

PBDrawResetClip pops all clip rectangles from the clip stack.


### PBDrawTexturedRect

```c
void PBDrawTexturedRect(PBTexture   texture,
                        PBRectangle bounds);
```

PBDrawTexturedRect draws a `texture` mapped to `bounds`, tinted by tintColor.
Use `PBColorRgbaSrgb`(1,1,1,1) for no tint.


### PBDrawTexturedRectExt

```c
void PBDrawTexturedRectExt(PBTexture   texture,
                           PBRectangle bounds,
                           PBRectangle uv,
                           PBColor     tintColor,
                           PBVector4   cornerRadius);
```

PBDrawTexturedRectExt draws a `texture` mapped to `bounds` with per-corner radius and tint color.


### PBDrawTexturedRectExt2

```c
void PBDrawTexturedRectExt2(PBTexture   texture,
                            PBRectangle bounds,
                            PBRectangle uv,
                            PBColor     colorTopLeft,
                            PBColor     colorTopRight,
                            PBColor     colorBottomRight,
                            PBColor     colorBottomLeft,
                            PBVector4   cornerRadius);
```

Same as `PBDrawTexturedRectExt`, but allows you to specify a color for each of the 4 vertices.

---
`#include <playbit/wgpu.h>`

### PBSysGpuCanvasGetWGPUTexture

```c
WGPUTexture PBSysGpuCanvasGetWGPUTexture(PBSysHandle canvas);
```


### PBSysGpuCanvasGetWGPUDevice

```c
WGPUDevice PBSysGpuCanvasGetWGPUDevice(PBSysHandle canvas);
```


### PBSysGpuCanvasGetWGPUQueue

```c
WGPUQueue PBSysGpuCanvasGetWGPUQueue(PBSysHandle canvas);
```

# Playbit API reference

Memory management in the Playbit C is done with explicit allocators. The type of an allocator is `PBMem` and is passed as an argument to functions which allocate memory. Every distinct allocation from `PBMem` allocators have an address-aligment guarantee of `PBMem_ALIGNMENT` (at least 16 bytes).

Example

```c
#include <playbit/playbit.h>

int* make_int_array_or_panic(PBMem ma, usize count) {
    int* array = PBMemAllocz(ma, count * sizeof(int));
    return PBExpectNotNull(array); // panic if allocation failed
}

void main() {
    PBMem ma = kPBMemGPA;
    int* a = make_int_array(ma, 12);
    print("allocated array of 12 integers at %p", a);
    PBMemFree(ma, a);
}
```

### Allocators

There are several allocators available "out of the box." Usually you just use `kPBMemGPA` and that's it, but sometimes a specialized allocator can be useful. For example, if you are parsing an AST, analyzing it and then throwing away the result, `PBArena` removes the need for freeing memory. A `PBMemNullAllocator` is useful when testing code that gracefully handles allocation failures.

- `kPBMemGPA` is a general-purpose allocator; a universal "heap allocator" that strikes a balance between performance and memory use. Use `kPBMemGPA` if you don't know what you want.
- [`PBArena`](#playbit/arena.h) implements an arena allocator, useful for region-based memory management. It's a hybrid betwen a simple bump allocator and a chained-block allocator.
- `PBMemBufAllocator` implements a simple bump allocator on top of an externally managed buffer. Useful for testing or for very performance cricital code where control over memory locality is important. Generally not a very useful allocator.
- `PBMemNullAllocator` always fails to allocate memory, intended to be used for testing.
- `PBMemZeroingAllocator` wraps another allocator and causes all allocations to be zero-initialized, useful for intercepting library code.



---
`#include <playbit/mem.h>`

### PBMem_ALIGNMENT

```c
#define PBMem_ALIGNMENT usize
```

PBMem_ALIGNMENT is the minimum guaranteed address alignment for allocations. It's at least `_Alignof(max_align_t)`


### PBMem

```c
typedef const struct PBMemAllocator * PBMem;
```

PBMem is the type of a memory allocator

### PBMemAllocator

```c
typedef struct PBMemAllocator {
    void* nullable (*f)(PBMem self, void* nullable ptr, usize* nullable nbyte_inout, u32 flags);
} PBMemAllocator;
```

PBMemAllocator is the type of a memory allocator. It's function is invoked as follows:

| PBMem                       | libc equivalent                                            |
| --------------------------- | ---------------------------------------------------------- |
| `f(NULL, size, 0)`          | `malloc(size)`                                             |
| `f(NULL, size, PBMem_ZERO)` | `calloc(size, 1)`                                          |
| `f(ptr, size, 0)`           | `realloc(ptr, size)`                                       |
| `f(ptr, size, PBMem_ZERO)`  | `realloc(ptr, size2);`<br>`bzero(ptr2+size1, size2-size1)` |
| `f(ptr, 0, 0)`              | `free(ptr)`                                                |

It's defined as a struct with a function pointer, rather than simply a function, to allow allocator implementations like arenas to store allocator-specific state.

### PBMem_ZERO

```c
const int PBMem_ZERO = 1;
```

allocate zeroed memory


### PBMem_ROUNDUP

```c
const int PBMem_ROUNDUP = 2;
```

PBMem_ROUNDUP requests that nbyte_inout is rounded up to a value that the allocator can allocate without adding any padding.


### PBMemAlloc

```c
void* PBMemAlloc(PBMem ma,
                 usize nbyte);
```

PBMemAlloc allocates `nbyte` bytes through allocator `ma`.

- Returns: NULL on allocation failure.

### PBMemAllocz

```c
void* PBMemAllocz(PBMem ma,
                  usize nbyte);
```

PBMemAllocz allocates `nbyte` bytes through allocator `ma` and zero-initializes the returned memory.

- Returns: NULL on allocation failure.

### PBMemRealloc

```c
void* PBMemRealloc(PBMem ma,
                   void* ptr,
                   usize nbyte);
```

PBMemRealloc resizes an allocation owned by `ma`.

- `ptr`: Pointer to existing allocation. Pass NULL to allocate like `PBMemAlloc`.
- `nbyte`: New size. Pass 0 to free like `PBMemFree`.
- Returns: NULL on allocation failure when growing or creating.

### PBMemReallocz

```c
void* PBMemReallocz(PBMem ma,
                    void* ptr,
                    usize nbyte);
```

PBMemReallocz is like `PBMemRealloc` but requests zero-initialization of newly added bytes.

- Returns: NULL on allocation failure when growing or creating.

### PBMemAllocx

```c
void* PBMemAllocx(PBMem  ma,
                  void*  ptr,
                  usize* nbyte_inout,
                  u32    flags);
```

PBMemAllocx is the most flexible allocator interface. You can perform all actions provided by `PBMemAlloc`, `PBMemAllocz`, `PBMemRealloc`, `PBMemReallocz` and `PBMemFree`, plus get the actual allocated memory region's size back.

- `nbyte_inout`: Points to the requested size and may be increased by the allocator.
- Returns: NULL on allocation failure.

### PBMemFree

```c
void PBMemFree(PBMem ma,
               void* ptr);
```

PBMemFree releases `ptr` to allocator `ma`.


### PBMemResize

```c
bool PBMemResize(PBMem  ma,
                 usize  elemSize,
                 void*  ptrInOut,
                 usize* capInOut,
                 usize  newCap,
                 u32    maFlags);
```

PBMemResize resizes the capacity of an array `*ptrInOut` to `newCap`.

- `ptrInOut`: holds the address of the current memory allocation, updated on successful return.
- `capInOut`: holds the current capacity (number of elements) of `*ptrInOut`, updated on successful return.
- `newCap`: The requested new capacity.
- `maFlags`: Flags passed to `PBMemAllocx`.
- Returns: true on success, in which case the value of `*ptrInOut` may be a new address and `*capInOut` holds the new capacity. If `PBMem_ROUNDUP` is set in `maFlags`, `*capInOut` has been rounded up to what's ideal for the memory allocator `ma`. false if resizing fails, in which case `*ptrInOut` and `*capInOut` remain unchanged and the current memory region remains valid.

### PBMemGrow

```c
bool PBMemGrow(PBMem  ma,
               usize  elemSize,
               void*  ptrInOut,
               usize* capInOut,
               usize  addCap,
               u32    maFlags);
```

PBMemGrow attempts to grow the array at `*dataPtr` to at least `*capInOut+addCap`, rounding up by allocator-friendly amounts. Usually ~1.5x of current capacity.

- `ptrInOut`: holds the address of the current memory allocation, updated on successful return.
- `capInOut`: holds the current capacity (number of elements) of `*ptrInOut`, updated on successful return.
- `addCap`: The requested _additional_ capacity.
- `maFlags`: Flags passed to `PBMemAllocx`.
- Returns: true on success, in which case the value of `*ptrInOut` may be a new address and `*capInOut` holds the new capacity.

### PBMemPageSize

```c
usize PBMemPageSize();
```

PBMemPageSize returns the underlying system's memory page size


### PBMemEq

```c
bool PBMemEq(const void* a,
             usize       aLen,
             const void* b,
             usize       bLen);
```

PBMemEq returns true if memory at `a` is equivalent to memory at `b`


### PBMemCmp

```c
int PBMemCmp(const void* a,
             usize       aLen,
             const void* b,
             usize       bLen);
```

PBMemCmp returns <0 if `a` is bytewise less than `b`, >1 if `b` < `a`, 0 if `a` == `b`


### PBMemoryCopy

```c
void PBMemoryCopy(void*       to,
                  const void* from,
                  usize       size);
```

PBMemoryCopy is a different name for `memcpy`


### PBMemoryZero

```c
void PBMemoryZero(void* ptr,
                  usize size);
```

PBMemoryZero does `memset(ptr, 0, size)`


### PBMemoryEquals

```c
bool PBMemoryEquals(const void* a,
                    const void* b,
                    usize       size);
```


### PBMemFindByte

```c
const u8* PBMemFindByte(const u8* v,
                        usize     vLen,
                        u8        byte);
```

PBMemFindByte returns a pointer into `v` where `byte` first occur, or NULL if `byte` is not in `v`


### PBMemFindLastByte

```c
const u8* PBMemFindLastByte(const u8* v,
                            usize     vLen,
                            u8        byte);
```

PBMemFindLastByte returns a pointer into `v` of the last occurrance of `byte`, or NULL if `byte` is not in `v`


### PBMemFindSegment

```c
const u8* PBMemFindSegment(const u8* v,
                           usize     vLen,
                           const u8* seg,
                           usize     segLen);
```

PBMemFindSegment returns a pointer into `v` where `seg` first occur, or NULL if `seg` is not in `v`


### PBMemFindLastSegment

```c
const u8* PBMemFindLastSegment(const u8* v,
                               usize     vLen,
                               const u8* seg,
                               usize     segLen);
```

PBMemFindLastSegment returns a pointer into `v` of the last occurrance of `seg`, or NULL if `seg` is not in `v`


### PBMemoryZeroStruct

```c
#define PBMemoryZeroStruct(ptr)
```

PBMemoryZeroStruct does `memset(ptr, 0, sizeof(*ptr))`


### PBMemRegionsOverlap

```c
bool PBMemRegionsOverlap(const void* a,
                         usize       aLen,
                         const void* b,
                         usize       bLen);
```

PBMemRegionsOverlap returns true if two memory regions overlap

---
`#include <playbit/mem_gpa.h>`

### kPBMemGPA

```c
extern PBMem kPBMemGPA;
```

kPBMemGPA is the general-purpose allocator


### PBMemGPAStats

```c
typedef struct PBMemGPAStats {
    usize totalBytes; // size of heap, in bytes
    usize peakBytes;  // max space allocated from system, in bytes
    usize freeBytes;  // free space, in bytes
    usize usedBytes;  // allocated space, in bytes
    usize usedCount;  // number of individual, active allocations
} PBMemGPAStats;
```

PBMemGPAStats describes info about the kPBMemGPA's state

### PBMemGPAGetStats

```c
void PBMemGPAGetStats(PBMem          m,
                      PBMemGPAStats* result);
```

PBMemGPAGetStats retrieves current stats of a GPA.

- `m`: Currently the only valid value is `kPBMemGPA`

---
`#include <playbit/mem_buf_allocator.h>`

### PBMemBufAllocator

```c
typedef struct PBMemBufAllocator {
    PBMemAllocator allocator;
    u8*            buf;
    usize          offs; // allocation offset, in bytes (i.e. memory allocated, in use)
    usize          cap;  // capacity of buf, in bytes
#if USIZE_MAX >= 0xffffffffffffffff
    usize lastSize : 56; // size in bytes of most recent allocation
    usize flags : 8;
#else
    usize lastSize;
    u8    flags;
#endif
} PBMemBufAllocator;
```

### PBMemBufAllocator_ZEROED

```c
const int PBMemBufAllocator_ZEROED = 1;
```

initial `buf` is zeroed


### PBMemBufAllocator_THREADSAFE

```c
const int PBMemBufAllocator_THREADSAFE = 2;
```

enable allocations across threads


### PBMemBufAllocatorInit

```c
PBMem PBMemBufAllocatorInit(PBMemBufAllocator* a,
                            void*              buf,
                            usize              bufCap,
                            u8                 flags);
```

PBMemBufAllocatorInit initializes `a` bump allocator on top of `buf`.

If address of `buf` is not aligned to PBMem_ALIGNMENT, the actual usable size may be smaller than `bufCap`.

`PBMemBufAllocator` is _not_ thread safe unless `PBMemBufAllocator_THREADSAFE` flag is set. If `PBMemBufAllocator_THREADSAFE` is set, only allocations are supported; resizing (realloc) will fail and free will have no effect.

- `bufCap`: must be at least PBMem_ALIGNMENT.
- Returns: `a` memory allocator handle which can be used with functions that allocate memory.

### PBMemBufAllocatorReset

```c
void PBMemBufAllocatorReset(PBMemBufAllocator* a);
```

PBMemBufAllocatorReset frees any and all allocations made in the allocator


### PBMemBufAllocatorScopeBegin

```c
usize PBMemBufAllocatorScopeBegin(PBMemBufAllocator* a);
```

PBMemBufAllocatorScopeBegin marks the beginning of `a` resumable state of the allocator. Any allocations made after `a` call to PBMemBufAllocatorScopeBegin are freed all at once by `a` matchin call to `PBMemBufAllocatorScopeEnd`.


### PBMemBufAllocatorScopeEnd

```c
void PBMemBufAllocatorScopeEnd(PBMemBufAllocator* a,
                               usize              scope);
```

`PBMemBufAllocatorScopeBegin` ends `a` region started by `PBMemBufAllocatorScopeBegin`

- `scope`: The value returned from `a` corresponding `PBMemBufAllocatorScopeBegin` call.

---
`#include <playbit/mem_null_allocator.h>`

### PBMemNullAllocator

```c
int PBMemNullAllocator();
```

PBMemNullAllocator always fails to allocate memory, intended to be used for testing

---
`#include <playbit/mem_zeroing_allocator.h>`

### PBMemZeroingAllocator

```c
typedef struct PBMemZeroingAllocator {
    PBMemAllocator ma;
    PBMem          source;
} PBMemZeroingAllocator;
```

PBMemZeroingAllocator wraps another allocator and sets the PBMem_ZERO flag for all allocations

### PBMemZeroingAllocatorImpl

```c
void* PBMemZeroingAllocatorImpl(PBMem  m,
                                void*  p,
                                usize* zp,
                                u32    fl);
```

PBMemZeroingAllocatorImpl forwards allocation to the wrapped source allocator and forces `PBMem_ZERO`.


### PBMemZeroingAllocatorInit

```c
PBMem PBMemZeroingAllocatorInit(PBMemZeroingAllocator* a,
                                PBMem                  source);
```

PBMemZeroingAllocatorInit initializes `a` `PBMemZeroingAllocator` wrapper and returns it as `PBMem`.

All allocations and reallocations performed through the returned allocator force `PBMem_ZERO`, regardless of caller flags.


### PBMemZeroingAllocatorWrap

```c
macro PBMem PBMemZeroingAllocatorWrap(PBMem sourceAllocator)
```

---
`#include <playbit/arena.h>`

`PBArena` is an arena allocator, useful for region-based memory management. It's a hybrid betwen a simple bump allocator and a chained-block allocator.

Example of basic use:

    // create an arena that sources memory blocks from the GPA
    PBArena* arena = PBArenaAlloc(.allocator = kPBMemGPA);
    int* array1 = PBArenaPush(arena, 4 * sizeof(int), alignof(int), 0);
    // free last 4*4 bytes allocated
    void PBArenaPop(arena, 4 * sizeof(int));
    int* array2 = PBArenaPush(arena, 4 * sizeof(int), alignof(int), 0);
    int* array3 = PBArenaPush(arena, 4 * sizeof(int), alignof(int), 0);
    // free all memory allocated:
    PBArenaReset(arena);
    // free the arena itself
    PBArenaFree(&arena);

Example use as a `PBMem` allocator:

    PBArena* arena = PBArenaAlloc(.allocator = kPBMemGPA);
    PBMem ma = PBMemFromArena(arena);
    SomeFunctionThatUsesPBMem(ma);
    // free all memory allocated with `ma`
    PBArenaFree(&arena);

Example of scoped allocations:

    PBArena* arena = PBArenaAlloc(.allocator = kPBMemGPA);
    u8* a = PBArenaPush(arena, 128, 1, 0);
    {
        PBArenaScope(arena);
        u8* b = PBArenaPush(arena, 128, 1, 0);
        expect(b == a);
        // all allocations made in this scope are freed when leaving
    }
    {
        PBArenaScope(arena);
        u8* b = PBArenaPush(arena, 128, 1, 0);
        expect(b == a);
    }
    PBArenaFree(&arena);

### PBArenaFlags

```c
typedef enum PBArenaFlags PB_ENUM_TYPE(u64){
    PBArenaFlag_NoChain = (1 << 0),
    PBArenaFlag_FixedBuffer = (1 << 1),
} PBArenaFlags;
```

### PBArena

```c
struct PBArena {
    // PBMem
    PBMemAllocator ma;

    // config
    PBMem        allocator;
    PBArenaFlags flags;

    // chains
    PBArena*          current;
    PBArena* nullable prev;
    usize             basePos;

    // arena state
    u8*   data;
    usize pos;
    usize size;

    // debug
    char* debugFile;
    int   debugLine;
};
```

### PBArenaParams

```c
struct PBArenaParams {
    // config
    PBMem        allocator;
    PBArenaFlags flags;
    usize        initialSize;
    void*        backingBuffer; // you must set initialSize if using!

    // debug
    char* debugFile;
    int   debugLine;
};
```

### PBArenaTemp

```c
struct PBArenaTemp {
    PBArena* arena;
    usize    pos;
};
```

### PBArena_HEADER_SIZE

```c
#define PBArena_HEADER_SIZE …
```

PBArena_HEADER_SIZE is the number of bytes of overhead per arena slab


### PBArenaAllocP

```c
PBArena* PBArenaAllocP(PBArenaParams params);
```

PBArenaAllocP creates an arena from `params`.

If `params`.backingBuffer is set, that memory is used as fixed backing storage.
Otherwise memory is allocated from `params`.allocator.

- Returns: NULL on invalid parameters or allocation failure.

### PBArenaAlloc

```c
macro PBArena* nullable PBArenaAlloc(.field = value ...)
```

creates an arena from params, a convenience wrapper for `PBArenaAllocP((PBArenaParams){ .field = value ... })`

- Returns: NULL on invalid parameters or allocation failure

### PBArenaFree

```c
void PBArenaFree(PBArena* arena);
```

PBArenaFree releases all memory owned by `*arena` and sets `*arena` to NULL.


### PBArenaFromBuffer

```c
PBArena* PBArenaFromBuffer(void* data,
                           usize size);
```

PBArenaFromBuffer creates an arena backed by caller-owned memory in `[data, data+size)`.


### PBArenaFromAllocator

```c
PBArena* PBArenaFromAllocator(PBMem allocator,
                              usize size);
```

PBArenaFromAllocator creates an arena that allocates slab memory from `allocator`.


### PBArenaPush

```c
void* PBArenaPush(PBArena* arena,
                  usize    size,
                  usize    align,
                  bool     zero);
```

PBArenaPush allocates `size` bytes from `arena` with alignment `align`.

If `zero` is true, returned bytes are `zero`-initialized.

- Returns: NULL if there is no room and `arena` growth is not possible.

### PBArenaPop

```c
void PBArenaPop(PBArena* arena,
                usize    size);
```

PBArenaPop releases the most-recent `size` bytes from `arena` state.


### PBArenaPopTo

```c
void PBArenaPopTo(PBArena* arena,
                  usize    pos);
```

PBArenaPopTo rewinds `arena` allocation position to absolute offset `pos`.


### PBArenaReset

```c
void PBArenaReset(PBArena* arena);
```

PBArenaReset rewinds `arena` to position 0, releasing all allocations.


### PBArenaPos

```c
usize PBArenaPos(const PBArena* arena);
```

PBArenaPos returns the current absolute allocation position.


### PBArenaSize

```c
usize PBArenaSize(const PBArena* arena);
```

PBArenaSize returns total bytes across all slabs currently attached to `arena`.


### PBArenaTempBegin

```c
PBArenaTemp PBArenaTempBegin(PBArena* arena);
```

PBArenaTempBegin snapshots current `arena` position for scoped rollback.


### PBArenaTempEnd

```c
void PBArenaTempEnd(PBArenaTemp temp);
```

PBArenaTempEnd rewinds arena to the position captured by `temp`.


### PBMemFromArena

```c
PBMem PBMemFromArena(PBArena* arena);
```

PBMemFromArena returns an allocator that can be used with anything that accepts `PBMem`


### PBArenaIsEmpty

```c
bool PBArenaIsEmpty(const PBArena* arena);
```

PBArenaIsEmpty reports whether `arena` has no usable backing storage. This is true for an `arena` initialized from a zero-sized buffer or after `PBArenaFree` has invalidated its slabs.


### PBArenaScope

```c
void PBArenaScope(PBArena* arena);
```

PBArenaScope brackets the current scope in `PBArenaTempBegin` and `PBArenaTempEnd` calls, effectively freeing any memory allocated in this `arena` during the span of the current scope.

# Playbit API reference

The Playbit networking APIs allow for communication between apps via Playbit's own data protocols and infrastructure. These APIs are currently available as a technical preview, and are not yet well suited for sensitive information as encryption is not yet implemented.

---
`#include <playbit/net.h>`

### PBNet

```c
typedef struct PBNet {
    PBSysHandle handle;
} PBNet;
```

PBNet is a general network capability

### PBNetSession

```c
typedef struct PBNetSession {
    PBSysHandle handle;
} PBNetSession;
```

PBNetSession is a Playbit network session

### PBNetTransport

```c
typedef struct PBNetTransport {
    PBSysHandle handle;
} PBNetTransport;
```

PBNetTransport represents a network connection

### PBNetTransportConfig

```c
typedef struct PBNetTransportConfig {
    /*
    idleTimeoutMs determines how long a connection may stay idle without I/O happening, in milliseconds. Once a connection has been idle for idleTimeoutMs, it's closed (assuming keep-alive is disabled.) A timeout of `0` means "default."
    */
    u32 idleTimeoutMs;

    PBSysNetTransportFlags flags;

    /*
    alpn is "Application-Layer Protocol Negotiation" for TLS and QUIC. A semicolon-separated ALPN list, in priority order.
    Required to be non-zero for QUIC.
    Currently only one ALPN is supported.
    */
    PBStrSlice alpn;

    // sni is "Server Name Indication" for TLS and QUIC
    PBStrSlice sni;

    // certPem is a PEM-encoded root certificate for TLS and QUIC peer verification
    PBU8Slice certPem;
} PBNetTransportConfig;
```

PBNetTransportConfig configures a PBNetTransport

### PBNetChannelOpenFlags

```c
typedef u64 PBNetChannelOpenFlags;
```

PBNetChannelOpenFlags are flags for PBNetChannelOpenEx

### PBNetChannelOpenFlag

```c
enum PBNetChannelOpenFlag PB_ENUM_TYPE(u64){
    /*
    PBNetChannelOpenFlag_SUBSCRIBE causes the PBNetChannel to automatically send SUBSCRIBE messages whenever the underlying access point connection is established, or re-established. If this flag is not set, nothing will be delivered to the opened PBNetChannel, until you send a SUBSCRIBE message yourself. Not setting this flag can be useful if you are only writing to a channel.
    */
    PBNetChannelOpenFlag_SUBSCRIBE = 1u << 0,

    /*
    PBNetChannelOpenFlag_TRACK_SUBSCRIBERS enables reception of SUBSCRIBE and UNSUBSCRIBE messages as other peers join and leave the channel. It can be used for participation discovery. PBNetChannelOpenFlag_SUBSCRIBE must be set if PBNetChannelOpenFlag_TRACK_SUBSCRIBERS is set.

    Corresponds to setting PBApFrameFlag_TRACK in the AP protocol on outgoing SUBSCRIBE message.
    */
    PBNetChannelOpenFlag_TRACK_SUBSCRIBERS = 1u << 1,
};
```

### PBNetChannelPublishFlags

```c
typedef u64 PBNetChannelPublishFlags;
```

PBNetChannelPublishFlags are flags for PBNetChannelPublishCommit et al

### PBNetChannelPublishFlag

```c
enum PBNetChannelPublishFlag PB_ENUM_TYPE(u64){
    /*
    PBNetChannelPublishFlag_ECHO makes the message delivered back to the sender, in addition to being sent to everyone else in a channel. It corresponds to PBApFrameFlag_ECHO in the AP protocol.
    */
    PBNetChannelPublishFlag_ECHO = 1u << 0,

    /*
    PBNetChannelPublishFlag_DEFER disables sending of the message on publish. Useful if you are sending many small messages in rapid succession: set PBNetChannelPublishFlag_DEFER for the first N-1 publish calls and don't set this flag for the last.

    Note that a call to PBNetChannelProcessIO will cause queued messages to be sent regardless of this flag, granted the underlying stream is writable.
    */
    PBNetChannelPublishFlag_DEFER = 1u << 1,
};
```

### PBNetChannelFrameType

```c
typedef enum PBNetChannelFrameType PB_ENUM_TYPE(u8){
    PBNetChannelFrameType_DIRECT = PBApFrameType_DIRECT,
    PBNetChannelFrameType_PUBLISH = PBApFrameType_PUBLISH,
    PBNetChannelFrameType_SUBSCRIBE = PBApFrameType_SUBSCRIBE,
    PBNetChannelFrameType_UNSUBSCRIBE = PBApFrameType_UNSUBSCRIBE,
    PBNetChannelFrameType_ERROR = PBApFrameType_ERROR,
    PBNetChannelFrameType_ERROR_CHAN = PBApFrameType_ERROR_CHAN,
    PBNetChannelFrameType_ERROR_SUB = PBApFrameType_ERROR_SUB,
    PBNetChannelFrameType_ERROR_PEER = PBApFrameType_ERROR_PEER,
    PBNetChannelFrameType_ERROR_DIRECT = PBApFrameType_ERROR_DIRECT,
} PBNetChannelFrameType;
```

PBNetChannelFrameType identifies frames delivered on a NetSession channel stream.

### PBNetChannelFrame

```c
typedef struct PBNetChannelFrame {
    u32                   bodyLen;     // Size of body in bytes.
    PBNetChannelFrameType type;        // Frame type.
    u8                    flags;       // Type-specific AP frame flags.
    u8                    senderIdLen; // Number of bytes at senderId.
    u8                    _reserved;
    const u8*             body;       // Pointer to the frame body. Always 16-byte aligned.
    u8                    senderId[]; // Sender peer ID bytes. May be empty.
} PBNetChannelFrame;
```

PBNetChannelFrame is a frame of information received via a PBNetChannel

### PBNetFeatures

```c
typedef struct {
    u64 bits;
} PBNetFeatures;
```

### PBNetDefault

```c
PBNet PBNetDefault();
```

PBNetDefault returns the default/initial network capability provided to the current thread when it was started.

Note: You can check `.handle == PBSysHandle_INVALID` on the return value to check if the current thread has a default network capability, or use PBExpectValidHandle to get a panic if not. All functions that take a `PBNet` as an argument will check its validity and panic if invalid, so for programs what want to simply crash if no networking is available, it's easier to just do no checking at all.


### PBNetSessionOpen

```c
PBSysErr PBNetSessionOpen(PBNet                        net,
                          PBNetSession*                netSession,
                          PBStrSlice                   sessionId,
                          const PBSysNetSessionConfig* config);
```

PBNetSessionOpen opens a logical Playbit network session.

A Playbit network session allows communication between multiple playbit programs participating in the same session. A session houses "channels" (see `PBNetChannelOpen` and PBNetChannel).

- `net`: Networking capability
- `netSession`: Session to initialize
- `sessionId`: Session identifier, unique within app-id namespace
- `config`: Optional configuration. Pass NULL for defaults.

### PBNetSessionClose

```c
PBSysErr PBNetSessionClose(PBNetSession* netSession);
```

PBNetSessionClose closes a network session


### PBNetChannelDirect

```c
PBSysErr PBNetChannelDirect(PBNetChannel* netChannel,
                            const u8*     dst,
                            u32           dstLen,
                            const u8*     body,
                            u32           bodyLen);
```

PBNetChannelDirect send a direct message to a peer in a session.


### PBNetChannelOpen

```c
PBSysErr PBNetChannelOpen(PBNetChannel*       netChannelOut,
                          const PBNetSession* netSession,
                          PBStrSlice          channelId,
                          PBMem               ma);
```

PBNetChannelOpen opens a stream to channel identified by `channelId`, and queues a SUBSCRIBE message.

PBNetChannelOpen is equivalent to calling `PBNetChannelOpenEx` with `PBNetChannelOpenFlag_SUBSCRIBE`.

- `netChannelOut`: Points to an open PBNetChannel on success
- `netSession`: The network session to open a channel in
- `channelId`: The identifier of the channel, unique within the session
- `ma`: Memory allocator to use for PBNetChannel and its resources. Must remain valid until `PBNetChannelClose` has been called.

### PBNetChannelOpenEx

```c
PBSysErr PBNetChannelOpenEx(PBNetChannel*         netChannelOut,
                            const PBNetSession*   netSession,
                            PBStrSlice            channelId,
                            PBMem                 ma,
                            PBNetChannelOpenFlags flags);
```

`PBNetChannelOpen` opens a stream to channel identified by `channelId`.

- `netChannelOut`: Points to an open PBNetChannel on success
- `netSession`: The network session to open a channel in
- `channelId`: The identifier of the channel, unique within the session
- `ma`: Memory allocator to use for PBNetChannel and its resources. Must remain valid until `PBNetChannelClose` has been called.
- `flags`: Customizes behavior. See `PBNetChannelOpenFlags`

### PBNetChannelClose

```c
void PBNetChannelClose(PBNetChannel* netChannel);
```

PBNetChannelClose closes the underlying stream, frees buffers owned by `netChannel`, and frees the channel object itself. The caller should discard any saved pointer after calling.


### PBNetChannelHandle

```c
PBSysHandle PBNetChannelHandle(const PBNetChannel* netChannel);
```

PBNetChannelHandle returns the underlying stream handle for a channel


### PBNetChannelPublish

```c
PBSysErr PBNetChannelPublish(PBNetChannel* netChannel,
                             const u8*     body,
                             u32           bodyLen);
```

PBNetChannelPublish queues one complete PUBLISH frame by copying `body` into an internal buffer.

Equivalent to calling `PBNetChannelPublishBegin` with `0` flags, copying `body` and then calling `PBNetChannelPublishCommit` with `0` flags.

- Returns: `PBSysErr_TOO_LARGE` if `bodyLen` is too large, as limited by `PBNetChannelSetSendLimit`

### PBNetChannelPublishEx

```c
PBSysErr PBNetChannelPublishEx(PBNetChannel*            netChannel,
                               const u8*                body,
                               u32                      bodyLen,
                               PBNetChannelPublishFlags flags);
```

PBNetChannelPublishEx queues one complete PUBLISH frame with explicit AP frame `flags`.

Equivalent to calling `PBNetChannelPublishBegin` with `flags`, copying `body` and then calling `PBNetChannelPublishCommit` with `flags`.

- Returns: `PBSysErr_TOO_LARGE` if `bodyLen` is too large, as limited by `PBNetChannelSetSendLimit`

### PBNetChannelPublishBegin

```c
PBSysErr PBNetChannelPublishBegin(PBNetChannel*            netChannel,
                                  u32                      bodyLen,
                                  u8*                      bodyOut,
                                  PBNetChannelPublishFlags flags);
```

PBNetChannelPublishBegin allocates one outgoing PUBLISH frame.

On success, reserves space in the send buffer, stores the body pointer in `bodyOut`, and expects a matching call to `PBNetChannelPublishCommit`.

- `bodyOut`: On success, `*bodyOut` is set to a pointer into an internal buffer of at least `bodyLen` size, with at least 16 byte address alignment. The pointer remains valid until `PBNetChannelPublishCommit` is called.
- Returns: `PBSysErr_TOO_LARGE` if `bodyLen` is too large, as limited by `PBNetChannelSetSendLimit`

### PBNetChannelPublishCommit

```c
PBSysErr PBNetChannelPublishCommit(PBNetChannel*            netChannel,
                                   u8*                      body,
                                   PBNetChannelPublishFlags flags);
```

PBNetChannelPublishCommit commits a draft PUBLISH frame previously started with `PBNetChannelPublishBegin`.

- `body`: Must be the exact pointer returned from the begin call

### PBNetChannelProcessIO

```c
PBSysErr PBNetChannelProcessIO(PBNetChannel*      netChannel,
                               PBSysSignals       signals,
                               PBNetChannelFrame* frameOut);
```

PBNetChannelProcessIO processes stream IO for a channel.

- `signals`: Current stream `signals` from a `PBEventType_SIGNAL` event, but 0 is also valid and still allows flushing of buffered outgoing data.
- Returns: On success, *frameOut is set to NULL if no complete frame is ready yet, or to a frame pointer owned by `netChannel` if one frame was decoded. The returned frame remains valid until `PBNetChannelReleaseFrame` is called.

### PBNetChannelReleaseFrame

```c
void PBNetChannelReleaseFrame(PBNetChannel*      netChannel,
                              PBNetChannelFrame* frame);
```

PBNetChannelReleaseFrame releases a `frame` previously returned by `PBNetChannelProcessIO`. Frames must be released in the order they were received.


### PBNetChannelRecvDiscardCount

```c
u32 PBNetChannelRecvDiscardCount(const PBNetChannel* netChannel);
```

PBNetChannelRecvDiscardCount returns the number of received messages which were discarded because they exceeded size limit set by `PBNetChannelSetRecvLimit`


### PBNetChannelSetRecvLimit

```c
u32 PBNetChannelSetRecvLimit(PBNetChannel* netChannel,
                             u32           nbytes);
```

PBNetChannelSetRecvLimit limits the size of received messages (body, not including protocol header.)

- `nbytes`: Max number of bytes to allow receiving.
- Returns: Previous limit

### PBNetChannelSetSendLimit

```c
u32 PBNetChannelSetSendLimit(PBNetChannel* netChannel,
                             u32           nbytes);
```

PBNetChannelSetSendLimit limits the size of published messages (body, not including protocol header.)

- `nbytes`: Max number of bytes per published message

### PBNetTransportOpen

```c
PBNetTransport PBNetTransportOpen(PBNet                       net,
                                  PBStrSlice                  uri,
                                  const PBNetTransportConfig* config);
```

PBNetTransportOpen opens a network transport (like a connection) to the named URI. See `PBNetTransportOpenEx` for more information.

This is a convenience function for the following:

    PBNetTransport transport;
    PanicOnErr(PBNetTransportOpenEx(net, &transport, uri, config));


### PBNetTransportOpenStream

```c
PBStream PBNetTransportOpenStream(PBNetTransport* transport);
```

PBNetTransportOpenStream opens a bidirectional stream within `transport`. See `PBNetTransportOpenStreamEx` for more information.

This is a convenience function for the following:

    PBStream stream;
    PanicOnErr(PBNetTransportOpenStreamEx(transport, &stream, PBSysNetTransportStream_RW));


### PBNetTransportOpenEx

```c
PBSysErr PBNetTransportOpenEx(PBNet                       net,
                              PBNetTransport*             transportOut,
                              PBStrSlice                  uri,
                              const PBNetTransportConfig* config);
```

PBNetTransportOpenEx opens a network transport (like a connection) to the named URI.

URIs have the form `protocol:node`, i.e.

quic:host:port QUIC transport
tcp:host:port  TCP/IP socket
udp:host:port  UDP/IP socket

The underlying implementation may not support the requested protocol.

For `quic:` URIs, `config->alpn` is required. ALPN is a semicolon-separated list in priority order; currently only one ALPN is supported. When `config->sni` is empty, SNI defaults to the URI host.


### PBNetTransportOpenStreamEx

```c
PBSysErr PBNetTransportOpenStreamEx(PBNetTransport*              transport,
                                    PBStream*                    streamOut,
                                    PBSysNetTransportStreamFlags flags);
```

PBNetTransportOpenStreamEx opens a stream within `transport`.

- `flags`: dictates how the stream may be used

### PBNetTransportSetKeepAlive

```c
void PBNetTransportSetKeepAlive(PBNetTransport* transport,
                                PBTimeDuration  interval);
```

PBNetTransportSetKeepAlive configures a `transport`'s keep-alive `interval`. When keep-alive is enabled, a `transport` stays open even across long periods of no I/O. When keep-alive is disabled, a `transport` connection closes after idleTimeoutMs (as configured by `PBSysNetTransportConfig`.)

Setting `interval` to a negative value means "enable keep-alive with implemention-default interval" while setting `interval` to 0 means "disable keep-alive."

Keep-alive is disabled by default.

- `interval`: How long between keep-alive pings

### PBNetFeaturesGet

```c
PBNetFeatures PBNetFeaturesGet(PBNet net);
```

PBNetFeaturesGet returns a bitmap describing what features are available for `net`. Use `PBNetFeaturesCheck` to check for a single feature or mask with bits of `PBSysNetFeature`.


### PBNetFeaturesCheck

```c
bool PBNetFeaturesCheck(PBNetFeatures   features,
                        PBSysNetFeature feature);
```

PBNetFeaturesCheck returns true if `feature` is true in `features` bitmap


### PBNetHasFeature

```c
bool PBNetHasFeature(PBSysNetFeature feature);
```

PBNetHasFeature returns true if `feature` is available for `net`. This is a convenience function and is equivalent to the following:

```c
bool PBNetHasFeature(PBSysNetFeature feature) {
    PBNet net = PBNetDefault();
    return net.handle > 0 &&
           PBNetFeaturesCheck(PBNetFeaturesGet(net), feature);
}
```

---
`#include <playbit/ap.h>`

Playbit Access Point protocol

### PBApFrameType

```c
typedef enum PBApFrameType PB_ENUM_TYPE(u8){
    PBApFrameType_HELLO = 0,          // 'src' is peer ID on recv, body=auth_tok
    PBApFrameType_REGISTER = 1,       // 'flags' holds APRegisterResStatus
    PBApFrameType_DIRECT = 2,         // 'dst' is peer ID,    'flags' is unused
    PBApFrameType_PUBLISH = 3,        // 'dst' is channel ID, 'flags' may have ECHO
    PBApFrameType_SUBSCRIBE = 4,      // 'dst' is channel ID, 'flags' may have TRACK
    PBApFrameType_UNSUBSCRIBE = 5,    // 'dst' is channel ID, 'flags' is unused
    PBApFrameType_ERROR = 200,        // generic error (text description in data)
    PBApFrameType_ERROR_CHAN = 201,   // operation on non-existing channel
    PBApFrameType_ERROR_SUB = 202,    // already subscribed or not subscribed
    PBApFrameType_ERROR_PEER = 203,   // no route to peer
    PBApFrameType_ERROR_DIRECT = 204, // failed to deliver direct message
} PBApFrameType;
```

### PBApFrameFlags

```c
typedef u8 PBApFrameFlags;
```

### PBApFrameFlag

```c
enum PBApFrameFlag PB_ENUM_TYPE(u8){
    PBApFrameFlag_ECHO = 1u << 0,
    PBApFrameFlag_TRACK = 1u << 0,
};
```

### PBApFrameHeaderSize

```c
const int PBApFrameHeaderSize = 8;
```


### PBApFrameBodyAlign

```c
const int PBApFrameBodyAlign = 16;
```

---
`#include <playbit/multiplayer.h>`

### PBMPModType

```c
typedef enum PBMPModType : uint8_t {
    PBMPModType_NOP,
    PBMPModType_SET,
    PBMPModType_ADD,
    PBMPModType_INSERT,
    PBMPModType_REMOVE,
    PBMPModType_RANGE,
    PBMPModType_MAP,
    PBMPModType_FINALIZE,
    PBMPModType_UNMAP,
} PBMPModType;
```

### PBMPRange

```c
typedef struct PBMPRange {
    uint32_t offset;
    uint32_t count;
    uint16_t key;
    uint16_t reserved;
    uint32_t dataLen;
    void* _Nullable data;
} PBMPRange;
```

### PBMPUUID

```c
typedef struct PBMPUUID {
    uint64_t p0;
    uint64_t p1;
} PBMPUUID;
```

### PBMPSyncStatus

```c
typedef enum PBMPSyncStatus {
    PBMPSyncStatus_NOT_SUBSCRIBED,
    PBMPSyncStatus_OFFLINE,
    PBMPSyncStatus_UP_TO_DATE,
    PBMPSyncStatus_UPLOADING,
    PBMPSyncStatus_DOWNLOADING,
} PBMPSyncStatus;
```

### PBMPDoc

```c
typedef struct PBMPDoc PBMPDoc;
```

### PBMPObject

```c
typedef struct PBMPObject PBMPObject;
```

### PBMPDocCreate2

```c
PBMPDoc* PBMPDocCreate2(u32 schemaVersion);
```

Documents:


### PBMPDocOpen2

```c
PBMPDoc* PBMPDocOpen2(PBMPUUID uuid,
                      PBMPUUID key,
                      u32      schemaVersion);
```


### PBMPDocGetUUID

```c
PBMPUUID PBMPDocGetUUID(PBMPDoc* doc);
```


### PBMPDocGetKey

```c
PBMPUUID PBMPDocGetKey(PBMPDoc* doc);
```


### PBMPDocDestroy

```c
void PBMPDocDestroy(PBMPDoc* doc);
```


### PBMPUUIDGenerate

```c
PBMPUUID PBMPUUIDGenerate(PBMPDoc* doc);
```


### PBMPRootObject

```c
PBMPObject* PBMPRootObject(PBMPDoc* doc);
```


### PBMPObjectLookup

```c
PBMPObject* PBMPObjectLookup(PBMPDoc* doc,
                             PBMPUUID uuid);
```


### PBMPObjectLookupChild

```c
PBMPObject* PBMPObjectLookupChild(PBMPObject* object,
                                  PBMPUUID    uuid);
```


### PBMPGetObjectUUID

```c
PBMPUUID PBMPGetObjectUUID(PBMPObject* object);
```


### PBMPDocDoneFirstImport

```c
bool PBMPDocDoneFirstImport(PBMPDoc* doc);
```


### PBMPGetDataSize

```c
u32 PBMPGetDataSize(PBMPObject* object);
```

Objects:


### PBMPGetDataPtr

```c
const u8* PBMPGetDataPtr(PBMPObject* object);
```


### PBMPGetRanges

```c
const PBMPRange* PBMPGetRanges(PBMPObject* object,
                               usize*      count);
```


### PBMPWriteData

```c
void PBMPWriteData(PBMPObject* object,
                   u32         offset,
                   const void* bytes,
                   usize       byteCount,
                   PBMPModType type);
```


### PBMPRemoveData

```c
void PBMPRemoveData(PBMPObject* object,
                    u32         offset,
                    u32         byteCount);
```

SET, ADD or INSERT


### PBMPAddRange

```c
void PBMPAddRange(PBMPObject* object,
                  u32         offset,
                  u32         byteCount,
                  u16         key,
                  const void* data,
                  usize       dataLen);
```


### PBMPWriteNew

```c
PBMPObject* PBMPWriteNew(PBMPObject* object,
                         u32         offset,
                         bool        link,
                         bool        insert);
```


### PBMPMapNew

```c
PBMPObject* PBMPMapNew(PBMPObject* object,
                       PBStrSlice  string,
                       bool        link);
```


### PBMPMapLookup

```c
PBMPObject* PBMPMapLookup(PBMPObject* object,
                          PBStrSlice  string);
```


### PBMPMapRemove

```c
void PBMPMapRemove(PBMPObject* object,
                   PBStrSlice  string);
```


### PBMPMapSetLock

```c
void PBMPMapSetLock(PBMPObject* object,
                    bool        lock);
```


### PBMPMapIterate

```c
PBMPObject* PBMPMapIterate(PBMPObject* object,
                           PBStrSlice* key,
                           uintptr_t*  position);
```


### PBMPModHook

```c
typedef void (*PBMPModHook)(PBMPObject * _Nonnull, uint32_t, uint32_t, PBMPModType, const uint8_t * _Nullable, void * _Nullable);
```

### PBMPAddModHook

```c
void PBMPAddModHook(PBMPObject* object,
                    PBMPModHook hook,
                    void*       contextPtr);
```


### PBMPRemoveModHook

```c
void PBMPRemoveModHook(PBMPObject* object,
                       PBMPModHook hook,
                       void*       contextPtr);
```


### PBMPMarkObject

```c
bool PBMPMarkObject(PBMPObject* object);
```


### PBMPSweepObjects

```c
void PBMPSweepObjects(PBMPDoc* doc);
```


### PBMPGetAndClearHasChangedFlag

```c
bool PBMPGetAndClearHasChangedFlag(PBMPDoc* doc);
```

Serialization:


### PBMPSerializeHistory

```c
void* PBMPSerializeHistory(PBMPDoc* doc,
                           usize*   mark,
                           usize*   len,
                           u32      flags);
```


### PBMPSerializeAll

```c
void* PBMPSerializeAll(PBMPDoc* doc,
                       usize*   len);
```


### PBMPSerializeHead

```c
void* PBMPSerializeHead(PBMPDoc* doc,
                        usize*   len);
```

out


### PBMPImport_REQUIRE_ENCRYPTION

```c
#define PBMPImport_REQUIRE_ENCRYPTION(1 << 0)
```

out


### PBMPImport

```c
bool PBMPImport(PBMPDoc*    doc,
                const void* ptr,
                usize       len,
                u32         flags);
```


### PBMPDone

```c
void PBMPDone(void* ptr);
```


### PBStrSlice_dump_json

```c
void PBStrSlice_dump_json(PBStrSlice  p,
                          int         depth,
                          const void* write,
                          void*       context);
```

Data JSON/serialize/deserialize helpers:


### PBStrSlice_serialize

```c
void PBStrSlice_serialize(PBStrSlice p,
                          void*      write,
                          void*      context);
```


### PBU8Slice_dump_json

```c
void PBU8Slice_dump_json(PBU8Slice   p,
                         int         depth,
                         const void* write,
                         void*       context);
```


### PBU8Slice_serialize

```c
void PBU8Slice_serialize(PBU8Slice p,
                         void*     write,
                         void*     context);
```


### PBMPSubscribe

```c
void PBMPSubscribe(PBMPDoc* doc,
                   void*    reconnectDataPtr,
                   usize    reconnectDataLen);
```

Networking:


### PBMPUnsubscribe

```c
void PBMPUnsubscribe(PBMPDoc* doc);
```


### PBMPGetSyncStatus

```c
PBMPSyncStatus PBMPGetSyncStatus(PBMPDoc* doc);
```


### PBMPSerializeReconnectData

```c
void* PBMPSerializeReconnectData(PBMPDoc* doc,
                                 usize*   len);
```


### PBMPOnSignalEvent

```c
void PBMPOnSignalEvent(i32 handle,
                       u32 signals);
```

out


### PBMPOnTimer

```c
void PBMPOnTimer();
```


### PBMPRelayChanges

```c
void PBMPRelayChanges();
```


### PBMPSetSimulateOffline

```c
void PBMPSetSimulateOffline(bool simulateOffline);
```


### PBMPNetChannelOpenAssociated

```c
PBSysErr PBMPNetChannelOpenAssociated(PBNetChannel* outChannel,
                                      PBMPDoc*      doc,
                                      PBStrSlice    name);
```

Open an network channel associted with the document, keyed by the provided `name` string.
Close with `PBNetChannelClose` as usual.


### PBMPNetChannelOpenAssociatedEx

```c
PBSysErr PBMPNetChannelOpenAssociatedEx(PBNetChannel* outChannel,
                                        PBMPDoc*      doc,
                                        PBStrSlice    name,
                                        u64           flags);
```

Like `PBMPNetChannelOpenAssociated`, but with explicit `PBNetChannelOpenFlags`
(e.g. `PBNetChannelOpenFlag_TRACK_SUBSCRIBERS` for participant discovery).

# Playbit API reference

Threads provide both a security boundary—isolation from effects—and parallelism.

All programs start with a single thread; the "main thread" which is given initial capabilities by the system, like a GUI window, access to a console for logging etc. The main thread may then spawn any number of additional threads, which can be limited to just some capabilities ([handles and rights](../../runtime/capabilities.md))

Simple example of spawning a second thread:

```c
#include <playbit/playbit.h>

void bg_thread(u64 arg) {
    log("Hello from bg_thread");
}

void main() {
    PBThread thread = PBOptOk(PBThreadStart(bg_thread, 0, NULL));
    log("thread #%d started", thread.handle);
}
```

---
`#include <playbit/thread.h>`

### PBThread

```c
typedef struct {
    PBSysHandle handle;
} PBThread;
```

### PBThreadOpt

```c
typedef PBOpt(PBThread) PBThreadOpt;
```

### PBThreadConfig

```c
typedef struct PBThreadConfig {
    PBThread parentThread; // defaults to PBThread_SELF if zero
    u64      flags;

    /*
    rights for the thread itself.
    Usually you want PBSysRight_SAME_RIGHTS. 0 means "no rights."
    */
    PBSysRights rights;

    void* nullable stack;
    u32            stackSize;

    u32                         transferHandlesCount;
    const PBSysHandle* nullable transferHandles;
} PBThreadConfig;
```

PBThreadConfig describes the configuration of a new thread

### PBThreadFeatures

```c
typedef struct {
    u64 bits;
} PBThreadFeatures;
```

### PBThreadFn

```c
typedef void (*PBThreadFn)(u64);
```

PBThreadFn is the thread entry point function

### PBProcessStart

```c
void PBProcessStart(void* mainFn,
                    u64   flags);
```

PBProcessStart starts the main function. `flags` are bits of PBSysThread_


### PBThreadStart

```c
PBThreadOpt PBThreadStart(PBThreadFn            arg,
                          u64                   arg,
                          const PBThreadConfig* config);
```

PBThreadStart starts a new thread


### PBThreadExit

```c
PBSysErr PBThreadExit(PBThread thread,
                      int      status);
```

`PBExit` terminates the `thread`. If this is called on the main `thread`, the process is terminated as an effect.


### PBExit

```c
PBSysErr PBExit(int status);
```

PBExit terminates the calling thread.
If this is called on the main thread, the process is terminated as an effect.


### PBExitProcess

```c
PBSysErr PBExitProcess(int status);
```

PBExitProcess terminates the current process.
Fails with `PBSysErr_ACCESS_DENIED` if the calling thread's `PBSysHandle_SELF_THREAD` does not have `PBSysRight_MANAGE_PROCESS`.


### PBThreadFeaturesGet

```c
PBThreadFeatures PBThreadFeaturesGet(PBThread thread);
```

PBThreadFeaturesGet returns a bitmap describing what features are available for `thread`. Use `PBThreadFeaturesCheck` to check for a single feature or mask with bits of `PBSysThreadFeature`.


### PBThreadFeaturesCheck

```c
bool PBThreadFeaturesCheck(PBThreadFeatures   features,
                           PBSysThreadFeature feature);
```

PBThreadFeaturesCheck returns true if `feature` is true in `features` bitmap


### PBThreadHasFeature

```c
bool PBThreadHasFeature(PBThread           thread,
                        PBSysThreadFeature feature);
```

PBThreadHasFeature returns true if `feature` is available for `thread`. This is a convenience function and is equivalent to the following:

```c
bool PBThreadHasFeature(PBThread thread, PBSysThreadFeature feature) {
    return thread.handle > 0 &&
           PBThreadFeaturesCheck(PBThreadFeaturesGet(thread), feature);
}
```


### PBThreadCanExit

```c
bool PBThreadCanExit(PBThread thread);
```

PBThreadCanExit returns true if `PBThreadExit` can be called on `thread` to terminate it.


### PBCallCtors

```c
#define PBCallCtors()
```

        PBCallCtors invokes wasm constructor list for builds without libc startup.


### PB_C_START_ATTR

```c
#define PB_C_START_ATTR attribute
```

    PB_C_START_ATTR defines attributes for the _start function, the program's entry point.
    This is only needed when no libc (crt, really) is used.


### PB_START_WITHOUT_GUI

```c
#define PB_START_WITHOUT_GUI …
```

PB_START_WITHOUT_GUI defines a _start function which sets `PBSysThread_NOGUI`


### PBSetupInitialHandles

```c
void PBSetupInitialHandles();
```

PBSetupInitialHandles sets up internal knowledge of what handles a thread is given at start

---
`#include <playbit/mutex.h>`

### PBMutex

```c
typedef struct PBMutex {
    _Atomic(u32) state;
} PBMutex;
```

PBMutex is a reader/writer mutual exclusion lock.

The lock can be held by up to 2^31-1 readers or by a single writer. The high bit is used as a "writer pending/active" flag, so the zero-initialized value for a PBMutex is a valid, unlocked mutex.

PBMutex is not re-entrant. In particular, a thread must not try to take a read lock recursively while a writer is waiting, since the pending writer bit blocks new readers until the writer runs.

Memory model: The N`th call to PBMutexUnlock "happens before" the M`th call to PBMutexLock for any N < M. For any call to PBMutexRLock, there exists an N such that the N`th call to PBMutexUnlock "happens before" that call to PBMutexRLock, and the corresponding call to PBMutexRUnlock "happens before" the N+1`th call to PBMutexUnlock.

In other words: There's no need to use atomic instructions for shared data guarded by a PBMutex.

### PBMutexInit

```c
void PBMutexInit(PBMutex* mu);
```

PBMutexInit initializes `mu` to an unlocked state with zero readers and no writer.


### PBMutexRLock

```c
void PBMutexRLock(PBMutex* mu);
```

PBMutexRLock acquires a shared read lock.


### PBMutexRUnlock

```c
void PBMutexRUnlock(PBMutex* mu);
```

PBMutexRUnlock releases a shared read lock.


### PBMutexLock

```c
void PBMutexLock(PBMutex* mu);
```

PBMutexLock acquires an exclusive write lock.


### PBMutexUnlock

```c
void PBMutexUnlock(PBMutex* mu);
```

PBMutexUnlock releases an exclusive write lock.


### PBMutexIsLocked

```c
bool PBMutexIsLocked(const PBMutex* mu);
```

PBMutexIsLocked returns true if the mutex is write locked at the time of the call


### PBMutexIsRLocked

```c
bool PBMutexIsRLocked(const PBMutex* mu);
```

`PBMutexIsLocked` returns true if the mutex is read locked at the time of the call


### PBMutexLockInScope

```c
macro void PBMutexLockInScope(PBMutex* mu)
```

PBMutexLockInScope locks a mutex for the duration of the current scope.
I.e.
void example(`PBMutex`* mu1, `PBMutex`* mu2) {
PBMutexLockInScope(mu1);
// mu1 locked until function returns
{
PBMutexLockInScope(mu2);
// mu2 locked until this scope ends
} // mu2 unlocked
} // mu1 unlocked


### PBMutexRLockInScope

```c
macro void PBMutexRLockInScope(PBMutex* mu)
```

---
`#include <playbit/semaphore.h>`

### PBSemaphore

```c
typedef struct PBSemaphore {
    _Atomic(u32) state;
} PBSemaphore;
```

PBSemaphore is a counting semaphore.

The zero-initialized value for a PBSemaphore is valid and has count 0.

PBSemaphoreWait blocks until the count is nonzero, then consumes one permit.
PBSemaphoreSignal adds count permits and releases up to count waiters.

Example:

    static PBSemaphore workReady = { 0 };

    void worker(void) {
        PBSemaphoreWait(&workReady);
        process_work();
    }

    void queue_work(void) {
        add_work();
        PBSemaphoreSignal(&workReady, 1);
    }

### PBSemaphoreInit

```c
void PBSemaphoreInit(PBSemaphore* sem,
                     u32          initCount);
```

PBSemaphoreInit initializes `sem` with `initCount` permits.

Note: While U32_MAX is allowed for `initCount`, any later signal would overflow (and panic.)

- `sem`: Semaphore to initialize
- `initCount`: Initial permit count

### PBSemaphoreWait

```c
void PBSemaphoreWait(PBSemaphore* sem);
```

PBSemaphoreWait blocks until one permit is available, then consumes it.

The successful wait has acquire semantics and synchronizes with a prior `PBSemaphoreSignal` that made the consumed permit available.

- `sem`: Semaphore to wait on

### PBSemaphoreSignal

```c
void PBSemaphoreSignal(PBSemaphore* sem,
                       u32          count);
```

PBSemaphoreSignal adds `count` permits and releases up to `count` waiters.

The signal has release semantics. Passing `count` 0 is a no-op.
This function fails fast if adding `count` would overflow the 32-bit permit `count`.

- `sem`: Semaphore to signal
- `count`: Number of permits to add; maximum number of waiting threads to unblock.

### PBSemaphoreValue

```c
u32 PBSemaphoreValue(const PBSemaphore* sem);
```

PBSemaphoreValue returns a best-effort count snapshot for diagnostics and tests.

The returned value is not a synchronization primitive and may be stale immediately.

- `sem`: Semaphore to inspect
- Returns: Observed permit count at the time of the atomic load.

# Playbit API reference

- `PBDate` represents a point in _calendar time_ and time zone, for example 2026-03-12 16:37:07 PDT. `PBDateNow` returns the current date-and-time and `PBDateFmt` creates string representations.
- `PBTime` represents a point in _system time_; a high-resolution timestamp that is monotonically incrementing, used for timing (timers, duration calculations, etc.) `PBTimeNow` returns the current system time.
- `PBTimeDuration` describes a duration of time, like 134ms. `PBTimeDurationFormat` can be used to format a human-readable string like "1.2h".

---
`#include <playbit/date.h>`

### PBDate

```c
typedef struct PBDate {
    PBSysDate  timestamp; // microseconds since 1970-01-01 00:00:00 UTC
    PBTimeZone timeZone;
} PBDate;
```

PBDate represents a point in "real" time (microseconds since 1970-01-01 00:00:00 UTC.)
Range limit: [290309 BCE, Dec 22, 19:59:05 UTC - 294247, Jan 10, 04:00:54 UTC]

### PBCalendar

```c
typedef enum PBCalendar {
    PBCalendar_GREGORIAN,
} PBCalendar;
```

PBCalendar identifies a calendar system.

### PBDateComponents

```c
typedef struct PBDateComponents {
    i32  year;       // e.g. 2026
    u8   month;      // [0-11] 0=January ... 11=December
    bool leapMonth;  // if this month is a leap month or not
    u8   week;       // [0-52]
    u8   day;        // [0-30] 0=first day of month
    u8   weekday;    // [0-6] 0=Sunday ... 6=Saturday
    u8   hour;       // [0-23] e.g. 14
    u8   minute;     // [0-59]
    u8   second;     // [0-59]
    u32  nanosecond; // [0-999999000] remainder of time, not total
} PBDateComponents;
```

### PBDateFormatLayout

```c
typedef enum PBDateFormatLayout {
    PBDateFormatLayout_DEFAULT,   // "2006-01-02 15:04:05 EDT"
    PBDateFormatLayout_DATE_TIME, // "2006-01-02 15:04:05"
    PBDateFormatLayout_DATE,      // "2006-01-02"
    PBDateFormatLayout_TIME,      // "15:04:05"
    PBDateFormatLayout_STAMP,     // "Jan 2 15:04:05.123456"
} PBDateFormatLayout;
```

### PBDateNow

```c
PBDate PBDateNow();
```

PBDateNow returns the current time


### PBDateFormat

```c
usize PBDateFormat(PBDate             date,
                   PBDateFormatLayout layout,
                   char*              buf,
                   usize              bufCap);
```

PBDateFormat writes a string representation of `date` to `buf` with the given `layout`.

- `bufCap`: is the capacity of `buf`
- Returns: the number of bytes that would have been written to `buf`, excluding a NUL terminator, as if `bufCap` was infinite.

### PBDateComponentsOf

```c
PBDateComponents PBDateComponentsOf(PBDate     date,
                                    PBCalendar calendar);
```

PBDateComponentsOf returns components of a `date` interpreted in `calendar`


### PBSysDateMake

```c
PBSysDate PBSysDateMake(i32 year,
                        u32 month,
                        u32 day,
                        u32 hour,
                        u32 minute,
                        u32 second);
```

PBSysDateMake constructs a `PBSysDate` timestamp from components, in UTC.


### PBSystemClock

```c
PBSysHandle PBSystemClock();
```

PBSystemClock returns the handle to the system clock (`PBSysHandle_INVALID` if none)

---
`#include <playbit/timezone.h>`

### PBTimeZone

```c
typedef struct PBTimeZone {
    u32 id;
} PBTimeZone;
```

### PBTimeZoneOfName

```c
PBTimeZone PBTimeZoneOfName(const char* name);
```

PBTimeZoneOfName returns a `PBTimeZone` for the time zone named by IANA identifier `name`.

- Returns: PBTimeZone_NONE if the `name` is invalid or unknown.

### PBTimeZoneDefault

```c
PBTimeZone PBTimeZoneDefault();
```

PBTimeZoneDefault returns the current default (system) time zone.


### PBTimeZoneSetDefault

```c
void PBTimeZoneSetDefault(PBTimeZone tz);
```

PBTimeZoneSetDefault sets the time zone that is used for new `PBDate` values, i.e. from calling `PBDateNow`. If you pass PBTimeZone_NONE, the host system's time zone will be used, effectively "clearing an override."


### PBTimeZoneSetDefaultFromSystem

```c
void PBTimeZoneSetDefaultFromSystem();
```

PBTimeZoneSetDefaultFromSystem sets the time zone that is used for new `PBDate` values by asking the system what the user's current time zone is.


### PBTimeZoneUTCOffset

```c
i64 PBTimeZoneUTCOffset(PBTimeZone tz);
```

PBTimeZoneUTCOffset returns the standard (non-DST) offset in seconds from UTC.


### PBTimeZoneUTCOffset2

```c
i64 PBTimeZoneUTCOffset2(PBTimeZone tz,
                         PBSysDate  timestamp);
```

`PBTimeZoneUTCOffset` returns the standard offset in seconds from UTC, accounting for DST.


### PBTimeZoneDSTOffset

```c
i64 PBTimeZoneDSTOffset(PBTimeZone tz,
                        PBSysDate  timestamp);
```

PBTimeZoneDSTOffset returns the daylight-savings time offset for the specified UTC `timestamp`


### PBTimeZoneName

```c
const char* PBTimeZoneName(PBTimeZone tz);
```

PBTimeZoneName returns the IANA identifier ("" for `tz`=PBTimeZone_NONE)


### PBTimeZoneShortName

```c
const char* PBTimeZoneShortName(PBTimeZone tz);
```

PBTimeZoneShortName returns an abbreviated name, e.g. "EDT" (Eastern Daylight Time.)


### PBTimeZoneShortNameAt

```c
const char* PBTimeZoneShortNameAt(PBTimeZone tz,
                                  PBSysDate  timestamp);
```

PBTimeZoneShortNameAt returns an abbreviated name at the specified UTC `timestamp`

---
`#include <playbit/time.h>`

### PBTime

```c
typedef u64 PBTime;
```

PBTime is a monotonic clock value; a specific point in time.

Can be used with `PB_TIME_` constants to calculate other values, for example:

    PBTime value = PBTimeNow();
    value + 100*PB_TIME_MILLISECOND; // 100ms in the future
    value - 2*PB_TIME_HOUR;          // 2 hours in the past

### PBTimeDuration

```c
typedef i64 PBTimeDuration;
```

PBTimeDuration describes a duration of time, like 134ms or -1.2h

Can be used with `PB_TIME_` constants to calculate other values, for example:

    PBTimeDuration td = 72 * PB_TIME_HOUR;
    td + 100*PB_TIME_MILLISECOND; // 100ms later
    td - 2*PB_TIME_HOUR;          // 2 hours sooner

    // convert to hours
    td / PB_TIME_HOUR;                    // truncation
    (td + PB_TIME_HOUR/2) / PB_TIME_HOUR; // integer round-to-nearest
    (i64)((f64)td / (f64)PB_TIME_HOUR)    // IEEE-754 round-to-nearest
    (f64)td / (f64)PB_TIME_HOUR;

### PB_TIME_HOUR

```c
const PBTimeDuration PB_TIME_HOUR = 3600000000000;
```


### PB_TIME_MINUTE

```c
const PBTimeDuration PB_TIME_MINUTE = 60000000000;
```


### PB_TIME_SECOND

```c
const PBTimeDuration PB_TIME_SECOND = 1000000000;
```


### PB_TIME_MILLISECOND

```c
const PBTimeDuration PB_TIME_MILLISECOND = 1000000;
```


### PB_TIME_MICROSECOND

```c
const PBTimeDuration PB_TIME_MICROSECOND = 1000;
```


### PB_TIME_NANOSECOND

```c
const PBTimeDuration PB_TIME_NANOSECOND = 1;
```


### PBTimeNow

```c
PBTime PBTimeNow();
```

PBTimeNow returns the current system time; the current value of a high-resolution monotonically-incrementing clock with undefined base. If you want to know the "human" time (wall clock / date-time), use `PBDateNow` instead.

`PBTime` is compatible with `PBTimeDuration`, so to make a time in the future, simply add to `PBTime`, i.e. "10 seconds from now" = `PBTimeNow() + 10*PB_TIME_SECOND`


### PBTimeSince

```c
PBTimeDuration PBTimeSince(PBTime past);
```

PBTimeSince returns the time delta between now and a point in time in the `past`


### PBTimeUntil

```c
PBTimeDuration PBTimeUntil(PBTime future);
```

PBTimeUntil returns the time delta between now and a point in time in the `future`


### PBTimeBetween

```c
PBTimeDuration PBTimeBetween(PBTime a,
                             PBTime b);
```

PBTimeBetween returns the time delta between `a` and `b`. i.e.
- PBTimeBetween(1, 3) == -2
- PBTimeBetween(3, 1) == 2


### PBTimeDurationFormat

```c
const char* PBTimeDurationFormat(PBTimeDuration d,
                                 char*          buf);
```

PBTimeDurationFormat writes a human-readable string like "1.6s" to `buf`.

- Returns: a pointer to beginning of `buf`.

### PBTimeDurationHours

```c
f64 PBTimeDurationHours(PBTimeDuration d);
```

PBTimeDurationHours converts duration `d` to hours as floating-point.


### PBTimeDurationMinutes

```c
f64 PBTimeDurationMinutes(PBTimeDuration d);
```

PBTimeDurationMinutes converts duration `d` to minutes as floating-point.


### PBTimeDurationSeconds

```c
f64 PBTimeDurationSeconds(PBTimeDuration d);
```

PBTimeDurationSeconds converts duration `d` to seconds as floating-point.


### PBTimeDurationMilliseconds

```c
i64 PBTimeDurationMilliseconds(PBTimeDuration d);
```

PBTimeDurationMilliseconds converts duration `d` to whole milliseconds, rounded to nearest, with ties rounded away from zero


### PBTimeDurationMicroseconds

```c
i64 PBTimeDurationMicroseconds(PBTimeDuration d);
```

PBTimeDurationMicroseconds converts duration `d` to whole microseconds, rounded to nearest, with ties rounded away from zero


### PBTimeDurationNanoseconds

```c
i64 PBTimeDurationNanoseconds(PBTimeDuration d);
```

PBTimeDurationNanoseconds converts duration `d` to whole nanoseconds. This function simply passes `d` back, since `PBTimeDuration` is a nanosecond value.


### PBTimeTimespec

```c
void PBTimeTimespec(PBTime           t,
                    struct timespec* ts);
```

PBTimeTimespec populates a timespec struct with the value of `t`


### PBTimeDurationTimespec

```c
void PBTimeDurationTimespec(PBTimeDuration   d,
                            struct timespec* ts);
```

PBTimeDurationTimespec populates a timespec struct with the value of `d`

---
`#include <playbit/timer.h>`

### PBTimer

```c
typedef struct {
    u64 id;
} PBTimer;
```

PBTimer identifies a timer

### PBTimerStart

```c
PBTimer PBTimerStart(PBTime         when,
                     PBTimeDuration repeat,
                     PBTimeDuration leeway,
                     u64            arg1,
                     u64            arg2);
```


### PBTimerStartTimeout

```c
PBTimer PBTimerStartTimeout(PBTimeDuration delay,
                            u64            arg1,
                            u64            arg2);
```

PBTimerStartTimeout starts a one-shot timer which triggers `delay` time from now.


### PBTimerStartInterval

```c
PBTimer PBTimerStartInterval(PBTimeDuration interval,
                             u64            arg1,
                             u64            arg2);
```

PBTimerStartInterval starts a repeating timer which triggers `interval` time from now and then repeats every `interval` time duration.


### PBTimerStop

```c
bool PBTimerStop(PBTimer timer);
```

PBTimerStop cancels a `timer`.

- Returns: true if `timer` was stopped, or false if `timer` is invalid or already stopped.

### PBTimerUpdate

```c
void PBTimerUpdate(PBTimer        timer,
                   PBTime         when,
                   PBTimeDuration repeat,
                   PBTimeDuration leeway);
```

PBTimerUpdate modifies an existing `timer` with new values


### PBTimerSetRepeatRate

```c
void PBTimerSetRepeatRate(PBTimer        timer,
                          PBTimeDuration repeat);
```

PBTimerSetRepeatRate sets the `repeat` rate of an existing `timer`


### PBTimerPoll

```c
bool PBTimerPoll(PBTime        now,
                 PBTimerEvent* result);
```

PBTimerPoll returns an expired timer, a timer which `when` time has recently passed `now`.

- Returns: false if there are no expired timers.

# Playbit API reference

Playbit's UI library is an immediate-mode styled API. The UI is composed of a tree of rectangles.

> Note: There's a [new UI library "UI3"](../ui3/) which will eventually replacing this older UI library

### Example

```c
UIBox* parent = UIDiv(PBStrLit("parent"));
parent->style = UIStyleMake(
    .size = UI_size2(UI_fill(1), UI_fill(1)),
    .direction = UIAxis_X,
    .align = UI_align2(UIAlign_Center, UIAlign_Center));

UIPushParent(parent);
{
    UIDiv(PBStrLit("A"))->style = UIStyleMake(
        .size = UI_size2(UI_px(20), UI_px(20)), .backgroundColor = UI_rgb(1, 0, 0));

    UIDiv(PBStrLit("B"))->style = UIStyleMake(
        .size = UI_size2(UI_px(20), UI_px(20)), .backgroundColor = UI_rgb(0, 1, 0));

    UIDiv(PBStrLit("C"))->style = UIStyleMake(
        .size = UI_size2(UI_px(20), UI_px(20)), .backgroundColor = UI_rgb(0, 0, 1));
}
UIPopParent(parent);
```

Would render:

<div style="display: flex; flex-direction: row; width: 320px; height: 240px; justify-content: center; align-items: center; font-size: 14px; font-weight: 500; font-family: monospace; text-align: center; border: 1px solid #222;">
    <div style="width:20px;height:20px;background:#f00;"></div>
    <div style="width:20px;height:20px;background:#0f0;"></div>
    <div style="width:20px;height:20px;background:#00f;"></div>
</div>

### Guide

- [The Basics](basics.md)
- [Keys and Strings](keys_and_strings.md)
- [Box Styles](box_styles.md)
- [Sizing and Layout](sizing_and_layout.md)
- [Events](events.md)
- [Alignment & Spacing](alignment_and_spacing.md)
- [Builtin Elements](builtin_elements.md)

---
`#include <playbit/app.h>`

### PBAppData

```c
struct PBAppData {
    union {
        void* nullable ctx; // any data, passed to callbacks
        u64            ctx64;
    };

    u64 flags;

    // onEvent can be set to handle any event which isn't handled by another handler
    void (*nullable onEvent)(const PBEvent* event);

    /*
    onRender is called once per frame when a render has been requested. By default a render is requested on each new event (e.g. resize, input). The draw context and UI state are set up automatically before calling onRender.
    */
    void (*nullable onRender)(void);
};
```

### PBAppResource

```c
typedef struct PBAppResource {
    PBStrSlice name;
    PBU8Slice  data; // guaranteed to be at least 16-byte aligned
} PBAppResource;
```

PBAppResource is a resource embedded in the program, defined in `pbapp.toml`

### PBAppTimerCallback

```c
typedef void (*PBAppTimerCallback)(PBTimer, u64);
```

PBAppResource is a resource embedded in the program, defined in `pbapp.toml`

### PBAppMain

```c
void PBAppMain();
```

PBAppMain processes events and calls callbacks. It blocks until the calling thread exits.


### PBAppName

```c
PBStrSlice PBAppName();
```

PBAppName retrieves the name of the app, as defined by `app_name` in `pbapp.toml`


### PBAppId

```c
PBStrSlice PBAppId();
```

PBAppId retrieves the id of the app, as defined by `app_id` in `pbapp.toml`


### PBAppResourceWithName

```c
PBAppResource PBAppResourceWithName(PBStrSlice name);
```

PBAppResourceWithName returns an embedded resource by `name`, defined in `pbapp.toml`. Panics if the named resource is not found


### PBAppResourceCount

```c
u32 PBAppResourceCount();
```

PBAppResourceCount returns the number of embedded resources available


### PBAppResourceAtIndex

```c
PBAppResource PBAppResourceAtIndex(u32 index);
```

PBAppResourceAtIndex returns an embedded resource by `index`.

- `index`: Must be < `PBAppResourceCount`() or this function will panic.

### PBAppTimerStart

```c
PBTimer PBAppTimerStart(PBTime             when,
                        PBTimeDuration     repeat,
                        PBTimeDuration     leeway,
                        PBAppTimerCallback callback,
                        u64                arg);
```

PBAppTimerStart starts a timer, which will call `callback` `when` it rings.

To cancel or stop a timer, use `PBTimerStop`. Returns a new timer handle.

- `when`: Absolute point in time `when` the timer should ring.
- `repeat`: if >0, `repeat` at this interval after it has rung at `when`.
- `leeway`: precision request; how much this timer is willing to fluctuate.

### PBAppTimeout

```c
PBTimer PBAppTimeout(PBTimeDuration     delay,
                     PBAppTimerCallback callback,
                     u64                arg);
```

PBAppTimeout starts a one-shot timer which triggers `delay` time from now


### PBAppInterval

```c
PBTimer PBAppInterval(PBTimeDuration     interval,
                      PBAppTimerCallback callback,
                      u64                arg);
```

PBAppInterval starts a repeating timer which triggers `interval` time from now and then repeats every `interval` time duration.


### PBAppRender

```c
void PBAppRender(PBEvent* ev,
                 u32      eventCount);
```

PBAppRender converts system events to UI/draw updates and executes one render pass, calling PBApp.onRender


### PBAppRequestRender

```c
void PBAppRequestRender();
```

PBAppRequestRender schedules `PBAppRender` to be called as soon as the current frame has finished
presenting (i.e. on display hardware to delivered to platform compositor.)


### PBAppSysGuiHandle

```c
PBSysHandle PBAppSysGuiHandle();
```

PBAppSysGuiHandle returns a handle to the system "GUI" object.

- Returns: `PBSysHandle_INVALID` for non-main threads. `PBSysHandle_INVALID` for main thread if the program is running without a GUI.

---
`#include <playbit/event.h>`

### PBGamepadAxis

```c
typedef enum PBGamepadAxis PB_ENUM_TYPE(u16){
    PBGamepadAxis_LEFT_X = PBSysGamepadAxis_LEFT_X,
    PBGamepadAxis_LEFT_Y = PBSysGamepadAxis_LEFT_Y,
    PBGamepadAxis_RIGHT_X = PBSysGamepadAxis_RIGHT_X,
    PBGamepadAxis_RIGHT_Y = PBSysGamepadAxis_RIGHT_Y,
    PBGamepadAxis_DPAD_X = PBSysGamepadAxis_DPAD_X,
    PBGamepadAxis_DPAD_Y = PBSysGamepadAxis_DPAD_Y,
    PBGamepadAxis_LEFT_TRIGGER = PBSysGamepadAxis_LEFT_TRIGGER,
    PBGamepadAxis_RIGHT_TRIGGER = PBSysGamepadAxis_RIGHT_TRIGGER,
    PBGamepadAxis_COUNT = PBSysGamepadAxis_COUNT,
} PBGamepadAxis;
```

### PBGamepadButton

```c
typedef enum PBGamepadButton PB_ENUM_TYPE(u16){
    PBGamepadButton_A = PBSysGamepadButton_A,
    PBGamepadButton_B = PBSysGamepadButton_B,
    PBGamepadButton_X = PBSysGamepadButton_X,
    PBGamepadButton_Y = PBSysGamepadButton_Y,
    PBGamepadButton_LEFT_SHOULDER = PBSysGamepadButton_LEFT_SHOULDER,
    PBGamepadButton_RIGHT_SHOULDER = PBSysGamepadButton_RIGHT_SHOULDER,
    PBGamepadButton_LEFT_TRIGGER = PBSysGamepadButton_LEFT_TRIGGER,
    PBGamepadButton_RIGHT_TRIGGER = PBSysGamepadButton_RIGHT_TRIGGER,
    PBGamepadButton_LEFT_THUMBSTICK = PBSysGamepadButton_LEFT_THUMBSTICK,
    PBGamepadButton_RIGHT_THUMBSTICK = PBSysGamepadButton_RIGHT_THUMBSTICK,
    PBGamepadButton_MENU = PBSysGamepadButton_MENU,
    PBGamepadButton_OPTIONS = PBSysGamepadButton_OPTIONS,
    PBGamepadButton_HOME = PBSysGamepadButton_HOME,
    PBGamepadButton_COUNT = PBSysGamepadButton_COUNT,
} PBGamepadButton;
```

### PBGesturePhase

```c
typedef enum PBGesturePhase PB_ENUM_TYPE(u8){
    PBGesturePhase_CHANGED = PBSysGesturePhase_CHANGED,
    PBGesturePhase_BEGAN = PBSysGesturePhase_BEGAN,
    PBGesturePhase_ENDED = PBSysGesturePhase_ENDED,
} PBGesturePhase;
```

### PBKeyboardFlags

```c
typedef enum PBKeyboardFlags PB_ENUM_TYPE(u16){
    PBKeyboardFlag_REPEAT = PBSysKeyboardFlag_REPEAT,
} PBKeyboardFlags;
```

### PBKeyboardKey

```c
typedef enum PBKeyboardKey PB_ENUM_TYPE(u16){
    PBKeyboardKey_None = PBSysKeyboardKey_None,
    PBKeyboardKey_Space = PBSysKeyboardKey_Space,
    PBKeyboardKey_Quote = PBSysKeyboardKey_Quote,
    PBKeyboardKey_Comma = PBSysKeyboardKey_Comma,
    PBKeyboardKey_Minus = PBSysKeyboardKey_Minus,
    PBKeyboardKey_Period = PBSysKeyboardKey_Period,
    PBKeyboardKey_Slash = PBSysKeyboardKey_Slash,
    PBKeyboardKey_0 = PBSysKeyboardKey_0,
    PBKeyboardKey_1 = PBSysKeyboardKey_1,
    PBKeyboardKey_2 = PBSysKeyboardKey_2,
    PBKeyboardKey_3 = PBSysKeyboardKey_3,
    PBKeyboardKey_4 = PBSysKeyboardKey_4,
    PBKeyboardKey_5 = PBSysKeyboardKey_5,
    PBKeyboardKey_6 = PBSysKeyboardKey_6,
    PBKeyboardKey_7 = PBSysKeyboardKey_7,
    PBKeyboardKey_8 = PBSysKeyboardKey_8,
    PBKeyboardKey_9 = PBSysKeyboardKey_9,
    PBKeyboardKey_Semicolon = PBSysKeyboardKey_Semicolon,
    PBKeyboardKey_Equal = PBSysKeyboardKey_Equal,
    PBKeyboardKey_A = PBSysKeyboardKey_A,
    PBKeyboardKey_B = PBSysKeyboardKey_B,
    PBKeyboardKey_C = PBSysKeyboardKey_C,
    PBKeyboardKey_D = PBSysKeyboardKey_D,
    PBKeyboardKey_E = PBSysKeyboardKey_E,
    PBKeyboardKey_F = PBSysKeyboardKey_F,
    PBKeyboardKey_G = PBSysKeyboardKey_G,
    PBKeyboardKey_H = PBSysKeyboardKey_H,
    PBKeyboardKey_I = PBSysKeyboardKey_I,
    PBKeyboardKey_J = PBSysKeyboardKey_J,
    PBKeyboardKey_K = PBSysKeyboardKey_K,
    PBKeyboardKey_L = PBSysKeyboardKey_L,
    PBKeyboardKey_M = PBSysKeyboardKey_M,
    PBKeyboardKey_N = PBSysKeyboardKey_N,
    PBKeyboardKey_O = PBSysKeyboardKey_O,
    PBKeyboardKey_P = PBSysKeyboardKey_P,
    PBKeyboardKey_Q = PBSysKeyboardKey_Q,
    PBKeyboardKey_R = PBSysKeyboardKey_R,
    PBKeyboardKey_S = PBSysKeyboardKey_S,
    PBKeyboardKey_T = PBSysKeyboardKey_T,
    PBKeyboardKey_U = PBSysKeyboardKey_U,
    PBKeyboardKey_V = PBSysKeyboardKey_V,
    PBKeyboardKey_W = PBSysKeyboardKey_W,
    PBKeyboardKey_X = PBSysKeyboardKey_X,
    PBKeyboardKey_Y = PBSysKeyboardKey_Y,
    PBKeyboardKey_Z = PBSysKeyboardKey_Z,
    PBKeyboardKey_LeftBracket = PBSysKeyboardKey_LeftBracket,
    PBKeyboardKey_Backslash = PBSysKeyboardKey_Backslash,
    PBKeyboardKey_RightBracket = PBSysKeyboardKey_RightBracket,
    PBKeyboardKey_Grave = PBSysKeyboardKey_Grave,
    PBKeyboardKey_Escape = PBSysKeyboardKey_Escape,
    PBKeyboardKey_Enter = PBSysKeyboardKey_Enter,
    PBKeyboardKey_Tab = PBSysKeyboardKey_Tab,
    PBKeyboardKey_Backspace = PBSysKeyboardKey_Backspace,
    PBKeyboardKey_Insert = PBSysKeyboardKey_Insert,
    PBKeyboardKey_Delete = PBSysKeyboardKey_Delete,
    PBKeyboardKey_Left = PBSysKeyboardKey_Left,
    PBKeyboardKey_Right = PBSysKeyboardKey_Right,
    PBKeyboardKey_Down = PBSysKeyboardKey_Down,
    PBKeyboardKey_Up = PBSysKeyboardKey_Up,
    PBKeyboardKey_PageUp = PBSysKeyboardKey_PageUp,
    PBKeyboardKey_PageDown = PBSysKeyboardKey_PageDown,
    PBKeyboardKey_Home = PBSysKeyboardKey_Home,
    PBKeyboardKey_End = PBSysKeyboardKey_End,
    PBKeyboardKey_CapsLock = PBSysKeyboardKey_CapsLock,
    PBKeyboardKey_LeftShift = PBSysKeyboardKey_LeftShift,
    PBKeyboardKey_LeftCtrl = PBSysKeyboardKey_LeftCtrl,
    PBKeyboardKey_LeftAlt = PBSysKeyboardKey_LeftAlt,
    PBKeyboardKey_LeftSuper = PBSysKeyboardKey_LeftSuper,
    PBKeyboardKey_MediaNext = PBSysKeyboardKey_MediaNext,
    PBKeyboardKey_MediaPrev = PBSysKeyboardKey_MediaPrev,
    PBKeyboardKey_MediaPlay = PBSysKeyboardKey_MediaPlay,
    PBKeyboardKey_MediaStop = PBSysKeyboardKey_MediaStop,
    PBKeyboardKey_World1 = PBSysKeyboardKey_World1,
    PBKeyboardKey_World2 = PBSysKeyboardKey_World2,
    PBKeyboardKey_ScrollLock = PBSysKeyboardKey_ScrollLock,
    PBKeyboardKey_NumLock = PBSysKeyboardKey_NumLock,
    PBKeyboardKey_PrintScreen = PBSysKeyboardKey_PrintScreen,
    PBKeyboardKey_Pause = PBSysKeyboardKey_Pause,
    PBKeyboardKey_F1 = PBSysKeyboardKey_F1,
    PBKeyboardKey_F2 = PBSysKeyboardKey_F2,
    PBKeyboardKey_F3 = PBSysKeyboardKey_F3,
    PBKeyboardKey_F4 = PBSysKeyboardKey_F4,
    PBKeyboardKey_F5 = PBSysKeyboardKey_F5,
    PBKeyboardKey_F6 = PBSysKeyboardKey_F6,
    PBKeyboardKey_F7 = PBSysKeyboardKey_F7,
    PBKeyboardKey_F8 = PBSysKeyboardKey_F8,
    PBKeyboardKey_F9 = PBSysKeyboardKey_F9,
    PBKeyboardKey_F10 = PBSysKeyboardKey_F10,
    PBKeyboardKey_F11 = PBSysKeyboardKey_F11,
    PBKeyboardKey_F12 = PBSysKeyboardKey_F12,
    PBKeyboardKey_F13 = PBSysKeyboardKey_F13,
    PBKeyboardKey_F14 = PBSysKeyboardKey_F14,
    PBKeyboardKey_F15 = PBSysKeyboardKey_F15,
    PBKeyboardKey_F16 = PBSysKeyboardKey_F16,
    PBKeyboardKey_F17 = PBSysKeyboardKey_F17,
    PBKeyboardKey_F18 = PBSysKeyboardKey_F18,
    PBKeyboardKey_F19 = PBSysKeyboardKey_F19,
    PBKeyboardKey_F20 = PBSysKeyboardKey_F20,
    PBKeyboardKey_F21 = PBSysKeyboardKey_F21,
    PBKeyboardKey_F22 = PBSysKeyboardKey_F22,
    PBKeyboardKey_F23 = PBSysKeyboardKey_F23,
    PBKeyboardKey_F24 = PBSysKeyboardKey_F24,
    PBKeyboardKey_Numpad0 = PBSysKeyboardKey_Numpad0,
    PBKeyboardKey_Numpad1 = PBSysKeyboardKey_Numpad1,
    PBKeyboardKey_Numpad2 = PBSysKeyboardKey_Numpad2,
    PBKeyboardKey_Numpad3 = PBSysKeyboardKey_Numpad3,
    PBKeyboardKey_Numpad4 = PBSysKeyboardKey_Numpad4,
    PBKeyboardKey_Numpad5 = PBSysKeyboardKey_Numpad5,
    PBKeyboardKey_Numpad6 = PBSysKeyboardKey_Numpad6,
    PBKeyboardKey_Numpad7 = PBSysKeyboardKey_Numpad7,
    PBKeyboardKey_Numpad8 = PBSysKeyboardKey_Numpad8,
    PBKeyboardKey_Numpad9 = PBSysKeyboardKey_Numpad9,
    PBKeyboardKey_NumpadDot = PBSysKeyboardKey_NumpadDot,
    PBKeyboardKey_NumpadDivide = PBSysKeyboardKey_NumpadDivide,
    PBKeyboardKey_NumpadMultiply = PBSysKeyboardKey_NumpadMultiply,
    PBKeyboardKey_NumpadSubtract = PBSysKeyboardKey_NumpadSubtract,
    PBKeyboardKey_NumpadAdd = PBSysKeyboardKey_NumpadAdd,
    PBKeyboardKey_NumpadEnter = PBSysKeyboardKey_NumpadEnter,
    PBKeyboardKey_NumpadEquals = PBSysKeyboardKey_NumpadEquals,
    PBKeyboardKey_NumpadClear = PBSysKeyboardKey_NumpadClear,
    PBKeyboardKey_RightShift = PBSysKeyboardKey_RightShift,
    PBKeyboardKey_RightCtrl = PBSysKeyboardKey_RightCtrl,
    PBKeyboardKey_RightAlt = PBSysKeyboardKey_RightAlt,
    PBKeyboardKey_RightSuper = PBSysKeyboardKey_RightSuper,
    PBKeyboardKey_Menu = PBSysKeyboardKey_Menu,
    PBKeyboardKey_VolumeUp = PBSysKeyboardKey_VolumeUp,
    PBKeyboardKey_VolumeDown = PBSysKeyboardKey_VolumeDown,
    PBKeyboardKey_Mute = PBSysKeyboardKey_Mute,
    PBKeyboardKey_COUNT = PBSysKeyboardKey_COUNT,
} PBKeyboardKey;
```

### PBKeyboardModifiers

```c
typedef enum PBKeyboardModifiers PB_ENUM_TYPE(u16){
    PBKeyboardModifier_SHIFT = PBSysKeyboardModifier_SHIFT,
    PBKeyboardModifier_CTRL = PBSysKeyboardModifier_CTRL,
    PBKeyboardModifier_ALT = PBSysKeyboardModifier_ALT,
    PBKeyboardModifier_META = PBSysKeyboardModifier_META,
    PBKeyboardModifier_CAPS_LOCK = PBSysKeyboardModifier_CAPS_LOCK,
    PBKeyboardModifier_FN = PBSysKeyboardModifier_FN,
} PBKeyboardModifiers;
```

### PBMouseButton

```c
typedef enum PBMouseButton PB_ENUM_TYPE(u16){
    PBMouseButton_Left = PBSysMouseButton_Left,     PBMouseButton_Right = PBSysMouseButton_Right,
    PBMouseButton_Middle = PBSysMouseButton_Middle, PBMouseButton_X1 = PBSysMouseButton_X1,
    PBMouseButton_X2 = PBSysMouseButton_X2,         PBMouseButton_COUNT = PBSysMouseButton_COUNT,
} PBMouseButton;
```

### PBPointerFlags

```c
typedef enum PBPointerFlags PB_ENUM_TYPE(u16){
    PBPointerFlag_PRIMARY = PBSysPointerFlag_PRIMARY,
    PBPointerFlag_IN_CONTACT = PBSysPointerFlag_IN_CONTACT,
    PBPointerFlag_ERASER = PBSysPointerFlag_ERASER,
    PBPointerFlag_INVERTED = PBSysPointerFlag_INVERTED,
    PBPointerFlag_COALESCED = PBSysPointerFlag_COALESCED,
    PBPointerFlag_PREDICTED = PBSysPointerFlag_PREDICTED,
} PBPointerFlags;
```

### PBPointerKind

```c
typedef enum PBPointerKind PB_ENUM_TYPE(u8){
    PBPointerKind_MOUSE = PBSysPointerKind_MOUSE,
    PBPointerKind_TOUCH = PBSysPointerKind_TOUCH,
    PBPointerKind_TRACKPAD = PBSysPointerKind_TRACKPAD,
    PBPointerKind_PEN = PBSysPointerKind_PEN,
} PBPointerKind;
```

### PBScrollFlags

```c
typedef enum PBScrollFlags PB_ENUM_TYPE(u16){
    PBScrollFlag_PRECISE = PBSysScrollFlag_PRECISE,
    PBScrollFlag_INVERTED = PBSysScrollFlag_INVERTED,
    PBScrollFlag_UNIT_LINES = PBSysScrollFlag_UNIT_LINES,
    PBScrollFlag_UNIT_PAGES = PBSysScrollFlag_UNIT_PAGES,
} PBScrollFlags;
```

### PBScrollPhase

```c
typedef enum PBScrollPhase PB_ENUM_TYPE(u8){
    PBScrollPhase_CHANGED = PBSysScrollPhase_CHANGED,
    PBScrollPhase_BEGAN = PBSysScrollPhase_BEGAN,
    PBScrollPhase_ENDED = PBSysScrollPhase_ENDED,
    PBScrollPhase_MOMENTUM = PBSysScrollPhase_MOMENTUM,
} PBScrollPhase;
```

### PBEventType

```c
typedef enum PBEventType PB_ENUM_TYPE(u16){
    PBEventType_INVALID = PBSysEventType_INVALID,
    PBEventType_SIGNAL = PBSysEventType_SIGNAL,
    PBEventType_FILE_PANEL_CLOSED = PBSysEventType_FILE_PANEL_CLOSED,

    // pointer
    PBEventType_POINTER_ENTER =
        PBSysEventType_POINTER_ENTER, // pointer started being "in" the surface/window
    PBEventType_POINTER_LEAVE = PBSysEventType_POINTER_LEAVE, // pointer left the surface/window
    PBEventType_POINTER_DOWN = PBSysEventType_POINTER_DOWN,
    PBEventType_POINTER_UP = PBSysEventType_POINTER_UP,
    PBEventType_POINTER_MOVE = PBSysEventType_POINTER_MOVE,
    PBEventType_POINTER_CANCEL = PBSysEventType_POINTER_CANCEL, // system canceled a sequence

    // scroll
    PBEventType_SCROLL = PBSysEventType_SCROLL,

    // gesture
    PBEventType_GESTURE_PAN = PBSysEventType_GESTURE_PAN,
    PBEventType_GESTURE_PINCH = PBSysEventType_GESTURE_PINCH,
    PBEventType_GESTURE_ROTATE = PBSysEventType_GESTURE_ROTATE,

    // keyboard
    PBEventType_KEY_DOWN = PBSysEventType_KEY_DOWN,
    PBEventType_KEY_UP = PBSysEventType_KEY_UP,

    // gamepad
    PBEventType_GAMEPAD_CONNECTED = PBSysEventType_GAMEPAD_CONNECTED,
    PBEventType_GAMEPAD_DISCONNECTED = PBSysEventType_GAMEPAD_DISCONNECTED,
    PBEventType_GAMEPAD_BUTTON_DOWN = PBSysEventType_GAMEPAD_BUTTON_DOWN,
    PBEventType_GAMEPAD_BUTTON_UP = PBSysEventType_GAMEPAD_BUTTON_UP,
    PBEventType_GAMEPAD_AXIS_MOVE = PBSysEventType_GAMEPAD_AXIS_MOVE,

    // webgpu
    PBEventType_WGPU_CALLBACK = PBSysEventType_WGPU_CALLBACK,

    // timer
    PBEventType_TIMER = 0x8000,
} PBEventType;
```

PBEventType defines the type of a PBEvent

### PBEvent

```c
typedef struct PBEvent {
    u16         size;     // size of the event
    PBEventType type;     // PBEventType
    u32         objectId; // originating object ID, e.g. window (0 means "unknown")
} PB_ATTR_ALIGNED(8) PBEvent;
```

PBEvent is the common header for all events. Events are variable-sized.

### PBSignalEvent

```c
typedef struct PBSignalEvent {
    PBEvent      event;
    PBSysHandle  handle;
    PBSysSignals signals;
    PBSysSignals pulseSignals;
    u16          objectType; // PBSysObjectType
    u16          _reserved;
} PBSignalEvent;
```

### PBFilePanelEvent

```c
typedef struct PBFilePanelEvent {
    PBEvent     event;
    PBSysHandle handle;
} PBFilePanelEvent;
```

### PBInputEvent

```c
typedef struct PBInputEvent {
    PBEvent event;
    PBTime  timestamp; // time the event occurred
    u32     clientId;  // originating client ID (0 for "local")
    u32     deviceId;  // stable per HID
    u16     modifiers; // PBKeyboardModifiers
    u16     _reserved;
} PBInputEvent;
```

### PBPointerEvent

```c
typedef struct PBPointerEvent {
    PBInputEvent  inputEvent;
    u32           pointerId;  // logical; stable per active contact/stream
    u16           flags;      // PBPointerFlags
    u16           buttons;    // current button bitmask (mouse/pen)
    u8            button;     // "changed" button for DOWN/UP/CLICK (0 if n/a)
    PBPointerKind kind;       //
    u8            clickCount; // for CLICK (and optionally DOWN/UP if platform provides)
    u8            _reserved;  //
    f32           x, y;       // position in window coords (dp)
    f32           dx, dy;     // delta since last event for this pointerId (dp). 0 if unknown.
} PBPointerEvent;
```

### PBPenPointerEvent

```c
typedef struct PBPenPointerEvent {
    PBPointerEvent pointerEvent;
    f32            pressure;           // [0..1]
    f32            tangentialPressure; // [0..1] barrel pressure (pen)
    f32            tiltX, tiltY;       // [-1, +1] 0 = perpendicular
    f32            twist;              // degrees [0, 359]; barrel rotation (pen)
    f32            width, height;      // contact ellipse in dp (touch/pen)
    f32            altitudeAngle;      // [0, π/2] radians (0 = parallel, π/2 = perpendicular)
    f32            azimuthAngle;       // [0, π/2] radians, direction in the screen plane
} PBPenPointerEvent;
```

PBPenPointerEvent is the shape of a PBPointerEvent when kind==PBPointerKind_PEN

### PBScrollEvent

```c
typedef struct PBScrollEvent {
    PBInputEvent  inputEvent;
    PBPointerKind kind;
    PBScrollPhase phase;
    u16           flags;  // PBScrollFlags
    f32           x, y;   // focus point in window coords if known, else 0
    f32           dx, dy; // scroll delta (dp or lines/pages depending on flags)
    f32           wheelZ; // optional for 3D wheels; else 0
} PBScrollEvent;
```

### PBGestureEvent

```c
typedef struct PBGestureEvent {
    PBInputEvent   inputEvent;
    PBGesturePhase phase;
    u8             _reserved;
    u16            flags;    // currenty unused
    f32            x, y;     // gesture center in window coords (dp) if known
    f32            dx, dy;   // pan delta (dp) for PAN; else 0
    f32            scale;    // relative scale delta for PINCH (1.0 means no change; e.g. 1.02)
    f32            rotation; // relative rotation delta in radians for ROTATE
} PBGestureEvent;
```

### PBKeyboardEvent

```c
typedef struct PBKeyboardEvent {
    PBInputEvent  inputEvent;
    PBKeyboardKey keyCode;    // logical code for the key, i.e. "the A key"
    PBKeyboardKey deviceCode; // physical key, i.e. "3rd key on 4th row"
    u32           text[8];    // Unicode representation
    u8            textLen;    // number of codepoints in text array
    u8            _reserved;  //
    u16           flags;      // PBKeyboardFlags
} PBKeyboardEvent;
```

### PBGamepadEvent

```c
typedef struct PBGamepadEvent {
    PBInputEvent inputEvent;
    u16          control; // PBGamepadButton for button events, PBGamepadAxis for axis events
    u16          flags;   // currently unused
    f32          value;   // scalar value for changed control
    f32          x;       // x axis for 2D controls, otherwise 0
    f32          y;       // y axis for 2D controls, otherwise 0
} PBGamepadEvent;
```

### PBTimerEvent

```c
typedef struct PBTimerEvent {
    PBEvent event;
    PBTimer timer;
    u64     arg1;
    u64     arg2;
} PBTimerEvent;
```

### PBEventAny

```c
typedef union PBEventAny {
    struct { // PBEvent
        u16         size;
        PBEventType type;
        u32         objectId;
    };
    PBEvent           event;
    PBSignalEvent     signal;
    PBInputEvent      input;
    PBPointerEvent    pointer;
    PBPenPointerEvent penPointer;
    PBScrollEvent     scroll;
    PBGestureEvent    gesture;
    PBKeyboardEvent   keyboard;
    PBGamepadEvent    gamepad;
    PBTimerEvent      timer;
    PBFilePanelEvent  filePanel;
    u8                _maxSize[PBSysEventSize_MAX];
} PBEventAny;
```

### PBEventPoll

```c
i32 PBEventPoll(PBEvent* events,
                u32      eventsSize,
                u32      maxCount);
```

PBEventPoll retrieves `events` for the calling thread.

- `eventsSize`: is the total number of bytes available at `events`.
- `maxCount`: limits the number of `events` returned.
- Returns: the number of `events` written to `events`. 0 if the thread is exiting, `eventsSize`=0 or `maxCount`=0. `PBSysErr_NO_MEM` if `eventsSize` is not large enough for a single event. Note that the largest possible event's size is <= PBSysEventSize_MAX.

### PBEventNext

```c
PBEvent* PBEventNext(PBEvent* event);
```

PBEventNext returns the next `event` in an array of events returned from `PBEventPoll`


### PBEventAnyNext

```c
PBEventAny* PBEventAnyNext(PBEventAny* event);
```

PBEventAnyNext returns the next `event` in an array of events returned from `PBEventPoll`


### PBEventTypeStr

```c
const char* PBEventTypeStr(PBEventType arg);
```

PBEventTypeStr returns a short string representation of an event type, e.g. "SIGNAL"


### PBEventStr

```c
u32 PBEventStr(const PBEvent* event,
               char*          buf,
               u32            bufCap);
```

PBEventStr writes a string representation of a `PBEvent` to `buf`.

- Returns: the number of bytes that would be written to `buf`, excluding NUL terminator, as if `bufCap` was inifinite.

### PBEventOfSysEvent

```c
usize PBEventOfSysEvent(PBEvent*          event,
                        usize             eventSize,
                        const PBSysEvent* sysEvent);
```

PBEventOfSysEvent copies a `PBSysEvent` entry to a `PBEvent`.

- `eventSize`: is the size of memory at `event`, in bytes.
- Returns: the number of bytes written to `event`, which will be the size of the appropriate `PBEvent` type, e.g. sizeof(`PBKeyboardEvent`) when `event`->type==`PBEventType_KEY_DOWN`. 0 if `eventSize` is too small for the `event` type.

### PBLogEvent

```c
void PBLogEvent(const PBEvent* event);
```

PBLogEvent is a convenience function which calls `PBLog` with the result of passing `event` to `PBEventStr`

---
`#include <playbit/hid.h>`

### PBHidDeviceInfoGet

```c
PBSysErr PBHidDeviceInfoGet(u32                 deviceId,
                            PBSysHidDeviceInfo* info);
```

PBHidDeviceInfoGet retrieves general information about an HID device.

- `deviceId`: HID device ID from `PBEvent`.`deviceId`
- `info`: Result storage

### PBHidDeviceName

```c
i32 PBHidDeviceName(u32 deviceId,
                    u8* buf,
                    u32 bufCap);
```

PBHidDeviceName retrieves a human-readable name describing an HID device, as UTF-8 text.

- `deviceId`: HID device ID from `PBEvent`.`deviceId`
- `buf`: Storage for name bytes
- `bufCap`: Size of `buf`, in bytes

### PBHidDeviceSetPlayerIndex

```c
PBSysErr PBHidDeviceSetPlayerIndex(u32 deviceId,
                                   u32 playerIndex);
```

PBHidDeviceSetPlayerIndex assigns a logical player number to an HID device.

- `deviceId`: HID device ID from `PBEvent`.`deviceId`
- `playerIndex`: 0 for "unset", 1, 2, 3 or 4 for player 1, 2, 3 or 4

### PBHidSysHandle

```c
PBSysHandle PBHidSysHandle();
```

PBHidSysHandle returns the HID object handle

---
`#include <playbit/window.h>`

### PBWindow

```c
typedef struct {
    PBSysHandle handle;
} PBWindow;
```

PBWindow is a handle to a UI window

### PBWindowOpt

```c
typedef PBOpt(PBWindow) PBWindowOpt;
```

PBWindow is a handle to a UI window

### PBWindowMain

```c
PBWindow PBWindowMain();
```

PBWindowMain retrieves the main window, or PBWindow_NONE if there's no main window.


### PBWindowClose

```c
PBSysErr PBWindowClose(PBWindow window);
```

PBWindowClose closes `window` handle and destroys the associated `window`.


### PBWindowOpen

```c
PBWindow PBWindowOpen(const char* title,
                      f32         width,
                      f32         height);
```

PBWindowOpen creates a window on the current thread with `title` and size.


### PBWindowOpenWithConfig

```c
PBWindowOpt PBWindowOpenWithConfig(PBThread                 thread,
                                   const PBSysWindowConfig* config);
```

PBWindowOpenWithConfig creates a window on `thread` using detailed system configuration.


### PBWindowCopyTitle

```c
PBSysErr PBWindowCopyTitle(PBWindow window,
                           PBStr*   titleOut,
                           PBMem    ma);
```

PBWindowCopyTitle copies the title of a `window` to `title`, allocating memory with `ma`


### PBWindowSetTitle

```c
void PBWindowSetTitle(PBWindow   window,
                      PBStrSlice title);
```

PBWindowSetTitle sets the `title` of a `window`


### PBWindowStyle

```c
PBSysWindowStyle PBWindowStyle(PBWindow window);
```

PBWindowStyle retrieves the current style of a `window`


### PBWindowSetStyle

```c
void PBWindowSetStyle(PBWindow         window,
                      PBSysWindowStyle style);
```

WindowSetStyle sets the `style` of a `window`


### PBWindowSetSizeLimits

```c
void PBWindowSetSizeLimits(PBWindow window,
                           PBSize   min,
                           PBSize   max);
```

PBWindowSetSizeLimits sets lower and upper limits for `window` frame size


### PBWindowSetMinSize

```c
void PBWindowSetMinSize(PBWindow window,
                        f32      minWidth,
                        f32      minHeight);
```

PBWindowSetMinSize sets lower limit for `window` frame size


### PBWindowSetMaxSize

```c
void PBWindowSetMaxSize(PBWindow window,
                        f32      maxWidth,
                        f32      maxHeight);
```

`PBWindowSetMinSize` sets upper limit for `window` frame size


### PBWindowRect

```c
PBRect PBWindowRect(PBWindow window);
```

PBWindowFrame returns the origin and size of a `window`. The origin is the top-left corner of the `window` in screen coordinates. The size includes OS `window` decorations.


### PBWindowSetFrame

```c
PBSysErr PBWindowSetFrame(PBWindow window,
                          PBRect   frame);
```

PBWindowSetFrame adjusts the origin and (outer) size of a `window`


### PBWindowSetOrigin

```c
PBSysErr PBWindowSetOrigin(PBWindow window,
                           f32      x,
                           f32      y);
```

PBWindowSetOrigin repositions the `window` on screen


### PBWindowSetSize

```c
PBSysErr PBWindowSetSize(PBWindow window,
                         f32      width,
                         f32      height);
```

PBWindowSetSize sets the (outer) size of a `window`


### PBWindowSetSizeCentered

```c
PBSysErr PBWindowSetSizeCentered(PBWindow window,
                                 f32      width,
                                 f32      height);
```

PBWindowSetSizeCentered sets the size of a `window` and positions it at the center of the screen


### PBWindowContentRect

```c
PBRect PBWindowContentRect(PBWindow window);
```

PBWindowContentRect returns the size and position (relative to the `window``s frame) of a `window``s content. The origin is the top-left corner of the contents relative to the `window`'s outer frame.


### PBWindowContentSize

```c
PBSize PBWindowContentSize(PBWindow window);
```

PBWindowContentSize returns the size of a `window`'s content


### PBWindowSetContentSizeCentered

```c
PBSysErr PBWindowSetContentSizeCentered(PBWindow window,
                                        f32      width,
                                        f32      height);
```

PBWindowSetContentSizeCentered adjusts the size of a `window` so that its content size is {wodth, `height`}, and positions the `window` at the center of the screen.


### PBWindowScaleFactor

```c
f32 PBWindowScaleFactor(PBWindow window);
```

PBWindowScaleFactor returns the dp scale factor for a `window` (pixels per dp.)


### PBWindowPxPerInch

```c
f32 PBWindowPxPerInch(PBWindow window);
```

PBWindowPxPerInch returns the physical pixel density of the display the `window` is currently on, with the documented fallback applied: the measured value when the OS reports one, otherwise 96 * dpScale (the CSS reference density). Read `PBSysWindowInfo`.pxPerInch directly when "unknown" must stay distinguishable from a guess.


### PBWindowGetMousePosition

```c
PBVector2 PBWindowGetMousePosition(PBWindow window);
```

PBWindowGetMousePosition gets the mouse position relative to the `window`


### PBKeyPressed

```c
bool PBKeyPressed(PBWindow      window,
                  PBKeyboardKey key);
```

PBKeyPressed returns true if the `key` was pressed this frame


### PBKeyReleased

```c
bool PBKeyReleased(PBWindow      window,
                   PBKeyboardKey key);
```

PBKeyReleased returns true if the `key` was released this frame


### PBKeyRepeated

```c
bool PBKeyRepeated(PBWindow      window,
                   PBKeyboardKey key);
```

`PBKeyPressed` returns true if the `key` was repeated this frame


### PBKeyDown

```c
bool PBKeyDown(PBWindow      window,
               PBKeyboardKey key);
```

PBKeyDown returns true if the `key` is currently being held down


### PBMousePressed

```c
bool PBMousePressed(PBWindow      window,
                    PBMouseButton button);
```


### PBMouseReleased

```c
bool PBMouseReleased(PBWindow      window,
                     PBMouseButton button);
```


### PBMouseDown

```c
bool PBMouseDown(PBWindow      window,
                 PBMouseButton button);
```


### PBWindowProcessEvents

```c
void PBWindowProcessEvents(PBWindow window,
                           PBEvent* ev,
                           u32      eventCount);
```

PBWindowProcessEvents is called by PBApp for you before the onRender callback - call manually if you're not using PBApp
Processes events so that `window` event queries (e.g. `PBKeyPressed` et all) work


### PBWindowEndFrame

```c
void PBWindowEndFrame(PBWindow window);
```

PBWindowEndFrame is called by PBApp for you after the onRender callback - call manually if you're not using PBApp
Resets the "pressed"/"released"/"repeat" signal of key events


### PBWindowGetSize

```c
PBVector2 PBWindowGetSize(PBWindow window);
```

PBWindowGetSize returns current `window`'s content size in dp

> **DEPRECATED** Use `PBWindowContentRect` instead


### PBWindowGetScale

```c
f32 PBWindowGetScale(PBWindow window);
```

PBWindowGetScale returns current device-pixel scale factor for `window`.

> **DEPRECATED** Use `PBWindowScaleFactor` instead


### PBCursorSetStyle

```c
int PBCursorSetStyle(u32 windowId,
                     u32 style);
```

---
`#include <playbit/ui.h>`

### PBUIFont

```c
struct PBUIFont {
    PBStrSlice family; // font family name (e.g. PBStrLit("sans") or PBStrLit("mono"))
    f32        size;   // font size in pixels (e.g. 16.0)
    f32        weight; // font weight between 100-900
};
```

Font descriptor used for text rendering. Passed to PBUIStyle.font and PBUIText().

### PBUIKey

```c
struct PBUIKey {
    u64 v;
};
```

Opaque 64-bit identity key that uniquely identifies a box across frames.
Keys are derived by hashing a string, optionally seeded by a parent key.
Use PBUIKeyFromString() or PBUIKeyFromStringAndIndex() to construct.

### PBUIBoxFlags

```c
typedef enum PBUIBoxFlags PB_ENUM_TYPE(u32){
    // Events
    PBUIBoxFlag_Clickable = (1 << 0), // whether or not boxes should receive clicks

    // Layout
    PBUIBoxFlag_FixedWidth = (1 << 1),  // box width must be _exactly_ fixedSize.x
    PBUIBoxFlag_FixedHeight = (1 << 2), // box height must be _exactly_ fixedSize.y
    PBUIBoxFlag_FloatingX = (1 << 3),   // remove box from layout along the X-axis and position
                                        // absolutely with fixedPosition.x
    PBUIBoxFlag_FloatingY = (1 << 4),   // remove box from layout along the Y-axis and position
                                        // absolutely with fixedPosition.y

    // Overflow
    PBUIBoxFlag_AllowOverflowX = (1 << 5),  // allow children to overflow on the X-axis
    PBUIBoxFlag_AllowOverflowY = (1 << 6),  // allow children to overflow on the Y-axis
    PBUIBoxFlag_SkipViewOffsetX = (1 << 7), // ignore parent's scroll offset along the X-axis
    PBUIBoxFlag_SkipViewOffsetY = (1 << 8), // ignore parent's scroll offset along the Y-axis

    // Drawing
    PBUIBoxFlag_DrawText = (1 << 9),        // draw box text
    PBUIBoxFlag_DrawBackground = (1 << 10), // draw box background
    PBUIBoxFlag_DrawBorder = (1 << 11),     // draw box border
    PBUIBoxFlag_DrawShadow = (1 << 12),     // draw box shadow

    // Clip
    PBUIBoxFlag_Clip = (1 << 13), // clip children contents to the parent's viewport

    // Scroll
    PBUIBoxFlag_ScrollX = (1 << 14), // scroll along X-axis
    PBUIBoxFlag_ScrollY = (1 << 15), // scroll along Y-axis

    // These are only used by components and can be moved
    PBUIBoxFlag_AutoHideScrollX = (1 << 16), // only show a scrollbar if one would be necessary
    PBUIBoxFlag_AutoHideScrollY = (1 << 17), // only show a scrollbar if one would be necessary
    PBUIBoxFlag_InvertScrollX = (1 << 18),   // only show a scrollbar if one would be necessary
    PBUIBoxFlag_InvertScrollY = (1 << 19),   // only show a scrollbar if one would be necessary

    PBUIBoxFlag_FixedViewSizeX = (1 << 20), // do not store bounds, instead use a fixed-view size
    PBUIBoxFlag_FixedViewSizeY = (1 << 21), // do not store bounds, instead use a fixed-view size

    PBUIBoxFlag_ViewClampX = (1 << 22),
    PBUIBoxFlag_ViewClampY = (1 << 23),
    PBUIBoxFlag_ScreenClampX = (1 << 24),
    PBUIBoxFlag_ScreenClampY = (1 << 25),

    PBUIBoxFlag_Focusable = (1 << 26),

    PBUIBoxFlag_Hidden = (1 << 27),
} PBUIBoxFlags;
```

Bit flags that control a box's layout, drawing, event handling, and scrolling.
Combine with bitwise OR. Composite convenience macros are defined below the enum.

### PBUIBoxFlag_Draw

```c
#define PBUIBoxFlag_Draw …
```

all draw flags turned on


### PBUISizeKind

```c
typedef enum PBUISizeKind PB_ENUM_TYPE(u32){
    PBUISizeKind_Null,
    PBUISizeKind_Pixels,          // size by pixels
    PBUISizeKind_TextContent,     // size of text content
    PBUISizeKind_PercentOfParent, // size as a percentage of the parent
    PBUISizeKind_ChildrenSum,     // size according to the total sum of the children
    PBUISizeKind_Ratio,           // size proportional to the size on the alternate axis
    PBUISizeKind_COUNT
} PBUISizeKind;
```

Determines how a box's preferred size is computed along one axis.
Set via PBUIStyle.width / .height using the PBUI_px(), PBUI_fill(), etc. macros.

### PBUIAxis

```c
typedef enum PBUIAxis PB_ENUM_TYPE(u32){ PBUIAxis_X, PBUIAxis_Y, PBUIAxis_COUNT } PBUIAxis;
```

The primary direction in which a box lays out its children. Set via PBUIStyle.direction.

### PBUIAlign

```c
typedef enum PBUIAlign PB_ENUM_TYPE(u32){
    PBUIAlign_Null,
    PBUIAlign_Start,        // start of layout axis (similar to CSS flex-start)
    PBUIAlign_End,          // end of layout axis (similar to CSS flex-end)
    PBUIAlign_Center,       // center of layout axis (similar to CSS center)
    PBUIAlign_Stretch,      // stretch all children (similar to CSS stretch)
    PBUIAlign_SpaceBetween, // space children flush to the edges (similar to CSS space-between)
    PBUIAlign_SpaceAround,  // space children with 1/2 spacing on the start and end (similar to CSS
                            // space-around)
    PBUIAlign_SpaceEvenly,  // space children evenly everywhere (similar to CSS space-evenly)
    PBUIAlign_COUNT
} PBUIAlign;
```

Controls child alignment along a layout axis.
Analogous to CSS flex-box justify-content / align-items values.
Set via PBUIStyle.align (a PBUIAlign2 for both axes independently).

### PBUIAlign2

```c
union PBUIAlign2 {
    struct {
        PBUIAlign x, y;
    };
    PBUIAlign e[2];
};
```

Alignment for both axes in a single struct. x aligns children along the main axis, y along the cross axis.

### PBUISize

```c
struct PBUISize {
    PBUISizeKind kind;
    f32          value;
    f32          strictness;
};
```

Preferred size specification for one axis.

### PBUISize2

```c
union PBUISize2 {
    struct {
        PBUISize width, height;
    };
    struct {
        PBUISize x, y;
    };
    PBUISize e[2];
};
```

Preferred size for both axes. Accessible as .width/.height, .x/.y, or .e[i].

### PBUIShadow

```c
struct PBUIShadow {
    PBVector2 offset; // in pixels
    f32       blur;   // blur radius, in pixels
    f32       spread; // spread radius, in pixels
    PBColor   color;
    bool      inset; // whether the shadow should be inset or outset
};
```

Drop or inset shadow applied to a box's background. Requires PBUIBoxFlag_DrawShadow.

### PBUIBorderGrow

```c
typedef enum PBUIBorderGrow {
    PBUIBorderGrow_CENTER = 0,
    PBUIBorderGrow_INNER = 1,
    PBUIBorderGrow_OUTER = 2,
} PBUIBorderGrow;
```

PBUIBorderGrow determines how a border grows

### PBUIBorder

```c
struct PBUIBorder {
    PBUIBorderGrow grow;
    f32            width;
    PBColor        color;
};
```

Uniform border rendered inset, on top of a box's content. Requires PBUIBoxFlag_DrawBorder.

### PBUIPadding

```c
struct PBUIPadding {
    f32 left, top, right, bottom;
};
```

Inner spacing between a box's edges and its children/content, in pixels.

### PBUICornerRadius

```c
struct PBUICornerRadius {
    f32 topLeft, topRight, bottomRight, bottomLeft;
};
```

Per-corner rounding radii in pixels. Passed via PBUIStyle.cornerRadius or PBUICornerRadiusMake().

### PBUITextAlign

```c
typedef enum PBUITextAlign PB_ENUM_TYPE(u32){
    PBUITextAlign_None,        PBUITextAlign_TopLeft,    PBUITextAlign_TopCenter,
    PBUITextAlign_TopRight,    PBUITextAlign_CenterLeft, PBUITextAlign_Center,
    PBUITextAlign_CenterRight, PBUITextAlign_BottomLeft, PBUITextAlign_BottomCenter,
    PBUITextAlign_BottomRight, PBUITextAlign_COUNT,
} PBUITextAlign;
```

9-position text alignment within a box's content area. Requires PBUIBoxFlag_DrawText.

### PBUITextWrap

```c
typedef enum PBUITextWrap PB_ENUM_TYPE(u32){
    PBUITextWrap_None,
    PBUITextWrap_Word,
    PBUITextWrap_COUNT,
} PBUITextWrap;
```

Controls whether text wraps to the next line when it exceeds the box width.
@Incomplete: Not implemented yet.

### PBUIDrawCommandType

```c
typedef enum PBUIDrawCommandType PB_ENUM_TYPE(u32){
    PBUIDrawCommand_Null,       PBUIDrawCommand_Rectangle, PBUIDrawCommand_Text,
    PBUIDrawCommand_SetScissor, PBUIDrawCommand_Image,     PBUIDrawCommand_Custom,
    PBUIDrawCommand_COUNT,
} PBUIDrawCommandType;
```

Type tag for a draw command. The renderer iterates the draw list and dispatches on this.

### PBUIDrawCommand

```c
struct PBUIDrawCommand {
    PBUIDrawCommandType type;
    PBRectangle         rect;

    PBVector4 cornerRadius;
    f32       borderWidth;
    u8        borderGrow; // 0=center, 1=inner, 2=outer
    f32       edgeSoftness;

    PBColor color;
    PBColor colors[4];

    PBUIFont   font;
    PBStrSlice text;
    void*      data;
};
```

A single renderer-agnostic draw instruction produced by the UI system.
Consume by switching on .type in your renderer backend.
Rectangle, Text, Image, and SetScissor commands cover the built-in cases;
Custom commands pass arbitrary data via .data for user-defined rendering.

### PBUIDrawCommandArray

```c
struct PBUIDrawCommandArray {
    PBUIDrawCommand* data;
    u64              count;
    u64              capacity;
};
```

Dynamic array of draw commands. Produced by PBUIOutputDrawCommands() each frame.

### PBUIDrawCallback

```c
#define PBUIDrawCallback(name)
```

Signature for a custom per-box draw callback.
Attach via `PBUIBoxSetDrawCallback`(). Called during draw command generation
with the box's computed rect and the command array to append to.


### PBUIDrawCallbackProc

```c
typedef void (PBUIBox * _Nonnull, PBRectangle, PBUIDrawCommandArray * _Nonnull) PBUIDrawCallbackProc;
```

Dynamic array of draw commands. Produced by PBUIOutputDrawCommands() each frame.

### PBUIPushDrawCommand

```c
bool PBUIPushDrawCommand(PBUIDrawCommandArray* cmds,
                         PBUIDrawCommand       cmd);
```

Append a single draw command, an array of commands, or a filled rect to a draw list.


### PBUIPushDrawCommandArray

```c
bool PBUIPushDrawCommandArray(PBUIDrawCommandArray* cmds,
                              PBUIDrawCommandArray  push_cmds);
```

Appends an array of draw commands to another array


### PBUIPushDrawRect

```c
bool PBUIPushDrawRect(PBUIDrawCommandArray* cmds,
                      PBRectangle           rect,
                      PBColor               color);
```

Pushes a single draw rectangle command


### PBUIBoxEquipDraw

```c
void PBUIBoxEquipDraw(PBUIBox* box,
                      u64      capacity);
```

Allocate a per-`box` draw command list (required before `PBUIBoxDraw`), or append a command to it.


### PBUIBoxDraw

```c
void PBUIBoxDraw(PBUIBox*        box,
                 PBUIDrawCommand cmd);
```

Makes sure the `box` is equipped with a draw-command list, and then pushes the draw command onto that list


### PBUIStyle

```c
struct PBUIStyle {
    // sizing and positioning
    union {
        PBVector2 minSize; // in pixels
        struct {
            f32 minWidth, minHeight;
        };
    };
    union {
        PBVector2 maxSize; // in pixels
        struct {
            f32 maxWidth, maxHeight;
        };
    };
    union {
        PBUISize2 size; // preferred box sizing (before layout constraints)
        struct {
            PBUISize width, height;
        };
    };

    // visuals
    union {
        PBVector4 cornerRadius; // in pixels
        struct {
            f32 cornerRadiusTopLeft, cornerRadiusTopRight, cornerRadiusBottomRight,
                cornerRadiusBottomLeft;
        };
    };
    PBColor color;
    PBColor backgroundColor;
    union {
        PBColor backgroundColors[4];
        struct {
            PBColor backgroundColorTopLeft, backgroundColorTopRight, backgroundColorBottomRight,
                backgroundColorBottomLeft;
        };
    };
    PBUIBorder border;
    // TODO: gradients

    // layout
    PBUIAxis   direction;  // UIAxis_X or UIAxis_Y
    PBUIAlign2 align;      // e.g. UIAlign_Start, etc.
    f32        childSpace; // in pixels

    union {
        PBVector4 padding; // the padding inside the box's content, in pixels
        struct {
            f32 paddingLeft, paddingTop, paddingRight, paddingBottom;
        };
    };

    // font and text
    PBUIFont      font;
    PBUITextAlign textAlign;
    PBUITextWrap  textWrap;

    // shadow
    PBUIShadow shadow;
    // TODO: shadow stacks

    // PBCursorStyleLegacy cursor;
};
```

Visual and layout properties for a PBUIBox. Set directly on box->style after creation.

### PBUIBox

```c
struct PBUIBox {
    // persistent links
    PBUIBox* nextHash;
    PBUIBox* prevHash;

    // per-frame links and data
    PBUIBox* next;
    PBUIBox* prev;
    PBUIBox* firstChild;
    PBUIBox* lastChild;
    PBUIBox* parent;
    u64      childCount;

    PBUIBox* scissor;

    // per-frame data
    PBUIKey      key;
    PBStrSlice   text;
    PBStrSlice   debugString;
    PBUIBoxFlags flags;
    PBUIStyle    style;
    PBVector2    fixedPosition;
    PBVector2    fixedSize;
    PBVector2    textSize;
    i64          order;

    // per-frame custom rendering data
    PBUIDrawCommandArray* drawCommands;
    PBUIDrawCallbackProc* drawCallback;

    void* imageData;
    void* customData;

    // per-frame computed values
    PBRectangle rect;
    PBVector2   viewSize;

    // persistent data
    u64       id;
    PBVector2 scroll; // viewOffset
    u64       firstFrameTouched;
    u64       lastFrameTouched;
    f32       hoverTime;
    f32       activeTime;
    u32       keyConflictsThisFrame;

    u64 state;
};
```

The fundamental UI node. Every visible element — text, panels, buttons — is a PBUIBox.

Boxes form a tree (firstChild / next / parent) rebuilt each frame. Persistent state
(scroll offsets, hover/active timers, custom .state) is carried across frames
via the key. Do not allocate directly; use PBUIBoxMakeFromString / PBUIBoxMakeFromKey.

Fields marked "per-frame" are reset each frame; "persistent" fields survive.

### PBUIBoxSlot

```c
struct PBUIBoxSlot {
    PBUIBox* firstHash;
    PBUIBox* lastHash;
};
```

Internal hash-table bucket for fast box lookup by key. Not intended for direct use.

### PBUIBoxIter

```c
struct PBUIBoxIter {
    PBUIBox* next;
    u32      pushCount;
    u32      popCount;
};
```

Iterator state for depth-first box tree traversal. Use with PBUIBoxIterDepthFirstPre/Post.

### PBUISignal

```c
struct PBUISignal {
    PBUIBox*  box;
    bool      hover;       // is the box being hovered by a pointer
    bool      click;       // was the box clicked (fires exactly once per pointer click)
    bool      drag;        // is the box being dragged?
    bool      down;        // is the pointer being held over the box?
    bool      pressed;     // was the pointer pressed this frame?
    bool      released;    // was the pointer released this frame?
    bool      doubleClick; // is this event a double-click?
    bool      tripleClick; // is this event a triple-click?
    u32       clickCount;  // the click count [0, 1 or 2]
    PBVector2 mouse;       // the mouse position relative to this box
    PBVector2 scroll;      // the scroll amount that on this box
    bool      changed;     // custom boolean
};
```

Aggregated pointer-interaction state for a box, returned by PBUISignalFromBox().
Query this each frame after PBUIEndBuild() to drive widget logic.

### PBUIMeasureTextFunction

```c
#define PBUIMeasureTextFunction(name)
```

Callback to measure the pixel dimensions of a text string in a given font.
Required for TextContent sizing (PBUI_text_size). Supply via `PBUIWindowInput`.measureTextProc.


### PBUIMeasureTextProc

```c
typedef PBVector2 (PBUIFont, PBStrSlice, f32, void * _Nonnull) PBUIMeasureTextProc;
```

Aggregated pointer-interaction state for a box, returned by PBUISignalFromBox().
Query this each frame after PBUIEndBuild() to drive widget logic.

### PBUIWindowInput

```c
struct PBUIWindowInput {
    const PBEvent* events;
    u32            eventCount;
    f32            dt;
    PBVector2      mouse;

    PBUIMeasureTextProc* measureTextProc;
    void*                userData;
};
```

Per-frame input snapshot passed to PBUIBeginBuild(). Supply all events, delta time,
current mouse position, and a text measure callback for TextContent sizing

### PBUIState

```c
struct PBUIState {
    PBArena* arena;
    PBArena* frameArenas[2];
    PBArena* dragArena;

    u64 frameIndex;
    u64 boxMakeCount;
    u64 nextBoxId;
    u64 subFrameIndex;

    PBUIBox* firstFreeBox;

    struct {
        PBUIBoxSlot* data;
        u64          size;
    } boxTable;

    // input
    PBRectangle     window;
    PBUIWindowInput input;
    PBVector2       mouse;
    u32             keyStates[PBKeyboardKey_COUNT];
    u32             mouseStates[PBMouseButton_COUNT];
    PBVector2       dragStartPos;

    // double and triple click handling
    PBVector2 lastMousePos;
    u32       mouseClickCount;
    f32       lastClickTimer;
    // scrolling with mouse wheel click+drag
    bool middleMouseScroll;

    bool usingKeyboardNavigation;

    PBUIBox* root;

    PBUIKey activeKey;
    PBUIKey hoverKey;
    PBUIKey clickKey;
    PBUIKey nextHoverKey;
    PBUIKey focusKey;

    PBUIDrawCommandArray commands;

    // PBCursorStyleLegacy cursor;
    PBVector2 syntheticScroll; // injected scroll (e.g. from middle-mouse drag)

    struct {
        PBUIBox* data[PBUI_STACK_MAX];
        u64      count;
    } parentStack;
};
```

All mutable state for one UI context. Allocate with PBUIStateAlloc(), activate with PBUISetState().
Multiple independent UI contexts are supported by swapping state pointers.
Do not access internal fields directly; use the provided API functions.

### PBUI_px

```c
#define PBUI_px(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_dp

```c
#define PBUI_dp(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_text_size

```c
#define PBUI_text_size(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_fill

```c
#define PBUI_fill(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_child_size

```c
#define PBUI_child_size(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_ratio

```c
#define PBUI_ratio(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_em

```c
#define PBUI_em(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_rem

```c
#define PBUI_rem(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_vw

```c
#define PBUI_vw(x)
```

Size literal macros. Assign to `PBUIStyle`.width / .height to specify box sizing.

PBUI_px(n)         — exactly n pixels
PBUI_dp(n)         — alias for PBUI_px(n)
PBUI_text_size(n)  — n × the box's text content size (requires measureTextProc)
PBUI_fill(n)       — n × parent size, e.g. PBUI_fill(1) = 100% of parent
PBUI_child_size(n) — n × sum of children sizes
PBUI_ratio(n)      — n × size on the alternate axis (enforces an aspect ratio)
PBUI_em(n)         — n × nearest parent's font size
PBUI_rem(n)        — n × root box's font size
PBUI_vw(n)         — n × viewport width
PBUI_vh(n)         — n × viewport height


### PBUI_vh

```c
#define PBUI_vh(x)
```

a fraction of the current view height [0-1]


### PBUI_size2

```c
#define PBUI_size2(x, y)
```

Shorthand constructors for two-component size and alignment types.


### PBUI_v2

```c
#define PBUI_v2(x, y)
```

Shorthand vector constructors.


### PBUI_rgb

```c
#define PBUI_rgb(r, g, b)
```

Color literal macros. All component values are in [0, 1] unless noted.

PBUI_rgb(`r`,`g`,`b`)        — opaque RGB color
PBUI_rgba(`r`,`g`,`b`,a)     — RGBA color with explicit alpha
PBUI_hex(0xRRGGBB)     — opaque color from 24-bit hex
PBUI_hexa(0xRRGGBBAA)  — color with alpha from 32-bit hex


### PBUI_rgba

```c
#define PBUI_rgba(r, g, b, a)
```

Color literal macros. All component values are in [0, 1] unless noted.

PBUI_rgb(`r`,`g`,`b`)        — opaque RGB color
PBUI_rgba(`r`,`g`,`b`,`a`)     — RGBA color with explicit alpha
PBUI_hex(0xRRGGBB)     — opaque color from 24-bit hex
PBUI_hexa(0xRRGGBBAA)  — color with alpha from 32-bit hex


### PBUI_hex

```c
#define PBUI_hex(hex)
```

Color literal macros. All component values are in [0, 1] unless noted.

PBUI_rgb(r,g,b)        — opaque RGB color
PBUI_rgba(r,g,b,a)     — RGBA color with explicit alpha
PBUI_hex(0xRRGGBB)     — opaque color from 24-bit `hex`
PBUI_hexa(0xRRGGBBAA)  — color with alpha from 32-bit `hex`


### PBUI_hexa

```c
#define PBUI_hexa(hex)
```

Color literal macros. All component values are in [0, 1] unless noted.

PBUI_rgb(r,g,b)        — opaque RGB color
PBUI_rgba(r,g,b,a)     — RGBA color with explicit alpha
PBUI_hex(0xRRGGBB)     — opaque color from 24-bit `hex`
PBUI_hexa(0xRRGGBBAA)  — color with alpha from 32-bit `hex`


### PBUIBoxEach

```c
#define PBUIBoxEach(box)
```

Iterate over a linked list of sibling boxes starting at `box`.
Usage: for PBUIBoxEach(root->firstChild) { ... it ... }


### PBStringWordScan

```c
i64 PBStringWordScan(PBStrSlice str,
                     i64        index,
                     i64        move);
```

- Returns: the delta (in bytes) that `index` would have to `move` to start at the next/previous word boundary Note: `move` is number of words to `move` by (can be positive or negative)

### PBStringCodepointScan

```c
i64 PBStringCodepointScan(PBStrSlice str,
                          i64        index,
                          i64        move);
```

- Returns: the delta (in bytes) that `index` would have to `move` in the `str` to start at the next/previous codepoint(s) Note: `move` is number of codepoints to `move` by (can be positive or negative)

### PBStringReplace

```c
PBStrSlice PBStringReplace(PBArena*   arena,
                           PBStrSlice text,
                           i64        index,
                           i64        remove_count,
                           PBStrSlice insert);
```

Applies a splice operation to the string, starting at `index` and removing up to `remove_count`, and inserting the `insert` `text`


### PBStringFromCodepoint

```c
PBStrSlice PBStringFromCodepoint(PBArena* arena,
                                 u32      codepoint);
```

- Returns: a PBString from a given `codepoint` (up to 4 bytes long)

### PBStringFind

```c
u64 PBStringFind(PBStrSlice str,
                 PBStrSlice search,
                 u64        start_index);
```

Find the offset of a substring, only looking for matches from `start_index`. Returns the length of the string if the substring is not found.


### PBUISizeMake

```c
PBUISize PBUISizeMake(PBUISizeKind kind,
                      f32          value,
                      f32          strictness);
```

Construct a `PBUISize`


### PBUISize2Make

```c
PBUISize2 PBUISize2Make(PBUISize x,
                        PBUISize y);
```

Construct a `PBUISize2`


### PBUIFontMake

```c
PBUIFont PBUIFontMake(PBStrSlice family,
                      f32        size,
                      f32        weight);
```

Construct a `PBUIFont`


### PBUIAlign2Make

```c
PBUIAlign2 PBUIAlign2Make(PBUIAlign x,
                          PBUIAlign y);
```

Construct a `PBUIAlign2`


### PBUIShadowMake

```c
PBUIShadow PBUIShadowMake(PBVector2 offset,
                          f32       blur,
                          f32       spread,
                          PBColor   color,
                          bool      inset);
```

Construct a `PBUIShadow`


### PBUIBorderMake

```c
PBUIBorder PBUIBorderMake(f32     width,
                          PBColor color);
```

Construct a `PBUIBorder`


### PBUIPaddingMake

```c
PBVector4 PBUIPaddingMake(f32 paddingLeft,
                          f32 paddingTop,
                          f32 paddingRight,
                          f32 paddingBottom);
```

Construct a `PBVector4` which represents the inner padding of a box: (left, top, right, bottom)


### PBUICornerRadiusMake

```c
PBVector4 PBUICornerRadiusMake(f32 cornerRadiusTopLeft,
                               f32 cornerRadiusTopRight,
                               f32 cornerRadiusBottomRight,
                               f32 cornerRadiusBottomLeft);
```

Construct a `PBVector4` which represents the corner radius of a box: (top left, top right, bottom right, bottom left)


### PBUI__Vector4FromPadding

```c
PBVector4 PBUI__Vector4FromPadding(PBUIPadding padding);
```


### PBUI__Vector4FromCornerRadius

```c
PBVector4 PBUI__Vector4FromCornerRadius(PBUICornerRadius cornerRadius);
```


### PBUI__TextAlignToAnchor

```c
PBVector2 PBUI__TextAlignToAnchor(PBUITextAlign align);
```

@Internal: converts `PBUITextAlign` to a normalized anchor vector.


### PBUIAxisToString

```c
PBStrSlice PBUIAxisToString(PBUIAxis axis);
```

Convert `PBUIAxis` to string


### PBUIAlignToString

```c
PBStrSlice PBUIAlignToString(PBUIAlign align);
```

Convert `PBUIAlign` to string


### PBUITextAlignToString

```c
PBStrSlice PBUITextAlignToString(PBUITextAlign textAlign);
```

Convert `PBUITextAlign` to string


### PBUIKeyZero

```c
PBUIKey PBUIKeyZero();
```

- Returns: the zero key

### PBUIKeyEquals

```c
bool PBUIKeyEquals(PBUIKey a,
                   PBUIKey b);
```

- Returns: if two keys are equal

### PBUIKeyIsZero

```c
bool PBUIKeyIsZero(PBUIKey a);
```

- Returns: if the key is zero

### PBUIKeyFromString

```c
PBUIKey PBUIKeyFromString(PBUIKey    seedKey,
                          PBStrSlice string);
```

- Returns: a key from a `string` and the seed key

### PBUIKeyFromStringAndIndex

```c
PBUIKey PBUIKeyFromStringAndIndex(PBUIKey    seedKey,
                                  PBStrSlice string,
                                  u32        index);
```

- Returns: a key from a `string`, the seed key, and an `index`

### PBStr

_Declaration source unavailable._

### PBUIBoxNil

```c
PBUIBox* PBUIBoxNil();
```

- Returns: a sentinel/null box

### PBUIBoxIsNil

```c
bool PBUIBoxIsNil(PBUIBox* it);
```

- Returns: if a box is null or "nil"

### PBUIBoxFromKey

```c
PBUIBox* PBUIBoxFromKey(PBUIKey key);
```

look up a box from the previous frame by `key` (may return nil)


### PBUIBoxFindScrollableParent

```c
PBUIBox* PBUIBoxFindScrollableParent(PBUIBox* parent);
```

finds the nearest `parent` with a scroll flag set


### PBUIBoxIterDepthFirstPre

```c
PBUIBoxIter PBUIBoxIterDepthFirstPre(PBUIBox* box,
                                     PBUIBox* root);
```

use for iterating a `box` tree in pre-order


### PBUIBoxIterDepthFirstPost

```c
PBUIBoxIter PBUIBoxIterDepthFirstPost(PBUIBox* box,
                                      PBUIBox* root);
```

use for iterating a `box` tree in post-order


### PBUITopParent

```c
PBUIBox* PBUITopParent();
```

- Returns: the top parent in the stack

### PBUIPushParent

```c
void PBUIPushParent(PBUIBox* box);
```

pushes a new `box` onto the parent stack (new boxes will be created as children of this)


### PBUIPopParent

```c
PBUIBox* PBUIPopParent(PBUIBox* box);
```

pops a `box` off the parent stack, optionally asserts that the popped `box` matches (or just pass 0 otherwise)


### PBDeferLoop

```c
#define PBDeferLoop(begin, end)
```

Generic scope-guard loop: runs `begin`, executes the loop body once, then runs `end`.


### PBUIParent

```c
macro Scope-guarded parent push/pop. Use as: PBUIParent(box) { ... children ... }
```


### PBUIBoxMakeFromKey

```c
PBUIBox* PBUIBoxMakeFromKey(PBUIBoxFlags flags,
                            PBUIKey      key);
```

Create or reuse a box for this frame. If a box with the same `key` existed last frame
its persistent state (scroll, hover timers, .state) is retained.

It is recommended to use `PBUIBoxMakeFromString` instead of this function.


### PBUIBoxMakeFromString

```c
PBUIBox* PBUIBoxMakeFromString(PBUIBoxFlags flags,
                               PBStrSlice   string);
```

Construct a box and add it as a child to the current parent


### PBUIBoxMakeFromStringF

```c
PBUIBox* PBUIBoxMakeFromStringF(PBUIBoxFlags flags,
                                const char*  fmt,
                                ...);
```

Same as `PBUIBoxMakeFromString`, but takes a format string instead


### PBUIBoxKey

```c
PBUIKey PBUIBoxKey(PBStrSlice string,
                   u64        index);
```

Shorthand for: `PBUIKeyFromStringAndIndex`(PBUIActiveSeedKey(), `string`, `index`)


### PBUIBoxSetText

```c
void PBUIBoxSetText(PBUIBox*   box,
                    PBStrSlice string);
```

Set the display text on a `box` (requires `PBUIBoxFlag_DrawText`).


### PBUIBoxSetFixedPosition

```c
void PBUIBoxSetFixedPosition(PBUIBox*  box,
                             PBVector2 pos);
```

Override a `box`'s position absolutely in pixels (requires `PBUIBoxFlag_FloatingX`/Y).


### PBUIBoxSetFixedSize

```c
void PBUIBoxSetFixedSize(PBUIBox*  box,
                         PBVector2 size);
```

Force a `box` to an exact pixel `size` (requires `PBUIBoxFlag_FixedWidth`/Height).


### PBUISignalFromBox

```c
PBUISignal PBUISignalFromBox(PBUIBox* box);
```

Query all pointer-interaction state for a `box` in a single call.


### PBUIBoxFindAtPoint

```c
PBUIBox* PBUIBoxFindAtPoint(PBUIBox*     root,
                            PBVector2    pos,
                            PBUIBoxFlags flags);
```

Walk the box tree from `root` and return the topmost box under `pos` matching `flags`.


### PBUIBoxSetParent

```c
void PBUIBoxSetParent(PBUIBox* box,
                      PBUIBox* parent);
```

Reparent a `box` or insert it after a sibling in the child list.


### PBUIBoxInsertAfter

```c
void PBUIBoxInsertAfter(PBUIBox* box,
                        PBUIBox* sibling);
```


### PBUIBoxScrollIntoView

```c
void PBUIBoxScrollIntoView(PBUIBox* box);
```

Request the nearest scrollable ancestor to scroll this `box` into view.


### PBUIBoxSetDrawCallback

```c
void PBUIBoxSetDrawCallback(PBUIBox*              box,
                            PBUIDrawCallbackProc* callback);
```

Attach a custom draw `callback`; called during draw-command generation. Requires `PBUIBoxEquipDraw`().


### PBUIBoxGetComputedRect

```c
PBRectangle PBUIBoxGetComputedRect(PBUIBox* box);
```

Returns the `box`'s computed screen-space rectangle after layout. Call after `PBUIEndBuild`().


### PBUISetState

```c
void PBUISetState(PBUIState* it);
```

Sets the current global UI state


### PBUIGetState

```c
PBUIState* PBUIGetState();
```

Gets the current global UI state


### PBUIRoot

```c
PBUIBox* PBUIRoot();
```

The root-most box of the current UI state


### PBUITopBox

```c
PBUIBox* PBUITopBox();
```

The last box created in the tree


### PBUIStateGetMemorySize

```c
u64 PBUIStateGetMemorySize();
```

Returns the minimum initial arena size for a UI state allocation


### PBUIStateAlloc

```c
PBUIState* PBUIStateAlloc(PBArena* arena);
```

Allocates and initializes a new UI state


### PBUIStateFree

```c
void PBUIStateFree(PBUIState* statePtr);
```

Frees the UI state and its arena, and sets *statePtr to NULL


### PBUIFrameArena

```c
PBArena* PBUIFrameArena();
```

Returns an arena that is valid for the lifetime of this frame


### PBUIfmt

```c
PBStrSlice PBUIfmt(const char* fmt, ...);
```

Prints a C-style formatted string into the frame arena


### PBUIMeasureText

```c
PBVector2 PBUIMeasureText(PBUIFont   font,
                          PBStrSlice text,
                          f32        maxWidth);
```

Measures the `text` size with the given `font`, optionally with a `maxWidth` (set to 0 for none)


### PBUIBeginBuild

```c
void PBUIBeginBuild(PBRectangle     window,
                    PBUIWindowInput input);
```

Equivalent to calling `PBUIBeginFrame` then `PBUIBeginLayout`


### PBUIEndBuild

```c
void PBUIEndBuild();
```

Equivalent to calling `PBUIEndFrame` then `PBUIEndLayout`


### PBUIBeginFrame

```c
void PBUIBeginFrame(PBRectangle     window,
                    PBUIWindowInput input);
```

Starts a UI tree build (call this _once_ per frame/build)


### PBUIEndFrame

```c
void PBUIEndFrame();
```

Ends a UI tree build (call this _once_ per frame/build)


### PBUIBeginLayout

```c
void PBUIBeginLayout();
```

Begins a layout pass, can be called multiple times per frame/build


### PBUIEndLayout

```c
void PBUIEndLayout();
```

Ends a layout pass, can be called multiple times per frame/build


### PBUICalcSizesStandalone

```c
void PBUICalcSizesStandalone(PBUIBox* root,
                             PBUIAxis axis);
```


### PBUICalcSizesUpwardsDependent

```c
void PBUICalcSizesUpwardsDependent(PBUIBox* root,
                                   PBUIAxis axis);
```


### PBUICalcSizesDownwardsDepenedent

```c
void PBUICalcSizesDownwardsDepenedent(PBUIBox* root,
                                      PBUIAxis axis);
```


### PBUILayoutEnforceConstraints

```c
void PBUILayoutEnforceConstraints(PBUIBox* root,
                                  PBUIAxis axis);
```


### PBUILayoutPosition

```c
void PBUILayoutPosition(PBUIBox* root,
                        PBUIAxis axis);
```


### PBUILayoutRoot

```c
void PBUILayoutRoot(PBUIBox* root,
                    PBUIAxis axis);
```

Applies a full layout pass along the given `axis`


### PBUIOutputDrawCommands

```c
PBUIDrawCommandArray PBUIOutputDrawCommands(PBArena*   arena,
                                            PBUIState* state);
```

Outputs a list of draw commands for the UI tree


### PBUIKeyPressed

```c
bool PBUIKeyPressed(PBKeyboardKey key);
```

- Returns: true if the `key` was pressed this frame (exactly once)

### PBUIKeyReleased

```c
bool PBUIKeyReleased(PBKeyboardKey key);
```

- Returns: true if the `key` was pressed this frame (exactly once)

### PBUIKeyRepeat

```c
bool PBUIKeyRepeat(PBKeyboardKey key);
```

- Returns: true if the `key` was repeated this frame (once per `key` repeat, in the case where a `key` is held down)

### PBUIKeyPressedOrRepeat

```c
bool PBUIKeyPressedOrRepeat(PBKeyboardKey key);
```

- Returns: `PBUIKeyPressed`() || `PBUIKeyReleased`()

### PBUIKeyDown

```c
bool PBUIKeyDown(PBKeyboardKey key);
```

- Returns: true if the `key` is currently being held down

### PBUIEventOfType

```c
const PBEvent* PBUIEventOfType(PBEventType    type,
                               const PBEvent* after);
```

Returns the first event of the given `type` this frame, optionally starting `after` a given event.
Pass NULL for `after` to start from the beginning. Returns NULL if no matching event is found.


### PBUIGetEvent

```c
const PBEvent* PBUIGetEvent(PBUIBox* box);
```

Returns the first event this frame if the mouse is within `box`'s rect, or any event if `box` is NULL.
Returns NULL if there are no events or the mouse is outside the `box`.


### PBUIMousePressed

```c
bool PBUIMousePressed(PBMouseButton button);
```

- Returns: true if the mouse `button` was pressed this frame

### PBUIMouseReleased

```c
bool PBUIMouseReleased(PBMouseButton button);
```

- Returns: true if the mouse `button` was released this frame

### PBUIMouseDown

```c
bool PBUIMouseDown(PBMouseButton button);
```

- Returns: true if the mouse `button` is currently being held down

### PBUIMousePosition

```c
PBVector2 PBUIMousePosition();
```

- Returns: the current mouse position in UI space (dps)

### PBUIDragStart

```c
PBVector2 PBUIDragStart();
```

- Returns: the mouse position when the mouse was first held down

### PBUIDragDelta

```c
PBVector2 PBUIDragDelta();
```

- Returns: the drag delta between `PBUIDragStart`() and `PBUIMousePosition`()

### PBUIScrollAmount

```c
PBVector2 PBUIScrollAmount();
```

- Returns: the current scroll amount from using a mouse wheel or trackpad

### PBUIBoxIsHover

```c
bool PBUIBoxIsHover(PBUIBox* box);
```

- Returns: true if the `box` is currently being hovered by a mouse/pointer

### PBUIBoxIsActive

```c
bool PBUIBoxIsActive(PBUIBox* box);
```

- Returns: true if the `box` is currently active (mouse/pointer pressed but not yet released)

### PBUIBoxIsDown

```c
bool PBUIBoxIsDown(PBUIBox* box);
```

- Returns: true if the `box` is currently down

### PBUIBoxOnPressed

```c
bool PBUIBoxOnPressed(PBUIBox* box);
```

- Returns: true if the `box` is has just been pressed

### PBUIBoxOnReleased

```c
bool PBUIBoxOnReleased(PBUIBox* box);
```

- Returns: true if the `box` is has just been released

### PBUIBoxIsFocused

```c
bool PBUIBoxIsFocused(PBUIBox* box);
```

- Returns: true if the `box` is focused

### PBUIBoxOnClick

```c
bool PBUIBoxOnClick(PBUIBox* box);
```

- Returns: true if the `box` is clicked

### PBUIBoxIsPressed

```c
bool PBUIBoxIsPressed(PBUIBox* box);
```

> **DEPRECATED** prefer `PBUIBoxOnPressed`


### PBUIBoxIsReleased

```c
bool PBUIBoxIsReleased(PBUIBox* box);
```

> **DEPRECATED** prefer `PBUIBoxOnReleased`


### PBUIBoxIsClick

```c
bool PBUIBoxIsClick(PBUIBox* box);
```

> **DEPRECATED** prefer `PBUIBoxOnClick`


### PBUIBoxIsDrag

```c
bool PBUIBoxIsDrag(PBUIBox* box);
```

- Returns: true if the current `box` is being dragged (similar/same to active)

### PBUIBoxOnDrop

```c
bool PBUIBoxOnDrop(PBUIBox* box);
```

- Returns: true if the `box` has just been dropped

### PBUIBoxIsDropTarget

```c
bool PBUIBoxIsDropTarget(PBUIBox* box);
```

- Returns: true if the `box` is currently being targeted for a drop

### PBUIBoxClick

```c
void PBUIBoxClick(PBUIBox* box);
```

Programmatically click a `box`


### PBUIBoxFocus

```c
void PBUIBoxFocus(PBUIBox* box);
```

Programmatically focus a `box`


### PBUISetDragDataSize

```c
void PBUISetDragDataSize(u8* data,
                         u64 size);
```

Set global drag `data`


### PBUIGetDragDataSize

```c
void* PBUIGetDragDataSize(u64 size);
```

Get global drag data


### PBUIBoxOnMount

```c
bool PBUIBoxOnMount(PBUIBox* box);
```

- Returns: true if the `box` was created this frame

### PBUIBoxPointToLocal

```c
PBVector2 PBUIBoxPointToLocal(PBUIBox*  box,
                              PBVector2 point);
```

Converts a `point` in UI-space to local `box`-space


### PBUIBoxGetScroll

```c
PBVector2 PBUIBoxGetScroll(PBUIBox* box);
```

- Returns: the amount that the mouse/touchpad has scrolled on a given `box`

### PBUIGetActiveBox

```c
PBUIBox* PBUIGetActiveBox();
```

- Returns: the currently active box

### PBUIGetHoverBox

```c
PBUIBox* PBUIGetHoverBox();
```

- Returns: the currently hovered box

### PBUISpacer

```c
PBUIBox* PBUISpacer(PBUISize size);
```

Create a gap between two boxes (similar to "margin" in some UI systems)


### PBUIText

```c
PBUIBox* PBUIText(PBUIFont   font,
                  PBStrSlice text);
```

A simple `text` element


### PBUIDiv

```c
PBUIBox* PBUIDiv(PBStrSlice label);
```

A simple divider that expands to fill it's child contents


### PBUIDrawCommmands

```c
void PBUIDrawCommmands(PBUIDrawCommandArray cmds);
```


### PBUIDrawState

```c
void PBUIDrawState(PBArena*   scratch,
                   PBUIState* state);
```

---
`#include <playbit/ui_components.h>`

### PBUINamedRowBegin

```c
int* PBUINamedRowBegin(PBStrSlice name);
```

Begin a named parent row. Must be paired with `PBUINamedRowEnd`


### PBUINamedRowEnd

```c
void PBUINamedRowEnd();
```

End a named parent row


### PBUIRowBegin

```c
int* PBUIRowBegin();
```

Begin a row. Must be paired with `PBUIRowEnd`


### PBUIRowEnd

```c
void PBUIRowEnd();
```

End a row


### PBUINamedColumnBegin

```c
int* PBUINamedColumnBegin(PBStrSlice name);
```

Begin a named parent column. Must be paired with `PBUINamedColumnEnd`


### PBUINamedColumnEnd

```c
void PBUINamedColumnEnd();
```

End a named parent column


### PBUIColumnBegin

```c
int* PBUIColumnBegin();
```

Begin a column. Must be paired with `PBUIColumnEnd`


### PBUIColumnEnd

```c
void PBUIColumnEnd();
```

End a column


### PBUIButtonProps

```c
struct PBUIButtonProps {
    PBStrSlice text;
    bool       disabled;
};
```

    Clickable button. Returns the box; check PBUISignalFromBox(box).click for activation.

    Use `UIButtonP(.text = PBStrLit("OK"))` for named-field construction.

### PBUIButton

```c
int* PBUIButton(PBUIButtonProps props);
```

Construct a button


### PBUISlider

```c
int* PBUISlider(f32* value);
```

Horizontal slider that reads and writes a float `value` in [0, 1]. Check .changed on the signal.


### PBUILabel

```c
int* PBUILabel(PBStrSlice text);
```

Non-interactive `text` label. Sized to `text` content.


### PBUICheckbox

```c
int* PBUICheckbox(bool* value);
```

Toggle checkbox. Reads and writes *value; check `PBUISignalFromBox`(box).changed for updates.


### PBUIColorPicker

```c
int* PBUIColorPicker(int* color);
```

Inline HSV `color` picker panel, writes to `color` on change


### PBUIColorSwatch

```c
int* PBUIColorSwatch(int color);
```

Non-interactive `color` preview rectangle


### PBUIColorPickerSwatch

```c
int* PBUIColorPickerSwatch(int*  color,
                           bool* open);
```

Swatch that toggles a picker popover; *open controls visibility


### PBUIScrollViewBegin

```c
int* PBUIScrollViewBegin(u32 flags);
```

Begin a scrollable container. Pass `PBUIBoxFlag_ScrollX` / `PBUIBoxFlag_ScrollY` to enable axes.
Must be paired with `PBUIScrollViewEnd`.


### PBUIScrollViewEnd

```c
void PBUIScrollViewEnd(int* scroll);
```

Ends a `scroll` view


### PBUIVirtualListCursor

```c
struct PBUIVirtualListCursor {
    PBUIBox* box;
    i64      start; // first item index to render (inclusive)
    i64      end;   // last item index to render (exclusive)
};
```

Virtual list with Y-only scrolling. Only the visible items need to be rendered each frame.

Returns the scroll view box so you can set its size and style.
Must be paired with PBUIVirtualListEnd.

    Usage:
        PBUIVirtualListCursor cursor = PBUIVirtualListBegin(1000, 24.0f);
        list->style.size = ...; // size the viewport
        for (i64 index = cursor.start; index < cursor.end; index += 1)
        {
            // build item i as a child box
        }
        PBUIVirtualListEnd(list);

### PBUIVirtualListBegin

```c
PBUIVirtualListCursor PBUIVirtualListBegin(i64 itemCount,
                                           f32 itemHeight);
```


### PBUIVirtualListEnd

```c
void PBUIVirtualListEnd(PBUIVirtualListCursor cursor);
```


### PBUITooltipExt

```c
int* PBUITooltipExt(int*       box,
                    int        anchor,
                    int        align,
                    PBStrSlice text);
```

Tooltip overlay rendered on top of all other content.
Positions tooltip at a custom `anchor`/alignment, relative to an explicit `box`.


### PBUITooltip

```c
int* PBUITooltip(PBStrSlice text);
```

Construct a tooltip that attaches to the most recently built box


### PBUIImage

```c
int* PBUIImage(u64 imageID);
```

Render an image identified by an opaque backend image ID. Size the box with FixedSize flags.


### PBUITextInputProps

```c
struct PBUITextInputProps {
    PBStrSlice key;         // unique string key for persistent state (cursor position, selection)
    PBStrSlice text;        // current string value; read box->state after edits for updated content
    PBStrSlice placeholder; // hint text shown when the field is empty
    bool       disabled;    // prevents editing when true
};
```

### PBUITextInput

```c
int* PBUITextInput(PBUITextInputProps props);
```

Single-line text input field with full keyboard editing support.

    Use with: `UITextInputP(.key = PBStrLit("search"), .placeholder = PBStrLit("Search..."))`


### PBUITextInputP

```c
macro PBUIBox* PBUITextInputP(props...)
```

Ergonomic helper for `PBUITextInput((PBUITextInputProps){ props... })`


### PBUIDevTools

```c
int* PBUIDevTools(int* inspect);
```

    Developer tools overlay. Pass the PBUIState to inspect for an interactive box-tree viewer
    with live style, size, and rect information. Useful for debugging layout issues.

# Playbit API reference

Playbit's new UI library is an immediate-mode styled API. The UI is composed of a tree of rectangles.

---
`#include <playbit/ui3.h>`

### U3Tree

```c
typedef struct U3Tree U3Tree;
```

### U3Point

```c
typedef union U3Point {
    struct {
        i64 x, y;
    };
    i64 e[2];
} U3Point;
```

### U3Rectangle

```c
typedef union U3Rectangle {
    struct {
        i64 x0, y0, x1, y1;
    };
    struct {
        U3Point p0, p1;
    };
    i64 e[4];
} U3Rectangle;
```

### U3CornerRadius

```c
typedef struct U3CornerRadius {
    f32 topLeft, topRight, bottomRight, bottomLeft;
} U3CornerRadius;
```

### U3Padding

```c
typedef struct U3Padding {
    f32 left, top, right, bottom;
} U3Padding;
```

### U3BoxStyle

```c
typedef struct U3BoxStyle {
    PBColor        fillColor;
    PBColor        strokeColor;
    f32            strokeWidth;
    U3CornerRadius cornerRadius;
} U3BoxStyle;
```

### U3BoxState

```c
typedef struct U3BoxState {
    bool pressed : 1;
    bool released : 1;
    bool hovered : 1;
    bool disabled : 1;
    bool clicked : 1;
} U3BoxState;
```

### U3EventKind

```c
typedef enum U3EventKind {
    // Called when a box is about to be removed from the tree
    U3Event_UNMOUNT,

    // Called when the box should respond to an input event (mouse, keyboard, etc.)
    U3Event_INPUT,

    // Called when a box should layout its children
    U3Event_LAYOUT,

    // Called to ask a box for its preferred sizes
    U3Event_ASK_WIDTH,
    U3Event_ASK_HEIGHT,

    // Called to ask a box for its cursor style
    // Set the event's cursor field if your box sets a cursor.
    U3Event_ASK_CURSOR,

    // Called to try to tab traverse to the box. Set U3Event.consumed if handled.
    U3Event_TAB_TRAVERSE,

    // Called when the box loses keyboard focus
    U3Event_LOSE_FOCUS,

    // Called when a box will be drawn
    U3Event_DRAW_BACKGROUND, // Before descendent boxes.
    U3Event_DRAW_FOREGROUND, // After descendent boxes.
} U3EventKind;
```

### U3Event

```c
typedef struct U3Event {
    // What type of event this is.
    U3EventKind kind;

    // Used by U3Event_INPUT.
    // All input events bubble up the tree.
    // Setting this field to true does *not* stop the bubbling.
    // You are expected to check and update this field as appropriate for your box.
    // e.g. a button uses the macros U3EventConsumeLMBPressed and U3EventWasLMBReleased.
    // The former checks consumed is false and sets it to tree;
    // the latter ignores the consumed field.
    // This way pressing the left mouse button only activates the button if it is the innermost box interested in such events,
    // but releasing the left mouse button is always able to deactivate the button.
    // Also used by U3Event_DRAW_BACKGROUND: set to true to skip drawing descendents.
    // Also used by U3Event_TAB_TRAVERSE: set to true to finish step.
    bool consumed;

    // Additional data specific to each type of event.
    union {
        // For U3Event_INPUT: the structure from the system containing more information about the input event.
        const PBEventAny* _Nullable data;

        // For U3Event_ASK_WIDTH and U3Event_ASK_HEIGHT.
        struct {
            // Output.
            i64 sizePx;

            // Input. If non-null: for U3Event_ASK_WIDTH, this is the available height;
            // for U3Event_ASK_HEIGHT, this is the available width.
            const i64* _Nullable otherSizePxIfKnown;
        } askSize;

        PBSysCursorStyle cursor; // Output.
    };
} U3Event;
```

An event that is sent to boxes' event handlers. See U3EventHandler.

### U3AttributedString

```c
typedef struct U3AttributedString U3AttributedString;
```

For U3Event_ASK_WIDTH and U3Event_ASK_HEIGHT.

### U3AttributedStringArray

```c
typedef PBArrayType(U3AttributedString* _Nonnull) U3AttributedStringArray;
```

For U3Event_ASK_WIDTH and U3Event_ASK_HEIGHT.

### U3Key

```c
typedef struct U3Key {
    i64 value;
} U3Key;
```

A key that uniquely identifies a box among its siblings.

### U3PrimaryAxisAlignment

```c
typedef enum U3PrimaryAxisAlignment {
    U3PrimaryAxisAlignment_START,
    U3PrimaryAxisAlignment_END,
    U3PrimaryAxisAlignment_CENTER,
    U3PrimaryAxisAlignment_SPACE_EVENLY,
    U3PrimaryAxisAlignment_SPACE_BETWEEN,
    U3PrimaryAxisAlignment_SPACE_AROUND,
} U3PrimaryAxisAlignment;
```

### U3SecondaryAxisAlignment

```c
typedef enum U3SecondaryAxisAlignment {
    U3SecondaryAxisAlignment_DEFAULT,
    U3SecondaryAxisAlignment_START,
    U3SecondaryAxisAlignment_END,
    U3SecondaryAxisAlignment_CENTER,
    U3SecondaryAxisAlignment_STRETCH,
} U3SecondaryAxisAlignment;
```

For U3FlexDirection_HORIZONTAL, the secondary axis is the vertical axis.
For U3FlexDirection_VERTICAL, the secondary axis is the horizontal axis.

### U3FlexDirection

```c
typedef enum U3FlexDirection {
    U3FlexDirection_VERTICAL,
    U3FlexDirection_HORIZONTAL,
} U3FlexDirection;
```

### U3BoxLayout

```c
typedef struct U3BoxLayout {
    // Overrides the values returned from U3Event_ASK_WIDTH/HEIGHT.
    // Set a field to zero if you don't want a fixed size on that axis.
    PBSize fixedSizeDp;

    union {
        // For child boxes of a flex box parent:
        struct {
            U3SecondaryAxisAlignment secondaryAxisAlignment;

            // If true, then the box is treated as having no size on the primary axis.
            // Then, after all other layout is done, any remaining space in the parent is distributed equally to all boxes with this flag set.
            bool primaryAxisGrow;
        } flex;
    };
} U3BoxLayout;
```

Describes the information the parent box needs to layout this box.

### U3EventHandler

```c
typedef void (U3Box * _Nonnull, U3Event * _Nonnull) U3EventHandler;
```

For child boxes of a flex box parent:

### U3BoxArray

```c
typedef PBArrayType(U3Box* _Nonnull) U3BoxArray;
```

For child boxes of a flex box parent:

### U3TreeAlloc

```c
U3Tree* U3TreeAlloc(PBMem    mem,
                    PBWindow window);
```

Allocate a new UI tree.


### U3TreeGetRoot

```c
U3Box* U3TreeGetRoot(U3Tree* tree);
```

Get the root box from the `tree`.


### U3TreeSetAdditionalScaleFactor

```c
void U3TreeSetAdditionalScaleFactor(U3Tree* tree,
                                    f32     additionalScale);
```

Set the additional scale factor of the `tree`.


### U3TreeUpdate

```c
void U3TreeUpdate(U3Tree*           tree,
                  U3Box*            fromBox,
                  const PBEventAny* optionalEvent);
```

Start a `tree` update.
If an `PBEvent` is passed, it will be forwarded to the relevant boxes via `U3Event_INPUT`.
This can be called multiple times before `U3TreeRender` if needed.


### U3TreeRender

```c
void U3TreeRender(U3Tree* tree);
```

End a `tree` update.
This removes any boxes from the `tree` that are no longer needed,
performs layout, draws the window, and finally deallocates temporary allocations such as U3Fragments.


### U3FindBoxAtPoint

```c
U3Box* U3FindBoxAtPoint(U3Box*  box,
                        U3Point point);
```

Find the front-most `box` intersecting the given `point` within the specified `box`.


### U3Contains

```c
bool U3Contains(U3Box* maybeAncestor,
                U3Box* maybeDescendent,
                bool   allowEquality);
```

Check if one box is an ancestor of another box.
If `maybeAncestor`=`maybeDescendent`, then `allowEquality` is returned.


### U3ScaleI64

```c
i64 U3ScaleI64(i64 x);
```

Convert a dp value to px, with correct rounding.


### U3ScaleF32

```c
i64 U3ScaleF32(f32 x);
```


### U3GetTree

```c
U3Tree* U3GetTree();
```


### U3GetFocus

```c
U3Box* U3GetFocus();
```

Get the currently focused box in the tree being updated.


### U3GetPointerOver

```c
U3Box* U3GetPointerOver();
```

Get the box that the main pointer is hovering over in the tree being updated.


### U3RectangleContainsPoint

```c
bool U3RectangleContainsPoint(U3Rectangle rect,
                              U3Point     p);
```


### U3PointMake

```c
U3Point U3PointMake(i64 x,
                    i64 y);
```


### U3Hash

```c
u64 U3Hash(const void* data,
           usize       dataBytes,
           u64         hash);
```


### U3DrawStyle

```c
void U3DrawStyle(const U3BoxStyle* style,
                 U3Rectangle       rect);
```

May be removed in a future version.


### U3BoxIsHidden

```c
bool U3BoxIsHidden(U3Box* box,
                   bool   testAncestors);
```


### U3BoxGetBounds

```c
U3Rectangle U3BoxGetBounds(U3Box* box);
```

Get the bounds of the `box` in `U3Rectangle`, which contains 64-bit integers. In pixels.


### U3BoxGetBoundsAsPBRectangle

```c
PBRectangle U3BoxGetBoundsAsPBRectangle(U3Box* box);
```

Get the bounds of the `box` in `PBRectangle`, which contains floating-point numbers. Suitable for passing to the PBDraw* family of functions.


### U3BoxMove

```c
void U3BoxMove(U3Box*             box,
               U3Rectangle        bounds,
               const U3Rectangle* clipRect,
               const U3Rectangle* reserved);
```

Only call if you are the parent of the `box`.
Move a `box` and, optionally, set its clip rectangle (which is intersected with its ancestors' clip rectangles).


### U3BoxGetData

```c
void* U3BoxGetData(U3Box* box);
```

Only call if you implement the `box`.
Get the implementor's data for the `box`.
This is N bytes of memory for custom use, where N is passed to `U3BoxMake` when the `box` is first created.
This cannot be resized. It is freed automatically when the `box` is removed.


### U3BoxGetOnEvent

```c
U3EventHandler* U3BoxGetOnEvent(U3Box* box);
```

Get the "onEvent" function the `box` uses, that was passed to `U3BoxMake`.


### U3BoxSetOnEvent

```c
void U3BoxSetOnEvent(U3Box*          box,
                     U3EventHandler* handler);
```


### U3BoxGetParent

```c
U3Box* U3BoxGetParent(U3Box* box);
```

Get the parent `box`, or NULL if the `box` is the root.


### U3BoxGetChild

```c
U3Box* U3BoxGetChild(U3Box* box,
                     u32    index);
```

Get the Nth child of the `box`, where 0<=N<`U3BoxGetChildrenLen`.


### U3BoxGetChildrenLen

```c
u32 U3BoxGetChildrenLen(U3Box* box);
```

Get the number of children of the `box`.


### U3BoxAskSize

```c
i64 U3BoxAskSize(U3Box*     box,
                 const i64* otherSizePxIfKnown,
                 i8         s);
```

Ask the `box` for its size. Returns px.
This either sends `U3Event_ASK_WIDTH` or `U3Event_ASK_HEIGHT` to the `box`'`s` event handler,
or the `box` has a fixed sized in its `U3BoxLayout`, then that will be scaled and returned instead.
The `otherSizePxIfKnown` parameter is used for boxes where their size on one axis depending on the space available on the other axis.
For example, with wrapped LTR text, its height increases as the available width decreases.


### U3BoxAskCursor

```c
PBSysCursorStyle U3BoxAskCursor(U3Box* box);
```

Ask the `box` for its cursor style. Returns `PBSysCursorStyle_DEFAULT` if the `box` doesn't set a cursor style.
This sends `U3Event_ASK_CURSOR` to the `box`'s event handler,


### U3BoxMake

```c
U3Box* U3BoxMake(U3Box*             parentBox,
                 U3Key              keyInParent,
                 const U3BoxLayout* positionInParent,
                 U3EventHandler*    onEvent,
                 usize              dataBytes);
```

This either creates a new box or finds an existing child box of the specified parent.
The latter occurs when the key matches an existing child, the former occurs when it does not.
If a new box is created, its event handler is set to the provided value and its data structure is allocated with the given size.
The layout parameters are always updated.


### U3BoxDeleteChild

```c
void U3BoxDeleteChild(U3Box* parent,
                      usize  index);
```

Immediately remove a box from the tree.


### U3BoxSetHidden

```c
void U3BoxSetHidden(U3Box* box,
                    bool   hidden);
```

Hide or show a `box`. A `box` is only shown if it and all its ancestors are shown.


### U3BoxSetStyle

```c
void U3BoxSetStyle(U3Box*            box,
                   const U3BoxStyle* style);
```

May be removed in a future version.


### U3BoxGetStyle

```c
const U3BoxStyle* U3BoxGetStyle(U3Box* box);
```


### U3BoxGetLayout

```c
U3BoxLayout U3BoxGetLayout(U3Box* box);
```

Get the layout parameters on the `box`.


### U3BoxSetFocus

```c
void U3BoxSetFocus(U3Box* box);
```

Give keyboard focus to the `box`. Only call if you implement the `box`.
The `box` that previously had keyboard focus is sent `U3Event_LOSE_FOCUS`.


### U3BoxGetClippedBounds

```c
U3Rectangle U3BoxGetClippedBounds(U3Box* box);
```

Get the intersection of the `box``s bounds with its and its ancestors` clips, where they exist.


### U3BoxProcessEvent

```c
void U3BoxProcessEvent(U3Box*   box,
                       U3Event* event);
```

Updates the `box`'s state from the `event` (passively)


### U3BoxWasClicked

```c
bool U3BoxWasClicked(U3Box* box);
```

Returns true if the `box` was clicked (and consumes the signal)


### U3BoxSetDisabled

```c
void U3BoxSetDisabled(U3Box* box,
                      bool   disabled);
```

Prevents the click signal from firing on the `box` (including passive signals)


### U3BoxIsDisabled

```c
bool U3BoxIsDisabled(U3Box* box);
```

Sets the `box` disabled signal


### U3BoxGetState

```c
U3BoxState U3BoxGetState(U3Box* box);
```

Returns the `box` state (updated by `U3BoxProcessEvent`)


### U3BoxSetLayout

```c
void U3BoxSetLayout(U3Box*       box,
                    U3BoxLayout* layout);
```


### U3ButtonFn

```c
typedef void (void * _Nullable) U3ButtonFn;
```

### U3ButtonMake

```c
U3Box* U3ButtonMake(U3Box*              parentBox,
                    U3Key               keyInParent,
                    const U3BoxLayout*  positionInParent,
                    U3AttributedString* label,
                    U3ButtonFn*         fn,
                    void*               context);
```


### U3ButtonWasClicked

```c
bool U3ButtonWasClicked(U3Box* button);
```


### U3ButtonSetDisabled

```c
void U3ButtonSetDisabled(U3Box* button,
                         bool   disabled);
```


### U3CheckMake

```c
U3Box* U3CheckMake(U3Box*              parentBox,
                   U3Key               keyInParent,
                   const U3BoxLayout*  positionInParent,
                   U3AttributedString* label,
                   bool                isChecked);
```


### U3CheckWasClicked

```c
bool U3CheckWasClicked(U3Box* check);
```


### U3ColorPickerMake

```c
U3Box* U3ColorPickerMake(U3Box*             parentBox,
                         U3Key              keyInParent,
                         const U3BoxLayout* positionInParent);
```


### U3ColorPickerSetColor

```c
void U3ColorPickerSetColor(U3Box*  picker,
                           PBColor color);
```


### U3ColorPickerGetColor

```c
PBColor U3ColorPickerGetColor(U3Box* picker);
```


### U3ColorPickerWasChangedByUser

```c
bool U3ColorPickerWasChangedByUser(U3Box* picker);
```


### U3TextMake

```c
U3Box* U3TextMake(U3Box*              parentBox,
                  U3Key               keyInParent,
                  const U3BoxLayout*  positionInParent,
                  U3AttributedString* content,
                  u32                 flags);
```


### U3TextSetContent

```c
void U3TextSetContent(U3Box*              box,
                      U3AttributedString* content);
```


### U3TextSetOverrideColor

```c
void U3TextSetOverrideColor(U3Box*   box,
                            PBColor* color);
```


### U3TextHitTest

```c
u64 U3TextHitTest(U3Box*  textBox,
                  U3Point point);
```

The `point` is in window coordinates. The result is the byte offset from the start of the text string.


### U3BodyMake

```c
U3Box* U3BodyMake(U3Box*             parentBox,
                  U3Key              keyInParent,
                  const U3BoxLayout* positionInParent,
                  bool               hasCaret);
```

Create a new body box, or match an existing box based on `parentBox`/`keyInParent`.


### U3BodyMakeTextSelectable

```c
void U3BodyMakeTextSelectable(U3Box* bodyBox,
                              U3Box* textBox,
                              i64    logicalIndex);
```

Register a descendent text box within the body box as containing selectable text.
The logical indices determine the order of text selection.


### U3BodySetScrollBox

```c
void U3BodySetScrollBox(U3Box* bodyBox,
                        U3Box* scrollBox);
```

Set the scroll box the body box should use when it needs to scroll the caret into view.


### U3BodyGetSelection

```c
void U3BodyGetSelection(U3Box* box,
                        i64*   caretPartLogicalIndex,
                        i64*   anchorPartLogicalIndex,
                        u32*   caretOffsetInPart,
                        u32*   anchorOffsetInPart);
```

Get the current range of selected text.


### U3BodySetSelection

```c
void U3BodySetSelection(U3Box* box,
                        i64    caretPartLogicalIndex,
                        i64    anchorPartLogicalIndex,
                        u32    caretOffsetInPart,
                        u32    anchorOffsetInPart,
                        bool   scrollCaretIntoView);
```

Set the range of selected text, and optionally scroll the caret into view (see `U3BodySetScrollBox`).


### U3BodyKeyDown

```c
bool U3BodyKeyDown(U3Box*                 box,
                   const PBKeyboardEvent* ev);
```

Simulate a key down event. Returns true if handled.


### U3BodyUserSelectingText

```c
bool U3BodyUserSelectingText(U3Box* box);
```

Test if the user is currently dragging a text selection.


### U3BodyExpect

```c
U3Box* U3BodyExpect(U3Box* box);
```

Panic if the `box` is not a Body.


### U3InputFieldMake

```c
U3Box* U3InputFieldMake(U3Box*             parentBox,
                        U3Key              keyInParent,
                        const U3BoxLayout* positionInParent);
```


### U3InputFieldMakeMultiline

```c
U3Box* U3InputFieldMakeMultiline(U3Box*             parentBox,
                                 U3Key              keyInParent,
                                 const U3BoxLayout* positionInParent);
```

U3InputFieldMakeMultiline adds a multi-line input field to `parentBox`. Text wraps, the field scrolls vertically, and Enter inserts a newline (WasEnterPressed never fires). Default height is three lines; override with `U3BoxLayout.fixedSizeDp.height`.


### U3InputFieldMakeWithMPObject

```c
U3Box* U3InputFieldMakeWithMPObject(U3Box*             parentBox,
                                    U3Key              keyInParent,
                                    const U3BoxLayout* positionInParent,
                                    PBMPObject*        object);
```


### U3InputFieldWasEdited

```c
bool U3InputFieldWasEdited(U3Box* box);
```


### U3InputFieldBufferDelete

```c
void U3InputFieldBufferDelete(U3Box* box,
                              u32    at,
                              u32    len);
```


### U3InputFieldBufferInsert

```c
void U3InputFieldBufferInsert(U3Box*     box,
                              u32        at,
                              PBStrSlice text);
```


### U3InputFieldBufferSetColor

```c
void U3InputFieldBufferSetColor(U3Box*  box,
                                u32     at,
                                u32     len,
                                PBColor color);
```


### U3InputFieldBufferSetFontFamily

```c
void U3InputFieldBufferSetFontFamily(U3Box* box,
                                     u32    at,
                                     u32    len,
                                     u32    fontFamily);
```


### U3InputFieldBufferSetWeight

```c
void U3InputFieldBufferSetWeight(U3Box* box,
                                 u32    at,
                                 u32    len,
                                 f32    weight);
```


### U3InputFieldBufferGetColor

```c
bool U3InputFieldBufferGetColor(U3Box*   box,
                                u32      at,
                                u32      len,
                                PBColor* color);
```


### U3InputFieldBufferGetFontFamily

```c
bool U3InputFieldBufferGetFontFamily(U3Box* box,
                                     u32    at,
                                     u32    len,
                                     u32*   fontFamily);
```


### U3InputFieldBufferGetWeight

```c
bool U3InputFieldBufferGetWeight(U3Box* box,
                                 u32    at,
                                 u32    len,
                                 f32*   weight);
```


### U3InputFieldOnChangeFn

```c
typedef bool (U3Box * _Nonnull, PBStrSlice, void * _Nullable) U3InputFieldOnChangeFn;
```

### U3InputFieldOnChange

```c
void U3InputFieldOnChange(U3Box*                  box,
                          U3InputFieldOnChangeFn* fn,
                          void*                   context);
```


### U3InputFieldGetSelection

```c
void U3InputFieldGetSelection(U3Box* box,
                              usize* caret,
                              usize* anchor);
```


### U3InputFieldSetSelection

```c
void U3InputFieldSetSelection(U3Box* box,
                              usize  caret,
                              usize  anchor,
                              bool   scrollCaretIntoView);
```


### U3InputFieldSetFocus

```c
void U3InputFieldSetFocus(U3Box* box);
```


### U3InputFieldSetText

```c
void U3InputFieldSetText(U3Box*     box,
                         PBStrSlice appText);
```


### U3InputFieldGetTextCopy

```c
PBStr U3InputFieldGetTextCopy(U3Box* box,
                              PBMem  allocator);
```


### U3InputFieldGetTextUnsafe

```c
PBStrSlice U3InputFieldGetTextUnsafe(U3Box* box);
```


### U3InputFieldSetPlaceholderText

```c
void U3InputFieldSetPlaceholderText(U3Box*     box,
                                    PBStrSlice placeholderText);
```


### U3InputFieldWasEnterPressed

```c
bool U3InputFieldWasEnterPressed(U3Box* box);
```


### U3InputFieldWasTabPressed

```c
bool U3InputFieldWasTabPressed(U3Box* box);
```


### U3InputFieldWasEscapePressed

```c
bool U3InputFieldWasEscapePressed(U3Box* box);
```


### U3UtilMake

```c
U3Box* U3UtilMake(U3Box*             parentBox,
                  U3Key              keyInParent,
                  const U3BoxLayout* positionInParent,
                  PBColor            fillColor,
                  f32                cornerRadiusDp,
                  PBColor            strokeColor,
                  f32                strokeWidthDp,
                  bool               clip);
```


### U3UtilExpect

```c
U3Box* U3UtilExpect(U3Box* box);
```

Panic if the `box` is not a Util.


### U3ScrollMake

```c
U3Box* U3ScrollMake(U3Box*             parentBox,
                    U3Key              keyInParent,
                    const U3BoxLayout* positionInParent,
                    bool               scrollHorizontally,
                    bool               scrollVertically,
                    bool               alwaysHideBars);
```


### U3ScrollGetState

```c
void U3ScrollGetState(U3Box* scroll,
                      f64*   outPosX,
                      f64*   outPosY,
                      f64*   outMaxPosX,
                      f64*   outMaxPosY);
```


### U3ScrollSetState

```c
void U3ScrollSetState(U3Box* scroll,
                      f64    inPosX,
                      f64    inPosY);
```


### U3ScrollLayoutNow

```c
void U3ScrollLayoutNow(U3Box* scroll);
```


### U3ScrollExpect

```c
U3Box* U3ScrollExpect(U3Box* box);
```

Panic if the `box` is not a Scroll.


### U3FlexParams

```c
typedef struct U3FlexParams {
    U3FlexDirection direction;

    // The spacing between each pair of child boxes.
    f32 childSpacingDp;

    // The spacing between the edges of the flex box and its children.
    U3Padding paddingDp;

    U3PrimaryAxisAlignment primaryAxisAlignment;

    // default for the children, unless otherwise specified in U3BoxLayout.secondaryAxisAlignment
    U3SecondaryAxisAlignment secondaryAxisAlignment;
} U3FlexParams;
```

Parameters determining how a flex box lays out its children.

### U3FlexMake

```c
U3Box* U3FlexMake(U3Box*             parentBox,
                  U3Key              keyInParent,
                  const U3BoxLayout* positionInParent,
                  U3FlexParams       params);
```


### U3FlexExpect

```c
U3Box* U3FlexExpect(U3Box* box);
```

Panic if the `box` is not a Flex.


### U3AttributedStringMake

```c
U3AttributedString* U3AttributedStringMake(PBStrSlice str,
                                           u32        fontFamily,
                                           f32        size,
                                           u32        weight,
                                           PBColor    color);
```

Create an immutable string with styling attribuets.
This is wrapper for `U3AttributedStringMake2`, which allows passing more attribute types.
The returned pointer is valid until the next call to `U3TreeRender`.


### U3AttributedStringMake2

```c
U3AttributedString* U3AttributedStringMake2(PBStrSlice          str,
                                            PBSysTextAttribute* attributes,
                                            usize               attributesLen);
```

Create an immutable string with styling `attributes`.
This is the fully-featured version of `U3AttributedStringMake`, which only allows the most common `attributes` to be passed.
The returned pointer is valid until the next call to `U3TreeRender`.


### U3AttributedStringConcatenate

```c
U3AttributedString* U3AttributedStringConcatenate(U3AttributedString* first, ...);
```

Concatenate together attributed strings. Terminate the varargs with NULL.


### U3AttributedStringConcatenateArray

```c
U3AttributedString* U3AttributedStringConcatenateArray(U3AttributedString* array,
                                                       usize               arrayLen);
```

Concatenate together attributed strings with an `array`.


### U3AttributedStringGetHash

```c
u64 U3AttributedStringGetHash(U3AttributedString* string);
```

Get a hash of the contents of the attributed `string`, included both the `string` and its attributes.


### PBMPShareAndJoinMake

```c
U3Box* PBMPShareAndJoinMake(U3Box*             parentBox,
                            U3Key              keyInParent,
                            const U3BoxLayout* positionInParent,
                            PBMPDoc*           _doc,
                            bool*              docChanged);
```
