Playbit API reference

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

It's also available as markdown.

Runtime types

Type aliases

PBSysAudioBuffer

typedef i64 PBSysAudioBuffer;

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

PBSysAudioSound

typedef i64 PBSysAudioSound;

PBSysDate

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

typedef i64 PBSysDuration;

PBSysDuration represents a duration of time, measured in nanoseconds.

PBSysFileMode

typedef u16 PBSysFileMode;

PBSysHandle

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

typedef u16 PBSysHandleName;

PBSysHandleName names special well-defined objects

PBSysObjectId

typedef u32 PBSysObjectId;

PBSysObjectId uniquely identifies a system object

PBSysRights

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

typedef u32 PBSysSignals;

PBSysSignals is a bitset of signals.

PBSysTime

typedef u64 PBSysTime;

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

PBSysWindowCreateTextureFlags

typedef u32 PBSysWindowCreateTextureFlags;

PBSysWindowSetRectFlags

typedef u64 PBSysWindowSetRectFlags;

PBSysWindowStyle

typedef u64 PBSysWindowStyle;

Function pointers

PBSysThreadEntry

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

PBSysThreadEntry

Enums

PBSysCallOp

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_AudioOutputInit = 122,
    PBSysCallOp_AudioSetVolume = 120,
    PBSysCallOp_BundleGetResource = 125,
    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_GuiCursorStyleSet = 69,
    PBSysCallOp_HandleClose = 70,
    PBSysCallOp_HandleDuplicate = 71,
    PBSysCallOp_HandleList = 77,
    PBSysCallOp_NetConnect = 95,
    PBSysCallOp_NetSessionOpen = 90,
    PBSysCallOp_NetSessionId = 93,
    PBSysCallOp_NetSessionOpenStream = 91,
    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_TextureWrite = 106,
    PBSysCallOp_ThreadEnterMain = 59,
    PBSysCallOp_ThreadExit = 30,
    PBSysCallOp_ThreadExitProcess = 31,
    PBSysCallOp_ThreadExitStatus = 47,
    PBSysCallOp_ThreadHostControllerConnect = 79,
    PBSysCallOp_ThreadLogWrite = 32,
    PBSysCallOp_ThreadNetConnect = 42,
    PBSysCallOp_ThreadRead = 76,
    PBSysCallOp_ThreadStart = 33,
    PBSysCallOp_ThreadWindowCreate = 41,
    PBSysCallOp_ThreadWrite = 75,
    PBSysCallOp_WindowClipboardReadText = 107,
    PBSysCallOp_WindowClipboardWriteText = 108,
    PBSysCallOp_WindowCopyTitle = 126,
    PBSysCallOp_WindowCreateTexture = 109,
    PBSysCallOp_WindowCreateTextureFromData = 110,
    PBSysCallOp_WindowFrameSyncEnable = 63,
    PBSysCallOp_WindowInfoGet = 64,
    PBSysCallOp_WindowRendererPackageWrite = 78,
    PBSysCallOp_WindowSetRect = 87,
    PBSysCallOp_WindowSetStyle = 127,
    PBSysCallOp_WindowSetTitle = 80,
    PBSysCallOp_WindowSizeLimitsSet = 128,
    PBSysCallOp_WindowTextplanCreate = 36,
    PBSysCallOp_READ = 9,               // legacy
    PBSysCallOp_WGPU = 10,              // 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

PBSysChannelFlags

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

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

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

typedef enum PBSysCursorStyle PB_ENUM_TYPE(uint16_t){
    PBSysCursorStyle_NONE = 0, //
    PBSysCursorStyle_IMAGE,    //
    PBSysCursorStyle_POINTER,  //
    PBSysCursorStyle_HAND,     //
    PBSysCursorStyle_TEXT,     //
    PBSysCursorStyle_HIDDEN,   //
    PBSysCursorStyle_LOADING,  //
    PBSysCursorStyle_BLOCKED,  //
    PBSysCursorStyle_PAN,      //
    PBSysCursorStyle_SIZEH,    //
    PBSysCursorStyle_SIZEV,    //
    PBSysCursorStyle_SIZENESW, //
    PBSysCursorStyle_SIZENWSE, //
    PBSysCursorStyle_SCROLLNS, //
    PBSysCursorStyle_SCROLLN,  //
    PBSysCursorStyle_SCROLLS,  //
} PBSysCursorStyle;

PBSysErr

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_UNKNOWN = -2000000000, // unknown or internal error
} PBSysErr;

PBSysErr defines error codes

PBSysEventType

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,
} PBSysEventType;

PBSysEventType defines the type of a PBSysEvent entry

PBSysFileListEntryType

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

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

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_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_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_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_RWX = PBSysFileMode_OTHER_RWX << 8,
} PBSysFileOpenFlags;

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

PBSysFileReadFlags

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

PBSysFileWriteFlags

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

PBSysGesturePhase

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

PBSysHandleListFilter

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;

PBSysHandleListFilter are possible filters

PBSysHandleListFlags

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

PBSysHandleListFlags are flags for PBSysHandleList

PBSysKeyboardFlags

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

PBSysKeyboardKey

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

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

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

PBSysNetSessionSignals

typedef enum PB_ENUM_TYPE(uint32_t) {
    /*
    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`.

PBSysObjectType

typedef enum PBSysObjectType PB_ENUM_TYPE(uint16_t){
    PBSysObject_None = 0, // invalid
    PBSysObject_Audio = 16,
    PBSysObject_Bundle = 18,
    PBSysObject_Channel = 7,
    PBSysObject_Clock = 1,
    PBSysObject_File = 12,
    PBSysObject_FileList = 14,
    PBSysObject_Gui = 8,
    PBSysObject_Net = 9,
    PBSysObject_NetSession = 10,
    PBSysObject_Stream = 2,
    PBSysObject_Textplan = 3,
    PBSysObject_Texture = 15,
    PBSysObject_Thread = 4,
    PBSysObject_Window = 6,
} PBSysObjectType;

PBSysObjectType expresses a type of object

PBSysPointerFlags

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

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

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_GET_PROPERTY = 1u << 11,  // can read object properties
    PBSysRight_SET_PROPERTY = 1u << 12,  // can change object properties

    PBSysRight_SAME_RIGHTS = 1u << 31,
};

PBSysScrollFlags

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

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

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

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

PBSysStreamWriteFlags are flags for PBSysStreamWrite

PBSysTextureFormat

typedef enum PB_ENUM_TYPE(u32) {
    PBSysTextureFormat_UNKNOWN,
    PBSysTextureFormat_RGBA8,
} PBSysTextureFormat;

PBSysTextureFormat describes the pixel format of a texture

PBSysThreadFlags

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

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)

PBSysWindowRendererInstructionKind

typedef enum PBSysWindowRendererInstructionKind {
    PBSysWindowRendererInstructionKind_SHAPE,
    PBSysWindowRendererInstructionKind_TEXT,
    PBSysWindowRendererInstructionKind_CLIP_PUSH,
    PBSysWindowRendererInstructionKind_CLIP_POP,
    PBSysWindowRendererInstructionKind_TEXTURE_SET, // set/clear the active texture for SHAPE draws
} PBSysWindowRendererInstructionKind;

PBSysWindowSignals

typedef enum PB_ENUM_TYPE(u32) {
    // 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 finised 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,
} PBSysWindowSignals;

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

Constants

Name Value
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
PBSysWindowCreateTextureFlag_NEAREST 2
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

PBSysBuf

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

PBSysClockInfo

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

PBSysEvent

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;

PBSysEventLegacy

typedef struct PBSysEventLegacy {
    uint16_t type; // PBSysEventLegacyType
    uint8_t  _reserved[6];
    union {
        struct { // PBSysEventLegacy_START
            uint32_t                  flags;
            uint32_t                  sysbufSize;
            void*                     sysbuf;
            PBSysHandleInfo* nullable handles;
            uint32_t                  handlesCount;
            uint64_t                  arg1, arg2; // values passed to PBSysThreadStart
        } start;
        struct { // PBSysEventLegacy_READ
            int32_t     result;
            PBSysHandle from;
            uint64_t    ud; // associated user data
        } read;
        struct { // PBSysEventLegacy_WRITE
            int32_t     result;
            PBSysHandle to;
            uint64_t    ud; // associated user data
        } write;
        struct { // PBSysEventLegacy_INPUT
            uint32_t type;
            uint32_t window;
            uint16_t index;
            uint16_t flags;
            uint32_t value;
            uint32_t extra1;
            uint32_t extra2;
        } input;
        struct { // PBSysEventLegacy_AUDIO_OUT
            uint16_t channelCount;
            uint16_t _reserved;
            uint32_t sampleCount; // per channel
            float    sampleRate;  // HZ
            float*   samples;     // interleaved, channels * sampleCount
        } audioOut;
        struct {                  // PBSysEventLegacy_RESIZE
            uint32_t width;       // TODO(rsms): unit?
            uint32_t height;      // TODO(rsms): unit?
            uint32_t scaleFactor; // percentage. TODO(rsms): change to f32 or f64
        } resize;
        struct { // PBSysEventLegacy_DISPLAY_SYNC
            uint32_t displayId;
            uint32_t width;
            uint32_t height;
            uint32_t scaleFactor;
            uint64_t frameTime; // in PBSysOp_CLOCK space
        } displaySync;
        struct { // PBSysEventLegacy_WGPU_CALLBACK
            PBWgpuCallbackKind            kind;
            PBSysEventLegacy_WgpuCallback data;
        } wgpuCallback;
        struct {                    // PBSysEventLegacy_THREAD_EXIT
            PBSysHandle thread;     // what thread exited
            int32_t     status;     // value passed to PBSysThreadExit
            void*       sysbuf;     // value passed to PBSysThreadStart
            uint32_t    sysbufSize; // value passed to PBSysThreadStart
            uint64_t    arg1, arg2; // values passed to PBSysThreadStart
        } threadExit;
        struct {               // PBSysEventLegacy_TIMER
            PBSysHandle timer; // what timer rang
        } timer;
        struct { // PBSysEventLegacy_SIGNAL
            PBSysSignals signals;
            PBSysHandle  handle;
            uint64_t     ud; // value provided to PBSysObjectObserve
        } signal;
        uint8_t _info[64];
    };
} PBSysEventLegacy;

PBSysEventLegacy describes an event produced by the Playbit system. See sysevents.h for complete definition.

PBSysFileId

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

PBSysFileListEntry

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

PBSysGestureEvent

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;

PBSysHandleInfo

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

PBSysHandlePair

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

PBSysInputEvent

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

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;

PBSysNetConnectConfig

typedef struct PBSysNetConnectConfig {
    u64 flags; // unused, set to 0
} PBSysNetConnectConfig;

PBSysNetSessionConfig

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;

PBSysPenPointerEvent

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

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;

PBSysScrollEvent

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

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

PBSysStr

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

PBSysStreamStats

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;

PBSysTextplanSelection

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

PBSysTextplanSelectionRect

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

PBSysThreadConfig

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;

PBSysWindowConfig

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

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
    u32              _reserved1;
    PBSysWindowStyle style;
    PBSysTime        frameTime; // estimated presentation time of next frame
} PBSysWindowInfo;

PBSysWindowRendererClipItem

typedef struct PBSysWindowRendererClipItem {
    struct {
        f32 x, y, z, w;
    } bounds;
} PBSysWindowRendererClipItem;

PBSysWindowRendererInstruction

typedef struct PBSysWindowRendererInstruction {
    PBSysWindowRendererInstructionKind kind;

    union {
        // a run of renderable "content"
        struct {
            u32 runLength;
        } content;
        // TEXTURE_SET: set active texture; PBSysHandle_INVALID clears to default (no texture)
        struct {
            PBSysHandle texture;
        } setTexture;
    };
} PBSysWindowRendererInstruction;

PBSysWindowRendererPackage

typedef struct PBSysWindowRendererPackage {
    u64 backgroundColor; // 0xAAAARRRRGGGGBBBB

    const PBSysWindowRendererShapeItem* shapes;
    u32                                 shapesLen;
    u32                                 shapeSize;

    const PBSysWindowRendererTextItem* texts;
    u32                                textsLen;
    u32                                textSize;

    const PBSysWindowRendererInstruction* instructions;
    u32                                   instructionsLen;
    u32                                   instructionSize;

    const PBSysWindowRendererClipItem* clips;
    u32                                clipsLen;
    u32                                clipSize;
} PBSysWindowRendererPackage;

PBSysWindowRendererShapeItem

typedef struct PBSysWindowRendererShapeItem {
    struct {
        f32 x, y, z, w;
    } bounds; // (minX, minY, maxX, maxY)

    struct {
        u16 x, y, z, w;
    } cornerRadius; // Per-corner radii (pixels): (tl, tr, br, bl)

    u64 fillColor; // 0xAAAARRRRGGGGBBBB
    u64 fillColors[4];
    u64 strokeColor; // 0xAAAARRRRGGGGBBBB
    f32 strokeWidth; // px
    u32 flags;       // 1=stroke_inside, 2=stroke_outside, 4=clip
    f32 blur;        // px
    f32 opacity;     // 0->1 percent

    // UV sub-rectangle for texture sampling.
    struct {
        f32 x, y;
    } uvMin; // top-left UV
    struct {
        f32 x, y;
    } uvMax; // bottom-right UV

    u8 padding[8];
} PBSysWindowRendererShapeItem;

PBSysWindowRendererTextItem

typedef struct PBSysWindowRendererTextItem {
    struct {
        f32 x, y, z, w;
    } bounds;

    PBSysHandle textPlan;

    u64 overrideColor; // 0xAAAARRRRGGGGBBBB
    u32 flags;         // 1=override color
    u8  padding[4];
} PBSysWindowRendererTextItem;

Runtime system calls

Audio

PBSysAudioBufferCreate

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

Creates a new audio buffer and uploads it to the sound mixer.

PBSysAudioBufferCreateFromFile

PBSysAudioBuffer PBSysAudioBufferCreateFromFile(PBSysHandle audio,
                                                const void* data,
                                                usize       dataSize);

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.

PBSysAudioBufferDestroy

PBSysErr PBSysAudioBufferDestroy(PBSysHandle      audio,
                                 PBSysAudioBuffer buffer);

Destroys an audio buffer (and frees the associated memory with it).

PBSysAudioBufferPlay

PBSysAudioSound PBSysAudioBufferPlay(PBSysHandle      audio,
                                     PBSysAudioBuffer buffer);

Starts playing an instance of an audio buffer.

PBSysAudioOutputInit

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.

PBSysAudioSetVolume

PBSysErr PBSysAudioSetVolume(PBSysHandle audio,
                             f32         volume);

Sets the global volume of the sound mixer.

Bundle

PBSysBundleGetResource

i64 PBSysBundleGetResource(PBSysHandle bundle,
                           const u8*   name,
                           usize       nameLen,
                           u8*         dest,
                           usize       destLen);

PBSysBundleGetResource retrieves a bundles resource, as described by the app's manifest at build time.

Channel

PBSysChannelCreate

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.

PBSysChannelDisableWrite

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.

PBSysChannelRead

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.

PBSysChannelWrite

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.

Clock

PBSysClockMonotonic

PBSysTime PBSysClockMonotonic();

PBSysClockMonotonic returns the current system time

PBSysClockRead

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.

PBSysClockReadInfo

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

PBSysClockReadInfo retrieves information about a clock

Event

PBSysEventPoll

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

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

FileList

PBSysFileListNext

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.

File

PBSysFileListOpen

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.

PBSysFileOpen

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.

PBSysFileRead

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.

PBSysFileWrite

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.

Gui

PBSysGuiCursorStyleSet

PBSysErr PBSysGuiCursorStyleSet(PBSysHandle      gui,
                                u32              pointerId,
                                PBSysCursorStyle style,
                                PBSysHandle      image,
                                u64              flags);

PBSysGuiCursorStyleSet sets the appearance of specified pointer's cursor.

Handle

PBSysHandleClose

PBSysErr PBSysHandleClose(PBSysHandle handle);

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

PBSysHandleDuplicate

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.

PBSysHandleList

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.

Net

PBSysNetConnect

PBSysHandle PBSysNetConnect(PBSysHandle                  net,
                            const u8*                    uri,
                            u32                          uriLen,
                            const PBSysNetConnectConfig* config,
                            u32                          configSize);

PBSysNetConnect opens a stream connected to a network endpoint.

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

tcp:host:port  TCP/IP socket
local:path     Local socket (aka UNIX socket)

The underlying implementation may not support the requested protocol.

The returned stream will have its PBSysStreamSignal_WRITABLE activated when the connection has been established.

PBSysNetSessionOpen

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

PBSysNetSessionOpen opens a Playbit network session

NetSession

PBSysNetSessionId

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

PBSysNetSessionId copies the session identifier bytes of a network session.

PBSysNetSessionOpenStream

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

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

Object

PBSysObjectObserve

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 PBSysEventLegacy.signal 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.

PBSysObjectSignal

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.

Stream

PBSysStreamOpenPipePair

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.

PBSysStreamRead

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

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

PBSysStreamStatsRead

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

PBSysStreamStatsRead retrieves statistics for a stream.

PBSysStreamWrite

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

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

Textplan

PBSysTextplanGetCaretBounds

u64 PBSysTextplanGetCaretBounds(PBSysHandle textPlan,
                                u64         caretTextIndex);

PBSysTextplanGetSelectionRects

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.

PBSysTextplanGetSize

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.

PBSysTextplanHitTest

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

PBSysTextplanLayout

i64 PBSysTextplanLayout(PBSysHandle textPlan,
                        u32         flags,
                        i32         width,
                        i32         height);

PBSysTextplanLayout lays a text document into a rectangular bounding box.

textPlan: The text plan to contain the resulting layout.

flags: Flags bitwise OR-ed together controlling the text layout operation. The available flags are

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.

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.

PBSysTextplanMoveSelection

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

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

PBSysTextplanMoveSelectionToPoint

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.

PBSysTextplanMoveSelectionVertical

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.

Texture

PBSysTextureWrite

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 (RGBA8: 4 bytes per pixel, row-major).

Thread

PBSysThreadEnterMain

void PBSysThreadEnterMain(u64 flags);

PBSysThreadEnterMain

PBSysThreadExit

PBSysErr PBSysThreadExit(PBSysHandle thread,
                         i32         status);

PBSysThreadExit stops a thread and sets its exit status.

PBSysThreadExitProcess

PBSysErr PBSysThreadExitProcess(PBSysHandle thread,
                                i32         status);

PBSysThreadExitProcess terminated the process.

PBSysThreadExitStatus

i32 PBSysThreadExitStatus(PBSysHandle thread);

PBSysThreadExitStatus returns the exit status of thread.

PBSysThreadHostControllerConnect

PBSysHandle PBSysThreadHostControllerConnect(PBSysHandle thread);

Note: Draft API; arguments will change

PBSysThreadLogWrite

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

PBSysThreadLogWrite writes to the runtime log sink for a thread.

PBSysThreadNetConnect

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

Note: Draft API; arguments will change

PBSysThreadRead

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.

PBSysThreadStart

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

PBSysThreadStart starts a new thread.

PBSysThreadWindowCreate

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

PBSysThreadWindowCreate creates a window associated with a thread.

PBSysThreadWrite

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.

Window

PBSysWindowClipboardReadText

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

PBSysWindowClipboardWriteText reads the text from the clipboard.

PBSysWindowClipboardWriteText

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

PBSysWindowClipboardWriteText sets the text on the clipboard.

PBSysWindowCopyTitle

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

PBSysWindowCopyTitle retrieves the title of a window.

PBSysWindowCreateTexture

PBSysHandle PBSysWindowCreateTexture(PBSysHandle                   window,
                                     PBSysTextureFormat            format,
                                     u32                           widthInPx,
                                     u32                           heightInPx,
                                     PBSysWindowCreateTextureFlags 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.

PBSysWindowCreateTextureFromData

PBSysHandle PBSysWindowCreateTextureFromData(PBSysHandle                   window,
                                             PBSysTextureFormat            format,
                                             const void*                   data,
                                             u64                           dataSize,
                                             PBSysWindowCreateTextureFlags 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.

PBSysWindowFrameSyncEnable

PBSysErr PBSysWindowFrameSyncEnable(PBSysHandle window,
                                    u64         flags);

PBSysWindowFrameSyncEnable controls the production of FRAME_SYNC pulses.

PBSysWindowInfoGet

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

PBSysWindowInfoGet retrieves latest window metrics and timing hints.

PBSysWindowRendererPackageWrite

PBSysErr PBSysWindowRendererPackageWrite(PBSysHandle                       window,
                                         const PBSysWindowRendererPackage* package,
                                         usize                             packageSize);

PBSysWindowRendererPackageWrite submits renderer package data for a window.

PBSysWindowSetRect

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.

PBSysWindowSetStyle

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

PBSysWindowSetStyle sets the style of a window.

PBSysWindowSetTitle

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

PBSysWindowSetTitle sets the title of a window.

PBSysWindowSizeLimitsSet

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.

PBSysWindowTextplanCreate

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.

TODO: Proper positioned attributes array.

Playbit API reference


#include <playbit/audio.h>

PBAudio

typedef struct {
    PBSysHandle handle;
} PBAudio;

PBAudioBuffer

typedef struct {
    PBSysAudioBuffer id;
} PBAudioBuffer;

PBAudioSound

typedef struct {
    PBSysAudioSound id;
} PBAudioSound;

PBAudioMain

PBAudio PBAudioMain();

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

PBAudioInit

bool PBAudioInit();

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

PBAudioSetVolume

PBSysErr PBAudioSetVolume(PBAudio audio,
                          f32     volume);

Sets the global volume of all playing sounds.

PBAudioBufferCreate

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

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

PBAudioBufferDestroy

PBSysErr PBAudioBufferDestroy(PBAudio       audio,
                              PBAudioBuffer buffer);

PBAudioBufferPlay

PBAudioSound PBAudioBufferPlay(PBAudio       audio,
                               PBAudioBuffer buffer);

Starts playing an instance of an audio buffer.

Playbit API reference


#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

typedef PBArrayType(i8) PBI8Array;

PBI16Array

typedef PBArrayType(i16) PBI16Array;

PBI32Array

typedef PBArrayType(i32) PBI32Array;

PBI64Array

typedef PBArrayType(i64) PBI64Array;

PBU8Array

typedef PBArrayType(u8) PBU8Array;

PBU16Array

typedef PBArrayType(u16) PBU16Array;

PBU32Array

typedef PBArrayType(u32) PBU32Array;

PBU64Array

typedef PBArrayType(u64) PBU64Array;

PBF32Array

typedef PBArrayType(f32) PBF32Array;

PBF64Array

typedef PBArrayType(f64) PBF64Array;

PBPtrArray

typedef PBArrayType(void*) PBPtrArray;

PBArrayStructStaticAssertLayout

#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

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

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

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

PBAnyArrayRemove removes len elements starting at index start.

PBAnyArrayAlloc

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

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

PBAnyArrayAllocAt

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

PBAnyArrayAllocAt inserts len uninitialized elements at index i.

PBAnyArrayReserve

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

PBAnyArrayReserve ensures at least nitems spare capacity beyond current length.

PBAnyArrayReserveExact

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

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

PBAnyArrayGrow

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

PBAnyArrayGrow grows by at least minavail additional slots.

PBAnyArrayFree

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

PBAnyArrayFree releases backing storage for a.

PBAnyArrayInsert

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.

PBAnyArrayMove

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

PBAnyArrayRot

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

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

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

PBAnyArrayRot64

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

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

macro void PBArrayInit(ArrayType* array)

Initializes array to zero in preparation for use.

PBArrayFrom

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

PBArrayFree

macro void PBArrayFree(ArrayType* array, PBMem ma)

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

PBArrayClear

macro void PBArrayClear(ArrayType* array)

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

PBArrayAt

macro T PBArrayAt(ArrayType* array, usize at)

PBArrayRefAt

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

PBArrayPush

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

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

PBArrayPop

macro T PBArrayPop(ArrayType* array)

Removes the last item in the array.

PBArrayAlloc

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

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

PBArrayAllocAt

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.

PBArrayResize

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.

PBArrayReserve

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

Ensures at least nItems spare capacity beyond current length.

PBArrayReserveExact

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

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

PBArrayShrinkwrap

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.

PBArrayAppend

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.

PBArrayInsert

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.

PBArrayRemove

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

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

PBArrayMove

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

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

PBArrayCmp

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

PBArrayFromSlice

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

PBArraySlice

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

#include <playbit/buf.h>

PBBuf

typedef PBArrayType(u8) PBBuf;

PBBuf is a growable byte buffer, binary compatible with PBU8Array

PBBufFromStrSlice

PBBuf PBBufFromStrSlice(PBMem      ma,
                        PBStrSlice source);

PBBufCStr

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.

PBBufAppendHex

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.

PBBufOf

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

#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)

PBBuf_INIT_WITH_STORAGE

#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

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

PBRingBufEnsureWriteCapacity

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

PBRingBufWriteReserve

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.

PBRingBufProduce

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

usize PBRingBufConsume(PBRingBuf* rb,
                       usize      n);

PBRingBufConsume removes up to n bytes from the logical head.


#include <playbit/hashtable.h>

Fundamental hash table

PBHashTableEqFn

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

PBHashTableHashFn

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

PBHashTable

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

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

PBHashTableInit initializes ht with capacity hint capHint.

PBHashTableFree

void PBHashTableFree(PBHashTable* ht);

PBHashTableFree releases all memory owned by ht.

PBHashTableClear

void PBHashTableClear(PBHashTable* ht,
                      usize        entsize);

PBHashTableClear removes all entries from the hashtable

PBHashTableAssign

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

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

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.

PBHashTableIter

#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

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

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

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

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

PBPoolFree

void PBPoolFree(PBPool* p,
                int     ma);

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

PBPoolEntryAlloc

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.

PBPoolEntryAllocIfRoom

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.

PBPoolEntryFree

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

void PBPoolEntryFreeAll(PBPool* p);

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

PBPoolEntryIsFree

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

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

PBPoolEntries

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

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

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

PBPoolFindEntry

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.

PBPoolIdxIsDead

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

#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)

PBSlotTableFree

void PBSlotTableFree(PBSlotTable* table,
                     PBMem        ma);

PBSlotTableFree frees table back to memory allocator ma

PBSlotTableAdd

#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)

PBSlotTableDel

void PBSlotTableDel(PBSlotTable* table,
                    u32          idx);

PBSlotTableDel frees the entry at idx.

PBSlotTableGet

#define PBSlotTableGet(T, table, idx)

PBSlotTableGet accesses entry with index idx.

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

PBSlotTableIsUsed

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

void PBSlotTableClear(PBSlotTable* table);

PBSlotTableClear frees all entries in one efficient operation.

PBSlotTableBlock

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

PBSlotTable

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

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

PBSlotTableCreate1 is the size-based worker behind PBSlotTableCreate.

PBSlotTableAdd1

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

PBSlotTableAdd1 is the size-based worker behind PBSlotTableAdd.

PBSlotTableGet1

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

typedef PBQueue(void) PBQueueAny;

PBQueueAnyInit

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

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

PBQueueAnyFree

void PBQueueAnyFree(PBQueueAny* q,
                    PBMem       ma);

PBQueueAnyFree releases storage owned by q.

PBQueueAnyLen

u32 PBQueueAnyLen(const PBQueueAny* q);

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

PBQueueAnyPushIfRoom

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

PBQueueAnyPushIfRoom reserves one entry slot at tail without growing q.

PBQueueAnyPush

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

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

PBQueueAnyPop

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

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

PBQueueAnyPopMany

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

PBQueueAnyPopMany pops up to dstCap entries from head into dst.

PBQueueAnyRemove

u32 PBQueueAnyRemove(PBQueueAny* q,
                     u32         limit);

PBQueueAnyRemove removes up to limit newest entries from tail.

PBQueueIter

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

PBQueueAnyIterCreate

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

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:

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

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

PBF32x2

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

PBF32x3

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

PBF32x4

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

PBF32x6

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

PBF32x8

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

PBF32x16

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

PBF32x32

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

PBF32x64

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

PBF16x2

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

PBF16x3

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

PBF16x4

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

PBF16x6

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

PBF16x8

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

PBF16x16

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

PBF16x32

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

PBF16x64

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

PBF16x128

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:

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, which provides the following:


#include <playbit/base.h>

PB_SHORT_NAMES

#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

#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

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

#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

#define PB_NORETURN

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

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

PB_UNUSED

#define PB_UNUSED attribute

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

PB_LIKELY

macro PB_LIKELY(integralexpr)->bool

PB_UNLIKELY

macro PB_UNLIKELY(integralexpr)->bool

PB_CPU_CACHE_LINE_SIZE

#define PB_CPU_CACHE_LINE_SIZE u32

PB_CPU_CACHE_LINE_SIZE defines the CPU L1 cache line size

PB_LIBC

#define PB_LIBC

PB_LIBC is 1 if compiling with libc, 0 if not

PB_SMT

#define PB_SMT 1|0

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

PB_FMT_ATTR

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

#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

#define PB_VARG_DISPATCH(a, ...)

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

PB_VARG_COUNT

#define PB_VARG_COUNT(...)

PB_VARG_COUNT counts macro variable arguments

PB_CONCAT

#define PB_CONCAT(a, b)

PB_CONCAT concatenates preprocessor values

PB_LOCAL_UNIQUE_ID

#define PB_LOCAL_UNIQUE_ID

PB_LOCAL_UNIQUE_ID is a portable version of __COUNTER__

PB_UNIQUE_NAME

macro NAME PB_UNIQUE_NAME(NAME)

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

PB_TMPID

macro NAME PB_TMPID(NAME)

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

PB_DEPRECATED

macro void PB_DEPRECATED([const char* message[, const char* replacement]])

marks a symbol as deprecated

PB_DEPRECATED_REPLACED_BY

macro void PB_DEPRECATED_REPLACED_BY(ID newName)

marks a symbol as deprecated, replaced by a symbol with name newName

PB_UNAVAILABLE

macro void PB_UNAVAILABLE(const char* message)

marks a symbol as unavailable under the current build configuration

PB_GUEST

#define PB_GUEST 1|0

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

PB_GUEST_ONLY

#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

#define PB_GUESTFN

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

PBMustCheck_UNLIKELY

bool PBMustCheck_UNLIKELY(bool unlikely);

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

PBBitsCountLeadingZeroes

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

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

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

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

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

macro bool PBIsPow2(T x)

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

PBAlign2

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

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

Constant-expression version of PBAlign2

PBIsAlign2

macro bool PBIsAlign2(T x, anyuint a)

returns true if x is aligned to a

PBPow2Floor

macro ANYINT PBPow2Floor(ANYINT x)

rounds down x to nearest power of two. Returns 1 if x is 0.

PB_POW2_FLOOR

macro ANYINT PB_POW2_FLOOR(ANYINT x)

Constant-expression implementation of PBPow2Floor. When used as a constant expression, compilation fails if x is 0.

PBPow2Ceil

macro ANYINT PBPow2Ceil(ANYINT x)

rounds up x to nearest power of two.

PB_POW2_CEIL

macro ANYINT PB_POW2_CEIL(ANYINT x)

Constant-expression implementation of PBPow2Ceil.

PBIDivCeil

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

macro T PB_IDIV_CEIL(T x, ANYINT divisor)

Constant-expression implementation of PBIDivCeil.

PBRangesOverlap

macro bool PBRangesOverlap(ANYNUM aStart, ANYNUM aEnd, ANYNUM bStart, ANYNUM bEnd)

PBRangesOverlap returns true if two ranges overlap

PBPanic

macro PBPanic(const char* format, ...)

prints a message to stderr and aborts the process. Includes a stack trace when available. When linking with the "core" version of playbit-c, you have to provide an implementation of _PBPanic

PBPanicOnErr

macro T PBPanicOnErr(T exprWithSysErrResult)

PB_DEBUG

#define PB_DEBUG 1|0

PB_DEBUG is 1 in debug builds, else 0

PBIsType

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

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

macro bool PBTypeIsConst(TYPE type)

Returns true at compile time if type has a const qualifier

PBExpect

macro void PBExpect(ANY truthyValue)

Calls PBPanic if truthyValue is false

PBExpectf

macro void PBExpectf(ANY truthyValue, const char* message, ...)

Calls PBPanic if truthyValue is false alond with a custom message

PBExpectNull

macro void PBExpectNull(ANY e)

Calls PBPanic if e != NULL

PBExpectNotNull

macro T PBExpectNotNull<T>(T e)

Calls PBPanic if e == NULL, otherwise e is returned

PBExpectInMemRegion

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

macro void PBExpectInBounds(T index, T startIndex, T endIndex)

Calls PBPanic if index is outside the range [startIndex .. endIndex)

PBStaticExpectIsType

macro void PBStaticExpectIsType(EXPR value, TYPE type)

Issues compilation error if the type of value is not assignable as type

PBExpectationFailure

macro void PBExpectationFailure(const char* message, ...)

Calls PBPanic with "Expect assertion failed: " plus message

PBOpt

macro type PBOpt(T)

returns a struct type struct { PBSysErr err; T ok; } used for optional results of type T

PBOptOk

macro T PBOptOk(PBOpt(T) opt)

panics if opt.err != 0, returns opt.ok.

PBSysCallOpStr

const char* PBSysCallOpStr(PBSysCallOp arg);

PBSysCallOpStr returns a symbolic string. I.e. PBSysCallOpStr(PBSysCallOp_HandleClose) => "HandleClose"

PBSysErrStr

const char* PBSysErrStr(PBSysErr arg);

PBSysErrStr returns a symbolic string

PBSysEventLegacyTypeStr

const char* PBSysEventLegacyTypeStr(PBSysEventLegacyType arg);

PBSysEventLegacyTypeStr returns a symbolic string

PBSysObjectTypeStr

const char* PBSysObjectTypeStr(PBSysObjectType arg);

PBSysObjectTypeStr returns a symbolic string

PBSysEventTypeStr

const char* PBSysEventTypeStr(PBSysEventType arg);

PBSysEventTypeStr returns a symbolic string

PBSysFileListEntryTypeStr

const char* PBSysFileListEntryTypeStr(PBSysFileListEntryType arg);

PBSysFileListEntryTypeStr returns a symbolic string

PBSysEventStr

u32 PBSysEventStr(const PBSysEvent* event,
                  char*             buf,
                  u32               bufCap);

PBSysEventStr writes a string representation of a PBSysEvent to buf.

PBSysRightsStr

u32 PBSysRightsStr(PBSysRights rights,
                   char*       buf,
                   u32         bufCap);

PBSysRightsStr writes a short string representation of all bits in rights to buf.

PBSysErrOfErrno

PBSysErr PBSysErrOfErrno(int errno_val);

PBSysErrOfErrno returns a PBSysErr value for a libc errno value.

PBStr

typedef struct PBStr {
    u8* nullable v;
    usize        len;
} PBStr;

PBStr represents a fixed-size "owned" array of bytes interpreted as UTF-8 text

PBStrSlice

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

typedef struct PBU8Slice {
    const u8* nullable v;
    usize              len;
} PBU8Slice;

PBU8Slice is a view into an array of bytes

PBPoint

typedef struct PBPoint {
    f32 x, y;
} PBPoint;

PBPoint defines a two-dimensional location

PBSize

typedef struct PBSize {
    f32 width, height;
} PBSize;

PBSize defines a two-dimensional size

PBRect

typedef struct PBRect {
    PBPoint origin;
    PBSize  size;
} PBRect;

PBRect defines a two-dimensional rectangle

PBPointOf

macro PBPoint PBPointOf(f32 x, f32 y)

Constructs a PBPoint

PBSizeOf

macro PBSize PBSizeOf(f32 width, f32 height)

Constructs a PBSize

PBRectOf

macro PBRect PBRectOf(f32 x, f32 y, f32 width, f32 height)

Constructs a PBRect

PBMinF32

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

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

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

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

macro T PBMin(T a, T b) returns the smaller value of the arguments

PBMax

macro T PBMax(T a, T b) returns the larger value of the arguments

PBCheckOverflowAdd

macro PBCheckOverflowAdd(T a, T b, T* dst) -> bool didOverflow

PBExpectNoOverflowAdd

#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

PBStream PBConsole();

PBConsole returns the console stream. If there's no console capability, stream.handle is PBSysHandle_INVALID

PBConsoleWrite

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)


#include <playbit/log.h>

PBLog

void PBLog(const char* format, ...);

PBLog writes a log message (stderr on platforms with stdio)

PBLogv

void PBLogv(const char* format,
            va_list     arg);

PBLogv writes a log message like PBLog, using a va_list.

PBLogWrite

PBSysErr PBLogWrite(PBSysBuf* bufv,
                    u32       bufc);

PBLogWrite writes a string to the console


#include <playbit/handle.h>

PBHandleList

i32 PBHandleList(PBSysHandleInfo* handles,
                 u32              handlesCap);

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

PBHandleFindByName

i32 PBHandleFindByName(PBSysHandleInfo* handles,
                       u32              handlesCap,
                       PBSysHandleName  name);

#include <playbit/signal.h>

PBObserve

void PBObserve(PBSysHandle  handle,
               PBSysSignals signals);

PBObserve sets what signals are to be observed for the object referred to by handle.

PBObserveOnce

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

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


#include <playbit/printf.h>

PBSnprintf

u32 PBSnprintf(char*       buf,
               u32         bufCap,
               const char* fmt,
               ...);

PBSnprintf formats strings using printf-style formatting.

PBVsnprintf

u32 PBVsnprintf(char*       buf,
                u32         bufCap,
                const char* fmt,
                va_list     args);

PBVsnprintf works like PBSnprintf but takes a va_list as input.

PBFprintf

void PBFprintf(PBStream    arg,
               const char* fmt,
               ...);

PBFprintf and PBVfprintf writes a formatted string to a stream

PBVfprintf

void PBVfprintf(PBStream    arg,
                const char* fmt,
                va_list     args);

PBVfprintf writes formatted output to a stream using va_list args.

PBPrintf

void PBPrintf(const char* fmt, ...);

PBPrintf writes formatted output to PBConsole.

PBVprintf

void PBVprintf(const char* fmt,
               va_list     arg);

PBVprintf writes formatted output to PBConsole using va_list.

PBPrint

void PBPrint(const char* cstr);

PBPrint writes a null-terminated string to PBConsole

PBPrintfln

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

u64 PBRand();

PBRand returns the next pseudo-random number

PBRandSeed

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:

See #include <playbit/sys/syscalls/stream.h> for complete list

PBStream

typedef struct {
    PBSysHandle handle;
} PBStream;

PBStreamOpenPipePair

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.

PBStreamRead

i64 PBStreamRead(PBStream stream,
                 void*    dst,
                 usize    nbyte);

PBStreamRead reads up to nbyte bytes into dst.

PBStreamReadv

i64 PBStreamReadv(PBStream        stream,
                  const PBSysBuf* bufs,
                  u32             bufCount,
                  u32             flags);

PBStreamReadv performs vectored read into bufs.

PBStreamWrite

i64 PBStreamWrite(PBStream    stream,
                  const void* src,
                  usize       nbyte);

PBStreamWrite writes nbyte bytes from src.

PBStreamWritev

i64 PBStreamWritev(PBStream        stream,
                   const PBSysBuf* bufs,
                   u32             bufCount,
                   u32             flags);

PBStreamWritev performs vectored write from bufs.

PBStreamClose

PBSysErr PBStreamClose(PBStream stream);

PBStreamClose closes stream handle.


#include <playbit/binsearch.h>

PBBinSearchLessFn

typedef bool (*PBBinSearchLessFn)(const void * _Nonnull, const void * _Nonnull);

PBBinSearchLowerBound

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

macro T PBAbs(T x)

Returns sign-normalized (positive) value of x

PBRound

macro T PBRound(T x)

Round x to nearest whole number

PBSin

macro T PBSin(T x)

PBCos

macro T PBCos(T x)

PBSqrt

macro T PBSqrt(T x)

Square root of x

PBAbsF32

f32 PBAbsF32(f32 x);

PBAbsF32 returns the absolute value of x

PBFloorF32

f32 PBFloorF32(f32 x);

PBFloorF32 rounds x toward negative infinity.

PBClampF32

f32 PBClampF32(f32 x,
               f32 a,
               f32 b);

PBClampF32 clamps x to the inclusive range [a,b].

PBRoundF32

f32 PBRoundF32(f32 x);

PBRoundF32 rounds x to nearest integer value (as f32).

PBSignF32

f32 PBSignF32(f32 x);

PBSignF32 returns -1, 0 or +1 depending on x.

PBModF32

f32 PBModF32(f32 x,
             f32 y);

PBModF32 returns floating-point remainder of x / y.

PBLerpF32

f32 PBLerpF32(f32 a,
              f32 b,
              f32 t);

PBLerpF32 linearly interpolates from a to b by parameter t.

PBUnlerpF32

f32 PBUnlerpF32(f32 a,
                f32 b,
                f32 v);

PBUnlerpF32 computes interpolation parameter t for value v in range [a,b].

PBRemapF32

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

f32 PBSinF32(f32 x);

PBSinF32 computes sine approximation for x (radians).

PBCosF32

f32 PBCosF32(f32 x);

PBCosF32 computes cosine approximation for x (radians).

PBF32IsZero

bool PBF32IsZero(f32 x);

PBF32IsZero returns true when |x| is smaller than PB_F32_EPSILON.

PBColorSpace

typedef enum PBColorSpace PB_ENUM_TYPE(u32){
    PBColorSpace_Null,
    PBColorSpace_Linear,
    PBColorSpace_SRGB,
    PBColorSpace_COUNT,
} PBColorSpace;

PBColor

struct PBColor {
    PBColorSpace space;
    f32          r, g, b, a;
};

PBVector2

union PBVector2 {
    struct {
        f32 x, y;
    };
    f32 e[2];
};

PBVector4

union PBVector4 {
    struct {
        f32 x, y, z, w;
    };
    f32 e[4];
};

PBRectangle

union PBRectangle {
    struct {
        PBVector2 p0, p1;
    };
    struct {
        f32 x0, y0, x1, y1;
    };
    f32 e[4];
};

PBColorMake

PBColor PBColorMake(f32 r,
                    f32 g,
                    f32 b,
                    f32 a);

PBColorMake constructs a clamped RGBA color.

PBColorFromRGBA

PBColor PBColorFromRGBA(f32 r,
                        f32 g,
                        f32 b,
                        f32 a);

PBColorFromRGBA constructs an sRGB color with clamped channels.

PBColorFromRGBHex

PBColor PBColorFromRGBHex(u32 hex);

PBColorFromRGBHex converts 0xRRGGBB to an opaque sRGB color.

PBColorFromRGBAHex

PBColor PBColorFromRGBAHex(u32 hex);

PBColorFromRGBAHex converts packed RGBA hex value to an sRGB color.

PBColorIsZero

bool PBColorIsZero(PBColor c);

PBColorIsZero reports whether all channels are exactly zero.

PBColorEquals

bool PBColorEquals(PBColor c0,
                   PBColor c1);

PBColorEquals compares channel values exactly.

PBColorToU64

u64 PBColorToU64(PBColor x);

PBColorToU64 packs color channels into 16-bit-per-channel ARGB.

PBColorToU32

u32 PBColorToU32(PBColor x);

PBColorToU32 packs color channels into 8-bit-per-channel ARGB.

PBColorToRGBA8

u32 PBColorToRGBA8(PBColor x);

PBColorToRGBA8 packs color channels into 8-bit-per-channel RGBA8 (for use with PBSysTextureFormat_RGBA8).

PBColorFromRGBA8

PBColor PBColorFromRGBA8(u32 x);

PBColorFromRGBA8 unpacks a previously packed color with PBColorToRGBA8.

PBColorToPackedRGBA

u32 PBColorToPackedRGBA(PBColor x);

PBColorToU32 packs color channels into 8-bit-per-channel ARGB.

PBColorHSVFromRGB

PBColor PBColorHSVFromRGB(PBColor rgb);

PBColorHSVFromRGB converts RGB color to HSV representation (stored in PBColor fields).

PBColorRGBFromHSV

PBColor PBColorRGBFromHSV(PBColor hsv);

PBColorRGBFromHSV converts HSV representation back to RGB.

PBVector2Make

PBVector2 PBVector2Make(f32 x,
                        f32 y);

PBVector2Make constructs a 2D vector.

PBVector2IsZero

bool PBVector2IsZero(PBVector2 v);

PBVector2IsZero reports whether both vector components are near-zero.

PBVector2Add

PBVector2 PBVector2Add(PBVector2 a,
                       PBVector2 b);

PBVector2Add adds two PBVector2s.

PBVector2Sub

PBVector2 PBVector2Sub(PBVector2 a,
                       PBVector2 b);

PBVector2Sub subtracts two PBVector2 types (a - b).

PBVector2Mul

PBVector2 PBVector2Mul(PBVector2 a,
                       PBVector2 b);

PBVector2Mul multiplies two PBVector2 types (a * b).

PBVector2Div

PBVector2 PBVector2Div(PBVector2 a,
                       PBVector2 b);

PBVector2Div divides one PBVector2 by another (a / b).

PBVector2AddF

PBVector2 PBVector2AddF(PBVector2 a,
                        f32       b);

PBVector2AddF adds a PBVector2 by a scalar value (a.x + b, a.y + b).

PBVector2SubF

PBVector2 PBVector2SubF(PBVector2 a,
                        f32       b);

PBVector2SubF subtracts a PBVector2 by a scalar value (a.x - b, a.y - b).

PBVector2MulF

PBVector2 PBVector2MulF(PBVector2 a,
                        f32       b);

PBVector2MulF multiplies a PBVector2 by a scalar value (a.x * b, a.y * b).

PBVector2DivF

PBVector2 PBVector2DivF(PBVector2 a,
                        f32       b);

PBVector2MulF divides a PBVector2 by a scalar value (a.x / b, a.y / b).

PBVector4Make

PBVector4 PBVector4Make(f32 x,
                        f32 y,
                        f32 z,
                        f32 w);

PBVector4Make constructs a 4D vector.

PBVector4IsZero

bool PBVector4IsZero(PBVector4 v);

PBVector4IsZero reports whether all vector components are near-zero.

PBVector4MulF

PBVector4 PBVector4MulF(PBVector4 v,
                        f32       f);

PBVector4MulF multiplies all components of v by scalar f.

PBRectangleMake

PBRectangle PBRectangleMake(f32 x0,
                            f32 y0,
                            f32 x1,
                            f32 y1);

PBRectangleMake constructs rectangle from two corners.

PBRectangleFromV2

PBRectangle PBRectangleFromV2(PBVector2 p0,
                              PBVector2 p1);

PBRectangleMake constructs rectangle from two corner points.

PBRectangleOfRect

PBRectangle PBRectangleOfRect(PBRect rect);

PBRectangleOfRect converts a PBRect to a PBRectangle

PBRectangleOfSize

PBRectangle PBRectangleOfSize(PBSize size);

PBRectangleOfSize converts a PBSize to a PBRectangle positioned at 0,0

PBRectangleEquals

bool PBRectangleEquals(PBRectangle a,
                       PBRectangle b);

PBRectangleEquals returns true if two rectangles are equal.

PBRectangleIsZero

bool PBRectangleIsZero(PBRectangle a);

PBRectangleIsZero returns true if the rectangle is nearly zero.

PBRectangleSize

PBVector2 PBRectangleSize(PBRectangle r);

PBRectangleSize returns width/height vector of rectangle r.

PBRectangleWidth

f32 PBRectangleWidth(PBRectangle r);

PBRectangleWidth returns horizontal extent of r.

PBRectangleHeight

f32 PBRectangleHeight(PBRectangle r);

PBRectangleHeight returns vertical extent of r.

PBRectangleScale

PBRectangle PBRectangleScale(PBRectangle r,
                             f32         sx,
                             f32         sy);

PBRectangleScale scales rectangle coordinates by (sx,sy).

PBRectangleCutRight

PBRectangle PBRectangleCutRight(PBRectangle r,
                                f32         right);

PBRectangleCutRight trims right side by right units.

PBRectangleHitTest

bool PBRectangleHitTest(PBRectangle r,
                        PBVector2   pos);

PBRectangleHitTest reports whether pos lies inside r.

PBRectangleClip

PBRectangle PBRectangleClip(PBRectangle a,
                            PBRectangle b);

PBRectangleClip returns intersection of rectangles a and b.

PBRectangleIntersects

bool PBRectangleIntersects(PBRectangle r0,
                           PBRectangle r1);

PBRectangleIntersects returns true when r0 and r1 overlap.


#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

typedef PBSliceType(i8) PBI8Slice;

PBI16Slice

typedef PBSliceType(i16) PBI16Slice;

PBI32Slice

typedef PBSliceType(i32) PBI32Slice;

PBI64Slice

typedef PBSliceType(i64) PBI64Slice;

PBU16Slice

typedef PBSliceType(u16) PBU16Slice;

PBU32Slice

typedef PBSliceType(u32) PBU32Slice;

PBU64Slice

typedef PBSliceType(u64) PBU64Slice;

PBF32Slice

typedef PBSliceType(f32) PBF32Slice;

PBF64Slice

typedef PBSliceType(f64) PBF64Slice;

PBPtrSlice

typedef PBSliceType(void*) PBPtrSlice;

PBSliceFrom

macro SliceType PBSliceFrom(SliceType, T* nullable values, usize len)

PBSliceSlice

macro SliceType PBSliceSlice(SliceType slice, usize start, usize len)

PBSliceAt

macro T PBSliceAt(SliceType slice, usize index)

PBSliceRefAt

macro T* nullable PBSliceRefAt(SliceType slice, usize index)

PBSliceEq

macro bool PBSliceEq(SliceType slice, SliceType otherSlice)

PBSliceCmp

macro int PBSliceCmp(SliceType slice, SliceType otherSlice)

#include <playbit/string.h>

PBStrSliceLike

typedef const void * PBStrSliceLike;

PBStrSliceLike is a symbolic type, representing all types that PBStrSliceOf and similar generic functions accept as a source.

PBStrLit

macro PBStrSlice PBStrLit(const char stringLiteral[])

Creates a compile-time constant PBStrSlice from a C-string literal

PBStrFree

void PBStrFree(PBStr str,
               PBMem ma);

PBStrFree releases the memory of str back to memory allocator ma

PBStrFrom

PBStr PBStrFrom(PBMem          ma,
                PBStrSliceLike value);

PBStrFrom makes a copy of bytes at value as a PBStr. It's implemented as a generic macro, with the following effective signature: PBStr PBStrFrom<T is convertible to PBStrSlice>(T value)

PBStrFromSlice

PBStr PBStrFromSlice(PBMem      ma,
                     PBStrSlice value);

PBStrFrom makes a copy of bytes at value as a PBStr.

PBStrFmt

PBStr PBStrFmt(PBMem       ma,
               const char* format,
               ...);

PBStrFmt makes a string with printf-like formatting.

PBStrFmtv

PBStr PBStrFmtv(PBMem       ma,
                const char* format,
                va_list     va);

PBStrFmtv is the va_list variant of PBStrFmt.

PBStrJoin

PBStr PBStrJoin(PBMem          ma,
                PBStrSliceLike glue,
                PBStrSliceLike value1,
                ...);

PBStrJoin concatenates byte arrays together with glue placed in between each value.

PBStrJoinSlice

PBStr PBStrJoinSlice(PBMem             ma,
                     PBStrSliceLike    glue,
                     const PBStrSlice* values,
                     usize             n);

PBStrJoinSlice joins n values with glue between each value.

PBStrCat

PBStr PBStrCat(PBMem          ma,
               PBStrSliceLike value1,
               ...);

PBStrCat concatenates byte arrays together. Its equivalent to PBStrJoint with empty glue.'

PBStrAssign

bool PBStrAssign(PBStr*         str,
                 PBMem          ma,
                 PBStrSliceLike newValue);

PBStrAssign replaces the value of str with newValue, reusing the existing memory of str if possible.

PBStrAssignFromSlice

bool PBStrAssignFromSlice(PBStr*     str,
                          PBMem      ma,
                          PBStrSlice newValue);

PBStrAssignFromSlice replaces the value of str with newValue, reusing the existing memory of str if possible.

PBStr_FMT

#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

#define PBStr_FMT_ARG(pbStr)

PBStr_FMT is used in printf arguments for a matching PBStr_FMT, with a PBStr-like value

PBStrSliceOf

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:

PBStrSliceOfStrSlice

PBStrSlice PBStrSliceOfStrSlice(PBStrSlice other);

PBStrSliceOf… constructs a slice of a value (type-specific constructors)

PBStrSliceOfStrSlice2

PBStrSlice PBStrSliceOfStrSlice2(PBStrSlice other,
                                 usize      start,
                                 usize      len);

PBStrSliceOfStrSlice3

PBStrSlice PBStrSliceOfStrSlice3(PBStrSlice other,
                                 usize      start,
                                 usize      end);

PBStrSliceOfU8Slice

PBStrSlice PBStrSliceOfU8Slice(PBU8Slice other);

PBStrSliceOfU8Slice2

PBStrSlice PBStrSliceOfU8Slice2(PBU8Slice other,
                                usize     start,
                                usize     len);

PBStrSliceOfCStr

PBStrSlice PBStrSliceOfCStr(const char* str);

PBStrSliceOfCStr2

PBStrSlice PBStrSliceOfCStr2(const char* str,
                             usize       start,
                             usize       len);

PBStrSliceOfStr

PBStrSlice PBStrSliceOfStr(const PBStr str);

PBStrSliceOfStr2

PBStrSlice PBStrSliceOfStr2(PBStr str,
                            usize start,
                            usize len);

PBStrSliceOfU8Array

PBStrSlice PBStrSliceOfU8Array(PBU8Array other);

PBStrSliceOfU8Array2

PBStrSlice PBStrSliceOfU8Array2(PBU8Array other,
                                usize     start,
                                usize     len);

PBStrSliceOfU8Arrayp

PBStrSlice PBStrSliceOfU8Arrayp(const PBU8Array* other);

PBStrSliceOfU8Arrayp2

PBStrSlice PBStrSliceOfU8Arrayp2(const PBU8Array* other,
                                 usize            start,
                                 usize            len);

PBStrSliceOfBuf

PBStrSlice PBStrSliceOfBuf(PBBuf other);

PBStrSliceOfBuf2

PBStrSlice PBStrSliceOfBuf2(PBBuf other,
                            usize start,
                            usize len);

PBStrSliceOfBufp

PBStrSlice PBStrSliceOfBufp(const PBBuf* other);

PBStrSliceOfBufp2

PBStrSlice PBStrSliceOfBufp2(const PBBuf* other,
                             usize        start,
                             usize        len);

PBStrSliceOfBytes

PBStrSlice PBStrSliceOfBytes(const u8* bytes,
                             usize     len);

PBStrSliceOfBytes is a helper for (PBStrSlice){bytes,len}

PBStrEq

#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)

PBCheckStrEq

macro PBCheckStrEq()

checks if a == b (bytewise) void PBCheckStrEq<A is convertible to PBStrSlice, B is convertible to PBStrSlice>(A a, B b)

PB_STR

macro PBStrSlice PB_STR(const char* cstr)

DEPRECATED: use PBStrLit for literals, or PBStrSliceOf for runtime-defined C strings

PBStrSlicePrintv

PBStrSlice PBStrSlicePrintv(PBArena*    arena,
                            const char* fmt,
                            va_list     args);

Prints a string into an arena (the result is always null-terminated)

PBStrSlicePrint

PBStrSlice PBStrSlicePrint(PBArena*    arena,
                           const char* fmt,
                           ...);

PBStrSlicePrint is the va_args variant of PBStrSlicePrintv.

PBStrSliceOfStrp

PBStrSlice PBStrSliceOfStrp(const PBStr* str);

PBStrSliceOfStrp returns a borrowed view of *str.

PBStrSliceOfStrp2

PBStrSlice PBStrSliceOfStrp2(const PBStr* str,
                             usize        start,
                             usize        len);

PBStrSliceOfStrp2 returns a subslice view of *str starting at start.


#include <playbit/sysbuf.h>

PBSysBufAdvance

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:

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

typedef enum PBHashImpl {
    PBHashImpl_NONE,
    PBHashImpl_BLAKE3,
} PBHashImpl;

PBHashBlake3_CHUNK_LEN

const int PBHashBlake3_CHUNK_LEN = 1024;

ideal max size for PBHasherUpdate

PBHashBlake3_OUT_LEN

const int PBHashBlake3_OUT_LEN = 32;

number of bytes returned by PBHasherFinalize

PBHashBlake3_HASHER_SIZE

const int PBHashBlake3_HASHER_SIZE = 1928;

bytes needed for PBHasherEmplace

PBHasherCreate

PBHasher* PBHasherCreate(PBMem      ma,
                         PBHashImpl impl);

PBHasherCreate allocates and initializes a new hasher using the provided implementation.

PBHasherFree

void PBHasherFree(PBHasher* hasher);

PBHasherFree frees the memory of a hasher allocated with PBHasherCreate

PBHasherEmplace

usize PBHasherEmplace(void*      mem,
                      usize      memSize,
                      PBHashImpl impl);

PBHasherEmplace initializes a hasher at mem

PBHasherUpdate

void PBHasherUpdate(PBHasher*   hasher,
                    const void* input,
                    usize       inputSize);

PBHasherUpdate feeds input data to the hasher

PBHasherFinalize

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.

PBHasherReset

void PBHasherReset(PBHasher* hasher);

PBHasherReset recycles the internal state of a hasher so it can be reused

PBHashRapidHash

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

u64 PBHashRapidHashSeeded(const void* data,
                          usize       dataSize,
                          u64         seed);

PBHashRapidHashSeeded works like PBHashRapidHash but allows setting a seed to alter hashing

PBHashRapidMix

u64 PBHashRapidMix(u64 a,
                   u64 b);

PBHashRapidMix mixes two integers together using multiply and xor

PBHashBytes

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

u64 PBHashBytesSeeded(const void* data,
                      usize       dataSize,
                      u64         seed);

PBHashBytesSeeded works like PBHashBytes but allows setting a seed to alter hashing

PBHashMix

u64 PBHashMix(u64 a,
              u64 b);

PBHashMix mixes two integers together

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

typedef struct PBFile {
    PBSysHandle handle;
} PBFile;

PBFile represents a file or directory on a file system

PBFileOpenFlags

typedef enum 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_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_RWX = PBSysFileOpenFlag_MODE_USER_RWX,
    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_RWX = PBSysFileOpenFlag_MODE_GROUP_RWX,
    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_RWX = PBSysFileOpenFlag_MODE_OTHER_RWX,

    // aliases
    PBFileOpen_R = PBFileOpen_READ,
    PBFileOpen_W = PBFileOpen_WRITE,
    PBFileOpen_RW = PBFileOpen_READ | PBFileOpen_WRITE,
} PBFileOpenFlags;

PBFileOpenFlags changes behavior of PBFileOpen

PBFileSystemRoot

PBFile PBFileSystemRoot();

PBFileSystemRoot returns the default/initial file system provided to the current thread when it was started.

PBFileOpen

PBSysErr PBFileOpen(PBFile*    file,
                    PBFile     at,
                    PBStrSlice path,
                    u32        flags);

PBFileOpen opens a file at path relative to parent directory at, or to file at if path is empty.

PBFileOpenOrPanic

PBFile PBFileOpenOrPanic(PBFile     at,
                         PBStrSlice path,
                         u32        flags);

PBFileOpenOrPanic works like PBFileOpen but panics on error

PBFileClose

void PBFileClose(PBFile* file);

PBFileClose closes file->handle and sets it to PBSysHandle_INVALID

PBFileRead

i64 PBFileRead(PBFile file,
               u8*    buf,
               usize  bufCap);

PBFileRead reads from file into buf.

PBFileReadv

i64 PBFileReadv(PBFile          file,
                const PBSysBuf* bufs,
                u32             bufCount);

PBFileReadv reads from file into bufs.

PBFileReadAll

PBSysErr PBFileReadAll(PBFile file,
                       PBBuf* buf,
                       PBMem  ma);

PBFileReadAll reads an entire file into a buffer allocated in ma

PBFileWrite

i64 PBFileWrite(PBFile    file,
                const u8* buf,
                usize     bufLen);

PBFileWrite writes to file from buf.

PBFileWritev

i64 PBFileWritev(PBFile          file,
                 const PBSysBuf* bufs,
                 u32             bufCount);

PBFileWritev writes to file from bufs.


#include <playbit/dir_iterator.h>

PBDirIterator

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

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

PBDirIterator PBDirIteratorOpenOrPanic(PBFile     dir,
                                       PBStrSlice subdirPath,
                                       PBMem      ma);

PBDirIteratorOpenOrPanic works like PBDirIteratorOpen but panics on error

PBDirIteratorNext

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);

PBDirIteratorClose

void PBDirIteratorClose(PBDirIterator* dirIterator);

PBDirIteratorClose closes dirIterator->handle and sets it to PBSysHandle_INVALID

Playbit API reference


#include <playbit/draw.h>

PBUIFont

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

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;
    u64         lastFrame;
};

PBTextCache

struct PBTextCache {
    PBArena*          arena; // owns text copies + entry array
    PBTextCacheEntry* entries;
    u64               capacity; // power of two
    u64               count;
    u64               frame; // incremented each PBTextCacheNextFrame()
    // context required to create plans
    PBWindow window;
};

PBRenderCommand

struct PBRenderCommand {
    PBSysWindowRendererInstructionKind kind;
    union {
        PBSysWindowRendererShapeItem shape;
        PBSysWindowRendererTextItem  text;
        PBSysWindowRendererClipItem  clip;
        PBSysHandle                  texture;
    };
};

PBRender

struct PBRender {
    PBArena* arena;

    struct {
        PBRenderCommand* data;
        u64              count;
        u64              capacity;
    } cmds;
};

PBDrawContext

struct PBDrawContext {
    PBArena*    arena;
    PBRender    render;
    PBTextCache textCache;

    PBWindow window;
    f32      scale;
    u32      clipDepth;
};

PBTexture

struct PBTexture {
    PBSysHandle handle;
};

PBStrokeType

typedef enum PB_ENUM_TYPE(uint32_t) {
    PBStrokeType_CENTER = 0,
    PBStrokeType_INNER = 1,
    PBStrokeType_OUTER = 2,
} PBStrokeType;

PBTextplanWidthOfSize

#define PBTextplanWidthOfSize(x)

PBSysTextplanGetSize result macros

PBTextureCreate

PBTexture PBTextureCreate(PBWindow                      window,
                          PBSysTextureFormat            format,
                          u32                           width,
                          u32                           height,
                          PBSysWindowCreateTextureFlags 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

PBTexture PBTextureCreateFromData(PBWindow                      window,
                                  const void*                   data,
                                  u64                           dataSize,
                                  PBSysWindowCreateTextureFlags 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

bool PBTextureIsValid(PBTexture texture);

PBTextureIsValid returns true if the texture handle is valid (i.e. successfully created).

PBTextureWrite

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

void PBTextureDestroy(PBTexture* texture);

PBTextureDestroy releases the texture's GPU resources and invalidates the handle.

PBDrawSetGlobal

void PBDrawSetGlobal(PBDrawContext* ctx);

PBDrawSetGlobal sets the thread-local draw context used by PBDraw* calls.

PBDrawGetGlobal

PBDrawContext* PBDrawGetGlobal();

PBDrawGetGlobal returns the active thread-local draw context.

PBDrawInit

void PBDrawInit(PBDrawContext* ctx,
                PBArena*       arena,
                PBWindow       window);

PBDrawInit initializes draw/render/text-cache state for window.

PBDrawBeginFrame

void PBDrawBeginFrame(PBWindow window);

PBDrawBeginFrame starts a frame and refreshes window scale and per-frame draw state.

PBDrawEndFrame

void PBDrawEndFrame();

PBDrawEndFrame submits queued commands and advances text-cache frame lifetime.

PBDrawSetScale

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).

PBDrawGetScale

f32 PBDrawGetScale();

PBDrawGetScale gets the drawing scale for the current frame.

PBDrawRect

void PBDrawRect(PBRectangle bounds,
                PBColor     color);

PBDrawRect enqueues a filled rectangle with square corners.

PBDrawRectExt

void PBDrawRectExt(PBRectangle bounds,
                   PBColor     color,
                   PBVector4   cornerRadius);

PBDrawRectExt enqueues a filled rectangle with per-corner radius.

PBDrawRectExt2

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

void PBDrawRectOutline(PBRectangle  bounds,
                       PBStrokeType type,
                       PBColor      strokeColor,
                       f32          strokeWidth,
                       PBVector4    cornerRadius);

PBDrawRectInset

void PBDrawRectInset(PBRectangle bounds,
                     PBColor     strokeColor,
                     f32         strokeWidth,
                     PBVector4   cornerRadius);

PBDrawRectInset enqueues an inset rectangle stroke with configurable width and corner radius.

PBDrawRectWithStroke

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

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.

PBDrawTextLine

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

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

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

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

PBVector2 PBDrawMeasureText(PBUIFont   font,
                            PBStrSlice text,
                            f32        maxWidth);

PBDrawMeasureText returns measured text size for the given font and max width constraint (in dps).

PBDrawPushClip

void PBDrawPushClip(PBRectangle bounds);

PBDrawPushClip pushes a clip rectangle onto the clip stack, restricting rendering to bounds.

PBDrawPopClip

void PBDrawPopClip();

PBDrawPopClip pops the most recently pushed clip rectangle from the clip stack.

PBDrawResetClip

void PBDrawResetClip();

PBDrawResetClip pops all clip rectangles from the clip stack.

PBDrawTexturedRect

void PBDrawTexturedRect(PBTexture   texture,
                        PBRectangle bounds);

PBDrawTexturedRect draws a texture mapped to bounds, tinted by tintColor. Use PBColorFromRGBA(1,1,1,1) for no tint.

PBDrawTexturedRectExt

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

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.

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

#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.


#include <playbit/mem.h>

PBMem_ALIGNMENT

#define PBMem_ALIGNMENT usize

PBMem_ALIGNMENT is the minimum guaranteed address alignment for allocations. It's at least _Alignof(max_align_t)

PBMem

typedef const struct PBMemAllocator * PBMem;

PBMem is the type of a memory allocator

PBMemAllocator

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);
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

const int PBMem_ZERO = 1;

allocate zeroed memory

PBMem_ROUNDUP

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

void* PBMemAlloc(PBMem ma,
                 usize nbyte);

PBMemAlloc allocates nbyte bytes through allocator ma.

PBMemAllocz

void* PBMemAllocz(PBMem ma,
                  usize nbyte);

PBMemAllocz allocates nbyte bytes through allocator ma and zero-initializes the returned memory.

PBMemRealloc

void* PBMemRealloc(PBMem ma,
                   void* ptr,
                   usize nbyte);

PBMemRealloc resizes an allocation owned by ma.

PBMemReallocz

void* PBMemReallocz(PBMem ma,
                    void* ptr,
                    usize nbyte);

PBMemReallocz is like PBMemRealloc but requests zero-initialization of newly added bytes.

PBMemAllocx

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.

PBMemFree

void PBMemFree(PBMem ma,
               void* ptr);

PBMemFree releases ptr to allocator ma.

PBMemResize

bool PBMemResize(PBMem  ma,
                 usize  elemSize,
                 void*  ptrInOut,
                 usize* capInOut,
                 usize  newCap,
                 u32    maFlags);

PBMemResize resizes the capacity of an array *ptrInOut to newCap.

PBMemGrow

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.

PBMemPageSize

usize PBMemPageSize();

PBMemPageSize returns the underlying system's memory page size

PBMemEq

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

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

void PBMemoryCopy(void*       to,
                  const void* from,
                  usize       size);

PBMemoryCopy is a different name for memcpy

PBMemoryZero

void PBMemoryZero(void* ptr,
                  usize size);

PBMemoryZero does memset(ptr, 0, size)

PBMemoryEquals

bool PBMemoryEquals(const void* a,
                    const void* b,
                    usize       size);

PBMemoryZeroStruct

#define PBMemoryZeroStruct(ptr)

PBMemoryZeroStruct does memset(ptr, 0, sizeof(*ptr))

PBMemRegionsOverlap

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

extern PBMem kPBMemGPA;

kPBMemGPA is the general-purpose allocator

PBMemGPAStats

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

void PBMemGPAGetStats(PBMem          m,
                      PBMemGPAStats* result);

PBMemGPAGetStats retrieves current stats of a GPA.


#include <playbit/mem_buf_allocator.h>

PBMemBufAllocator

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

const int PBMemBufAllocator_ZEROED = 1;

initial buf is zeroed

PBMemBufAllocator_THREADSAFE

const int PBMemBufAllocator_THREADSAFE = 2;

enable allocations across threads

PBMemBufAllocatorInit

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.

PBMemBufAllocatorReset

void PBMemBufAllocatorReset(PBMemBufAllocator* a);

PBMemBufAllocatorReset frees any and all allocations made in the allocator

PBMemBufAllocatorScopeBegin

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

void PBMemBufAllocatorScopeEnd(PBMemBufAllocator* a,
                               usize              scope);

PBMemBufAllocatorScopeBegin ends a region started by PBMemBufAllocatorScopeBegin


#include <playbit/mem_null_allocator.h>

PBMemNullAllocator

int PBMemNullAllocator();

PBMemNullAllocator always fails to allocate memory, intended to be used for testing


#include <playbit/mem_zeroing_allocator.h>

PBMemZeroingAllocator

typedef struct PBMemZeroingAllocator {
    PBMemAllocator ma;
    PBMem          source;
} PBMemZeroingAllocator;

PBMemZeroingAllocator wraps another allocator and sets the PBMem_ZERO flag for all allocations

PBMemZeroingAllocatorImpl

void* PBMemZeroingAllocatorImpl(PBMem  m,
                                void*  p,
                                usize* zp,
                                u32    fl);

PBMemZeroingAllocatorImpl forwards allocation to the wrapped source allocator and forces PBMem_ZERO.

PBMemZeroingAllocatorInit

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

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

typedef enum PBArenaFlags PB_ENUM_TYPE(u64){
    PBArenaFlag_NoChain = (1 << 0),
    PBArenaFlag_FixedBuffer = (1 << 1),
} PBArenaFlags;

PBArena

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

struct PBArenaParams {
    // config
    PBMem        allocator;
    PBArenaFlags flags;
    usize        initialSize;
    void*        backingBuffer; // you must set initialSize if using!

    // debug
    char* debugFile;
    int   debugLine;
};

PBArenaTemp

struct PBArenaTemp {
    PBArena* arena;
    usize    pos;
};

PBArena_HEADER_SIZE

#define PBArena_HEADER_SIZE

PBArena_HEADER_SIZE is the number of bytes of overhead per arena slab

PBArenaAllocP

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.

PBArenaAlloc

macro PBArena* nullable PBArenaAlloc(.field = value ...)

creates an arena from params, a convenience wrapper for PBArenaAllocP((PBArenaParams){ .field = value ... })

PBArenaFree

void PBArenaFree(PBArena* arena);

PBArenaFree releases all memory owned by *arena and sets *arena to NULL.

PBArenaFromBuffer

PBArena* PBArenaFromBuffer(void* data,
                           usize size);

PBArenaFromBuffer creates an arena backed by caller-owned memory in [data, data+size).

PBArenaFromAllocator

PBArena* PBArenaFromAllocator(PBMem allocator,
                              usize size);

PBArenaFromAllocator creates an arena that allocates slab memory from allocator.

PBArenaPush

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.

PBArenaPop

void PBArenaPop(PBArena* arena,
                usize    size);

PBArenaPop releases the most-recent size bytes from arena state.

PBArenaPopTo

void PBArenaPopTo(PBArena* arena,
                  usize    pos);

PBArenaPopTo rewinds arena allocation position to absolute offset pos.

PBArenaReset

void PBArenaReset(PBArena* arena);

PBArenaReset rewinds arena to position 0, releasing all allocations.

PBArenaPos

usize PBArenaPos(const PBArena* arena);

PBArenaPos returns the current absolute allocation position.

PBArenaSize

usize PBArenaSize(const PBArena* arena);

PBArenaSize returns total bytes across all slabs currently attached to arena.

PBArenaTempBegin

PBArenaTemp PBArenaTempBegin(PBArena* arena);

PBArenaTempBegin snapshots current arena position for scoped rollback.

PBArenaTempEnd

void PBArenaTempEnd(PBArenaTemp temp);

PBArenaTempEnd rewinds arena to the position captured by temp.

PBMemFromArena

PBMem PBMemFromArena(PBArena* arena);

PBMemFromArena returns an allocator that can be used with anything that accepts PBMem

PBArenaIsEmpty

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

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

typedef struct PBNet {
    PBSysHandle handle;
} PBNet;

PBNet is a general network capability

PBNetSession

typedef struct PBNetSession {
    PBSysHandle handle;
} PBNetSession;

PBNetSession is a Playbit network session

PBNetChannelOpenFlags

typedef u64 PBNetChannelOpenFlags;

PBNetChannelOpenFlags are flags for PBNetChannelOpenEx

PBNetChannelOpenFlag

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

typedef u64 PBNetChannelPublishFlags;

PBNetChannelPublishFlags are flags for PBNetChannelPublishCommit et al

PBNetChannelPublishFlag

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

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

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

PBNetDefault

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

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).

PBNetSessionClose

PBSysErr PBNetSessionClose(PBNetSession* netSession);

PBNetSessionClose closes a network session

PBNetChannelOpen

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.

PBNetChannelOpenEx

PBSysErr PBNetChannelOpenEx(PBNetChannel*         netChannelOut,
                            const PBNetSession*   netSession,
                            PBStrSlice            channelId,
                            PBMem                 ma,
                            PBNetChannelOpenFlags flags);

PBNetChannelOpen opens a stream to channel identified by channelId.

PBNetChannelClose

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

PBSysHandle PBNetChannelHandle(const PBNetChannel* netChannel);

PBNetChannelHandle returns the underlying stream handle for a channel

PBNetChannelPublish

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.

PBNetChannelPublishEx

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.

PBNetChannelPublishBegin

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.

PBNetChannelPublishCommit

PBSysErr PBNetChannelPublishCommit(PBNetChannel*            netChannel,
                                   u8*                      body,
                                   PBNetChannelPublishFlags flags);

PBNetChannelPublishCommit commits a draft PUBLISH frame previously started with PBNetChannelPublishBegin.

PBNetChannelProcessIO

PBSysErr PBNetChannelProcessIO(PBNetChannel*      netChannel,
                               PBSysSignals       signals,
                               PBNetChannelFrame* frameOut);

PBNetChannelProcessIO processes stream IO for a channel.

PBNetChannelReleaseFrame

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

u32 PBNetChannelRecvDiscardCount(const PBNetChannel* netChannel);

PBNetChannelRecvDiscardCount returns the number of received messages which were discarded because they exceeded size limit set by PBNetChannelSetRecvLimit

PBNetChannelSetRecvLimit

u32 PBNetChannelSetRecvLimit(PBNetChannel* netChannel,
                             u32           nbytes);

PBNetChannelSetRecvLimit limits the size of received messages (body, not including protocol header.)

PBNetChannelSetSendLimit

u32 PBNetChannelSetSendLimit(PBNetChannel* netChannel,
                             u32           nbytes);

PBNetChannelSetSendLimit limits the size of published messages (body, not including protocol header.)


#include <playbit/ap.h>

Playbit Access Point protocol

PBApFrameType

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

typedef u8 PBApFrameFlags;

PBApFrameFlag

enum PBApFrameFlag PB_ENUM_TYPE(u8){
    PBApFrameFlag_ECHO = 1u << 0,
    PBApFrameFlag_TRACK = 1u << 0,
};

PBApFrameHeaderSize

const int PBApFrameHeaderSize = 8;

PBApFrameBodyAlign

const int PBApFrameBodyAlign = 16;

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)

Simple example of spawning a second thread:

#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

typedef struct {
    PBSysHandle handle;
} PBThread;

PBThreadOpt

typedef PBOpt(PBThread) PBThreadOpt;

PBThreadConfig

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

PBThreadFn

typedef void (*PBThreadFn)(u64);

PBThreadFn is the thread entry point function

PBProcessStart

void PBProcessStart(void* mainFn,
                    u64   flags);

PBProcessStart starts the main function. flags are bits of PBSysThread_

PBThreadStart

PBThreadOpt PBThreadStart(PBThreadFn            arg,
                          u64                   arg,
                          const PBThreadConfig* config);

PBThreadStart starts a new thread

PBThreadExit

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

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

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.

PBCallCtors

#define PBCallCtors()
    PBCallCtors invokes wasm constructor list for builds without libc startup.

PB_C_START_ATTR

#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

#define PB_START_WITHOUT_GUI

PB_START_WITHOUT_GUI defines a _start function which sets PBSysThread_NOGUI

PBSetupInitialHandles

void PBSetupInitialHandles();

PBSetupInitialHandles sets up internal knowledge of what handles a thread is given at start


#include <playbit/mutex.h>

PBMutex

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 Nth call to PBMutexUnlock "happens before" the Mth call to PBMutexLock for any N < M. For any call to PBMutexRLock, there exists an N such that the Nth call to PBMutexUnlock "happens before" that call to PBMutexRLock, and the corresponding call to PBMutexRUnlock "happens before" the N+1th call to PBMutexUnlock.

In other words: There's no need to use atomic instructions for shared data guarded by a PBMutex.

PBMutexInit

void PBMutexInit(PBMutex* mu);

PBMutexInit initializes mu to an unlocked state with zero readers and no writer.

PBMutexRLock

void PBMutexRLock(PBMutex* mu);

PBMutexRLock acquires a shared read lock.

PBMutexRUnlock

void PBMutexRUnlock(PBMutex* mu);

PBMutexRUnlock releases a shared read lock.

PBMutexLock

void PBMutexLock(PBMutex* mu);

PBMutexLock acquires an exclusive write lock.

PBMutexUnlock

void PBMutexUnlock(PBMutex* mu);

PBMutexUnlock releases an exclusive write lock.

PBMutexIsLocked

bool PBMutexIsLocked(const PBMutex* mu);

PBMutexIsLocked returns true if the mutex is write locked at the time of the call

PBMutexIsRLocked

bool PBMutexIsRLocked(const PBMutex* mu);

PBMutexIsLocked returns true if the mutex is read locked at the time of the call

PBMutexLockInScope

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

macro void PBMutexRLockInScope(PBMutex* mu)

#include <playbit/semaphore.h>

PBSemaphore

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

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.)

PBSemaphoreWait

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.

PBSemaphoreSignal

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.

PBSemaphoreValue

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.

Playbit API reference


#include <playbit/date.h>

PBDate

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

typedef enum PBCalendar {
    PBCalendar_GREGORIAN,
} PBCalendar;

PBCalendar identifies a calendar system.

PBDateComponents

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

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

PBDate PBDateNow();

PBDateNow returns the current time

PBDateFormat

usize PBDateFormat(PBDate             date,
                   PBDateFormatLayout layout,
                   char*              buf,
                   usize              bufCap);

PBDateFormat writes a string representation of date to buf with the given layout.

PBDateComponentsOf

PBDateComponents PBDateComponentsOf(PBDate     date,
                                    PBCalendar calendar);

PBDateComponentsOf returns components of a date interpreted in calendar

PBSysDateMake

PBSysDate PBSysDateMake(i32 year,
                        u32 month,
                        u32 day,
                        u32 hour,
                        u32 minute,
                        u32 second);

PBSysDateMake constructs a PBSysDate timestamp from components, in UTC.

PBSystemClock

PBSysHandle PBSystemClock();

PBSystemClock returns the handle to the system clock (PBSysHandle_INVALID if none)


#include <playbit/timezone.h>

PBTimeZone

typedef struct PBTimeZone {
    u32 id;
} PBTimeZone;

PBTimeZoneOfName

PBTimeZone PBTimeZoneOfName(const char* name);

PBTimeZoneOfName returns a PBTimeZone for the time zone named by IANA identifier name.

PBTimeZoneDefault

PBTimeZone PBTimeZoneDefault();

PBTimeZoneDefault returns the current default (system) time zone.

PBTimeZoneSetDefault

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

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

i64 PBTimeZoneUTCOffset(PBTimeZone tz);

PBTimeZoneUTCOffset returns the standard (non-DST) offset in seconds from UTC.

PBTimeZoneUTCOffset2

i64 PBTimeZoneUTCOffset2(PBTimeZone tz,
                         PBSysDate  timestamp);

PBTimeZoneUTCOffset returns the standard offset in seconds from UTC, accounting for DST.

PBTimeZoneDSTOffset

i64 PBTimeZoneDSTOffset(PBTimeZone tz,
                        PBSysDate  timestamp);

PBTimeZoneDSTOffset returns the daylight-savings time offset for the specified UTC timestamp

PBTimeZoneName

const char* PBTimeZoneName(PBTimeZone tz);

PBTimeZoneName returns the IANA identifier ("" for tz=PBTimeZone_NONE)

PBTimeZoneShortName

const char* PBTimeZoneShortName(PBTimeZone tz);

PBTimeZoneShortName returns an abbreviated name, e.g. "EDT" (Eastern Daylight Time.)

PBTimeZoneShortNameAt

const char* PBTimeZoneShortNameAt(PBTimeZone tz,
                                  PBSysDate  timestamp);

PBTimeZoneShortNameAt returns an abbreviated name at the specified UTC timestamp


#include <playbit/time.h>

PBTime

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

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

const PBTimeDuration PB_TIME_HOUR = 3600000000000;

PB_TIME_MINUTE

const PBTimeDuration PB_TIME_MINUTE = 60000000000;

PB_TIME_SECOND

const PBTimeDuration PB_TIME_SECOND = 1000000000;

PB_TIME_MILLISECOND

const PBTimeDuration PB_TIME_MILLISECOND = 1000000;

PB_TIME_MICROSECOND

const PBTimeDuration PB_TIME_MICROSECOND = 1000;

PB_TIME_NANOSECOND

const PBTimeDuration PB_TIME_NANOSECOND = 1;

PBTimeNow

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

PBTimeDuration PBTimeSince(PBTime past);

PBTimeSince returns the time delta between now and a point in time in the past

PBTimeUntil

PBTimeDuration PBTimeUntil(PBTime future);

PBTimeUntil returns the time delta between now and a point in time in the future

PBTimeBetween

PBTimeDuration PBTimeBetween(PBTime a,
                             PBTime b);

PBTimeBetween returns the time delta between a and b. i.e.

PBTimeDurationFormat

const char* PBTimeDurationFormat(PBTimeDuration d,
                                 char*          buf);

PBTimeDurationFormat writes a human-readable string like "1.6s" to buf.

PBTimeDurationHours

f64 PBTimeDurationHours(PBTimeDuration d);

PBTimeDurationHours converts duration d to hours as floating-point.

PBTimeDurationMinutes

f64 PBTimeDurationMinutes(PBTimeDuration d);

PBTimeDurationMinutes converts duration d to minutes as floating-point.

PBTimeDurationSeconds

f64 PBTimeDurationSeconds(PBTimeDuration d);

PBTimeDurationSeconds converts duration d to seconds as floating-point.

PBTimeDurationMilliseconds

i64 PBTimeDurationMilliseconds(PBTimeDuration d);

PBTimeDurationMilliseconds converts duration d to whole milliseconds.

PBTimeDurationMicroseconds

i64 PBTimeDurationMicroseconds(PBTimeDuration d);

PBTimeDurationMicroseconds converts duration d to whole microseconds.

PBTimeDurationNanoseconds

i64 PBTimeDurationNanoseconds(PBTimeDuration d);

PBTimeDurationNanoseconds converts duration d to whole nanoseconds.

PBTimeTimespec

void PBTimeTimespec(PBTime           t,
                    struct timespec* ts);

PBTimeTimespec populates a timespec struct with the value of t

PBTimeDurationTimespec

void PBTimeDurationTimespec(PBTimeDuration   d,
                            struct timespec* ts);

PBTimeDurationTimespec populates a timespec struct with the value of d


#include <playbit/timer.h>

PBTimer

typedef struct {
    u64 id;
} PBTimer;

PBTimer identifies a timer

PBTimerStart

PBTimer PBTimerStart(PBTime         when,
                     PBTimeDuration repeat,
                     PBTimeDuration leeway,
                     u64            arg1,
                     u64            arg2);

PBTimerStartTimeout

PBTimer PBTimerStartTimeout(PBTimeDuration delay,
                            u64            arg1,
                            u64            arg2);

PBTimerStartTimeout starts a one-shot timer which triggers delay time from now.

PBTimerStartInterval

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

bool PBTimerStop(PBTimer timer);

PBTimerStop cancels a timer.

PBTimerUpdate

void PBTimerUpdate(PBTimer        timer,
                   PBTime         when,
                   PBTimeDuration repeat,
                   PBTimeDuration leeway);

PBTimerUpdate modifies an existing timer with new values

PBTimerSetRepeatRate

void PBTimerSetRepeatRate(PBTimer        timer,
                          PBTimeDuration repeat);

PBTimerSetRepeatRate sets the repeat rate of an existing timer

PBTimerPoll

bool PBTimerPoll(PBTime        now,
                 PBTimerEvent* result);

PBTimerPoll returns an expired timer, a timer which when time has recently passed now.

Playbit API reference

Playbit's UI library is an immediate-mode styled API. The UI is composed of a tree of rectangles.

Example

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:

Guide


#include <playbit/app.h>

PBAppData

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

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

typedef void (*PBAppTimerCallback)(PBTimer, u64);

PBAppResource is a resource embedded in the program, defined in pbapp.toml

PBAppMain

void PBAppMain();

PBAppMain processes events and calls callbacks. It blocks until the calling thread exits.

PBAppName

PBStrSlice PBAppName();

PBAppName retrieves the name of the app, as defined by app_name in pbapp.toml

PBAppId

PBStrSlice PBAppId();

PBAppId retrieves the id of the app, as defined by app_id in pbapp.toml

PBAppResourceWithName

PBAppResource PBAppResourceWithName(PBStrSlice name);

PBAppResourceWithName returns an embedded resource by name, defined in pbapp.toml. Panics if the named resource is not found

PBAppResourceCount

u32 PBAppResourceCount();

PBAppResourceCount returns the number of embedded resources available

PBAppResourceAtIndex

PBAppResource PBAppResourceAtIndex(u32 index);

PBAppResourceAtIndex returns an embedded resource by index.

PBAppTimerStart

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.

PBAppTimeout

PBTimer PBAppTimeout(PBTimeDuration     delay,
                     PBAppTimerCallback callback,
                     u64                arg);

PBAppTimeout starts a one-shot timer which triggers delay time from now

PBAppInterval

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

void PBAppRender(PBEvent* ev,
                 u32      eventCount);

PBAppRender converts system events to UI/draw updates and executes one render pass, calling PBApp.onRender

PBAppRequestRender

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.)


#include <playbit/event.h>

PBGesturePhase

typedef enum PBGesturePhase PB_ENUM_TYPE(u8){
    PBGesturePhase_CHANGED = PBSysGesturePhase_CHANGED,
    PBGesturePhase_BEGAN = PBSysGesturePhase_BEGAN,
    PBGesturePhase_ENDED = PBSysGesturePhase_ENDED,
} PBGesturePhase;

PBKeyboardFlags

typedef enum PBKeyboardFlags PB_ENUM_TYPE(u16){
    PBKeyboardFlag_REPEAT = PBSysKeyboardFlag_REPEAT,
} PBKeyboardFlags;

PBKeyboardKey

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

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

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

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

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

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

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

typedef enum PBEventType PB_ENUM_TYPE(u16){
    PBEventType_INVALID = PBSysEventType_INVALID,
    PBEventType_SIGNAL = PBSysEventType_SIGNAL,

    // 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,

    // timer
    PBEventType_TIMER = 0x8000,
} PBEventType;

PBEventType defines the type of a PBEvent

PBEvent

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

typedef struct PBSignalEvent {
    PBEvent      event;
    PBSysHandle  handle;
    PBSysSignals signals;
    PBSysSignals pulseSignals;
    u16          objectType; // PBSysObjectType
    u16          _reserved;
} PBSignalEvent;

PBInputEvent

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

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

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

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

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

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;

PBTimerEvent

typedef struct PBTimerEvent {
    PBEvent event;
    PBTimer timer;
    u64     arg1;
    u64     arg2;
} PBTimerEvent;

PBEventAny

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;
    PBTimerEvent      timer;
    u8                _maxSize[PBSysEventSize_MAX];
} PBEventAny;

PBEventPoll

i32 PBEventPoll(PBEvent* events,
                u32      eventsSize,
                u32      maxCount);

PBEventPoll retrieves events for the calling thread.

PBEventNext

PBEvent* PBEventNext(PBEvent* event);

PBEventNext returns the next event in an array of events returned from PBEventPoll

PBEventAnyNext

PBEventAny* PBEventAnyNext(PBEventAny* event);

PBEventAnyNext returns the next event in an array of events returned from PBEventPoll

PBEventTypeStr

const char* PBEventTypeStr(PBEventType arg);

PBEventTypeStr returns a short string representation of an event type, e.g. "SIGNAL"

PBEventStr

u32 PBEventStr(const PBEvent* event,
               char*          buf,
               u32            bufCap);

PBEventStr writes a string representation of a PBEvent to buf.

PBEventOfSysEvent

usize PBEventOfSysEvent(PBEvent*          event,
                        usize             eventSize,
                        const PBSysEvent* sysEvent);

PBEventOfSysEvent copies a PBSysEvent entry to a PBEvent.

PBLogEvent

void PBLogEvent(const PBEvent* event);

PBLogEvent is a convenience function which calls PBLog with the result of passing event to PBEventStr


#include <playbit/window.h>

PBWindow

typedef struct {
    PBSysHandle handle;
} PBWindow;

PBWindow is a handle to a UI window

PBWindowOpt

typedef PBOpt(PBWindow) PBWindowOpt;

PBWindow is a handle to a UI window

PBWindowMain

PBWindow PBWindowMain();

PBWindowMain retrieves the main window, or PBWindow_NONE if there's no main window.

PBWindowClose

PBSysErr PBWindowClose(PBWindow window);

PBWindowClose closes window handle and destroys the associated window.

PBWindowOpen

PBWindow PBWindowOpen(const char* title,
                      f32         width,
                      f32         height);

PBWindowOpen creates a window on the current thread with title and size.

PBWindowOpenWithConfig

PBWindowOpt PBWindowOpenWithConfig(PBThread                 thread,
                                   const PBSysWindowConfig* config);

PBWindowOpenWithConfig creates a window on thread using detailed system configuration.

PBWindowCopyTitle

PBSysErr PBWindowCopyTitle(PBWindow window,
                           PBStr*   titleOut,
                           PBMem    ma);

PBWindowCopyTitle copies the title of a window to title, allocating memory with ma

PBWindowSetTitle

void PBWindowSetTitle(PBWindow   window,
                      PBStrSlice title);

PBWindowSetTitle sets the title of a window

PBWindowStyle

PBSysWindowStyle PBWindowStyle(PBWindow window);

PBWindowStyle retrieves the current style of a window

PBWindowSetStyle

void PBWindowSetStyle(PBWindow         window,
                      PBSysWindowStyle style);

WindowSetStyle sets the style of a window

PBWindowSetSizeLimits

void PBWindowSetSizeLimits(PBWindow window,
                           PBSize   min,
                           PBSize   max);

PBWindowSetSizeLimits sets lower and upper limits for window frame size

PBWindowSetMinSize

void PBWindowSetMinSize(PBWindow window,
                        f32      minWidth,
                        f32      minHeight);

PBWindowSetMinSize sets lower limit for window frame size

PBWindowSetMaxSize

void PBWindowSetMaxSize(PBWindow window,
                        f32      maxWidth,
                        f32      maxHeight);

PBWindowSetMinSize sets upper limit for window frame size

PBWindowRect

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

PBSysErr PBWindowSetFrame(PBWindow window,
                          PBRect   frame);

PBWindowSetFrame adjusts the origin and (outer) size of a window

PBWindowSetOrigin

PBSysErr PBWindowSetOrigin(PBWindow window,
                           f32      x,
                           f32      y);

PBWindowSetOrigin repositions the window on screen

PBWindowSetSize

PBSysErr PBWindowSetSize(PBWindow window,
                         f32      width,
                         f32      height);

PBWindowSetSize sets the (outer) size of a window

PBWindowSetSizeCentered

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

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

PBSize PBWindowContentSize(PBWindow window);

PBWindowContentSize returns the size of a window's content

PBWindowSetContentSizeCentered

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

f32 PBWindowScaleFactor(PBWindow window);

PBWindowScaleFactor returns the dp scale factor for a window (pixels per dp.)

PBWindowGetSize

PBVector2 PBWindowGetSize(PBWindow window);

PBWindowGetSize returns current window's content size in dp

PBWindowGetScale

f32 PBWindowGetScale(PBWindow window);

PBWindowGetScale returns current device-pixel scale factor for window.

PBCursorSetStyle

int PBCursorSetStyle(u32 windowId,
                     u32 style);

#include <playbit/ui.h>

PBUIFont

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

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

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

#define PBUIBoxFlag_Draw

all draw flags turned on

PBUISizeKind

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

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

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

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

struct PBUISize {
    PBUISizeKind kind;
    f32          value;
    f32          strictness;
};

Preferred size specification for one axis.

PBUISize2

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

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

typedef enum PBUIBorderGrow {
    PBUIBorderGrow_CENTER = 0,
    PBUIBorderGrow_INNER = 1,
    PBUIBorderGrow_OUTER = 2,
} PBUIBorderGrow;

PBUIBorderGrow determines how a border grows

PBUIBorder

struct PBUIBorder {
    PBUIBorderGrow grow;
    f32            width;
    PBColor        color;
};

Uniform border rendered inset, on top of a box's content. Requires PBUIBoxFlag_DrawBorder.

PBUIPadding

struct PBUIPadding {
    f32 left, top, right, bottom;
};

Inner spacing between a box's edges and its children/content, in pixels.

PBUICornerRadius

struct PBUICornerRadius {
    f32 topLeft, topRight, bottomRight, bottomLeft;
};

Per-corner rounding radii in pixels. Passed via PBUIStyle.cornerRadius or PBUICornerRadiusMake().

PBUITextAlign

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

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

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

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

struct PBUIDrawCommandArray {
    PBUIDrawCommand* data;
    u64              count;
    u64              capacity;
};

Dynamic array of draw commands. Produced by PBUIOutputDrawCommands() each frame.

PBUIDrawCallback

#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

typedef void (PBUIBox * _Nonnull, PBRectangle, PBUIDrawCommandArray * _Nonnull) PBUIDrawCallbackProc;

Dynamic array of draw commands. Produced by PBUIOutputDrawCommands() each frame.

PBUIPushDrawCommand

bool PBUIPushDrawCommand(PBUIDrawCommandArray* cmds,
                         PBUIDrawCommand       cmd);

Append a single draw command, an array of commands, or a filled rect to a draw list.

PBUIPushDrawCommandArray

bool PBUIPushDrawCommandArray(PBUIDrawCommandArray* cmds,
                              PBUIDrawCommandArray  push_cmds);

Appends an array of draw commands to another array

PBUIPushDrawRect

bool PBUIPushDrawRect(PBUIDrawCommandArray* cmds,
                      PBRectangle           rect,
                      PBColor               color);

Pushes a single draw rectangle command

PBUIBoxEquipDraw

void PBUIBoxEquipDraw(PBUIBox* box,
                      u64      capacity);

Allocate a per-box draw command list (required before PBUIBoxDraw), or append a command to it.

PBUIBoxDraw

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

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

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

struct PBUIBoxSlot {
    PBUIBox* firstHash;
    PBUIBox* lastHash;
};

Internal hash-table bucket for fast box lookup by key. Not intended for direct use.

PBUIBoxIter

struct PBUIBoxIter {
    PBUIBox* next;
    u32      pushCount;
    u32      popCount;
};

Iterator state for depth-first box tree traversal. Use with PBUIBoxIterDepthFirstPre/Post.

PBUISignal

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

#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

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

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

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

#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

#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

#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

#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

#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

#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

#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

#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

#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

#define PBUI_vh(x)

a fraction of the current view height [0-1]

PBUI_size2

#define PBUI_size2(x, y)

Shorthand constructors for two-component size and alignment types.

PBUI_v2

#define PBUI_v2(x, y)

Shorthand vector constructors.

PBUI_rgb

#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

#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

#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

#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

#define PBUIBoxEach(box)

Iterate over a linked list of sibling boxes starting at box. Usage: for PBUIBoxEach(root->firstChild) { ... it ... }

PBStringWordScan

i64 PBStringWordScan(PBStrSlice str,
                     i64        index,
                     i64        move);

PBStringCodepointScan

i64 PBStringCodepointScan(PBStrSlice str,
                          i64        index,
                          i64        move);

PBStringReplace

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

PBStrSlice PBStringFromCodepoint(PBArena* arena,
                                 u32      codepoint);

PBStringFind

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

PBUISize PBUISizeMake(PBUISizeKind kind,
                      f32          value,
                      f32          strictness);

Construct a PBUISize

PBUISize2Make

PBUISize2 PBUISize2Make(PBUISize x,
                        PBUISize y);

Construct a PBUISize2

PBUIFontMake

PBUIFont PBUIFontMake(PBStrSlice family,
                      f32        size,
                      f32        weight);

Construct a PBUIFont

PBUIAlign2Make

PBUIAlign2 PBUIAlign2Make(PBUIAlign x,
                          PBUIAlign y);

Construct a PBUIAlign2

PBUIShadowMake

PBUIShadow PBUIShadowMake(PBVector2 offset,
                          f32       blur,
                          f32       spread,
                          PBColor   color,
                          bool      inset);

Construct a PBUIShadow

PBUIBorderMake

PBUIBorder PBUIBorderMake(f32     width,
                          PBColor color);

Construct a PBUIBorder

PBUIPaddingMake

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

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

PBVector4 PBUI__Vector4FromPadding(PBUIPadding padding);

PBUI__Vector4FromCornerRadius

PBVector4 PBUI__Vector4FromCornerRadius(PBUICornerRadius cornerRadius);

PBUI__TextAlignToAnchor

PBVector2 PBUI__TextAlignToAnchor(PBUITextAlign align);

@Internal: converts PBUITextAlign to a normalized anchor vector.

PBUIAxisToString

PBStrSlice PBUIAxisToString(PBUIAxis axis);

Convert PBUIAxis to string

PBUIAlignToString

PBStrSlice PBUIAlignToString(PBUIAlign align);

Convert PBUIAlign to string

PBUITextAlignToString

PBStrSlice PBUITextAlignToString(PBUITextAlign textAlign);

Convert PBUITextAlign to string

PBUIKeyZero

PBUIKey PBUIKeyZero();

PBUIKeyEquals

bool PBUIKeyEquals(PBUIKey a,
                   PBUIKey b);

PBUIKeyIsZero

bool PBUIKeyIsZero(PBUIKey a);

PBUIKeyFromString

PBUIKey PBUIKeyFromString(PBUIKey    seedKey,
                          PBStrSlice string);

PBUIKeyFromStringAndIndex

PBUIKey PBUIKeyFromStringAndIndex(PBUIKey    seedKey,
                                  PBStrSlice string,
                                  u32        index);

PBUIBoxNil

PBUIBox* PBUIBoxNil();

PBUIBoxIsNil

bool PBUIBoxIsNil(PBUIBox* it);

PBUIBoxFromKey

PBUIBox* PBUIBoxFromKey(PBUIKey key);

look up a box from the previous frame by key (may return nil)

PBUIBoxFindScrollableParent

PBUIBox* PBUIBoxFindScrollableParent(PBUIBox* parent);

finds the nearest parent with a scroll flag set

PBUIBoxIterDepthFirstPre

PBUIBoxIter PBUIBoxIterDepthFirstPre(PBUIBox* box,
                                     PBUIBox* root);

use for iterating a box tree in pre-order

PBUIBoxIterDepthFirstPost

PBUIBoxIter PBUIBoxIterDepthFirstPost(PBUIBox* box,
                                      PBUIBox* root);

use for iterating a box tree in post-order

PBUITopParent

PBUIBox* PBUITopParent();

PBUIPushParent

void PBUIPushParent(PBUIBox* box);

pushes a new box onto the parent stack (new boxes will be created as children of this)

PBUIPopParent

PBUIBox* PBUIPopParent(PBUIBox* box);

pops a box off the parent stack, optionally asserts that the popped box matches (or just pass 0 otherwise)

PBDeferLoop

#define PBDeferLoop(begin, end)

Generic scope-guard loop: runs begin, executes the loop body once, then runs end.

PBUIParent

macro Scope-guarded parent push/pop. Use as: PBUIParent(box) { ... children ... }

PBUIBoxMakeFromKey

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

PBUIBox* PBUIBoxMakeFromString(PBUIBoxFlags flags,
                               PBStrSlice   string);

Construct a box and add it as a child to the current parent

PBUIBoxMakeFromStringF

PBUIBox* PBUIBoxMakeFromStringF(PBUIBoxFlags flags,
                                const char*  fmt,
                                ...);

Same as PBUIBoxMakeFromString, but takes a format string instead

PBUIBoxKey

PBUIKey PBUIBoxKey(PBStrSlice string,
                   u64        index);

Shorthand for: PBUIKeyFromStringAndIndex(PBUIActiveSeedKey(), string, index)

PBUIBoxSetText

void PBUIBoxSetText(PBUIBox*   box,
                    PBStrSlice string);

Set the display text on a box (requires PBUIBoxFlag_DrawText).

PBUIBoxSetFixedPosition

void PBUIBoxSetFixedPosition(PBUIBox*  box,
                             PBVector2 pos);

Override a box's position absolutely in pixels (requires PBUIBoxFlag_FloatingX/Y).

PBUIBoxSetFixedSize

void PBUIBoxSetFixedSize(PBUIBox*  box,
                         PBVector2 size);

Force a box to an exact pixel size (requires PBUIBoxFlag_FixedWidth/Height).

PBUISignalFromBox

PBUISignal PBUISignalFromBox(PBUIBox* box);

Query all pointer-interaction state for a box in a single call.

PBUIBoxFindAtPoint

PBUIBox* PBUIBoxFindAtPoint(PBUIBox*     root,
                            PBVector2    pos,
                            PBUIBoxFlags flags);

Walk the box tree from root and return the topmost box under pos matching flags.

PBUIBoxSetParent

void PBUIBoxSetParent(PBUIBox* box,
                      PBUIBox* parent);

Reparent a box or insert it after a sibling in the child list.

PBUIBoxInsertAfter

void PBUIBoxInsertAfter(PBUIBox* box,
                        PBUIBox* sibling);

PBUIBoxScrollIntoView

void PBUIBoxScrollIntoView(PBUIBox* box);

Request the nearest scrollable ancestor to scroll this box into view.

PBUIBoxSetDrawCallback

void PBUIBoxSetDrawCallback(PBUIBox*              box,
                            PBUIDrawCallbackProc* callback);

Attach a custom draw callback; called during draw-command generation. Requires PBUIBoxEquipDraw().

PBUIBoxGetComputedRect

PBRectangle PBUIBoxGetComputedRect(PBUIBox* box);

Returns the box's computed screen-space rectangle after layout. Call after PBUIEndBuild().

PBUISetState

void PBUISetState(PBUIState* it);

Sets the current global UI state

PBUIGetState

PBUIState* PBUIGetState();

Gets the current global UI state

PBUIRoot

PBUIBox* PBUIRoot();

The root-most box of the current UI state

PBUITopBox

PBUIBox* PBUITopBox();

The last box created in the tree

PBUIStateGetMemorySize

u64 PBUIStateGetMemorySize();

Returns the minimum initial arena size for a UI state allocation

PBUIStateAlloc

PBUIState* PBUIStateAlloc(PBArena* arena);

Allocates and initializes a new UI state

PBUIStateFree

void PBUIStateFree(PBUIState* statePtr);

Frees the UI state and its arena, and sets *statePtr to NULL

PBUIFrameArena

PBArena* PBUIFrameArena();

Returns an arena that is valid for the lifetime of this frame

PBUIfmt

PBStrSlice PBUIfmt(const char* fmt, ...);

Prints a C-style formatted string into the frame arena

PBUIMeasureText

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

void PBUIBeginBuild(PBRectangle     window,
                    PBUIWindowInput input);

Equivalent to calling PBUIBeginFrame then PBUIBeginLayout

PBUIEndBuild

void PBUIEndBuild();

Equivalent to calling PBUIEndFrame then PBUIEndLayout

PBUIBeginFrame

void PBUIBeginFrame(PBRectangle     window,
                    PBUIWindowInput input);

Starts a UI tree build (call this once per frame/build)

PBUIEndFrame

void PBUIEndFrame();

Ends a UI tree build (call this once per frame/build)

PBUIBeginLayout

void PBUIBeginLayout();

Begins a layout pass, can be called multiple times per frame/build

PBUIEndLayout

void PBUIEndLayout();

Ends a layout pass, can be called multiple times per frame/build

PBUICalcSizesStandalone

void PBUICalcSizesStandalone(PBUIBox* root,
                             PBUIAxis axis);

PBUICalcSizesUpwardsDependent

void PBUICalcSizesUpwardsDependent(PBUIBox* root,
                                   PBUIAxis axis);

PBUICalcSizesDownwardsDepenedent

void PBUICalcSizesDownwardsDepenedent(PBUIBox* root,
                                      PBUIAxis axis);

PBUILayoutEnforceConstraints

void PBUILayoutEnforceConstraints(PBUIBox* root,
                                  PBUIAxis axis);

PBUILayoutPosition

void PBUILayoutPosition(PBUIBox* root,
                        PBUIAxis axis);

PBUILayoutRoot

void PBUILayoutRoot(PBUIBox* root,
                    PBUIAxis axis);

Applies a full layout pass along the given axis

PBUIOutputDrawCommands

PBUIDrawCommandArray PBUIOutputDrawCommands(PBArena*   arena,
                                            PBUIState* state);

Outputs a list of draw commands for the UI tree

PBUIKeyPressed

bool PBUIKeyPressed(PBKeyboardKey key);

PBUIKeyReleased

bool PBUIKeyReleased(PBKeyboardKey key);

PBUIKeyRepeat

bool PBUIKeyRepeat(PBKeyboardKey key);

PBUIKeyPressedOrRepeat

bool PBUIKeyPressedOrRepeat(PBKeyboardKey key);

PBUIKeyDown

bool PBUIKeyDown(PBKeyboardKey key);

PBUIEventOfType

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

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

bool PBUIMousePressed(PBMouseButton button);

PBUIMouseReleased

bool PBUIMouseReleased(PBMouseButton button);

PBUIMouseDown

bool PBUIMouseDown(PBMouseButton button);

PBUIMousePosition

PBVector2 PBUIMousePosition();

PBUIDragStart

PBVector2 PBUIDragStart();

PBUIDragDelta

PBVector2 PBUIDragDelta();

PBUIScrollAmount

PBVector2 PBUIScrollAmount();

PBUIBoxIsHover

bool PBUIBoxIsHover(PBUIBox* box);

PBUIBoxIsActive

bool PBUIBoxIsActive(PBUIBox* box);

PBUIBoxIsDown

bool PBUIBoxIsDown(PBUIBox* box);

PBUIBoxOnPressed

bool PBUIBoxOnPressed(PBUIBox* box);

PBUIBoxOnReleased

bool PBUIBoxOnReleased(PBUIBox* box);

PBUIBoxIsFocused

bool PBUIBoxIsFocused(PBUIBox* box);

PBUIBoxOnClick

bool PBUIBoxOnClick(PBUIBox* box);

PBUIBoxIsDrag

bool PBUIBoxIsDrag(PBUIBox* box);

PBUIBoxOnDrop

bool PBUIBoxOnDrop(PBUIBox* box);

PBUIBoxIsDropTarget

bool PBUIBoxIsDropTarget(PBUIBox* box);

PBUIBoxClick

void PBUIBoxClick(PBUIBox* box);

Programmatically click a box

PBUIBoxFocus

void PBUIBoxFocus(PBUIBox* box);

Programmatically focus a box

PBUISetDragDataSize

void PBUISetDragDataSize(u8* data,
                         u64 size);

Set global drag data

PBUIGetDragDataSize

void* PBUIGetDragDataSize(u64 size);

Get global drag data

PBUIBoxOnMount

bool PBUIBoxOnMount(PBUIBox* box);

PBUIBoxPointToLocal

PBVector2 PBUIBoxPointToLocal(PBUIBox*  box,
                              PBVector2 point);

Converts a point in UI-space to local box-space

PBUIBoxGetScroll

PBVector2 PBUIBoxGetScroll(PBUIBox* box);

PBUIGetActiveBox

PBUIBox* PBUIGetActiveBox();

PBUIGetHoverBox

PBUIBox* PBUIGetHoverBox();

PBUISpacer

PBUIBox* PBUISpacer(PBUISize size);

Create a gap between two boxes (similar to "margin" in some UI systems)

PBUIText

PBUIBox* PBUIText(PBUIFont   font,
                  PBStrSlice text);

A simple text element

PBUIDiv

PBUIBox* PBUIDiv(PBStrSlice label);

A simple divider that expands to fill it's child contents

PBUIDrawCommmands

void PBUIDrawCommmands(PBUIDrawCommandArray cmds);

PBUIDrawState

void PBUIDrawState(PBArena*   scratch,
                   PBUIState* state);

#include <playbit/ui_components.h>

PBUINamedRowBegin

int* PBUINamedRowBegin(PBStrSlice name);

Begin a named parent row. Must be paired with PBUINamedRowEnd

PBUINamedRowEnd

void PBUINamedRowEnd();

End a named parent row

PBUIRowBegin

int* PBUIRowBegin();

Begin a row. Must be paired with PBUIRowEnd

PBUIRowEnd

void PBUIRowEnd();

End a row

PBUINamedColumnBegin

int* PBUINamedColumnBegin(PBStrSlice name);

Begin a named parent column. Must be paired with PBUINamedColumnEnd

PBUINamedColumnEnd

void PBUINamedColumnEnd();

End a named parent column

PBUIColumnBegin

int* PBUIColumnBegin();

Begin a column. Must be paired with PBUIColumnEnd

PBUIColumnEnd

void PBUIColumnEnd();

End a column

PBUIButtonProps

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

int* PBUIButton(PBUIButtonProps props);

Construct a button

PBUISlider

int* PBUISlider(f32* value);

Horizontal slider that reads and writes a float value in [0, 1]. Check .changed on the signal.

PBUILabel

int* PBUILabel(PBStrSlice text);

Non-interactive text label. Sized to text content.

PBUICheckbox

int* PBUICheckbox(bool* value);

Toggle checkbox. Reads and writes *value; check PBUISignalFromBox(box).changed for updates.

PBUIColorPicker

int* PBUIColorPicker(int* color);

Inline HSV color picker panel, writes to color on change

PBUIColorSwatch

int* PBUIColorSwatch(int color);

Non-interactive color preview rectangle

PBUIColorPickerSwatch

int* PBUIColorPickerSwatch(int*  color,
                           bool* open);

Swatch that toggles a picker popover; *open controls visibility

PBUIScrollViewBegin

int* PBUIScrollViewBegin(u32 flags);

Begin a scrollable container. Pass PBUIBoxFlag_ScrollX / PBUIBoxFlag_ScrollY to enable axes. Must be paired with PBUIScrollViewEnd.

PBUIScrollViewEnd

void PBUIScrollViewEnd(int* scroll);

Ends a scroll view

PBUIVirtualListCursor

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

PBUIVirtualListCursor PBUIVirtualListBegin(i64 itemCount,
                                           f32 itemHeight);

PBUIVirtualListEnd

void PBUIVirtualListEnd(PBUIVirtualListCursor cursor);

PBUITooltipExt

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

int* PBUITooltip(PBStrSlice text);

Construct a tooltip that attaches to the most recently built box

PBUIImage

int* PBUIImage(u64 imageID);

Render an image identified by an opaque backend image ID. Size the box with FixedSize flags.

PBUITextInputProps

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

int* PBUITextInput(PBUITextInputProps props);

Single-line text input field with full keyboard editing support.

Use with: `UITextInputP(.key = PBStrLit("search"), .placeholder = PBStrLit("Search..."))`

PBUITextInputP

macro PBUIBox* PBUITextInputP(props...)

Ergonomic helper for PBUITextInput((PBUITextInputProps){ props... })

PBUIDevTools

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.