Finished preliminary socket layer and win32 implementation.

This commit is contained in:
Peter Slattery 2021-01-30 14:01:04 -08:00
parent 070773437d
commit cd6bee6d7e
10 changed files with 163 additions and 30 deletions

View File

@ -10,9 +10,13 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
{
mic_listen_job_data* Data = (mic_listen_job_data*)UserData;
gs_data Msg = {};
while (true)
{
gs_data Msg = SocketRecieve(Data->SocketManager, Data->ListenSocket, Ctx->Transient);
#if 0
// TODO(pjs): Make this a peek operation
Msg = SocketRecieve(Data->SocketManager, Data->ListenSocket, Ctx->Transient);
if (Msg.Size > 0)
{
OutputDebugStringA("Listened");
@ -22,6 +26,23 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
Data->MicPacketBuffer->WriteHead = 0;
}
}
#endif
while (Data->OutgoingMsgQueue->ReadHead != Data->OutgoingMsgQueue->WriteHead)
{
u32 ReadIndex = Data->OutgoingMsgQueue->ReadHead++;
if (Data->OutgoingMsgQueue->ReadHead >= BLUMEN_MESSAGE_QUEUE_COUNT)
{
Data->OutgoingMsgQueue->ReadHead = 0;
}
Msg = Data->OutgoingMsgQueue->Buffers[ReadIndex];
u32 Address = 0;
u32 Port = 0;
s32 Flags = 0;
SocketSend(Data->SocketManager, Data->ListenSocket, Address, Port, Msg, Flags);
OutputDebugStringA("Wrote\n");
}
}
CloseSocket(Data->SocketManager, Data->ListenSocket);
@ -41,15 +62,13 @@ BlumenLumen_CustomInit(app_state* State, context Context)
blumen_lumen_state* BLState = (blumen_lumen_state*)Result.Memory;
BLState->MicListenJobData.SocketManager = Context.SocketManager;
BLState->MicListenJobData.MicPacketBuffer = &BLState->MicPacketBuffer;
BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue;
BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185");
BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData);
#if 1
gs_const_string SculpturePath = ConstString("data/test_blumen.fold");
LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, SculpturePath, State->GlobalLog);
#endif
{ // Animation PLAYGROUND
animation Anim0 = {0};
@ -122,17 +141,40 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
State->AnimationSystem.ActiveAnimationIndex = 2;
}
gs_string TempString = PushStringF(State->Transient, 256, "%.*s", 32, Packet.AnimationFileName);
NullTerminate(&TempString);
OutputDebugStringA("Received\n");
OutputDebugStringA(TempString.Str);
if (BLState->MicPacketBuffer.ReadHead >= PACKETS_MAX)
{
BLState->MicPacketBuffer.ReadHead = 0;
}
}
if ((BLState->OutgoingMsgQueue.WriteHead >= BLState->OutgoingMsgQueue.ReadHead) ||
(BLState->OutgoingMsgQueue.WriteHead < BLState->OutgoingMsgQueue.ReadHead))
{
u32 WriteIndex = BLState->OutgoingMsgQueue.WriteHead;
if (BLState->OutgoingMsgQueue.WriteHead >= BLUMEN_MESSAGE_QUEUE_COUNT)
{
BLState->OutgoingMsgQueue.WriteHead = 0;
}
gs_data* Msg = BLState->OutgoingMsgQueue.Buffers + WriteIndex;
if (Msg->Size == 0)
{
*Msg = PushSizeToData(&State->Permanent, sizeof(motor_packet));
}
motor_packet* Packet = (motor_packet*)Msg->Memory;
Packet->FlowerPositions[0] = 5;
Packet->FlowerPositions[0] = 4;
Packet->FlowerPositions[0] = 9;
// NOTE(pjs): We increment the write head AFTER we've written so that
// the network thread doesn't think the buffer is ready to send before
// the data is set. We want to avoid the case of:
// 1. Main Thread increments write head to 1
// 2. Network Thread thinks theres a new message to send at 0
// 3. Network Thread sends the message at 0
// 4. Main Thread sets the message at 0
BLState->OutgoingMsgQueue.WriteHead += 1;
}
}

View File

@ -24,18 +24,32 @@ struct microphone_packet
};
#pragma pack(pop)
#define BLUMEN_MESSAGE_QUEUE_COUNT 32
typedef struct blumen_network_msg_queue
{
gs_data Buffers[BLUMEN_MESSAGE_QUEUE_COUNT];
u32 WriteHead;
u32 ReadHead;
} blumen_network_msg_queue;
// TODO(pjs): Refactor this -> blumen_network_job_state
struct mic_listen_job_data
{
platform_socket_manager* SocketManager;
packet_ringbuffer* MicPacketBuffer;
platform_socket_handle_ ListenSocket;
blumen_network_msg_queue* OutgoingMsgQueue;
};
struct blumen_lumen_state
{
packet_ringbuffer MicPacketBuffer;
blumen_network_msg_queue OutgoingMsgQueue;
temp_job_req JobReq;
platform_thread_handle MicListenThread;
mic_listen_job_data MicListenJobData;
};

View File

@ -610,7 +610,7 @@ PlayBar_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Pan
ui_interface* Interface = &State->Interface;
ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("PlayBar Layout"));
ui_FillRect(Interface, Bounds, Interface->Style.PanelBGColors[0]);
ui_FillRect(Interface, Bounds, Interface->Style.PanelBG);
ui_BeginRow(&State->Interface, 4);
{
if (ui_Button(Interface, MakeString("Pause")))
@ -645,7 +645,7 @@ FrameCount_Render(animation_timeline_state* TimelineState, rect2 Bounds, render_
s32 VisibleFrameCount = VisibleFrames.Max - VisibleFrames.Min;
ui_FillRect(Interface, Bounds, Interface->Style.PanelBGColors[0]);
ui_FillRect(Interface, Bounds, Interface->Style.PanelBG);
// Frame Ticks
u32 TickCount = 10;
@ -692,7 +692,7 @@ LayerList_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* P
ui_interface* Interface = &State->Interface;
animation ActiveAnim = *AnimationSystem_GetActiveAnimation(&State->AnimationSystem);
ui_FillRect(Interface, Bounds, Interface->Style.PanelBGColors[0]);
ui_FillRect(Interface, Bounds, Interface->Style.PanelBG);
v2 LayerDim = { Rect2Width(Bounds), LAYER_HEIGHT };
rect2 LayerBounds = {0};
@ -801,7 +801,7 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel
ui_interface* Interface = &State->Interface;
ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("AnimInfo Layout"));
ui_FillRect(&State->Interface, Bounds, Interface->Style.PanelBGColors[0]);
ui_FillRect(&State->Interface, Bounds, Interface->Style.PanelBG);
if (ui_BeginLabeledDropdown(Interface, MakeString("Active Animation"), ActiveAnim->Name))
{

View File

@ -58,18 +58,15 @@ INITIALIZE_APPLICATION(InitializeApplication)
interface_config IConfig = {0};
IConfig.FontSize = 14;
IConfig.PanelBGColors[0] = v4{.3f, .3f, .3f, 1};
IConfig.PanelBGColors[1] = v4{.4f, .4f, .4f, 1};
IConfig.PanelBGColors[2] = v4{.5f, .5f, .5f, 1};
IConfig.PanelBGColors[3] = v4{.6f, .6f, .6f, 1};
IConfig.PanelBG = v4{ .3f, .3f, .3f, 1.f };
IConfig.ButtonColor_Inactive = BlackV4;
IConfig.ButtonColor_Active = v4{.1f, .1f, .1f, 1};
IConfig.ButtonColor_Selected = v4{.3f, .3f, .3f, 1};
IConfig.ButtonColor_Active = v4{ .1f, .1f, .1f, 1.f };
IConfig.ButtonColor_Selected = v4{ .3f, .3f, .3f, 1.f };
IConfig.TextColor = WhiteV4;
IConfig.ListBGColors[0] = v4{ .16f, .16f, .16f, 1.f };
IConfig.ListBGColors[1] = v4{ .18f, .18f, .18f, 1.f };
IConfig.ListBGHover = v4{ .22f, .22f, .22f, 1.f };
IConfig.ListBGSelected = v4{.44f, .44f, .44f, 1.f };
IConfig.ListBGSelected = v4{ .44f, .44f, .44f, 1.f };
IConfig.Margin = v2{5, 5};
State->Interface = ui_InterfaceCreate(Context, IConfig, &State->Permanent);

View File

@ -315,7 +315,7 @@ struct ui_eval_result
struct interface_config
{
v4 PanelBGColors[4];
v4 PanelBG;
// TODO(pjs): Turn these into _Default, _Hot, _Active
v4 ButtonColor_Inactive, ButtonColor_Active, ButtonColor_Selected;

View File

@ -497,7 +497,7 @@ WinMain (
*Context.ThreadManager = CreatePlatformThreadManager(Win32CreateThread, Win32KillThread);
Context.SocketManager = PushStruct(&PlatformPermanent, platform_socket_manager);
*Context.SocketManager = CreatePlatformSocketManager(Win32CreateSocket, Win32CloseSocket, Win32SocketReceive);
*Context.SocketManager = CreatePlatformSocketManager(Win32CreateSocket, Win32CloseSocket, Win32SocketReceive, Win32SocketSend);
win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName);
if (!ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, true)) { return -1; }
@ -512,6 +512,8 @@ WinMain (
addressed_data_buffer_list OutputData = AddressedDataBufferList_Create(ThreadContext);
Context.InitializeApplication(Context);
Running = true;
Context.WindowIsVisible = true;
while (Running)
@ -588,6 +590,7 @@ WinMain (
Win32SocketSystem_Cleanup();
Win32WorkQueue_Cleanup();
Win32_TestCode_SocketReading_Cleanup();
return 0;
}

View File

@ -226,6 +226,34 @@ Win32SocketReceive(platform_socket* Socket, gs_memory_arena* Storage)
#endif
}
internal s32
Win32SocketSend(platform_socket* Socket, u32 Address, u32 Port, gs_data Data, s32 Flags)
{
SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle;
sockaddr_in SockAddress = {};
SockAddress.sin_family = AF_INET;
SockAddress.sin_port = HostToNetU16(Port);
SockAddress.sin_addr.s_addr = HostToNetU32(Address);
s32 LengthSent = sendto(*Win32Sock, (char*)Data.Memory, Data.Size, Flags, (sockaddr*)&SockAddress, sizeof(sockaddr_in));
if (LengthSent == SOCKET_ERROR)
{
s32 Error = WSAGetLastError();
if (Error == 10051)
{
}
else
{
// TODO(Peter): :ErrorLogging
InvalidCodePath;
}
}
return LengthSent;
}
internal s32
Win32Socket_SetOption(win32_socket* Socket, s32 Level, s32 Option, const char* OptionValue, s32 OptionLength)
{
@ -323,8 +351,19 @@ Win32Socket_Receive(win32_socket* Socket, gs_memory_arena* Storage)
{
// TODO(pjs): Error logging
s32 Error = WSAGetLastError();
if (Error == 10053)
{
// WSAECONNABORTED - aborted by the software
}
else if (Error == 10093)
{
// WSANOTINITIALISED
}
else
{
InvalidCodePath;
}
}
Result.Size = BytesReceived;
return Result;
#endif

View File

@ -35,6 +35,7 @@ Win32_TestCode_UART(gs_thread_context ThreadContext)
#endif
win32_socket ListenSocket;
HANDLE ListenThread;
DWORD WINAPI
Win32_TestCode_ListenThreadProc(LPVOID ThreadData)
@ -54,7 +55,7 @@ Win32_TestCode_SocketReading(gs_thread_context ThreadContext, temp_job_req* Req)
{
ListenSocket = Win32Socket_ConnectToAddress("127.0.0.1", "20185");
u8* Arg = (u8*)Req;
HANDLE Handle = CreateThread(0, 0, &Win32_TestCode_ListenThreadProc, Arg, 0, 0);
ListenThread = CreateThread(0, 0, &Win32_TestCode_ListenThreadProc, Arg, 0, 0);
}
internal void
@ -74,5 +75,12 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
}
}
internal void
Win32_TestCode_SocketReading_Cleanup()
{
TerminateThread(ListenThread, 0);
Win32Socket_Close(&ListenSocket);
}
#define WIN32_TEST_CODE_CPP
#endif // WIN32_TEST_CODE_CPP

View File

@ -3364,16 +3364,22 @@ SOCKET_RECEIVE(PlatformSocketRecieve_Stub)
return {};
}
SOCKET_SEND(PlatformSocketSend_Stub)
{
return false;
}
internal platform_socket_manager
CreatePlatformSocketManager(platform_create_socket* CreateSocketProc,
platform_close_socket* CloseSocketProc,
platform_socket_receive* SocketRecieveProc)
platform_socket_receive* SocketRecieveProc,
platform_socket_send* SocketSendProc)
{
platform_socket_manager Result = {};
Result.CreateSocketProc = CreateSocketProc;
Result.CloseSocketProc = CloseSocketProc;
Result.SocketRecieveProc = SocketRecieveProc;
Result.SocketSendProc = SocketSendProc;
if (!CreateSocketProc)
{
@ -3387,6 +3393,10 @@ CreatePlatformSocketManager(platform_create_socket* CreateSocketProc,
{
Result.SocketRecieveProc = PlatformSocketRecieve_Stub;
}
if (!SocketSendProc)
{
Result.SocketSendProc = PlatformSocketSend_Stub;
}
return Result;
}
@ -3440,6 +3450,22 @@ SocketRecieve(platform_socket_manager* Manager, platform_socket_handle_ SocketHa
return Result;
}
internal bool
SocketSend(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle, u32 Address, u32 Port, gs_data Data, s32 Flags)
{
bool Result = false;
if (Manager->SocketsUsed[SocketHandle.Index])
{
platform_socket* Socket = &Manager->Sockets[SocketHandle.Index];
if (Socket->PlatformHandle != 0)
{
s32 SizeSent = Manager->SocketSendProc(Socket, Address, Port, Data, Flags);
Result = (SizeSent == Data.Size);
}
}
return Result;
}
///////////////////////////
//
// Hashes

View File

@ -1107,6 +1107,9 @@ typedef CLOSE_SOCKET(platform_close_socket);
#define SOCKET_RECEIVE(name) gs_data name(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)
typedef SOCKET_SEND(platform_socket_send);
#define SOCKETS_COUNT_MAX 32
typedef struct platform_socket_manager
{
@ -1116,6 +1119,7 @@ typedef struct platform_socket_manager
platform_create_socket* CreateSocketProc;
platform_close_socket* CloseSocketProc;
platform_socket_receive* SocketRecieveProc;
platform_socket_send* SocketSendProc;
} platform_socket_manager;
#define GS_TYPES_H
#endif // GS_TYPES_H