playbit / docs

Foundation

Foundational types and functions.

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

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

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

playbit/base.h includes playbit/sys/compiler.h from the runtime API, which provides the following:


#include <playbit/base.h>

PB_SHORT_NAMES

#define PB_SHORT_NAMES 1|0

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

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

PB_HAS_VECTOR_TYPES

#define PB_HAS_VECTOR_TYPES 1|0

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

PB_UNREACHABLE

macro PB_UNREACHABLE()

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

PB_MUSTTAIL

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

PB_NORETURN

#define PB_NORETURN

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

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

PB_UNUSED

#define PB_UNUSED attribute

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

PB_LIKELY

macro PB_LIKELY(integralexpr)->bool

PB_UNLIKELY

macro PB_UNLIKELY(integralexpr)->bool

PB_CPU_CACHE_LINE_SIZE

#define PB_CPU_CACHE_LINE_SIZE u32

PB_CPU_CACHE_LINE_SIZE defines the CPU L1 cache line size

PB_LIBC

#define PB_LIBC

PB_LIBC is 1 if compiling with libc, 0 if not

PB_SMT

#define PB_SMT 1|0

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

PB_FMT_ATTR

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

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

PB_PLUS_ONE

#define PB_PLUS_ONE(...)

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

PB_VARG_DISPATCH

#define PB_VARG_DISPATCH(a, ...)

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

PB_VARG_COUNT

#define PB_VARG_COUNT(...)

PB_VARG_COUNT counts macro variable arguments

PB_CONCAT

#define PB_CONCAT(a, b)

PB_CONCAT concatenates preprocessor values

PB_LOCAL_UNIQUE_ID

#define PB_LOCAL_UNIQUE_ID

PB_LOCAL_UNIQUE_ID is a portable version of __COUNTER__

PB_UNIQUE_NAME

macro NAME PB_UNIQUE_NAME(NAME)

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

PB_TMPID

macro NAME PB_TMPID(NAME)

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

PB_DEPRECATED

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

marks a symbol as deprecated

PB_DEPRECATED_REPLACED_BY

macro void PB_DEPRECATED_REPLACED_BY(ID newName)

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

PB_UNAVAILABLE

macro void PB_UNAVAILABLE(const char* message)

marks a symbol as unavailable under the current build configuration

PB_GUEST

#define PB_GUEST 1|0

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

PB_GUEST_ONLY

#define PB_GUEST_ONLY

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

PB_GUESTFN

#define PB_GUESTFN

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

PBMustCheck_UNLIKELY

bool PBMustCheck_UNLIKELY(bool unlikely);

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

PBBitsCountLeadingZeroes

macro int PBBitsCountLeadingZeroes(ANYINT x)

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

PBBitsFindFirstSet

macro int PBBitsFindFirstSet(ANYINT x)

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

PBBitsFindLastSet

macro u32 PBBitsFindLastSet(ANYINT n)

finds the last set bit. e.g.

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

PBBitWidth

macro u32 PBBitWidth(ANYINT x)

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

PBILog2

macro int PBILog2(ANYINT x)

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

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

Result is undefined if x is 0.

PBIsPow2

macro bool PBIsPow2(T x)

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

PBAlign2

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

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

PB_ALIGN2

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

Constant-expression version of PBAlign2

PBIsAlign2

macro bool PBIsAlign2(T x, anyuint a)

returns true if x is aligned to a

PBPow2Floor

macro ANYINT PBPow2Floor(ANYINT x)

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

PB_POW2_FLOOR

macro ANYINT PB_POW2_FLOOR(ANYINT x)

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

PBPow2Ceil

macro ANYINT PBPow2Ceil(ANYINT x)

rounds up x to nearest power of two.

PB_POW2_CEIL

macro ANYINT PB_POW2_CEIL(ANYINT x)

Constant-expression implementation of PBPow2Ceil.

PBIDivCeil

macro T PBIDivCeil(T x, ANYINT divisor)

divides x by divisor, rounding up. If x is zero, returns max value of x (wraps.)

PB_IDIV_CEIL

macro T PB_IDIV_CEIL(T x, ANYINT divisor)

Constant-expression implementation of PBIDivCeil.

PBRangesOverlap

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

PBRangesOverlap returns true if two ranges overlap

PBPanic

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

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

PBPanicOnErr

macro T PBPanicOnErr(T exprWithSysErrResult)

PB_DEBUG

#define PB_DEBUG 1|0

PB_DEBUG is 1 in debug builds, else 0

PBIsType

macro bool PBIsType(ANY value, TYPE type)

Returns true at compile time if the type of value is assignable to a local of type

PBIsSameType

macro bool PBIsSameType(TYPE a, TYPE b)

Returns true at compile time if a value of type a is assignable to a local of type b

PBTypeIsConst

macro bool PBTypeIsConst(TYPE type)

Returns true at compile time if type has a const qualifier

PBExpect

macro void PBExpect(ANY truthyValue)

Calls PBPanic if truthyValue is false

PBExpectf

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

Calls PBPanic if truthyValue is false alond with a custom message

PBExpectNull

macro void PBExpectNull(ANY e)

Calls PBPanic if e != NULL

PBExpectNotNull

macro T PBExpectNotNull<T>(T e)

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

PBExpectInMemRegion

macro void PBExpectInMemRegion(const void* validRegion, usize validRegionSize, const void* subject, usize subjectSize)

asserts that the memory region [subject, subject+subjectSize) is fully contained in [validRegion, validRegion+validRegionSize). Calls PBPanic if not.

PBExpectInBounds

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

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

PBStaticExpectIsType

macro void PBStaticExpectIsType(EXPR value, TYPE type)

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

PBExpectationFailure

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

Calls PBPanic with "Expect assertion failed: " plus message

PBOpt

macro type PBOpt(T)

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

PBOptOk

macro T PBOptOk(PBOpt(T) opt)

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

PBSysCallOpStr

const char* PBSysCallOpStr(PBSysCallOp arg);

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

PBSysErrStr

const char* PBSysErrStr(PBSysErr arg);

PBSysErrStr returns a symbolic string

PBSysEventLegacyTypeStr

const char* PBSysEventLegacyTypeStr(PBSysEventLegacyType arg);

PBSysEventLegacyTypeStr returns a symbolic string

PBSysObjectTypeStr

const char* PBSysObjectTypeStr(PBSysObjectType arg);

PBSysObjectTypeStr returns a symbolic string

PBSysEventTypeStr

const char* PBSysEventTypeStr(PBSysEventType arg);

PBSysEventTypeStr returns a symbolic string

PBSysFileListEntryTypeStr

const char* PBSysFileListEntryTypeStr(PBSysFileListEntryType arg);

PBSysFileListEntryTypeStr returns a symbolic string

PBSysEventStr

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

PBSysEventStr writes a string representation of a PBSysEvent to buf.

PBSysRightsStr

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

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

PBSysErrOfErrno

PBSysErr PBSysErrOfErrno(int errno_val);

PBSysErrOfErrno returns a PBSysErr value for a libc errno value.

PBStr

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

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

PBStrSlice

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

PBStrSlice is a view into an array of bytes interpreted as UTF-8 text

PBU8Slice

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

PBU8Slice is a view into an array of bytes

PBPoint

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

PBPoint defines a two-dimensional location

PBSize

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

PBSize defines a two-dimensional size

PBRect

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

PBRect defines a two-dimensional rectangle

PBPointOf

macro PBPoint PBPointOf(f32 x, f32 y)

Constructs a PBPoint

PBSizeOf

macro PBSize PBSizeOf(f32 width, f32 height)

Constructs a PBSize

PBRectOf

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

Constructs a PBRect

PBMinF32

f32 PBMinF32(f32 a,
             f32 b);

PBMinF32 returns the smaller of a and b as f32. On targets with wasm min/max builtins they preserve IEEE min/max semantics for NaN handling.

PBMaxF32

f32 PBMaxF32(f32 a,
             f32 b);

PBMaxF32 returns the larger of a and b as f32. On targets with wasm min/max builtins they preserve IEEE min/max semantics for NaN handling.

PBMinF64

f64 PBMinF64(f64 a,
             f64 b);

PBMinF64 returns the smaller of a and b as f64. On targets with wasm min/max builtins they preserve IEEE min/max semantics for NaN handling.

PBMaxF64

f64 PBMaxF64(f64 a,
             f64 b);

PBMaxF64 returns the larger of a and b as f64. On targets with wasm min/max builtins they preserve IEEE min/max semantics for NaN handling.

PBMin

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

PBMax

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

PBCheckOverflowAdd

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

PBExpectNoOverflowAdd

#define PBExpectNoOverflowAdd(a, b, dst)

void PBExpectNoOverflow…(T a, T b, T* dst) TODO: consider using __builtin_add_overflow_p et al. instead


#include <playbit/console.h>

PBConsole

PBStream PBConsole();

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

PBConsoleWrite

i64 PBConsoleWrite(const u8* bytes,
                   usize     bytesLen);

PBConsoleWrite writes bytes verbatim to the console. The write is blocking and is implemented as PBStreamWritev(PBConsole(), bytes, PBSysStreamWrite_SYNC)


#include <playbit/log.h>

PBLog

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

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

PBLogv

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

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

PBLogWrite

PBSysErr PBLogWrite(PBSysBuf* bufv,
                    u32       bufc);

PBLogWrite writes a string to the console


#include <playbit/handle.h>

PBHandleList

i32 PBHandleList(PBSysHandleInfo* handles,
                 u32              handlesCap);

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

PBHandleFindByName

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

#include <playbit/signal.h>

PBObserve

void PBObserve(PBSysHandle  handle,
               PBSysSignals signals);

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

PBObserveOnce

void PBObserveOnce(PBSysHandle  handle,
                   PBSysSignals signals);

PBObserveOnce sets what signals are to be observed for the object referred to by handle, configured to produce a SIGNAL even just once (edge triggered.)

PBSignal

void PBSignal(PBSysHandle  handle,
              PBSysSignals disableUserSignals,
              PBSysSignals enableUserSignals,
              PBSysSignals pulseUserSignals);

PBSignal manages user signals for the object referred to by handle. Signal masks must only contain user bits (PBSysSignal_USER_*). This function panics if


#include <playbit/printf.h>

PBSnprintf

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

PBSnprintf formats strings using printf-style formatting.

PBVsnprintf

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

PBVsnprintf works like PBSnprintf but takes a va_list as input.

PBFprintf

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

PBFprintf and PBVfprintf writes a formatted string to a stream

PBVfprintf

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

PBVfprintf writes formatted output to a stream using va_list args.

PBPrintf

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

PBPrintf writes formatted output to PBConsole.

PBVprintf

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

PBVprintf writes formatted output to PBConsole using va_list.

PBPrint

void PBPrint(const char* cstr);

PBPrint writes a null-terminated string to PBConsole

PBPrintfln

macro void PBPrintfln(const char* fmt, ...)

writes formatted output to PBConsole() with a trailing linebreak. Prefer to use the short name alias print.


#include <playbit/random.h>

PBRand

u64 PBRand();

PBRand returns the next pseudo-random number

PBRandSeed

void PBRandSeed(u64 seed);

PBRandSeed sets the deterministic seed used by PBRand.


#include <playbit/stream.h>

Streams are byte-oriented duplex or simplex pipes. Reads and writes may be partial.

Streams activate the following singals:

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

PBStream

typedef struct {
    PBSysHandle handle;
} PBStream;

PBStreamOpenPipePair

PBSysErr PBStreamOpenPipePair(PBStream* pairOut,
                              u32       bufferSize,
                              u64       flags);

PBStreamOpenPipePair creates two connected duplex streams.

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

PBStreamRead

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

PBStreamRead reads up to nbyte bytes into dst.

PBStreamReadv

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

PBStreamReadv performs vectored read into bufs.

PBStreamWrite

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

PBStreamWrite writes nbyte bytes from src.

PBStreamWritev

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

PBStreamWritev performs vectored write from bufs.

PBStreamClose

PBSysErr PBStreamClose(PBStream stream);

PBStreamClose closes stream handle.


#include <playbit/binsearch.h>

PBBinSearchLessFn

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

PBBinSearchLowerBound

usize PBBinSearchLowerBound(const void*       element,
                            const void*       array,
                            usize             stride,
                            usize             begin,
                            usize             end,
                            PBBinSearchLessFn lessFn);

PBBinSearchLowerBound finds the lower bound of some element in a sorted array.

I.e. the leftmost position we could insert element into the array while keeping it sorted. Alternatively phrased: this is the number of elements strictly less than element in the array. Note: inline so that generated code can avoid indirect calls to lessFn, inlining it.


#include <playbit/math.h>

PBAbs

macro T PBAbs(T x)

Returns sign-normalized (positive) value of x

PBRound

macro T PBRound(T x)

Round x to nearest whole number

PBSin

macro T PBSin(T x)

PBCos

macro T PBCos(T x)

PBSqrt

macro T PBSqrt(T x)

Square root of x

PBAbsF32

f32 PBAbsF32(f32 x);

PBAbsF32 returns the absolute value of x

PBFloorF32

f32 PBFloorF32(f32 x);

PBFloorF32 rounds x toward negative infinity.

PBClampF32

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

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

PBRoundF32

f32 PBRoundF32(f32 x);

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

PBSignF32

f32 PBSignF32(f32 x);

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

PBModF32

f32 PBModF32(f32 x,
             f32 y);

PBModF32 returns floating-point remainder of x / y.

PBLerpF32

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

PBLerpF32 linearly interpolates from a to b by parameter t.

PBUnlerpF32

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

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

PBRemapF32

f32 PBRemapF32(f32 inMin,
               f32 inMax,
               f32 outMin,
               f32 outMax,
               f32 v);

PBRemapF32 maps v from input range [inMin,inMax] to output range [outMin,outMax].

PBSinF32

f32 PBSinF32(f32 x);

PBSinF32 computes sine approximation for x (radians).

PBCosF32

f32 PBCosF32(f32 x);

PBCosF32 computes cosine approximation for x (radians).

PBF32IsZero

bool PBF32IsZero(f32 x);

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

PBColorSpace

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

PBColor

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

PBVector2

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

PBVector4

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

PBRectangle

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

PBColorMake

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

PBColorMake constructs a clamped RGBA color.

PBColorFromRGBA

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

PBColorFromRGBA constructs an sRGB color with clamped channels.

PBColorFromRGBHex

PBColor PBColorFromRGBHex(u32 hex);

PBColorFromRGBHex converts 0xRRGGBB to an opaque sRGB color.

PBColorFromRGBAHex

PBColor PBColorFromRGBAHex(u32 hex);

PBColorFromRGBAHex converts packed RGBA hex value to an sRGB color.

PBColorIsZero

bool PBColorIsZero(PBColor c);

PBColorIsZero reports whether all channels are exactly zero.

PBColorEquals

bool PBColorEquals(PBColor c0,
                   PBColor c1);

PBColorEquals compares channel values exactly.

PBColorToU64

u64 PBColorToU64(PBColor x);

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

PBColorToU32

u32 PBColorToU32(PBColor x);

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

PBColorToRGBA8

u32 PBColorToRGBA8(PBColor x);

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

PBColorFromRGBA8

PBColor PBColorFromRGBA8(u32 x);

PBColorFromRGBA8 unpacks a previously packed color with PBColorToRGBA8.

PBColorToPackedRGBA

u32 PBColorToPackedRGBA(PBColor x);

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

PBColorHSVFromRGB

PBColor PBColorHSVFromRGB(PBColor rgb);

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

PBColorRGBFromHSV

PBColor PBColorRGBFromHSV(PBColor hsv);

PBColorRGBFromHSV converts HSV representation back to RGB.

PBVector2Make

PBVector2 PBVector2Make(f32 x,
                        f32 y);

PBVector2Make constructs a 2D vector.

PBVector2IsZero

bool PBVector2IsZero(PBVector2 v);

PBVector2IsZero reports whether both vector components are near-zero.

PBVector2Add

PBVector2 PBVector2Add(PBVector2 a,
                       PBVector2 b);

PBVector2Add adds two PBVector2s.

PBVector2Sub

PBVector2 PBVector2Sub(PBVector2 a,
                       PBVector2 b);

PBVector2Sub subtracts two PBVector2 types (a - b).

PBVector2Mul

PBVector2 PBVector2Mul(PBVector2 a,
                       PBVector2 b);

PBVector2Mul multiplies two PBVector2 types (a * b).

PBVector2Div

PBVector2 PBVector2Div(PBVector2 a,
                       PBVector2 b);

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

PBVector2AddF

PBVector2 PBVector2AddF(PBVector2 a,
                        f32       b);

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

PBVector2SubF

PBVector2 PBVector2SubF(PBVector2 a,
                        f32       b);

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

PBVector2MulF

PBVector2 PBVector2MulF(PBVector2 a,
                        f32       b);

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

PBVector2DivF

PBVector2 PBVector2DivF(PBVector2 a,
                        f32       b);

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

PBVector4Make

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

PBVector4Make constructs a 4D vector.

PBVector4IsZero

bool PBVector4IsZero(PBVector4 v);

PBVector4IsZero reports whether all vector components are near-zero.

PBVector4MulF

PBVector4 PBVector4MulF(PBVector4 v,
                        f32       f);

PBVector4MulF multiplies all components of v by scalar f.

PBRectangleMake

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

PBRectangleMake constructs rectangle from two corners.

PBRectangleFromV2

PBRectangle PBRectangleFromV2(PBVector2 p0,
                              PBVector2 p1);

PBRectangleMake constructs rectangle from two corner points.

PBRectangleOfRect

PBRectangle PBRectangleOfRect(PBRect rect);

PBRectangleOfRect converts a PBRect to a PBRectangle

PBRectangleOfSize

PBRectangle PBRectangleOfSize(PBSize size);

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

PBRectangleEquals

bool PBRectangleEquals(PBRectangle a,
                       PBRectangle b);

PBRectangleEquals returns true if two rectangles are equal.

PBRectangleIsZero

bool PBRectangleIsZero(PBRectangle a);

PBRectangleIsZero returns true if the rectangle is nearly zero.

PBRectangleSize

PBVector2 PBRectangleSize(PBRectangle r);

PBRectangleSize returns width/height vector of rectangle r.

PBRectangleWidth

f32 PBRectangleWidth(PBRectangle r);

PBRectangleWidth returns horizontal extent of r.

PBRectangleHeight

f32 PBRectangleHeight(PBRectangle r);

PBRectangleHeight returns vertical extent of r.

PBRectangleScale

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

PBRectangleScale scales rectangle coordinates by (sx,sy).

PBRectangleCutRight

PBRectangle PBRectangleCutRight(PBRectangle r,
                                f32         right);

PBRectangleCutRight trims right side by right units.

PBRectangleHitTest

bool PBRectangleHitTest(PBRectangle r,
                        PBVector2   pos);

PBRectangleHitTest reports whether pos lies inside r.

PBRectangleClip

PBRectangle PBRectangleClip(PBRectangle a,
                            PBRectangle b);

PBRectangleClip returns intersection of rectangles a and b.

PBRectangleIntersects

bool PBRectangleIntersects(PBRectangle r0,
                           PBRectangle r1);

PBRectangleIntersects returns true when r0 and r1 overlap.


#include <playbit/slice.h>

Define a slice type with PBSliceType(ElementType) and operate on it via "method" macros.

Example use:

typedef struct {
    int a, b;
} Foo;
typedef PBSliceType(Foo) FooSlice;

Type generated by PBSliceType(T):

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

Predefined slice types:

PBI8Slice

typedef PBSliceType(i8) PBI8Slice;

PBI16Slice

typedef PBSliceType(i16) PBI16Slice;

PBI32Slice

typedef PBSliceType(i32) PBI32Slice;

PBI64Slice

typedef PBSliceType(i64) PBI64Slice;

PBU16Slice

typedef PBSliceType(u16) PBU16Slice;

PBU32Slice

typedef PBSliceType(u32) PBU32Slice;

PBU64Slice

typedef PBSliceType(u64) PBU64Slice;

PBF32Slice

typedef PBSliceType(f32) PBF32Slice;

PBF64Slice

typedef PBSliceType(f64) PBF64Slice;

PBPtrSlice

typedef PBSliceType(void*) PBPtrSlice;

PBSliceFrom

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

PBSliceSlice

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

PBSliceAt

macro T PBSliceAt(SliceType slice, usize index)

PBSliceRefAt

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

PBSliceEq

macro bool PBSliceEq(SliceType slice, SliceType otherSlice)

PBSliceCmp

macro int PBSliceCmp(SliceType slice, SliceType otherSlice)

#include <playbit/string.h>

PBStrSliceLike

typedef const void * PBStrSliceLike;

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

PBStrLit

macro PBStrSlice PBStrLit(const char stringLiteral[])

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

PBStrFree

void PBStrFree(PBStr str,
               PBMem ma);

PBStrFree releases the memory of str back to memory allocator ma

PBStrFrom

PBStr PBStrFrom(PBMem          ma,
                PBStrSliceLike value);

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

PBStrFromSlice

PBStr PBStrFromSlice(PBMem      ma,
                     PBStrSlice value);

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

PBStrFmt

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

PBStrFmt makes a string with printf-like formatting.

PBStrFmtv

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

PBStrFmtv is the va_list variant of PBStrFmt.

PBStrJoin

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

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

PBStrJoinSlice

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

PBStrJoinSlice joins n values with glue between each value.

PBStrCat

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

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

PBStrAssign

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

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

PBStrAssignFromSlice

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

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

PBStr_FMT

#define PBStr_FMT const char*

PBStr_FMT is used in printf format as the pattern for a PBStr-like value, like PBStrSlice

PBStr_FMT_ARG

#define PBStr_FMT_ARG(pbStr)

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

PBStrSliceOf

PBStrSlice PBStrSliceOf(const void* value, ...);

PBStrSliceOf constructs a slice of a value. It's implemented as a generic macro, with the following effective signature: PBStrSlice PBStrSliceOf<T is convertible to PBStrSlice>( T value [, usize start [, usize len]]) Types convertible to PBStrSlice:

PBStrSliceOfStrSlice

PBStrSlice PBStrSliceOfStrSlice(PBStrSlice other);

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

PBStrSliceOfStrSlice2

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

PBStrSliceOfStrSlice3

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

PBStrSliceOfU8Slice

PBStrSlice PBStrSliceOfU8Slice(PBU8Slice other);

PBStrSliceOfU8Slice2

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

PBStrSliceOfCStr

PBStrSlice PBStrSliceOfCStr(const char* str);

PBStrSliceOfCStr2

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

PBStrSliceOfStr

PBStrSlice PBStrSliceOfStr(const PBStr str);

PBStrSliceOfStr2

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

PBStrSliceOfU8Array

PBStrSlice PBStrSliceOfU8Array(PBU8Array other);

PBStrSliceOfU8Array2

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

PBStrSliceOfU8Arrayp

PBStrSlice PBStrSliceOfU8Arrayp(const PBU8Array* other);

PBStrSliceOfU8Arrayp2

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

PBStrSliceOfBuf

PBStrSlice PBStrSliceOfBuf(PBBuf other);

PBStrSliceOfBuf2

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

PBStrSliceOfBufp

PBStrSlice PBStrSliceOfBufp(const PBBuf* other);

PBStrSliceOfBufp2

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

PBStrSliceOfBytes

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

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

PBStrEq

#define PBStrEq(a, b)

PBStrEq returns true if a is equal to b. It's implemented as a generic macro, with the following effective signature: bool PBStrEq<A is convertible to PBStrSlice, B is convertible to PBStrSlice>(A a, B b)

PBCheckStrEq

macro PBCheckStrEq()

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

PB_STR

macro PBStrSlice PB_STR(const char* cstr)

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

PBStrSlicePrintv

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

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

PBStrSlicePrint

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

PBStrSlicePrint is the va_args variant of PBStrSlicePrintv.

PBStrSliceOfStrp

PBStrSlice PBStrSliceOfStrp(const PBStr* str);

PBStrSliceOfStrp returns a borrowed view of *str.

PBStrSliceOfStrp2

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

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


#include <playbit/sysbuf.h>

PBSysBufAdvance

bool PBSysBufAdvance(PBSysBuf* bufvPtr,
                     u32*      bufcPtr,
                     i64       nbytes);

PBSysBufAdvance "removes" the first nbytes bytes from a list of PBSysBuf buffers. This is a helper function meant to be used when reading or writing chains of buffers. Caution: This function modifies buffers at *bufvPtr, updating their bytes and len fields. Returns true if *bufcPtr reached zero; i.e. buffers are empty.

Example:

void Write(PBSysHandle stream, PBSysBuf* bufv, u32 bufc) {
    i64 nbytesWritten = PBSysStreamWrite(stream, bufv, bufc, 0);
    if (nbytesWritten > 0) {
        if (SysBufAdvance(&bufv, &bufc, nbytesWritten)) {
            // everything has been written
        }
    } else {
        // handle error
    }
}

#include <playbit/hash.h>

PBHashImpl

typedef enum PBHashImpl {
    PBHashImpl_NONE,
    PBHashImpl_BLAKE3,
} PBHashImpl;

PBHashBlake3_CHUNK_LEN

const int PBHashBlake3_CHUNK_LEN = 1024;

ideal max size for PBHasherUpdate

PBHashBlake3_OUT_LEN

const int PBHashBlake3_OUT_LEN = 32;

number of bytes returned by PBHasherFinalize

PBHashBlake3_HASHER_SIZE

const int PBHashBlake3_HASHER_SIZE = 1928;

bytes needed for PBHasherEmplace

PBHasherCreate

PBHasher* PBHasherCreate(PBMem      ma,
                         PBHashImpl impl);

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

PBHasherFree

void PBHasherFree(PBHasher* hasher);

PBHasherFree frees the memory of a hasher allocated with PBHasherCreate

PBHasherEmplace

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

PBHasherEmplace initializes a hasher at mem

PBHasherUpdate

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

PBHasherUpdate feeds input data to the hasher

PBHasherFinalize

usize PBHasherFinalize(PBHasher* hasher,
                       u8*       output,
                       usize     outputCap);

PBHasherFinalize computes the final hash.

Note: Blake3 uses a fixed hash size of PBHashBlake3_OUT_LEN bytes.

PBHasherReset

void PBHasherReset(PBHasher* hasher);

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

PBHashRapidHash

u64 PBHashRapidHash(const void* data,
                    usize       dataSize);

PBHashRapidHash computes a hash of data using the rapidhash hash implementation, a successor to wyhash with very good distribution and speed.

PBHashRapidHashSeeded

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

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

PBHashRapidMix

u64 PBHashRapidMix(u64 a,
                   u64 b);

PBHashRapidMix mixes two integers together using multiply and xor

PBHashBytes

u64 PBHashBytes(const void* data,
                usize       dataSize);

PBHashBytes computes a non-cryptographic hash of data. Currently an alias of PBHashRapidHash, but may change in the future if a more suitable hash algorithm comes along.

PBHashBytesSeeded

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

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

PBHashMix

u64 PBHashMix(u64 a,
              u64 b);

PBHashMix mixes two integers together