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.
- Bits 1 through 24 are reserved for the system.
- Bits 25 through 32 are reserved for user-defined 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
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.
- Required rights: none
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.
- Required rights: none
PBSysAudioBufferDestroy
PBSysErr PBSysAudioBufferDestroy(PBSysHandle audio,
PBSysAudioBuffer buffer);
Destroys an audio buffer (and frees the associated memory with it).
- Required rights: none
PBSysAudioBufferPlay
PBSysAudioSound PBSysAudioBufferPlay(PBSysHandle audio,
PBSysAudioBuffer buffer);
Starts playing an instance of an audio buffer.
- Required rights: none
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.
- Required rights: none
PBSysAudioSetVolume
PBSysErr PBSysAudioSetVolume(PBSysHandle audio,
f32 volume);
Sets the global volume of the sound mixer.
- Required rights: none
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.
- Parameters:
dest: The memory location in the guest program where the runtime will copy the resourcedestLen: How large of a space in guest memory for the runtime to copy into
- Returns: The size of the resource which has been loaded, or a
PBSysErrvalue if < 0 - Required rights:
PBSysRight_READ
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.
- Parameters:
readHandleOut: If not NULL, a second handle is returned withPBSysRight_READ.cap: Initial capacity of the internal buffer, in number of entries. I.e. the total amount of memory allocated for the internal buffer is at leastentSize*cap bytes.maxCap: Limits how much the internal buffer can grow. IfmaxCapis <=cap, a fixed size is used.
- Returns: A handle to the channel with
PBSysRight_WRITE. - Required rights: none
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.
- Required rights:
PBSysRight_WRITE
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.
- Parameters:
dstEnts: Must be an array ofdstEntsCapnumber of entries,dstEntSizebytes each.flags: Should be 0.
- Returns: The number of entries read. 0 if there were no entries to be read or if
dstEntsCap== 0.PBSysErr_ENDif thechannelis closed. - Required rights:
PBSysRight_READ
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.
- Parameters:
srcEnts: Must be an array ofsrcEntsCapnumber of entries,srcEntSizebytes each.flags: Should be 0.
- Returns: The number of entries written. 0 if the
channelis full orsrcEntsCap== 0.PBSysErr_ENDif thechannelis closed for writing. - Required rights:
PBSysRight_WRITE
Clock
PBSysClockMonotonic
PBSysTime PBSysClockMonotonic();
PBSysClockMonotonic returns the current system time
- Required rights: none
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.
- Required rights:
PBSysRight_READ
PBSysClockReadInfo
PBSysErr PBSysClockReadInfo(PBSysHandle clock,
PBSysClockInfo* info,
u32 infoSize);
PBSysClockReadInfo retrieves information about a clock
- Required rights:
PBSysRight_READ
Event
PBSysEventPoll
i32 PBSysEventPoll(PBSysEvent* events,
u32 eventsSize,
u64 deadline,
u64 deadlineLeeway);
PBSysEventPoll retrieves events from the runtime, suspending the calling thread if needed.
- Parameters:
events: Buffer to be populated with producedevents.eventsSize: Total number of bytes available atevents. Note that this is not the number ofPBSysEventstructs but bytes of memory. The size of aPBSysEventis variable. Generally this should be at least a kilobyte since IME inputeventsmay be arbitrarily large. In most cases singleeventsare small; tens of bytes.deadline: When to time out. Ifdeadlineis U64_MAX, it will wait indefinitely until at least one event can be returned or an error occurs. Ifdeadlineis 0, this function only checks for availableeventswithout blocking.deadlineLeeway: Precision request in nanoseconds; how muchdeadlineis willing to fluctuate.
- Returns: The number of
eventswritten (not the number of bytes.) 0 ifdeadlinewas reached, whendeadline> 0. 0 if there were noeventsavailable, whendeadline== 0 or eventsCap == 0.PBSysErr_ENDif the current thread is exiting (even pipeline shut down.)PBSysErr_NO_MEMifeventsSizeis too small for a single event. - Required rights: none
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.
- Parameters:
fileList:Handleto object of typePBSysObject_FileListname: Buffer in which to writenameof nextentrynameCap: Capacity ofname, in bytesentry: Optional buffer in which to write additional information about the nextentryentrySize: Size in bytes ofentry
- Returns: Total number of bytes written to
namePBSysErr_ENDwhen the end of the list has been reached.PBSysErr_BUFFER_TOO_SMALLifnamewas too short, in which can you can try again with largernameCapPBSysErras a negative value on error. - Required rights:
PBSysRight_READ
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.
- Parameters:
path: Path as UTF-8 textpathLen: Size in bytes ofpath. May be 0 to mean "dir"flags: Unused. Pass 0.
- Returns: a handle to an object of type
PBSysObject_FileList - Required rights: none
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.
- Parameters:
dir: Parent directory, an object of typePBSysObject_Filepath: Path as UTF-8 textpathLen: Size in bytes ofpath. Must be >0flags: Bits ofPBSysFileOpenFlags
- Returns:
Handleto aPBSysObject_Fileobject that represents the item atpath, orPBSysErr(negative value) on error - Required rights:
PBSysRight_READ
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.
- Parameters:
flags: Bits ofPBSysFileReadFlags
- Required rights:
PBSysRight_READ
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.
- Parameters:
flags: Bits ofPBSysFileWriteFlags
- Required rights:
PBSysRight_WRITE
Gui
PBSysGuiCursorStyleSet
PBSysErr PBSysGuiCursorStyleSet(PBSysHandle gui,
u32 pointerId,
PBSysCursorStyle style,
PBSysHandle image,
u64 flags);
PBSysGuiCursorStyleSet sets the appearance of specified pointer's cursor.
pointerId: set to 0 to set cursor for all pointers, or a specificpointerId(e.g. from aPBSysPointerEvent) to set the cursor only for that pointer.styledetermines how the cursor is presented.imageshould be the handle of animageifstyleisPBSysCursorStyle_IMAGE, otherwise theimageparameter is ignored and should be 0.flagsare unused; pass 0.Required rights: none
Handle
PBSysHandleClose
PBSysErr PBSysHandleClose(PBSysHandle handle);
PBSysHandleClose closes a handle. The handle is invalid after this call.
- Required rights: none
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.
- Returns: A negative value as PBSysError on error.
- Required rights:
PBSysRight_DUPLICATE
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.
- Returns: The total number of
handles, which might be more thanhandlesCap. <0 if an error occurred, as aPBSysErr. - Required rights: none
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.
- Parameters:
net: Networking capability (handle to an object of typePBSysObject_Net)uri: URI.uriLen: Size in bytes ofuriconfig: ConfigurationconfigSize: Size in bytes of struct inconfigparameter
- Returns:
Handleto aNetSessionobject on success, orPBSysErr(negative value) on error.PBSysErr_NOT_SUPPORTEDif the protocol type requested inuriis not supported. - Required rights: none
PBSysNetSessionOpen
PBSysHandle PBSysNetSessionOpen(PBSysHandle net,
const u8* sessionId,
u32 sessionIdLen,
const PBSysNetSessionConfig* config,
u32 configSize);
PBSysNetSessionOpen opens a Playbit network session
- Parameters:
net: Networking capability (handle to an object of typePBSysObject_Net)sessionId: Session identifier, unique within app-id namespacesessionIdLen: Size in bytes ofsessionIdconfig: ConfigurationconfigSize: Size in bytes of struct inconfigparameter
- Returns:
Handleto aNetSessionobject, orPBSysErr(negative value) on error. Opening aNetSessionstarts or attaches to the underlying AP connection asynchronously. - Required rights: none
NetSession
PBSysNetSessionId
PBSysErr PBSysNetSessionId(PBSysHandle netSession,
u8* sessionIdBuf,
u32 sessionIdBufCap);
PBSysNetSessionId copies the session identifier bytes of a network session.
- Parameters:
netSession: Network session, handle to aNetSessionobjectsessionIdBuf: Destination buffer for the session identifier bytessessionIdBufCap: Size in bytes ofsessionIdBuf
- Returns: 0 on success,
PBSysErr_BUFFER_TOO_SMALLifsessionIdBufCapis too small, orPBSysErron failure. - Required rights:
PBSysRight_READ
PBSysNetSessionOpenStream
PBSysHandle PBSysNetSessionOpenStream(PBSysHandle netSession,
const u8* channelId,
u32 channelIdLen,
u64 flags);
PBSysNetSessionOpenStream opens a stream for a channel in a network session.
- Parameters:
netSession: Network session, handle to aNetSessionobjectchannelId:Channelidentifier, unique within the network sessionchannelIdLen: Size in bytes ofchannelIdflags: Reserved. Must be 0.
- Returns:
Handleto aStreamobject, orPBSysErr(negative value) on error. The stream may become writable later, after the underlying session is authenticated and ready. - Required rights: none
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.
- Required rights:
PBSysRight_OBSERVE
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.
- Returns:
PBSysErr_INVALIDif any non-user (i.e. system) signals are included in the bitmasks. - Required rights: none
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.
- Parameters:
handlesOut: Receives the two created stream handles on success.bufferSize: Per-direction buffer capacity in bytes. 0 uses an implementation default.flags: Must be 0.
- Required rights: none
PBSysStreamRead
i64 PBSysStreamRead(PBSysHandle stream,
const PBSysBuf* bufs,
u32 bufCount,
u32 flags);
PBSysStreamRead reads bytes from a stream into one or more buffers.
- Parameters:
flags: Unused. Pass 0
- Required rights:
PBSysRight_READ
PBSysStreamStatsRead
PBSysErr PBSysStreamStatsRead(PBSysHandle stream,
PBSysStreamStats* stats,
u32 statsSize,
u64 flags);
PBSysStreamStatsRead retrieves statistics for a stream.
- Parameters:
stats: Storage location for resultsstatsSize: Capacity ofstatsin bytesflags: Unused. Pass 0.
- Required rights: none
PBSysStreamWrite
i64 PBSysStreamWrite(PBSysHandle stream,
const PBSysBuf* bufs,
u32 bufCount,
u32 flags);
PBSysStreamWrite writes bytes from one or more buffers to a stream.
- Parameters:
flags: Bits ofPBSysStreamWriteFlags
- Required rights:
PBSysRight_WRITE
Textplan
PBSysTextplanGetCaretBounds
u64 PBSysTextplanGetCaretBounds(PBSysHandle textPlan,
u64 caretTextIndex);
- Required rights: none
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.
- Parameters:
textPlan: the text plan objectselectionStart: one end of the selection rangeselectionEnd: the other end of the selection rangerects: output buffer, or NULL to query the count onlyrectsCap: number of entries available inrectsrectSize: size of one entry inrects, usually sizeof(PBSysTextplanSelectionRect)
- Returns: the total number of selection rectangles for the requested range
- Required rights:
PBSysRight_READ
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.
- Required rights:
PBSysRight_READ
PBSysTextplanHitTest
u64 PBSysTextplanHitTest(PBSysHandle textPlan,
i32 x,
i32 y);
- Required rights: none
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
- PBTextPlanLayout_PREFORMATTED = 1<<0: Prevents trimming of trailing/leading/duplicate whitespace.
- PBTextPlanLayout_ONE_LINE = 1<<1: When set: the text will be placed on a single line; newline characters are ignored; and PBTextPlanLayout_ALWAYS_SET_HEIGHT is implied. When clear, the text will be wrapped to multiple lines as necessary.
- PBTextPlanLayout_ALWAYS_SET_HEIGHT = 1<<2: Implied by PBTextPlanLayout_ONE_LINE. The computed
height(seePBSysTextplanGetSize) will be set to theheightof the single line, even if the input text is an empty string. Note that #defines are not provided yet for theseflags, so you will need to enter the constant values manually.
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.
- Required rights:
PBSysRight_WRITE
PBSysTextplanMoveSelection
bool PBSysTextplanMoveSelection(PBSysHandle textPlan,
u32 mode,
PBSysTextplanSelection* selection,
u32 selectionSize);
PBSysTextplanMoveSelection updates a selection using selection-adjustment flags without hit
testing a point.
- Parameters:
textPlan: the text plan objectmode: a bitwise OR of PBSysTextplanSelectionAdjustment_* flagsselection: in-outselectionstate containing anchor, caret, and lastDownselectionSize: size of *selection, usually sizeof(PBSysTextplanSelection)
- Returns: true if the
selectionchanged - Required rights:
PBSysRight_READ
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.
- Parameters:
textPlan: the text plan objectmode: a bitwise OR of PBSysTextplanSelectionAdjustment_* flagsx: pointxin px relative to the text plan originy: pointyin px relative to the text plan originselection: in-outselectionstate containing anchor, caret, and lastDownselectionSize: size of *selection, usually sizeof(PBSysTextplanSelection)
- Returns: true if the
selectionchanged - Required rights:
PBSysRight_READ
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.
- Parameters:
textPlan: the text plan objectpreferredX: x in px relative to the text plan origin used to preserve column intentupwards: true to move up one visual line, false to move downextend: true toextendthe currentselectioninstead of collapsing to the moved caretselection: in-outselectionstate containing anchor, caret, and lastDownselectionSize: size of *selection, usually sizeof(PBSysTextplanSelection)
- Returns: true if the
selectionchanged - Required rights:
PBSysRight_READ
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).
- Parameters:
originXInPx: x offset within thetextureoriginYInPx: y offset within thetexturepixels: pointer to pixel datapixelCount: number of bytes atpixels(must be >=widthInPx*heightInPx* 4)widthInPx: width of the upload regionheightInPx: height of the upload region
- Required rights:
PBSysRight_WRITE
Thread
PBSysThreadEnterMain
void PBSysThreadEnterMain(u64 flags);
PBSysThreadEnterMain
- Parameters:
flags: are bits of PBSysThread_
- Required rights: none
PBSysThreadExit
PBSysErr PBSysThreadExit(PBSysHandle thread,
i32 status);
PBSysThreadExit stops a thread and sets its exit status.
- Required rights:
PBSysRight_MANAGE_THREAD
PBSysThreadExitProcess
PBSysErr PBSysThreadExitProcess(PBSysHandle thread,
i32 status);
PBSysThreadExitProcess terminated the process.
- Required rights:
PBSysRight_MANAGE_PROCESS
PBSysThreadExitStatus
i32 PBSysThreadExitStatus(PBSysHandle thread);
PBSysThreadExitStatus returns the exit status of thread.
- Returns:
PBSysErron error. - Required rights:
PBSysRight_MANAGE_THREAD
PBSysThreadHostControllerConnect
PBSysHandle PBSysThreadHostControllerConnect(PBSysHandle thread);
Note: Draft API; arguments will change
- Required rights: none
PBSysThreadLogWrite
PBSysErr PBSysThreadLogWrite(PBSysHandle thread,
const PBSysBuf* bufs,
u32 bufCount,
u32 flags);
PBSysThreadLogWrite writes to the runtime log sink for a thread.
- Required rights: none
PBSysThreadNetConnect
PBSysHandle PBSysThreadNetConnect(PBSysHandle thread,
u32 ipAddr,
u16 tcpPort);
Note: Draft API; arguments will change
- Required rights:
PBSysRight_NETWORK
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.
- Parameters:
data: is a buffer to place readdataintodataSizeInOut: in: capacity ofdata, out: bytes readhandles: to accept ownership of, transferred from sender threadhandlesCountInOut: in: capacity ofhandles, out:handlesreceivedflags: are currently unused; pass 0.
- Required rights: none
PBSysThreadStart
PBSysHandle PBSysThreadStart(PBSysHandle parentThread,
u64 flags,
const PBSysThreadConfig* config,
u64 configSize);
PBSysThreadStart starts a new thread.
- Required rights:
PBSysRight_MANAGE_THREAD
PBSysThreadWindowCreate
PBSysHandle PBSysThreadWindowCreate(PBSysHandle thread,
const PBSysWindowConfig* config,
usize configSize);
PBSysThreadWindowCreate creates a window associated with a thread.
- Required rights:
PBSysRight_WRITE
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.
- Parameters:
data: to be writtendataSize: is the number of bytes atdatahandles: to transfer ownership of to receiverthreadhandlesCount: is the number ofhandlesathandlesflags: are currently unused; pass 0.
- Required rights:
PBSysRight_WRITE
Window
PBSysWindowClipboardReadText
i64 PBSysWindowClipboardReadText(PBSysHandle window,
u8* buffer,
u64 bufferSize);
PBSysWindowClipboardWriteText reads the text from the clipboard.
- Required rights:
PBSysRight_READ
PBSysWindowClipboardWriteText
PBSysErr PBSysWindowClipboardWriteText(PBSysHandle window,
const u8* text,
u64 textSize);
PBSysWindowClipboardWriteText sets the text on the clipboard.
- Required rights:
PBSysRight_WRITE
PBSysWindowCopyTitle
i32 PBSysWindowCopyTitle(PBSysHandle window,
u8* buf,
u32 bufCap,
u64 flags);
PBSysWindowCopyTitle retrieves the title of a window.
- Parameters:
buf: Destination to write UTF-8 bytesbufCap: Capacity ofbuf, in bytes
- Required rights:
PBSysRight_READ
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.
- Parameters:
format: must bePBSysTextureFormat_RGBA8flags:PBSysWindowCreateTextureFlags(e.g. STREAMING for frequently updated textures)
- Required rights: none
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.
- Parameters:
data: pointer to encoded image bytes (e.g. a PNG file loaded into memory)dataSize: number of bytes atdataflags:PBSysWindowCreateTextureFlags
- Required rights: none
PBSysWindowFrameSyncEnable
PBSysErr PBSysWindowFrameSyncEnable(PBSysHandle window,
u64 flags);
PBSysWindowFrameSyncEnable controls the production of FRAME_SYNC pulses.
- Parameters:
flags: should be 0 (disable) or 1 (enable).
- Required rights: none
PBSysWindowInfoGet
PBSysErr PBSysWindowInfoGet(PBSysHandle window,
PBSysWindowInfo* info,
u64 infoSize);
PBSysWindowInfoGet retrieves latest window metrics and timing hints.
- Required rights:
PBSysRight_READ
PBSysWindowRendererPackageWrite
PBSysErr PBSysWindowRendererPackageWrite(PBSysHandle window,
const PBSysWindowRendererPackage* package,
usize packageSize);
PBSysWindowRendererPackageWrite submits renderer package data for a window.
- Required rights:
PBSysRight_WRITE
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.
- Parameters:
x: dpy: dpwidth: dpheight: dp
- Required rights:
PBSysRight_WRITE
PBSysWindowSetStyle
PBSysErr PBSysWindowSetStyle(PBSysHandle window,
PBSysWindowStyle style,
u64 flags);
PBSysWindowSetStyle sets the style of a window.
- Required rights:
PBSysRight_WRITE
PBSysWindowSetTitle
PBSysErr PBSysWindowSetTitle(PBSysHandle window,
const u8* text,
u64 textLen);
PBSysWindowSetTitle sets the title of a window.
- Parameters:
text: UTF-8 bytestextLen: Number of bytes attext
- Required rights:
PBSysRight_WRITE
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.
- Required rights:
PBSysRight_WRITE
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.
- Required rights: none
Playbit API reference
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
PBArrayprovides dynamically-growable arrays (aka buffers)PBHashTableprovides building blocks for dictionaries and setsPBPoolandPBSlotTablemaps data to dense indices
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:
PBI8Arraywith element typei8PBI16Arraywith element typei16PBI32Arraywith element typei32PBI64Arraywith element typei64PBU8Arraywith element typeu8PBU16Arraywith element typeu16PBU32Arraywith element typeu32PBU64Arraywith element typeu64PBF32Arraywith element typef32PBF64Arraywith element typef64PBPtrArraywith element typevoid*
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
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.
- Returns: NULL if capacity growth fails or if
len==0.
PBAnyArrayAllocAt
void* PBAnyArrayAllocAt(PBAnyArray* arg,
usize elemSize,
PBMem arg,
usize i,
usize len);
PBAnyArrayAllocAt inserts len uninitialized elements at index i.
- Returns: NULL if capacity growth fails.
PBAnyArrayReserve
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.
elemSize: size of one element. Must be>0.ma: memory allocator to use in case array needs to grow. Must be same allocator used for all memory operations on this array.i: Index at which to insert elements.i=0means "insert at beginning",i=lenmeans insert at end. Value must be<=len.src: Pointer to elements to copy into the arraylen: Number of element atsrc. Must be>0.- Returns: true on success, false on allocation failure.
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)
- Returns: an instance of
ArrayTypepre-populated withlenitems pointed to bysrc.
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)
- Returns: a copy of the item stored in
arrayatindexat.
PBArrayRefAt
macro T* PBArrayRefAt(ArrayType* array, usize at)
- Returns: a pointer to the item stored in
arrayatindexat.
PBArrayPush
macro bool PBArrayPush(ArrayType* array, PBMem ma, T item)
Pushes item onto the end of the array pointed to by array.
- Returns:
falseif capacity growth fails.
PBArrayPop
macro T PBArrayPop(ArrayType* array)
Removes the last item in the array.
- Returns: 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.
- Returns: NULL if capacity growth fails, otherwise a pointer to first new item.
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.
- Returns: NULL if capacity growth fails, otherwise a pointer to first new item.
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.
- Returns:
falseif capacity growth fails.
PBArrayReserve
macro bool PBArrayReserve(ArrayType* array, PBMem ma, usize nItems)
Ensures at least nItems spare capacity beyond current length.
- Returns:
falseif capacity growth fails.
PBArrayReserveExact
macro bool PBArrayReserveExact(ArrayType* array, PBMem ma, usize nItems)
Grows capacity to satisfy nItems spare slots without geometric extra growth.
- Returns:
falseif capacity growth fails.
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.
- Returns:
falseon failure.
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.
- Returns:
falseon failure.
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.
- Returns:
falseon failure.
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)
- Returns: true if
ptrLenequalsarray's length and all the bytes in the array equal those pointed to byptr.
PBArrayCmp
macro int PBArrayCmp(ArrayType* array, T* ptr, usize ptrLen)
- Returns: <0 if the contents of
arrayis bytewise less than the contents ofptr, >1 ifptr<array, 0 ifarray==ptr.
PBArrayFromSlice
macro ArrayType PBArrayFromSlice(ArrayType, PBMem ma, SliceType slice)
- Returns: a new array of type
ArrayTypewith a copy of the items inslice.
PBArraySlice
macro SliceType PBArraySlice(SliceType, ArrayType* array, usize start, usize rangeLen)
- Returns: a new slice of type
SliceTypereferencing the items inarraystarting at indexstartand withrangeLenlength.
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.
- Returns: a pointer to
buf->v, or NULL if memory could not be allocated.
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.
- Returns: true on success, false if memory could not be allocated
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
PBBufEq is implemented as a generic macro, with the following effective signature:
bool PBBufEq<A is convertible to PBStrSlice, B is convertible to PBStrSlice>(A a, B b)
- Returns: true if a is equal to b.
PBBuf_INIT_WITH_STORAGE
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);
}
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.
- Returns: NULL on allocation failure.
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.
- Returns: Number of bytes consumed.
#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.
- Returns: false on allocation failure.
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.
- Returns: false if not found.
PBHashTableIter
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.
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.
- Returns: false if memory could not be allocated.
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.
- Returns: NULL if memory allocation failed.
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.
- Returns: NULL if the pool is full (does not grow pool memory like
PBPoolEntryAlloc.)
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.
- Returns: false for
idx==0oridxbeyond current capacity.
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.
- Returns: pointer to entry
idx. The returned pointer (address) is valid until the next modification of the pool.
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.
- Returns: 0 when no matching entry exists.
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
PBSlotTableCreate creates a new table with initial capacity for cap entries of elemSize size.
Note that the table is implemented as a list of blocks of entries, each holding cap entries. This means that cap should be a reasonably large number. cap will be rounded up to the nearest multiple of 64.
PBSlotTable* nullable PBSlotTableCreate(type T, PBMem ma, u32 cap)
- Returns: NULL if memory could not be allocated.
PBSlotTableFree
void PBSlotTableFree(PBSlotTable* table,
PBMem ma);
PBSlotTableFree frees table back to memory allocator ma
PBSlotTableAdd
PBSlotTableAdd allocates an entry with the lowest index in the table.
On success, the returned memory region is zeroed and guaranteed to remain valid until either the entry is freed by a call to PBSlotTableDel, the table is cleared with PBSlotTableClear or the table is freed. I.e. even when the table grows, to accommodate more entires, the address of existing entries remain valid. This is a really useful invariant when you want to hold on to pointers.
T PBSlotTableAdd(type T, PBSlotTable* table, PBMem ma, u32* idxOut)
- Returns: NULL if memory allocation failed.
PBSlotTableDel
void PBSlotTableDel(PBSlotTable* table,
u32 idx);
PBSlotTableDel frees the entry at idx.
PBSlotTableGet
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.
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.
- Returns: NULL if queue is full.
PBQueueAnyPush
void* PBQueueAnyPush(PBQueueAny* q,
u32 entrySize,
PBMem ma);
PBQueueAnyPush reserves one entry slot at tail, growing q when necessary.
- Returns: NULL on allocation failure.
PBQueueAnyPop
void* PBQueueAnyPop(PBQueueAny* q,
u32 entrySize);
PBQueueAnyPop removes one entry from head and returns pointer to its storage.
- Returns: NULL if queue is empty.
PBQueueAnyPopMany
u32 PBQueueAnyPopMany(PBQueueAny* q,
u32 entrySize,
void* dst,
u32 dstCap);
PBQueueAnyPopMany pops up to dstCap entries from head into dst.
- Returns: Number of entries copied and removed.
PBQueueAnyRemove
u32 PBQueueAnyRemove(PBQueueAny* q,
u32 limit);
PBQueueAnyRemove removes up to limit newest entries from tail.
- Returns: Number of entries removed.
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);
Multi-dimensional vector types with SIMD acceleration.
These types are special N dimensional vector types which directly maps to target-CPU-agnostic SIMD types. They enables efficient SIMD operations and is usable in general-purpose code.
Vector types may not be available for all compilation targets: PB_HAS_VECTOR_TYPES is set to 1 if vector types are supported, 0 if not.
These types allow element access via:
- the array subscript operator
[index] sNwhereNis a hexadecimal valuex,y,z,wfor graphics-style indexing
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:
PB_API_BEGINsetsextern "C"if needed and configures nullability diagnosticsPB_API_ENDrestores state altered byPB_API_BEGINPB_ATTR_ALIGNED(N)is__attribute__((__aligned__(N)))when supportedPB_ENUM_TYPE(T)is:Twhen supported
PB_SHORT_NAMES
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
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
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
PB_NORETURN is an attribute that tells the compiler that a function never returns.
- The compiler is free to perform optimizations which would cause UB if the function would actually return
- Affects static analysis
Note: _Noreturn is deprecated in C23, replaced by [[noreturn]]
PB_UNUSED
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
PB_CPU_CACHE_LINE_SIZE defines the CPU L1 cache line size
PB_LIBC
PB_LIBC is 1 if compiling with libc, 0 if not
PB_SMT
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
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
PB_VARG_DISPATCH allows writing functions with compile-time variable-count arguments
PB_VARG_COUNT
PB_VARG_COUNT counts macro variable arguments
PB_CONCAT
PB_CONCAT concatenates preprocessor values
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
PB_GUEST is 1 if playbit-c is full-featured, or 0 for "core" version
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
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.
x: evaluated multiple times
PBPow2Ceil
macro ANYINT PBPow2Ceil(ANYINT x)
rounds up x to nearest power of two.
- Returns: 1 when
xis 0. 0 whenxis larger than the max pow2 forx's type (e.g. >0x80000000 for u32)
PB_POW2_CEIL
macro ANYINT PB_POW2_CEIL(ANYINT x)
Constant-expression implementation of PBPow2Ceil.
x: evaluated multiple times
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.
divisor: evaluated multiple times
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
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.
- Returns: the number of bytes that would be written to
buf, excluding NUL terminator, as ifbufCapwas inifinite.
PBSysRightsStr
u32 PBSysRightsStr(PBSysRights rights,
char* buf,
u32 bufCap);
PBSysRightsStr writes a short string representation of all bits in rights to buf.
- Returns: the number of bytes that would be written to
buf, excluding NUL terminator, as ifbufCapwas inifinite.
PBSysErrOfErrno
PBSysErr PBSysErrOfErrno(int errno_val);
PBSysErrOfErrno returns a PBSysErr value for a libc errno value.
- Returns:
PBSysErr_UNKNOWNif using playbit-c library without libc support (PB_LIBC=0)
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
void PBExpectNoOverflow…(T a, T b, T* dst)
TODO: consider using __builtin_add_overflow_p et al. instead
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)
- Returns: Number of
byteswritten orPBSysErras negative value
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
PBHandleList
i32 PBHandleList(PBSysHandleInfo* handles,
u32 handlesCap);
PBHandleList returns information about handles held by the calling thread. Writes up to handlesCap entries to handles.
- Returns: the total number of
handles, which might be more thanhandlesCap.
PBHandleFindByName
i32 PBHandleFindByName(PBSysHandleInfo* handles,
u32 handlesCap,
PBSysHandleName name);
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
handleis invalid, orhandledoes not havePBSysRight_SIGNALrights, or- any signal mask contains non-user signals (
PBSysSignal_SYSTEM_ALL)
PBSnprintf
u32 PBSnprintf(char* buf,
u32 bufCap,
const char* fmt,
...);
PBSnprintf formats strings using printf-style formatting.
- Returns: the number of bytes that would be written to
buf, excluding NUL terminator, as ifbufCapwas inifinite.
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.
PBRand
u64 PBRand();
PBRand returns the next pseudo-random number
PBRandSeed
void PBRandSeed(u64 seed);
PBRandSeed sets the deterministic seed used by PBRand.
Streams are byte-oriented duplex or simplex pipes. Reads and writes may be partial.
Streams activate the following singals:
PBSysStreamSignal_READABLEwhen there's at least one byte available to readPBSysStreamSignal_WRITABLEwhen there's room to write at least one bytePBSysStreamSignal_PEER_CLOSEDwhen the other end of the stream closed reading & writingPBSysStreamSignal_PEER_WRITE_DISABLEDwhen the other end of the stream closed writingPBSysStreamSignal_WRITE_DISABLEDwhen the local end of the stream closed writing
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.
pairOut: Receives the two created streams on success.bufferSize: Per-direction buffer capacity in bytes. 0 uses an implementation default.flags: Must be 0.- Returns: 0 on success or a
PBSysErron failure.
PBStreamRead
i64 PBStreamRead(PBStream stream,
void* dst,
usize nbyte);
PBStreamRead reads up to nbyte bytes into dst.
- Returns: Number of bytes read or negative
PBSysErr.
PBStreamReadv
i64 PBStreamReadv(PBStream stream,
const PBSysBuf* bufs,
u32 bufCount,
u32 flags);
PBStreamReadv performs vectored read into bufs.
- Returns: Number of bytes read or negative
PBSysErr.
PBStreamWrite
i64 PBStreamWrite(PBStream stream,
const void* src,
usize nbyte);
PBStreamWrite writes nbyte bytes from src.
- Returns: Number of bytes written or negative
PBSysErr.
PBStreamWritev
i64 PBStreamWritev(PBStream stream,
const PBSysBuf* bufs,
u32 bufCount,
u32 flags);
PBStreamWritev performs vectored write from bufs.
- Returns: Number of bytes written or negative
PBSysErr.
PBStreamClose
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.
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.
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:
PBI8Slicewith element typei8PBI16Slicewith element typei16PBI32Slicewith element typei32PBI64Slicewith element typei64PBU8Slicewith element typeu8PBU16Slicewith element typeu16PBU32Slicewith element typeu32PBU64Slicewith element typeu64PBF32Slicewith element typef32PBF64Slicewith element typef64PBPtrSlicewith element typevoid*
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)
- Returns: an instance of
SliceTypepointed tolenitems pointed to byvalues.
PBSliceSlice
macro SliceType PBSliceSlice(SliceType slice, usize start, usize len)
- Returns: a new
slicereferencing the items inslicestarting at indexstartand withlenlength.
PBSliceAt
macro T PBSliceAt(SliceType slice, usize index)
- Returns: a copy of the item pointed to by
sliceatindexindex.
PBSliceRefAt
macro T* nullable PBSliceRefAt(SliceType slice, usize index)
- Returns: a pointer to the item pointed to by
sliceatindexindex.
PBSliceEq
macro bool PBSliceEq(SliceType slice, SliceType otherSlice)
- Returns: true if both slices' lengths are equal and all the bytes pointed to by
sliceequal those pointed to byotherSlice.
PBSliceCmp
macro int PBSliceCmp(SliceType slice, SliceType otherSlice)
- Returns: <0 if the contents pointed to by
sliceis bytewise less than the contents pointed to byotherSlice, >1 ifotherSlice<slice, 0 ifslice==otherSlice.
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)
- Returns: .bytes=NULL if memory could not be allocated.
PBStrFromSlice
PBStr PBStrFromSlice(PBMem ma,
PBStrSlice value);
PBStrFrom makes a copy of bytes at value as a PBStr.
- Returns: .bytes=NULL if memory could not be allocated.
PBStrFmt
PBStr PBStrFmt(PBMem ma,
const char* format,
...);
PBStrFmt makes a string with printf-like formatting.
- Returns: .bytes=NULL if memory could not be allocated.
PBStrFmtv
PBStr PBStrFmtv(PBMem ma,
const char* format,
va_list va);
PBStrFmtv is the va_list variant of PBStrFmt.
- Returns: .bytes=NULL if memory could not be allocated.
PBStrJoin
PBStr PBStrJoin(PBMem ma,
PBStrSliceLike glue,
PBStrSliceLike value1,
...);
PBStrJoin concatenates byte arrays together with glue placed in between each value.
- Returns: .bytes=NULL if memory could not be allocated.
PBStrJoinSlice
PBStr PBStrJoinSlice(PBMem ma,
PBStrSliceLike glue,
const PBStrSlice* values,
usize n);
PBStrJoinSlice joins n values with glue between each value.
- Returns: .bytes=NULL if memory could not be allocated.
PBStrCat
PBStr PBStrCat(PBMem ma,
PBStrSliceLike value1,
...);
PBStrCat concatenates byte arrays together. Its equivalent to PBStrJoint with empty glue.'
- Returns: .bytes=NULL if memory could not be allocated.
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.
- Returns: true on success or false if memory allocation failed
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.
- Returns: true on success or false if memory allocation failed
PBStr_FMT
PBStr_FMT is used in printf format as the pattern for a PBStr-like value, like PBStrSlice
PBStr_FMT_ARG
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:
PBStrSlicePBU8SlicePBBufPBU8Array- const
PBStr - const char* (NUL-terminated "C string")
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
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.
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
}
}
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.
- Returns: NULL if enough memory could not be allocated
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
mem: start of memory where to initialize a hasher. It's only valid to provide NULL ifmemSizeis0.memSize: capacity of the memory region starting atmemimpl: hash implementation to use- Returns: number of bytes required for the requested hasher. If the returned value is larger than
memSize, the function failed.
PBHasherUpdate
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.
output: Where to write the hash. It's only valid to provide NULL ifoutputCapis0.outputCap: capacity ofoutputin bytes.- Returns: number of bytes that would have been written to
outputifoutputCapwas inifinitely large.
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.
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.
flags: Bits ofPBFileOpenFlags- Returns:
PBFile.handle<0 asPBSysErron failure.
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.
- Returns: number of bytes read into
buf, orPBSysErras a negative value
PBFileReadv
i64 PBFileReadv(PBFile file,
const PBSysBuf* bufs,
u32 bufCount);
PBFileReadv reads from file into bufs.
- Returns: number of bytes read into
bufs, orPBSysErras a negative value
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.
- Returns: number of bytes written from
buf, orPBSysErras a negative value
PBFileWritev
i64 PBFileWritev(PBFile file,
const PBSysBuf* bufs,
u32 bufCount);
PBFileWritev writes to file from bufs.
- Returns: number of bytes written from
bufs, orPBSysErras a negative value
#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);
- Returns: true if a name was appended to buf, false if there are no more entries or if a filesystem error occurred.
PBDirIteratorClose
void PBDirIteratorClose(PBDirIterator* dirIterator);
PBDirIteratorClose closes dirIterator->handle and sets it to PBSysHandle_INVALID
Playbit API reference
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
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
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.
kPBMemGPAis a general-purpose allocator; a universal "heap allocator" that strikes a balance between performance and memory use. UsekPBMemGPAif you don't know what you want.PBArenaimplements an arena allocator, useful for region-based memory management. It's a hybrid betwen a simple bump allocator and a chained-block allocator.PBMemBufAllocatorimplements a simple bump allocator on top of an externally managed buffer. Useful for testing or for very performance cricital code where control over memory locality is important. Generally not a very useful allocator.PBMemNullAllocatoralways fails to allocate memory, intended to be used for testing.PBMemZeroingAllocatorwraps another allocator and causes all allocations to be zero-initialized, useful for intercepting library code.
PBMem_ALIGNMENT
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.
- Returns: NULL on allocation failure.
PBMemAllocz
void* PBMemAllocz(PBMem ma,
usize nbyte);
PBMemAllocz allocates nbyte bytes through allocator ma and zero-initializes the returned memory.
- Returns: NULL on allocation failure.
PBMemRealloc
void* PBMemRealloc(PBMem ma,
void* ptr,
usize nbyte);
PBMemRealloc resizes an allocation owned by ma.
ptr: Pointer to existing allocation. Pass NULL to allocate likePBMemAlloc.nbyte: New size. Pass 0 to free likePBMemFree.- Returns: NULL on allocation failure when growing or creating.
PBMemReallocz
void* PBMemReallocz(PBMem ma,
void* ptr,
usize nbyte);
PBMemReallocz is like PBMemRealloc but requests zero-initialization of newly added bytes.
- Returns: NULL on allocation failure when growing or creating.
PBMemAllocx
void* PBMemAllocx(PBMem ma,
void* ptr,
usize* nbyte_inout,
u32 flags);
PBMemAllocx is the most flexible allocator interface. You can perform all actions provided by PBMemAlloc, PBMemAllocz, PBMemRealloc, PBMemReallocz and PBMemFree, plus get the actual allocated memory region's size back.
nbyte_inout: Points to the requested size and may be increased by the allocator.- Returns: NULL on allocation failure.
PBMemFree
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.
ptrInOut: holds the address of the current memory allocation, updated on successful return.capInOut: holds the current capacity (number of elements) of*ptrInOut, updated on successful return.newCap: The requested new capacity.maFlags: Flags passed toPBMemAllocx.- Returns: true on success, in which case the value of
*ptrInOutmay be a new address and*capInOutholds the new capacity. IfPBMem_ROUNDUPis set inmaFlags,*capInOuthas been rounded up to what's ideal for the memory allocatorma. false if resizing fails, in which case*ptrInOutand*capInOutremain unchanged and the current memory region remains valid.
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.
ptrInOut: holds the address of the current memory allocation, updated on successful return.capInOut: holds the current capacity (number of elements) of*ptrInOut, updated on successful return.addCap: The requested additional capacity.maFlags: Flags passed toPBMemAllocx.- Returns: true on success, in which case the value of
*ptrInOutmay be a new address and*capInOutholds the new 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
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
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.
m: Currently the only valid value iskPBMemGPA
#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
usize lastSize : 56; // size in bytes of most recent allocation
usize flags : 8;
usize lastSize;
u8 flags;
} 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.
bufCap: must be at least PBMem_ALIGNMENT.- Returns:
amemory allocator handle which can be used with functions that allocate memory.
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
scope: The value returned fromacorrespondingPBMemBufAllocatorScopeBegincall.
#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)
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
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.
- Returns: NULL on invalid parameters or allocation failure.
PBArenaAlloc
macro PBArena* nullable PBArenaAlloc(.field = value ...)
creates an arena from params, a convenience wrapper for PBArenaAllocP((PBArenaParams){ .field = value ... })
- Returns: NULL on invalid parameters or allocation failure
PBArenaFree
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.
- Returns: NULL if there is no room and
arenagrowth is not possible.
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.
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).
net: Networking capabilitynetSession: Session to initializesessionId: Session identifier, unique within app-id namespaceconfig: Optional configuration. Pass NULL for defaults.
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.
netChannelOut: Points to an open PBNetChannel on successnetSession: The network session to open a channel inchannelId: The identifier of the channel, unique within the sessionma: Memory allocator to use for PBNetChannel and its resources. Must remain valid untilPBNetChannelClosehas been called.
PBNetChannelOpenEx
PBSysErr PBNetChannelOpenEx(PBNetChannel* netChannelOut,
const PBNetSession* netSession,
PBStrSlice channelId,
PBMem ma,
PBNetChannelOpenFlags flags);
PBNetChannelOpen opens a stream to channel identified by channelId.
netChannelOut: Points to an open PBNetChannel on successnetSession: The network session to open a channel inchannelId: The identifier of the channel, unique within the sessionma: Memory allocator to use for PBNetChannel and its resources. Must remain valid untilPBNetChannelClosehas been called.flags: Customizes behavior. SeePBNetChannelOpenFlags
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.
- Returns:
PBSysErr_TOO_LARGEifbodyLenis too large, as limited byPBNetChannelSetSendLimit
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.
- Returns:
PBSysErr_TOO_LARGEifbodyLenis too large, as limited byPBNetChannelSetSendLimit
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.
bodyOut: On success,*bodyOutis set to a pointer into an internal buffer of at leastbodyLensize, with at least 16 byte address alignment. The pointer remains valid untilPBNetChannelPublishCommitis called.- Returns:
PBSysErr_TOO_LARGEifbodyLenis too large, as limited byPBNetChannelSetSendLimit
PBNetChannelPublishCommit
PBSysErr PBNetChannelPublishCommit(PBNetChannel* netChannel,
u8* body,
PBNetChannelPublishFlags flags);
PBNetChannelPublishCommit commits a draft PUBLISH frame previously started with PBNetChannelPublishBegin.
body: Must be the exact pointer returned from the begin call
PBNetChannelProcessIO
PBSysErr PBNetChannelProcessIO(PBNetChannel* netChannel,
PBSysSignals signals,
PBNetChannelFrame* frameOut);
PBNetChannelProcessIO processes stream IO for a channel.
signals: Current streamsignalsfrom aPBEventType_SIGNALevent, but 0 is also valid and still allows flushing of buffered outgoing data.- Returns: On success, *frameOut is set to NULL if no complete frame is ready yet, or to a frame pointer owned by
netChannelif one frame was decoded. The returned frame remains valid untilPBNetChannelReleaseFrameis called.
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.)
nbytes: Max number of bytes to allow receiving.- Returns: Previous limit
PBNetChannelSetSendLimit
u32 PBNetChannelSetSendLimit(PBNetChannel* netChannel,
u32 nbytes);
PBNetChannelSetSendLimit limits the size of published messages (body, not including protocol header.)
nbytes: Max number of bytes per published message
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:
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);
}
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
PBCallCtors invokes wasm constructor list for builds without libc startup.
PB_C_START_ATTR
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
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
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.)
sem: Semaphore to initializeinitCount: Initial permit count
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.
sem: Semaphore to wait on
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.
sem: Semaphore to signalcount: Number of permits to add; maximum number of waiting threads to unblock.
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.
sem: Semaphore to inspect- Returns: Observed permit count at the time of the atomic load.
Playbit API reference
PBDaterepresents a point in calendar time and time zone, for example 2026-03-12 16:37:07 PDT.PBDateNowreturns the current date-and-time andPBDateFmtcreates string representations.PBTimerepresents a point in system time; a high-resolution timestamp that is monotonically incrementing, used for timing (timers, duration calculations, etc.)PBTimeNowreturns the current system time.PBTimeDurationdescribes a duration of time, like 134ms.PBTimeDurationFormatcan be used to format a human-readable string like "1.2h".
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.
bufCap: is the capacity ofbuf- Returns: the number of bytes that would have been written to
buf, excluding a NUL terminator, as ifbufCapwas infinite.
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)
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.
- Returns: PBTimeZone_NONE if the
nameis invalid or unknown.
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
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.
- PBTimeBetween(1, 3) == -2
- PBTimeBetween(3, 1) == 2
PBTimeDurationFormat
const char* PBTimeDurationFormat(PBTimeDuration d,
char* buf);
PBTimeDurationFormat writes a human-readable string like "1.6s" to buf.
- Returns: a pointer to beginning of
buf.
PBTimeDurationHours
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
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.
- Returns: true if
timerwas stopped, or false iftimeris invalid or already stopped.
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.
- Returns: false if there are no expired timers.
Playbit API reference
Playbit's UI library is an immediate-mode styled API. The UI is composed of a tree of rectangles.
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
- The Basics
- Keys and Strings
- Box Styles
- Sizing and Layout
- Events
- Alignment & Spacing
- Builtin Elements
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.
index: Must be <PBAppResourceCount() or this function will panic.
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.
when: Absolute point in timewhenthe timer should ring.repeat: if >0,repeatat this interval after it has rung atwhen.leeway: precision request; how much this timer is willing to fluctuate.
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.)
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.
eventsSize: is the total number of bytes available atevents.maxCount: limits the number ofeventsreturned.- Returns: the number of
eventswritten toevents. 0 if the thread is exiting,eventsSize=0 ormaxCount=0.PBSysErr_NO_MEMifeventsSizeis not large enough for a single event. Note that the largest possible event's size is <= PBSysEventSize_MAX.
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.
- Returns: the number of bytes that would be written to
buf, excluding NUL terminator, as ifbufCapwas inifinite.
PBEventOfSysEvent
usize PBEventOfSysEvent(PBEvent* event,
usize eventSize,
const PBSysEvent* sysEvent);
PBEventOfSysEvent copies a PBSysEvent entry to a PBEvent.
eventSize: is the size of memory atevent, in bytes.- Returns: the number of bytes written to
event, which will be the size of the appropriatePBEventtype, e.g. sizeof(PBKeyboardEvent) whenevent->type==PBEventType_KEY_DOWN. 0 ifeventSizeis too small for theeventtype.
PBLogEvent
void PBLogEvent(const PBEvent* event);
PBLogEvent is a convenience function which calls PBLog with the result of passing event to PBEventStr
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);
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
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
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
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
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
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
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
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
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
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
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
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
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
a fraction of the current view height [0-1]
PBUI_size2
Shorthand constructors for two-component size and alignment types.
PBUI_v2
Shorthand vector constructors.
PBUI_rgb
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
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
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
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
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);
- Returns: the delta (in bytes) that
indexwould have tomoveto start at the next/previous word boundary Note:moveis number of words tomoveby (can be positive or negative)
PBStringCodepointScan
i64 PBStringCodepointScan(PBStrSlice str,
i64 index,
i64 move);
- Returns: the delta (in bytes) that
indexwould have tomovein thestrto start at the next/previous codepoint(s) Note:moveis number of codepoints tomoveby (can be positive or negative)
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);
- Returns: a PBString from a given
codepoint(up to 4 bytes long)
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();
- Returns: the zero key
PBUIKeyEquals
bool PBUIKeyEquals(PBUIKey a,
PBUIKey b);
- Returns: if two keys are equal
PBUIKeyIsZero
bool PBUIKeyIsZero(PBUIKey a);
- Returns: if the key is zero
PBUIKeyFromString
PBUIKey PBUIKeyFromString(PBUIKey seedKey,
PBStrSlice string);
- Returns: a key from a
stringand the seed key
PBUIKeyFromStringAndIndex
PBUIKey PBUIKeyFromStringAndIndex(PBUIKey seedKey,
PBStrSlice string,
u32 index);
- Returns: a key from a
string, the seed key, and anindex
PBUIBoxNil
PBUIBox* PBUIBoxNil();
- Returns: a sentinel/null box
PBUIBoxIsNil
bool PBUIBoxIsNil(PBUIBox* it);
- Returns: if a box is null or "nil"
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();
- Returns: the top parent in the stack
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
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);
- Returns: true if the
keywas pressed this frame (exactly once)
PBUIKeyReleased
bool PBUIKeyReleased(PBKeyboardKey key);
- Returns: true if the
keywas pressed this frame (exactly once)
PBUIKeyRepeat
bool PBUIKeyRepeat(PBKeyboardKey key);
- Returns: true if the
keywas repeated this frame (once perkeyrepeat, in the case where akeyis held down)
PBUIKeyPressedOrRepeat
bool PBUIKeyPressedOrRepeat(PBKeyboardKey key);
- Returns:
PBUIKeyPressed() ||PBUIKeyReleased()
PBUIKeyDown
bool PBUIKeyDown(PBKeyboardKey key);
- Returns: true if the
keyis currently being held down
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);
- Returns: true if the mouse
buttonwas pressed this frame
PBUIMouseReleased
bool PBUIMouseReleased(PBMouseButton button);
- Returns: true if the mouse
buttonwas released this frame
PBUIMouseDown
bool PBUIMouseDown(PBMouseButton button);
- Returns: true if the mouse
buttonis currently being held down
PBUIMousePosition
PBVector2 PBUIMousePosition();
- Returns: the current mouse position in UI space (dps)
PBUIDragStart
PBVector2 PBUIDragStart();
- Returns: the mouse position when the mouse was first held down
PBUIDragDelta
PBVector2 PBUIDragDelta();
- Returns: the drag delta between
PBUIDragStart() andPBUIMousePosition()
PBUIScrollAmount
PBVector2 PBUIScrollAmount();
- Returns: the current scroll amount from using a mouse wheel or trackpad
PBUIBoxIsHover
bool PBUIBoxIsHover(PBUIBox* box);
- Returns: true if the
boxis currently being hovered by a mouse/pointer
PBUIBoxIsActive
bool PBUIBoxIsActive(PBUIBox* box);
- Returns: true if the
boxis currently active (mouse/pointer pressed but not yet released)
PBUIBoxIsDown
bool PBUIBoxIsDown(PBUIBox* box);
- Returns: true if the
boxis currently down
PBUIBoxOnPressed
bool PBUIBoxOnPressed(PBUIBox* box);
- Returns: true if the
boxis has just been pressed
PBUIBoxOnReleased
bool PBUIBoxOnReleased(PBUIBox* box);
- Returns: true if the
boxis has just been released
PBUIBoxIsFocused
bool PBUIBoxIsFocused(PBUIBox* box);
- Returns: true if the
boxis focused
PBUIBoxOnClick
bool PBUIBoxOnClick(PBUIBox* box);
- Returns: true if the
boxis clicked
PBUIBoxIsDrag
bool PBUIBoxIsDrag(PBUIBox* box);
- Returns: true if the current
boxis being dragged (similar/same to active)
PBUIBoxOnDrop
bool PBUIBoxOnDrop(PBUIBox* box);
- Returns: true if the
boxhas just been dropped
PBUIBoxIsDropTarget
bool PBUIBoxIsDropTarget(PBUIBox* box);
- Returns: true if the
boxis currently being targeted for a drop
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);
- Returns: true if the
boxwas created this frame
PBUIBoxPointToLocal
PBVector2 PBUIBoxPointToLocal(PBUIBox* box,
PBVector2 point);
Converts a point in UI-space to local box-space
PBUIBoxGetScroll
PBVector2 PBUIBoxGetScroll(PBUIBox* box);
- Returns: the amount that the mouse/touchpad has scrolled on a given
box
PBUIGetActiveBox
PBUIBox* PBUIGetActiveBox();
- Returns: the currently active box
PBUIGetHoverBox
PBUIBox* PBUIGetHoverBox();
- Returns: the currently hovered box
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.