Lumenarium/src/foldhaus_operation_mode.h

84 lines
2.8 KiB
C
Raw Normal View History

2019-11-01 12:46:40 +00:00
typedef struct operation_mode operation_mode;
2019-12-28 19:31:21 +00:00
#define OPERATION_STATE_DEF(name) struct name
2019-11-01 14:38:44 +00:00
#define OPERATION_RENDER_PROC(name) void name(app_state* State, render_command_buffer* RenderBuffer, operation_mode Operation, mouse_state Mouse)
2019-11-01 12:46:40 +00:00
typedef OPERATION_RENDER_PROC(operation_render_proc);
struct operation_mode
{
input_command_registry Commands;
2019-11-01 12:46:40 +00:00
operation_render_proc* Render;
u8* OpStateMemory;
};
#define OPERATION_MODES_MAX 32
struct operation_mode_system
{
s32 ActiveModesCount;
operation_mode ActiveModes[OPERATION_MODES_MAX];
2019-11-01 12:46:40 +00:00
arena_snapshot ModeMemorySnapshots[OPERATION_MODES_MAX];
// NOTE(Peter): This acts as mode scoped memory. When a mode gets activated, it can allocate
// temporary memory which then gets freed when the mode is deactivated
memory_arena Arena;
};
2019-11-01 12:46:40 +00:00
internal operation_mode*
2019-12-28 19:31:21 +00:00
ActivateOperationMode (operation_mode_system* System, operation_render_proc* RenderProc)
{
2019-12-28 19:31:21 +00:00
operation_mode* Result = 0;
Assert(System->ActiveModesCount < OPERATION_MODES_MAX);
2019-11-01 12:46:40 +00:00
s32 ModeIndex = System->ActiveModesCount++;
System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(&System->Arena);
operation_mode NewMode = {};
System->ActiveModes[ModeIndex] = NewMode;
2019-12-28 19:31:21 +00:00
Result = &System->ActiveModes[ModeIndex];
Result->Render = RenderProc;
return Result;
}
2019-12-28 19:31:21 +00:00
#define ActivateOperationModeWithCommands(sys, cmds, render) \
ActivateOperationModeWithCommands_(sys, cmds, (s32)(sizeof(cmds) / sizeof(cmds[0])), render);
internal operation_mode*
2019-12-28 19:31:21 +00:00
ActivateOperationModeWithCommands_(operation_mode_system* System, input_command* Commands, s32 CommandsCount, operation_render_proc* RenderProc)
{
2019-12-28 19:31:21 +00:00
operation_mode* NewMode = ActivateOperationMode(System, RenderProc);
InitializeInputCommandRegistry(&NewMode->Commands, CommandsCount, &System->Arena);
for (s32 i = 0; i < CommandsCount; i++)
{
input_command Command = Commands[i];
RegisterKeyPressCommand(&NewMode->Commands, Command.Key, Command.Flags, Command.Mdfr, Command.Proc);
}
return NewMode;
}
internal void
DeactivateCurrentOperationMode (operation_mode_system* System)
{
Assert(System->ActiveModesCount > 0);
2019-11-01 12:46:40 +00:00
s32 ModeIndex = --System->ActiveModesCount;
ClearArenaToSnapshot(&System->Arena, System->ModeMemorySnapshots[ModeIndex]);
}
#define CreateOperationState(mode, modeSystem, stateType) \
(stateType*)CreateOperationState_(mode, modeSystem, sizeof(stateType))
#define GetCurrentOperationState(modeSystem, stateType) \
(stateType*)(modeSystem).ActiveModes[(modeSystem).ActiveModesCount - 1].OpStateMemory;
internal u8*
CreateOperationState_ (operation_mode* Mode, operation_mode_system* System, s32 StateSize)
{
Mode->OpStateMemory = PushSize(&System->Arena, StateSize);
return Mode->OpStateMemory;
}