Skip to documentation
SLOP

tiny.ui.style.share

Reference tiny.ui style share

Defined in style.

API (8)

Actions

Public operations.

Types and contracts

Public types and contracts.

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

Source

Called byCallsNo direct callersstyle.computedlowerprivate sourcelib.ui.src.style.share.Poolrememberprivate sourcelib.ui.src.style.share.PoolsameMatchesstyle.share.Poolintern
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.ui.src.style.share.PoolsameMatchesstyle.share.Poollookup
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/ui/src/style/root.zig:4

zig
pub const share = @import("share.zig");

Source: lib/ui/src/style/share.zig

zig
const std = @import("std");const css = @import("css");const computed = @import("computed.zig");const asset = @import("../asset/root.zig");pub const Key = extern struct {    matched_rules: u32,    inline_first: u32,    inline_count: u32,    parent_style: u32,};pub const KeySlot = struct {    key: Key = .{ .matched_rules = 0, .inline_first = 0, .inline_count = 0, .parent_style = 0 },    style: u32 = 0,    matched: [4]u64 = @splat(0),    matched_count: u8 = 0,};comptime {    std.debug.assert(@sizeOf(Key) == 16);    std.debug.assert(@alignOf(Key) == 4);    std.debug.assert(@offsetOf(Key, "parent_style") == 12);}pub const Pool = struct {    records: []computed.Record,    slots: []u32,    keys: []KeySlot = &.{},    chains: []asset.AssetHandle = &.{},    font_faces: u32 = 0,    used: u32 = 0,    pub fn reset(self: *Pool) void {        self.used = 0;        @memset(self.slots, 0);        for (self.keys) |*slot| slot.* = .{};    }    pub fn truncate(self: *Pool, retained: u32) void {        std.debug.assert(retained <= self.used);        self.used = retained;        @memset(self.slots, 0);        for (self.keys) |*slot| slot.* = .{};        const mask = self.slots.len - 1;        for (self.records[0..retained], 0..) |*record, index| {            const hash = std.hash.Wyhash.hash(0, std.mem.asBytes(&record.computed));            var at: usize = @intCast(hash & @as(u64, @intCast(mask)));            while (self.slots[at] != 0) at = (at + 1) & mask;            self.slots[at] = @intCast(index + 1);        }    }    fn sameMatches(slot: KeySlot, matches: []const css.match.Match) bool {        if (matches.len != slot.matched_count) return false;        for (matches, 0..) |item, at| {            const identity = (@as(u64, item.rule) << 32) | item.selector;            if (slot.matched[at] != identity) return false;        }        return true;    }    fn remember(slot: *KeySlot, key: Key, matches: []const css.match.Match, style: u32) void {        slot.* = .{ .key = key, .style = style, .matched_count = @intCast(matches.len) };        for (matches, 0..) |item, at| {            slot.matched[at] = (@as(u64, item.rule) << 32) | item.selector;        }    }    pub fn lookup(self: *const Pool, key: Key, matches: []const css.match.Match) ?u32 {        if (self.keys.len == 0 or matches.len > 4) return null;        const key_hash = std.hash.Wyhash.hash(0, std.mem.asBytes(&key));        const mask = self.keys.len - 1;        var at: usize = @intCast(key_hash & @as(u64, @intCast(mask)));        var probe: usize = 0;        while (probe < self.keys.len) : (probe += 1) {            const slot = self.keys[at];            if (slot.style == 0) return null;            if (std.meta.eql(slot.key, key) and sameMatches(slot, matches)) return slot.style;            at = (at + 1) & mask;        }        return null;    }    pub fn intern(self: *Pool, key: Key, matches: []const css.match.Match, style: css.cascade.Computed, metrics: computed.Metrics, fonts: ?computed.FontSource) error{DistinctStyleQuota}!u32 {        var key_slot: ?*KeySlot = null;        if (self.keys.len != 0 and matches.len <= 4) {            std.debug.assert(std.math.isPowerOfTwo(self.keys.len));            const key_hash = std.hash.Wyhash.hash(0, std.mem.asBytes(&key));            const key_mask = self.keys.len - 1;            var key_at: usize = @intCast(key_hash & @as(u64, @intCast(key_mask)));            var key_probe: usize = 0;            while (key_probe < self.keys.len) : (key_probe += 1) {                const slot = &self.keys[key_at];                if (slot.style == 0) {                    key_slot = slot;                    break;                }                if (std.meta.eql(slot.key, key) and sameMatches(slot.*, matches) and std.mem.eql(u8, std.mem.asBytes(&self.records[slot.style - 1].computed), std.mem.asBytes(&style))) return slot.style;                key_at = (key_at + 1) & key_mask;            }        }        std.debug.assert(std.math.isPowerOfTwo(self.slots.len));        const hash = std.hash.Wyhash.hash(0, std.mem.asBytes(&style));        const mask = self.slots.len - 1;        var probe: usize = 0;        var at: usize = @intCast(hash & @as(u64, @intCast(mask)));        while (probe < self.slots.len) : (probe += 1) {            const id = self.slots[at];            if (id == 0) {                if (self.used == self.records.len) return error.DistinctStyleQuota;                const font_environment: ?computed.FontEnvironment = if (fonts) |source| blk: {                    std.debug.assert(source.registry.font_used <= self.font_faces);                    const first = @as(usize, self.used) * self.font_faces;                    break :blk .{                        .source = source,                        .fallback_out = self.chains[first..][0..self.font_faces],                        .first = @intCast(first),                    };                } else null;                self.used += 1;                self.records[self.used - 1] = computed.lower(style, metrics, font_environment);                self.slots[at] = self.used;                if (key_slot) |slot| remember(slot, key, matches, self.used);                return self.used;            }            if (std.mem.eql(u8, std.mem.asBytes(&self.records[id - 1].computed), std.mem.asBytes(&style))) {                if (key_slot) |slot| remember(slot, key, matches, id);                return id;            }            at = (at + 1) & mask;        }        return error.DistinctStyleQuota;    }    pub fn get(self: *const Pool, id: u32) *const computed.Record {        std.debug.assert(id > 0);        std.debug.assert(id <= self.used);        return &self.records[id - 1];    }};test "style sharing interns equal independent cascade results" {    var records: [3]computed.Record = undefined;    var slots: [8]u32 = @splat(0);    var pool = Pool{ .records = &records, .slots = &slots };    const initial = css.cascade.Computed.initial();    const left = try pool.intern(.{ .matched_rules = 1, .inline_first = 0, .inline_count = 0, .parent_style = 0 }, &.{}, initial, .{}, null);    const right = try pool.intern(.{ .matched_rules = 2, .inline_first = 1, .inline_count = 0, .parent_style = 0 }, &.{}, initial, .{}, null);    try std.testing.expectEqual(left, right);    var changed = initial;    changed.set(.color, css.value.Value.color(0xFF0000FF));    const other = try pool.intern(.{ .matched_rules = 2, .inline_first = 1, .inline_count = 1, .parent_style = 0 }, &.{}, changed, .{}, null);    try std.testing.expect(other != left);    try std.testing.expectEqual(@as(u32, 2), pool.used);}

Audit

Definitions9
Public names9
Members14
Version26.7.0
Revisiondaab053ee433