diff --git a/src/app/editor/interface.h b/src/app/editor/interface.h index 4b4d13e..1c3dfaf 100644 --- a/src/app/editor/interface.h +++ b/src/app/editor/interface.h @@ -1444,6 +1444,22 @@ ui_Toggle(ui_interface* Interface, gs_string Text, bool Value) return Result; } +internal bool +ui_ToggleText(ui_interface* Interface, gs_string Text, bool Value) +{ + ui_widget* Widget = ui_CreateWidget(Interface, Text); + ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); + ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); + ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); + ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawHorizontalFill); + ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawOutline); + ui_eval_result Eval = ui_EvaluateWidget(Interface, Widget); + + bool Result = Eval.Clicked ? !Value : Value; + Widget->FillPercent = Result ? 1.0f : 0.0f; + return Result; +} + internal void ui_BeginList(ui_interface* Interface, gs_string Text, u32 ViewportRows, u32 ElementCount) { diff --git a/src/app/editor/panels/foldhaus_panel_assembly_debug.h b/src/app/editor/panels/foldhaus_panel_assembly_debug.h index ee75876..7d7b122 100644 --- a/src/app/editor/panels/foldhaus_panel_assembly_debug.h +++ b/src/app/editor/panels/foldhaus_panel_assembly_debug.h @@ -43,70 +43,91 @@ AssemblyDebug_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Ren ui_interface* Interface = &State->Interface; ui_PushLayout(Interface, PanelBounds, LayoutDirection_TopDown, MakeString("Assembly Debug Layout")); - InterfaceAssert(Interface->PerFrameMemory); - - gs_string OverrideStr = MakeString(OverrideTypeStrings[State->AssemblyDebugState.Override]); - if (ui_BeginLabeledDropdown(Interface, MakeString("Override"), OverrideStr)) + ui_BeginRow(Interface, 2); { - for (u32 i = 0; i < ADS_Override_Count; i++) + if (ui_Button(Interface, MakeString("Assembly"))) { - if (ui_Button(Interface, MakeString(OverrideTypeStrings[i]))) - { - State->AssemblyDebugState.Override = (override_type)i; - } + State->ShowingUserSpaceDebug = false; + } + + if (ui_Button(Interface, MakeString("User Space"))) + { + State->ShowingUserSpaceDebug = true; } } - ui_EndLabeledDropdown(Interface); - InterfaceAssert(Interface->PerFrameMemory); + ui_EndRow(Interface); - switch (State->AssemblyDebugState.Override) + if (State->ShowingUserSpaceDebug && State->UserSpaceDesc.CustomDebugUI) { - case ADS_Override_TagWhite: - case ADS_Override_TagStripWhite: + US_CustomDebugUI(&State->UserSpaceDesc, Panel, PanelBounds, RenderBuffer, + State, Context); + } + else + { + InterfaceAssert(Interface->PerFrameMemory); + + gs_string OverrideStr = MakeString(OverrideTypeStrings[State->AssemblyDebugState.Override]); + if (ui_BeginLabeledDropdown(Interface, MakeString("Override"), OverrideStr)) { - ui_LabeledTextEntry(Interface, MakeString("Tag Name"), &State->AssemblyDebugState.TagName); - ui_LabeledTextEntry(Interface, MakeString("Tag Value"), &State->AssemblyDebugState.TagValue); - - if (State->AssemblyDebugState.Override == ADS_Override_TagStripWhite) + for (u32 i = 0; i < ADS_Override_Count; i++) { + if (ui_Button(Interface, MakeString(OverrideTypeStrings[i]))) + { + State->AssemblyDebugState.Override = (override_type)i; + } + } + } + ui_EndLabeledDropdown(Interface); + InterfaceAssert(Interface->PerFrameMemory); + + switch (State->AssemblyDebugState.Override) + { + case ADS_Override_TagWhite: + case ADS_Override_TagStripWhite: + { + ui_LabeledTextEntry(Interface, MakeString("Tag Name"), &State->AssemblyDebugState.TagName); + ui_LabeledTextEntry(Interface, MakeString("Tag Value"), &State->AssemblyDebugState.TagValue); + + if (State->AssemblyDebugState.Override == ADS_Override_TagStripWhite) + { + State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly); + + State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip); + } + }break; + + case ADS_Override_ChannelWhite: + { + u64 Board = 0; + u64 Strip = 0; + Board = ui_LabeledTextEntryU64(Interface, MakeString("Board"), Board); + Strip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), Strip); + + State->AssemblyDebugState.TargetChannel = FSC(Board, Strip); + }break; + + case ADS_Override_AllRed: + case ADS_Override_AllGreen: + case ADS_Override_AllBlue: + case ADS_Override_AllWhite: + { + State->AssemblyDebugState.Brightness = (u8)ui_LabeledRangeSlider(Interface, MakeString("Brightness"), (r32)State->AssemblyDebugState.Brightness, 0, 255); + }break; + + default: + { + InterfaceAssert(Interface->PerFrameMemory); + State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly); + InterfaceAssert(Interface->PerFrameMemory); + State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip); - } - }break; - - case ADS_Override_ChannelWhite: - { - u64 Board = 0; - u64 Strip = 0; - Board = ui_LabeledTextEntryU64(Interface, MakeString("Board"), Board); - Strip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), Strip); - - State->AssemblyDebugState.TargetChannel = FSC(Board, Strip); - }break; - - case ADS_Override_AllRed: - case ADS_Override_AllGreen: - case ADS_Override_AllBlue: - case ADS_Override_AllWhite: - { - State->AssemblyDebugState.Brightness = (u8)ui_LabeledRangeSlider(Interface, MakeString("Brightness"), (r32)State->AssemblyDebugState.Brightness, 0, 255); - }break; - - default: - { - InterfaceAssert(Interface->PerFrameMemory); - - State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly); - - InterfaceAssert(Interface->PerFrameMemory); - - State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip); - - InterfaceAssert(Interface->PerFrameMemory); - }break; + + InterfaceAssert(Interface->PerFrameMemory); + }break; + } } - ui_PopLayout(Interface, MakeString("Assembly Debug Layout")); } diff --git a/src/app/engine/animation/foldhaus_animation.h b/src/app/engine/animation/foldhaus_animation.h index 91204c7..64ef95c 100644 --- a/src/app/engine/animation/foldhaus_animation.h +++ b/src/app/engine/animation/foldhaus_animation.h @@ -725,26 +725,29 @@ AnimationSystem_Update(animation_system* System, r32 DeltaTime) AnimationFadeGroup_Update(&System->ActiveFadeGroup, DeltaTime); animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System); - // TODO(Peter): Revisit this. This implies that the framerate of the animation system - // is tied to the framerate of the simulation. That seems correct to me, but I'm not sure - System->CurrentFrame += 1; - - // Loop back to the beginning - if (System->CurrentFrame > ActiveAnim->PlayableRange.Max) + if (ActiveAnim) { - switch (System->RepeatMode) + // TODO(Peter): Revisit this. This implies that the framerate of the animation system + // is tied to the framerate of the simulation. That seems correct to me, but I'm not sure + System->CurrentFrame += 1; + + // Loop back to the beginning + if (System->CurrentFrame > ActiveAnim->PlayableRange.Max) { - case AnimationRepeat_Single: + switch (System->RepeatMode) { - System->CurrentFrame = 0; - }break; - - case AnimationRepeat_Loop: - { - // TODO(pjs): - }break; - - InvalidDefaultCase; + case AnimationRepeat_Single: + { + System->CurrentFrame = 0; + }break; + + case AnimationRepeat_Loop: + { + // TODO(pjs): + }break; + + InvalidDefaultCase; + } } } } diff --git a/src/app/engine/user_space.cpp b/src/app/engine/user_space.cpp index 752435a..7e401df 100644 --- a/src/app/engine/user_space.cpp +++ b/src/app/engine/user_space.cpp @@ -32,6 +32,16 @@ US_CustomUpdate(user_space_desc* Desc, app_state* State, context* Context) } } +internal void +US_CustomDebugUI(user_space_desc* Desc, panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, + app_state* State, context Context) +{ + if (Desc->CustomDebugUI) + { + Desc->CustomDebugUI(Desc->UserData, Panel, PanelBounds, RenderBuffer, State, Context); + } +} + internal void US_CustomCleanup(user_space_desc* Desc, app_state* State, context Context) { diff --git a/src/app/engine/user_space.h b/src/app/engine/user_space.h index 8dc5f8a..5373fcb 100644 --- a/src/app/engine/user_space.h +++ b/src/app/engine/user_space.h @@ -14,6 +14,9 @@ typedef US_CUSTOM_INIT(us_custom_init_proc); #define US_CUSTOM_UPDATE(name) void name(gs_data UserData, app_state* State, context* Context) typedef US_CUSTOM_UPDATE(us_custom_update_proc); +#define US_CUSTOM_DEBUG_UI(name) void name(gs_data UserData, panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) +typedef US_CUSTOM_DEBUG_UI(us_custom_debug_ui); + #define US_CUSTOM_CLEANUP(name) void name(gs_data UserData, app_state* State, context Context) typedef US_CUSTOM_CLEANUP(us_custom_cleanup_proc); @@ -22,6 +25,7 @@ typedef struct user_space_desc us_load_patterns_proc* LoadPatterns; us_custom_init_proc* CustomInit; us_custom_update_proc* CustomUpdate; + us_custom_debug_ui* CustomDebugUI; us_custom_cleanup_proc* CustomCleanup; gs_data UserData; diff --git a/src/app/foldhaus_app.h b/src/app/foldhaus_app.h index f18ea3f..6e44c4d 100644 --- a/src/app/foldhaus_app.h +++ b/src/app/foldhaus_app.h @@ -72,6 +72,7 @@ struct app_state panel* HotPanel; user_space_desc UserSpaceDesc; + bool ShowingUserSpaceDebug; bool RunEditor; }; diff --git a/src/app/platform_win32/win32_foldhaus.cpp b/src/app/platform_win32/win32_foldhaus.cpp index 28769ba..cc1020e 100644 --- a/src/app/platform_win32/win32_foldhaus.cpp +++ b/src/app/platform_win32/win32_foldhaus.cpp @@ -575,27 +575,6 @@ WinMain ( if (!SetWorkingDirectory(HInstance, ThreadContext)) return 1; - - gs_file TestFile = ReadEntireFile(ThreadContext.FileHandler, ConstString("data/flower_codes.tsv")); - gs_const_string TestFileStr = {}; - TestFileStr.Str = (char*)TestFile.Memory; - TestFileStr.Length = TestFile.Size; - gscsv_sheet Sheet = CSV_Parse(TestFileStr, { '\t' }, ThreadContext.Transient); - - gs_string Out = PushString(ThreadContext.Transient, TestFile.Size * 2); - - for (u64 y = 0; y < Sheet.RowCount; y++) - { - for (u64 x = 0; x < Sheet.ColumnCount; x++) - { - gs_const_string Cell = CSVSheet_GetCell(Sheet, x, y); - AppendPrintF(&Out, "%S\t", Cell); - } - AppendPrintF(&Out, "\n"); - } - NullTerminate(&Out); - OutputDebugStringA(Out.Str); - MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents); Win32UpdateWindowDimension(&MainWindow); diff --git a/src/app/platform_win32/win32_foldhaus_serial.h b/src/app/platform_win32/win32_foldhaus_serial.h index a1244a9..23d8cdf 100644 --- a/src/app/platform_win32/win32_foldhaus_serial.h +++ b/src/app/platform_win32/win32_foldhaus_serial.h @@ -172,6 +172,7 @@ Win32SerialPort_Open(char* PortName, gs_memory_arena* Transient) s32 Error = GetLastError(); switch (Error) { + case ERROR_INVALID_FUNCTION: case ERROR_NO_SUCH_DEVICE: case ERROR_FILE_NOT_FOUND: { diff --git a/src/app/platform_win32/win32_foldhaus_socket.h b/src/app/platform_win32/win32_foldhaus_socket.h index 00bceec..2cb326a 100644 --- a/src/app/platform_win32/win32_foldhaus_socket.h +++ b/src/app/platform_win32/win32_foldhaus_socket.h @@ -132,7 +132,7 @@ Win32Socket_ConnectToAddress(char* Address, char* DefaultPort) } internal bool -Win32ConnectSocket(platform_socket* Socket) +Win32ConnectSocket(platform_socket_manager* Manager, platform_socket* Socket) { bool Result = false; @@ -156,7 +156,7 @@ Win32ConnectSocket(platform_socket* Socket) // If iMode == 0, blocking is enabled // if iMode != 0, non-blocking mode is enabled - u_long iMode = 1; + u_long iMode = 0; Error = ioctlsocket(SocketHandle, FIONBIO, &iMode); if (Error != NO_ERROR) { @@ -218,7 +218,7 @@ Win32ConnectSocket(platform_socket* Socket) } internal bool -Win32CloseSocket(platform_socket* Socket) +Win32CloseSocket(platform_socket_manager* Manager, platform_socket* Socket) { SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; closesocket(*Win32Sock); @@ -228,7 +228,7 @@ Win32CloseSocket(platform_socket* Socket) } internal bool -Win32SocketQueryStatus(platform_socket* Socket) +Win32SocketQueryStatus(platform_socket_manager* Manager, platform_socket* Socket) { SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; bool Result = (*Win32Sock != INVALID_SOCKET); @@ -236,7 +236,7 @@ Win32SocketQueryStatus(platform_socket* Socket) } internal u32 -Win32SocketPeek(platform_socket* Socket) +Win32SocketPeek(platform_socket_manager* Manager, platform_socket* Socket) { u32 Result = 0; s32 Flags = MSG_PEEK; @@ -257,16 +257,10 @@ Win32SocketPeek(platform_socket* Socket) { case WSAEWOULDBLOCK: case WSAENOTCONN: - { - }break; - case WSAECONNRESET: - { - }break; - case WSAECONNABORTED: { - Win32CloseSocket(Socket); + CloseSocket(Manager, Socket); }break; InvalidDefaultCase; @@ -276,7 +270,7 @@ Win32SocketPeek(platform_socket* Socket) } internal gs_data -Win32SocketReceive(platform_socket* Socket, gs_memory_arena* Storage) +Win32SocketReceive(platform_socket_manager* Manager, platform_socket* Socket, gs_memory_arena* Storage) { // TODO(pjs): Test this first code path when you have data running - it should // get the actual size of the data packet being sent @@ -309,7 +303,7 @@ Win32SocketReceive(platform_socket* Socket, gs_memory_arena* Storage) internal s32 -Win32SocketSend(platform_socket* Socket, u32 Address, u32 Port, gs_data Data, s32 Flags) +Win32SocketSend(platform_socket_manager* Manager, platform_socket* Socket, u32 Address, u32 Port, gs_data Data, s32 Flags) { SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; @@ -327,26 +321,23 @@ Win32SocketSend(platform_socket* Socket, u32 Address, u32 Port, gs_data Data, s3 switch (Error) { case WSAECONNABORTED: - { - }break; - case WSAENETUNREACH: - { - }break; - case WSAECONNRESET: - { - - }break; - case WSAENOTCONN: { + if (CloseSocket(Manager, Socket)) + { + Error = 0; + } }break; InvalidDefaultCase; } - OutputDebugString("Error\n"); + if (Error) + { + OutputDebugString("Error\n"); + } } else { diff --git a/src/app/ss_blumen_lumen/blumen_lumen.cpp b/src/app/ss_blumen_lumen/blumen_lumen.cpp index fd02a59..3c11b10 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.cpp +++ b/src/app/ss_blumen_lumen/blumen_lumen.cpp @@ -5,24 +5,50 @@ // #ifndef BLUMEN_LUMEN_CPP -internal bool -MessageQueue_CanRead(blumen_network_msg_queue* Queue) +internal void +DEBUG_AppendText(gs_string Str, gs_thread_context Ctx) { - bool Result = (Queue->ReadHead != Queue->WriteHead); - return Result; + gs_const_string DebugPath = ConstString("data/debug_motor_changes.txt"); + gs_file DebugFile = ReadEntireFile(Ctx.FileHandler, + DebugPath); + gs_string NewString = PushString(Ctx.Transient, DebugFile.Size + Str.Size + 16); + if (DebugFile.Size > 0) + { + PrintF(&NewString, "%.*s\nENTRY:\n", DebugFile.Size, (char*)DebugFile.Memory); + } + AppendPrintF(&NewString, "%S\n", Str.ConstString); + NullTerminate(&NewString); + + if (!WriteEntireFile(Ctx.FileHandler, DebugPath, StringToData(NewString))) + { + InvalidCodePath; + } } -internal gs_data -MessageQueue_Read(blumen_network_msg_queue* Queue) +internal void +DEBUG_SentMotorCommand(motor_packet Packet, gs_thread_context Ctx) { - gs_data Result = {}; - u32 ReadIndex = Queue->ReadHead++; - if (Queue->ReadHead >= BLUMEN_MESSAGE_QUEUE_COUNT) - { - Queue->ReadHead = 0; - } - Result = Queue->Buffers[ReadIndex]; - return Result; + gs_string Str = PushStringF(Ctx.Transient, 256, "Motor Command Sent\nRequested Positions: %d %d %d\n", + Packet.FlowerPositions[0], + Packet.FlowerPositions[1], + Packet.FlowerPositions[2]); + DEBUG_AppendText(Str, Ctx); + + NullTerminate(&Str); + OutputDebugStringA(Str.Str); +} + +internal void +DEBUG_ReceivedMotorPositions(motor_packet Packet, gs_thread_context Ctx) +{ + gs_string Str = PushStringF(Ctx.Transient, 256, "Motor Status Received\nCurrent Positions: %d %d %d\n", + Packet.FlowerPositions[0], + Packet.FlowerPositions[1], + Packet.FlowerPositions[2]); + DEBUG_AppendText(Str, Ctx); + + NullTerminate(&Str); + OutputDebugStringA(Str.Str); } // KB(1) is just bigger than any packet we send. Good for now @@ -37,6 +63,14 @@ MessageQueue_Init(blumen_network_msg_queue* Queue, gs_memory_arena* Arena) } } +internal bool +MessageQueue_CanWrite(blumen_network_msg_queue Queue) +{ + bool Result = ((Queue.WriteHead >= Queue.ReadHead) || + (Queue.WriteHead < Queue.ReadHead)); + return Result; +} + internal bool MessageQueue_Write(blumen_network_msg_queue* Queue, gs_data Msg) { @@ -58,13 +92,34 @@ MessageQueue_Write(blumen_network_msg_queue* Queue, gs_data Msg) } internal bool -MessageQueue_CanWrite(blumen_network_msg_queue Queue) +MessageQueue_CanRead(blumen_network_msg_queue Queue) { - bool Result = ((Queue.WriteHead >= Queue.ReadHead) || - (Queue.WriteHead < Queue.ReadHead)); + bool Result = (Queue.ReadHead != Queue.WriteHead); return Result; } +internal gs_data +MessageQueue_Read(blumen_network_msg_queue* Queue) +{ + gs_data Result = {}; + u32 ReadIndex = Queue->ReadHead++; + if (Queue->ReadHead >= BLUMEN_MESSAGE_QUEUE_COUNT) + { + Queue->ReadHead = 0; + } + Result = Queue->Buffers[ReadIndex]; + return Result; +} + +internal void +MessageQueue_Clear(blumen_network_msg_queue* Queue) +{ + while (MessageQueue_CanRead(*Queue)) + { + MessageQueue_Read(Queue); + } +} + internal void BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData) { @@ -81,32 +136,51 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData) u32 WeathermanIPV4 = (u32)UpackB4(WeathermanIPAddr); u32 WeathermanPort = 20185; + platform_socket_handle_ ListenSocket = {0}; + while (*Data->Running) { - if (SocketQueryStatus(Data->SocketManager, Data->ListenSocket)) + if (!SocketQueryStatus(Data->SocketManager, ListenSocket)) { - if (SocketPeek(Data->SocketManager, Data->ListenSocket)) + if (SocketHandleIsValid(ListenSocket)) + { + OutputDebugStringA("Disconnected from Python Server\n"); + CloseSocket(Data->SocketManager, ListenSocket); + } + ListenSocket = CreateSocket(Data->SocketManager, "127.0.0.1", "20185"); + if (ListenSocket.Index != 0) + { + OutputDebugStringA("Connected to Python Server\n"); + } + } + + if (SocketQueryStatus(Data->SocketManager, ListenSocket)) + { + if (SocketPeek(Data->SocketManager, ListenSocket)) { // TODO(pjs): Make this a peek operation - Msg = SocketRecieve(Data->SocketManager, Data->ListenSocket, Ctx->Transient); + Msg = SocketRecieve(Data->SocketManager, ListenSocket, Ctx->Transient); if (Msg.Size > 0) { MessageQueue_Write(Data->IncomingMsgQueue, Msg); } } - while (MessageQueue_CanRead(Data->OutgoingMsgQueue)) + while (MessageQueue_CanRead(*Data->OutgoingMsgQueue)) { Msg = MessageQueue_Read(Data->OutgoingMsgQueue); + u32 Address = WeathermanIPV4; u32 Port = WeathermanPort; s32 Flags = 0; - SocketSend(Data->SocketManager, Data->ListenSocket, Address, Port, Msg, Flags); + SocketSend(Data->SocketManager, ListenSocket, Address, Port, Msg, Flags); } } + + MessageQueue_Clear(Data->OutgoingMsgQueue); } - CloseSocket(Data->SocketManager, Data->ListenSocket); + CloseSocket(Data->SocketManager, ListenSocket); } internal void @@ -143,19 +217,6 @@ BlumenLumen_LoadPatterns(app_state* State) Patterns_PushPattern(Patterns, Pattern_WavyPatchy, PATTERN_SINGLETHREADED); } -internal v4 -TEMP_Saturate(v4 P) -{ - v4 CRGB = P; - v4 CHSV = RGBToHSV(CRGB); - if (CHSV.g > .3f) - { - CHSV.g = 1; - CRGB = HSVToRGB(CHSV); - } - return CRGB; -} - internal gs_data BlumenLumen_CustomInit(app_state* State, context Context) { @@ -177,9 +238,8 @@ BlumenLumen_CustomInit(app_state* State, context Context) BLState->MicListenJobData.SocketManager = Context.SocketManager; BLState->MicListenJobData.IncomingMsgQueue = &BLState->IncomingMsgQueue; BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue; - BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185"); -#if 0 +#if 1 BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData); #endif @@ -236,12 +296,6 @@ BlumenLumen_CustomInit(app_state* State, context Context) State->AnimationSystem.ActiveFadeGroup.From = DemoPatternsAnim; #endif State->AnimationSystem.TimelineShouldAdvance = true; - for (u32 i = 0; i < FLOWER_COLORS_COUNT; i++) - { - //FlowerAColors[i] = TEMP_Saturate(FlowerAColors[i]); - //FlowerBColors[i] = TEMP_Saturate(FlowerBColors[i]); - //FlowerCColors[i] = TEMP_Saturate(FlowerCColors[i]); - } BLState->AssemblyColors[0] = RedV4; BLState->AssemblyColors[1] = GreenV4; @@ -271,7 +325,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) } #endif - while (MessageQueue_CanRead(&BLState->IncomingMsgQueue)) + while (MessageQueue_CanRead(BLState->IncomingMsgQueue)) { gs_data PacketData = MessageQueue_Read(&BLState->IncomingMsgQueue); @@ -291,29 +345,12 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup, animation_handle{(s32)PhraseIndex}, 3.0f); - OutputDebugStringA("\nReceived Pattern Packet\n"); - { - // DEBUG CODE - u8 MotorState = BLState->LastKnownMotorState.FlowerPositions[0]; - if (MotorState == 2) { - OutputDebugStringA("Sending 1\n"); - MotorState = 1; - } - else - { - OutputDebugStringA("Sending 1\n"); - MotorState = 2; - } - - blumen_packet MPacket = {}; - MPacket.Type = PacketType_MotorState; - MPacket.MotorPacket.FlowerPositions[0] = MotorState; - MPacket.MotorPacket.FlowerPositions[1] = MotorState; - MPacket.MotorPacket.FlowerPositions[2] = MotorState; - MotorCommand = MPacket; - SendMotorCommand = true; - } + gs_string T = PushStringF(State->Transient, 256, + "Received Animation Packet:\nAnimationIndex: %d\n", + PhraseIndex); + NullTerminate(&T); + OutputDebugStringA(T.Str); } } }break; @@ -328,27 +365,22 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) Motor.Temperature = (T[0] << 8 | T[1] << 0); + motor_packet LastPos = BLState->LastKnownMotorState; + if (LastPos.FlowerPositions[0] != Motor.Pos.FlowerPositions[0] || + LastPos.FlowerPositions[1] != Motor.Pos.FlowerPositions[1] || + LastPos.FlowerPositions[2] != Motor.Pos.FlowerPositions[2]) + { + DEBUG_ReceivedMotorPositions(Motor.Pos, Context->ThreadContext); + } BLState->LastKnownMotorState = Motor.Pos; - gs_string Temp = PushStringF(State->Transient, 256, "\nReceived Motor States: \n\tPos: %d %d %d\n\tErr: %d %d %d\n\tTemp: %d\n\n", - Motor.Pos.FlowerPositions[0], - Motor.Pos.FlowerPositions[1], - Motor.Pos.FlowerPositions[2], - Motor.MotorStatus[0], - Motor.MotorStatus[1], - Motor.MotorStatus[2], - (u32)Motor.Temperature - ); - NullTerminate(&Temp); - - OutputDebugStringA(Temp.Str); }break; case PacketType_Temperature: { temp_packet Temp = Packet.TempPacket; - if (Temp.Temperature > 21) + if (Temp.Temperature > 0) { BLState->BrightnessPercent = .25f; } @@ -372,19 +404,19 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) if (MessageQueue_CanWrite(BLState->OutgoingMsgQueue)) { -#if 0 +#if 1 for (u32 i = 0; i < MotorOpenTimesCount; i++) { time_range Range = MotorOpenTimes[i]; bool CurrTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Current, Range); + bool LastSendTimeInRange = SystemTimeIsInTimeRange(BLState->LastSendTime, Range); + bool LastTimeInRange = SystemTimeIsInTimeRange(Context->SystemTime_Last, Range); - bool SendOpen = CurrTimeInRange && !LastTimeInRange; - - r64 NanosSinceLastSend = ((r64)Context->SystemTime_Current.NanosSinceEpoch - (r64)BLState->LastSendTime.NanosSinceEpoch); - r64 SecondsSinceLastSend = NanosSinceLastSend / PowR32(10, 8); + bool SendOpen = CurrTimeInRange && !LastSendTimeInRange; + bool SendClose = !CurrTimeInRange && LastSendTimeInRange; //SendOpen = SecondsSinceLastSend > 2; if (SendOpen) @@ -401,9 +433,10 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) Packet.MotorPacket.FlowerPositions[2] = 2; MotorCommand = Packet; } - else if (!CurrTimeInRange && LastTimeInRange) + else if (SendClose) { SendMotorCommand = true; + BLState->LastSendTime = Context->SystemTime_Current; OutputDebugString("Motors: Close\n"); blumen_packet Packet = {}; @@ -420,6 +453,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) { gs_data Msg = StructToData(&MotorCommand, blumen_packet); MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); + DEBUG_SentMotorCommand(MotorCommand.MotorPacket, Context->ThreadContext); } } // Dim the leds based on temp data @@ -439,8 +473,14 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) // TODO(PS): This should really only happen if we think the // flower _might_ be open + for (u32 a = 0; a < State->Assemblies.Count; a++) { + // TODO(PS): make sure to align which assembly goes with which + // flower index + bool FlowerIsOpen = BLState->LastKnownMotorState.FlowerPositions[a] == 2; + //if (!FlowerIsOpen) continue; + assembly Assembly = State->Assemblies.Values[a]; led_buffer Buffer = State->LedSystem.Buffers[Assembly.LedBufferIndex]; @@ -466,7 +506,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) if (SecondsSinceLastSend >= STATUS_PACKET_FREQ_SECONDS) { BLState->LastStatusUpdateTime = Context->SystemTime_Current; - OutputDebugString("Sending Status\n"); + OutputDebugString("Attempting to Send Lumenarium Status\n"); blumen_packet Packet = {}; Packet.Type = PacketType_LumenariumStatus; @@ -484,6 +524,61 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context) } } +US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI) +{ + blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory; + ui_interface* I = &State->Interface; + + // NOTE(PS): Motors + { + motor_packet PendingPacket = BLState->DEBUG_PendingMotorPacket; + + for (u32 MotorIndex = 0; MotorIndex < 3; MotorIndex++) + { + gs_string Label = PushStringF(State->Transient, 32, "Motor %d", MotorIndex); + ui_BeginRow(I, 5); + { + ui_Label(I, Label); + + bool IsClosed = PendingPacket.FlowerPositions[MotorIndex] == 1; + if (ui_ToggleText(I, MakeString("Closed (1)"), IsClosed)) + { + PendingPacket.FlowerPositions[MotorIndex] = 1; + } + bool IsHOpen = PendingPacket.FlowerPositions[MotorIndex] == 3; + if (ui_ToggleText(I, MakeString("Half Open (3)"), IsHOpen)) + { + PendingPacket.FlowerPositions[MotorIndex] = 3; + } + bool IsMOpen = PendingPacket.FlowerPositions[MotorIndex] == 4; + if (ui_ToggleText(I, MakeString("Mostly Open (4)"), IsMOpen)) + { + PendingPacket.FlowerPositions[MotorIndex] = 4; + } + bool IsOpen = PendingPacket.FlowerPositions[MotorIndex] == 2; + if (ui_ToggleText(I, MakeString("Open (2)"), IsOpen)) + { + PendingPacket.FlowerPositions[MotorIndex] = 2; + } + } + ui_EndRow(I); + } + BLState->DEBUG_PendingMotorPacket = PendingPacket; + + if (ui_Button(I, MakeString("Send Motor Packet"))) + { + blumen_packet Packet = {}; + Packet.Type = PacketType_MotorState; + Packet.MotorPacket = BLState->DEBUG_PendingMotorPacket; + gs_data Msg = StructToData(&Packet, blumen_packet); + MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg); + + DEBUG_SentMotorCommand(Packet.MotorPacket, Context.ThreadContext); + } + + } +} + US_CUSTOM_CLEANUP(BlumenLumen_CustomCleanup) { blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory; @@ -497,6 +592,7 @@ BlumenLumen_UserSpaceCreate() Result.LoadPatterns = BlumenLumen_LoadPatterns; Result.CustomInit = BlumenLumen_CustomInit; Result.CustomUpdate = BlumenLumen_CustomUpdate; + Result.CustomDebugUI = BlumenLumen_DebugUI; Result.CustomCleanup = BlumenLumen_CustomCleanup; return Result; } diff --git a/src/app/ss_blumen_lumen/blumen_lumen.h b/src/app/ss_blumen_lumen/blumen_lumen.h index fb5b238..160d90b 100644 --- a/src/app/ss_blumen_lumen/blumen_lumen.h +++ b/src/app/ss_blumen_lumen/blumen_lumen.h @@ -95,7 +95,6 @@ struct mic_listen_job_data platform_socket_manager* SocketManager; blumen_network_msg_queue* IncomingMsgQueue; - platform_socket_handle_ ListenSocket; blumen_network_msg_queue* OutgoingMsgQueue; }; @@ -120,12 +119,52 @@ SystemTimeIsInTimeRange(system_time SysTime, time_range Range) } global time_range MotorOpenTimes[] = { - { 17, 56, 17, 56 }, - { 17, 58, 17, 56 }, - { 18, 00, 18, 00 }, - + { 00, 30, 00, 40 }, + { 00, 50, 01, 00 }, + { 01, 10, 01, 20 }, + { 01, 30, 01, 40 }, + { 01, 50, 02, 00 }, + { 02, 10, 02, 20 }, + { 02, 30, 02, 40 }, + { 02, 50, 03, 00 }, + { 03, 10, 03, 20 }, + { 03, 30, 03, 40 }, + { 03, 50, 04, 00 }, + { 04, 10, 04, 20 }, + { 04, 30, 04, 40 }, + { 04, 50, 05, 00 }, + { 05, 10, 05, 20 }, + { 05, 30, 05, 40 }, + { 05, 50, 06, 00 }, + { 06, 10, 06, 20 }, + { 06, 30, 06, 40 }, + { 06, 50, 07, 00 }, + { 07, 10, 07, 20 }, + { 07, 30, 07, 40 }, + { 07, 50, 8, 00 }, + { 8, 10, 8, 20 }, + { 8, 30, 8, 40 }, + { 8, 50, 9, 00 }, + { 9, 10, 9, 20 }, + { 9, 30, 9, 40 }, + { 9, 50, 10, 00 }, + { 10, 10, 10, 20 }, + { 10, 30, 10, 40 }, + { 10, 50, 11, 00 }, + { 11, 10, 11, 20 }, + { 11, 30, 11, 40 }, + { 11, 50, 12, 00 }, + { 12, 10, 12, 20 }, + { 12, 30, 12, 40 }, + { 12, 50, 13, 00 }, + { 13, 10, 13, 20 }, + { 13, 30, 13, 40 }, + { 13, 50, 14, 00 }, + { 14, 10, 14, 20 }, + { 14, 30, 14, 40 }, + { 14, 50, 15, 00 }, }; -global u32 MotorOpenTimesCount = 3; +global u32 MotorOpenTimesCount = sizeof(MotorOpenTimes) / sizeof(MotorOpenTimes[0]);; struct phrase_string_to_anim_file { @@ -171,6 +210,9 @@ struct blumen_lumen_state system_time LastSendTime; v4 AssemblyColors[3]; + + // Debug + motor_packet DEBUG_PendingMotorPacket; }; diff --git a/src/gs_libs/gs_types.cpp b/src/gs_libs/gs_types.cpp index ca3336d..04fabd6 100644 --- a/src/gs_libs/gs_types.cpp +++ b/src/gs_libs/gs_types.cpp @@ -3584,6 +3584,12 @@ CreatePlatformSocketManager(platform_connect_socket* ConnectSocketProc, return Result; } +internal bool +SocketHandleIsValid(platform_socket_handle_ Handle) +{ + return Handle.Index != 0; +} + internal platform_socket* SocketManagerGetSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle) { @@ -3606,11 +3612,19 @@ ConnectSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle) platform_socket* Socket = SocketManagerGetSocket(Manager, Handle); if (Socket) { - Result = Manager->ConnectSocketProc(Socket); + Result = Manager->ConnectSocketProc(Manager, Socket); } return Result; } +internal bool +RemoveSocket (platform_socket_manager* Manager, platform_socket_handle_ Handle) +{ + bool Result = Manager->SocketsUsed[Handle.Index]; + Manager->SocketsUsed[Handle.Index] = false; + return Result; +} + internal platform_socket_handle_ CreateSocket(platform_socket_manager* Manager, char* Addr, char* Port) { @@ -3627,30 +3641,52 @@ CreateSocket(platform_socket_manager* Manager, char* Addr, char* Port) Assert(Result.Index != 0); platform_socket* Socket = &Manager->Sockets[Result.Index]; + Socket->Handle = Result; CopyArray(Addr, Socket->Addr, char, CStringLength(Addr) + 1); CopyArray(Port, Socket->Port, char, CStringLength(Port) + 1); - bool Success = Manager->ConnectSocketProc(Socket); - Assert(Success); + bool Success = Manager->ConnectSocketProc(Manager, Socket); + if (!Success) + { + if (RemoveSocket(Manager, Result)) + { + Result = {}; + } + else + { + InvalidCodePath; + } + } return Result; } +internal bool +CloseSocket(platform_socket_manager* Manager, platform_socket* Socket) +{ + bool Result = false; + if (Socket) + { + if (Manager->CloseSocketProc(Manager, Socket)) + { + RemoveSocket(Manager, Socket->Handle); + *Socket = {}; + Result = true; + } + else + { + InvalidCodePath; + } + } + return Result; +} + internal bool CloseSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle) { bool Result = false; platform_socket* Socket = SocketManagerGetSocket(Manager, Handle); - if (Socket) - { - if (Manager->CloseSocketProc(Socket)) - { - Manager->SocketsUsed[Handle.Index] = false; - *Socket = {}; - Result = true; - } - } - return Result; + return CloseSocket(Manager, Socket); } // NOTE(pjs): returns true if the socket is connected @@ -3662,7 +3698,7 @@ SocketQueryStatus(platform_socket_manager* Manager, platform_socket_handle_ Sock platform_socket* Socket = SocketManagerGetSocket(Manager, SocketHandle); if (Socket) { - Result = Manager->SocketQueryStatusProc(Socket); + Result = Manager->SocketQueryStatusProc(Manager, Socket); } return Result; } @@ -3674,7 +3710,7 @@ SocketPeek(platform_socket_manager* Manager, platform_socket_handle_ SocketHandl platform_socket* Socket = SocketManagerGetSocket(Manager, SocketHandle); if (Socket) { - Result = Manager->SocketPeekProc(Socket); + Result = Manager->SocketPeekProc(Manager, Socket); } return Result; } @@ -3686,7 +3722,7 @@ SocketRecieve(platform_socket_manager* Manager, platform_socket_handle_ SocketHa platform_socket* Socket = SocketManagerGetSocket(Manager, SocketHandle); if (Socket) { - Result = Manager->SocketRecieveProc(Socket, Storage); + Result = Manager->SocketRecieveProc(Manager, Socket, Storage); } return Result; } @@ -3698,7 +3734,7 @@ SocketSend(platform_socket_manager* Manager, platform_socket_handle_ SocketHandl platform_socket* Socket = SocketManagerGetSocket(Manager, SocketHandle); if (Socket) { - s32 SizeSent = Manager->SocketSendProc(Socket, Address, Port, Data, Flags); + s32 SizeSent = Manager->SocketSendProc(Manager, Socket, Address, Port, Data, Flags); Result = (SizeSent == Data.Size); } return Result; diff --git a/src/gs_libs/gs_types.h b/src/gs_libs/gs_types.h index 243f51b..5006ffe 100644 --- a/src/gs_libs/gs_types.h +++ b/src/gs_libs/gs_types.h @@ -1158,31 +1158,34 @@ typedef struct platform_socket_handle_ typedef struct platform_socket { + platform_socket_handle_ Handle; char Addr[128]; char Port[32]; u8* PlatformHandle; } platform_socket; -#define CONNECT_SOCKET(name) bool name(platform_socket* Socket) +typedef struct platform_socket_manager platform_socket_manager; + +#define CONNECT_SOCKET(name) bool name(platform_socket_manager* Manager, platform_socket* Socket) typedef CONNECT_SOCKET(platform_connect_socket); -#define CLOSE_SOCKET(name) bool name(platform_socket* Socket) +#define CLOSE_SOCKET(name) bool name(platform_socket_manager* Manager, platform_socket* Socket) typedef CLOSE_SOCKET(platform_close_socket); -#define SOCKET_QUERY_STATUS(name) bool name(platform_socket* Socket) +#define SOCKET_QUERY_STATUS(name) bool name(platform_socket_manager* Manager, platform_socket* Socket) typedef SOCKET_QUERY_STATUS(platform_socket_query_status); -#define SOCKET_PEEK(name) u32 name(platform_socket* Socket) +#define SOCKET_PEEK(name) u32 name(platform_socket_manager* Manager, platform_socket* Socket) typedef SOCKET_PEEK(platform_socket_peek); // TODO(pjs): allow for a size parameter that can be zero // if provided, that is how big the message it expects to be // if it equals zero, the proc will peek at the message first to determine // the needed size -#define SOCKET_RECEIVE(name) gs_data name(platform_socket* Socket, gs_memory_arena* Storage) +#define SOCKET_RECEIVE(name) gs_data name(platform_socket_manager* Manager, platform_socket* Socket, gs_memory_arena* Storage) typedef SOCKET_RECEIVE(platform_socket_receive); -#define SOCKET_SEND(name) s32 name(platform_socket* Socket, u32 Address, u32 Port, gs_data Data, s32 Flags) +#define SOCKET_SEND(name) s32 name(platform_socket_manager* Manager, platform_socket* Socket, u32 Address, u32 Port, gs_data Data, s32 Flags) typedef SOCKET_SEND(platform_socket_send); #define SOCKETS_COUNT_MAX 32