sanity tests, path handling, file lister update and began working on saving files

This commit is contained in:
Peter Slattery 2021-03-06 18:17:00 -08:00
parent c68cb80ca4
commit b91a7a9a02
11 changed files with 132 additions and 47 deletions

View File

@ -34,6 +34,11 @@ cl %CommonCompilerFlags% %ProjectDevPath%\src\serial_monitor\first.cpp /Feserial
cl %CommonCompilerFlags% %ProjectDevPath%\src\sculpture_gen\gen_blumen_lumen.cpp /Fegen_blumen_lumen.exe /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib cl %CommonCompilerFlags% %ProjectDevPath%\src\sculpture_gen\gen_blumen_lumen.cpp /Fegen_blumen_lumen.exe /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib
REM COMPILE AND RUN TESTS
cl %CommonCompilerFlags% %ProjectDevPath%\src\tests\sanity_tests.cpp /Fesanity_tests.exe /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib
sanity_tests.exe
popd popd
call %MyPath%\_postbuild_win32.bat call %MyPath%\_postbuild_win32.bat

View File

@ -126,7 +126,9 @@ BlumenLumen_CustomInit(app_state* State, context Context)
BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue; BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue;
BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185"); BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185");
#if 0
BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData); BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData);
#endif
gs_const_string SculpturePath = ConstString("data/test_blumen.fold"); gs_const_string SculpturePath = ConstString("data/test_blumen.fold");
LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, SculpturePath, State->GlobalLog); LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, SculpturePath, State->GlobalLog);

View File

@ -792,6 +792,29 @@ TimeRange_Render(animation_timeline_state* TimelineState, rect2 Bounds, render_c
} }
} }
internal void
AnimInfoView_SaveAnimFile (gs_const_string Path, app_state* State, context Context)
{
u32 ActiveAnimIndex = State->AnimationSystem.ActiveAnimationIndex;
animation ActiveAnimation = State->AnimationSystem.Animations.Values[ActiveAnimIndex];
gs_string FileText = AnimSerializer_Serialize(ActiveAnimation, State->Patterns, State->Transient);
if (!WriteEntireFile(Context.ThreadContext.FileHandler, Path, StringToData(FileText)))
{
InvalidCodePath;
}
}
PANEL_MODAL_OVERRIDE_CALLBACK(AnimInfoView_SaveAnimFileCallback)
{
Assert(ReturningFrom->TypeIndex == PanelType_FileView);
file_view_state* FileViewState = Panel_GetStateStruct(ReturningFrom, file_view_state);
gs_file_info FileInfo = FileViewState->SelectedFile;
AnimInfoView_SaveAnimFile(FileInfo.Path, State, Context);
}
internal void internal void
AnimInfoView_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context) AnimInfoView_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
@ -833,10 +856,14 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel
// need to use the file browser to create a file // need to use the file browser to create a file
u32 ActiveAnimIndex = State->AnimationSystem.ActiveAnimationIndex; u32 ActiveAnimIndex = State->AnimationSystem.ActiveAnimationIndex;
animation ActiveAnimation = State->AnimationSystem.Animations.Values[ActiveAnimIndex]; animation ActiveAnimation = State->AnimationSystem.Animations.Values[ActiveAnimIndex];
gs_string FileText = AnimSerializer_Serialize(ActiveAnimation, State->Patterns, State->Transient);
if (WriteEntireFile(Context.ThreadContext.FileHandler, ActiveAnimation.FileInfo.Path, StringToData(FileText))) if (!ActiveAnimation.FileInfo.Path.Str)
{ {
InvalidCodePath; panel* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context);
FileView_SetMode(FileBrowser, FileViewMode_Save);
Panel_PushModalOverride(Panel, FileBrowser, AnimInfoView_SaveAnimFileCallback);
} else {
AnimInfoView_SaveAnimFile(ActiveAnimation.FileInfo.Path, State, Context);
} }
} }
if (ui_Button(Interface, MakeString("Load"))) if (ui_Button(Interface, MakeString("Load")))

View File

@ -49,30 +49,31 @@ s32 FileView_CommandsCount = 0;
internal void internal void
FileView_UpdateWorkingDirectory(gs_const_string WorkingDirectory, file_view_state* State, context Context) FileView_UpdateWorkingDirectory(gs_const_string WorkingDirectory, file_view_state* State, context Context)
{ {
// NOTE(pjs): make sure we're only passing valid directory paths to the
// function
char LastChar = WorkingDirectory.Str[WorkingDirectory.Length - 1];
Assert(LastChar == '\\' || LastChar == '/');
ClearArena(&State->FileNamesArena); ClearArena(&State->FileNamesArena);
gs_const_string SanitizedDirectory = WorkingDirectory; gs_string SanitizedDir = PushString(Context.ThreadContext.Transient, WorkingDirectory.Length + 2);
SanitizePath(WorkingDirectory, &SanitizedDir, Context.ThreadContext.Transient);
u32 LastSlashIndex = FindLast(SanitizedDirectory, '\\'); if (SanitizedDir.Str[SanitizedDir.Length - 1] != '\\')
gs_const_string LastDir = Substring(SanitizedDirectory, LastSlashIndex + 1, SanitizedDirectory.Length);
if (StringsEqual(LastDir, ConstString("..")))
{ {
u32 SecondLastSlashIndex = FindLast(SanitizedDirectory, LastSlashIndex - 1, '\\'); AppendPrintF(&SanitizedDir, "\\");
SanitizedDirectory = Substring(SanitizedDirectory, 0, SecondLastSlashIndex);
}
else if (StringsEqual(LastDir, ConstString(".")) && LastDir.Length > 1)
{
SanitizedDirectory = Substring(SanitizedDirectory, 0, LastSlashIndex);
} }
gs_file_info NewWorkingDirectory = GetFileInfo(Context.ThreadContext.FileHandler, SanitizedDirectory); gs_file_info NewWorkingDir = GetFileInfo(Context.ThreadContext.FileHandler, SanitizedDir.ConstString);
if (NewWorkingDirectory.IsDirectory) if (NewWorkingDir.IsDirectory)
{ {
AppendPrintF(&SanitizedDir, "*");
NullTerminate(&SanitizedDir);
State->FileNames = EnumerateDirectory(Context.ThreadContext.FileHandler, &State->FileNamesArena, SanitizedDir.ConstString, EnumerateDirectory_IncludeDirectories);
// NOTE(pjs): we might be printing from State->WorkingDirectory to State->WorkingDirectory // NOTE(pjs): we might be printing from State->WorkingDirectory to State->WorkingDirectory
// in some cases. Shouldn't be a problem but it is unnecessary // in some cases. Shouldn't be a problem but it is unnecessary
PrintF(&State->WorkingDirectory, "%S", WorkingDirectory); PrintF(&State->WorkingDirectory, "%S", SanitizedDir.ConstString);
State->FileNames = EnumerateDirectory(Context.ThreadContext.FileHandler, &State->FileNamesArena, State->WorkingDirectory.ConstString, EnumerateDirectory_IncludeDirectories);
} }
} }
@ -88,7 +89,7 @@ FileView_Init(panel* Panel, app_state* State, context Context)
// TODO(pjs): this shouldn't be stored in permanent // TODO(pjs): this shouldn't be stored in permanent
FileViewState->WorkingDirectory = PushString(&State->Permanent, 256); FileViewState->WorkingDirectory = PushString(&State->Permanent, 256);
FileView_UpdateWorkingDirectory(ConstString("."), FileViewState, Context); FileView_UpdateWorkingDirectory(ConstString(".\\"), FileViewState, Context);
} }
GSMetaTag(panel_cleanup); GSMetaTag(panel_cleanup);
@ -105,14 +106,26 @@ internal void
FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
{ {
file_view_state* FileViewState = Panel_GetStateStruct(Panel, file_view_state); file_view_state* FileViewState = Panel_GetStateStruct(Panel, file_view_state);
Assert(FileViewState->Mode == FileViewMode_Save);
ui_PushLayout(&State->Interface, PanelBounds, LayoutDirection_TopDown, MakeString("FileView Layout")); ui_PushLayout(&State->Interface, PanelBounds, LayoutDirection_TopDown, MakeString("FileView Layout"));
{ {
ui_BeginRow(&State->Interface, 3);
{
if (FileViewState->Mode == FileViewMode_Save)
{
if (ui_Button(&State->Interface, MakeString("Save")))
{
FileView_Exit_(Panel, State, Context);
}
}
if (ui_Button(&State->Interface, MakeString("Exit"))) if (ui_Button(&State->Interface, MakeString("Exit")))
{ {
FileView_Exit_(Panel, State, Context); FileView_Exit_(Panel, State, Context);
} }
}
ui_EndRow(&State->Interface);
// Header // Header
if (ui_TextEntry(&State->Interface, MakeString("pwd"), &FileViewState->WorkingDirectory)) if (ui_TextEntry(&State->Interface, MakeString("pwd"), &FileViewState->WorkingDirectory))
@ -137,7 +150,7 @@ FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBu
{ {
gs_file_info File = FileViewState->FileNames.Values[i]; gs_file_info File = FileViewState->FileNames.Values[i];
u32 LastSlashIndex = FindLast(File.Path, '\\'); u32 LastSlashIndex = FindLast(File.Path, File.Path.Length - 2, '\\');
gs_const_string FileName = Substring(File.Path, LastSlashIndex + 1, File.Path.Length); gs_const_string FileName = Substring(File.Path, LastSlashIndex + 1, File.Path.Length);
gs_string PathString = PushString(State->Transient, FileName.Length); gs_string PathString = PushString(State->Transient, FileName.Length);
PrintF(&PathString, "%S", FileName); PrintF(&PathString, "%S", FileName);
@ -149,9 +162,20 @@ FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBu
FileView_UpdateWorkingDirectory(File.Path, FileViewState, Context); FileView_UpdateWorkingDirectory(File.Path, FileViewState, Context);
} }
else else
{
switch (FileViewState->Mode)
{ {
FileViewState->SelectedFile = File; FileViewState->SelectedFile = File;
case FileViewMode_Load:
{
FileView_Exit_(Panel, State, Context); FileView_Exit_(Panel, State, Context);
} break;
case FileViewMode_Save:
{
} break;
}
} }
} }
} }

View File

@ -69,7 +69,7 @@ HierarchyView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Ren
if (ui_Button(&State->Interface, MakeString("+ Add Assembly"))) if (ui_Button(&State->Interface, MakeString("+ Add Assembly")))
{ {
panel* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context); panel* FileBrowser = PanelSystem_PushPanel(&State->PanelSystem, PanelType_FileView, State, Context);
FileView_SetMode(FileBrowser, FileViewMode_Save); FileView_SetMode(FileBrowser, FileViewMode_Load);
Panel_PushModalOverride(Panel, FileBrowser, LoadAssemblyCallback); Panel_PushModalOverride(Panel, FileBrowser, LoadAssemblyCallback);
} }
ui_EndRow(&State->Interface); ui_EndRow(&State->Interface);

View File

@ -57,7 +57,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128); State->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128);
State->AssemblyDebugState = AssemblyDebug_Create(&State->Permanent); State->AssemblyDebugState = AssemblyDebug_Create(&State->Permanent);
State->AssemblyDebugState.Brightness = 255; State->AssemblyDebugState.Brightness = 255;
State->AssemblyDebugState.Override = ADS_Override_AllBlue; State->AssemblyDebugState.Override = ADS_Override_None;
GlobalDebugServices->Interface.RenderSculpture = true; GlobalDebugServices->Interface.RenderSculpture = true;
@ -80,7 +80,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
Panel_SetType(Profiler, &State->PanelSystem, PanelType_ProfilerView, State, Context); Panel_SetType(Profiler, &State->PanelSystem, PanelType_ProfilerView, State, Context);
panel* Hierarchy = LeftPanel->Left; panel* Hierarchy = LeftPanel->Left;
Panel_SetType(Hierarchy, &State->PanelSystem, PanelType_HierarchyView, State, Context); Panel_SetType(Hierarchy, &State->PanelSystem, PanelType_AssemblyDebug, State, Context);
} }

View File

@ -11,6 +11,7 @@
#include "..\gs_libs\gs_types.h" #include "..\gs_libs\gs_types.h"
#include "..\gs_libs\gs_types.cpp" #include "..\gs_libs\gs_types.cpp"
#include "..\gs_libs\gs_path.h"
struct handle struct handle
{ {

View File

@ -523,6 +523,8 @@ SetWorkingDirectory(HINSTANCE HInstance, gs_thread_context ThreadContext)
return Result; return Result;
} }
#include "../../gs_libs/gs_path.h"
int WINAPI int WINAPI
WinMain ( WinMain (
HINSTANCE HInstance, HINSTANCE HInstance,
@ -533,6 +535,11 @@ WinMain (
{ {
gs_thread_context ThreadContext = Win32CreateThreadContext(); gs_thread_context ThreadContext = Win32CreateThreadContext();
gs_file_info A = GetFileInfo(ThreadContext.FileHandler, ConstString("C:\\projects\\Lumenarium"));
gs_file_info B = GetFileInfo(ThreadContext.FileHandler, ConstString("C:\\projects\\Lumenarium\\"));
if (!SetWorkingDirectory(HInstance, ThreadContext)) return 1; if (!SetWorkingDirectory(HInstance, ThreadContext)) return 1;
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents); MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
@ -629,7 +636,7 @@ WinMain (
Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData); Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData);
bool Multithread = false; bool Multithread = true;
if (Multithread) if (Multithread)
{ {
for (addressed_data_buffer* At = OutputData.Root; for (addressed_data_buffer* At = OutputData.Root;

View File

@ -178,28 +178,39 @@ Win32SetFileInfoFromFindFileData(gs_file_info* Info, WIN32_FIND_DATA FindFileDat
{ {
u32 FileNameLength = CharArrayLength(FindFileData.cFileName); u32 FileNameLength = CharArrayLength(FindFileData.cFileName);
// NOTE(Peter): String Storage
// Storing the string in the final storage means we don't have to copy the string later, and all
// strings will be continguous in memory at the calling site, though they will be before the array
gs_string FileName = PushString(Storage, SearchPath.Length + FileNameLength + 1);
PrintF(&FileName, "%S%.*s", SearchPath, FileName.Size, FindFileData.cFileName);
NullTerminate(&FileName);
Info->FileSize = Win32HighLowToU64(FindFileData.nFileSizeLow, FindFileData.nFileSizeHigh); Info->FileSize = Win32HighLowToU64(FindFileData.nFileSizeLow, FindFileData.nFileSizeHigh);
Info->CreationTime = Win32FileTimeToU64(FindFileData.ftCreationTime); Info->CreationTime = Win32FileTimeToU64(FindFileData.ftCreationTime);
Info->LastWriteTime = Win32FileTimeToU64(FindFileData.ftLastWriteTime); Info->LastWriteTime = Win32FileTimeToU64(FindFileData.ftLastWriteTime);
Info->Path = FileName.ConstString;
Info->IsDirectory = HasFlag(FindFileData.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY); Info->IsDirectory = HasFlag(FindFileData.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY);
// NOTE(Peter): String Storage
// Storing the string in the final storage means we don't have to copy the string later, and all
// strings will be continguous in memory at the calling site, though they will be before the array
gs_string FileName = PushString(Storage, SearchPath.Length + FileNameLength + 2);
PrintF(&FileName, "%S%.*s", SearchPath, FileName.Size, FindFileData.cFileName);
if (Info->IsDirectory)
{
AppendPrintF(&FileName, "\\");
}
NullTerminate(&FileName);
Info->Path = FileName.ConstString;
} }
internal u32 internal u32
Win32EnumerateDirectoryIntoTempList(gs_file_handler FileHandler, temp_file_list* TempList, gs_const_string Path, gs_memory_arena* Storage, b32 Flags) Win32EnumerateDirectoryIntoTempList(gs_file_handler FileHandler, temp_file_list* TempList, gs_const_string Path, gs_memory_arena* Storage, b32 Flags)
{ {
u32 FilesCount = 0; u32 FilesCount = 0;
Assert(Path.Str[Path.Length - 1] != '\\' &&
Path.Str[Path.Length - 1] != '/');
gs_const_string SearchPath = Path;
s64 IndexOfLastSlash = FindLastFromSet(Path, "\\/"); gs_const_string SearchPathDir = SearchPath;
Assert(IndexOfLastSlash >= 0); s64 LastSlash = FindLastFromSet(SearchPath, "\\/");
gs_const_string SearchPath = Substring(Path, 0, IndexOfLastSlash + 1); if (LastSlash >= 0)
{
SearchPathDir = Substring(SearchPath, 0, LastSlash + 1);
}
WIN32_FIND_DATA FindFileData; WIN32_FIND_DATA FindFileData;
HANDLE SearchHandle = FindFirstFile(Path.Str, &FindFileData); HANDLE SearchHandle = FindFirstFile(Path.Str, &FindFileData);
@ -211,15 +222,18 @@ Win32EnumerateDirectoryIntoTempList(gs_file_handler FileHandler, temp_file_list*
if (HasFlag(FindFileData.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) if (HasFlag(FindFileData.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY))
{ {
gs_const_string SubDirName = ConstString(FindFileData.cFileName);
bool IsNav = (StringsEqual(SubDirName, ConstString(".")) ||
StringsEqual(SubDirName, ConstString("..")));
if (HasFlag(Flags, EnumerateDirectory_Recurse)) if (HasFlag(Flags, EnumerateDirectory_Recurse))
{ {
gs_const_string SubDirName = ConstString(FindFileData.cFileName); if (!IsNav)
if (!StringsEqual(SubDirName, ConstString(".")) &&
!StringsEqual(SubDirName, ConstString("..")))
{ {
gs_string SubDirectoryPath = PushString(FileHandler.Transient, SearchPath.Length + SubDirName.Length + 3); gs_string SubDirectoryPath = PushString(FileHandler.Transient, SearchPath.Length + SubDirName.Length + 3);
PrintF(&SubDirectoryPath, "%S%S/*\0", SearchPath, SubDirName); PrintF(&SubDirectoryPath, "%S%S/*\0", SearchPath, SubDirName);
FilesCount += Win32EnumerateDirectoryIntoTempList(FileHandler, TempList, SubDirectoryPath.ConstString, Storage, Flags); FilesCount += Win32EnumerateDirectoryIntoTempList(FileHandler, TempList, SubDirectoryPath.ConstString,
Storage, Flags);
} }
} }
@ -230,7 +244,7 @@ Win32EnumerateDirectoryIntoTempList(gs_file_handler FileHandler, temp_file_list*
{ {
temp_file_list_entry* File = PushStruct(FileHandler.Transient, temp_file_list_entry); temp_file_list_entry* File = PushStruct(FileHandler.Transient, temp_file_list_entry);
*File = {0}; *File = {0};
Win32SetFileInfoFromFindFileData(&File->Info, FindFileData, SearchPath, Storage); Win32SetFileInfoFromFindFileData(&File->Info, FindFileData, SearchPathDir, Storage);
SLLPushOrInit(TempList->First, TempList->Last, File); SLLPushOrInit(TempList->First, TempList->Last, File);
FilesCount += 1; FilesCount += 1;
} }

View File

@ -146,6 +146,11 @@ Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
// ie. the usb stick was removed // ie. the usb stick was removed
}break; }break;
case ERROR_ACCESS_DENIED:
{
// ??
}break;
case ERROR_INVALID_HANDLE: case ERROR_INVALID_HANDLE:
InvalidDefaultCase; InvalidDefaultCase;
} }

View File

@ -191,7 +191,7 @@ int main(int ArgCount, char** Args)
u32 BloomInnerChannels[] = { FSC(0, 0), FSC(0, 1), FSC(0, 2), FSC(0, 3), FSC(0, 4), FSC(0, 5) }; u32 BloomInnerChannels[] = { FSC(0, 0), FSC(0, 1), FSC(0, 2), FSC(0, 3), FSC(0, 4), FSC(0, 5) };
flower_desc F0 = {}; flower_desc F0 = {};
F0.Pos = v3{-1, 0, 0}; F0.Pos = v3{-1, 0, 0};
F0.ComPort = "\\\\.\\COM4"; F0.ComPort = "\\\\.\\COM11";
F0.FlowerTagValue = "left"; F0.FlowerTagValue = "left";
F0.StemChannels = StemChannels; F0.StemChannels = StemChannels;
F0.BloomOuterChannels = BloomOuterChannels; F0.BloomOuterChannels = BloomOuterChannels;
@ -200,7 +200,7 @@ int main(int ArgCount, char** Args)
flower_desc F1 = {}; flower_desc F1 = {};
F1.Pos = v3{0, 0, 0}; F1.Pos = v3{0, 0, 0};
F1.ComPort = "\\\\.\\COM5"; F1.ComPort = "\\\\.\\COM12";
F1.FlowerTagValue = "center"; F1.FlowerTagValue = "center";
F1.StemChannels = StemChannels; F1.StemChannels = StemChannels;
F1.BloomInnerChannels = BloomInnerChannels; F1.BloomInnerChannels = BloomInnerChannels;