move pp sim & vis into separate layers

This commit is contained in:
jacob 2025-11-12 15:21:26 -06:00
parent cd40046afc
commit 391fc33a5e
24 changed files with 573 additions and 529 deletions

View File

@ -1,29 +1,4 @@
@Layer proto @Layer proto
//- Dependencies @Dep pp_sim
@Dep gpu @Dep pp_vis
@Dep sprite
@Dep font
@Dep collider
@Dep net
@Dep mixer
@Dep playback
@Dep platform
@Dep window
@Dep ui
//- Api
@IncludeC pp_ent.h
@IncludeC pp_widgets.h
@IncludeC pp_game.h
//- Impl
@IncludeC pp_ent.c
@IncludeC pp_widgets.c
@IncludeC pp_game.c
//- Embeds
@EmbedDir PP_Resources pp_res
//- Startup
@Startup PP_Startup

View File

@ -1,14 +0,0 @@
Readonly PP_Ent PP_nil_ent = ZI;
////////////////////////////////////////////////////////////
//~ Nil helpers
b32 PP_IsKeyNil(PP_EntKey key)
{
return key.v.hi == 0 && key.v.lo == 0;
}
b32 PP_IsEntNil(PP_Ent *ent)
{
return ent == 0 || ent == &PP_nil_ent;
}

View File

@ -1,93 +0,0 @@
////////////////////////////////////////////////////////////
//~ Key types
#define PP_NilEntKey ((PP_EntKey) { 0 })
#define PP_RootEntKey ((PP_EntKey) { .v.hi = 0x75ebb7a47d1ca753, .v.lo = 0x2d505fc8961e5576 })
Struct(PP_EntKey)
{
U128 v;
};
////////////////////////////////////////////////////////////
//~ Shape types
Struct(PP_Shape)
{
f32 radius;
u32 points_count;
Vec2 points[8];
};
////////////////////////////////////////////////////////////
//~ Ent types
//////////////////////////////
//- Ent roperties
Enum(PP_EntProp)
{
PP_EntProp_None,
};
//////////////////////////////
//- Ent
Struct(PP_Ent)
{
PP_EntKey parent;
PP_EntKey first;
PP_EntKey last;
PP_EntKey next;
PP_EntKey prev;
PP_EntKey key;
PP_Shape shape;
} extern Readonly PP_nil_ent;
//////////////////////////////
//- Ent list
Struct(PP_EntListNode)
{
PP_EntListNode *next;
PP_Ent ent;
};
Struct(PP_EntList)
{
PP_EntListNode *first;
PP_EntListNode *last;
u64 count;
};
////////////////////////////////////////////////////////////
//~ Lookup types
Struct(PP_EntLookupBin)
{
i32 _;
};
////////////////////////////////////////////////////////////
//~ World types
Struct(PP_World)
{
i64 tick;
PP_Ent *ents;
i64 ents_count;
};
Struct(PP_WorldNode)
{
PP_WorldNode *next;
PP_World world;
};
////////////////////////////////////////////////////////////
//~ Nil helpers
b32 PP_IsKeyNil(PP_EntKey key);
b32 PP_IsEntNil(PP_Ent *ent);

View File

@ -1,153 +0,0 @@
////////////////////////////////////////////////////////////
//~ Vis command table
#define PP_VisCmdsTableXMacro(X) \
X(nop, NOP, PP_VisCmdDescFlag_HideFromPalette, PP_HOTKEY(0), ) \
X(exit_program, Exit Program, PP_VisCmdDescFlag_HideFromPalette, PP_HOTKEY( Button_Esc ) ) \
X(toggle_command_palette, Toggle Command Palette, PP_VisCmdDescFlag_HideFromPalette, PP_HOTKEY( Button_P, .ctrl = 1, .shift = 1 ), ) \
X(toggle_ui_debug, Toggle UI Debug, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_F5 ), ) \
X(toggle_console, Toggle Developer Console, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_GraveAccent ), ) \
X(toggle_fullscreen, Toggle Fullscreen Mode, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_Enter, .alt = 1 ), PP_HOTKEY( Button_F11 ) ) \
X(toggle_window_topmost, Toggle Window Topmost, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_F4 ), ) \
X(spawn, Spawn, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_S, .ctrl = 1 ), ) \
/* -------------------------------------------------------------------------------------------------------------------- */
////////////////////////////////////////////////////////////
//~ Sim command types
Enum(PP_SimCmdKind)
{
PP_SimCmdKind_Nop,
PP_SimCmdKind_Ent,
};
Struct(PP_SimCmd)
{
PP_SimCmdKind kind;
PP_Ent ent;
};
Struct(PP_SimCmdNode)
{
PP_SimCmdNode *next;
PP_SimCmd cmd;
};
////////////////////////////////////////////////////////////
//~ Vis command types
Enum(PP_VisCmdKind)
{
#define X(name, ...) PP_VisCmdKind_##name,
PP_VisCmdsTableXMacro(X)
#undef X
PP_VisCmdKind_Count,
};
Struct(PP_Shortcut)
{
PP_Shortcut *next_in_bin;
PP_Shortcut *prev_in_bin;
u64 hotkey_hash;
PP_Hotkey hotkey;
String cmd_name;
};
Struct(PP_ShortcutBin)
{
PP_Shortcut *first;
PP_Shortcut *last;
};
Enum(PP_VisCmdDescFlag)
{
PP_VisCmdDescFlag_None = 0,
PP_VisCmdDescFlag_HideFromPalette = (1 << 0),
};
Struct(PP_VisCmdDesc)
{
String name;
String display_name;
PP_VisCmdDescFlag flags;
PP_Hotkey default_hotkeys[8];
};
Struct(PP_VisCmd)
{
String name;
};
Struct(PP_VisCmdNode)
{
PP_VisCmdNode *next;
PP_VisCmd cmd;
};
Global Readonly PP_VisCmdDesc PP_vis_cmd_descs[PP_VisCmdKind_Count] = {
#define X(_name, _display_name, _flags, ...) { .name = CompLit(#_name), .display_name = CompLit(#_display_name), .flags = _flags, .default_hotkeys = { __VA_ARGS__ } },
PP_VisCmdsTableXMacro(X)
#undef X
};
////////////////////////////////////////////////////////////
//~ State types
#define PP_SimInputStatesCount 2
#define PP_SimOutputStatesCount 2
Struct(PP_SimInputState)
{
Arena *arena;
PP_SimCmdNode *first_cmd_node;
PP_SimCmdNode *last_cmd_node;
u64 cmds_count;
};
Struct(PP_SimOutputState)
{
Arena *arena;
PP_WorldNode *first_world_node;
PP_WorldNode *last_world_node;
u64 worlds_count;
};
Struct(PP_SharedState)
{
Atomic32 shutdown;
Fence worker_completion_fence;
i64 workers_count;
//- Vis -> Sim
TicketMutex sim_input_back_tm;
i32 sim_input_back_idx;
PP_SimInputState sim_input_states[PP_SimInputStatesCount];
//- Sim -> Vis
TicketMutex sim_output_back_tm;
i32 sim_output_back_idx;
PP_SimOutputState sim_output_states[PP_SimOutputStatesCount];
} extern PP_shared_state;
////////////////////////////////////////////////////////////
//~ Startup
void PP_Startup(void);
void PP_Shutdown(void);
////////////////////////////////////////////////////////////
//~ Hotkey helpers
String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey);
////////////////////////////////////////////////////////////
//~ Sim worker
JobDecl(PP_SimWorker, EmptySig);
////////////////////////////////////////////////////////////
//~ Vis worker
JobDecl(PP_VisWorker, EmptySig);

View File

@ -0,0 +1,13 @@
@Layer pp_sim
//- Dependencies
@Dep platform
//- Api
@IncludeC pp_sim_core.h
//- Impl
@IncludeC pp_sim_core.c
//- Startup
@Startup S_Startup

View File

@ -0,0 +1,170 @@
S_SharedState S_shared_state = ZI;
Readonly S_Ent S_nil_ent = ZI;
////////////////////////////////////////////////////////////
//~ Startup
void S_Startup(void)
{
S_SharedState *shared = &S_shared_state;
/* Initialize shared state */
for (u64 i = 0; i < countof(shared->input_states); ++i)
{
S_InputState *input = &shared->input_states[i];
input->arena = AcquireArena(Gibi(64));
}
for (u64 i = 0; i < countof(shared->output_states); ++i)
{
S_OutputState *output = &shared->output_states[i];
output->arena = AcquireArena(Gibi(64));
}
/* Create job pools */
JobPoolId sim_pool = InitJobPool(1, Lit("Sim"), JobPoolPriority_Simulation);
/* Start jobs */
shared->workers_count += RunJob(S_SimWorker, .pool = sim_pool, .fence = &shared->worker_completion_fence);
OnExit(&S_Shutdown);
}
void S_Shutdown(void)
{
S_SharedState *shared = &S_shared_state;
Atomic32Set(&shared->shutdown, 1);
YieldOnFence(&shared->worker_completion_fence, shared->workers_count);
}
////////////////////////////////////////////////////////////
//~ Nil helpers
b32 S_IsKeyNil(S_EntKey key)
{
return key.v.hi == 0 && key.v.lo == 0;
}
b32 S_IsEntNil(S_Ent *ent)
{
return ent == 0 || ent == &S_nil_ent;
}
////////////////////////////////////////////////////////////
//~ Sim worker
JobDef(S_SimWorker, sig, job_id)
{
S_SharedState *shared = &S_shared_state;
Arena *frame_arena = AcquireArena(Gibi(64));
Arena *perm = PermArena();
//- World data
Arena *ents_arena = AcquireArena(Gibi(64));
S_Ent *ents = ArenaFirst(ents_arena, S_Ent);
i64 tick = 0;
/* Create root ent */
{
S_Ent *root_ent = PushStruct(ents_arena, S_Ent);
*root_ent = S_nil_ent;
root_ent->key = S_RootEntKey;
}
/* Create test ent */
{
S_Ent *test_ent = PushStruct(ents_arena, S_Ent);
*test_ent = S_nil_ent;
test_ent->parent = S_RootEntKey;
test_ent->shape.points_count = 1;
test_ent->shape.radius = 0.25;
}
//////////////////////////////
//- Begin sim loop
b32 shutdown = 0;
while (!shutdown)
{
ResetArena(frame_arena);
//////////////////////////////
//- Begin sim frame
i64 frame_begin_ns = TimeNs();
//////////////////////////////
//- Pop sim commands
S_InputState *input = 0;
LockTicketMutex(&shared->input_back_tm);
{
input = &shared->input_states[shared->input_back_idx];
++shared->input_back_idx;
if (shared->input_back_idx >= countof(shared->input_states))
{
shared->input_back_idx = 0;
}
}
UnlockTicketMutex(&shared->input_back_tm);
//////////////////////////////
//- Process sim commands
for (S_CmdNode *cmd_node = input->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
{
S_Cmd cmd = cmd_node->cmd;
switch (cmd.kind)
{
case S_CmdKind_Ent:
{
LogInfoF("Ent cmd");
} break;
}
}
//////////////////////////////
//- Publish sim state
LockTicketMutex(&shared->output_back_tm);
{
S_OutputState *output = &shared->output_states[shared->output_back_idx];
S_WorldNode *world_node = PushStruct(output->arena, S_WorldNode);
S_World *world = &world_node->world;
SllQueuePush(output->first_world_node, output->last_world_node, world_node);
++output->worlds_count;
world->ents_count = ArenaCount(ents_arena, S_Ent);
world->tick = tick;
world->ents = PushStructsNoZero(output->arena, S_Ent, world->ents_count);
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
{
S_Ent *ent = &ents[ent_idx];
world->ents[ent_idx] = *ent;
}
}
UnlockTicketMutex(&shared->output_back_tm);
//////////////////////////////
//- End sim frame
/* Reset front input state */
{
Arena *arena = input->arena;
ResetArena(arena);
ZeroStruct(input);
input->arena = arena;
}
i64 frame_end_ns = TimeNs();
++tick;
//////////////////////////////
//- Sleep
if (!Atomic32Fetch(&shared->shutdown))
{
i64 step_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
P_SleepFrame(frame_begin_ns, step_dt_ns);
}
shutdown = Atomic32Fetch(&shared->shutdown);
}
}

View File

@ -0,0 +1,165 @@
////////////////////////////////////////////////////////////
//~ Key types
#define S_NilEntKey ((S_EntKey) { 0 })
#define S_RootEntKey ((S_EntKey) { .v.hi = 0x75ebb7a47d1ca753, .v.lo = 0x2d505fc8961e5576 })
Struct(S_EntKey)
{
U128 v;
};
////////////////////////////////////////////////////////////
//~ Shape types
Struct(S_Shape)
{
f32 radius;
u32 points_count;
Vec2 points[8];
};
////////////////////////////////////////////////////////////
//~ Ent types
//////////////////////////////
//- Ent roperties
Enum(S_EntProp)
{
S_EntProp_None,
};
//////////////////////////////
//- Ent
Struct(S_Ent)
{
S_EntKey parent;
S_EntKey first;
S_EntKey last;
S_EntKey next;
S_EntKey prev;
S_EntKey key;
S_Shape shape;
} extern Readonly S_nil_ent;
//////////////////////////////
//- Ent list
Struct(S_EntListNode)
{
S_EntListNode *next;
S_Ent ent;
};
Struct(S_EntList)
{
S_EntListNode *first;
S_EntListNode *last;
u64 count;
};
////////////////////////////////////////////////////////////
//~ Lookup types
Struct(S_EntLookupBin)
{
i32 _;
};
////////////////////////////////////////////////////////////
//~ World types
Struct(S_World)
{
i64 tick;
S_Ent *ents;
i64 ents_count;
};
Struct(S_WorldNode)
{
S_WorldNode *next;
S_World world;
};
////////////////////////////////////////////////////////////
//~ Command types
Enum(S_CmdKind)
{
S_CmdKind_Nop,
S_CmdKind_Ent,
};
Struct(S_Cmd)
{
S_CmdKind kind;
S_Ent ent;
};
Struct(S_CmdNode)
{
S_CmdNode *next;
S_Cmd cmd;
};
////////////////////////////////////////////////////////////
//~ State types
#define S_InputStatesCount 2
#define S_OutputStatesCount 2
Struct(S_InputState)
{
Arena *arena;
S_CmdNode *first_cmd_node;
S_CmdNode *last_cmd_node;
u64 cmds_count;
};
Struct(S_OutputState)
{
Arena *arena;
S_WorldNode *first_world_node;
S_WorldNode *last_world_node;
u64 worlds_count;
};
Struct(S_SharedState)
{
Atomic32 shutdown;
Fence worker_completion_fence;
i64 workers_count;
//- Sim input
TicketMutex input_back_tm;
i32 input_back_idx;
S_InputState input_states[S_InputStatesCount];
//- Sim output
TicketMutex output_back_tm;
i32 output_back_idx;
S_OutputState output_states[S_OutputStatesCount];
} extern S_shared_state;
////////////////////////////////////////////////////////////
//~ Startup
void S_Startup(void);
void S_Shutdown(void);
////////////////////////////////////////////////////////////
//~ Nil helpers
b32 S_IsKeyNil(S_EntKey key);
b32 S_IsEntNil(S_Ent *ent);
////////////////////////////////////////////////////////////
//~ Sim worker
JobDecl(S_SimWorker, EmptySig);

View File

@ -0,0 +1,28 @@
@Layer pp_vis
//- Dependencies
@Dep gpu
@Dep sprite
@Dep font
@Dep collider
@Dep net
@Dep mixer
@Dep playback
@Dep platform
@Dep window
@Dep ui
@Dep pp_sim
//- Api
@IncludeC pp_vis_widgets.h
@IncludeC pp_vis_core.h
//- Impl
@IncludeC pp_vis_widgets.c
@IncludeC pp_vis_core.c
//- Embeds
@EmbedDir V_Resources pp_vis_res
//- Startup
@Startup V_Startup

View File

@ -1,168 +1,34 @@
PP_SharedState PP_shared_state = ZI; V_SharedState V_shared_state = ZI;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Startup //~ Startup
void PP_Startup(void) void V_Startup(void)
{ {
PP_SharedState *shared = &PP_shared_state; V_SharedState *shared = &V_shared_state;
/* Initialize shared state */
for (u64 i = 0; i < countof(shared->sim_input_states); ++i)
{
PP_SimInputState *input = &shared->sim_input_states[i];
input->arena = AcquireArena(Gibi(64));
}
for (u64 i = 0; i < countof(shared->sim_output_states); ++i)
{
PP_SimOutputState *output = &shared->sim_output_states[i];
output->arena = AcquireArena(Gibi(64));
}
/* Create job pools */ /* Create job pools */
JobPoolId sim_pool = InitJobPool(1, Lit("Sim"), JobPoolPriority_Simulation);
JobPoolId vis_pool = InitJobPool(1, Lit("Vis"), JobPoolPriority_Graphics); JobPoolId vis_pool = InitJobPool(1, Lit("Vis"), JobPoolPriority_Graphics);
/* Start jobs */ /* Start jobs */
shared->workers_count += RunJob(PP_SimWorker, .pool = sim_pool, .fence = &shared->worker_completion_fence); shared->workers_count += RunJob(V_VisWorker, .pool = vis_pool, .fence = &shared->worker_completion_fence);
shared->workers_count += RunJob(PP_VisWorker, .pool = vis_pool, .fence = &shared->worker_completion_fence); OnExit(&V_Shutdown);
OnExit(&PP_Shutdown);
} }
void PP_Shutdown(void) void V_Shutdown(void)
{ {
PP_SharedState *shared = &PP_shared_state; V_SharedState *shared = &V_shared_state;
Atomic32Set(&shared->shutdown, 1); Atomic32Set(&shared->shutdown, 1);
YieldOnFence(&shared->worker_completion_fence, shared->workers_count); YieldOnFence(&shared->worker_completion_fence, shared->workers_count);
} }
////////////////////////////////////////////////////////////
//~ Sim worker
JobDef(PP_SimWorker, sig, job_id)
{
PP_SharedState *shared = &PP_shared_state;
Arena *frame_arena = AcquireArena(Gibi(64));
Arena *perm = PermArena();
//- World data
Arena *ents_arena = AcquireArena(Gibi(64));
PP_Ent *ents = ArenaFirst(ents_arena, PP_Ent);
i64 tick = 0;
/* Create root ent */
{
PP_Ent *root_ent = PushStruct(ents_arena, PP_Ent);
*root_ent = PP_nil_ent;
root_ent->key = PP_RootEntKey;
}
/* Create test ent */
{
PP_Ent *test_ent = PushStruct(ents_arena, PP_Ent);
*test_ent = PP_nil_ent;
test_ent->parent = PP_RootEntKey;
test_ent->shape.points_count = 1;
test_ent->shape.radius = 0.25;
}
//////////////////////////////
//- Begin sim loop
b32 shutdown = 0;
while (!shutdown)
{
ResetArena(frame_arena);
//////////////////////////////
//- Begin sim frame
i64 frame_begin_ns = TimeNs();
//////////////////////////////
//- Pop sim commands
PP_SimInputState *input = 0;
LockTicketMutex(&shared->sim_input_back_tm);
{
input = &shared->sim_input_states[shared->sim_input_back_idx];
++shared->sim_input_back_idx;
if (shared->sim_input_back_idx >= countof(shared->sim_input_states))
{
shared->sim_input_back_idx = 0;
}
}
UnlockTicketMutex(&shared->sim_input_back_tm);
//////////////////////////////
//- Process sim commands
for (PP_SimCmdNode *cmd_node = input->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
{
PP_SimCmd cmd = cmd_node->cmd;
switch (cmd.kind)
{
case PP_SimCmdKind_Ent:
{
LogInfoF("Ent cmd");
} break;
}
}
//////////////////////////////
//- Publish sim state
LockTicketMutex(&shared->sim_output_back_tm);
{
PP_SimOutputState *output = &shared->sim_output_states[shared->sim_output_back_idx];
PP_WorldNode *world_node = PushStruct(output->arena, PP_WorldNode);
PP_World *world = &world_node->world;
SllQueuePush(output->first_world_node, output->last_world_node, world_node);
++output->worlds_count;
world->ents_count = ArenaCount(ents_arena, PP_Ent);
world->tick = tick;
world->ents = PushStructsNoZero(output->arena, PP_Ent, world->ents_count);
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
{
PP_Ent *ent = &ents[ent_idx];
world->ents[ent_idx] = *ent;
}
}
UnlockTicketMutex(&shared->sim_output_back_tm);
//////////////////////////////
//- End sim frame
/* Reset front input state */
{
Arena *arena = input->arena;
ResetArena(arena);
ZeroStruct(input);
input->arena = arena;
}
i64 frame_end_ns = TimeNs();
++tick;
//////////////////////////////
//- Sleep
if (!Atomic32Fetch(&shared->shutdown))
{
i64 step_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
P_SleepFrame(frame_begin_ns, step_dt_ns);
}
shutdown = Atomic32Fetch(&shared->shutdown);
}
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Vis worker //~ Vis worker
JobDef(PP_VisWorker, sig, job_id) JobDef(V_VisWorker, sig, job_id)
{ {
PP_SharedState *shared = &PP_shared_state; V_SharedState *vis_shared = &V_shared_state;
S_SharedState *sim_shared = &S_shared_state;
Arena *frame_arena = AcquireArena(Gibi(64)); Arena *frame_arena = AcquireArena(Gibi(64));
Arena *perm = PermArena(); Arena *perm = PermArena();
@ -171,7 +37,7 @@ JobDef(PP_VisWorker, sig, job_id)
Struct(VisPersist) Struct(VisPersist)
{ {
PP_CommandsWidget commands_widget; V_CommandsWidget commands_widget;
b32 ui_debug; b32 ui_debug;
b32 show_command_palette; b32 show_command_palette;
b32 show_console; b32 show_console;
@ -183,14 +49,14 @@ JobDef(PP_VisWorker, sig, job_id)
/* Init shortcuts */ /* Init shortcuts */
u64 shortcut_bins_count = 1024; u64 shortcut_bins_count = 1024;
PP_ShortcutBin *shortcut_bins = PushStructs(perm, PP_ShortcutBin, shortcut_bins_count); V_ShortcutBin *shortcut_bins = PushStructs(perm, V_ShortcutBin, shortcut_bins_count);
{ {
for (u64 desc_idx = 1; desc_idx < countof(PP_vis_cmd_descs); ++desc_idx) for (u64 desc_idx = 1; desc_idx < countof(V_cmd_descs); ++desc_idx)
{ {
PP_VisCmdDesc desc = PP_vis_cmd_descs[desc_idx]; V_CmdDesc desc = V_cmd_descs[desc_idx];
for (u64 hotkey_idx = 0; hotkey_idx < countof(desc.default_hotkeys); ++hotkey_idx) for (u64 hotkey_idx = 0; hotkey_idx < countof(desc.default_hotkeys); ++hotkey_idx)
{ {
PP_Hotkey hotkey = desc.default_hotkeys[hotkey_idx]; V_Hotkey hotkey = desc.default_hotkeys[hotkey_idx];
if (hotkey.button == Button_None) if (hotkey.button == Button_None)
{ {
break; break;
@ -198,8 +64,8 @@ JobDef(PP_VisWorker, sig, job_id)
else else
{ {
u64 hotkey_hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey)); u64 hotkey_hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey));
PP_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count]; V_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
PP_Shortcut *shortcut = PushStruct(perm, PP_Shortcut); V_Shortcut *shortcut = PushStruct(perm, V_Shortcut);
shortcut->hotkey_hash = hotkey_hash; shortcut->hotkey_hash = hotkey_hash;
shortcut->hotkey = hotkey; shortcut->hotkey = hotkey;
shortcut->cmd_name = desc.name; shortcut->cmd_name = desc.name;
@ -238,7 +104,7 @@ JobDef(PP_VisWorker, sig, job_id)
Arena *ents_arena = AcquireArena(Gibi(64)); Arena *ents_arena = AcquireArena(Gibi(64));
PP_Ent *ents = ArenaFirst(ents_arena, PP_Ent); S_Ent *ents = ArenaFirst(ents_arena, S_Ent);
i64 tick = 0; i64 tick = 0;
@ -270,8 +136,8 @@ JobDef(PP_VisWorker, sig, job_id)
} }
/* Set widget theme */ /* Set widget theme */
PP_WidgetTheme theme = PP_GetWidgetTheme(); V_WidgetTheme theme = V_GetWidgetTheme();
PP_PushWidgetThemeStyles(theme); V_PushWidgetThemeStyles(theme);
UI_Push(ChildLayoutAxis, Axis_Y); UI_Push(ChildLayoutAxis, Axis_Y);
UI_Push(Width, UI_GROW(1, 0)); UI_Push(Width, UI_GROW(1, 0));
@ -282,35 +148,24 @@ JobDef(PP_VisWorker, sig, job_id)
////////////////////////////// //////////////////////////////
//- Pop sim output //- Pop sim output
PP_SimOutputState *sim_output = 0; S_OutputState *sim_output = 0;
LockTicketMutex(&shared->sim_output_back_tm); LockTicketMutex(&sim_shared->output_back_tm);
{ {
sim_output = &shared->sim_output_states[shared->sim_output_back_idx]; sim_output = &sim_shared->output_states[sim_shared->output_back_idx];
++shared->sim_output_back_idx; ++sim_shared->output_back_idx;
if (shared->sim_output_back_idx >= countof(shared->sim_output_states)) if (sim_shared->output_back_idx >= countof(sim_shared->output_states))
{ {
shared->sim_output_back_idx = 0; sim_shared->output_back_idx = 0;
}
}
UnlockTicketMutex(&shared->sim_output_back_tm);
{
PP_WorldNode *last = sim_output->last_world_node;
if (last && last->world.tick > tick)
{
ResetArena(ents_arena);
ents = PushStructsNoZero(ents_arena, PP_Ent, last->world.ents_count);
CopyStructs(ents, last->world.ents, last->world.ents_count);
tick = last->world.tick;
} }
} }
UnlockTicketMutex(&sim_shared->output_back_tm);
////////////////////////////// //////////////////////////////
//- Process controller events vis cmds //- Process controller events vis cmds
u64 cmds_count = 0; u64 cmds_count = 0;
PP_VisCmdNode *first_cmd_node = 0; V_CmdNode *first_cmd_node = 0;
PP_VisCmdNode *last_cmd_node = 0; V_CmdNode *last_cmd_node = 0;
for (u64 i = 0; i < window_frame.controller_events.count; ++i) for (u64 i = 0; i < window_frame.controller_events.count; ++i)
{ {
@ -319,15 +174,15 @@ JobDef(PP_VisWorker, sig, job_id)
b32 up = cev.kind == ControllerEventKind_ButtonUp; b32 up = cev.kind == ControllerEventKind_ButtonUp;
if (down || up) if (down || up)
{ {
PP_Hotkey hotkey = ZI; V_Hotkey hotkey = ZI;
hotkey.button = cev.button; hotkey.button = cev.button;
hotkey.ctrl = held_buttons[Button_Ctrl]; hotkey.ctrl = held_buttons[Button_Ctrl];
hotkey.shift = held_buttons[Button_Shift]; hotkey.shift = held_buttons[Button_Shift];
hotkey.alt = held_buttons[Button_Alt]; hotkey.alt = held_buttons[Button_Alt];
{ {
u64 hotkey_hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey)); u64 hotkey_hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey));
PP_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count]; V_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
PP_Shortcut *shortcut = bin->first; V_Shortcut *shortcut = bin->first;
for (; shortcut; shortcut = shortcut->next_in_bin) for (; shortcut; shortcut = shortcut->next_in_bin)
{ {
if (shortcut->hotkey_hash == hotkey_hash && MatchStruct(&shortcut->hotkey, &hotkey)) if (shortcut->hotkey_hash == hotkey_hash && MatchStruct(&shortcut->hotkey, &hotkey))
@ -337,7 +192,7 @@ JobDef(PP_VisWorker, sig, job_id)
} }
if (shortcut != 0 && down) if (shortcut != 0 && down)
{ {
PP_VisCmdNode *cmd_node = PushStruct(frame_arena, PP_VisCmdNode); V_CmdNode *cmd_node = PushStruct(frame_arena, V_CmdNode);
cmd_node->cmd.name = shortcut->cmd_name; cmd_node->cmd.name = shortcut->cmd_name;
SllQueuePush(first_cmd_node, last_cmd_node, cmd_node); SllQueuePush(first_cmd_node, last_cmd_node, cmd_node);
++cmds_count; ++cmds_count;
@ -352,20 +207,20 @@ JobDef(PP_VisWorker, sig, job_id)
if (persist.show_command_palette) if (persist.show_command_palette)
{ {
PP_BeginCommandsWidget(&persist.commands_widget); V_BeginCommandsWidget(&persist.commands_widget);
{ {
for (u64 i = 0; i < countof(PP_vis_cmd_descs); ++i) for (u64 i = 0; i < countof(V_cmd_descs); ++i)
{ {
PP_VisCmdDesc desc = PP_vis_cmd_descs[i]; V_CmdDesc desc = V_cmd_descs[i];
if (!desc.flags & PP_VisCmdDescFlag_HideFromPalette) if (!desc.flags & V_CmdDescFlag_HideFromPalette)
{ {
PP_CommandsWidgetItemDesc item_desc = ZI; V_CommandsWidgetItemDesc item_desc = ZI;
item_desc.display_name = desc.display_name; item_desc.display_name = desc.display_name;
/* FIXME: Attach active shortcuts instead of default hotkeys */ /* FIXME: Attach active shortcuts instead of default hotkeys */
CopyStructs(item_desc.hotkeys, desc.default_hotkeys, MinU32(countof(item_desc.hotkeys), countof(desc.default_hotkeys))); CopyStructs(item_desc.hotkeys, desc.default_hotkeys, MinU32(countof(item_desc.hotkeys), countof(desc.default_hotkeys)));
if (PP_PushCommandsWidgetItem(&persist.commands_widget, item_desc).pressed > 0) if (V_PushCommandsWidgetItem(&persist.commands_widget, item_desc).pressed > 0)
{ {
PP_VisCmdNode *cmd_node = PushStruct(frame_arena, PP_VisCmdNode); V_CmdNode *cmd_node = PushStruct(frame_arena, V_CmdNode);
cmd_node->cmd.name = desc.name; cmd_node->cmd.name = desc.name;
SllQueuePush(first_cmd_node, last_cmd_node, cmd_node); SllQueuePush(first_cmd_node, last_cmd_node, cmd_node);
++cmds_count; ++cmds_count;
@ -373,7 +228,7 @@ JobDef(PP_VisWorker, sig, job_id)
} }
} }
} }
PP_EndCommandsWidget(&persist.commands_widget); V_EndCommandsWidget(&persist.commands_widget);
} }
////////////////////////////// //////////////////////////////
@ -382,21 +237,21 @@ JobDef(PP_VisWorker, sig, job_id)
if (persist.show_console) if (persist.show_console)
{ {
b32 minimized = 0; b32 minimized = 0;
PP_BuildConsoleWidget(minimized); V_BuildConsoleWidget(minimized);
} }
////////////////////////////// //////////////////////////////
//- Process vis commands //- Process vis commands
PP_EntList spawn_ents = ZI; S_EntList spawn_ents = ZI;
for (PP_VisCmdNode *cmd_node = first_cmd_node; cmd_node; cmd_node = cmd_node->next) for (V_CmdNode *cmd_node = first_cmd_node; cmd_node; cmd_node = cmd_node->next)
{ {
String cmd_name = cmd_node->cmd.name; String cmd_name = cmd_node->cmd.name;
PP_VisCmdKind kind = PP_VisCmdKind_nop; V_CmdKind kind = V_CmdKind_nop;
for (PP_VisCmdKind tmp_kind = PP_VisCmdKind_nop; tmp_kind < PP_VisCmdKind_Count; ++tmp_kind) for (V_CmdKind tmp_kind = V_CmdKind_nop; tmp_kind < V_CmdKind_Count; ++tmp_kind)
{ {
PP_VisCmdDesc desc = PP_vis_cmd_descs[tmp_kind]; V_CmdDesc desc = V_cmd_descs[tmp_kind];
if (MatchString(desc.name, cmd_name)) if (MatchString(desc.name, cmd_name))
{ {
kind = tmp_kind; kind = tmp_kind;
@ -406,22 +261,22 @@ JobDef(PP_VisWorker, sig, job_id)
switch (kind) switch (kind)
{ {
case PP_VisCmdKind_exit_program: case V_CmdKind_exit_program:
{ {
SignalExit(0); SignalExit(0);
} break; } break;
case PP_VisCmdKind_toggle_command_palette: case V_CmdKind_toggle_command_palette:
{ {
persist.show_command_palette = !persist.show_command_palette; persist.show_command_palette = !persist.show_command_palette;
} break; } break;
case PP_VisCmdKind_toggle_ui_debug: case V_CmdKind_toggle_ui_debug:
{ {
persist.ui_debug = !persist.ui_debug; persist.ui_debug = !persist.ui_debug;
} break; } break;
case PP_VisCmdKind_toggle_console: case V_CmdKind_toggle_console:
{ {
b32 new = !persist.show_console; b32 new = !persist.show_console;
if (new) if (new)
@ -431,23 +286,23 @@ JobDef(PP_VisWorker, sig, job_id)
persist.show_console = new; persist.show_console = new;
} break; } break;
case PP_VisCmdKind_toggle_fullscreen: case V_CmdKind_toggle_fullscreen:
{ {
b32 new = !window_frame.fullscreen; b32 new = !window_frame.fullscreen;
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetFullscreen, .v = new); WND_PushCmd(window_frame, .kind = WND_CmdKind_SetFullscreen, .v = new);
LogInfoF("Toggled fullscreen: %F", FmtSint(new)); LogInfoF("Toggled fullscreen: %F", FmtSint(new));
} break; } break;
case PP_VisCmdKind_toggle_window_topmost: case V_CmdKind_toggle_window_topmost:
{ {
b32 new = !window_frame.forced_top; b32 new = !window_frame.forced_top;
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = new); WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = new);
LogInfoF("Toggled topmost: %F", FmtSint(new)); LogInfoF("Toggled topmost: %F", FmtSint(new));
} break; } break;
case PP_VisCmdKind_spawn: case V_CmdKind_spawn:
{ {
PP_EntListNode *n = PushStruct(frame_arena, PP_EntListNode); S_EntListNode *n = PushStruct(frame_arena, S_EntListNode);
++spawn_ents.count; ++spawn_ents.count;
SllQueuePush(spawn_ents.first, spawn_ents.last, n); SllQueuePush(spawn_ents.first, spawn_ents.last, n);
} break; } break;
@ -457,19 +312,19 @@ JobDef(PP_VisWorker, sig, job_id)
////////////////////////////// //////////////////////////////
//- Submit sim commands //- Submit sim commands
LockTicketMutex(&shared->sim_input_back_tm); LockTicketMutex(&sim_shared->input_back_tm);
{ {
PP_SimInputState *v2s = &shared->sim_input_states[shared->sim_input_back_idx]; S_InputState *v2s = &sim_shared->input_states[sim_shared->input_back_idx];
for (PP_EntListNode *ent_node = spawn_ents.first; ent_node; ent_node = ent_node->next) for (S_EntListNode *ent_node = spawn_ents.first; ent_node; ent_node = ent_node->next)
{ {
PP_SimCmdNode *cmd_node = PushStruct(v2s->arena, PP_SimCmdNode); S_CmdNode *cmd_node = PushStruct(v2s->arena, S_CmdNode);
cmd_node->cmd.kind = PP_SimCmdKind_Ent; cmd_node->cmd.kind = S_CmdKind_Ent;
cmd_node->cmd.ent = ent_node->ent; cmd_node->cmd.ent = ent_node->ent;
SllQueuePush(v2s->first_cmd_node, v2s->last_cmd_node, cmd_node); SllQueuePush(v2s->first_cmd_node, v2s->last_cmd_node, cmd_node);
++v2s->cmds_count; ++v2s->cmds_count;
} }
} }
UnlockTicketMutex(&shared->sim_input_back_tm); UnlockTicketMutex(&sim_shared->input_back_tm);
////////////////////////////// //////////////////////////////
//- End vis frame //- End vis frame
@ -477,7 +332,7 @@ JobDef(PP_VisWorker, sig, job_id)
gpu_fence_target = UI_EndFrame(ui_frame); gpu_fence_target = UI_EndFrame(ui_frame);
++frame_gen; ++frame_gen;
shutdown = Atomic32Fetch(&shared->shutdown); shutdown = Atomic32Fetch(&vis_shared->shutdown);
} }
////////////////////////////// //////////////////////////////

View File

@ -0,0 +1,98 @@
////////////////////////////////////////////////////////////
//~ Command table
#define V_CmdsTableXMacro(X) \
X(nop, NOP, V_CmdDescFlag_HideFromPalette, V_HOTKEY(0), ) \
X(exit_program, Exit Program, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_Esc ) ) \
X(toggle_command_palette, Toggle Command Palette, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_P, .ctrl = 1, .shift = 1 ), ) \
X(toggle_ui_debug, Toggle UI Debug, V_CmdDescFlag_None, V_HOTKEY( Button_F5 ), ) \
X(toggle_console, Toggle Developer Console, V_CmdDescFlag_None, V_HOTKEY( Button_GraveAccent ), ) \
X(toggle_fullscreen, Toggle Fullscreen Mode, V_CmdDescFlag_None, V_HOTKEY( Button_Enter, .alt = 1 ), V_HOTKEY( Button_F11 ) ) \
X(toggle_window_topmost, Toggle Window Topmost, V_CmdDescFlag_None, V_HOTKEY( Button_F4 ), ) \
X(spawn, Spawn, V_CmdDescFlag_None, V_HOTKEY( Button_S, .ctrl = 1 ), ) \
/* -------------------------------------------------------------------------------------------------------------------- */
////////////////////////////////////////////////////////////
//~ Command types
Enum(V_CmdKind)
{
#define X(name, ...) V_CmdKind_##name,
V_CmdsTableXMacro(X)
#undef X
V_CmdKind_Count,
};
Struct(V_Shortcut)
{
V_Shortcut *next_in_bin;
V_Shortcut *prev_in_bin;
u64 hotkey_hash;
V_Hotkey hotkey;
String cmd_name;
};
Struct(V_ShortcutBin)
{
V_Shortcut *first;
V_Shortcut *last;
};
Enum(V_CmdDescFlag)
{
V_CmdDescFlag_None = 0,
V_CmdDescFlag_HideFromPalette = (1 << 0),
};
Struct(V_CmdDesc)
{
String name;
String display_name;
V_CmdDescFlag flags;
V_Hotkey default_hotkeys[8];
};
Struct(V_Cmd)
{
String name;
};
Struct(V_CmdNode)
{
V_CmdNode *next;
V_Cmd cmd;
};
Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_Count] = {
#define X(_name, _display_name, _flags, ...) { .name = CompLit(#_name), .display_name = CompLit(#_display_name), .flags = _flags, .default_hotkeys = { __VA_ARGS__ } },
V_CmdsTableXMacro(X)
#undef X
};
////////////////////////////////////////////////////////////
//~ State types
Struct(V_SharedState)
{
Atomic32 shutdown;
Fence worker_completion_fence;
i64 workers_count;
} extern V_shared_state;
////////////////////////////////////////////////////////////
//~ Startup
void V_Startup(void);
void V_Shutdown(void);
////////////////////////////////////////////////////////////
//~ Hotkey helpers
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey);
////////////////////////////////////////////////////////////
//~ Vis worker
JobDecl(V_VisWorker, EmptySig);

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,11 +1,11 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Theme helpers //~ Theme helpers
PP_WidgetTheme PP_GetWidgetTheme(void) V_WidgetTheme V_GetWidgetTheme(void)
{ {
PP_WidgetTheme theme = ZI; V_WidgetTheme theme = ZI;
theme.font = ResourceKeyFromStore(&PP_Resources, Lit("font/fixedsys.ttf")); theme.font = ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf"));
theme.font_size = 16; theme.font_size = 16;
theme.window_background_color = Rgb32(0xff1a1d1e); theme.window_background_color = Rgb32(0xff1a1d1e);
@ -22,7 +22,7 @@ PP_WidgetTheme PP_GetWidgetTheme(void)
return theme; return theme;
} }
void PP_PushWidgetThemeStyles(PP_WidgetTheme theme) void V_PushWidgetThemeStyles(V_WidgetTheme theme)
{ {
UI_Push(Font, theme.font); UI_Push(Font, theme.font);
UI_Push(FontSize, theme.font_size); UI_Push(FontSize, theme.font_size);
@ -31,7 +31,7 @@ void PP_PushWidgetThemeStyles(PP_WidgetTheme theme)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Hotkey helpers //~ Hotkey helpers
String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey) String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey)
{ {
TempArena scratch = BeginScratch(arena); TempArena scratch = BeginScratch(arena);
StringList parts = ZI; StringList parts = ZI;
@ -54,27 +54,27 @@ String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Commands widget //~ Commands widget
void PP_BeginCommandsWidget(PP_CommandsWidget *widget) void V_BeginCommandsWidget(V_CommandsWidget *widget)
{ {
ZeroStruct(&widget->build); ZeroStruct(&widget->build);
widget->build.cp = UI_PushCP(UI_NilKey); widget->build.cp = UI_PushCP(UI_NilKey);
UI_Push(Tag, HashF("commands widget")); UI_Push(Tag, HashF("commands widget"));
} }
PP_CommandsWidgetItemReport PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, PP_CommandsWidgetItemDesc desc) V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc)
{ {
Arena *frame_arena = UI_FrameArena(); Arena *frame_arena = UI_FrameArena();
UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items)); UI_Key key = UI_KeyF("btn%F", FmtSint(widget->build.num_items));
{ {
PP_CommandsWidgetItem *item = PushStruct(frame_arena, PP_CommandsWidgetItem); V_CommandsWidgetItem *item = PushStruct(frame_arena, V_CommandsWidgetItem);
item->key = key; item->key = key;
item->desc = desc; item->desc = desc;
SllQueuePush(widget->build.first_item, widget->build.last_item, item); SllQueuePush(widget->build.first_item, widget->build.last_item, item);
++widget->build.num_items; ++widget->build.num_items;
} }
PP_CommandsWidgetItemReport result = ZI; V_CommandsWidgetItemReport result = ZI;
UI_Report rep = UI_ReportFromKey(key); UI_Report rep = UI_ReportFromKey(key);
result.ui_report = rep; result.ui_report = rep;
result.pressed = rep.m1_presses > 0; result.pressed = rep.m1_presses > 0;
@ -82,9 +82,9 @@ PP_CommandsWidgetItemReport PP_PushCommandsWidgetItem(PP_CommandsWidget *widget,
return result; return result;
} }
void PP_EndCommandsWidget(PP_CommandsWidget *widget) void V_EndCommandsWidget(V_CommandsWidget *widget)
{ {
PP_WidgetTheme theme = PP_GetWidgetTheme(); V_WidgetTheme theme = V_GetWidgetTheme();
Vec2 cursor_pos = UI_CursorPos(); Vec2 cursor_pos = UI_CursorPos();
UI_Push(Tag, HashF("commands widget")); UI_Push(Tag, HashF("commands widget"));
@ -163,7 +163,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
UI_SetNext(Width, UI_GROW(1, 0)); UI_SetNext(Width, UI_GROW(1, 0));
UI_PushCP(UI_BuildColumn()); UI_PushCP(UI_BuildColumn());
{ {
for (PP_CommandsWidgetItem *item = widget->build.first_item; item; item = item->next) for (V_CommandsWidgetItem *item = widget->build.first_item; item; item = item->next)
{ {
UI_BuildDivider(UI_PIX(1, 1), theme.divider_color, Axis_Y); UI_BuildDivider(UI_PIX(1, 1), theme.divider_color, Axis_Y);
@ -229,7 +229,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
hotkey_border_color = BlendSrgb(hotkey_border_color, Rgb32(0x0078a6), hotkey_hot); hotkey_border_color = BlendSrgb(hotkey_border_color, Rgb32(0x0078a6), hotkey_hot);
} }
PP_Hotkey hotkey = item->desc.hotkeys[i]; V_Hotkey hotkey = item->desc.hotkeys[i];
if (hotkey.button == Button_None) if (hotkey.button == Button_None)
{ {
break; break;
@ -238,7 +238,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
{ {
UI_BuildSpacer(UI_PIX(10, 1), Axis_X); UI_BuildSpacer(UI_PIX(10, 1), Axis_X);
String hotkey_name = PP_StringFromHotkey(UI_FrameArena(), hotkey); String hotkey_name = V_StringFromHotkey(UI_FrameArena(), hotkey);
UI_SetNext(BackgroundColor, hotkey_color); UI_SetNext(BackgroundColor, hotkey_color);
UI_SetNext(BorderColor, hotkey_border_color); UI_SetNext(BorderColor, hotkey_border_color);
UI_SetNext(Text, hotkey_name); UI_SetNext(Text, hotkey_name);
@ -277,7 +277,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Console widget //~ Console widget
UI_Key PP_BuildConsoleWidget(b32 minimized) UI_Key V_BuildConsoleWidget(b32 minimized)
{ {
/* TODO: Remove this whole thing */ /* TODO: Remove this whole thing */
__prof; __prof;

View File

@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Theme types //~ Theme types
Struct(PP_WidgetTheme) Struct(V_WidgetTheme)
{ {
ResourceKey font; ResourceKey font;
f32 font_size; f32 font_size;
@ -21,8 +21,8 @@ Struct(PP_WidgetTheme)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Hotkey types //~ Hotkey types
#define PP_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ } #define V_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ }
Struct(PP_Hotkey) Struct(V_Hotkey)
{ {
Button button; Button button;
b32 ctrl; b32 ctrl;
@ -33,28 +33,28 @@ Struct(PP_Hotkey)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Commands widget types //~ Commands widget types
Struct(PP_CommandsWidgetItemReport) Struct(V_CommandsWidgetItemReport)
{ {
b32 pressed; b32 pressed;
b32 hotkey_changed; b32 hotkey_changed;
UI_Report ui_report; UI_Report ui_report;
PP_Hotkey new_hotkeys[8]; V_Hotkey new_hotkeys[8];
}; };
Struct(PP_CommandsWidgetItemDesc) Struct(V_CommandsWidgetItemDesc)
{ {
String display_name; String display_name;
PP_Hotkey hotkeys[8]; V_Hotkey hotkeys[8];
}; };
Struct(PP_CommandsWidgetItem) Struct(V_CommandsWidgetItem)
{ {
PP_CommandsWidgetItem *next; V_CommandsWidgetItem *next;
UI_Key key; UI_Key key;
PP_CommandsWidgetItemDesc desc; V_CommandsWidgetItemDesc desc;
}; };
Struct(PP_CommandsWidget) Struct(V_CommandsWidget)
{ {
/* Persistent state */ /* Persistent state */
Vec2 pos; Vec2 pos;
@ -63,8 +63,8 @@ Struct(PP_CommandsWidget)
struct struct
{ {
UI_Checkpoint cp; UI_Checkpoint cp;
PP_CommandsWidgetItem *first_item; V_CommandsWidgetItem *first_item;
PP_CommandsWidgetItem *last_item; V_CommandsWidgetItem *last_item;
u64 num_items; u64 num_items;
} build; } build;
}; };
@ -72,22 +72,22 @@ Struct(PP_CommandsWidget)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Theme helpers //~ Theme helpers
PP_WidgetTheme PP_GetWidgetThemeStyles(void); V_WidgetTheme V_GetWidgetThemeStyles(void);
void PP_PushWidgetTheme(PP_WidgetTheme theme); void V_PushWidgetTheme(V_WidgetTheme theme);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Hotkey helpers //~ Hotkey helpers
String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey); String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Commands widget //~ Commands widget
void PP_BeginCommandsWidget(PP_CommandsWidget *widget); void V_BeginCommandsWidget(V_CommandsWidget *widget);
PP_CommandsWidgetItemReport PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, PP_CommandsWidgetItemDesc desc); V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc);
void PP_EndCommandsWidget(PP_CommandsWidget *widget); void V_EndCommandsWidget(V_CommandsWidget *widget);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Console widget //~ Console widget
UI_Key PP_BuildConsoleWidget(b32 minimized); UI_Key V_BuildConsoleWidget(b32 minimized);