Started implementing character state

main
sixtenhugosson 2023-09-13 06:42:11 +02:00
parent 41c1f17158
commit 10c5793a1d
14 changed files with 171 additions and 92 deletions

View File

@ -10,6 +10,7 @@ static void Copy(void *Dest, void *Source, umm Count);
static void CopyReverse(void *Dest, void *Source, umm Count);
static void Fill(void *Dest, u8 Value, umm Count);
#define Move(Dest, Source, Count) memmove(Dest, Source, Count)
#define ZeroStruct(Struct) Fill(Struct, 0, sizeof(*(Struct)))
////////////////////////////////
//- sixten: Memory Arena Types

View File

@ -166,7 +166,7 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender)
//- sixten: build the ui
UI_BeginBuild(RenderCommands->RenderDim);
{
b32 EditorMode = true;
b32 EditorMode = false;
if(EditorMode)
{
W_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas);
@ -206,9 +206,9 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender)
if(DEBUG_DebugSettings->ListHotAndActive)
{
PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 20), 15, Color_Grey,
PushFormat(State->UI.FrameArena, "Hot: %S:%llu", UI_GetBoxNameByKey(UI_GetHot()), UI_GetHot()));
PushFormat(State->UI.FrameArena, "Hot: %S:%llu", UI_BoxStringFromKey(UI_HotKey()), UI_HotKey()));
PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 40), 15, Color_Grey,
PushFormat(State->UI.FrameArena, "Active: %S:%llu", UI_GetBoxNameByKey(UI_GetActive()), UI_GetActive()));
PushFormat(State->UI.FrameArena, "Active: %S:%llu", UI_BoxStringFromKey(UI_ActiveKey()), UI_ActiveKey()));
}
}
}

View File

@ -1,5 +1,63 @@
global character_registry *Global_CharacterRegistry = 0;
////////////////////////////////
//~ sixten: Character String Chunk Functions
static character_string_list CR_CharacterStringListAlloc(character_registry *Registry, string String)
{
character_string_list Result = {};
s64 ChunksNeeded = (String.Count + CHARACTER_STRING_CHUNK_DATA_SIZE - 1) / CHARACTER_STRING_CHUNK_DATA_SIZE;
s64 BytesLeft = String.Count;
u64 StringIndex = 0;
for(s64 ChunkIndex = 0; ChunkIndex < ChunksNeeded; ChunkIndex += 1)
{
character_string_chunk *Chunk = Registry->FirstFreeChunk;
if(Chunk)
{
Registry->FirstFreeChunk = Chunk->Next;
}
else
{
Chunk = PushStructNoClear(Registry->StringArena, character_string_chunk);
}
u64 ToCopy = Min(BytesLeft, CHARACTER_STRING_CHUNK_DATA_SIZE);
Copy(Chunk->Data, String.Data+StringIndex, ToCopy);
QueuePush(Result.First, Result.Last, Chunk);
Result.ChunkCount += 1;
Result.StringCount += ToCopy;
BytesLeft -= ToCopy;
StringIndex += ToCopy;
}
return(Result);
}
static character_string_list CR_CharacterStringListRelease(character_registry *Registry, character_string_list *List)
{
for(character_string_chunk *Chunk = List->First, *Next = 0; Chunk != 0; Chunk = Next)
{
Next = Chunk->Next;
Chunk->Next = Registry->FirstFreeChunk;
Registry->FirstFreeChunk = Chunk;
}
ZeroStruct(List);
}
static string CR_StringFromList(memory_arena *Arena, character_string_list *List)
{
string Result;
Result.Count = List->StringCount;
Result.Data = PushArrayNoClear(Arena, u8, Result.Count);
s64 StringIndex = 0;
s64 BytesLeft = List->StringCount;
for(character_string_chunk *Chunk = List->First; Chunk != 0; Chunk = Chunk->Next)
{
s64 ToCopy = Min(BytesLeft, CHARACTER_STRING_CHUNK_DATA_SIZE);
Copy(Result.Data+StringIndex, Chunk->Data, ToCopy);
StringIndex += ToCopy;
BytesLeft -= ToCopy;
}
return(Result);
}
////////////////////////////////
//~ sixten: Character Registry Functions
static void CR_SetState(character_registry *State)
@ -14,9 +72,7 @@ static character_registry *CR_GetState(void)
static character_list CR_GetCharacters(void)
{
character_registry *Registry = CR_GetState();
character_list List = Registry->Characters;
return(List);
return(CR_GetState()->Characters);
}
static void CR_Init(character_registry *State)

View File

@ -3,6 +3,25 @@
#ifndef VN_CHARACTER_H
#define VN_CHARACTER_H
////////////////////////////////
//~ sixten: Character String Chunk Types
#define CHARACTER_STRING_CHUNK_DATA_SIZE (64 - sizeof(character_string_chunk *))
struct character_string_chunk
{
character_string_chunk *Next;
u8 Data[CHARACTER_STRING_CHUNK_DATA_SIZE];
};
CTAssert(sizeof(character_string_chunk) == 64);
struct character_string_list
{
character_string_chunk *First;
character_string_chunk *Last;
u64 ChunkCount;
s64 StringCount;
};
////////////////////////////////
//~ sixten: Character Registry Types
struct character_entry
@ -24,8 +43,16 @@ struct character_registry
{
memory_arena *Arena;
character_list Characters;
memory_arena *StringArena;
character_string_chunk *FirstFreeChunk;
};
////////////////////////////////
//~ sixten: Character String Chunk Functions
static character_string_list CR_CharacterStringListAlloc(character_registry *Registry, string String);
static character_string_list CR_CharacterStringListRelease(character_registry *Registry, character_string_list *List);
static string CR_StringFromList(memory_arena *Arena, character_string_list *List);
////////////////////////////////
//~ sixten: Character Registry Functions

View File

@ -188,7 +188,6 @@ struct vn_input
struct vn_memory
{
platform_api PlatformAPI;
struct vn_state *State;
};

View File

@ -230,6 +230,22 @@ static void S_ParseDeclaration(scene_compiler *Compiler)
Compiler->At += 1;
S_ParseBranchStatement(Compiler);
} break;
case TokenKind_At:
{
Compiler->At += 1;
token IdentifierToken = S_ConsumeToken(Compiler, TokenKind_Identifier, "Expected identifier after '@'");
if(Compiler->At->Kind == TokenKind_ParenthesisOpen)
{
Compiler->At += 1;
token StateToken = S_ConsumeToken(Compiler, TokenKind_Identifier, "Expected character state.");
S_ConsumeToken(Compiler, TokenKind_ParenthesisClose, "Expected ')' after character state.");
}
else
{
}
} break;
case TokenKind_StringLiteral:
{
S_ParseExpression(Compiler);

View File

@ -66,6 +66,8 @@ enum scene_opcode
S_Op_AwaitInput,
S_Op_ShowCharacter,
S_Op_LineEntry = 0x80, // sixten(NOTE): All opcoodes above are reserved.
};

View File

@ -1,32 +1,11 @@
#include "generated/vn_ui.meta.c"
inline ui_size UI_Pixels(r32 Value, r32 Strictness)
static ui_size UI_MakeSize(ui_size_kind Kind, r32 Value, r32 Strictness)
{
ui_size Result = {UI_SizeType_Pixels, Value, Strictness};
return(Result);
}
inline ui_size UI_Em(r32 Value, r32 Strictness)
{
ui_size Result = {UI_SizeType_Pixels, Value*UI_TopFontSize(), Strictness};
return(Result);
}
inline ui_size UI_TextContent(r32 Value, r32 Strictness)
{
ui_size Result = {UI_SizeType_TextContent, Value, Strictness};
return(Result);
}
inline ui_size UI_Percent(r32 Value, r32 Strictness)
{
ui_size Result = {UI_SizeType_PercentOfParent, Value, Strictness};
return(Result);
}
inline ui_size UI_ChildrenSum(r32 Value, r32 Strictness)
{
ui_size Result = {UI_SizeType_ChildrenSum, Value, Strictness};
ui_size Result;
Result.Kind = Kind;
Result.Value = Value;
Result.Strictness = Strictness;
return(Result);
}
@ -42,43 +21,36 @@ inline ui *UI_GetState(void)
return(ThreadLocal_UI);
}
inline ui_key UI_GetHot(void)
inline ui_key UI_HotKey(void)
{
ui *UI = UI_GetState();
return(UI->Hot);
return(UI_GetState()->Hot);
}
inline ui_key UI_GetActive(void)
inline ui_key UI_ActiveKey(void)
{
ui *UI = UI_GetState();
return(UI->Active);
return(UI_GetState()->Active);
}
inline platform_event_list *UI_EventList(void)
{
ui *UI = UI_GetState();
return(UI->EventList);
return(UI_GetState()->EventList);
}
inline memory_arena *UI_FrameArena(void)
{
ui *UI = UI_GetState();
return(UI->FrameArena);
return(UI_GetState()->FrameArena);
}
inline v2_r32 UI_MouseP(void)
{
ui *UI = UI_GetState();
return(UI->MouseP);
return(UI_GetState()->MouseP);
}
inline glyph_atlas *UI_GlyphAtlas(void)
{
ui *UI = UI_GetState();
return(UI->GlyphAtlas);
return(UI_GetState()->GlyphAtlas);
}
inline void UI_SetDragStartP(v2 P)
{
ui *UI = UI_GetState();
@ -160,7 +132,7 @@ inline ui_key UI_SeedKey(ui_key Key, ui_key Seed)
return(Result);
}
inline ui_key UI_GenerateKeyFromString(string String)
inline ui_key UI_KeyFromString(string String)
{
ui_key Key;
if(String.Count)
@ -175,7 +147,7 @@ inline ui_key UI_GenerateKeyFromString(string String)
return(Key);
}
static string UI_GetBoxNameByKey(ui_key Key)
static string UI_BoxStringFromKey(ui_key Key)
{
ui *UI = UI_GetState();
string Result = StrLit("Empty or Not Found");
@ -204,7 +176,7 @@ static string UI_GetBoxNameByKey(ui_key Key)
return(Result);
}
inline ui_box *UI_GetBoxByKey(ui *UI, ui_key Key)
inline ui_box *UI_BoxFromKey(ui *UI, ui_key Key)
{
u64 Hash = Key.Value;
u64 Slot = Hash % ArrayCount(UI->BoxBuckets);
@ -256,7 +228,7 @@ inline ui_box *UI_MakeBox(ui_box_flags Flags, string String)
ui_box *Parent = UI_TopParent();
ui_key BaseKey = UI_GenerateKeyFromString(String);
ui_key BaseKey = UI_KeyFromString(String);
ui_key Seed = UI_SeedKey(BaseKey, Parent ? Parent->Seed : UI_EmptyKey());
ui_key Key = BaseKey.Value ? Seed : UI_EmptyKey();
@ -273,7 +245,7 @@ inline ui_box *UI_MakeBox(ui_box_flags Flags, string String)
}
#endif
ui_box *Box = UI_GetBoxByKey(UI, Key);
ui_box *Box = UI_BoxFromKey(UI, Key);
Box->Seed = Seed;
Box->First = Box->Last = Box->Next = Box->Prev = Box->Parent = 0;
@ -714,14 +686,14 @@ static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis)
ui *UI = UI_GetState();
ui_box *Parent = Box->Parent;
switch(Box->SemanticSize[Axis].Type)
switch(Box->SemanticSize[Axis].Kind)
{
case UI_SizeType_Pixels:
case UI_SizeKind_Pixels:
{
Result = Box->SemanticSize[Axis].Value;
} break;
case UI_SizeType_TextContent:
case UI_SizeKind_TextContent:
{
glyph_atlas *Atlas = UI->GlyphAtlas;
@ -731,9 +703,9 @@ static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis)
Box->SemanticSize[Axis].Value;
} break;
case UI_SizeType_PercentOfParent:
case UI_SizeKind_PercentOfParent:
{
if(Parent && Parent->SemanticSize[Axis].Type != UI_SizeType_ChildrenSum)
if(Parent && Parent->SemanticSize[Axis].Kind != UI_SizeKind_ChildrenSum)
{
r32 Size = Parent->ComputedDim.E[Axis];
// sixten: if the size is zero, try to find it.
@ -751,7 +723,7 @@ static r32 UI_CalculateBoxSize(ui_box *Box, axis2 Axis)
}
} break;
case UI_SizeType_ChildrenSum:
case UI_SizeKind_ChildrenSum:
{
Result = UI_CalculateChildrenSum(Box, Axis)*Box->SemanticSize[Axis].Value;
} break;

View File

@ -16,26 +16,28 @@ inline b32 AreEqual(ui_key A, ui_key B)
}
//- sixten: Semantic sizing
enum ui_size_type
enum ui_size_kind
{
UI_SizeType_Pixels,
UI_SizeType_TextContent,
UI_SizeType_PercentOfParent,
UI_SizeType_ChildrenSum,
UI_SizeKind_Pixels,
UI_SizeKind_TextContent,
UI_SizeKind_PercentOfParent,
UI_SizeKind_ChildrenSum,
};
struct ui_size
{
ui_size_type Type;
ui_size_kind Kind;
r32 Value;
r32 Strictness;
};
inline ui_size UI_Pixels(r32 Value, r32 Strictness);
inline ui_size UI_Em(r32 Value, r32 Strictness);
inline ui_size UI_TextContent(r32 Value, r32 Strictness);
inline ui_size UI_Percent(r32 Value, r32 Strictness);
inline ui_size UI_ChildrenSum(r32 Value, r32 Strictness);
static ui_size UI_MakeSize(ui_size_kind Kind, r32 Value, r32 Strictness);
#define UI_Pixels(Value, Strictness) UI_MakeSize(UI_SizeKind_Pixels, Value, Strictness)
#define UI_Em(Value, Strictness) UI_MakeSize(UI_SizeKind_Pixels, (Value)*UI_TopFontSize(), Strictness)
#define UI_TextContent(Value, Strictness) UI_MakeSize(UI_SizeKind_TextContent, Value, Strictness)
#define UI_Percent(Value, Strictness) UI_MakeSize(UI_SizeKind_PercentOfParent, Value, Strictness)
#define UI_ChildrenSum(Value, Strictness) UI_MakeSize(UI_SizeKind_ChildrenSum, Value, Strictness)
//- sixten: UI core
enum
@ -160,8 +162,8 @@ struct ui
//- sixten: State management
inline void UI_SetState(ui *UI);
inline ui *UI_GetState(void);
inline ui_key UI_GetHot(void);
inline ui_key UI_GetActive(void);
inline ui_key UI_HotKey(void);
inline ui_key UI_ActiveKey(void);
inline platform_event_list *UI_EventList(void);
inline memory_arena *UI_FrameArena(void);
inline v2 UI_MouseP(void);
@ -183,9 +185,9 @@ inline void *UI_GetDragDataPointer(void);
//- sixten: Key functions
static ui_key UI_EmptyKey(void);
static ui_key UI_SeedKey(ui_key Key, ui_key Seed);
static ui_key UI_GenerateKeyFromString(string String);
static string UI_GetBoxNameByKey(ui_key Key);
static ui_box *UI_GetBoxByKey(ui *UI, ui_key Key);
static ui_key UI_KeyFromString(string String);
static string UI_BoxStringFromKey(ui_key Key);
static ui_box *UI_BoxFromKey(ui *UI, ui_key Key);
//- sixten: Box creation
static ui_box *UI_MakeBox(ui_box_flags Flags, string String);

View File

@ -52,14 +52,10 @@ static void UI_ScrollEnd(r32 *X, r32 *Y, ui_box_flags Flags=UI_BoxFlag_Clip|UI_B
//- sixten: Common widgets
static ui_box *UI_Label(string String);
static ui_box *UI_LabelF(char *Format, ...);
static ui_signal UI_Button(string String);
static ui_signal UI_ButtonF(char *Format, ...);
static ui_signal UI_Checkbox(b32 *Checked, string String);
static r32 UI_Slider(r32 Value, range1_r32 Range);
static void UI_TooltipLabel(string Label, v2 P);
#endif //VN_UI_UTILS_H

View File

@ -581,11 +581,11 @@ static void W_BuildPanel(workspace_panel *Panel)
if(Panel->CurrentView)
{
ui_key CurrentActive = UI_GetActive();
ui_key CurrentActive = UI_ActiveKey();
W_BuildView(Panel->CurrentView);
if(!AreEqual(CurrentActive, UI_GetActive()))
if(!AreEqual(CurrentActive, UI_ActiveKey()))
{
Workspace->CurrentPanel = Panel;
}
@ -741,7 +741,7 @@ static void W_BuildDragPayload()
Workspace->DragPayloadState = W_DragPayload_Inactive;
}
if(AreEqual(Payload.Key, UI_GetActive()))
if(AreEqual(Payload.Key, UI_ActiveKey()))
{
workspace_view *DraggedView = Payload.View;
UI_SetNextCornerRadius(4);
@ -774,14 +774,16 @@ static void W_Init(workspace *Workspace)
}
// sixten: build text editor / scene view layout
if(0)
if(1)
{
W_CreateNewView(W_View_TextEditor, Workspace->RootPanel);
W_SplitPanel(Workspace->RootPanel, Axis2_X);
W_CreateNewView(W_View_SceneView, Workspace->RootPanel->Last);
}
W_CreateNewView(W_View_CharacterEditor, Workspace->RootPanel);
else // sixten: build character editor
{
W_CreateNewView(W_View_CharacterEditor, Workspace->RootPanel);
}
}
static void W_Update(workspace *Workspace, vn_render_commands *RenderCommands,

View File

@ -131,7 +131,7 @@ static void Workspace_BuildEditorListerDropdown(workspace_editor_lister_dropdown
ui_signal Signal = UI_SignalFromBox(ClickableBox);
if(AreEqual(UI_GetActive(), ClickableBox->Key))
if(AreEqual(UI_ActiveKey(), ClickableBox->Key))
{
ActiveInDropdown = true;
}
@ -139,7 +139,7 @@ static void Workspace_BuildEditorListerDropdown(workspace_editor_lister_dropdown
UI_Parent(ClickableBox)
UI_Height(UI_Percent(1, 1))
{
b32 IsHot = AreEqual(UI_GetHot(), ClickableBox->Key);
b32 IsHot = AreEqual(UI_HotKey(), ClickableBox->Key);
r32 TargetHot = IsHot*0.8;
UI_SetNextCornerRadius(3.0);
@ -169,7 +169,7 @@ static void Workspace_BuildEditorListerDropdown(workspace_editor_lister_dropdown
}
ui_signal Signal = UI_SignalFromBox(Box);
if(AreEqual(UI_GetActive(), Box->Key))
if(AreEqual(UI_ActiveKey(), Box->Key))
{
ActiveInDropdown = true;
}
@ -177,7 +177,7 @@ static void Workspace_BuildEditorListerDropdown(workspace_editor_lister_dropdown
UI_PopBackgroundColor();
UI_PopBorderColor();
if(!ActiveInDropdown && !AreEqual(UI_GetActive(), UI_EmptyKey()))
if(!ActiveInDropdown && !AreEqual(UI_ActiveKey(), UI_EmptyKey()))
{
ListerDropdown->Open = false;
}

View File

@ -354,7 +354,7 @@ static b32 UI_DropdownSelection(char **Alternatives, s32 AlternativeCount, b32 *
*Open = !(*Open);
}
if(AreEqual(UI_GetActive(), DropdownBox->Key))
if(AreEqual(UI_ActiveKey(), DropdownBox->Key))
{
ActiveInDropdown = true;
}
@ -381,7 +381,7 @@ static b32 UI_DropdownSelection(char **Alternatives, s32 AlternativeCount, b32 *
++Index)
{
ui_signal ButtonSignal = UI_ButtonF(Alternatives[Index]);
if(AreEqual(UI_GetActive(), ButtonSignal.Box->Key))
if(AreEqual(UI_ActiveKey(), ButtonSignal.Box->Key))
{
ActiveInDropdown = true;
}
@ -398,7 +398,7 @@ static b32 UI_DropdownSelection(char **Alternatives, s32 AlternativeCount, b32 *
}
}
if(!ActiveInDropdown && !AreEqual(UI_GetActive(), UI_EmptyKey()))
if(!ActiveInDropdown && !AreEqual(UI_ActiveKey(), UI_EmptyKey()))
{
*Open = false;
}

View File

@ -0,0 +1,6 @@
proc main
{
@arthur(greeting) "Welcome to this fine estate!";
jump main; // return to start
}