abbandoning Lua... Error in runtime
This commit is contained in:
parent
cafced2917
commit
54703852e7
20 changed files with 1119 additions and 164 deletions
|
@ -7,10 +7,9 @@ private:
|
||||||
std::chrono::duration<float> timer{ 0 };
|
std::chrono::duration<float> timer{ 0 };
|
||||||
std::chrono::duration<float> tickRate;
|
std::chrono::duration<float> tickRate;
|
||||||
|
|
||||||
std::function<void()> callback;
|
|
||||||
public:
|
public:
|
||||||
TickSystem(std::chrono::duration<float> tickRateSeconds, std::function<void()> func)
|
TickSystem(std::chrono::duration<float> tickRateSeconds)
|
||||||
: tickRate(tickRateSeconds), callback(func) {
|
: tickRate(tickRateSeconds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(std::chrono::duration<float> deltaTime) {
|
bool update(std::chrono::duration<float> deltaTime) {
|
||||||
|
@ -23,6 +22,4 @@ public:
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void call() const { callback(); }
|
|
||||||
};
|
};
|
|
@ -122,7 +122,7 @@ struct linked_list
|
||||||
next->first = this;
|
next->first = this;
|
||||||
return *next;
|
return *next;
|
||||||
}
|
}
|
||||||
next->value = val;
|
next->put(val);
|
||||||
if (first)
|
if (first)
|
||||||
next->first = first;
|
next->first = first;
|
||||||
else
|
else
|
626
include/raylibs/modules/gui_window_file_dialog.hpp
Normal file
626
include/raylibs/modules/gui_window_file_dialog.hpp
Normal file
|
@ -0,0 +1,626 @@
|
||||||
|
#pragma once
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* Window File Dialog v1.2 - Modal file dialog to open/save files
|
||||||
|
*
|
||||||
|
* MODULE USAGE:
|
||||||
|
* #define GUI_WINDOW_FILE_DIALOG_IMPLEMENTATION
|
||||||
|
* #include "gui_window_file_dialog.h"
|
||||||
|
*
|
||||||
|
* INIT: GuiWindowFileDialogState state = GuiInitWindowFileDialog();
|
||||||
|
* DRAW: GuiWindowFileDialog(&state);
|
||||||
|
*
|
||||||
|
* NOTE: This module depends on some raylib file system functions:
|
||||||
|
* - LoadDirectoryFiles()
|
||||||
|
* - UnloadDirectoryFiles()
|
||||||
|
* - GetWorkingDirectory()
|
||||||
|
* - DirectoryExists()
|
||||||
|
* - FileExists()
|
||||||
|
*
|
||||||
|
* LICENSE: zlib/libpng
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||||
|
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||||
|
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||||
|
* in the product documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||||
|
* as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
#ifndef GUI_WINDOW_FILE_DIALOG_H
|
||||||
|
#define GUI_WINDOW_FILE_DIALOG_H
|
||||||
|
|
||||||
|
// Gui file dialog context data
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
// Window management variables
|
||||||
|
bool windowActive;
|
||||||
|
Rectangle windowBounds;
|
||||||
|
Vector2 panOffset;
|
||||||
|
bool dragMode;
|
||||||
|
bool supportDrag;
|
||||||
|
|
||||||
|
// UI variables
|
||||||
|
bool dirPathEditMode;
|
||||||
|
char dirPathText[1024];
|
||||||
|
|
||||||
|
int filesListScrollIndex;
|
||||||
|
bool filesListEditMode;
|
||||||
|
int filesListActive;
|
||||||
|
|
||||||
|
bool fileNameEditMode;
|
||||||
|
char fileNameText[1024];
|
||||||
|
bool SelectFilePressed;
|
||||||
|
bool CancelFilePressed;
|
||||||
|
int fileTypeActive;
|
||||||
|
int itemFocused;
|
||||||
|
|
||||||
|
// Custom state variables
|
||||||
|
FilePathList dirFiles;
|
||||||
|
char filterExt[256];
|
||||||
|
char dirPathTextCopy[1024];
|
||||||
|
char fileNameTextCopy[1024];
|
||||||
|
|
||||||
|
int prevFilesListActive;
|
||||||
|
|
||||||
|
bool saveFileMode;
|
||||||
|
|
||||||
|
} GuiWindowFileDialogState;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" { // Prevents name mangling of functions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
//...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// ...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Global Variables Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
//...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
GuiWindowFileDialogState InitGuiWindowFileDialog(const char* initPath);
|
||||||
|
void GuiWindowFileDialog(GuiWindowFileDialogState* state);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // GUI_WINDOW_FILE_DIALOG_H
|
||||||
|
|
||||||
|
/***********************************************************************************
|
||||||
|
*
|
||||||
|
* GUI_WINDOW_FILE_DIALOG IMPLEMENTATION
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
#if defined(GUI_WINDOW_FILE_DIALOG_IMPLEMENTATION)
|
||||||
|
|
||||||
|
#include <raylibs/raygui.h>
|
||||||
|
|
||||||
|
#include <string.h> // Required for: strcpy()
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#define MAX_DIRECTORY_FILES 2048
|
||||||
|
#define MAX_ICON_PATH_LENGTH 512
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define PATH_SEPERATOR "\\"
|
||||||
|
#else
|
||||||
|
#define PATH_SEPERATOR "/"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#if defined(USE_CUSTOM_LISTVIEW_FILEINFO)
|
||||||
|
// Detailed file info type
|
||||||
|
typedef struct FileInfo {
|
||||||
|
const char* name;
|
||||||
|
int size;
|
||||||
|
int modTime;
|
||||||
|
int type;
|
||||||
|
int icon;
|
||||||
|
} FileInfo;
|
||||||
|
#else
|
||||||
|
// Filename only
|
||||||
|
typedef char* FileInfo; // Files are just a path string
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Global Variables Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
FileInfo* dirFilesIcon = NULL; // Path string + icon (for fancy drawing)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Internal Module Functions Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Read files in new path
|
||||||
|
static void ReloadDirectoryFiles(GuiWindowFileDialogState* state);
|
||||||
|
|
||||||
|
#if defined(USE_CUSTOM_LISTVIEW_FILEINFO)
|
||||||
|
// List View control for files info with extended parameters
|
||||||
|
static int GuiListViewFiles(Rectangle bounds, FileInfo* files, int count, int* focus, int* scrollIndex, int active);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
GuiWindowFileDialogState InitGuiWindowFileDialog(const char* initPath)
|
||||||
|
{
|
||||||
|
GuiWindowFileDialogState state = { 0 };
|
||||||
|
|
||||||
|
// Init window data
|
||||||
|
state.windowBounds = { static_cast<float>(GetScreenWidth()) / 2 - 440 / 2, static_cast<float>(GetScreenHeight()) / 2 - 310 / 2, 440, 310 };
|
||||||
|
state.windowActive = false;
|
||||||
|
state.supportDrag = true;
|
||||||
|
state.dragMode = false;
|
||||||
|
state.panOffset = { 0, 0 };
|
||||||
|
|
||||||
|
// Init path data
|
||||||
|
state.dirPathEditMode = false;
|
||||||
|
state.filesListActive = -1;
|
||||||
|
state.prevFilesListActive = state.filesListActive;
|
||||||
|
state.filesListScrollIndex = 0;
|
||||||
|
|
||||||
|
state.fileNameEditMode = false;
|
||||||
|
|
||||||
|
state.SelectFilePressed = false;
|
||||||
|
state.CancelFilePressed = false;
|
||||||
|
|
||||||
|
state.fileTypeActive = 0;
|
||||||
|
|
||||||
|
strcpy(state.fileNameText, "\0");
|
||||||
|
|
||||||
|
// Custom variables initialization
|
||||||
|
if (initPath && DirectoryExists(initPath))
|
||||||
|
{
|
||||||
|
strcpy(state.dirPathText, initPath);
|
||||||
|
}
|
||||||
|
else if (initPath && FileExists(initPath))
|
||||||
|
{
|
||||||
|
strcpy(state.dirPathText, GetDirectoryPath(initPath));
|
||||||
|
strcpy(state.fileNameText, GetFileName(initPath));
|
||||||
|
}
|
||||||
|
else strcpy(state.dirPathText, GetWorkingDirectory());
|
||||||
|
|
||||||
|
// TODO: Why we keep a copy?
|
||||||
|
strcpy(state.dirPathTextCopy, state.dirPathText);
|
||||||
|
strcpy(state.fileNameTextCopy, state.fileNameText);
|
||||||
|
|
||||||
|
state.filterExt[0] = '\0';
|
||||||
|
//strcpy(state.filterExt, "all");
|
||||||
|
|
||||||
|
state.dirFiles.count = 0;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update and draw file dialog
|
||||||
|
void GuiWindowFileDialog(GuiWindowFileDialogState* state)
|
||||||
|
{
|
||||||
|
if (state->windowActive)
|
||||||
|
{
|
||||||
|
// Update window dragging
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
if (state->supportDrag)
|
||||||
|
{
|
||||||
|
Vector2 mousePosition = GetMousePosition();
|
||||||
|
|
||||||
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||||
|
{
|
||||||
|
// Window can be dragged from the top window bar
|
||||||
|
if (CheckCollisionPointRec(mousePosition, { state->windowBounds.x, state->windowBounds.y, (float)state->windowBounds.width, RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT }))
|
||||||
|
{
|
||||||
|
state->dragMode = true;
|
||||||
|
state->panOffset.x = mousePosition.x - state->windowBounds.x;
|
||||||
|
state->panOffset.y = mousePosition.y - state->windowBounds.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->dragMode)
|
||||||
|
{
|
||||||
|
state->windowBounds.x = (mousePosition.x - state->panOffset.x);
|
||||||
|
state->windowBounds.y = (mousePosition.y - state->panOffset.y);
|
||||||
|
|
||||||
|
// Check screen limits to avoid moving out of screen
|
||||||
|
if (state->windowBounds.x < 0) state->windowBounds.x = 0;
|
||||||
|
else if (state->windowBounds.x > (GetScreenWidth() - state->windowBounds.width)) state->windowBounds.x = GetScreenWidth() - state->windowBounds.width;
|
||||||
|
|
||||||
|
if (state->windowBounds.y < 0) state->windowBounds.y = 0;
|
||||||
|
else if (state->windowBounds.y > (GetScreenHeight() - state->windowBounds.height)) state->windowBounds.y = GetScreenHeight() - state->windowBounds.height;
|
||||||
|
|
||||||
|
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) state->dragMode = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Load dirFilesIcon and state->dirFiles lazily on windows open
|
||||||
|
// NOTE: They are automatically unloaded at fileDialog closing
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
if (dirFilesIcon == NULL)
|
||||||
|
{
|
||||||
|
dirFilesIcon = (FileInfo*)RL_CALLOC(MAX_DIRECTORY_FILES, sizeof(FileInfo)); // Max files to read
|
||||||
|
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) dirFilesIcon[i] = (char*)RL_CALLOC(MAX_ICON_PATH_LENGTH, 1); // Max file name length
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load current directory files
|
||||||
|
if (state->dirFiles.paths == NULL) ReloadDirectoryFiles(state);
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw window and controls
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
state->windowActive = !GuiWindowBox(state->windowBounds, "#198# Select File Dialog");
|
||||||
|
|
||||||
|
// Draw previous directory button + logic
|
||||||
|
if (GuiButton({ state->windowBounds.x + state->windowBounds.width - 48, state->windowBounds.y + 24 + 12, 40, 24 }, "< .."))
|
||||||
|
{
|
||||||
|
// Move dir path one level up
|
||||||
|
strcpy(state->dirPathText, GetPrevDirectoryPath(state->dirPathText));
|
||||||
|
|
||||||
|
// Reload directory files (frees previous list)
|
||||||
|
ReloadDirectoryFiles(state);
|
||||||
|
|
||||||
|
state->filesListActive = -1;
|
||||||
|
memset(state->fileNameText, 0, 1024);
|
||||||
|
memset(state->fileNameTextCopy, 0, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw current directory text box info + path editing logic
|
||||||
|
if (GuiTextBox({ state->windowBounds.x + 8, state->windowBounds.y + 24 + 12, state->windowBounds.width - 48 - 16, 24 }, state->dirPathText, 1024, state->dirPathEditMode))
|
||||||
|
{
|
||||||
|
if (state->dirPathEditMode)
|
||||||
|
{
|
||||||
|
// Verify if a valid path has been introduced
|
||||||
|
if (DirectoryExists(state->dirPathText))
|
||||||
|
{
|
||||||
|
// Reload directory files (frees previous list)
|
||||||
|
ReloadDirectoryFiles(state);
|
||||||
|
|
||||||
|
strcpy(state->dirPathTextCopy, state->dirPathText);
|
||||||
|
}
|
||||||
|
else strcpy(state->dirPathText, state->dirPathTextCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->dirPathEditMode = !state->dirPathEditMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List view elements are aligned left
|
||||||
|
int prevTextAlignment = GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT);
|
||||||
|
int prevElementsHeight = GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT);
|
||||||
|
GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
||||||
|
GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, 24);
|
||||||
|
# if defined(USE_CUSTOM_LISTVIEW_FILEINFO)
|
||||||
|
state->filesListActive = GuiListViewFiles({ state->position.x + 8, state->position.y + 48 + 20, state->windowBounds.width - 16, state->windowBounds.height - 60 - 16 - 68 }, fileInfo, state->dirFiles.count, &state->itemFocused, &state->filesListScrollIndex, state->filesListActive);
|
||||||
|
# else
|
||||||
|
GuiListViewEx({ state->windowBounds.x + 8, state->windowBounds.y + 48 + 20, state->windowBounds.width - 16, state->windowBounds.height - 60 - 16 - 68 },
|
||||||
|
(const char**)dirFilesIcon, state->dirFiles.count, &state->filesListScrollIndex, &state->filesListActive, &state->itemFocused);
|
||||||
|
# endif
|
||||||
|
GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, prevTextAlignment);
|
||||||
|
GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, prevElementsHeight);
|
||||||
|
|
||||||
|
// Check if a path has been selected, if it is a directory, move to that directory (and reload paths)
|
||||||
|
if ((state->filesListActive >= 0) && (state->filesListActive != state->prevFilesListActive))
|
||||||
|
//&& (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_DPAD_A)))
|
||||||
|
{
|
||||||
|
strcpy(state->fileNameText, GetFileName(state->dirFiles.paths[state->filesListActive]));
|
||||||
|
|
||||||
|
if (DirectoryExists(TextFormat("%s/%s", state->dirPathText, state->fileNameText)))
|
||||||
|
{
|
||||||
|
if (TextIsEqual(state->fileNameText, "..")) strcpy(state->dirPathText, GetPrevDirectoryPath(state->dirPathText));
|
||||||
|
else strcpy(state->dirPathText, TextFormat("%s/%s", (strcmp(state->dirPathText, "/") == 0) ? "" : state->dirPathText, state->fileNameText));
|
||||||
|
|
||||||
|
strcpy(state->dirPathTextCopy, state->dirPathText);
|
||||||
|
|
||||||
|
// Reload directory files (frees previous list)
|
||||||
|
ReloadDirectoryFiles(state);
|
||||||
|
|
||||||
|
strcpy(state->dirPathTextCopy, state->dirPathText);
|
||||||
|
|
||||||
|
state->filesListActive = -1;
|
||||||
|
strcpy(state->fileNameText, "\0");
|
||||||
|
strcpy(state->fileNameTextCopy, state->fileNameText);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->prevFilesListActive = state->filesListActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw bottom controls
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
GuiLabel({ state->windowBounds.x + 8, state->windowBounds.y + state->windowBounds.height - 68, 60, 24 }, "File name:");
|
||||||
|
if (GuiTextBox({ state->windowBounds.x + 72, state->windowBounds.y + state->windowBounds.height - 68, state->windowBounds.width - 184, 24 }, state->fileNameText, 128, state->fileNameEditMode))
|
||||||
|
{
|
||||||
|
if (*state->fileNameText)
|
||||||
|
{
|
||||||
|
// Verify if a valid filename has been introduced
|
||||||
|
if (FileExists(TextFormat("%s/%s", state->dirPathText, state->fileNameText)))
|
||||||
|
{
|
||||||
|
// Select filename from list view
|
||||||
|
for (int i = 0; i < state->dirFiles.count; i++)
|
||||||
|
{
|
||||||
|
if (TextIsEqual(state->fileNameText, state->dirFiles.paths[i]))
|
||||||
|
{
|
||||||
|
state->filesListActive = i;
|
||||||
|
strcpy(state->fileNameTextCopy, state->fileNameText);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!state->saveFileMode)
|
||||||
|
{
|
||||||
|
strcpy(state->fileNameText, state->fileNameTextCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state->fileNameEditMode = !state->fileNameEditMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiLabel({ state->windowBounds.x + 8, state->windowBounds.y + state->windowBounds.height - 24 - 12, 68, 24 }, "File filter:");
|
||||||
|
GuiComboBox({ state->windowBounds.x + 72, state->windowBounds.y + state->windowBounds.height - 24 - 12, state->windowBounds.width - 184, 24 }, "All files", &state->fileTypeActive);
|
||||||
|
|
||||||
|
state->SelectFilePressed = GuiButton({ state->windowBounds.x + state->windowBounds.width - 96 - 8, state->windowBounds.y + state->windowBounds.height - 68, 96, 24 }, "Select");
|
||||||
|
|
||||||
|
if (GuiButton({ state->windowBounds.x + state->windowBounds.width - 96 - 8, state->windowBounds.y + state->windowBounds.height - 24 - 12, 96, 24 }, "Cancel")) state->windowActive = false;
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Exit on file selected
|
||||||
|
if (state->SelectFilePressed) state->windowActive = false;
|
||||||
|
|
||||||
|
// File dialog has been closed, free all memory before exit
|
||||||
|
if (!state->windowActive)
|
||||||
|
{
|
||||||
|
// Free dirFilesIcon memory
|
||||||
|
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) RL_FREE(dirFilesIcon[i]);
|
||||||
|
|
||||||
|
RL_FREE(dirFilesIcon);
|
||||||
|
dirFilesIcon = NULL;
|
||||||
|
|
||||||
|
// Unload directory file paths
|
||||||
|
UnloadDirectoryFiles(state->dirFiles);
|
||||||
|
|
||||||
|
// Reset state variables
|
||||||
|
state->dirFiles.count = 0;
|
||||||
|
state->dirFiles.capacity = 0;
|
||||||
|
state->dirFiles.paths = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare two files from a directory
|
||||||
|
static inline int FileCompare(const char* d1, const char* d2, const char* dir)
|
||||||
|
{
|
||||||
|
const bool b1 = DirectoryExists(TextFormat("%s/%s", dir, d1));
|
||||||
|
const bool b2 = DirectoryExists(TextFormat("%s/%s", dir, d2));
|
||||||
|
|
||||||
|
if (b1 && !b2) return -1;
|
||||||
|
if (!b1 && b2) return 1;
|
||||||
|
|
||||||
|
if (!FileExists(TextFormat("%s/%s", dir, d1))) return 1;
|
||||||
|
if (!FileExists(TextFormat("%s/%s", dir, d2))) return -1;
|
||||||
|
|
||||||
|
return strcmp(d1, d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read files in new path
|
||||||
|
static void ReloadDirectoryFiles(GuiWindowFileDialogState* state)
|
||||||
|
{
|
||||||
|
UnloadDirectoryFiles(state->dirFiles);
|
||||||
|
|
||||||
|
state->dirFiles = LoadDirectoryFilesEx(state->dirPathText, (state->filterExt[0] == '\0') ? NULL : state->filterExt, false);
|
||||||
|
state->itemFocused = 0;
|
||||||
|
|
||||||
|
// Reset dirFilesIcon memory
|
||||||
|
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) memset(dirFilesIcon[i], 0, MAX_ICON_PATH_LENGTH);
|
||||||
|
|
||||||
|
// Copy paths as icon + fileNames into dirFilesIcon
|
||||||
|
for (int i = 0; i < state->dirFiles.count; i++)
|
||||||
|
{
|
||||||
|
if (IsPathFile(state->dirFiles.paths[i]))
|
||||||
|
{
|
||||||
|
// Path is a file, a file icon for convenience (for some recognized extensions)
|
||||||
|
if (IsFileExtension(state->dirFiles.paths[i], ".png;.bmp;.tga;.gif;.jpg;.jpeg;.psd;.hdr;.qoi;.dds;.pkm;.ktx;.pvr;.astc"))
|
||||||
|
{
|
||||||
|
strcpy(dirFilesIcon[i], TextFormat("#12#%s", GetFileName(state->dirFiles.paths[i])));
|
||||||
|
}
|
||||||
|
else if (IsFileExtension(state->dirFiles.paths[i], ".wav;.mp3;.ogg;.flac;.xm;.mod;.it;.wma;.aiff"))
|
||||||
|
{
|
||||||
|
strcpy(dirFilesIcon[i], TextFormat("#11#%s", GetFileName(state->dirFiles.paths[i])));
|
||||||
|
}
|
||||||
|
else if (IsFileExtension(state->dirFiles.paths[i], ".txt;.info;.md;.nfo;.xml;.json;.c;.cpp;.cs;.lua;.py;.glsl;.vs;.fs"))
|
||||||
|
{
|
||||||
|
strcpy(dirFilesIcon[i], TextFormat("#10#%s", GetFileName(state->dirFiles.paths[i])));
|
||||||
|
}
|
||||||
|
else if (IsFileExtension(state->dirFiles.paths[i], ".exe;.bin;.raw;.msi"))
|
||||||
|
{
|
||||||
|
strcpy(dirFilesIcon[i], TextFormat("#200#%s", GetFileName(state->dirFiles.paths[i])));
|
||||||
|
}
|
||||||
|
else strcpy(dirFilesIcon[i], TextFormat("#218#%s", GetFileName(state->dirFiles.paths[i])));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Path is a directory, add a directory icon
|
||||||
|
strcpy(dirFilesIcon[i], TextFormat("#1#%s", GetFileName(state->dirFiles.paths[i])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(USE_CUSTOM_LISTVIEW_FILEINFO)
|
||||||
|
// List View control for files info with extended parameters
|
||||||
|
static int GuiListViewFiles(Rectangle bounds, FileInfo* files, int count, int* focus, int* scrollIndex, int* active)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
GuiState state = guiState;
|
||||||
|
int itemFocused = (focus == NULL) ? -1 : *focus;
|
||||||
|
int itemSelected = *active;
|
||||||
|
|
||||||
|
// Check if we need a scroll bar
|
||||||
|
bool useScrollBar = false;
|
||||||
|
if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING)) * count > bounds.height) useScrollBar = true;
|
||||||
|
|
||||||
|
// Define base item rectangle [0]
|
||||||
|
Rectangle itemBounds = { 0 };
|
||||||
|
itemBounds.x = bounds.x + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING);
|
||||||
|
itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING) + GuiGetStyle(DEFAULT, BORDER_WIDTH);
|
||||||
|
itemBounds.width = bounds.width - 2 * GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING) - GuiGetStyle(DEFAULT, BORDER_WIDTH);
|
||||||
|
itemBounds.height = GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT);
|
||||||
|
if (useScrollBar) itemBounds.width -= GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH);
|
||||||
|
|
||||||
|
// Get items on the list
|
||||||
|
int visibleItems = bounds.height / (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING));
|
||||||
|
if (visibleItems > count) visibleItems = count;
|
||||||
|
|
||||||
|
int startIndex = (scrollIndex == NULL) ? 0 : *scrollIndex;
|
||||||
|
if ((startIndex < 0) || (startIndex > (count - visibleItems))) startIndex = 0;
|
||||||
|
int endIndex = startIndex + visibleItems;
|
||||||
|
|
||||||
|
// Update control
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
if ((state != GUI_STATE_DISABLED) && !guiLocked)
|
||||||
|
{
|
||||||
|
Vector2 mousePoint = GetMousePosition();
|
||||||
|
|
||||||
|
// Check mouse inside list view
|
||||||
|
if (CheckCollisionPointRec(mousePoint, bounds))
|
||||||
|
{
|
||||||
|
state = GUI_STATE_FOCUSED;
|
||||||
|
|
||||||
|
// Check focused and selected item
|
||||||
|
for (int i = 0; i < visibleItems; i++)
|
||||||
|
{
|
||||||
|
if (CheckCollisionPointRec(mousePoint, itemBounds))
|
||||||
|
{
|
||||||
|
itemFocused = startIndex + i;
|
||||||
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) itemSelected = startIndex + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update item rectangle y position for next item
|
||||||
|
itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useScrollBar)
|
||||||
|
{
|
||||||
|
int wheelMove = GetMouseWheelMove();
|
||||||
|
startIndex -= wheelMove;
|
||||||
|
|
||||||
|
if (startIndex < 0) startIndex = 0;
|
||||||
|
else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems;
|
||||||
|
|
||||||
|
endIndex = startIndex + visibleItems;
|
||||||
|
if (endIndex > count) endIndex = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else itemFocused = -1;
|
||||||
|
|
||||||
|
// Reset item rectangle y to [0]
|
||||||
|
itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING) + GuiGetStyle(DEFAULT, BORDER_WIDTH);
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw control
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
DrawRectangleRec(bounds, GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background
|
||||||
|
DrawRectangleLinesEx(bounds, GuiGetStyle(DEFAULT, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER + state * 3)), guiAlpha));
|
||||||
|
|
||||||
|
// TODO: Draw list view header with file sections: icon+name | size | type | modTime
|
||||||
|
|
||||||
|
// Draw visible items
|
||||||
|
for (int i = 0; i < visibleItems; i++)
|
||||||
|
{
|
||||||
|
if (state == GUI_STATE_DISABLED)
|
||||||
|
{
|
||||||
|
if ((startIndex + i) == itemSelected)
|
||||||
|
{
|
||||||
|
DrawRectangleRec(itemBounds, Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED)), guiAlpha));
|
||||||
|
DrawRectangleLinesEx(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), guiAlpha));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Draw full file info line: icon+name | size | type | modTime
|
||||||
|
|
||||||
|
GuiDrawText(files[startIndex + i].name, GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED)), guiAlpha));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((startIndex + i) == itemSelected)
|
||||||
|
{
|
||||||
|
// Draw item selected
|
||||||
|
DrawRectangleRec(itemBounds, Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED)), guiAlpha));
|
||||||
|
DrawRectangleLinesEx(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), guiAlpha));
|
||||||
|
|
||||||
|
GuiDrawText(files[startIndex + i].name, GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED)), guiAlpha));
|
||||||
|
}
|
||||||
|
else if ((startIndex + i) == itemFocused)
|
||||||
|
{
|
||||||
|
// Draw item focused
|
||||||
|
DrawRectangleRec(itemBounds, Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED)), guiAlpha));
|
||||||
|
DrawRectangleLinesEx(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), guiAlpha));
|
||||||
|
|
||||||
|
GuiDrawText(files[startIndex + i].name, GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED)), guiAlpha));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Draw item normal
|
||||||
|
GuiDrawText(files[startIndex + i].name, GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL)), guiAlpha));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update item rectangle y position for next item
|
||||||
|
itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_PADDING));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useScrollBar)
|
||||||
|
{
|
||||||
|
Rectangle scrollBarBounds = {
|
||||||
|
bounds.x + bounds.width - GuiGetStyle(LISTVIEW, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH),
|
||||||
|
bounds.y + GuiGetStyle(LISTVIEW, BORDER_WIDTH), (float)GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH),
|
||||||
|
bounds.height - 2 * GuiGetStyle(DEFAULT, BORDER_WIDTH)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate percentage of visible items and apply same percentage to scrollbar
|
||||||
|
float percentVisible = (float)(endIndex - startIndex) / count;
|
||||||
|
float sliderSize = bounds.height * percentVisible;
|
||||||
|
|
||||||
|
int prevSliderSize = GuiGetStyle(SCROLLBAR, SLIDER_WIDTH); // Save default slider size
|
||||||
|
int prevScrollSpeed = GuiGetStyle(SCROLLBAR, SCROLL_SPEED); // Save default scroll speed
|
||||||
|
GuiSetStyle(SCROLLBAR, SLIDER_WIDTH, sliderSize); // Change slider size
|
||||||
|
GuiSetStyle(SCROLLBAR, SCROLL_SPEED, count - visibleItems); // Change scroll speed
|
||||||
|
|
||||||
|
startIndex = GuiScrollBar(scrollBarBounds, startIndex, 0, count - visibleItems);
|
||||||
|
|
||||||
|
GuiSetStyle(SCROLLBAR, SCROLL_SPEED, prevScrollSpeed); // Reset scroll speed to default
|
||||||
|
GuiSetStyle(SCROLLBAR, SLIDER_WIDTH, prevSliderSize); // Reset slider size to default
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (focus != NULL) *focus = itemFocused;
|
||||||
|
if (scrollIndex != NULL) *scrollIndex = startIndex;
|
||||||
|
|
||||||
|
*active = itemSelected;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif // USE_CUSTOM_LISTVIEW_FILEINFO
|
||||||
|
|
||||||
|
#endif // GUI_FILE_DIALOG_IMPLEMENTATION
|
25
res/lua/bubble_sortiva.lua
Normal file
25
res/lua/bubble_sortiva.lua
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
local bubble_sort = Future:new()
|
||||||
|
|
||||||
|
function bubble_sort:poll(array)
|
||||||
|
local n = array:size()
|
||||||
|
self.state[n] = self.state[n] or n
|
||||||
|
if n == 0 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local swapped = false
|
||||||
|
for i = 1, n - 1 do
|
||||||
|
if array.at(i-1) > array.at(i) then
|
||||||
|
array.swap(i-1, i)
|
||||||
|
swapped = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.state.n = self.state.n - 1
|
||||||
|
|
||||||
|
return not swapped
|
||||||
|
end
|
||||||
|
|
||||||
|
function make_available(sorter_list)
|
||||||
|
table.insert(sorter_list, "bubble_sort")
|
||||||
|
end
|
59
res/lua/quick_sortiva.lua
Normal file
59
res/lua/quick_sortiva.lua
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
local quick_sort = Future:new()
|
||||||
|
|
||||||
|
function quick_sort:sort(A, lo, hi, i)
|
||||||
|
if lo >= 0 and lo < hi then
|
||||||
|
lt, gt = partition(A, lo, hi) -- Multiple return values
|
||||||
|
|
||||||
|
if #self.state["lt"] >= i and #self.state["gt"] >= i then
|
||||||
|
self:sort(A, lo, self.state["lt"][i] - 1, i+1)
|
||||||
|
self:sort(A, self.state["gt"][i] + 1, hi, i+1)
|
||||||
|
else
|
||||||
|
table.insert(self.state["lt"], lt)
|
||||||
|
table.insert(self.state["gt"], gt)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function quick_sort:poll(array)
|
||||||
|
return self:sort(array, 0, array:size(),0)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Divides array into three partitions
|
||||||
|
function partition(A, lo, hi)
|
||||||
|
-- Pivot value
|
||||||
|
local pivot = A.at((lo + hi) / 2) -- Choose the middle element as the pivot (integer division)
|
||||||
|
|
||||||
|
-- Lesser, equal and greater index
|
||||||
|
local lt = lo
|
||||||
|
local eq = lo
|
||||||
|
local gt = hi
|
||||||
|
|
||||||
|
-- Iterate and compare all elements with the pivot
|
||||||
|
while eq <= gt do
|
||||||
|
if A[eq] < pivot then
|
||||||
|
-- Swap the elements at the equal and lesser indices
|
||||||
|
A:swap(eq, lt)
|
||||||
|
-- Increase lesser index
|
||||||
|
lt = lt + 1
|
||||||
|
-- Increase equal index
|
||||||
|
eq = eq + 1
|
||||||
|
elseif A[eq] > pivot then
|
||||||
|
-- Swap the elements at the equal and greater indices
|
||||||
|
A:swap(eq, gt)
|
||||||
|
-- Decrease greater index
|
||||||
|
gt = gt - 1
|
||||||
|
else -- if A[eq] = pivot then
|
||||||
|
-- Increase equal index
|
||||||
|
eq = eq + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Return lesser and greater indices
|
||||||
|
return lt, gt
|
||||||
|
end
|
||||||
|
|
||||||
|
function make_available(sorter_list)
|
||||||
|
table.insert(sorter_list, "quick_sort")
|
||||||
|
end
|
33
src/LuaSortList.hpp
Normal file
33
src/LuaSortList.hpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class LuaSortList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<uint16_t> list;
|
||||||
|
|
||||||
|
void swap(size_t i1, size_t i2)
|
||||||
|
{
|
||||||
|
std::swap(list[i1], list[i2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t at(size_t i) const
|
||||||
|
{
|
||||||
|
return list[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sorted() const
|
||||||
|
{
|
||||||
|
for (int i = 1; i < list.size() + 1; ++i)
|
||||||
|
{
|
||||||
|
if (list[i - 1] > list[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -1,2 +1,7 @@
|
||||||
#define RAYGUI_IMPLEMENTATION
|
#define RAYGUI_IMPLEMENTATION
|
||||||
#include <raylibs/raygui.h>
|
#include <raylibs/raygui.h>
|
||||||
|
|
||||||
|
#undef RAYGUI_IMPLEMENTATION
|
||||||
|
#define GUI_WINDOW_FILE_DIALOG_IMPLEMENTATION
|
||||||
|
#define RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT 24
|
||||||
|
#include <raylibs/modules/gui_window_file_dialog.hpp>
|
16
src/lua/Future.lua
Normal file
16
src/lua/Future.lua
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
Future = {
|
||||||
|
state = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Future:new(state)
|
||||||
|
local f = {}
|
||||||
|
setmetatable(f, self)
|
||||||
|
self.__index = self
|
||||||
|
f["state"] = state or {}
|
||||||
|
|
||||||
|
return f
|
||||||
|
end
|
||||||
|
|
||||||
|
function Future:pull()
|
||||||
|
return true
|
||||||
|
end
|
35
src/lua/FutureLua.hpp
Normal file
35
src/lua/FutureLua.hpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
static inline const char lua_future_class[] = R"(
|
||||||
|
Future = {
|
||||||
|
state = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Future:new(state)
|
||||||
|
local f = {}
|
||||||
|
setmetatable(f, self)
|
||||||
|
self.__index = self
|
||||||
|
f["state"] = state or {}
|
||||||
|
|
||||||
|
return f
|
||||||
|
end
|
||||||
|
|
||||||
|
function Future:poll()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function Future.get(t, ...)
|
||||||
|
return t:poll(unpack(arg))
|
||||||
|
end
|
||||||
|
)";
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class Future
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Future() = default;
|
||||||
|
virtual bool poll() = 0;
|
||||||
|
virtual T& get() = 0;
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "sortiva.hpp"
|
#include "sortiva/sortiva.hpp"
|
||||||
|
|
||||||
|
#undef _DEBUG
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
printf("Darling, I'm Home!\n");
|
printf("Darling, I'm Home!\n");
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#include "sortiva.hpp"
|
|
||||||
|
|
||||||
void Sortiva::update(double dt) {
|
|
||||||
for (auto& ticker : m_TickSystems)
|
|
||||||
{
|
|
||||||
if (ticker.update(std::chrono::milliseconds(static_cast<long long>(dt))))
|
|
||||||
{
|
|
||||||
ticker.call();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
#include "sortiva.hpp"
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
|
|
||||||
namespace rl
|
|
||||||
{
|
|
||||||
#include <raylib.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Sortiva::Sortiva()
|
|
||||||
{
|
|
||||||
rl::InitWindow(1280, 720, "Sortiva");
|
|
||||||
if (!rl::IsWindowReady()) exit(2);
|
|
||||||
|
|
||||||
m_Width = rl::GetRenderWidth();
|
|
||||||
m_Height = rl::GetRenderHeight();
|
|
||||||
rl::SetWindowMinSize(static_cast<int>(1280 * 0.25f), static_cast<int>(720 * 0.25f));
|
|
||||||
rl::SetWindowState(rl::ConfigFlags::FLAG_WINDOW_RESIZABLE | rl::ConfigFlags::FLAG_VSYNC_HINT);
|
|
||||||
|
|
||||||
rl::SetTargetFPS(60);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sortiva::~Sortiva()
|
|
||||||
{
|
|
||||||
rl::CloseWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sortiva::run()
|
|
||||||
{
|
|
||||||
setup();
|
|
||||||
while (m_Running)
|
|
||||||
{
|
|
||||||
if (rl::WindowShouldClose()) m_Running = false;
|
|
||||||
if (rl::IsWindowResized())
|
|
||||||
{
|
|
||||||
m_Width = rl::GetScreenWidth();
|
|
||||||
m_Height = rl::GetScreenHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
rl::ClearBackground({ 25, 25, 25, 255 });
|
|
||||||
rl::BeginDrawing();
|
|
||||||
|
|
||||||
update(rl::GetFrameTime());
|
|
||||||
draw();
|
|
||||||
|
|
||||||
rl::EndDrawing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sortiva::setup()
|
|
||||||
{
|
|
||||||
m_Steps.reset();
|
|
||||||
m_Steps = std::make_unique<val_step_diag>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m_Steps->emplace_back();
|
|
||||||
m_Steps->emplace_back();
|
|
||||||
m_Steps->emplace_back();
|
|
||||||
|
|
||||||
linked_list<uint16_t>& list1 = m_Steps->at(0);
|
|
||||||
list1.value = 1;
|
|
||||||
list1.put(1).put(3).put(1).put(1);
|
|
||||||
//
|
|
||||||
linked_list<uint16_t>& list2 = m_Steps->at(1);
|
|
||||||
list2.value = 3;
|
|
||||||
list2.put(2).put(1).put(3).put(2);
|
|
||||||
//
|
|
||||||
linked_list<uint16_t>& list3 = m_Steps->at(2);
|
|
||||||
list3.value = 2;
|
|
||||||
list3.put(3).put(2).put(2).put(3);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
|
||||||
#include "collections.hpp"
|
|
||||||
#include "TickSystem.hpp"
|
|
||||||
|
|
||||||
class Sortiva final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Sortiva();
|
|
||||||
~Sortiva();
|
|
||||||
|
|
||||||
void run();
|
|
||||||
private:
|
|
||||||
int m_Width;
|
|
||||||
int m_Height;
|
|
||||||
bool m_Running;
|
|
||||||
|
|
||||||
|
|
||||||
void draw();
|
|
||||||
void update(double deltatime);
|
|
||||||
|
|
||||||
void setup();
|
|
||||||
|
|
||||||
std::vector<TickSystem> m_TickSystems;
|
|
||||||
|
|
||||||
// std::unique_ptr
|
|
||||||
// -> tree
|
|
||||||
// -> linked_list
|
|
||||||
// -> uint16_t
|
|
||||||
using val_step_diag = std::vector<linked_list<uint16_t>>;
|
|
||||||
std::unique_ptr<val_step_diag> m_Steps;
|
|
||||||
};
|
|
45
src/sortiva/GuiFileDialog.cpp
Normal file
45
src/sortiva/GuiFileDialog.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include "GuiFileDialog.hpp"
|
||||||
|
#include <raylibs/raygui.h>
|
||||||
|
#include <raylibs/modules/gui_window_file_dialog.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
Gui_WindowFileDialog::Gui_WindowFileDialog()
|
||||||
|
{
|
||||||
|
fileDialogState = new GuiWindowFileDialogState(InitGuiWindowFileDialog(GetWorkingDirectory()));
|
||||||
|
fileDialogState->windowBounds = { 10, 10, fileDialogState->windowBounds.height, fileDialogState->windowBounds.height };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Gui_WindowFileDialog::update()
|
||||||
|
{
|
||||||
|
bool file_opened = false;
|
||||||
|
if (fileDialogState->SelectFilePressed)
|
||||||
|
{
|
||||||
|
// Load image file (if supported extension)
|
||||||
|
if (IsFileExtension(fileDialogState->fileNameText, ".lua"))
|
||||||
|
{
|
||||||
|
strcpy(fileNameToLoad, TextFormat("%s/%s", fileDialogState->dirPathText, fileDialogState->fileNameText));
|
||||||
|
openedFile = fileNameToLoad;
|
||||||
|
file_opened = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileDialogState->SelectFilePressed = false;
|
||||||
|
}
|
||||||
|
return file_opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gui_WindowFileDialog::draw()
|
||||||
|
{
|
||||||
|
// raygui: controls drawing
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (fileDialogState->windowActive) GuiLock();
|
||||||
|
|
||||||
|
if (GuiButton({ 20, 20, 140, 30 }, GuiIconText(GuiIconName::ICON_FILE_OPEN, "Open Image"))) fileDialogState->windowActive = true;
|
||||||
|
|
||||||
|
GuiUnlock();
|
||||||
|
|
||||||
|
// GUI: Dialog Window
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
GuiWindowFileDialog(fileDialogState);
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
}
|
19
src/sortiva/GuiFileDialog.hpp
Normal file
19
src/sortiva/GuiFileDialog.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <raylibs/modules/gui_window_file_dialog.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
class Gui_WindowFileDialog
|
||||||
|
{
|
||||||
|
GuiWindowFileDialogState* fileDialogState;
|
||||||
|
char fileNameToLoad[512] = { 0 };
|
||||||
|
public:
|
||||||
|
Gui_WindowFileDialog();
|
||||||
|
|
||||||
|
std::string openedFile;
|
||||||
|
|
||||||
|
bool update();
|
||||||
|
|
||||||
|
void draw();
|
||||||
|
};
|
|
@ -1,13 +1,11 @@
|
||||||
#include "sortiva.hpp"
|
#include "sortiva.hpp"
|
||||||
|
|
||||||
namespace rl
|
|
||||||
{
|
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
}
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
constexpr rl::Color sorter_colors[] = {
|
constexpr Color sorter_colors[] = {
|
||||||
{ 253, 249, 0, 255 }, // Yellow
|
{ 253, 249, 0, 255 }, // Yellow
|
||||||
{ 255, 203, 0, 255 }, // Gold
|
{ 255, 203, 0, 255 }, // Gold
|
||||||
{ 255, 161, 0, 255 }, // Orange
|
{ 255, 161, 0, 255 }, // Orange
|
||||||
|
@ -29,23 +27,23 @@ constexpr rl::Color sorter_colors[] = {
|
||||||
{ 76, 63, 47, 255 }, // Dark Brown
|
{ 76, 63, 47, 255 }, // Dark Brown
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int sorter_colors_size = sizeof(sorter_colors) / sizeof(rl::Color);
|
constexpr int sorter_colors_size = sizeof(sorter_colors) / sizeof(Color);
|
||||||
|
|
||||||
constexpr rl::Color sorter_block_colors[] = {
|
constexpr Color sorter_block_colors[] = {
|
||||||
{ 200, 200, 200, 255 }, // Light Gray
|
{ 200, 200, 200, 255 }, // Light Gray
|
||||||
{ 80, 80, 80, 255 }, // Dark Gray
|
{ 80, 80, 80, 255 }, // Dark Gray
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int sorter_block_colors_size = sizeof(sorter_block_colors) / sizeof(rl::Color);
|
constexpr int sorter_block_colors_size = sizeof(sorter_block_colors) / sizeof(Color);
|
||||||
|
|
||||||
|
|
||||||
void Sortiva::draw()
|
void Sortiva::draw()
|
||||||
{
|
{
|
||||||
rl::Vector2 margin = {
|
Vector2 margin = {
|
||||||
.x = m_Width * 0.01f,
|
.x = m_Width * 0.01f,
|
||||||
.y = m_Height * 0.01f
|
.y = m_Height * 0.01f
|
||||||
};
|
};
|
||||||
rl::DrawRectangleV(margin, { m_Width - 2 * margin.x, m_Height - 2 * margin.y }, { 60, 60, 60, 255 });
|
DrawRectangleV(margin, { m_Width - 2 * margin.x, m_Height - 2 * margin.y }, { 60, 60, 60, 255 });
|
||||||
|
|
||||||
|
|
||||||
margin = {
|
margin = {
|
||||||
|
@ -53,6 +51,21 @@ void Sortiva::draw()
|
||||||
.y = m_Height * 0.02f
|
.y = m_Height * 0.02f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Rectangle plane = {
|
||||||
|
.x = margin.x,
|
||||||
|
.y = margin.y,
|
||||||
|
.width = m_Width - margin.x * 2,
|
||||||
|
.height = m_Height - margin.y * 2
|
||||||
|
};
|
||||||
|
|
||||||
|
if (m_Steps->empty())
|
||||||
|
{
|
||||||
|
static const char* msg = "Select and run a Sorting algorithm";
|
||||||
|
static int width = MeasureText(msg, 20);
|
||||||
|
DrawText(msg, plane.x + plane.width / 2 - width / 2, plane.y + plane.height / 2 - 10, 20, { 245, 245, 245, 255 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// +2 for start points and end points; will be removed later in the function
|
// +2 for start points and end points; will be removed later in the function
|
||||||
size_t cvals = m_Steps->size();
|
size_t cvals = m_Steps->size();
|
||||||
|
|
||||||
|
@ -64,13 +77,6 @@ void Sortiva::draw()
|
||||||
|
|
||||||
steps += 1;
|
steps += 1;
|
||||||
|
|
||||||
rl::Rectangle plane = {
|
|
||||||
.x = margin.x,
|
|
||||||
.y = margin.y,
|
|
||||||
.width = m_Width - margin.x * 2,
|
|
||||||
.height = m_Height - margin.y * 2
|
|
||||||
};
|
|
||||||
|
|
||||||
// ui distance values
|
// ui distance values
|
||||||
int w = static_cast<int>(plane.width / static_cast<float>(steps));
|
int w = static_cast<int>(plane.width / static_cast<float>(steps));
|
||||||
int g = plane.height / static_cast<float>(cvals + 1);
|
int g = plane.height / static_cast<float>(cvals + 1);
|
||||||
|
@ -85,7 +91,7 @@ void Sortiva::draw()
|
||||||
|
|
||||||
for (size_t i = 0; i < steps; ++i)
|
for (size_t i = 0; i < steps; ++i)
|
||||||
{
|
{
|
||||||
rl::DrawRectangle(
|
DrawRectangle(
|
||||||
static_cast<int>(i) * w + static_cast<int>(plane.x),
|
static_cast<int>(i) * w + static_cast<int>(plane.x),
|
||||||
plane.y,
|
plane.y,
|
||||||
w,
|
w,
|
||||||
|
@ -99,19 +105,18 @@ void Sortiva::draw()
|
||||||
int colid = sorter_colors_size / cvals;
|
int colid = sorter_colors_size / cvals;
|
||||||
|
|
||||||
// font settings
|
// font settings
|
||||||
constexpr rl::Color textColor = { 0, 0, 0, 255 };
|
constexpr Color textColor = { 0, 0, 0, 255 };
|
||||||
int l3 = static_cast<int>(l * 3);
|
int l3 = static_cast<int>(l * 3);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
rl::DrawFPS(5, 5);
|
DrawFPS(5, 5);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int v = 0; v < cvals; ++v)
|
for (int v = 0; v < cvals; ++v)
|
||||||
{
|
{
|
||||||
linked_list<uint16_t>* list = &m_Steps->at(v);
|
linked_list<uint16_t>* list = &m_Steps->at(v);
|
||||||
|
|
||||||
uint16_t value = list->value;
|
uint16_t value = list->value;
|
||||||
rl::Color col = sorter_colors[(v * colid) % sorter_colors_size];
|
Color col = sorter_colors[(v * colid) % sorter_colors_size];
|
||||||
|
|
||||||
|
|
||||||
float wf = static_cast<float>(w);
|
float wf = static_cast<float>(w);
|
||||||
|
@ -127,7 +132,7 @@ void Sortiva::draw()
|
||||||
float yt = plane.y + h + g * (nvalue - 1);
|
float yt = plane.y + h + g * (nvalue - 1);
|
||||||
|
|
||||||
|
|
||||||
rl::DrawSplineSegmentBezierCubic(
|
DrawSplineSegmentBezierCubic(
|
||||||
{ (sf + 1.f) * wf + plane.x - 1, y },
|
{ (sf + 1.f) * wf + plane.x - 1, y },
|
||||||
{ (sf + 2.f) * wf + plane.x, y },
|
{ (sf + 2.f) * wf + plane.x, y },
|
||||||
{ (sf + 1.f) * wf + plane.x, yt },
|
{ (sf + 1.f) * wf + plane.x, yt },
|
||||||
|
@ -140,8 +145,8 @@ void Sortiva::draw()
|
||||||
float font_size = l * 1.2f;
|
float font_size = l * 1.2f;
|
||||||
int yd = y - yt < 0 ? -font_size : +font_size;
|
int yd = y - yt < 0 ? -font_size : +font_size;
|
||||||
yd *= 2;
|
yd *= 2;
|
||||||
rl::DrawText(
|
DrawText(
|
||||||
rl::TextFormat("%d -> %d", value, nvalue),
|
TextFormat("%d -> %d", value, nvalue),
|
||||||
(sf + 1.f) * wf + plane.x + 10,
|
(sf + 1.f) * wf + plane.x + 10,
|
||||||
y + yd,
|
y + yd,
|
||||||
font_size,
|
font_size,
|
||||||
|
@ -152,18 +157,18 @@ void Sortiva::draw()
|
||||||
|
|
||||||
value = list->value;
|
value = list->value;
|
||||||
|
|
||||||
rl::Vector2 pos = { wf * steps + e + plane.x, h + (value - 1) * g + plane.y };
|
Vector2 pos = { wf * steps + e + plane.x, h + (value - 1) * g + plane.y };
|
||||||
rl::DrawCircleV(pos, l3, col);
|
DrawCircleV(pos, l3, col);
|
||||||
|
|
||||||
rl::DrawLineEx(
|
DrawLineEx(
|
||||||
{ pos.x - e - 1, pos.y },
|
{ pos.x - e - 1, pos.y },
|
||||||
pos,
|
pos,
|
||||||
l,
|
l,
|
||||||
col
|
col
|
||||||
);
|
);
|
||||||
|
|
||||||
const char* strv = rl::TextFormat("%d", v + 1);
|
const char* strv = TextFormat("%d", v + 1);
|
||||||
rl::DrawText(
|
DrawText(
|
||||||
strv,
|
strv,
|
||||||
static_cast<int>(pos.x) + e / 2,
|
static_cast<int>(pos.x) + e / 2,
|
||||||
static_cast<int>(pos.y) - l3 / 2,
|
static_cast<int>(pos.y) - l3 / 2,
|
||||||
|
@ -171,11 +176,12 @@ void Sortiva::draw()
|
||||||
textColor
|
textColor
|
||||||
);
|
);
|
||||||
|
|
||||||
list = list->first;
|
if (list->first)
|
||||||
|
list = list->first->next;
|
||||||
value = list->value;
|
value = list->value;
|
||||||
pos = { wf - e + plane.x, h + (value - 1) * g + plane.y };
|
pos = { wf - e + plane.x, h + (value - 1) * g + plane.y };
|
||||||
|
|
||||||
rl::DrawText(
|
DrawText(
|
||||||
strv,
|
strv,
|
||||||
static_cast<int>(pos.x) - e / 2 - l3 / 2,
|
static_cast<int>(pos.x) - e / 2 - l3 / 2,
|
||||||
static_cast<int>(pos.y) - l3 / 2,
|
static_cast<int>(pos.y) - l3 / 2,
|
||||||
|
@ -183,7 +189,7 @@ void Sortiva::draw()
|
||||||
textColor
|
textColor
|
||||||
);
|
);
|
||||||
|
|
||||||
rl::DrawRing(
|
DrawRing(
|
||||||
pos,
|
pos,
|
||||||
l * 2,
|
l * 2,
|
||||||
l3,
|
l3,
|
||||||
|
@ -193,11 +199,12 @@ void Sortiva::draw()
|
||||||
col
|
col
|
||||||
);
|
);
|
||||||
|
|
||||||
rl::DrawLineEx(
|
DrawLineEx(
|
||||||
pos,
|
pos,
|
||||||
{ pos.x + e, pos.y },
|
{ pos.x + e, pos.y },
|
||||||
l,
|
l,
|
||||||
col
|
col
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
28
src/sortiva/sortiva-draw_overlay.cpp
Normal file
28
src/sortiva/sortiva-draw_overlay.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include "sortiva.hpp"
|
||||||
|
|
||||||
|
#include <raylibs/raygui.h>
|
||||||
|
|
||||||
|
|
||||||
|
void Sortiva::draw_overlay()
|
||||||
|
{
|
||||||
|
//static bool edit_mode = false;
|
||||||
|
//
|
||||||
|
//GuiUnlock();
|
||||||
|
//
|
||||||
|
//static int active = 0;
|
||||||
|
//if (GuiDropdownBox({ 250,20,200,30 }, m_Lua.SorterListStr.c_str(), &active, edit_mode)) edit_mode = !edit_mode;
|
||||||
|
//
|
||||||
|
//if (edit_mode) GuiLock();
|
||||||
|
|
||||||
|
if (GuiButton({ 450, 20, 100, 40 }, "Run"))
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
m_SortingFinished = false;
|
||||||
|
}
|
||||||
|
if (GuiButton({ 200, 20, 100, 40 }, "Pause"))
|
||||||
|
{
|
||||||
|
if (m_SortingFinished && m_Steps->empty()) return;
|
||||||
|
m_SortingFinished = !m_SortingFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
src/sortiva/sortiva-update.cpp
Normal file
22
src/sortiva/sortiva-update.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include "sortiva.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
void Sortiva::update(double dt) {
|
||||||
|
if (m_Ticker.update(std::chrono::duration<float>(dt)))
|
||||||
|
{
|
||||||
|
if (!m_SortingFinished) {
|
||||||
|
if (m_Sorter.poll())
|
||||||
|
{
|
||||||
|
m_SortingFinished = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LuaSortList& list = m_Sorter.get();
|
||||||
|
for (uint16_t i = 0; i < list.size(); ++i)
|
||||||
|
{
|
||||||
|
m_Steps->at(list.at(i) - 1).put(i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
78
src/sortiva/sortiva.cpp
Normal file
78
src/sortiva/sortiva.cpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#include "sortiva.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
|
||||||
|
Sortiva::Sortiva() : m_Ticker(std::chrono::seconds(1))
|
||||||
|
{
|
||||||
|
m_Sorter.set(m_List);
|
||||||
|
|
||||||
|
m_Steps = std::make_unique<val_step_diag>();
|
||||||
|
|
||||||
|
InitWindow(1280, 720, "Sortiva");
|
||||||
|
if (!IsWindowReady()) exit(2);
|
||||||
|
|
||||||
|
m_Width = GetRenderWidth();
|
||||||
|
m_Height = GetRenderHeight();
|
||||||
|
SetWindowMinSize(static_cast<int>(1280 * 0.25f), static_cast<int>(720 * 0.25f));
|
||||||
|
SetWindowState(ConfigFlags::FLAG_WINDOW_RESIZABLE | ConfigFlags::FLAG_VSYNC_HINT);
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sortiva::~Sortiva()
|
||||||
|
{
|
||||||
|
CloseWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sortiva::run()
|
||||||
|
{
|
||||||
|
while (m_Running)
|
||||||
|
{
|
||||||
|
if (WindowShouldClose()) m_Running = false;
|
||||||
|
if (IsWindowResized())
|
||||||
|
{
|
||||||
|
m_Width = GetScreenWidth();
|
||||||
|
m_Height = GetScreenHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearBackground({ 25, 25, 25, 255 });
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
update(GetFrameTime());
|
||||||
|
draw();
|
||||||
|
draw_overlay();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sortiva::setup()
|
||||||
|
{
|
||||||
|
m_Steps->clear();
|
||||||
|
m_List.list.clear();
|
||||||
|
|
||||||
|
uint16_t count = 5;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i <= count; ++i) // 1,2,3,4,5
|
||||||
|
{
|
||||||
|
m_List.list.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::random_device dev;
|
||||||
|
std::mt19937 rng(dev());
|
||||||
|
|
||||||
|
std::ranges::shuffle(m_List.list, rng); // 2,3,1,5,4
|
||||||
|
|
||||||
|
for (int i = 1; i <= count; ++i)
|
||||||
|
{
|
||||||
|
m_Steps->emplace_back().value = m_List.list[i - 1];
|
||||||
|
}
|
||||||
|
}
|
82
src/sortiva/sortiva.hpp
Normal file
82
src/sortiva/sortiva.hpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <collections.hpp>
|
||||||
|
#include "../lua/FutureLua.hpp"
|
||||||
|
#include <TickSystem.hpp>
|
||||||
|
#include "../LuaSortList.hpp"
|
||||||
|
|
||||||
|
class Bubble_Sorter : Future<LuaSortList>
|
||||||
|
{
|
||||||
|
LuaSortList* list = nullptr;
|
||||||
|
struct STATE
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
} state;
|
||||||
|
public:
|
||||||
|
Bubble_Sorter() = default;
|
||||||
|
Bubble_Sorter(LuaSortList& l) : list(&l) {}
|
||||||
|
|
||||||
|
bool poll() override
|
||||||
|
{
|
||||||
|
int n = list->size();
|
||||||
|
if (n <= 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.n = state.n + 1;
|
||||||
|
|
||||||
|
if (state.n >= n)
|
||||||
|
{
|
||||||
|
state.n = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list->at(state.n - 1) > list->at(state.n)) {
|
||||||
|
list->swap(state.n - 1, state.n);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return list->sorted();
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaSortList& get() override
|
||||||
|
{
|
||||||
|
return *list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(LuaSortList& l)
|
||||||
|
{
|
||||||
|
list = &l;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Sortiva final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Sortiva();
|
||||||
|
~Sortiva();
|
||||||
|
|
||||||
|
void run();
|
||||||
|
private:
|
||||||
|
int m_Width;
|
||||||
|
int m_Height;
|
||||||
|
bool m_Running = true;
|
||||||
|
|
||||||
|
void draw();
|
||||||
|
void draw_overlay();
|
||||||
|
void update(double);
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
|
||||||
|
bool m_SortingFinished = true;
|
||||||
|
TickSystem m_Ticker;
|
||||||
|
Bubble_Sorter m_Sorter;
|
||||||
|
LuaSortList m_List;
|
||||||
|
|
||||||
|
|
||||||
|
// std::unique_ptr
|
||||||
|
// -> tree
|
||||||
|
// -> linked_list
|
||||||
|
// -> uint16_t
|
||||||
|
using val_step_diag = std::vector<linked_list<uint16_t>>;
|
||||||
|
std::unique_ptr<val_step_diag> m_Steps;
|
||||||
|
};
|
Loading…
Reference in a new issue