photo: a frame's tags written into a kept buffer and interned, one string per distinct text - a viewfinder composes every frame, and each tag concatenated a new text the frame dropped

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 13:29:00 +03:00
parent f38581754a
commit 7b91300962
2 changed files with 24 additions and 3 deletions

View file

@ -2,6 +2,7 @@
# takes the best subject's grade - which is what a photographer would say about it # takes the best subject's grade - which is what a photographer would say about it
export function photo_frame_begin(photo_st: mut PhotoState) -> void { export function photo_frame_begin(photo_st: mut PhotoState) -> void {
photo_st.pht_pending_tags = "" photo_st.pht_pending_tags = ""
sb_clear(photo_st.pht_tag_sb)
photo_st.pht_pending_mask = 0 photo_st.pht_pending_mask = 0
photo_st.pht_pending_legend = 0 photo_st.pht_pending_legend = 0
photo_st.pht_pending_grade = 0 photo_st.pht_pending_grade = 0
@ -27,11 +28,29 @@ export function photo_frame_subject(photo_st: mut PhotoState, sp: int, name: str
} }
# anything else in the picture worth naming: a landmark, the water, a sign # anything else in the picture worth naming: a landmark, the water, a sign
@alloc_ok("a shot's tags: once per photograph taken") # (a viewfinder composes every frame: the text is written into a kept buffer and interned)
export function photo_frame_tag(photo_st: mut PhotoState, text: string) -> void { export function photo_frame_tag(photo_st: mut PhotoState, text: string) -> void {
if len(text) == 0 { return } if len(text) == 0 { return }
if len(photo_st.pht_pending_tags) > 0 { photo_st.pht_pending_tags = photo_st.pht_pending_tags + ", " } let sb = photo_st.pht_tag_sb
photo_st.pht_pending_tags = photo_st.pht_pending_tags + text if sb_len(sb) > 0 { sb_add(sb, ", ") }
sb_add(sb, text)
photo_st.pht_pending_tags = pht_tags_text(photo_st)
}
# past the table's most, a copy only when the text changed - never one a frame
@alloc_ok("a tag text past 4096 distinct ones: one copy per change")
function pht_tags_text(photo_st: PhotoState) -> string {
let sb = photo_st.pht_tag_sb
let tb = photo_st.pht_tag_tb
if strs_count(tb) < tb.most { return sb_intern(sb, tb) }
if pht_same(sb, photo_st.pht_pending_tags) { return photo_st.pht_pending_tags }
return keep(text_of(sb.b, sb_len(sb)))
}
function pht_same(sb: StrBuf, s: string) -> bool {
if len(s) != sb_len(sb) { return false }
for i in 0 .. sb_len(sb) { if s[i] != sb.b[i] { return false } }
return true
} }
export function photo_frame_sign(photo_st: mut PhotoState, sign: int) -> void { photo_st.pht_pending_sign = sign } export function photo_frame_sign(photo_st: mut PhotoState, sign: int) -> void { photo_st.pht_pending_sign = sign }

View file

@ -47,6 +47,8 @@ export state PhotoState {
pht_legend_shot: int = 0 pht_legend_shot: int = 0
pht_cover: int = -1 # the one frame a game shows for the whole roll pht_cover: int = -1 # the one frame a game shows for the whole roll
pht_pending_tags: string = "" pht_pending_tags: string = ""
pht_tag_sb: StrBuf = sb_new(512) # the tags written in place, then one string per distinct text
pht_tag_tb: StrTable = strs_new(4096)
pht_pending_mask: int = 0 pht_pending_mask: int = 0
pht_pending_legend: int = 0 pht_pending_legend: int = 0
pht_pending_grade: int = 0 pht_pending_grade: int = 0