From 10c5793a1d9c615dc820ae60ce642a7de718b91a Mon Sep 17 00:00:00 2001 From: sixtenhugosson Date: Wed, 13 Sep 2023 06:42:11 +0200 Subject: [PATCH] Started implementing character state --- code/core/core_memory.h | 1 + code/vn.cpp | 6 +-- code/vn_character.cpp | 62 +++++++++++++++++++++++++++-- code/vn_character.h | 27 +++++++++++++ code/vn_platform.h | 1 - code/vn_scene.cpp | 16 ++++++++ code/vn_scene.h | 2 + code/vn_ui.cpp | 76 ++++++++++++------------------------ code/vn_ui.h | 34 ++++++++-------- code/vn_ui_utils.h | 4 -- code/vn_workspace.cpp | 14 ++++--- code/vn_workspace_editor.cpp | 8 ++-- code/vn_workspace_view.cpp | 6 +-- data/character.vns | 6 +++ 14 files changed, 171 insertions(+), 92 deletions(-) create mode 100644 data/character.vns diff --git a/code/core/core_memory.h b/code/core/core_memory.h index dcf1b49..4d047aa 100644 --- a/code/core/core_memory.h +++ b/code/core/core_memory.h @@ -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 diff --git a/code/vn.cpp b/code/vn.cpp index 861f1d1..ec4da9c 100644 --- a/code/vn.cpp +++ b/code/vn.cpp @@ -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())); } } } \ No newline at end of file diff --git a/code/vn_character.cpp b/code/vn_character.cpp index 1d6a68e..3d5d0c9 100644 --- a/code/vn_character.cpp +++ b/code/vn_character.cpp @@ -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) diff --git a/code/vn_character.h b/code/vn_character.h index b1d315c..d15d009 100644 --- a/code/vn_character.h +++ b/code/vn_character.h @@ -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 diff --git a/code/vn_platform.h b/code/vn_platform.h index 0831bc8..693e4a8 100644 --- a/code/vn_platform.h +++ b/code/vn_platform.h @@ -188,7 +188,6 @@ struct vn_input struct vn_memory { platform_api PlatformAPI; - struct vn_state *State; }; diff --git a/code/vn_scene.cpp b/code/vn_scene.cpp index 6361287..d35770b 100644 --- a/code/vn_scene.cpp +++ b/code/vn_scene.cpp @@ -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); diff --git a/code/vn_scene.h b/code/vn_scene.h index 4b0048c..5e54b4f 100644 --- a/code/vn_scene.h +++ b/code/vn_scene.h @@ -66,6 +66,8 @@ enum scene_opcode S_Op_AwaitInput, + S_Op_ShowCharacter, + S_Op_LineEntry = 0x80, // sixten(NOTE): All opcoodes above are reserved. }; diff --git a/code/vn_ui.cpp b/code/vn_ui.cpp index bb27173..6cb0531 100644 --- a/code/vn_ui.cpp +++ b/code/vn_ui.cpp @@ -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; diff --git a/code/vn_ui.h b/code/vn_ui.h index c953806..b0243f0 100644 --- a/code/vn_ui.h +++ b/code/vn_ui.h @@ -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); diff --git a/code/vn_ui_utils.h b/code/vn_ui_utils.h index 3bc1bf7..802acc1 100644 --- a/code/vn_ui_utils.h +++ b/code/vn_ui_utils.h @@ -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 diff --git a/code/vn_workspace.cpp b/code/vn_workspace.cpp index 761c9a0..8bbfddb 100644 --- a/code/vn_workspace.cpp +++ b/code/vn_workspace.cpp @@ -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, diff --git a/code/vn_workspace_editor.cpp b/code/vn_workspace_editor.cpp index 8ecb559..25aed25 100644 --- a/code/vn_workspace_editor.cpp +++ b/code/vn_workspace_editor.cpp @@ -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; } diff --git a/code/vn_workspace_view.cpp b/code/vn_workspace_view.cpp index ba3dec1..e7fbf5e 100644 --- a/code/vn_workspace_view.cpp +++ b/code/vn_workspace_view.cpp @@ -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; } diff --git a/data/character.vns b/data/character.vns new file mode 100644 index 0000000..1e75782 --- /dev/null +++ b/data/character.vns @@ -0,0 +1,6 @@ +proc main +{ + @arthur(greeting) "Welcome to this fine estate!"; + + jump main; // return to start +} \ No newline at end of file