move pp sim & vis into separate layers
This commit is contained in:
parent
cd40046afc
commit
391fc33a5e
@ -1,29 +1,4 @@
|
||||
@Layer proto
|
||||
|
||||
//- Dependencies
|
||||
@Dep gpu
|
||||
@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
|
||||
@Dep pp_sim
|
||||
@Dep pp_vis
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
@ -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);
|
||||
13
src/proto/pp_sim/pp_sim.lay
Normal file
13
src/proto/pp_sim/pp_sim.lay
Normal 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
|
||||
170
src/proto/pp_sim/pp_sim_core.c
Normal file
170
src/proto/pp_sim/pp_sim_core.c
Normal 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);
|
||||
}
|
||||
}
|
||||
165
src/proto/pp_sim/pp_sim_core.h
Normal file
165
src/proto/pp_sim/pp_sim_core.h
Normal 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);
|
||||
28
src/proto/pp_vis/pp_vis.lay
Normal file
28
src/proto/pp_vis/pp_vis.lay
Normal 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
|
||||
@ -1,168 +1,34 @@
|
||||
PP_SharedState PP_shared_state = ZI;
|
||||
V_SharedState V_shared_state = ZI;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Startup
|
||||
|
||||
void PP_Startup(void)
|
||||
void V_Startup(void)
|
||||
{
|
||||
PP_SharedState *shared = &PP_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));
|
||||
}
|
||||
V_SharedState *shared = &V_shared_state;
|
||||
|
||||
/* Create job pools */
|
||||
JobPoolId sim_pool = InitJobPool(1, Lit("Sim"), JobPoolPriority_Simulation);
|
||||
JobPoolId vis_pool = InitJobPool(1, Lit("Vis"), JobPoolPriority_Graphics);
|
||||
|
||||
/* Start jobs */
|
||||
shared->workers_count += RunJob(PP_SimWorker, .pool = sim_pool, .fence = &shared->worker_completion_fence);
|
||||
shared->workers_count += RunJob(PP_VisWorker, .pool = vis_pool, .fence = &shared->worker_completion_fence);
|
||||
OnExit(&PP_Shutdown);
|
||||
shared->workers_count += RunJob(V_VisWorker, .pool = vis_pool, .fence = &shared->worker_completion_fence);
|
||||
OnExit(&V_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);
|
||||
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
|
||||
|
||||
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 *perm = PermArena();
|
||||
|
||||
@ -171,7 +37,7 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
|
||||
Struct(VisPersist)
|
||||
{
|
||||
PP_CommandsWidget commands_widget;
|
||||
V_CommandsWidget commands_widget;
|
||||
b32 ui_debug;
|
||||
b32 show_command_palette;
|
||||
b32 show_console;
|
||||
@ -183,14 +49,14 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
|
||||
/* Init shortcuts */
|
||||
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)
|
||||
{
|
||||
PP_Hotkey hotkey = desc.default_hotkeys[hotkey_idx];
|
||||
V_Hotkey hotkey = desc.default_hotkeys[hotkey_idx];
|
||||
if (hotkey.button == Button_None)
|
||||
{
|
||||
break;
|
||||
@ -198,8 +64,8 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
else
|
||||
{
|
||||
u64 hotkey_hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey));
|
||||
PP_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
|
||||
PP_Shortcut *shortcut = PushStruct(perm, PP_Shortcut);
|
||||
V_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
|
||||
V_Shortcut *shortcut = PushStruct(perm, V_Shortcut);
|
||||
shortcut->hotkey_hash = hotkey_hash;
|
||||
shortcut->hotkey = hotkey;
|
||||
shortcut->cmd_name = desc.name;
|
||||
@ -238,7 +104,7 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -270,8 +136,8 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
}
|
||||
|
||||
/* Set widget theme */
|
||||
PP_WidgetTheme theme = PP_GetWidgetTheme();
|
||||
PP_PushWidgetThemeStyles(theme);
|
||||
V_WidgetTheme theme = V_GetWidgetTheme();
|
||||
V_PushWidgetThemeStyles(theme);
|
||||
|
||||
UI_Push(ChildLayoutAxis, Axis_Y);
|
||||
UI_Push(Width, UI_GROW(1, 0));
|
||||
@ -282,35 +148,24 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
//////////////////////////////
|
||||
//- Pop sim output
|
||||
|
||||
PP_SimOutputState *sim_output = 0;
|
||||
LockTicketMutex(&shared->sim_output_back_tm);
|
||||
S_OutputState *sim_output = 0;
|
||||
LockTicketMutex(&sim_shared->output_back_tm);
|
||||
{
|
||||
sim_output = &shared->sim_output_states[shared->sim_output_back_idx];
|
||||
++shared->sim_output_back_idx;
|
||||
if (shared->sim_output_back_idx >= countof(shared->sim_output_states))
|
||||
sim_output = &sim_shared->output_states[sim_shared->output_back_idx];
|
||||
++sim_shared->output_back_idx;
|
||||
if (sim_shared->output_back_idx >= countof(sim_shared->output_states))
|
||||
{
|
||||
shared->sim_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;
|
||||
sim_shared->output_back_idx = 0;
|
||||
}
|
||||
}
|
||||
UnlockTicketMutex(&sim_shared->output_back_tm);
|
||||
|
||||
//////////////////////////////
|
||||
//- Process controller events vis cmds
|
||||
|
||||
u64 cmds_count = 0;
|
||||
PP_VisCmdNode *first_cmd_node = 0;
|
||||
PP_VisCmdNode *last_cmd_node = 0;
|
||||
V_CmdNode *first_cmd_node = 0;
|
||||
V_CmdNode *last_cmd_node = 0;
|
||||
|
||||
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;
|
||||
if (down || up)
|
||||
{
|
||||
PP_Hotkey hotkey = ZI;
|
||||
V_Hotkey hotkey = ZI;
|
||||
hotkey.button = cev.button;
|
||||
hotkey.ctrl = held_buttons[Button_Ctrl];
|
||||
hotkey.shift = held_buttons[Button_Shift];
|
||||
hotkey.alt = held_buttons[Button_Alt];
|
||||
{
|
||||
u64 hotkey_hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey));
|
||||
PP_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
|
||||
PP_Shortcut *shortcut = bin->first;
|
||||
V_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
|
||||
V_Shortcut *shortcut = bin->first;
|
||||
for (; shortcut; shortcut = shortcut->next_in_bin)
|
||||
{
|
||||
if (shortcut->hotkey_hash == hotkey_hash && MatchStruct(&shortcut->hotkey, &hotkey))
|
||||
@ -337,7 +192,7 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
}
|
||||
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;
|
||||
SllQueuePush(first_cmd_node, last_cmd_node, cmd_node);
|
||||
++cmds_count;
|
||||
@ -352,20 +207,20 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
|
||||
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];
|
||||
if (!desc.flags & PP_VisCmdDescFlag_HideFromPalette)
|
||||
V_CmdDesc desc = V_cmd_descs[i];
|
||||
if (!desc.flags & V_CmdDescFlag_HideFromPalette)
|
||||
{
|
||||
PP_CommandsWidgetItemDesc item_desc = ZI;
|
||||
V_CommandsWidgetItemDesc item_desc = ZI;
|
||||
item_desc.display_name = desc.display_name;
|
||||
/* FIXME: Attach active shortcuts instead of 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;
|
||||
SllQueuePush(first_cmd_node, last_cmd_node, cmd_node);
|
||||
++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)
|
||||
{
|
||||
b32 minimized = 0;
|
||||
PP_BuildConsoleWidget(minimized);
|
||||
V_BuildConsoleWidget(minimized);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- 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;
|
||||
PP_VisCmdKind kind = PP_VisCmdKind_nop;
|
||||
for (PP_VisCmdKind tmp_kind = PP_VisCmdKind_nop; tmp_kind < PP_VisCmdKind_Count; ++tmp_kind)
|
||||
V_CmdKind kind = V_CmdKind_nop;
|
||||
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))
|
||||
{
|
||||
kind = tmp_kind;
|
||||
@ -406,22 +261,22 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case PP_VisCmdKind_exit_program:
|
||||
case V_CmdKind_exit_program:
|
||||
{
|
||||
SignalExit(0);
|
||||
} break;
|
||||
|
||||
case PP_VisCmdKind_toggle_command_palette:
|
||||
case V_CmdKind_toggle_command_palette:
|
||||
{
|
||||
persist.show_command_palette = !persist.show_command_palette;
|
||||
} break;
|
||||
|
||||
case PP_VisCmdKind_toggle_ui_debug:
|
||||
case V_CmdKind_toggle_ui_debug:
|
||||
{
|
||||
persist.ui_debug = !persist.ui_debug;
|
||||
} break;
|
||||
|
||||
case PP_VisCmdKind_toggle_console:
|
||||
case V_CmdKind_toggle_console:
|
||||
{
|
||||
b32 new = !persist.show_console;
|
||||
if (new)
|
||||
@ -431,23 +286,23 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
persist.show_console = new;
|
||||
} break;
|
||||
|
||||
case PP_VisCmdKind_toggle_fullscreen:
|
||||
case V_CmdKind_toggle_fullscreen:
|
||||
{
|
||||
b32 new = !window_frame.fullscreen;
|
||||
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetFullscreen, .v = new);
|
||||
LogInfoF("Toggled fullscreen: %F", FmtSint(new));
|
||||
} break;
|
||||
|
||||
case PP_VisCmdKind_toggle_window_topmost:
|
||||
case V_CmdKind_toggle_window_topmost:
|
||||
{
|
||||
b32 new = !window_frame.forced_top;
|
||||
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = new);
|
||||
LogInfoF("Toggled topmost: %F", FmtSint(new));
|
||||
} 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;
|
||||
SllQueuePush(spawn_ents.first, spawn_ents.last, n);
|
||||
} break;
|
||||
@ -457,19 +312,19 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
//////////////////////////////
|
||||
//- 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];
|
||||
for (PP_EntListNode *ent_node = spawn_ents.first; ent_node; ent_node = ent_node->next)
|
||||
S_InputState *v2s = &sim_shared->input_states[sim_shared->input_back_idx];
|
||||
for (S_EntListNode *ent_node = spawn_ents.first; ent_node; ent_node = ent_node->next)
|
||||
{
|
||||
PP_SimCmdNode *cmd_node = PushStruct(v2s->arena, PP_SimCmdNode);
|
||||
cmd_node->cmd.kind = PP_SimCmdKind_Ent;
|
||||
S_CmdNode *cmd_node = PushStruct(v2s->arena, S_CmdNode);
|
||||
cmd_node->cmd.kind = S_CmdKind_Ent;
|
||||
cmd_node->cmd.ent = ent_node->ent;
|
||||
SllQueuePush(v2s->first_cmd_node, v2s->last_cmd_node, cmd_node);
|
||||
++v2s->cmds_count;
|
||||
}
|
||||
}
|
||||
UnlockTicketMutex(&shared->sim_input_back_tm);
|
||||
UnlockTicketMutex(&sim_shared->input_back_tm);
|
||||
|
||||
//////////////////////////////
|
||||
//- End vis frame
|
||||
@ -477,7 +332,7 @@ JobDef(PP_VisWorker, sig, job_id)
|
||||
gpu_fence_target = UI_EndFrame(ui_frame);
|
||||
|
||||
++frame_gen;
|
||||
shutdown = Atomic32Fetch(&shared->shutdown);
|
||||
shutdown = Atomic32Fetch(&vis_shared->shutdown);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
98
src/proto/pp_vis/pp_vis_core.h
Normal file
98
src/proto/pp_vis/pp_vis_core.h
Normal 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);
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@ -1,11 +1,11 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ 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.window_background_color = Rgb32(0xff1a1d1e);
|
||||
@ -22,7 +22,7 @@ PP_WidgetTheme PP_GetWidgetTheme(void)
|
||||
return theme;
|
||||
}
|
||||
|
||||
void PP_PushWidgetThemeStyles(PP_WidgetTheme theme)
|
||||
void V_PushWidgetThemeStyles(V_WidgetTheme theme)
|
||||
{
|
||||
UI_Push(Font, theme.font);
|
||||
UI_Push(FontSize, theme.font_size);
|
||||
@ -31,7 +31,7 @@ void PP_PushWidgetThemeStyles(PP_WidgetTheme theme)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Hotkey helpers
|
||||
|
||||
String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey)
|
||||
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey)
|
||||
{
|
||||
TempArena scratch = BeginScratch(arena);
|
||||
StringList parts = ZI;
|
||||
@ -54,27 +54,27 @@ String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Commands widget
|
||||
|
||||
void PP_BeginCommandsWidget(PP_CommandsWidget *widget)
|
||||
void V_BeginCommandsWidget(V_CommandsWidget *widget)
|
||||
{
|
||||
ZeroStruct(&widget->build);
|
||||
widget->build.cp = UI_PushCP(UI_NilKey);
|
||||
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();
|
||||
|
||||
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->desc = desc;
|
||||
SllQueuePush(widget->build.first_item, widget->build.last_item, item);
|
||||
++widget->build.num_items;
|
||||
}
|
||||
|
||||
PP_CommandsWidgetItemReport result = ZI;
|
||||
V_CommandsWidgetItemReport result = ZI;
|
||||
UI_Report rep = UI_ReportFromKey(key);
|
||||
result.ui_report = rep;
|
||||
result.pressed = rep.m1_presses > 0;
|
||||
@ -82,9 +82,9 @@ PP_CommandsWidgetItemReport PP_PushCommandsWidgetItem(PP_CommandsWidget *widget,
|
||||
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();
|
||||
|
||||
UI_Push(Tag, HashF("commands widget"));
|
||||
@ -163,7 +163,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
|
||||
UI_SetNext(Width, UI_GROW(1, 0));
|
||||
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);
|
||||
|
||||
@ -229,7 +229,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
|
||||
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)
|
||||
{
|
||||
break;
|
||||
@ -238,7 +238,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
|
||||
{
|
||||
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(BorderColor, hotkey_border_color);
|
||||
UI_SetNext(Text, hotkey_name);
|
||||
@ -277,7 +277,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Console widget
|
||||
|
||||
UI_Key PP_BuildConsoleWidget(b32 minimized)
|
||||
UI_Key V_BuildConsoleWidget(b32 minimized)
|
||||
{
|
||||
/* TODO: Remove this whole thing */
|
||||
__prof;
|
||||
@ -1,7 +1,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Theme types
|
||||
|
||||
Struct(PP_WidgetTheme)
|
||||
Struct(V_WidgetTheme)
|
||||
{
|
||||
ResourceKey font;
|
||||
f32 font_size;
|
||||
@ -21,8 +21,8 @@ Struct(PP_WidgetTheme)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Hotkey types
|
||||
|
||||
#define PP_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ }
|
||||
Struct(PP_Hotkey)
|
||||
#define V_HOTKEY(_button, ...) { .button = _button, __VA_ARGS__ }
|
||||
Struct(V_Hotkey)
|
||||
{
|
||||
Button button;
|
||||
b32 ctrl;
|
||||
@ -33,28 +33,28 @@ Struct(PP_Hotkey)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Commands widget types
|
||||
|
||||
Struct(PP_CommandsWidgetItemReport)
|
||||
Struct(V_CommandsWidgetItemReport)
|
||||
{
|
||||
b32 pressed;
|
||||
b32 hotkey_changed;
|
||||
UI_Report ui_report;
|
||||
PP_Hotkey new_hotkeys[8];
|
||||
V_Hotkey new_hotkeys[8];
|
||||
};
|
||||
|
||||
Struct(PP_CommandsWidgetItemDesc)
|
||||
Struct(V_CommandsWidgetItemDesc)
|
||||
{
|
||||
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;
|
||||
PP_CommandsWidgetItemDesc desc;
|
||||
V_CommandsWidgetItemDesc desc;
|
||||
};
|
||||
|
||||
Struct(PP_CommandsWidget)
|
||||
Struct(V_CommandsWidget)
|
||||
{
|
||||
/* Persistent state */
|
||||
Vec2 pos;
|
||||
@ -63,8 +63,8 @@ Struct(PP_CommandsWidget)
|
||||
struct
|
||||
{
|
||||
UI_Checkpoint cp;
|
||||
PP_CommandsWidgetItem *first_item;
|
||||
PP_CommandsWidgetItem *last_item;
|
||||
V_CommandsWidgetItem *first_item;
|
||||
V_CommandsWidgetItem *last_item;
|
||||
u64 num_items;
|
||||
} build;
|
||||
};
|
||||
@ -72,22 +72,22 @@ Struct(PP_CommandsWidget)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Theme helpers
|
||||
|
||||
PP_WidgetTheme PP_GetWidgetThemeStyles(void);
|
||||
void PP_PushWidgetTheme(PP_WidgetTheme theme);
|
||||
V_WidgetTheme V_GetWidgetThemeStyles(void);
|
||||
void V_PushWidgetTheme(V_WidgetTheme theme);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Hotkey helpers
|
||||
|
||||
String PP_StringFromHotkey(Arena *arena, PP_Hotkey hotkey);
|
||||
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Commands widget
|
||||
|
||||
void PP_BeginCommandsWidget(PP_CommandsWidget *widget);
|
||||
PP_CommandsWidgetItemReport PP_PushCommandsWidgetItem(PP_CommandsWidget *widget, PP_CommandsWidgetItemDesc desc);
|
||||
void PP_EndCommandsWidget(PP_CommandsWidget *widget);
|
||||
void V_BeginCommandsWidget(V_CommandsWidget *widget);
|
||||
V_CommandsWidgetItemReport V_PushCommandsWidgetItem(V_CommandsWidget *widget, V_CommandsWidgetItemDesc desc);
|
||||
void V_EndCommandsWidget(V_CommandsWidget *widget);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Console widget
|
||||
|
||||
UI_Key PP_BuildConsoleWidget(b32 minimized);
|
||||
UI_Key V_BuildConsoleWidget(b32 minimized);
|
||||
Loading…
Reference in New Issue
Block a user