power_play/src/base/base_tweak.c
2026-01-09 15:37:23 -06:00

143 lines
3.8 KiB
C

////////////////////////////////////////////////////////////
//~ Bootstrap
void BootstrapTweakVars(void)
{
// TODO: Swap in/out for persistence
}
////////////////////////////////////////////////////////////
//~ Tweak var operations
String TweakEx(Arena *arena, TweakVar desc, b32 update_existing)
{
String result = Zi;
Arena *perm = PermArena();
u64 hash = HashString(desc.name);
TweakVarEntryBin *bin = &Base.tweak.entry_bins[hash % countof(Base.tweak.entry_bins)];
LockTicketMutex(&Base.tweak.tm);
{
TweakVarEntry *e = bin->first;
for (; e; e = e->next_in_bin)
{
if (e->hash == hash)
{
break;
}
}
if (!e)
{
PushAlign(perm, CachelineSize);
e = PushStruct(perm, TweakVarEntry);
e->hash = hash;
{
// FIXME: Not perm
String store_name = PushString(perm, desc.name);
String store_category = PushString(perm, desc.category);
String store_value = PushString(perm, desc.value);
String store_initial = PushString(perm, desc.initial);
TweakVar *v = &e->v;
*v = desc;
v->name = store_name;
v->category = store_category;
v->value = store_value;
v->initial = store_initial;
}
PushAlign(perm, CachelineSize);
SllQueuePushN(bin->first, bin->last, e, next_in_bin);
SllQueuePushN(Base.tweak.first_entry, Base.tweak.last_entry, e, next_in_list);
Base.tweak.entries_count += 1;
}
else if (update_existing)
{
if (!MatchString(e->v.value, desc.value))
{
// FIXME: Not perm
String store_value = PushString(perm, desc.value);
// FIXME: free old value
e->v.value = store_value;
}
}
result = PushString(arena, e->v.value);
}
UnlockTicketMutex(&Base.tweak.tm);
return result;
}
TweakVarArray GetAllTweakVars(Arena *arena)
{
TweakVarArray result = Zi;
LockTicketMutex(&Base.tweak.tm);
{
result.count = Base.tweak.entries_count;
result.v = PushStructsNoZero(arena, TweakVar, result.count);
i64 var_idx = 0;
for (TweakVarEntry *e = Base.tweak.first_entry; e; e = e->next_in_list)
{
TweakVar *src = &e->v;
TweakVar *dst = &result.v[var_idx];
*dst = *src;
dst->name = PushString(arena, src->name);
dst->category = PushString(arena, src->category);
dst->value = PushString(arena, src->value);
dst->initial = PushString(arena, src->initial);
var_idx += 1;
}
}
UnlockTicketMutex(&Base.tweak.tm);
return result;
}
////////////////////////////////////////////////////////////
//~ Tweak utils
b32 TweakBool_(String name, b32 initial, TweakBoolDesc desc)
{
b32 result = 0;
TempArena scratch = BeginScratchNoConflict();
{
String initial_str = StringFromBool(scratch.arena, initial);
TweakVar var = Zi;
{
var.flags = desc.flags;
var.kind = TweakKind_Bool;
var.name = name;
var.category = desc.category;
var.value = initial_str;
var.initial = initial_str;
}
String tweak_str = TweakEx(scratch.arena, var, 0);
result = CR_BoolFromString(tweak_str);
}
EndScratch(scratch);
return result;
}
f64 TweakFloat_(String name, f64 initial, TweakFloatDesc desc)
{
f64 result = 0;
TempArena scratch = BeginScratchNoConflict();
{
String initial_str = StringFromFloat(scratch.arena, initial, desc.precision);
TweakVar var = Zi;
{
var.flags = desc.flags;
var.kind = TweakKind_Float;
var.name = name;
var.category = desc.category;
var.value = initial_str;
var.initial = initial_str;
var.range.min = desc.min;
var.range.max = desc.max;
var.precision = desc.precision;
}
String tweak_str = TweakEx(scratch.arena, var, 0);
result = CR_FloatFromString(tweak_str);
}
EndScratch(scratch);
return result;
}