splink/source/os.c

326 lines
6.9 KiB
C

// TODO(allen): Changes durring this jam
// fix with os->event_count not resetting
////////////////////////////////
// NOTE(allen): Events
internal String8
KeyName(Key index)
{
local_persist char *strings[Key_Max] =
{
#define Key(name, str) str,
#include "os_key_list.inc"
#undef Key
};
char *string = "(Invalid Key)";
if(index >= 0 && index < ArrayCount(strings))
{
string = strings[index];
}
String8 result;
result.str = string;
result.size = CalculateCStringLength(result.str);
return result;
}
internal String8
GamepadButtonName(GamepadButton index)
{
local_persist char *strings[GamepadButton_Max] =
{
#define GamepadButton(name, str) str,
#include "os_gamepad_button_list.inc"
#undef GamepadButton
};
char *string = "(Invalid Gamepad Button)";
if(index >= 0 && index < ArrayCount(strings))
{
string = strings[index];
}
String8 result;
result.str = string;
result.size = CalculateCStringLength(result.str);
return result;
}
internal b32
OS_EventIsMouse(OS_Event *event)
{
return event->type > OS_EventType_MouseStart && event->type < OS_EventType_MouseEnd;
}
internal b32
OS_CompareEvents(OS_Event a, OS_Event b)
{
b32 result = 0;
if(a.type == b.type &&
a.key == b.key &&
a.mouse_button == b.mouse_button &&
a.gamepad_button == b.gamepad_button &&
a.character == b.character &&
a.modifiers == b.modifiers)
{
result = 1;
}
return result;
}
internal OS_Event
OS_KeyPressEvent(Key key, KeyModifiers modifiers)
{
OS_Event event =
{
.type = OS_EventType_KeyPress,
};
event.key = key;
event.modifiers = modifiers;
return event;
}
internal OS_Event
OS_KeyReleaseEvent(Key key, KeyModifiers modifiers)
{
OS_Event event =
{
.type = OS_EventType_KeyRelease,
};
event.key = key;
event.modifiers = modifiers;
return event;
}
internal OS_Event
OS_CharacterInputEvent(u64 character)
{
OS_Event event =
{
.type = OS_EventType_CharacterInput,
};
event.character = character;
return event;
}
internal OS_Event
OS_MouseMoveEvent(v2 position, v2 delta)
{
OS_Event event =
{
.type = OS_EventType_MouseMove,
};
event.position = position;
event.delta = delta;
return event;
}
internal OS_Event
OS_MousePressEvent(MouseButton button, v2 position)
{
OS_Event event =
{
.type = OS_EventType_MousePress,
};
event.mouse_button = button;
event.position = position;
return event;
}
internal OS_Event
OS_MouseReleaseEvent(MouseButton mouse_button, v2 position)
{
OS_Event event =
{
.type = OS_EventType_MouseRelease,
};
event.mouse_button = mouse_button;
event.position = position;
return event;
}
internal OS_Event
OS_MouseScrollEvent(v2 delta, KeyModifiers modifiers)
{
OS_Event event =
{
.type = OS_EventType_MouseScroll,
};
event.scroll = delta;
event.modifiers = modifiers;
return event;
}
internal b32
OS_GetNextEvent(OS_Event **event)
{
b32 result = 0;
Assert(os != 0);
u32 start_index = 0;
OS_Event *new_event = 0;
if(*event)
{
start_index = (*event - os->events) + 1;
}
for(u32 i = start_index; i < os->event_count; ++i)
{
if(os->events[i].type != OS_EventType_Null)
{
new_event = os->events+i;
break;
}
}
*event = new_event;
result = new_event != 0;
return result;
}
internal void
OS_EatEvent(OS_Event *event)
{
event->type = OS_EventType_Null;
}
// NOTE(rjf): Only called by platform layers. Do not call in app.
internal void
OS_BeginFrame(void)
{
os->pump_events = 0;
}
// NOTE(rjf): Only called by platform layers. Do not call in app.
internal void
OS_EndFrame(void)
{
os->current_time += 1.f / os->target_frames_per_second;
}
// NOTE(rjf): Only called by platform layers. Do not call in app.
internal void
OS_PushEvent(OS_Event event)
{
Assert(os != 0);
if(os->event_count < ArrayCount(os->events))
{
os->events[os->event_count++] = event;
}
}
////////////////////////////////
// NOTE(allen): Thread Context
internal OS_ArenaNode*
_OS_GetFreeScratch(OS_ThreadContext *tctx)
{
OS_ArenaNode *usable_node = tctx->free;
Assert(usable_node != 0);
SLLStackPop(tctx->free);
DLLPushBack(tctx->first_used, tctx->last_used, usable_node);
return(usable_node);
}
internal M_Arena*
_OS_MarkArenaRestore(OS_ArenaNode *node)
{
M_Arena *result = &node->arena;
OS_ArenaInlineRestore *restore = PushArray(result, OS_ArenaInlineRestore, 1);
SLLStackPush(node->restore, restore);
node->ref_count += 1;
return(result);
}
internal M_Arena*
OS_GetScratch(void)
{
OS_ThreadContext *tctx = os->GetThreadContext();
OS_ArenaNode *usable_node = tctx->first_used;
if (usable_node == 0)
{
usable_node = _OS_GetFreeScratch(tctx);
}
return(_OS_MarkArenaRestore(usable_node));
}
internal M_Arena*
OS_GetScratch1(M_Arena *a1)
{
OS_ThreadContext *tctx = os->GetThreadContext();
OS_ArenaNode *usable_node = 0;
for (OS_ArenaNode *node = tctx->first_used;
node != 0;
node = node->next)
{
if (&node->arena != a1)
{
usable_node = node;
break;
}
}
if (usable_node == 0)
{
usable_node = _OS_GetFreeScratch(tctx);
}
return(_OS_MarkArenaRestore(usable_node));
}
internal M_Arena*
OS_GetScratch2(M_Arena *a1, M_Arena *a2)
{
OS_ThreadContext *tctx = os->GetThreadContext();
OS_ArenaNode *usable_node = 0;
for (OS_ArenaNode *node = tctx->first_used;
node != 0;
node = node->next)
{
if (&node->arena != a1 && &node->arena != a2)
{
usable_node = node;
break;
}
}
if (usable_node == 0)
{
usable_node = _OS_GetFreeScratch(tctx);
}
return(_OS_MarkArenaRestore(usable_node));
}
internal void
OS_ReleaseScratch(M_Arena *arena)
{
OS_ArenaNode *node = CastFromMember(OS_ArenaNode, arena, arena);
Assert(node->ref_count > 0);
node->ref_count -= 1;
if (node->ref_count == 0)
{
OS_ThreadContext *tctx = os->GetThreadContext();
DLLRemove(tctx->first_used, tctx->last_used, node);
M_ArenaClear(arena);
SLLStackPush(tctx->free, node);
}
else
{
void *ptr = node->restore;
node->restore = node->restore->next;
M_ArenaSetPosBackByPtr(arena, ptr);
}
}
internal void
_OS_ThreadSaveFileLine(char *file_name, u64 line_number)
{
OS_ThreadContext *tctx = os->GetThreadContext();
tctx->file_name = file_name;
tctx->line_number = line_number;
}
#define OS_ThreadSaveFileLine() _OS_ThreadSaveFileLine(__FILE__, __LINE__)
internal OS_File_Line
OS_ThreadRememberFileLine(void)
{
OS_ThreadContext *tctx = os->GetThreadContext();
OS_File_Line result = {tctx->file_name, tctx->line_number};
return(result);
}