Skip to documentation
SLOP

tiny.ui.AssetRegistry

Reference tiny.ui AssetRegistry

Defined in tiny.ui.

API (32)

Actions

Public operations.

Types and contracts

Public types and contracts.

Fields and members

Public fields and members.

No direct callersNo direct callstiny.uiAssetRegistry
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/ui/src/asset/registry.zig:13

zig
pub const Registry = struct {    phase: alloc_phase.capacity.Phase,    limits: Limits,    capacity: Capacity,    storage: []align(8) u8,    fonts: []FontDescriptor,    font_bytes: []Bytes,    font_generation: []u32,    font_used: u32,    images: []ImageDescriptor,    image_bytes: []Bytes,    image_generation: []u32,    image_used: u32,    strings: []u8,    owned_bytes: []u8,    font_occupied: []u64,    image_occupied: []u64,    epoch: u64,    pub const Limits: type = capacity_mod.Limits;    pub const Capacity: type = capacity_mod.Capacity;    pub const Exhaustion: type = model.Error;    pub const InitError: type = Allocator.Error || capacity_mod.Error;    pub const claim: alloc_phase.capacity.Declaration = .{        .source = .{            .id = "ui.asset_table",            .kind = .phase_static,            .limit_source = .caller,            .storage = .{                .covered = &.{.{                    .id = "asset_table_and_owned_payload_pool",                    .lifetime = .steady,                    .detail = "font and image descriptors, byte views, generation and occupancy arrays, family strings, and the copied payload pool in one allocation",                }},                .excluded = &.{                    "borrowed font and image bytes kept alive by the caller",                    "embedded fallback face bytes held in startup static storage",                },            },            .capacity = .{                .inputs = &.{                    alloc_phase.capacity.bindInput(Limits, "fonts", "fonts"),                    alloc_phase.capacity.bindInput(Limits, "images", "images"),                    alloc_phase.capacity.bindInput(Limits, "owned_bytes", "owned_bytes"),                },                .type_selectors = &.{                    alloc_phase.capacity.bindType(FontDescriptor, "font_descriptor"),                    alloc_phase.capacity.bindType(ImageDescriptor, "image_descriptor"),                    alloc_phase.capacity.bindType(Bytes, "bytes"),                    alloc_phase.capacity.bindType(u32, "generation"),                    alloc_phase.capacity.bindType(u64, "occupancy_word"),                },                .nodes = &.{                    .{ .input = 0 },                    .{ .input = 1 },                    .{ .input = 2 },                    .{ .scale = .{ .node = 0, .coefficient = .{ .size_of_concrete_type = 0 } } },                    .{ .alignment = .{ .node = 3, .alignment = .{ .concrete_type = 2 } } },                    .{ .scale = .{ .node = 0, .coefficient = .{ .size_of_concrete_type = 2 } } },                    .{ .add = .{ .left = 4, .right = 5 } },                    .{ .alignment = .{ .node = 6, .alignment = .{ .concrete_type = 3 } } },                    .{ .scale = .{ .node = 0, .coefficient = .{ .size_of_concrete_type = 3 } } },                    .{ .add = .{ .left = 7, .right = 8 } },                    .{ .alignment = .{ .node = 9, .alignment = .{ .concrete_type = 4 } } },                    .{ .constant = 64 },                    .{ .ceiling_division = .{ .left = 0, .right = 11 } },                    .{ .scale = .{ .node = 12, .coefficient = .{ .size_of_concrete_type = 4 } } },                    .{ .add = .{ .left = 10, .right = 13 } },                    .{ .alignment = .{ .node = 14, .alignment = .{ .concrete_type = 1 } } },                    .{ .scale = .{ .node = 1, .coefficient = .{ .size_of_concrete_type = 1 } } },                    .{ .add = .{ .left = 15, .right = 16 } },                    .{ .alignment = .{ .node = 17, .alignment = .{ .concrete_type = 2 } } },                    .{ .scale = .{ .node = 1, .coefficient = .{ .size_of_concrete_type = 2 } } },                    .{ .add = .{ .left = 18, .right = 19 } },                    .{ .alignment = .{ .node = 20, .alignment = .{ .concrete_type = 3 } } },                    .{ .scale = .{ .node = 1, .coefficient = .{ .size_of_concrete_type = 3 } } },                    .{ .add = .{ .left = 21, .right = 22 } },                    .{ .alignment = .{ .node = 23, .alignment = .{ .concrete_type = 4 } } },                    .{ .ceiling_division = .{ .left = 1, .right = 11 } },                    .{ .scale = .{ .node = 25, .coefficient = .{ .size_of_concrete_type = 4 } } },                    .{ .add = .{ .left = 24, .right = 26 } },                    .{ .scale = .{ .node = 0, .coefficient = .{ .literal = capacity_mod.family_bytes_per_font } } },                    .{ .add = .{ .left = 27, .right = 28 } },                    .{ .add = .{ .left = 29, .right = 2 } },                },                .assertions = &.{.{                    .scope = .closure_total,                    .measure = .retained,                    .relation = .exact,                    .expression = 30,                }},            },            .overload = .{                .kind = .reject_before_mutation,                .detail = "slot, family length, and owned payload quota checks run before changing table fields",            },            .risks = .{                .transitive = .{                    .status = .open,                    .detail = "owned bytes use one allocation at initialization; the bounded registration scan takes no allocator",                },                .foreign = .{                    .status = .excluded,                    .detail = "registration and lookup operate on caller and table bytes without an operating-system call",                },            },            .obligations = &.{                .{ .key = "ui_asset_capacity", .role = .capacity_model },                .{ .key = "ui_asset_acquisition", .role = .acquisition },                .{ .key = "ui_asset_generation", .role = .integration },                .{ .key = "ui_asset_oom", .role = .overload },                .{ .key = "ui_asset_teardown", .role = .teardown },            },        },        .bindings = .{            .owner = @This(),            .seal = .{                .family = alloc_phase.capacity.selector(@This().activate),                .premise = .{ .class = .checked_semantic_fact, .authority = .checker },            },            .teardown = .{                .family = alloc_phase.capacity.selector(@This().deinit),                .premise = .{ .class = .checked_semantic_fact, .authority = .checker },            },        },    };    pub fn init(allocator: Allocator, limits: Limits) InitError!Registry {        const capacity = try Capacity.derive(limits);        const storage = try allocator.alignedAlloc(u8, .fromByteUnits(8), capacity.total_bytes);        var self = Registry{            .phase = .initialization,            .limits = limits,            .capacity = capacity,            .storage = storage,            .fonts = &.{},            .font_bytes = &.{},            .font_generation = &.{},            .font_used = 0,            .images = &.{},            .image_bytes = &.{},            .image_generation = &.{},            .image_used = 0,            .strings = &.{},            .owned_bytes = &.{},            .font_occupied = &.{},            .image_occupied = &.{},            .epoch = 0,        };        self.place();        @memset(self.storage, 0);        for (self.font_bytes) |*entry| entry.* = .{ .borrowed = &.{} };        for (self.image_bytes) |*entry| entry.* = .{ .borrowed = &.{} };        @memset(self.font_generation, 1);        @memset(self.image_generation, 1);        return self;    }    pub fn activate(self: *Registry) void {        std.debug.assert(self.phase == .initialization);        std.debug.assert(self.storage.len == self.capacity.total_bytes);        self.phase = .steady;    }    pub fn deinit(self: *Registry, allocator: Allocator) void {        std.debug.assert(self.phase != .teardown);        allocator.free(self.storage);        self.phase = .teardown;        self.storage = &.{};        self.fonts = &.{};        self.font_bytes = &.{};        self.font_generation = &.{};        self.images = &.{};        self.image_bytes = &.{};        self.image_generation = &.{};        self.strings = &.{};        self.owned_bytes = &.{};        self.font_occupied = &.{};        self.image_occupied = &.{};        self.font_used = 0;        self.image_used = 0;        self.epoch = 0;    }    pub fn registerFont(self: *Registry, family: []const u8, input: FontDescriptor, bytes: Bytes) model.Error!AssetHandle {        std.debug.assert(self.phase == .steady);        if (family.len > capacity_mod.family_bytes_per_font) return error.FamilyTooLong;        const index = firstFree(self.font_occupied, self.limits.fonts) orelse return error.FontCapacityExceeded;        const source = bytes.slice();        const offset = switch (bytes) {            .borrowed => null,            .owned => self.findOwned(source.len) orelse return error.OwnedBytesExceeded,        };        const family_offset = @as(usize, index) * capacity_mod.family_bytes_per_font;        var descriptor = input;        descriptor.family_offset = @intCast(family_offset);        descriptor.family_len = @intCast(family.len);        @memcpy(self.strings[family_offset..][0..family.len], family);        self.fonts[index] = descriptor;        self.font_bytes[index] = self.storeBytes(bytes, offset);        setOccupied(self.font_occupied, index, true);        self.font_used += 1;        self.epoch +%= 1;        return .{ .index = index, .generation = self.font_generation[index] };    }    pub fn registerImage(self: *Registry, descriptor: ImageDescriptor, bytes: Bytes) model.Error!AssetHandle {        std.debug.assert(self.phase == .steady);        const index = firstFree(self.image_occupied, self.limits.images) orelse return error.ImageCapacityExceeded;        const source = bytes.slice();        const offset = switch (bytes) {            .borrowed => null,            .owned => self.findOwned(source.len) orelse return error.OwnedBytesExceeded,        };        self.images[index] = descriptor;        self.image_bytes[index] = self.storeBytes(bytes, offset);        setOccupied(self.image_occupied, index, true);        self.image_used += 1;        self.epoch +%= 1;        return .{ .index = index, .generation = self.image_generation[index] };    }    pub fn release(self: *Registry, kind: model.Kind, handle: AssetHandle) model.Error!void {        std.debug.assert(self.phase == .steady);        switch (kind) {            .font => {                if (!self.hasFont(handle)) return error.StaleAsset;                if (handle.generation == std.math.maxInt(u32)) return error.GenerationExhausted;                clearOwned(self.font_bytes[handle.index]);                const start = @as(usize, handle.index) * capacity_mod.family_bytes_per_font;                @memset(self.strings[start..][0..capacity_mod.family_bytes_per_font], 0);                self.fonts[handle.index] = .{};                self.font_bytes[handle.index] = .{ .borrowed = &.{} };                self.font_generation[handle.index] += 1;                setOccupied(self.font_occupied, handle.index, false);                self.font_used -= 1;                self.epoch +%= 1;            },            .image => {                if (!self.hasImage(handle)) return error.StaleAsset;                if (handle.generation == std.math.maxInt(u32)) return error.GenerationExhausted;                clearOwned(self.image_bytes[handle.index]);                self.images[handle.index] = .{};                self.image_bytes[handle.index] = .{ .borrowed = &.{} };                self.image_generation[handle.index] += 1;                setOccupied(self.image_occupied, handle.index, false);                self.image_used -= 1;                self.epoch +%= 1;            },        }    }    pub fn hasFont(self: *const Registry, handle: AssetHandle) bool {        return handle.index < self.limits.fonts and occupied(self.font_occupied, handle.index) and self.font_generation[handle.index] == handle.generation;    }    pub fn hasImage(self: *const Registry, handle: AssetHandle) bool {        return handle.index < self.limits.images and occupied(self.image_occupied, handle.index) and self.image_generation[handle.index] == handle.generation;    }    pub fn font(self: *const Registry, handle: AssetHandle) model.Error!model.Font {        if (!self.hasFont(handle)) return error.StaleAsset;        const descriptor = self.fonts[handle.index];        return .{            .descriptor = descriptor,            .family = self.strings[descriptor.family_offset..][0..descriptor.family_len],            .bytes = self.font_bytes[handle.index].slice(),        };    }    pub fn image(self: *const Registry, handle: AssetHandle) model.Error!model.Image {        if (!self.hasImage(handle)) return error.StaleAsset;        return .{ .descriptor = self.images[handle.index], .bytes = self.image_bytes[handle.index].slice() };    }    fn storeBytes(self: *Registry, bytes: Bytes, offset: ?usize) Bytes {        return switch (bytes) {            .borrowed => bytes,            .owned => |source| blk: {                const start = offset.?;                @memcpy(self.owned_bytes[start..][0..source.len], source);                break :blk .{ .owned = self.owned_bytes[start..][0..source.len] };            },        };    }    fn findOwned(self: *const Registry, len: usize) ?usize {        if (len > self.owned_bytes.len) return null;        var candidate: usize = 0;        while (candidate <= self.owned_bytes.len - len) {            var conflict_end: usize = candidate;            for (self.font_bytes, 0..) |entry, index| {                if (!occupied(self.font_occupied, @intCast(index))) continue;                overlapEnd(self.owned_bytes, entry, candidate, len, &conflict_end);            }            for (self.image_bytes, 0..) |entry, index| {                if (!occupied(self.image_occupied, @intCast(index))) continue;                overlapEnd(self.owned_bytes, entry, candidate, len, &conflict_end);            }            if (conflict_end == candidate) return candidate;            candidate = conflict_end;        }        return null;    }    fn place(self: *Registry) void {        var cursor: usize = 0;        self.fonts = take(self.storage, &cursor, FontDescriptor, self.limits.fonts);        self.font_bytes = take(self.storage, &cursor, Bytes, self.limits.fonts);        self.font_generation = take(self.storage, &cursor, u32, self.limits.fonts);        self.font_occupied = take(self.storage, &cursor, u64, std.math.divCeil(usize, self.limits.fonts, 64) catch unreachable);        self.images = take(self.storage, &cursor, ImageDescriptor, self.limits.images);        self.image_bytes = take(self.storage, &cursor, Bytes, self.limits.images);        self.image_generation = take(self.storage, &cursor, u32, self.limits.images);        self.image_occupied = take(self.storage, &cursor, u64, std.math.divCeil(usize, self.limits.images, 64) catch unreachable);        self.strings = take(self.storage, &cursor, u8, self.capacity.string_bytes);        self.owned_bytes = take(self.storage, &cursor, u8, self.limits.owned_bytes);        std.debug.assert(cursor == self.capacity.total_bytes);    }};

Source: lib/ui/src/root.zig:34

zig
pub const AssetRegistry = asset.Registry;
Called byCallsNo direct callsasset.Embeddedopenprivate sourcelib.ui.src.asset.registryopenAndClosetest sourcelib.ui.src.asset.registrytest: ui asset capacity accepts each ...test sourcelib.ui.src.asset.registrytest: ui asset capacity default slot ...test sourcelib.ui.src.asset.registrytest: ui asset generation register re...+5 moreAssetRegistryactivate
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.ui.src.asset.registryopenAndClosetest sourcelib.ui.src.asset.registrytest: ui asset capacity accepts each ...test sourcelib.ui.src.asset.registrytest: ui asset capacity default slot ...test sourcelib.ui.src.asset.registrytest: ui asset generation register re...test sourcelib.ui.src.asset.registrytest: ui asset oom registration rejec...test sourcelib.ui.src.asset.registrytest: ui asset teardown borrows calle...AssetRegistrydeinit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest sourcelib.ui.src.asset.registrytest: ui asset capacity default slot ...test sourcelib.ui.src.asset.registrytest: ui asset generation register re...test sourcelib.ui.src.asset.registrytest: ui asset oom registration rejec...test sourcelib.ui.src.asset.registrytest: ui asset teardown borrows calle...AssetRegistryhasFontAssetRegistryfont
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsAssetRegistryfontAssetRegistryreleaseprivate sourcelib.ui.src.asset.registryoccupiedAssetRegistryhasFont
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsAssetRegistryimageAssetRegistryreleaseprivate sourcelib.ui.src.asset.registryoccupiedAssetRegistryhasImage
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.ui.src.asset.registrytest: ui asset teardown borrows calle...AssetRegistryhasImageAssetRegistryimage
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsasset.Embeddedopenprivate sourcelib.ui.src.asset.registryopenAndClosetest sourcelib.ui.src.asset.registrytest: ui asset capacity accepts each ...test sourcelib.ui.src.asset.registrytest: ui asset capacity default slot ...test sourcelib.ui.src.asset.registrytest: ui asset generation register re...+2 moreAssetRegistryinit
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallstest sourcelib.ui.src.asset.registrytest: ui asset capacity accepts each ...test sourcelib.ui.src.asset.registrytest: ui asset capacity default slot ...test sourcelib.ui.src.asset.registrytest: ui asset generation register re...test sourcelib.ui.src.asset.registrytest: ui asset oom registration rejec...test sourcelib.ui.src.asset.registrytest: ui asset teardown borrows calle...+3 moreprivate sourcelib.ui.src.asset.registry.RegistryfindOwnedprivate sourcelib.ui.src.asset.registry.RegistrystoreBytesprivate sourcelib.ui.src.asset.registryfirstFreeprivate sourcelib.ui.src.asset.registrysetOccupiedAssetRegistryregisterFont
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest sourcelib.ui.src.asset.registrytest: ui asset capacity accepts each ...test sourcelib.ui.src.asset.registrytest: ui asset capacity default slot ...test sourcelib.ui.src.asset.registrytest: ui asset oom registration rejec...test sourcelib.ui.src.asset.registrytest: ui asset teardown borrows calle...private sourcelib.ui.src.asset.registry.RegistryfindOwnedprivate sourcelib.ui.src.asset.registry.RegistrystoreBytesprivate sourcelib.ui.src.asset.registryfirstFreeprivate sourcelib.ui.src.asset.registrysetOccupiedAssetRegistryregisterImage
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest sourcelib.ui.src.asset.registrytest: ui asset generation register re...test sourcelib.ui.src.asset.registrytest: ui asset teardown borrows calle...AssetRegistryhasFontAssetRegistryhasImageprivate sourcelib.ui.src.asset.registryclearOwnedprivate sourcelib.ui.src.asset.registrysetOccupiedAssetRegistryrelease
Static calls · unresolved targets: 0 · external targets: 0.

Also reachable as

asset.Registry.

Complete caller list for AssetRegistry.activate

10 direct callers.

Complete caller list for AssetRegistry.init

7 direct callers.

Complete caller list for AssetRegistry.registerFont

8 direct callers.

Audit

Definitions16
Public names32
Members17
Version26.7.0
Revisiondaab053ee433