mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-02 13:37:42 -05:00
tests: Integrated ImGui Test Engine
This commit is contained in:
183
lib/third_party/imgui/imgui_test_engine/include/imgui_capture_tool.h
vendored
Normal file
183
lib/third_party/imgui/imgui_test_engine/include/imgui_capture_tool.h
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
// dear imgui test engine
|
||||
// (screen/video capture tool)
|
||||
// This is usable as a standalone applet or controlled by the test engine.
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Need "imgui_te_engine.h" included for ImFuncPtr
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Our types
|
||||
struct ImGuiCaptureArgs; // Parameters for Capture
|
||||
struct ImGuiCaptureContext; // State of an active capture tool
|
||||
struct ImGuiCaptureImageBuf; // Simple helper to store an RGBA image in memory
|
||||
struct ImGuiCaptureToolUI; // Capture tool instance + UI window
|
||||
|
||||
typedef unsigned int ImGuiCaptureFlags; // See enum: ImGuiCaptureFlags_
|
||||
|
||||
// Capture function which needs to be provided by user application
|
||||
typedef bool (ImGuiScreenCaptureFunc)(ImGuiID viewport_id, int x, int y, int w, int h, unsigned int* pixels, void* user_data);
|
||||
|
||||
// External types
|
||||
struct ImGuiWindow; // imgui.h
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// [Internal]
|
||||
// Helper class for simple bitmap manipulation (not particularly efficient!)
|
||||
struct IMGUI_API ImGuiCaptureImageBuf
|
||||
{
|
||||
int Width;
|
||||
int Height;
|
||||
unsigned int* Data; // RGBA8
|
||||
|
||||
ImGuiCaptureImageBuf() { Width = Height = 0; Data = nullptr; }
|
||||
~ImGuiCaptureImageBuf() { Clear(); }
|
||||
|
||||
void Clear(); // Free allocated memory buffer if such exists.
|
||||
void CreateEmpty(int w, int h); // Reallocate buffer for pixel data and zero it.
|
||||
bool SaveFile(const char* filename); // Save pixel data to specified image file.
|
||||
void RemoveAlpha(); // Clear alpha channel from all pixels.
|
||||
};
|
||||
|
||||
enum ImGuiCaptureFlags_ : unsigned int
|
||||
{
|
||||
ImGuiCaptureFlags_None = 0,
|
||||
ImGuiCaptureFlags_StitchAll = 1 << 0, // Capture entire window scroll area (by scrolling and taking multiple screenshot). Only works for a single window.
|
||||
ImGuiCaptureFlags_IncludeOtherWindows = 1 << 1, // Disable hiding other windows (when CaptureAddWindow has been called by default other windows are hidden)
|
||||
ImGuiCaptureFlags_IncludePopups = 1 << 2, // Expand capture area to automatically include visible popups (Unused if ImGuiCaptureFlags_IncludeOtherWindows is set)
|
||||
ImGuiCaptureFlags_HideMouseCursor = 1 << 3, // Hide render software mouse cursor during capture.
|
||||
ImGuiCaptureFlags_Instant = 1 << 4, // Perform capture on very same frame. Only works when capturing a rectangular region. Unsupported features: content stitching, window hiding, window relocation.
|
||||
ImGuiCaptureFlags_NoSave = 1 << 5 // Do not save output image.
|
||||
};
|
||||
|
||||
// Defines input and output arguments for capture process.
|
||||
// When capturing from tests you can usually use the ImGuiTestContext::CaptureXXX() helpers functions.
|
||||
struct ImGuiCaptureArgs
|
||||
{
|
||||
// [Input]
|
||||
ImGuiCaptureFlags InFlags = 0; // Flags for customizing behavior of screenshot tool.
|
||||
ImVector<ImGuiWindow*> InCaptureWindows; // Windows to capture. All other windows will be hidden. May be used with InCaptureRect to capture only some windows in specified rect.
|
||||
ImRect InCaptureRect; // Screen rect to capture. Does not include padding.
|
||||
float InPadding = 16.0f; // Extra padding at the edges of the screenshot. Ensure that there is available space around capture rect horizontally, also vertically if ImGuiCaptureFlags_StitchFullContents is not used.
|
||||
char InOutputFile[256] = ""; // Output will be saved to a file if InOutputImageBuf is nullptr.
|
||||
ImGuiCaptureImageBuf* InOutputImageBuf = nullptr; // _OR_ Output will be saved to image buffer if specified.
|
||||
int InRecordFPSTarget = 30; // FPS target for recording videos.
|
||||
int InSizeAlign = 0; // Resolution alignment (0 = auto, 1 = no alignment, >= 2 = align width/height to be multiple of given value)
|
||||
|
||||
// [Output]
|
||||
ImVec2 OutImageSize; // Produced image size.
|
||||
};
|
||||
|
||||
enum ImGuiCaptureStatus
|
||||
{
|
||||
ImGuiCaptureStatus_InProgress,
|
||||
ImGuiCaptureStatus_Done,
|
||||
ImGuiCaptureStatus_Error
|
||||
};
|
||||
|
||||
struct ImGuiCaptureWindowData
|
||||
{
|
||||
ImGuiWindow* Window;
|
||||
ImRect BackupRect;
|
||||
ImVec2 PosDuringCapture;
|
||||
};
|
||||
|
||||
// Implements functionality for capturing images
|
||||
struct IMGUI_API ImGuiCaptureContext
|
||||
{
|
||||
// IO
|
||||
ImFuncPtr(ImGuiScreenCaptureFunc) ScreenCaptureFunc = nullptr; // Graphics backend specific function that captures specified portion of framebuffer and writes RGBA data to `pixels` buffer.
|
||||
void* ScreenCaptureUserData = nullptr; // Custom user pointer which is passed to ScreenCaptureFunc. (Optional)
|
||||
char* VideoCaptureEncoderPath = nullptr; // Video encoder path (not owned, stored externally).
|
||||
int VideoCaptureEncoderPathSize = 0; // Optional. Set in order to edit this parameter from UI.
|
||||
char* VideoCaptureEncoderParams = nullptr; // Video encoder params (not owned, stored externally).
|
||||
int VideoCaptureEncoderParamsSize = 0; // Optional. Set in order to edit this parameter from UI.
|
||||
char* GifCaptureEncoderParams = nullptr; // Video encoder params for GIF output (not owned, stored externally).
|
||||
int GifCaptureEncoderParamsSize = 0; // Optional. Set in order to edit this parameter from UI.
|
||||
|
||||
// [Internal]
|
||||
ImRect _CaptureRect; // Viewport rect that is being captured.
|
||||
ImRect _CapturedWindowRect; // Top-left corner of region that covers all windows included in capture. This is not same as _CaptureRect.Min when capturing explicitly specified rect.
|
||||
int _ChunkNo = 0; // Number of chunk that is being captured when capture spans multiple frames.
|
||||
int _FrameNo = 0; // Frame number during capture process that spans multiple frames.
|
||||
ImVec2 _MouseRelativeToWindowPos; // Mouse cursor position relative to captured window (when _StitchAll is in use).
|
||||
ImGuiWindow* _HoveredWindow = nullptr; // Window which was hovered at capture start.
|
||||
ImGuiCaptureImageBuf _CaptureBuf; // Output image buffer.
|
||||
const ImGuiCaptureArgs* _CaptureArgs = nullptr; // Current capture args. Set only if capture is in progress.
|
||||
ImVector<ImGuiCaptureWindowData> _WindowsData; // Backup windows that will have their rect modified and restored. args->InCaptureWindows can not be used because popups may get closed during capture and no longer appear in that list.
|
||||
|
||||
// [Internal] Video recording
|
||||
bool _VideoRecording = false; // Flag indicating that video recording is in progress.
|
||||
double _VideoLastFrameTime = 0; // Time when last video frame was recorded.
|
||||
FILE* _VideoEncoderPipe = nullptr; // File writing to stdin of video encoder process.
|
||||
|
||||
// [Internal] Backups
|
||||
bool _BackupMouseDrawCursor = false; // Initial value of g.IO.MouseDrawCursor
|
||||
ImVec2 _BackupDisplayWindowPadding; // Backup padding. We set it to {0, 0} during capture.
|
||||
ImVec2 _BackupDisplaySafeAreaPadding; // Backup padding. We set it to {0, 0} during capture.
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
ImGuiCaptureContext(ImGuiScreenCaptureFunc capture_func = nullptr) { ScreenCaptureFunc = capture_func; _MouseRelativeToWindowPos = ImVec2(-FLT_MAX, -FLT_MAX); }
|
||||
|
||||
// These functions should be called from appropriate context hooks. See ImGui::AddContextHook() for more info.
|
||||
// (ImGuiTestEngine automatically calls that for you, so this only apply to independently created instance)
|
||||
void PreNewFrame();
|
||||
void PreRender();
|
||||
void PostRender();
|
||||
|
||||
// Update capturing. If this function returns true then it should be called again with same arguments on the next frame.
|
||||
ImGuiCaptureStatus CaptureUpdate(ImGuiCaptureArgs* args);
|
||||
void RestoreBackedUpData();
|
||||
void ClearState();
|
||||
|
||||
// Begin video capture. Call CaptureUpdate() every frame afterwards until it returns false.
|
||||
void BeginVideoCapture(ImGuiCaptureArgs* args);
|
||||
void EndVideoCapture();
|
||||
bool IsCapturingVideo();
|
||||
bool IsCapturing();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImGuiCaptureToolUI
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Implements UI for capturing images
|
||||
// (when using ImGuiTestEngine scripting API you may not need to use this at all)
|
||||
struct IMGUI_API ImGuiCaptureToolUI
|
||||
{
|
||||
float SnapGridSize = 32.0f; // Size of the grid cell for "snap to grid" functionality.
|
||||
char OutputLastFilename[256] = ""; // File name of last captured file.
|
||||
char* VideoCaptureExtension = nullptr; // Video file extension (e.g. ".gif" or ".mp4")
|
||||
int VideoCaptureExtensionSize = 0; // Optional. Set in order to edit this parameter from UI.
|
||||
|
||||
ImGuiCaptureArgs _CaptureArgs; // Capture args
|
||||
bool _StateIsPickingWindow = false;
|
||||
bool _StateIsCapturing = false;
|
||||
ImVector<ImGuiID> _SelectedWindows;
|
||||
char _OutputFileTemplate[256] = ""; //
|
||||
int _FileCounter = 0; // Counter which may be appended to file name when saving. By default, counting starts from 1. When done this field holds number of saved files.
|
||||
|
||||
// Public
|
||||
ImGuiCaptureToolUI();
|
||||
void ShowCaptureToolWindow(ImGuiCaptureContext* context, bool* p_open = nullptr); // Render a capture tool window with various options and utilities.
|
||||
|
||||
// [Internal]
|
||||
void _CaptureWindowPicker(ImGuiCaptureArgs* args); // Render a window picker that captures picked window to file specified in file_name.
|
||||
void _CaptureWindowsSelector(ImGuiCaptureContext* context, ImGuiCaptureArgs* args); // Render a selector for selecting multiple windows for capture.
|
||||
void _SnapWindowsToGrid(float cell_size); // Snap edges of all visible windows to a virtual grid.
|
||||
bool _InitializeOutputFile(); // Format output file template into capture args struct and ensure target directory exists.
|
||||
bool _ShowEncoderConfigFields(ImGuiCaptureContext* context);
|
||||
};
|
||||
|
||||
#define IMGUI_CAPTURE_DEFAULT_VIDEO_PARAMS_FOR_FFMPEG "-hide_banner -loglevel error -r $FPS -f rawvideo -pix_fmt rgba -s $WIDTHx$HEIGHT -i - -threads 0 -y -preset ultrafast -pix_fmt yuv420p -crf 20 $OUTPUT"
|
||||
#define IMGUI_CAPTURE_DEFAULT_GIF_PARAMS_FOR_FFMPEG "-hide_banner -loglevel error -r $FPS -f rawvideo -pix_fmt rgba -s $WIDTHx$HEIGHT -i - -threads 0 -y -filter_complex \"split=2 [a] [b]; [a] palettegen [pal]; [b] [pal] paletteuse\" $OUTPUT"
|
||||
643
lib/third_party/imgui/imgui_test_engine/include/imgui_te_context.h
vendored
Normal file
643
lib/third_party/imgui/imgui_test_engine/include/imgui_te_context.h
vendored
Normal file
@@ -0,0 +1,643 @@
|
||||
// dear imgui test engine
|
||||
// (context when a running test + end user automation API)
|
||||
// This is the main (if not only) interface that your Tests will be using.
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h" // ImGuiAxis, ImGuiItemStatusFlags, ImGuiInputSource, ImGuiWindow
|
||||
#include "imgui_te_engine.h" // ImGuiTestStatus, ImGuiTestRunFlags, ImGuiTestActiveFunc, ImGuiTestItemInfo, ImGuiTestLogFlags
|
||||
|
||||
/*
|
||||
|
||||
Index of this file:
|
||||
// [SECTION] Header mess, warnings
|
||||
// [SECTION] Forward declarations
|
||||
// [SECTION] ImGuiTestRef
|
||||
// [SECTION] Helper keys
|
||||
// [SECTION] ImGuiTestContext related Flags/Enumerations
|
||||
// [SECTION] ImGuiTestGenericVars, ImGuiTestGenericItemStatus
|
||||
// [SECTION] ImGuiTestContext
|
||||
// [SECTION] Debugging macros: IM_SUSPEND_TESTFUNC()
|
||||
// [SECTION] Testing/Checking macros: IM_CHECK(), IM_ERRORF() etc.
|
||||
|
||||
*/
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Header mess, warnings
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Undo some of the damage done by <windows.h>
|
||||
#ifdef Yield
|
||||
#undef Yield
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Forward declarations
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// This file
|
||||
typedef int ImGuiTestOpFlags; // Flags: See ImGuiTestOpFlags_
|
||||
|
||||
// External: imgui
|
||||
struct ImGuiDockNode;
|
||||
struct ImGuiTabBar;
|
||||
struct ImGuiWindow;
|
||||
|
||||
// External: test engine
|
||||
struct ImGuiTest; // A test registered with IM_REGISTER_TEST()
|
||||
struct ImGuiTestEngine; // Test Engine Instance (opaque)
|
||||
struct ImGuiTestEngineIO; // Test Engine IO structure (configuration flags, state)
|
||||
struct ImGuiTestItemInfo; // Information gathered about an item: label, status, bounding box etc.
|
||||
struct ImGuiTestItemList; // Result of an GatherItems() query
|
||||
struct ImGuiTestInputs; // Test Engine Simulated Inputs structure (opaque)
|
||||
struct ImGuiTestGatherTask; // Test Engine task for scanning/finding items
|
||||
struct ImGuiCaptureArgs; // Parameters for ctx->CaptureXXX functions
|
||||
enum ImGuiTestVerboseLevel : int;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] ImGuiTestRef
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Weak reference to an Item/Window given an hashed ID _or_ a string path ID.
|
||||
// This is most often passed as argument to function and generally has a very short lifetime.
|
||||
// Documentation: https://github.com/ocornut/imgui_test_engine/wiki/Named-References
|
||||
// (SUGGESTION: add those constructors to "VA Step Filter" (Visual Assist) or a .natstepfilter file (Visual Studio) so they are skipped by F11 (StepInto)
|
||||
struct IMGUI_API ImGuiTestRef
|
||||
{
|
||||
ImGuiID ID; // Pre-hashed ID
|
||||
const char* Path; // Relative or absolute path (string pointed to, not owned, as our lifetime is very short)
|
||||
|
||||
ImGuiTestRef() { ID = 0; Path = nullptr; }
|
||||
ImGuiTestRef(ImGuiID id) { ID = id; Path = nullptr; }
|
||||
ImGuiTestRef(const char* path) { ID = 0; Path = path; }
|
||||
bool IsEmpty() const { return ID == 0 && (Path == nullptr || Path[0] == 0); }
|
||||
};
|
||||
|
||||
// Debug helper to output a string showing the Path, ID or Debug Label based on what is available (some items only have ID as we couldn't find/store a Path)
|
||||
// (The size is arbitrary, this is only used for logging info the user/debugger)
|
||||
struct IMGUI_API ImGuiTestRefDesc
|
||||
{
|
||||
char Buf[80];
|
||||
|
||||
const char* c_str() { return Buf; }
|
||||
ImGuiTestRefDesc(const ImGuiTestRef& ref);
|
||||
ImGuiTestRefDesc(const ImGuiTestRef& ref, const ImGuiTestItemInfo& item);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] ImGuiTestContext related Flags/Enumerations
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Named actions. Generally you will call the named helpers e.g. ItemClick(). This is used by shared/low-level functions such as ItemAction().
|
||||
enum ImGuiTestAction
|
||||
{
|
||||
ImGuiTestAction_Unknown = 0,
|
||||
ImGuiTestAction_Hover, // Move mouse
|
||||
ImGuiTestAction_Click, // Move mouse and click
|
||||
ImGuiTestAction_DoubleClick, // Move mouse and double-click
|
||||
ImGuiTestAction_Check, // Check item if unchecked (Checkbox, MenuItem or any widget reporting ImGuiItemStatusFlags_Checkable)
|
||||
ImGuiTestAction_Uncheck, // Uncheck item if checked
|
||||
ImGuiTestAction_Open, // Open item if closed (TreeNode, BeginMenu or any widget reporting ImGuiItemStatusFlags_Openable)
|
||||
ImGuiTestAction_Close, // Close item if opened
|
||||
ImGuiTestAction_Input, // Start text inputing into a field (e.g. CTRL+Click on Drags/Slider, click on InputText etc.)
|
||||
ImGuiTestAction_NavActivate, // Activate item with navigation
|
||||
ImGuiTestAction_COUNT
|
||||
};
|
||||
|
||||
// Generic flags for many ImGuiTestContext functions
|
||||
// Some flags are only supported by a handful of functions. Check function headers for list of supported flags.
|
||||
enum ImGuiTestOpFlags_
|
||||
{
|
||||
ImGuiTestOpFlags_None = 0,
|
||||
ImGuiTestOpFlags_NoCheckHoveredId = 1 << 1, // Don't check for HoveredId after aiming for a widget. A few situations may want this: while e.g. dragging or another items prevents hovering, or for items that don't use ItemHoverable()
|
||||
ImGuiTestOpFlags_NoError = 1 << 2, // Don't abort/error e.g. if the item cannot be found or the operation doesn't succeed.
|
||||
ImGuiTestOpFlags_NoFocusWindow = 1 << 3, // Don't focus window when aiming at an item
|
||||
ImGuiTestOpFlags_NoAutoUncollapse = 1 << 4, // Disable automatically uncollapsing windows (useful when specifically testing Collapsing behaviors)
|
||||
ImGuiTestOpFlags_NoAutoOpenFullPath = 1 << 5, // Disable automatically opening intermediaries (e.g. ItemClick("Hello/OK") will automatically first open "Hello" if "OK" isn't found. Only works if ref is a string path.
|
||||
ImGuiTestOpFlags_NoYield = 1 << 6, // Don't yield (only supported by a few functions), in case you need to manage rigorous per-frame timing.
|
||||
ImGuiTestOpFlags_IsSecondAttempt = 1 << 7, // Used by recursing functions to indicate a second attempt
|
||||
ImGuiTestOpFlags_MoveToEdgeL = 1 << 8, // Simple Dumb aiming helpers to test widget that care about clicking position. May need to replace will better functionalities.
|
||||
ImGuiTestOpFlags_MoveToEdgeR = 1 << 9,
|
||||
ImGuiTestOpFlags_MoveToEdgeU = 1 << 10,
|
||||
ImGuiTestOpFlags_MoveToEdgeD = 1 << 11,
|
||||
};
|
||||
|
||||
// Advanced filtering for ItemActionAll()
|
||||
struct IMGUI_API ImGuiTestActionFilter
|
||||
{
|
||||
int MaxDepth;
|
||||
int MaxPasses;
|
||||
const int* MaxItemCountPerDepth;
|
||||
ImGuiItemStatusFlags RequireAllStatusFlags;
|
||||
ImGuiItemStatusFlags RequireAnyStatusFlags;
|
||||
|
||||
ImGuiTestActionFilter() { MaxDepth = -1; MaxPasses = -1; MaxItemCountPerDepth = nullptr; RequireAllStatusFlags = RequireAnyStatusFlags = 0; }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] ImGuiTestGenericVars, ImGuiTestGenericItemStatus
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Helper struct to store various query-able state of an item.
|
||||
// This facilitate interactions between GuiFunc and TestFunc, since those state are frequently used.
|
||||
struct IMGUI_API ImGuiTestGenericItemStatus
|
||||
{
|
||||
int RetValue; // return value
|
||||
int Hovered; // result of IsItemHovered()
|
||||
int Active; // result of IsItemActive()
|
||||
int Focused; // result of IsItemFocused()
|
||||
int Clicked; // result of IsItemClicked()
|
||||
int Visible; // result of IsItemVisible()
|
||||
int Edited; // result of IsItemEdited()
|
||||
int Activated; // result of IsItemActivated()
|
||||
int Deactivated; // result of IsItemDeactivated()
|
||||
int DeactivatedAfterEdit; // result of IsItemDeactivatedAfterEdit()
|
||||
|
||||
ImGuiTestGenericItemStatus() { Clear(); }
|
||||
void Clear() { memset(this, 0, sizeof(*this)); }
|
||||
void QuerySet(bool ret_val = false) { Clear(); QueryInc(ret_val); }
|
||||
void QueryInc(bool ret_val = false) { RetValue += ret_val; Hovered += ImGui::IsItemHovered(); Active += ImGui::IsItemActive(); Focused += ImGui::IsItemFocused(); Clicked += ImGui::IsItemClicked(); Visible += ImGui::IsItemVisible(); Edited += ImGui::IsItemEdited(); Activated += ImGui::IsItemActivated(); Deactivated += ImGui::IsItemDeactivated(); DeactivatedAfterEdit += ImGui::IsItemDeactivatedAfterEdit(); }
|
||||
void Draw() { ImGui::Text("Ret: %d, Hovered: %d, Active: %d, Focused: %d\nClicked: %d, Visible: %d, Edited: %d\nActivated: %d, Deactivated: %d, DeactivatedAfterEdit: %d", RetValue, Hovered, Active, Focused, Clicked, Visible, Edited, Activated, Deactivated, DeactivatedAfterEdit); }
|
||||
};
|
||||
|
||||
// Generic structure with various storage fields.
|
||||
// This is useful for tests to quickly share data between GuiFunc and TestFunc without creating custom data structure.
|
||||
// If those fields are not enough: using test->SetVarsDataType<>() + ctx->GetVars<>() it is possible to store custom data.
|
||||
struct IMGUI_API ImGuiTestGenericVars
|
||||
{
|
||||
// Generic storage with a bit of semantic to make user/test code look neater
|
||||
int Step;
|
||||
int Count;
|
||||
ImGuiID DockId;
|
||||
ImGuiID OwnerId;
|
||||
ImVec2 WindowSize;
|
||||
ImGuiWindowFlags WindowFlags;
|
||||
ImGuiTableFlags TableFlags;
|
||||
ImGuiPopupFlags PopupFlags;
|
||||
ImGuiTestGenericItemStatus Status;
|
||||
bool ShowWindow1, ShowWindow2;
|
||||
bool UseClipper;
|
||||
bool UseViewports;
|
||||
float Width;
|
||||
ImVec2 Pos;
|
||||
ImVec2 Pivot;
|
||||
ImVec2 ItemSize;
|
||||
ImVec4 Color1, Color2;
|
||||
|
||||
// Generic unnamed storage
|
||||
int Int1, Int2, IntArray[10];
|
||||
float Float1, Float2, FloatArray[10];
|
||||
bool Bool1, Bool2, BoolArray[10];
|
||||
ImGuiID Id, IdArray[10];
|
||||
char Str1[256], Str2[256];
|
||||
|
||||
ImGuiTestGenericVars() { Clear(); }
|
||||
void Clear() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] ImGuiTestContext
|
||||
// Context for a running ImGuiTest
|
||||
// This is the interface that most tests will interact with.
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct IMGUI_API ImGuiTestContext
|
||||
{
|
||||
// User variables
|
||||
ImGuiTestGenericVars GenericVars; // Generic variables holder for convenience.
|
||||
void* UserVars = nullptr; // Access using ctx->GetVars<Type>(). Setup with test->SetVarsDataType<>().
|
||||
|
||||
// Public fields
|
||||
ImGuiContext* UiContext = nullptr; // UI context
|
||||
ImGuiTestEngineIO* EngineIO = nullptr; // Test Engine IO/settings
|
||||
ImGuiTest* Test = nullptr; // Test currently running
|
||||
ImGuiTestOutput* TestOutput = nullptr; // Test output (generally == &Test->Output)
|
||||
ImGuiTestOpFlags OpFlags = ImGuiTestOpFlags_None; // Flags affecting all operation (supported: ImGuiTestOpFlags_NoAutoUncollapse)
|
||||
int PerfStressAmount = 0; // Convenience copy of engine->IO.PerfStressAmount
|
||||
int FrameCount = 0; // Test frame count (restarts from zero every time)
|
||||
int FirstTestFrameCount = 0; // First frame where TestFunc is running (after warm-up frame). This is generally -1 or 0 depending on whether we have warm up enabled
|
||||
bool FirstGuiFrame = false;
|
||||
bool HasDock = false; // #ifdef IMGUI_HAS_DOCK expressed in an easier to test value
|
||||
ImGuiCaptureArgs* CaptureArgs = nullptr; // Capture settings used by ctx->Capture*() functions
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [Internal Fields]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
ImGuiTestEngine* Engine = nullptr;
|
||||
ImGuiTestInputs* Inputs = nullptr;
|
||||
ImGuiTestRunFlags RunFlags = ImGuiTestRunFlags_None;
|
||||
ImGuiTestActiveFunc ActiveFunc = ImGuiTestActiveFunc_None; // None/GuiFunc/TestFunc
|
||||
double RunningTime = 0.0; // Amount of wall clock time the Test has been running. Used by safety watchdog.
|
||||
int ActionDepth = 0; // Nested depth of ctx-> function calls (used to decorate log)
|
||||
int CaptureCounter = 0; // Number of captures
|
||||
int ErrorCounter = 0; // Number of errors (generally this maxxes at 1 as most functions will early out)
|
||||
bool Abort = false;
|
||||
double PerfRefDt = -1.0;
|
||||
int PerfIterations = 400; // Number of frames for PerfCapture() measurements
|
||||
char RefStr[256] = { 0 }; // Reference window/path over which all named references are based
|
||||
ImGuiID RefID = 0; // Reference ID over which all named references are based
|
||||
ImGuiID RefWindowID = 0; // ID of a window that contains RefID item
|
||||
ImGuiInputSource InputMode = ImGuiInputSource_Mouse; // Prefer interacting with mouse/keyboard/gamepad
|
||||
ImVector<char> TempString;
|
||||
ImVector<char> Clipboard; // Private clipboard for the test instance
|
||||
ImVector<ImGuiWindow*> ForeignWindowsToHide;
|
||||
ImGuiTestItemInfo DummyItemInfoNull; // Storage for ItemInfoNull()
|
||||
bool CachedLinesPrintedToTTY = false;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Public API
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Main control
|
||||
void Finish(ImGuiTestStatus status = ImGuiTestStatus_Success); // Set test status and stop running. Usually called when running test logic from GuiFunc() only.
|
||||
ImGuiTestStatus RunChildTest(const char* test_name, ImGuiTestRunFlags flags = 0); // [Experimental] Run another test from the current test.
|
||||
template <typename T> T& GetVars() { IM_ASSERT(UserVars != nullptr); return *(T*)(UserVars); }// Campanion to using t->SetVarsDataType<>(). FIXME: Assert to compare sizes
|
||||
|
||||
// Main status queries
|
||||
bool IsError() const { return TestOutput->Status == ImGuiTestStatus_Error || Abort; }
|
||||
bool IsWarmUpGuiFrame() const { return FrameCount < FirstTestFrameCount; } // Unless test->Flags has ImGuiTestFlags_NoGuiWarmUp, we run GuiFunc() twice before running TestFunc(). Those frames are called "WarmUp" frames.
|
||||
bool IsFirstGuiFrame() const { return FirstGuiFrame; }
|
||||
bool IsFirstTestFrame() const { return FrameCount == FirstTestFrameCount; } // First frame where TestFunc is running (after warm-up frame).
|
||||
bool IsGuiFuncOnly() const { return (RunFlags & ImGuiTestRunFlags_GuiFuncOnly) != 0; }
|
||||
|
||||
// Debugging
|
||||
bool SuspendTestFunc(const char* file = nullptr, int line = 0); // [DEBUG] Generally called via IM_SUSPEND_TESTFUNC
|
||||
|
||||
// Logging
|
||||
void LogEx(ImGuiTestVerboseLevel level, ImGuiTestLogFlags flags, const char* fmt, ...) IM_FMTARGS(4);
|
||||
void LogExV(ImGuiTestVerboseLevel level, ImGuiTestLogFlags flags, const char* fmt, va_list args) IM_FMTLIST(4);
|
||||
void LogToTTY(ImGuiTestVerboseLevel level, const char* message, const char* message_end = nullptr);
|
||||
void LogToDebugger(ImGuiTestVerboseLevel level, const char* message);
|
||||
void LogDebug(const char* fmt, ...) IM_FMTARGS(2); // ImGuiTestVerboseLevel_Debug or ImGuiTestVerboseLevel_Trace depending on context depth
|
||||
void LogInfo(const char* fmt, ...) IM_FMTARGS(2); // ImGuiTestVerboseLevel_Info
|
||||
void LogWarning(const char* fmt, ...) IM_FMTARGS(2); // ImGuiTestVerboseLevel_Warning
|
||||
void LogError(const char* fmt, ...) IM_FMTARGS(2); // ImGuiTestVerboseLevel_Error
|
||||
void LogBasicUiState();
|
||||
void LogItemList(ImGuiTestItemList* list);
|
||||
|
||||
// Yield, Timing
|
||||
void Yield(int count = 1);
|
||||
void Sleep(float time_in_second); // Sleep for a given simulation time, unless in Fast mode
|
||||
void SleepShort(); // Standard short delay of io.ActionDelayShort (~0.15f), unless in Fast mode.
|
||||
void SleepStandard(); // Standard regular delay of io.ActionDelayStandard (~0.40f), unless in Fast mode.
|
||||
void SleepNoSkip(float time_in_second, float framestep_in_second);
|
||||
|
||||
// Base Reference
|
||||
// - ItemClick("Window/Button") --> click "Window/Button"
|
||||
// - SetRef("Window"), ItemClick("Button") --> click "Window/Button"
|
||||
// - SetRef("Window"), ItemClick("/Button") --> click "Window/Button"
|
||||
// - SetRef("Window"), ItemClick("//Button") --> click "/Button"
|
||||
// - SetRef("//$FOCUSED"), ItemClick("Button") --> click "Button" in focused window.
|
||||
// See https://github.com/ocornut/imgui_test_engine/wiki/Named-References about using ImGuiTestRef in all ImGuiTestContext functions.
|
||||
// Note: SetRef() may take multiple frames to complete if specified ref is an item id.
|
||||
// Note: SetRef() ignores current reference, so they are always absolute path.
|
||||
void SetRef(ImGuiTestRef ref);
|
||||
void SetRef(ImGuiWindow* window); // Shortcut to SetRef(window->Name) which works for ChildWindow (see code)
|
||||
ImGuiTestRef GetRef();
|
||||
|
||||
// Windows
|
||||
// - Use WindowInfo() to access path to child windows, since the paths are internally mangled.
|
||||
// - SetRef(WindowInfo("Parent/Child")->Window) --> set ref to child window.
|
||||
ImGuiTestItemInfo WindowInfo(ImGuiTestRef window_ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
void WindowClose(ImGuiTestRef window_ref);
|
||||
void WindowCollapse(ImGuiTestRef window_ref, bool collapsed);
|
||||
void WindowFocus(ImGuiTestRef window_ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
void WindowBringToFront(ImGuiTestRef window_ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
void WindowMove(ImGuiTestRef window_ref, ImVec2 pos, ImVec2 pivot = ImVec2(0.0f, 0.0f), ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
void WindowResize(ImGuiTestRef window_ref, ImVec2 sz);
|
||||
bool WindowTeleportToMakePosVisible(ImGuiTestRef window_ref, ImVec2 pos_in_window);
|
||||
ImGuiWindow*GetWindowByRef(ImGuiTestRef window_ref);
|
||||
|
||||
// Popups
|
||||
void PopupCloseOne();
|
||||
void PopupCloseAll();
|
||||
ImGuiID PopupGetWindowID(ImGuiTestRef ref);
|
||||
|
||||
// Get hash for a decorated ID Path.
|
||||
// Note: for windows you may use WindowInfo()
|
||||
ImGuiID GetID(ImGuiTestRef ref);
|
||||
ImGuiID GetID(ImGuiTestRef ref, ImGuiTestRef seed_ref);
|
||||
|
||||
// Miscellaneous helpers
|
||||
ImVec2 GetPosOnVoid(ImGuiViewport* viewport); // Find a point that has no windows // FIXME: This needs error return and flag to enable/disable forcefully finding void.
|
||||
ImVec2 GetWindowTitlebarPoint(ImGuiTestRef window_ref); // Return a clickable point on window title-bar (window tab for docked windows).
|
||||
ImVec2 GetMainMonitorWorkPos(); // Work pos and size of main viewport when viewports are disabled, or work pos and size of monitor containing main viewport when viewports are enabled.
|
||||
ImVec2 GetMainMonitorWorkSize();
|
||||
|
||||
// Screenshot/Video Captures
|
||||
void CaptureReset(); // Reset state (use when doing multiple captures)
|
||||
void CaptureSetExtension(const char* ext); // Set capture file format (otherwise for video this default to EngineIO->VideoCaptureExtension)
|
||||
bool CaptureAddWindow(ImGuiTestRef ref); // Add window to be captured (default to capture everything)
|
||||
void CaptureScreenshotWindow(ImGuiTestRef ref, int capture_flags = 0); // Trigger a screen capture of a single window (== CaptureAddWindow() + CaptureScreenshot())
|
||||
bool CaptureScreenshot(int capture_flags = 0); // Trigger a screen capture
|
||||
bool CaptureBeginVideo(); // Start a video capture
|
||||
bool CaptureEndVideo();
|
||||
|
||||
// Mouse inputs
|
||||
void MouseMove(ImGuiTestRef ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
void MouseMoveToPos(ImVec2 pos);
|
||||
void MouseTeleportToPos(ImVec2 pos, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
void MouseClick(ImGuiMouseButton button = 0);
|
||||
void MouseClickMulti(ImGuiMouseButton button, int count);
|
||||
void MouseDoubleClick(ImGuiMouseButton button = 0);
|
||||
void MouseDown(ImGuiMouseButton button = 0);
|
||||
void MouseUp(ImGuiMouseButton button = 0);
|
||||
void MouseLiftDragThreshold(ImGuiMouseButton button = 0);
|
||||
void MouseDragWithDelta(ImVec2 delta, ImGuiMouseButton button = 0);
|
||||
void MouseWheel(ImVec2 delta);
|
||||
void MouseWheelX(float dx) { MouseWheel(ImVec2(dx, 0.0f)); }
|
||||
void MouseWheelY(float dy) { MouseWheel(ImVec2(0.0f, dy)); }
|
||||
void MouseMoveToVoid(ImGuiViewport* viewport = nullptr);
|
||||
void MouseClickOnVoid(ImGuiMouseButton button = 0, ImGuiViewport* viewport = nullptr);
|
||||
ImGuiWindow*FindHoveredWindowAtPos(const ImVec2& pos);
|
||||
bool FindExistingVoidPosOnViewport(ImGuiViewport* viewport, ImVec2* out);
|
||||
|
||||
// Mouse inputs: Viewports
|
||||
// - This is automatically called by SetRef() and any mouse action taking an item reference (e.g. ItemClick("button"), MouseClick("button"))
|
||||
// - But when using raw position directy e.g. MouseMoveToPos() / MouseTeleportToPos() without referring to the parent window before, this needs to be set.
|
||||
void MouseSetViewport(ImGuiWindow* window);
|
||||
void MouseSetViewportID(ImGuiID viewport_id);
|
||||
|
||||
// Keyboard inputs
|
||||
void KeyDown(ImGuiKeyChord key_chord);
|
||||
void KeyUp(ImGuiKeyChord key_chord);
|
||||
void KeyPress(ImGuiKeyChord key_chord, int count = 1);
|
||||
void KeyHold(ImGuiKeyChord key_chord, float time);
|
||||
void KeySetEx(ImGuiKeyChord key_chord, bool is_down, float time);
|
||||
void KeyChars(const char* chars); // Input characters
|
||||
void KeyCharsAppend(const char* chars); // Input characters at end of field
|
||||
void KeyCharsAppendEnter(const char* chars); // Input characters at end of field, press Enter
|
||||
void KeyCharsReplace(const char* chars); // Delete existing field then input characters
|
||||
void KeyCharsReplaceEnter(const char* chars); // Delete existing field then input characters, press Enter
|
||||
|
||||
// Navigation inputs
|
||||
// FIXME: Need some redesign/refactoring:
|
||||
// - This was initially intended to: replace mouse action with keyboard/gamepad
|
||||
// - Abstract keyboard vs gamepad actions
|
||||
// However this is widely inconsistent and unfinished at this point.
|
||||
void SetInputMode(ImGuiInputSource input_mode); // Mouse or Keyboard or Gamepad. In Keyboard or Gamepad mode, actions such as ItemClick or ItemInput are using nav facilities instead of Mouse.
|
||||
void NavMoveTo(ImGuiTestRef ref);
|
||||
void NavActivate(); // Activate current selected item: activate button, tweak sliders/drags. Equivalent of pressing Space on keyboard, ImGuiKey_GamepadFaceUp on a gamepad.
|
||||
void NavInput(); // Input into select item: input sliders/drags. Equivalent of pressing Enter on keyboard, ImGuiKey_GamepadFaceDown on a gamepad.
|
||||
|
||||
// Scrolling
|
||||
void ScrollTo(ImGuiTestRef ref, ImGuiAxis axis, float scroll_v, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
void ScrollToX(ImGuiTestRef ref, float scroll_x) { ScrollTo(ref, ImGuiAxis_X, scroll_x); }
|
||||
void ScrollToY(ImGuiTestRef ref, float scroll_y) { ScrollTo(ref, ImGuiAxis_Y, scroll_y); }
|
||||
void ScrollToTop(ImGuiTestRef ref);
|
||||
void ScrollToBottom(ImGuiTestRef ref);
|
||||
void ScrollToItem(ImGuiTestRef ref, ImGuiAxis axis, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
void ScrollToItemX(ImGuiTestRef ref);
|
||||
void ScrollToItemY(ImGuiTestRef ref);
|
||||
void ScrollToTabItem(ImGuiTabBar* tab_bar, ImGuiID tab_id);
|
||||
bool ScrollErrorCheck(ImGuiAxis axis, float expected, float actual, int* remaining_attempts);
|
||||
void ScrollVerifyScrollMax(ImGuiTestRef ref);
|
||||
|
||||
// Low-level queries
|
||||
// - ItemInfo queries never returns nullptr! Instead they return an empty instance (info->IsEmpty(), info->ID == 0) and set contexted as errored.
|
||||
// - You can use ImGuiTestOpFlags_NoError to do a query without marking context as errored. This is what ItemExists() does.
|
||||
ImGuiTestItemInfo ItemInfo(ImGuiTestRef ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
ImGuiTestItemInfo ItemInfoOpenFullPath(ImGuiTestRef ref, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
ImGuiID ItemInfoHandleWildcardSearch(const char* wildcard_prefix_start, const char* wildcard_prefix_end, const char* wildcard_suffix_start);
|
||||
ImGuiTestItemInfo ItemInfoNull() { return ImGuiTestItemInfo(); }
|
||||
void GatherItems(ImGuiTestItemList* out_list, ImGuiTestRef parent, int depth = -1);
|
||||
|
||||
// Item/Widgets manipulation
|
||||
void ItemAction(ImGuiTestAction action, ImGuiTestRef ref, ImGuiTestOpFlags flags = 0, void* action_arg = nullptr);
|
||||
void ItemClick(ImGuiTestRef ref, ImGuiMouseButton button = 0, ImGuiTestOpFlags flags = 0) { ItemAction(ImGuiTestAction_Click, ref, flags, (void*)(size_t)button); }
|
||||
void ItemDoubleClick(ImGuiTestRef ref, ImGuiTestOpFlags flags = 0) { ItemAction(ImGuiTestAction_DoubleClick, ref, flags); }
|
||||
void ItemCheck(ImGuiTestRef ref, ImGuiTestOpFlags flags = 0) { ItemAction(ImGuiTestAction_Check, ref, flags); }
|
||||
void ItemUncheck(ImGuiTestRef ref, ImGuiTestOpFlags flags = 0) { ItemAction(ImGuiTestAction_Uncheck, ref, flags); }
|
||||
void ItemOpen(ImGuiTestRef ref, ImGuiTestOpFlags flags = 0) { ItemAction(ImGuiTestAction_Open, ref, flags); }
|
||||
void ItemClose(ImGuiTestRef ref, ImGuiTestOpFlags flags = 0) { ItemAction(ImGuiTestAction_Close, ref, flags); }
|
||||
void ItemInput(ImGuiTestRef ref, ImGuiTestOpFlags flags = 0) { ItemAction(ImGuiTestAction_Input, ref, flags); }
|
||||
void ItemNavActivate(ImGuiTestRef ref, ImGuiTestOpFlags flags = 0) { ItemAction(ImGuiTestAction_NavActivate, ref, flags); }
|
||||
|
||||
// Item/Widgets: Batch actions over an entire scope
|
||||
void ItemActionAll(ImGuiTestAction action, ImGuiTestRef ref_parent, const ImGuiTestActionFilter* filter = nullptr);
|
||||
void ItemOpenAll(ImGuiTestRef ref_parent, int depth = -1, int passes = -1);
|
||||
void ItemCloseAll(ImGuiTestRef ref_parent, int depth = -1, int passes = -1);
|
||||
|
||||
// Item/Widgets: Helpers to easily set a value
|
||||
void ItemInputValue(ImGuiTestRef ref, int v);
|
||||
void ItemInputValue(ImGuiTestRef ref, float f);
|
||||
void ItemInputValue(ImGuiTestRef ref, const char* str);
|
||||
|
||||
// Item/Widgets: Helpers to easily read a value by selecting Slider/Drag/Input text, copying it and parsing it.
|
||||
// - This requires the item to be selectable (we will later provide helpers that works in more general manner)
|
||||
// - (this temporarily use the internal test clipboard, but original clipboard value is restored afterwards)
|
||||
// See https://github.com/ocornut/imgui_test_engine/wiki/Automation-API#accessing-your-data
|
||||
int ItemReadAsInt(ImGuiTestRef ref);
|
||||
float ItemReadAsFloat(ImGuiTestRef ref);
|
||||
bool ItemReadAsScalar(ImGuiTestRef ref, ImGuiDataType data_type, void* out_data, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None);
|
||||
const char* ItemReadAsString(ImGuiTestRef ref);
|
||||
size_t ItemReadAsString(ImGuiTestRef ref, char* out_buf, size_t out_buf_size);
|
||||
|
||||
// Item/Widgets: Status query
|
||||
bool ItemExists(ImGuiTestRef ref);
|
||||
bool ItemIsChecked(ImGuiTestRef ref);
|
||||
bool ItemIsOpened(ImGuiTestRef ref);
|
||||
void ItemVerifyCheckedIfAlive(ImGuiTestRef ref, bool checked);
|
||||
|
||||
// Item/Widgets: Drag and Mouse operations
|
||||
void ItemHold(ImGuiTestRef ref, float time);
|
||||
void ItemHoldForFrames(ImGuiTestRef ref, int frames);
|
||||
void ItemDragOverAndHold(ImGuiTestRef ref_src, ImGuiTestRef ref_dst);
|
||||
void ItemDragAndDrop(ImGuiTestRef ref_src, ImGuiTestRef ref_dst, ImGuiMouseButton button = 0);
|
||||
void ItemDragWithDelta(ImGuiTestRef ref_src, ImVec2 pos_delta);
|
||||
|
||||
// Helpers for Tab Bars widgets
|
||||
void TabClose(ImGuiTestRef ref);
|
||||
bool TabBarCompareOrder(ImGuiTabBar* tab_bar, const char** tab_order);
|
||||
|
||||
// Helpers for MenuBar and Menus widgets
|
||||
// - e.g. MenuCheck("File/Options/Enable grid"); // Access menu in current ref window.
|
||||
// - e.g. MenuClick("//Window/File/Quit"); // Access menu in another window.
|
||||
void MenuAction(ImGuiTestAction action, ImGuiTestRef ref);
|
||||
void MenuActionAll(ImGuiTestAction action, ImGuiTestRef ref_parent);
|
||||
void MenuClick(ImGuiTestRef ref) { MenuAction(ImGuiTestAction_Click, ref); }
|
||||
void MenuCheck(ImGuiTestRef ref) { MenuAction(ImGuiTestAction_Check, ref); }
|
||||
void MenuUncheck(ImGuiTestRef ref) { MenuAction(ImGuiTestAction_Uncheck, ref); }
|
||||
void MenuCheckAll(ImGuiTestRef ref_parent) { MenuActionAll(ImGuiTestAction_Check, ref_parent); }
|
||||
void MenuUncheckAll(ImGuiTestRef ref_parent) { MenuActionAll(ImGuiTestAction_Uncheck, ref_parent); }
|
||||
|
||||
// Helpers for Combo Boxes
|
||||
void ComboClick(ImGuiTestRef ref);
|
||||
void ComboClickAll(ImGuiTestRef ref);
|
||||
|
||||
// Helpers for Tables
|
||||
void TableOpenContextMenu(ImGuiTestRef ref, int column_n = -1);
|
||||
ImGuiSortDirection TableClickHeader(ImGuiTestRef ref, const char* label, ImGuiKeyChord key_mods = 0);
|
||||
void TableSetColumnEnabled(ImGuiTestRef ref, const char* label, bool enabled);
|
||||
void TableResizeColumn(ImGuiTestRef ref, int column_n, float width);
|
||||
const ImGuiTableSortSpecs* TableGetSortSpecs(ImGuiTestRef ref);
|
||||
|
||||
// Viewports
|
||||
// IMPORTANT: Those function may alter Platform state (unless using the "Mock Viewport" backend). Use carefully.
|
||||
// Those are mostly useful to simulate OS actions and testing of viewport-specific features, may not be useful to most users.
|
||||
#ifdef IMGUI_HAS_VIEWPORT
|
||||
void ViewportPlatform_SetWindowPos(ImGuiViewport* viewport, const ImVec2& pos);
|
||||
void ViewportPlatform_SetWindowSize(ImGuiViewport* viewport, const ImVec2& size);
|
||||
void ViewportPlatform_SetWindowFocus(ImGuiViewport* viewport);
|
||||
void ViewportPlatform_CloseWindow(ImGuiViewport* viewport);
|
||||
#endif
|
||||
|
||||
// Docking
|
||||
#ifdef IMGUI_HAS_DOCK
|
||||
void DockClear(const char* window_name, ...);
|
||||
void DockInto(ImGuiTestRef src_id, ImGuiTestRef dst_id, ImGuiDir split_dir = ImGuiDir_None, bool is_outer_docking = false, ImGuiTestOpFlags flags = 0);
|
||||
void UndockNode(ImGuiID dock_id);
|
||||
void UndockWindow(const char* window_name);
|
||||
bool WindowIsUndockedOrStandalone(ImGuiWindow* window);
|
||||
bool DockIdIsUndockedOrStandalone(ImGuiID dock_id);
|
||||
void DockNodeHideTabBar(ImGuiDockNode* node, bool hidden);
|
||||
#endif
|
||||
|
||||
// Performances Measurement (use along with Dear ImGui Perf Tool)
|
||||
void PerfCalcRef();
|
||||
void PerfCapture(const char* category = nullptr, const char* test_name = nullptr, const char* csv_file = nullptr);
|
||||
|
||||
// Obsolete functions
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Obsoleted 2025/01/20
|
||||
bool ItemSelectAndReadValue(ImGuiTestRef ref, ImGuiDataType data_type, void* out_data, ImGuiTestOpFlags flags = ImGuiTestOpFlags_None) { return ItemReadAsScalar(ref, data_type, out_data, flags); }
|
||||
void ItemSelectAndReadValue(ImGuiTestRef ref, int* out_v) { int v = ItemReadAsInt(ref); *out_v = v; }
|
||||
void ItemSelectAndReadValue(ImGuiTestRef ref, float* out_v) { float v = ItemReadAsFloat(ref); *out_v = v; }
|
||||
// Obsoleted 2024/05/21
|
||||
void YieldUntil(int frame_count) { while (FrameCount < frame_count) { Yield(); } }
|
||||
// Obsoleted 2022/10/11
|
||||
ImGuiID GetIDByInt(int n); // Prefer using "$$123"
|
||||
ImGuiID GetIDByInt(int n, ImGuiTestRef seed_ref);
|
||||
ImGuiID GetIDByPtr(void* p); // Prefer using "$$(ptr)0xFFFFFFFF"
|
||||
ImGuiID GetIDByPtr(void* p, ImGuiTestRef seed_ref);
|
||||
// Obsoleted 2022/09/26
|
||||
//void KeyModDown(ImGuiModFlags mods) { KeyDown(mods); }
|
||||
//void KeyModUp(ImGuiModFlags mods) { KeyUp(mods); }
|
||||
//void KeyModPress(ImGuiModFlags mods) { KeyPress(mods); }
|
||||
#endif
|
||||
|
||||
// [Internal]
|
||||
void _MakeAimingSpaceOverPos(ImGuiViewport* viewport, ImGuiWindow* over_window, const ImVec2& over_pos); // Move windows covering 'window' at pos.
|
||||
void _ForeignWindowsHideOverPos(const ImVec2& pos, ImGuiWindow** ignore_list); // FIXME: Aim to remove this system...
|
||||
void _ForeignWindowsUnhideAll(); // FIXME: Aim to remove this system...
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Debugging macros (IM_SUSPEND_TESTFUNC)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Debug: Temporarily suspend TestFunc to let user interactively inspect the GUI state (user will need to press the "Continue" button to resume TestFunc execution)
|
||||
#define IM_SUSPEND_TESTFUNC() do { if (ctx->SuspendTestFunc(__FILE__, __LINE__)) return; } while (0)
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Testing/Checking macros: IM_CHECK(), IM_ERRORF() etc.
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Helpers used by IM_CHECK_OP() macros.
|
||||
// ImGuiTestEngine_GetTempStringBuilder() returns a shared instance of ImGuiTextBuffer to recycle memory allocations
|
||||
template<typename T> void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, T v) { buf->append("???"); IM_UNUSED(v); } // FIXME-TESTS: Could improve with some template magic
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, const char* v) { buf->appendf("\"%s\"", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, bool v) { buf->append(v ? "true" : "false"); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImS8 v) { buf->appendf("%d", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImU8 v) { buf->appendf("%u", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImS16 v) { buf->appendf("%hd", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImU16 v) { buf->appendf("%hu", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImS32 v) { buf->appendf("%d", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImU32 v) { buf->appendf("0x%08X", v); } // Assuming ImGuiID
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImS64 v) { buf->appendf("%lld", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImU64 v) { buf->appendf("%llu", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, float v) { buf->appendf("%.3f", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, double v) { buf->appendf("%f", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImVec2 v) { buf->appendf("(%.3f, %.3f)", v.x, v.y); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, const void* v) { buf->appendf("%p", v); }
|
||||
template<> inline void ImGuiTestEngineUtil_appendf_auto(ImGuiTextBuffer* buf, ImGuiWindow* v){ if (v) buf->appendf("\"%s\"", v->Name); else buf->append("nullptr"); }
|
||||
|
||||
// We embed every macro in a do {} while(0) statement as a trick to allow using them as regular single statement, e.g. if (XXX) IM_CHECK(A); else IM_CHECK(B)
|
||||
// We leave the IM_DEBUG_BREAK() outside of the check function to step out faster when using a debugger. It also has the benefit of being lighter than an IM_ASSERT().
|
||||
#define IM_CHECK(_EXPR) do { bool res = (bool)(_EXPR); if (ImGuiTestEngine_Check(__FILE__, __func__, __LINE__, ImGuiTestCheckFlags_None, res, #_EXPR)) { IM_DEBUG_BREAK(); } if (!res) return; } while (0)
|
||||
#define IM_CHECK_NO_RET(_EXPR) do { bool res = (bool)(_EXPR); if (ImGuiTestEngine_Check(__FILE__, __func__, __LINE__, ImGuiTestCheckFlags_None, res, #_EXPR)) { IM_DEBUG_BREAK(); } } while (0)
|
||||
#define IM_CHECK_SILENT(_EXPR) do { bool res = (bool)(_EXPR); if (ImGuiTestEngine_Check(__FILE__, __func__, __LINE__, ImGuiTestCheckFlags_SilentSuccess, res, #_EXPR)) { IM_DEBUG_BREAK(); } if (!res) return; } while (0)
|
||||
#define IM_CHECK_RETV(_EXPR,_RETV) do { bool res = (bool)(_EXPR); if (ImGuiTestEngine_Check(__FILE__, __func__, __LINE__, ImGuiTestCheckFlags_None, res, #_EXPR)) { IM_DEBUG_BREAK(); } if (!res) return _RETV; } while (0)
|
||||
#define IM_CHECK_SILENT_RETV(_EXPR,_RETV) do { bool res = (bool)(_EXPR); if (ImGuiTestEngine_Check(__FILE__, __func__, __LINE__, ImGuiTestCheckFlags_SilentSuccess, res, #_EXPR)) { IM_DEBUG_BREAK(); } if (!res) return _RETV; } while (0)
|
||||
#define IM_ERRORF(_FMT,...) do { if (ImGuiTestEngine_Error(__FILE__, __func__, __LINE__, ImGuiTestCheckFlags_None, _FMT, __VA_ARGS__)) { IM_DEBUG_BREAK(); } } while (0)
|
||||
#define IM_ERRORF_NOHDR(_FMT,...) do { if (ImGuiTestEngine_Error(nullptr, nullptr, 0, ImGuiTestCheckFlags_None, _FMT, __VA_ARGS__)) { IM_DEBUG_BREAK(); } } while (0)
|
||||
|
||||
// Those macros allow us to print out the values of both LHS and RHS expressions involved in a check.
|
||||
#define IM_CHECK_OP(_LHS, _RHS, _OP, _RETURN) \
|
||||
do \
|
||||
{ \
|
||||
auto __lhs = _LHS; /* Cache to avoid side effects */ \
|
||||
auto __rhs = _RHS; \
|
||||
bool __res = __lhs _OP __rhs; \
|
||||
ImGuiTextBuffer* expr_buf = ImGuiTestEngine_GetTempStringBuilder(); \
|
||||
expr_buf->append(#_LHS " ["); \
|
||||
ImGuiTestEngineUtil_appendf_auto(expr_buf, __lhs); \
|
||||
expr_buf->append("] " #_OP " " #_RHS " ["); \
|
||||
ImGuiTestEngineUtil_appendf_auto(expr_buf, __rhs); \
|
||||
expr_buf->append("]"); \
|
||||
if (ImGuiTestEngine_Check(__FILE__, __func__, __LINE__, ImGuiTestCheckFlags_None, __res, expr_buf->c_str())) \
|
||||
IM_ASSERT(__res); \
|
||||
if (_RETURN && !__res) \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
#define IM_CHECK_STR_OP(_LHS, _RHS, _OP, _RETURN, _FLAGS) \
|
||||
do \
|
||||
{ \
|
||||
bool __res; \
|
||||
if (ImGuiTestEngine_CheckStrOp(__FILE__, __func__, __LINE__, _FLAGS, #_OP, #_LHS, _LHS, #_RHS, _RHS, &__res)) \
|
||||
IM_ASSERT(__res); \
|
||||
if (_RETURN && !__res) \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
// Scalar compares
|
||||
#define IM_CHECK_EQ(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, ==, true) // Equal
|
||||
#define IM_CHECK_NE(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, !=, true) // Not Equal
|
||||
#define IM_CHECK_LT(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, < , true) // Less Than
|
||||
#define IM_CHECK_LE(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, <=, true) // Less or Equal
|
||||
#define IM_CHECK_GT(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, > , true) // Greater Than
|
||||
#define IM_CHECK_GE(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, >=, true) // Greater or Equal
|
||||
|
||||
// Scalar compares, without return on failure
|
||||
#define IM_CHECK_EQ_NO_RET(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, ==, false) // Equal
|
||||
#define IM_CHECK_NE_NO_RET(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, !=, false) // Not Equal
|
||||
#define IM_CHECK_LT_NO_RET(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, < , false) // Less Than
|
||||
#define IM_CHECK_LE_NO_RET(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, <=, false) // Less or Equal
|
||||
#define IM_CHECK_GT_NO_RET(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, > , false) // Greater Than
|
||||
#define IM_CHECK_GE_NO_RET(_LHS, _RHS) IM_CHECK_OP(_LHS, _RHS, >=, false) // Greater or Equal
|
||||
|
||||
// String compares
|
||||
#define IM_CHECK_STR_EQ(_LHS, _RHS) IM_CHECK_STR_OP(_LHS, _RHS, ==, true, ImGuiTestCheckFlags_None)
|
||||
#define IM_CHECK_STR_NE(_LHS, _RHS) IM_CHECK_STR_OP(_LHS, _RHS, !=, true, ImGuiTestCheckFlags_None)
|
||||
#define IM_CHECK_STR_EQ_NO_RET(_LHS, _RHS) IM_CHECK_STR_OP(_LHS, _RHS, ==, false, ImGuiTestCheckFlags_None)
|
||||
#define IM_CHECK_STR_NE_NO_RET(_LHS, _RHS) IM_CHECK_STR_OP(_LHS, _RHS, !=, false, ImGuiTestCheckFlags_None)
|
||||
#define IM_CHECK_STR_EQ_SILENT(_LHS, _RHS) IM_CHECK_STR_OP(_LHS, _RHS, ==, true, ImGuiTestCheckFlags_SilentSuccess)
|
||||
|
||||
// Floating point compares
|
||||
#define IM_CHECK_FLOAT_EQ_EPS(_LHS, _RHS) IM_CHECK_LE(ImFabs(_LHS - (_RHS)), FLT_EPSILON) // Float Equal
|
||||
#define IM_CHECK_FLOAT_NE_EPS(_LHS, _RHS) IM_CHECK_GT(ImFabs(_LHS - (_RHS)), FLT_EPSILON) // Float Not Equal
|
||||
#define IM_CHECK_FLOAT_NEAR(_LHS, _RHS, _EPS) IM_CHECK_LE(ImFabs(_LHS - (_RHS)), _EPS)
|
||||
#define IM_CHECK_FLOAT_NEAR_NO_RET(_LHS, _RHS, _E) IM_CHECK_LE_NO_RET(ImFabs(_LHS - (_RHS)), _E)
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
59
lib/third_party/imgui/imgui_test_engine/include/imgui_te_coroutine.h
vendored
Normal file
59
lib/third_party/imgui/imgui_test_engine/include/imgui_te_coroutine.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// dear imgui test engine
|
||||
// (coroutine interface + optional implementation)
|
||||
// Read https://github.com/ocornut/imgui_test_engine/wiki/Setting-Up
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef IMGUI_VERSION
|
||||
#include "imgui.h"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Coroutine abstraction
|
||||
//------------------------------------------------------------------------
|
||||
// Coroutines should be used like this:
|
||||
// ImGuiTestCoroutineHandle handle = CoroutineCreate(<func>, <name>, <ctx>); // name being for debugging, and ctx being an arbitrary user context pointer
|
||||
// while (CoroutineRun(handle)) { <do other stuff };
|
||||
// CoroutineDestroy(handle);
|
||||
// The coroutine code itself should call CoroutineYieldFunc() whenever it wants to yield control back to the main thread.
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// An arbitrary handle used internally to represent coroutines (nullptr indicates no handle)
|
||||
typedef void* ImGuiTestCoroutineHandle;
|
||||
|
||||
// A coroutine main function
|
||||
typedef void (ImGuiTestCoroutineMainFunc)(void* data);
|
||||
|
||||
// Coroutine support interface
|
||||
// Your app needs to return and implement this.
|
||||
// You can '#define IMGUI_TEST_ENGINE_ENABLE_COROUTINE_STDTHREAD_IMPL 1' in your imconfig file to use a default implementation using std::thread
|
||||
// Documentation: https://github.com/ocornut/imgui_test_engine/wiki/Setting-Up
|
||||
struct IMGUI_API ImGuiTestCoroutineInterface
|
||||
{
|
||||
// Create a new coroutine
|
||||
ImGuiTestCoroutineHandle (*CreateFunc)(ImGuiTestCoroutineMainFunc* func, const char* name, void* data);
|
||||
|
||||
// Destroy a coroutine (which must have completed first)
|
||||
void (*DestroyFunc)(ImGuiTestCoroutineHandle handle);
|
||||
|
||||
// Run a coroutine until it yields or finishes, returning false if finished
|
||||
bool (*RunFunc)(ImGuiTestCoroutineHandle handle);
|
||||
|
||||
// Yield from a coroutine back to the caller, preserving coroutine state
|
||||
void (*YieldFunc)();
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Coroutine implementation using std::thread
|
||||
// The "coroutine" thread and user's main thread will always block on each other (both threads will NEVER run in parallel)
|
||||
// It is just an implementation convenience that we provide an implementation using std::thread as it is widely available/standard.
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#if IMGUI_TEST_ENGINE_ENABLE_COROUTINE_STDTHREAD_IMPL
|
||||
|
||||
IMGUI_API ImGuiTestCoroutineInterface* Coroutine_ImplStdThread_GetInterface();
|
||||
|
||||
#endif // #if IMGUI_TEST_ENGINE_ENABLE_COROUTINE_STDTHREAD_IMPL
|
||||
475
lib/third_party/imgui/imgui_test_engine/include/imgui_te_engine.h
vendored
Normal file
475
lib/third_party/imgui/imgui_test_engine/include/imgui_te_engine.h
vendored
Normal file
@@ -0,0 +1,475 @@
|
||||
// dear imgui test engine
|
||||
// (core)
|
||||
// This is the interface that your initial setup (app init, main loop) will mostly be using.
|
||||
// Actual tests will mostly use the interface of imgui_te_context.h
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h" // ImPool<>, ImRect, ImGuiItemStatusFlags, ImFormatString
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#endif
|
||||
#ifdef Status // X11 headers
|
||||
#undef Status
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function Pointers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if IMGUI_TEST_ENGINE_ENABLE_STD_FUNCTION
|
||||
#include <functional>
|
||||
#define ImFuncPtr(FUNC_TYPE) std::function<FUNC_TYPE>
|
||||
#else
|
||||
#define ImFuncPtr(FUNC_TYPE) FUNC_TYPE*
|
||||
#endif
|
||||
|
||||
#include "imgui_capture_tool.h" // ImGuiScreenCaptureFunc
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Forward Declarations
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiTest; // Data for a test registered with IM_REGISTER_TEST()
|
||||
struct ImGuiTestContext; // Context while a test is running
|
||||
struct ImGuiTestCoroutineInterface; // Interface to expose coroutine functions (imgui_te_coroutine provides a default implementation for C++11 using std::thread, but you may use your own)
|
||||
struct ImGuiTestEngine; // Test engine instance
|
||||
struct ImGuiTestEngineIO; // Test engine public I/O
|
||||
struct ImGuiTestEngineResultSummary;// Output of ImGuiTestEngine_GetResultSummary()
|
||||
struct ImGuiTestItemInfo; // Info queried from item (id, geometry, status flags, debug label)
|
||||
struct ImGuiTestItemList; // A list of items
|
||||
struct ImGuiTestInputs; // Simulated user inputs (will be fed into ImGuiIO by the test engine)
|
||||
struct ImGuiTestRunTask; // A queued test (test + runflags)
|
||||
|
||||
typedef int ImGuiTestFlags; // Flags: See ImGuiTestFlags_
|
||||
typedef int ImGuiTestCheckFlags; // Flags: See ImGuiTestCheckFlags_
|
||||
typedef int ImGuiTestLogFlags; // Flags: See ImGuiTestLogFlags_
|
||||
typedef int ImGuiTestRunFlags; // Flags: See ImGuiTestRunFlags_
|
||||
|
||||
enum ImGuiTestActiveFunc : int;
|
||||
enum ImGuiTestGroup : int;
|
||||
enum ImGuiTestRunSpeed : int;
|
||||
enum ImGuiTestStatus : int;
|
||||
enum ImGuiTestVerboseLevel : int;
|
||||
enum ImGuiTestEngineExportFormat : int;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Types
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Stored in ImGuiTestContext: where we are currently running GuiFunc or TestFunc
|
||||
enum ImGuiTestActiveFunc : int
|
||||
{
|
||||
ImGuiTestActiveFunc_None,
|
||||
ImGuiTestActiveFunc_GuiFunc,
|
||||
ImGuiTestActiveFunc_TestFunc
|
||||
};
|
||||
|
||||
enum ImGuiTestRunSpeed : int
|
||||
{
|
||||
ImGuiTestRunSpeed_Fast = 0, // Run tests as fast as possible (teleport mouse, skip delays, etc.)
|
||||
ImGuiTestRunSpeed_Normal = 1, // Run tests at human watchable speed (for debugging)
|
||||
ImGuiTestRunSpeed_Cinematic = 2, // Run tests with pauses between actions (for e.g. tutorials)
|
||||
ImGuiTestRunSpeed_COUNT
|
||||
};
|
||||
|
||||
enum ImGuiTestVerboseLevel : int
|
||||
{
|
||||
ImGuiTestVerboseLevel_Silent = 0, // -v0
|
||||
ImGuiTestVerboseLevel_Error = 1, // -v1
|
||||
ImGuiTestVerboseLevel_Warning = 2, // -v2
|
||||
ImGuiTestVerboseLevel_Info = 3, // -v3
|
||||
ImGuiTestVerboseLevel_Debug = 4, // -v4
|
||||
ImGuiTestVerboseLevel_Trace = 5,
|
||||
ImGuiTestVerboseLevel_COUNT
|
||||
};
|
||||
|
||||
// Test status (stored in ImGuiTest)
|
||||
enum ImGuiTestStatus : int
|
||||
{
|
||||
ImGuiTestStatus_Unknown = 0,
|
||||
ImGuiTestStatus_Success = 1,
|
||||
ImGuiTestStatus_Queued = 2,
|
||||
ImGuiTestStatus_Running = 3,
|
||||
ImGuiTestStatus_Error = 4,
|
||||
ImGuiTestStatus_Suspended = 5,
|
||||
ImGuiTestStatus_COUNT
|
||||
};
|
||||
|
||||
// Test group: this is mostly used to categorize tests in our testing UI. (Stored in ImGuiTest)
|
||||
enum ImGuiTestGroup : int
|
||||
{
|
||||
ImGuiTestGroup_Unknown = -1,
|
||||
ImGuiTestGroup_Tests = 0,
|
||||
ImGuiTestGroup_Perfs = 1,
|
||||
ImGuiTestGroup_COUNT
|
||||
};
|
||||
|
||||
// Flags (stored in ImGuiTest)
|
||||
enum ImGuiTestFlags_
|
||||
{
|
||||
ImGuiTestFlags_None = 0,
|
||||
ImGuiTestFlags_NoGuiWarmUp = 1 << 0, // Disable running the GUI func for 2 frames before starting test code. For tests which absolutely need to start before GuiFunc.
|
||||
ImGuiTestFlags_NoAutoFinish = 1 << 1, // By default, tests with no TestFunc (only a GuiFunc) will end after warmup. Setting this require test to call ctx->Finish().
|
||||
ImGuiTestFlags_NoRecoveryWarnings = 1 << 2 // Error/recovery warnings (missing End/Pop calls etc.) will be displayed as normal debug entries, for tests which may rely on those.
|
||||
//ImGuiTestFlags_RequireViewports = 1 << 10
|
||||
};
|
||||
|
||||
// Flags for IM_CHECK* macros.
|
||||
enum ImGuiTestCheckFlags_
|
||||
{
|
||||
ImGuiTestCheckFlags_None = 0,
|
||||
ImGuiTestCheckFlags_SilentSuccess = 1 << 0
|
||||
};
|
||||
|
||||
// Flags for ImGuiTestContext::Log* functions.
|
||||
enum ImGuiTestLogFlags_
|
||||
{
|
||||
ImGuiTestLogFlags_None = 0,
|
||||
ImGuiTestLogFlags_NoHeader = 1 << 0 // Do not display frame count and depth padding
|
||||
};
|
||||
|
||||
enum ImGuiTestRunFlags_
|
||||
{
|
||||
ImGuiTestRunFlags_None = 0,
|
||||
ImGuiTestRunFlags_GuiFuncDisable = 1 << 0, // Used internally to temporarily disable the GUI func (at the end of a test, etc)
|
||||
ImGuiTestRunFlags_GuiFuncOnly = 1 << 1, // Set when user selects "Run GUI func"
|
||||
ImGuiTestRunFlags_NoSuccessMsg = 1 << 2,
|
||||
ImGuiTestRunFlags_EnableRawInputs = 1 << 3, // Disable input submission to let test submission raw input event (in order to test e.g. IO queue)
|
||||
ImGuiTestRunFlags_RunFromGui = 1 << 4, // Test ran manually from GUI, will disable watchdog.
|
||||
ImGuiTestRunFlags_RunFromCommandLine= 1 << 5, // Test queued from command-line.
|
||||
|
||||
// Flags for ImGuiTestContext::RunChildTest()
|
||||
ImGuiTestRunFlags_NoError = 1 << 10,
|
||||
ImGuiTestRunFlags_ShareVars = 1 << 11, // Share generic vars and custom vars between child and parent tests (custom vars need to be same type)
|
||||
ImGuiTestRunFlags_ShareTestContext = 1 << 12, // Share ImGuiTestContext instead of creating a new one (unsure what purpose this may be useful for yet)
|
||||
// TODO: Add GuiFunc options
|
||||
};
|
||||
|
||||
struct ImGuiTestEngineResultSummary
|
||||
{
|
||||
int CountTested = 0; // Number of tests executed
|
||||
int CountSuccess = 0; // Number of tests succeeded
|
||||
int CountInQueue = 0; // Number of tests remaining in queue (e.g. aborted, crashed)
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Hooks for core imgui/ library (generally called via macros)
|
||||
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ui_ctx, ImGuiID id, const ImRect& bb, const ImGuiLastItemData* item_data);
|
||||
#if IMGUI_VERSION_NUM < 18934
|
||||
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ui_ctx, const ImRect& bb, ImGuiID id);
|
||||
#endif
|
||||
#ifdef IMGUI_HAS_IMSTR
|
||||
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ui_ctx, ImGuiID id, ImStrv label, ImGuiItemStatusFlags flags);
|
||||
#else
|
||||
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ui_ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags);
|
||||
#endif
|
||||
extern void ImGuiTestEngineHook_Log(ImGuiContext* ui_ctx, const char* fmt, ...);
|
||||
extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ui_ctx, ImGuiID id);
|
||||
|
||||
// Functions (generally called via IM_CHECK() macros)
|
||||
IMGUI_API bool ImGuiTestEngine_Check(const char* file, const char* func, int line, ImGuiTestCheckFlags flags, bool result, const char* expr);
|
||||
IMGUI_API bool ImGuiTestEngine_CheckStrOp(const char* file, const char* func, int line, ImGuiTestCheckFlags flags, const char* op, const char* lhs_var, const char* lhs_value, const char* rhs_var, const char* rhs_value, bool* out_result);
|
||||
IMGUI_API bool ImGuiTestEngine_Error(const char* file, const char* func, int line, ImGuiTestCheckFlags flags, const char* fmt, ...);
|
||||
IMGUI_API void ImGuiTestEngine_AssertLog(const char* expr, const char* file, const char* function, int line);
|
||||
IMGUI_API ImGuiTextBuffer* ImGuiTestEngine_GetTempStringBuilder();
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ImGuiTestEngine API
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Functions: Initialization
|
||||
IMGUI_API ImGuiTestEngine* ImGuiTestEngine_CreateContext(); // Create test engine
|
||||
IMGUI_API void ImGuiTestEngine_DestroyContext(ImGuiTestEngine* engine); // Destroy test engine. Call after ImGui::DestroyContext() so test engine specific ini data gets saved.
|
||||
IMGUI_API void ImGuiTestEngine_Start(ImGuiTestEngine* engine, ImGuiContext* ui_ctx); // Bind to a dear imgui context. Start coroutine.
|
||||
IMGUI_API void ImGuiTestEngine_Stop(ImGuiTestEngine* engine); // Stop coroutine and export if any. (Unbind will lazily happen on context shutdown)
|
||||
IMGUI_API void ImGuiTestEngine_PostSwap(ImGuiTestEngine* engine); // Call every frame after framebuffer swap, will process screen capture and call test_io.ScreenCaptureFunc()
|
||||
IMGUI_API ImGuiTestEngineIO& ImGuiTestEngine_GetIO(ImGuiTestEngine* engine);
|
||||
|
||||
// Macros: Register Test
|
||||
#define IM_REGISTER_TEST(_ENGINE, _CATEGORY, _NAME) ImGuiTestEngine_RegisterTest(_ENGINE, _CATEGORY, _NAME, __FILE__, __LINE__)
|
||||
IMGUI_API ImGuiTest* ImGuiTestEngine_RegisterTest(ImGuiTestEngine* engine, const char* category, const char* name, const char* src_file = nullptr, int src_line = 0); // Prefer calling IM_REGISTER_TEST()
|
||||
IMGUI_API void ImGuiTestEngine_UnregisterTest(ImGuiTestEngine* engine, ImGuiTest* test);
|
||||
IMGUI_API void ImGuiTestEngine_UnregisterAllTests(ImGuiTestEngine* engine);
|
||||
|
||||
// Functions: Main
|
||||
IMGUI_API void ImGuiTestEngine_QueueTest(ImGuiTestEngine* engine, ImGuiTest* test, ImGuiTestRunFlags run_flags = 0);
|
||||
IMGUI_API void ImGuiTestEngine_QueueTests(ImGuiTestEngine* engine, ImGuiTestGroup group, const char* filter = nullptr, ImGuiTestRunFlags run_flags = 0);
|
||||
IMGUI_API bool ImGuiTestEngine_TryAbortEngine(ImGuiTestEngine* engine);
|
||||
IMGUI_API void ImGuiTestEngine_AbortCurrentTest(ImGuiTestEngine* engine);
|
||||
IMGUI_API ImGuiTest* ImGuiTestEngine_FindTestByName(ImGuiTestEngine* engine, const char* category, const char* name);
|
||||
|
||||
// Functions: Status Queries
|
||||
// FIXME: Clarify API to avoid function calls vs raw bools in ImGuiTestEngineIO
|
||||
IMGUI_API bool ImGuiTestEngine_IsTestQueueEmpty(ImGuiTestEngine* engine);
|
||||
IMGUI_API bool ImGuiTestEngine_IsUsingSimulatedInputs(ImGuiTestEngine* engine);
|
||||
IMGUI_API void ImGuiTestEngine_GetResultSummary(ImGuiTestEngine* engine, ImGuiTestEngineResultSummary* out_results);
|
||||
IMGUI_API void ImGuiTestEngine_GetTestList(ImGuiTestEngine* engine, ImVector<ImGuiTest*>* out_tests);
|
||||
IMGUI_API void ImGuiTestEngine_GetTestQueue(ImGuiTestEngine* engine, ImVector<ImGuiTestRunTask>* out_tests);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Obsoleted 2025/03/17
|
||||
static inline void ImGuiTestEngine_GetResult(ImGuiTestEngine* engine, int& out_count_tested, int& out_count_success) { ImGuiTestEngineResultSummary summary; ImGuiTestEngine_GetResultSummary(engine, &summary); out_count_tested = summary.CountTested; out_count_success = summary.CountSuccess; }
|
||||
#endif
|
||||
|
||||
// Functions: Crash Handling
|
||||
// Ensure past test results are properly exported even if application crash during a test.
|
||||
IMGUI_API void ImGuiTestEngine_InstallDefaultCrashHandler(); // Install default crash handler (if you don't have one)
|
||||
IMGUI_API void ImGuiTestEngine_CrashHandler(); // Default crash handler, should be called from a custom crash handler if such exists
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IO structure to configure the test engine
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Function bound to right-clicking on a test and selecting "Open source" in the UI
|
||||
// - Easy: you can make this function call OS shell to "open" the file (e.g. ImOsOpenInShell() helper).
|
||||
// - Better: bind this function to a custom setup which can pass line number to a text editor (e.g. see 'imgui_test_suite/tools/win32_open_with_sublime.cmd' example)
|
||||
typedef void (ImGuiTestEngineSrcFileOpenFunc)(const char* filename, int line_no, void* user_data);
|
||||
|
||||
struct IMGUI_API ImGuiTestEngineIO
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Options: Functions
|
||||
ImGuiTestCoroutineInterface* CoroutineFuncs = nullptr; // (Required) Coroutine functions (see imgui_te_coroutines.h)
|
||||
ImFuncPtr(ImGuiTestEngineSrcFileOpenFunc) SrcFileOpenFunc = nullptr; // (Optional) To open source files from test engine UI (otherwise default to open file in shell)
|
||||
ImFuncPtr(ImGuiScreenCaptureFunc) ScreenCaptureFunc = nullptr; // (Optional) To capture graphics output (application _MUST_ call ImGuiTestEngine_PostSwap() function after swapping is framebuffer)
|
||||
void* SrcFileOpenUserData = nullptr; // (Optional) User data for SrcFileOpenFunc
|
||||
void* ScreenCaptureUserData = nullptr; // (Optional) User data for ScreenCaptureFunc
|
||||
|
||||
// Options: Main
|
||||
bool ConfigSavedSettings = true; // Load/Save settings in main context .ini file.
|
||||
ImGuiTestRunSpeed ConfigRunSpeed = ImGuiTestRunSpeed_Fast; // Run tests in fast/normal/cinematic mode
|
||||
bool ConfigStopOnError = false; // Stop queued tests on test error
|
||||
bool ConfigBreakOnError = false; // Break debugger on test error by calling IM_DEBUG_BREAK()
|
||||
bool ConfigKeepGuiFunc = false; // Keep test GUI running at the end of the test
|
||||
ImGuiTestVerboseLevel ConfigVerboseLevel = ImGuiTestVerboseLevel_Warning;
|
||||
ImGuiTestVerboseLevel ConfigVerboseLevelOnError = ImGuiTestVerboseLevel_Info;
|
||||
bool ConfigLogToTTY = false;
|
||||
bool ConfigLogToDebugger = false;
|
||||
bool ConfigRestoreFocusAfterTests = true;// Restore focus back after running tests
|
||||
bool ConfigCaptureEnabled = true; // Master enable flags for capturing and saving captures. Disable to avoid e.g. lengthy saving of large PNG files.
|
||||
bool ConfigCaptureOnError = false;
|
||||
bool ConfigNoThrottle = false; // Disable vsync for performance measurement or fast test running
|
||||
bool ConfigMouseDrawCursor = true; // Enable drawing of Dear ImGui software mouse cursor when running tests
|
||||
float ConfigFixedDeltaTime = 0.0f; // Use fixed delta time instead of calculating it from wall clock
|
||||
int PerfStressAmount = 1; // Integer to scale the amount of items submitted in test
|
||||
char GitBranchName[64] = ""; // e.g. fill in branch name (e.g. recorded in perf samples .csv)
|
||||
|
||||
// Options: Speed of user simulation
|
||||
float MouseSpeed = 600.0f; // Mouse speed (pixel/second) when not running in fast mode
|
||||
float MouseWobble = 0.25f; // (0.0f..1.0f) How much wobble to apply to the mouse (pixels per pixel of move distance) when not running in fast mode
|
||||
float ScrollSpeed = 1400.0f; // Scroll speed (pixel/second) when not running in fast mode
|
||||
float TypingSpeed = 20.0f; // Char input speed (characters/second) when not running in fast mode
|
||||
float ActionDelayShort = 0.15f; // Time between short actions
|
||||
float ActionDelayStandard = 0.40f; // Time between most actions
|
||||
|
||||
// Options: Screen/video capture
|
||||
char VideoCaptureEncoderPath[256] = ""; // Video encoder executable path, e.g. "path/to/ffmpeg.exe".
|
||||
char VideoCaptureEncoderParams[256] = "";// Video encoder parameters for .MP4 captures, e.g. see IMGUI_CAPTURE_DEFAULT_VIDEO_PARAMS_FOR_FFMPEG
|
||||
char GifCaptureEncoderParams[512] = ""; // Video encoder parameters for .GIF captures, e.g. see IMGUI_CAPTURE_DEFAULT_GIF_PARAMS_FOR_FFMPEG
|
||||
char VideoCaptureExtension[8] = ".mp4"; // Video file extension (default, may be overridden by test).
|
||||
|
||||
// Options: Watchdog. Set values to FLT_MAX to disable.
|
||||
// Interactive GUI applications that may be slower tend to use higher values.
|
||||
float ConfigWatchdogWarning = 30.0f; // Warn when a test exceed this time (in second)
|
||||
float ConfigWatchdogKillTest = 60.0f; // Attempt to stop running a test when exceeding this time (in second)
|
||||
float ConfigWatchdogKillApp = FLT_MAX; // Stop application when exceeding this time (in second)
|
||||
|
||||
// Options: Export
|
||||
// While you can manually call ImGuiTestEngine_Export(), registering filename/format here ensure the crash handler will always export if application crash.
|
||||
const char* ExportResultsFilename = nullptr;
|
||||
ImGuiTestEngineExportFormat ExportResultsFormat = (ImGuiTestEngineExportFormat)0;
|
||||
|
||||
// Options: Sanity Checks
|
||||
bool CheckDrawDataIntegrity = false; // Check ImDrawData integrity (buffer count, etc.). Currently cheap but may become a slow operation.
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Output
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Output: State of test engine
|
||||
bool IsRunningTests = false;
|
||||
bool IsRequestingMaxAppSpeed = false; // When running in fast mode: request app to skip vsync or even skip rendering if it wants
|
||||
bool IsCapturing = false; // Capture is in progress
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ImGuiTestItemInfo
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Information about a given item or window, result of an ItemInfo() or WindowInfo() query
|
||||
struct ImGuiTestItemInfo
|
||||
{
|
||||
ImGuiID ID = 0; // Item ID
|
||||
char DebugLabel[32] = {}; // Shortened/truncated label for debugging and convenience purpose
|
||||
ImGuiWindow* Window = nullptr; // Item Window
|
||||
unsigned int NavLayer : 1; // Nav layer of the item (ImGuiNavLayer)
|
||||
int Depth : 16; // Depth from requested parent id. 0 == ID is immediate child of requested parent id.
|
||||
int TimestampMain; // Timestamp of main result (all fields)
|
||||
int TimestampStatus; // Timestamp of StatusFlags
|
||||
ImGuiID ParentID = 0; // Item Parent ID (value at top of the ID stack)
|
||||
ImRect RectFull = ImRect(); // Item Rectangle
|
||||
ImRect RectClipped = ImRect(); // Item Rectangle (clipped with window->ClipRect at time of item submission)
|
||||
ImGuiItemFlags ItemFlags = 0; // Item flags
|
||||
//ImGuiItemFlags InFlags = 0; // Item flags (OBSOLETE: before 2024/10/17 ItemFlags was called InFlags)
|
||||
ImGuiItemStatusFlags StatusFlags = 0; // Item Status flags (fully updated for some items only, compare TimestampStatus to FrameCount)
|
||||
|
||||
ImGuiTestItemInfo() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Result of an GatherItems() query
|
||||
struct IMGUI_API ImGuiTestItemList
|
||||
{
|
||||
ImPool<ImGuiTestItemInfo> Pool;
|
||||
|
||||
void Clear() { Pool.Clear(); }
|
||||
void Reserve(int capacity) { Pool.Reserve(capacity); }
|
||||
int GetSize() const { return Pool.GetMapSize(); }
|
||||
const ImGuiTestItemInfo* GetByIndex(int n) { return Pool.GetByIndex(n); }
|
||||
const ImGuiTestItemInfo* GetByID(ImGuiID id) { return Pool.GetByKey(id); }
|
||||
|
||||
// For range-for
|
||||
size_t size() const { return (size_t)Pool.GetMapSize(); }
|
||||
const ImGuiTestItemInfo* begin() const { return Pool.Buf.begin(); }
|
||||
const ImGuiTestItemInfo* end() const { return Pool.Buf.end(); }
|
||||
const ImGuiTestItemInfo* operator[] (size_t n) { return &Pool.Buf[(int)n]; }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ImGuiTestLog: store textual output of one given Test.
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct IMGUI_API ImGuiTestLogLineInfo
|
||||
{
|
||||
ImGuiTestVerboseLevel Level;
|
||||
int LineOffset;
|
||||
};
|
||||
|
||||
struct IMGUI_API ImGuiTestLog
|
||||
{
|
||||
ImGuiTextBuffer Buffer;
|
||||
ImVector<ImGuiTestLogLineInfo> LineInfo;
|
||||
int CountPerLevel[ImGuiTestVerboseLevel_COUNT] = {};
|
||||
|
||||
// Functions
|
||||
ImGuiTestLog() {}
|
||||
bool IsEmpty() const { return Buffer.empty(); }
|
||||
void Clear();
|
||||
|
||||
// Extract log contents filtered per log-level.
|
||||
// Output:
|
||||
// - If 'buffer != nullptr': all extracted lines are appended to 'buffer'. Use 'buffer->c_str()' on your side to obtain the text.
|
||||
// - Return value: number of lines extracted (should be equivalent to number of '\n' inside buffer->c_str()).
|
||||
// - You may call the function with buffer == nullptr to only obtain a count without getting the data.
|
||||
// Verbose levels are inclusive:
|
||||
// - To get ONLY Error: Use level_min == ImGuiTestVerboseLevel_Error, level_max = ImGuiTestVerboseLevel_Error
|
||||
// - To get ONLY Error and Warnings: Use level_min == ImGuiTestVerboseLevel_Error, level_max = ImGuiTestVerboseLevel_Warning
|
||||
// - To get All Errors, Warnings, Debug... Use level_min == ImGuiTestVerboseLevel_Error, level_max = ImGuiTestVerboseLevel_Trace
|
||||
int ExtractLinesForVerboseLevels(ImGuiTestVerboseLevel level_min, ImGuiTestVerboseLevel level_max, ImGuiTextBuffer* out_buffer);
|
||||
|
||||
// [Internal]
|
||||
void UpdateLineOffsets(ImGuiTestEngineIO* engine_io, ImGuiTestVerboseLevel level, const char* start);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ImGuiTest
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
typedef void (ImGuiTestGuiFunc)(ImGuiTestContext* ctx);
|
||||
typedef void (ImGuiTestTestFunc)(ImGuiTestContext* ctx);
|
||||
|
||||
// Wraps a placement new of a given type (where 'buffer' is the allocated memory)
|
||||
typedef void (ImGuiTestVarsConstructor)(void* buffer);
|
||||
typedef void (ImGuiTestVarsPostConstructor)(ImGuiTestContext* ctx, void* ptr, void* fn);
|
||||
typedef void (ImGuiTestVarsDestructor)(void* ptr);
|
||||
|
||||
// Storage for the output of a test run
|
||||
struct IMGUI_API ImGuiTestOutput
|
||||
{
|
||||
ImGuiTestStatus Status = ImGuiTestStatus_Unknown;
|
||||
ImGuiTestLog Log;
|
||||
ImU64 StartTime = 0;
|
||||
ImU64 EndTime = 0;
|
||||
};
|
||||
|
||||
// Storage for one test
|
||||
struct IMGUI_API ImGuiTest
|
||||
{
|
||||
// Test Definition
|
||||
const char* Category = nullptr; // Literal, not owned
|
||||
const char* Name = nullptr; // Literal, generally not owned unless NameOwned=true
|
||||
ImGuiTestGroup Group = ImGuiTestGroup_Unknown; // Coarse groups: 'Tests' or 'Perf'
|
||||
bool NameOwned = false; //
|
||||
int ArgVariant = 0; // User parameter. Generally we use it to run variations of a same test by sharing GuiFunc/TestFunc
|
||||
ImGuiTestFlags Flags = ImGuiTestFlags_None; // See ImGuiTestFlags_
|
||||
ImFuncPtr(ImGuiTestGuiFunc) GuiFunc = nullptr; // GUI function (optional if your test are running over an existing GUI application)
|
||||
ImFuncPtr(ImGuiTestTestFunc) TestFunc = nullptr; // Test function
|
||||
void* UserData = nullptr; // General purpose user data (if assigning capturing lambdas on GuiFunc/TestFunc you may not need to use this)
|
||||
//ImVector<ImGuiTestRunTask> Dependencies; // Registered via AddDependencyTest(), ran automatically before our test. This is a simpler wrapper to calling ctx->RunChildTest()
|
||||
|
||||
// Sources information (exposed in UI)
|
||||
const char* SourceFile = nullptr; // __FILE__
|
||||
int SourceLine = 0; // __LINE__
|
||||
int SourceLineEnd = 0; // end of line (when calculated by ImGuiTestEngine_StartCalcSourceLineEnds())
|
||||
|
||||
// Last Test Output/Status
|
||||
// (this is the only part that may change after registration)
|
||||
ImGuiTestOutput Output;
|
||||
|
||||
// User variables (which are instantiated when running the test)
|
||||
// Setup after test registration with SetVarsDataType<>(), access instance during test with GetVars<>().
|
||||
// This is mostly useful to communicate between GuiFunc and TestFunc. If you don't use both you may not want to use it!
|
||||
size_t VarsSize = 0;
|
||||
ImGuiTestVarsConstructor* VarsConstructor = nullptr;
|
||||
ImGuiTestVarsPostConstructor* VarsPostConstructor = nullptr; // To override constructor default (in case the default are problematic on the first GuiFunc frame)
|
||||
void* VarsPostConstructorUserFn = nullptr;
|
||||
ImGuiTestVarsDestructor* VarsDestructor = nullptr;
|
||||
|
||||
// Functions
|
||||
ImGuiTest() {}
|
||||
~ImGuiTest();
|
||||
|
||||
void SetOwnedName(const char* name);
|
||||
|
||||
template <typename T>
|
||||
void SetVarsDataType(void(*post_initialize)(ImGuiTestContext* ctx, T& vars) = nullptr)
|
||||
{
|
||||
VarsSize = sizeof(T);
|
||||
VarsConstructor = [](void* ptr) { IM_PLACEMENT_NEW(ptr) T; };
|
||||
VarsDestructor = [](void* ptr) { IM_UNUSED(ptr); reinterpret_cast<T*>(ptr)->~T(); };
|
||||
if (post_initialize != nullptr)
|
||||
{
|
||||
VarsPostConstructorUserFn = (void*)post_initialize;
|
||||
VarsPostConstructor = [](ImGuiTestContext* ctx, void* ptr, void* fn) { ((void (*)(ImGuiTestContext*, T&))(fn))(ctx, *(T*)ptr); };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Stored in test queue
|
||||
struct IMGUI_API ImGuiTestRunTask
|
||||
{
|
||||
ImGuiTest* Test = nullptr;
|
||||
ImGuiTestRunFlags RunFlags = ImGuiTestRunFlags_None;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
62
lib/third_party/imgui/imgui_test_engine/include/imgui_te_exporters.h
vendored
Normal file
62
lib/third_party/imgui/imgui_test_engine/include/imgui_te_exporters.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
// dear imgui test engine
|
||||
// (result exporters)
|
||||
// Read https://github.com/ocornut/imgui_test_engine/wiki/Exporting-Results
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
#pragma once
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Description
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// Test results may be exported in one of supported formats.
|
||||
// To enable result exporting please configure test engine as follows:
|
||||
//
|
||||
// ImGuiTestEngineIO& test_io = ImGuiTestEngine_GetIO(engine);
|
||||
// test_io.ExportResultsFile = "output_file.xml";
|
||||
// test_io.ExportResultsFormat = ImGuiTestEngineExportFormat_<...>;
|
||||
//
|
||||
// JUnit XML format
|
||||
//------------------
|
||||
// JUnit XML format described at https://llg.cubic.org/docs/junit/. Many
|
||||
// third party applications support consumption of this format. Some of
|
||||
// of them are listed here:
|
||||
// - Jenkins
|
||||
// - Installation guide: https://www.jenkins.io/doc/book/installing/docker/
|
||||
// - JUnit plugin: https://plugins.jenkins.io/junit/
|
||||
// - xunit-viewer
|
||||
// - Project: https://github.com/lukejpreston/xunit-viewer
|
||||
// - Install npm: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm
|
||||
// - Install viewer and view test results:
|
||||
// npm install xunit-viewer
|
||||
// imgui_test_suite -nopause -v2 -ve4 -nogui -export-file junit.xml tests
|
||||
// node_modules/xunit-viewer/bin/xunit-viewer -r junit.xml -o junit.html
|
||||
// - Open junit.html
|
||||
//
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Forward Declarations
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiTestEngine;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Types
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
enum ImGuiTestEngineExportFormat : int
|
||||
{
|
||||
ImGuiTestEngineExportFormat_None = 0,
|
||||
ImGuiTestEngineExportFormat_JUnitXml,
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void ImGuiTestEngine_PrintResultSummary(ImGuiTestEngine* engine);
|
||||
|
||||
void ImGuiTestEngine_Export(ImGuiTestEngine* engine);
|
||||
void ImGuiTestEngine_ExportEx(ImGuiTestEngine* engine, ImGuiTestEngineExportFormat format, const char* filename);
|
||||
67
lib/third_party/imgui/imgui_test_engine/include/imgui_te_imconfig.h
vendored
Normal file
67
lib/third_party/imgui/imgui_test_engine/include/imgui_te_imconfig.h
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// dear imgui test engine
|
||||
// (template for compile-time configuration)
|
||||
// Replicate or #include this file in your imconfig.h to enable test engine.
|
||||
|
||||
// Compile Dear ImGui with test engine hooks
|
||||
// (Important: This is a value-less define, to be consistent with other defines used in core dear imgui.)
|
||||
#define IMGUI_ENABLE_TEST_ENGINE
|
||||
|
||||
// [Optional, default 0] Enable plotting of perflog data for comparing performance of different runs.
|
||||
// This feature requires ImPlot to be linked in the application.
|
||||
#ifndef IMGUI_TEST_ENGINE_ENABLE_IMPLOT
|
||||
#define IMGUI_TEST_ENGINE_ENABLE_IMPLOT 1
|
||||
#endif
|
||||
|
||||
// [Optional, default 1] Enable screen capture and PNG/GIF saving functionalities
|
||||
// There's not much point to disable this but we provide it to reassure user that the dependencies on imstb_image_write.h and ffmpeg are technically optional.
|
||||
#ifndef IMGUI_TEST_ENGINE_ENABLE_CAPTURE
|
||||
#define IMGUI_TEST_ENGINE_ENABLE_CAPTURE 1
|
||||
#endif
|
||||
|
||||
// [Optional, default 0] Using std::function and <functional> for function pointers such as ImGuiTest::TestFunc and ImGuiTest::GuiFunc
|
||||
#ifndef IMGUI_TEST_ENGINE_ENABLE_STD_FUNCTION
|
||||
#define IMGUI_TEST_ENGINE_ENABLE_STD_FUNCTION 1
|
||||
#endif
|
||||
|
||||
// [Optional, default 0] Automatically fill ImGuiTestEngineIO::CoroutineFuncs with a default implementation using std::thread
|
||||
#ifndef IMGUI_TEST_ENGINE_ENABLE_COROUTINE_STDTHREAD_IMPL
|
||||
#define IMGUI_TEST_ENGINE_ENABLE_COROUTINE_STDTHREAD_IMPL 1
|
||||
#endif
|
||||
|
||||
// [Optional, default 0] Disable calls that do not make sense on game consoles
|
||||
// (Disable: system(), popen(), sigaction(), colored TTY output)
|
||||
#ifndef IMGUI_TEST_ENGINE_IS_GAME_CONSOLE
|
||||
#if defined(__ORBIS__) || defined(__PROSPERO__) || defined(_GAMING_XBOX) || defined(_DURANGO)
|
||||
#define IMGUI_TEST_ENGINE_IS_GAME_CONSOLE 1
|
||||
#else
|
||||
#define IMGUI_TEST_ENGINE_IS_GAME_CONSOLE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Define IM_DEBUG_BREAK macros so it is accessible in imgui.h
|
||||
// (this is a conveniance for app using test engine may define an IM_ASSERT() that uses this instead of an actual assert)
|
||||
// (this is a copy of the block in imgui_internal.h. if the one in imgui_internal.h were to be defined at the top of imgui.h we wouldn't need this)
|
||||
#ifndef IM_DEBUG_BREAK
|
||||
#if defined (_MSC_VER)
|
||||
#define IM_DEBUG_BREAK() __debugbreak()
|
||||
#elif defined(__clang__)
|
||||
#define IM_DEBUG_BREAK() __builtin_debugtrap()
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
#define IM_DEBUG_BREAK() __asm__ volatile("int $0x03")
|
||||
#elif defined(__GNUC__) && defined(__thumb__)
|
||||
#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xde01")
|
||||
#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
|
||||
#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xe7f001f0");
|
||||
#else
|
||||
#define IM_DEBUG_BREAK() IM_ASSERT(0) // It is expected that you define IM_DEBUG_BREAK() into something that will break nicely in a debugger!
|
||||
#endif
|
||||
#endif // #ifndef IMGUI_DEBUG_BREAK
|
||||
|
||||
// [Options] We provide custom assert macro used by our our test suite, which you may use:
|
||||
// - Calling IM_DEBUG_BREAK() instead of an actual assert, so we can easily recover and step over (compared to many assert implementations).
|
||||
// - If a test is running, test name will be included in the log.
|
||||
// - Macro is calling IM_DEBUG_BREAK() inline to get debugger to break in the calling function (instead of a deeper callstack level).
|
||||
// - Macro is using comma operator instead of an if() to avoid "conditional expression is constant" warnings.
|
||||
extern void ImGuiTestEngine_AssertLog(const char* expr, const char* file, const char* func, int line);
|
||||
#define IM_TEST_ENGINE_ASSERT(_EXPR) do { if ((void)0, !(_EXPR)) { ImGuiTestEngine_AssertLog(#_EXPR, __FILE__, __func__, __LINE__); IM_DEBUG_BREAK(); } } while (0)
|
||||
// V_ASSERT_CONTRACT, assertMacro:IM_ASSERT
|
||||
242
lib/third_party/imgui/imgui_test_engine/include/imgui_te_internal.h
vendored
Normal file
242
lib/third_party/imgui/imgui_test_engine/include/imgui_te_internal.h
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
// dear imgui test engine
|
||||
// (internal api)
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui_te_coroutine.h"
|
||||
#include "imgui_te_utils.h" // ImMovingAverage
|
||||
#include "imgui_capture_tool.h" // ImGuiCaptureTool // FIXME
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// FORWARD DECLARATIONS
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class Str; // Str<> from thirdparty/Str/Str.h
|
||||
struct ImGuiPerfTool;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// DATA STRUCTURES
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Query item position/window/state given ID.
|
||||
struct ImGuiTestInfoTask
|
||||
{
|
||||
// Input
|
||||
ImGuiID ID = 0;
|
||||
int FrameCount = -1; // Timestamp of request
|
||||
char DebugName[64] = ""; // Debug string representing the queried ID
|
||||
|
||||
// Output
|
||||
ImGuiTestItemInfo Result;
|
||||
};
|
||||
|
||||
// Gather item list in given parent ID.
|
||||
struct ImGuiTestGatherTask
|
||||
{
|
||||
// Input
|
||||
ImGuiID InParentID = 0;
|
||||
int InMaxDepth = 0;
|
||||
short InLayerMask = 0;
|
||||
|
||||
// Output/Temp
|
||||
ImGuiTestItemList* OutList = nullptr;
|
||||
ImGuiTestItemInfo* LastItemInfo = nullptr;
|
||||
|
||||
void Clear() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Find item ID given a label and a parent id
|
||||
// Usually used by queries with wildcards such as ItemInfo("hello/**/foo/bar")
|
||||
struct ImGuiTestFindByLabelTask
|
||||
{
|
||||
// Input
|
||||
ImGuiID InPrefixId = 0; // A known base ID which appears BEFORE the wildcard ID (for "hello/**/foo/bar" it would be hash of "hello")
|
||||
int InSuffixDepth = 0; // Number of labels in a path, after unknown base ID (for "hello/**/foo/bar" it would be 2)
|
||||
const char* InSuffix = nullptr; // A label string which appears on ID stack after unknown base ID (for "hello/**/foo/bar" it would be "foo/bar")
|
||||
const char* InSuffixLastItem = nullptr; // A last label string (for "hello/**/foo/bar" it would be "bar")
|
||||
ImGuiID InSuffixLastItemHash = 0;
|
||||
ImGuiItemStatusFlags InFilterItemStatusFlags = 0; // Flags required for item to be returned
|
||||
|
||||
// Output
|
||||
ImGuiID OutItemId = 0; // Result item ID
|
||||
};
|
||||
|
||||
enum ImGuiTestInputType
|
||||
{
|
||||
ImGuiTestInputType_None,
|
||||
ImGuiTestInputType_Key,
|
||||
ImGuiTestInputType_Char,
|
||||
ImGuiTestInputType_ViewportFocus,
|
||||
ImGuiTestInputType_ViewportSetPos,
|
||||
ImGuiTestInputType_ViewportSetSize,
|
||||
ImGuiTestInputType_ViewportClose
|
||||
};
|
||||
|
||||
// FIXME: May want to strip further now that core imgui is using its own input queue
|
||||
struct ImGuiTestInput
|
||||
{
|
||||
ImGuiTestInputType Type = ImGuiTestInputType_None;
|
||||
ImGuiKeyChord KeyChord = ImGuiKey_None;
|
||||
ImWchar Char = 0;
|
||||
bool Down = false;
|
||||
ImGuiID ViewportId = 0;
|
||||
ImVec2 ViewportPosSize;
|
||||
|
||||
static ImGuiTestInput ForKeyChord(ImGuiKeyChord key_chord, bool down)
|
||||
{
|
||||
ImGuiTestInput inp;
|
||||
inp.Type = ImGuiTestInputType_Key;
|
||||
inp.KeyChord = key_chord;
|
||||
inp.Down = down;
|
||||
return inp;
|
||||
}
|
||||
|
||||
static ImGuiTestInput ForChar(ImWchar v)
|
||||
{
|
||||
ImGuiTestInput inp;
|
||||
inp.Type = ImGuiTestInputType_Char;
|
||||
inp.Char = v;
|
||||
return inp;
|
||||
}
|
||||
|
||||
static ImGuiTestInput ForViewportFocus(ImGuiID viewport_id)
|
||||
{
|
||||
ImGuiTestInput inp;
|
||||
inp.Type = ImGuiTestInputType_ViewportFocus;
|
||||
inp.ViewportId = viewport_id;
|
||||
return inp;
|
||||
}
|
||||
|
||||
static ImGuiTestInput ForViewportSetPos(ImGuiID viewport_id, const ImVec2& pos)
|
||||
{
|
||||
ImGuiTestInput inp;
|
||||
inp.Type = ImGuiTestInputType_ViewportSetPos;
|
||||
inp.ViewportId = viewport_id;
|
||||
inp.ViewportPosSize = pos;
|
||||
return inp;
|
||||
}
|
||||
|
||||
static ImGuiTestInput ForViewportSetSize(ImGuiID viewport_id, const ImVec2& size)
|
||||
{
|
||||
ImGuiTestInput inp;
|
||||
inp.Type = ImGuiTestInputType_ViewportSetSize;
|
||||
inp.ViewportId = viewport_id;
|
||||
inp.ViewportPosSize = size;
|
||||
return inp;
|
||||
}
|
||||
|
||||
static ImGuiTestInput ForViewportClose(ImGuiID viewport_id)
|
||||
{
|
||||
ImGuiTestInput inp;
|
||||
inp.Type = ImGuiTestInputType_ViewportClose;
|
||||
inp.ViewportId = viewport_id;
|
||||
return inp;
|
||||
}
|
||||
};
|
||||
|
||||
struct ImGuiTestInputs
|
||||
{
|
||||
ImVec2 MousePosValue; // Own non-rounded copy of MousePos in order facilitate simulating mouse movement very slow speed and high-framerate
|
||||
ImVec2 MouseWheel;
|
||||
ImGuiID MouseHoveredViewport = 0;
|
||||
int MouseButtonsValue = 0x00; // FIXME-TESTS: Use simulated_io.MouseDown[] ?
|
||||
ImVector<ImGuiTestInput> Queue;
|
||||
bool HostEscDown = false;
|
||||
float HostEscDownDuration = -1.0f; // Maintain our own DownDuration for host/backend ESC key so we can abort.
|
||||
};
|
||||
|
||||
// [Internal] Test Engine Context
|
||||
struct ImGuiTestEngine
|
||||
{
|
||||
ImGuiTestEngineIO IO;
|
||||
ImGuiContext* UiContextTarget = nullptr; // imgui context for testing
|
||||
ImGuiContext* UiContextActive = nullptr; // imgui context for testing == UiContextTarget or nullptr
|
||||
|
||||
bool Started = false;
|
||||
ImU64 BatchStartTime = 0;
|
||||
ImU64 BatchEndTime = 0;
|
||||
int FrameCount = 0;
|
||||
float OverrideDeltaTime = -1.0f; // Inject custom delta time into imgui context to simulate clock passing faster than wall clock time.
|
||||
ImVector<ImGuiTest*> TestsAll;
|
||||
ImVector<ImGuiTestRunTask> TestsQueue;
|
||||
ImGuiTestContext* TestContext = nullptr; // Running test context
|
||||
bool TestsSourceLinesDirty = false;
|
||||
ImVector<ImGuiTestInfoTask*>InfoTasks;
|
||||
ImGuiTestGatherTask GatherTask;
|
||||
ImGuiTestFindByLabelTask FindByLabelTask;
|
||||
ImGuiTestCoroutineHandle TestQueueCoroutine = nullptr; // Coroutine to run the test queue
|
||||
bool TestQueueCoroutineShouldExit = false; // Flag to indicate that we are shutting down and the test queue coroutine should stop
|
||||
|
||||
// Inputs
|
||||
ImGuiTestInputs Inputs;
|
||||
|
||||
// UI support
|
||||
bool Abort = false;
|
||||
ImGuiTest* UiSelectAndScrollToTest = nullptr;
|
||||
ImGuiTest* UiSelectedTest = nullptr;
|
||||
Str* UiFilterTests;
|
||||
Str* UiFilterPerfs;
|
||||
ImU32 UiFilterByStatusMask = ~0u;
|
||||
bool UiMetricsOpen = false;
|
||||
bool UiDebugLogOpen = false;
|
||||
bool UiCaptureToolOpen = false;
|
||||
bool UiStackToolOpen = false;
|
||||
bool UiPerfToolOpen = false;
|
||||
float UiLogHeight = 150.0f;
|
||||
|
||||
// Performance Monitor
|
||||
double PerfRefDeltaTime;
|
||||
ImMovingAverage<double> PerfDeltaTime100;
|
||||
ImMovingAverage<double> PerfDeltaTime500;
|
||||
ImGuiPerfTool* PerfTool = nullptr;
|
||||
|
||||
// Screen/Video Capturing
|
||||
ImGuiCaptureToolUI CaptureTool; // Capture tool UI
|
||||
ImGuiCaptureContext CaptureContext; // Capture context used in tests
|
||||
ImGuiCaptureArgs* CaptureCurrentArgs = nullptr;
|
||||
|
||||
// Tools
|
||||
bool PostSwapCalled = false;
|
||||
bool ToolDebugRebootUiContext = false; // Completely shutdown and recreate the dear imgui context in place
|
||||
bool ToolSlowDown = false;
|
||||
int ToolSlowDownMs = 100;
|
||||
ImGuiTestRunSpeed BackupConfigRunSpeed = ImGuiTestRunSpeed_Fast;
|
||||
bool BackupConfigNoThrottle = false;
|
||||
|
||||
// Functions
|
||||
ImGuiTestEngine();
|
||||
~ImGuiTestEngine();
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// INTERNAL FUNCTIONS
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
ImGuiTestItemInfo* ImGuiTestEngine_FindItemInfo(ImGuiTestEngine* engine, ImGuiID id, const char* debug_id);
|
||||
void ImGuiTestEngine_Yield(ImGuiTestEngine* engine);
|
||||
void ImGuiTestEngine_SetDeltaTime(ImGuiTestEngine* engine, float delta_time);
|
||||
int ImGuiTestEngine_GetFrameCount(ImGuiTestEngine* engine);
|
||||
bool ImGuiTestEngine_PassFilter(ImGuiTest* test, const char* filter);
|
||||
void ImGuiTestEngine_RunTest(ImGuiTestEngine* engine, ImGuiTestContext* ctx, ImGuiTest* test, ImGuiTestRunFlags run_flags);
|
||||
|
||||
void ImGuiTestEngine_BindImGuiContext(ImGuiTestEngine* engine, ImGuiContext* ui_ctx);
|
||||
void ImGuiTestEngine_UnbindImGuiContext(ImGuiTestEngine* engine, ImGuiContext* ui_ctx);
|
||||
|
||||
void ImGuiTestEngine_RebootUiContext(ImGuiTestEngine* engine);
|
||||
ImGuiPerfTool* ImGuiTestEngine_GetPerfTool(ImGuiTestEngine* engine);
|
||||
void ImGuiTestEngine_UpdateTestsSourceLines(ImGuiTestEngine* engine);
|
||||
|
||||
// Screen/Video Capturing
|
||||
bool ImGuiTestEngine_CaptureScreenshot(ImGuiTestEngine* engine, ImGuiCaptureArgs* args);
|
||||
bool ImGuiTestEngine_CaptureBeginVideo(ImGuiTestEngine* engine, ImGuiCaptureArgs* args);
|
||||
bool ImGuiTestEngine_CaptureEndVideo(ImGuiTestEngine* engine, ImGuiCaptureArgs* args);
|
||||
|
||||
// Helper functions
|
||||
const char* ImGuiTestEngine_GetStatusName(ImGuiTestStatus v);
|
||||
const char* ImGuiTestEngine_GetRunSpeedName(ImGuiTestRunSpeed v);
|
||||
const char* ImGuiTestEngine_GetVerboseLevelName(ImGuiTestVerboseLevel v);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
134
lib/third_party/imgui/imgui_test_engine/include/imgui_te_perftool.h
vendored
Normal file
134
lib/third_party/imgui/imgui_test_engine/include/imgui_te_perftool.h
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
// dear imgui test engine
|
||||
// (performance tool)
|
||||
// Browse and visualize samples recorded by ctx->PerfCapture() calls.
|
||||
// User access via 'Test Engine UI -> Tools -> Perf Tool'
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
// Forward Declaration
|
||||
struct ImGuiPerfToolColumnInfo;
|
||||
struct ImGuiTestEngine;
|
||||
struct ImGuiCsvParser;
|
||||
|
||||
// Configuration
|
||||
#define IMGUI_PERFLOG_DEFAULT_FILENAME "output/imgui_perflog.csv"
|
||||
|
||||
// [Internal] Perf log entry. Changes to this struct should be reflected in ImGuiTestContext::PerfCapture() and ImGuiTestEngine_Start().
|
||||
// This struct assumes strings stored here will be available until next ImGuiPerfTool::Clear() call. Fortunately we do not have to actively
|
||||
// manage lifetime of these strings. New entries are created only in two cases:
|
||||
// 1. ImGuiTestEngine_PerfToolAppendToCSV() call after perf test has run. This call receives ImGuiPerfToolEntry with const strings stored indefinitely by application.
|
||||
// 2. As a consequence of ImGuiPerfTool::LoadCSV() call, we persist the ImGuiCSVParser instance, which keeps parsed CSV text, from which strings are referenced.
|
||||
// As a result our solution also doesn't make many allocations.
|
||||
struct IMGUI_API ImGuiPerfToolEntry
|
||||
{
|
||||
ImU64 Timestamp = 0; // Title of a particular batch of perftool entries.
|
||||
const char* Category = nullptr; // Name of category perf test is in.
|
||||
const char* TestName = nullptr; // Name of perf test.
|
||||
double DtDeltaMs = 0.0; // Result of perf test.
|
||||
double DtDeltaMsMin = +FLT_MAX; // May be used by perftool.
|
||||
double DtDeltaMsMax = -FLT_MAX; // May be used by perftool.
|
||||
int NumSamples = 1; // Number aggregated samples.
|
||||
int PerfStressAmount = 0; //
|
||||
const char* GitBranchName = nullptr; // Build information.
|
||||
const char* BuildType = nullptr; //
|
||||
const char* Cpu = nullptr; //
|
||||
const char* OS = nullptr; //
|
||||
const char* Compiler = nullptr; //
|
||||
const char* Date = nullptr; // Date of this entry or min date of combined entries.
|
||||
//const char* DateMax = nullptr; // Max date of combined entries, or nullptr.
|
||||
double VsBaseline = 0.0; // Percent difference vs baseline.
|
||||
int LabelIndex = 0; // Index of TestName in ImGuiPerfTool::_LabelsVisible.
|
||||
|
||||
ImGuiPerfToolEntry() { }
|
||||
ImGuiPerfToolEntry(const ImGuiPerfToolEntry& rhs) { Set(rhs); }
|
||||
ImGuiPerfToolEntry& operator=(const ImGuiPerfToolEntry& rhs){ Set(rhs); return *this; }
|
||||
void Set(const ImGuiPerfToolEntry& rhs);
|
||||
};
|
||||
|
||||
// [Internal] Perf log batch.
|
||||
struct ImGuiPerfToolBatch
|
||||
{
|
||||
ImU64 BatchID = 0; // Timestamp of the batch, or unique ID of the build in combined mode.
|
||||
int NumSamples = 0; // A number of unique batches aggregated.
|
||||
int BranchIndex = 0; // For per-branch color mapping.
|
||||
ImVector<ImGuiPerfToolEntry> Entries; // Aggregated perf test entries. Order follows ImGuiPerfTool::_LabelsVisible order.
|
||||
~ImGuiPerfToolBatch() { Entries.clear_destruct(); } // FIXME: Misleading: nothing to destruct in that struct?
|
||||
};
|
||||
|
||||
enum ImGuiPerfToolDisplayType : int
|
||||
{
|
||||
ImGuiPerfToolDisplayType_Simple, // Each run will be displayed individually.
|
||||
ImGuiPerfToolDisplayType_PerBranchColors, // Use one bar color per branch.
|
||||
ImGuiPerfToolDisplayType_CombineByBuildInfo, // Entries with same build information will be averaged.
|
||||
};
|
||||
|
||||
//
|
||||
struct IMGUI_API ImGuiPerfTool
|
||||
{
|
||||
ImVector<ImGuiPerfToolEntry>_SrcData; // Raw entries from CSV file (with string pointer into CSV data).
|
||||
ImVector<const char*> _Labels;
|
||||
ImVector<const char*> _LabelsVisible; // ImPlot requires a pointer of all labels beforehand. Always contains a dummy "" entry at the end!
|
||||
ImVector<ImGuiPerfToolBatch> _Batches;
|
||||
ImGuiStorage _LabelBarCounts; // Number bars each label will render.
|
||||
int _NumVisibleBuilds = 0; // Cached number of visible builds.
|
||||
int _NumUniqueBuilds = 0; // Cached number of unique builds.
|
||||
ImGuiPerfToolDisplayType _DisplayType = ImGuiPerfToolDisplayType_CombineByBuildInfo;
|
||||
int _BaselineBatchIndex = 0; // Index of baseline build.
|
||||
ImU64 _BaselineTimestamp = 0;
|
||||
ImU64 _BaselineBuildId = 0;
|
||||
char _Filter[128]; // Context menu filtering substring.
|
||||
char _FilterDateFrom[11] = {};
|
||||
char _FilterDateTo[11] = {};
|
||||
float _InfoTableHeight = 180.0f;
|
||||
int _AlignStress = 0; // Alignment values for build info components, so they look aligned in the legend.
|
||||
int _AlignType = 0;
|
||||
int _AlignOs = 0;
|
||||
int _AlignCpu = 0;
|
||||
int _AlignCompiler = 0;
|
||||
int _AlignBranch = 0;
|
||||
int _AlignSamples = 0;
|
||||
bool _InfoTableSortDirty = false;
|
||||
ImVector<ImU64> _InfoTableSort; // _InfoTableSort[_LabelsVisible.Size * _Batches.Size]. Contains sorted batch indices for each label.
|
||||
const ImGuiTableSortSpecs* _InfoTableSortSpecs = nullptr; // Current table sort specs.
|
||||
ImGuiStorage _TempSet; // Used as a set
|
||||
int _TableHoveredTest = -1; // Index within _VisibleLabelPointers array.
|
||||
int _TableHoveredBatch = -1;
|
||||
int _PlotHoverTest = -1;
|
||||
int _PlotHoverBatch = -1;
|
||||
bool _PlotHoverTestLabel = false;
|
||||
bool _ReportGenerating = false;
|
||||
ImGuiStorage _Visibility;
|
||||
ImGuiCsvParser* _CsvParser = nullptr; // We keep this around and point to its fields
|
||||
|
||||
ImGuiPerfTool();
|
||||
~ImGuiPerfTool();
|
||||
|
||||
void Clear();
|
||||
bool LoadCSV(const char* filename = nullptr);
|
||||
void AddEntry(ImGuiPerfToolEntry* entry);
|
||||
|
||||
void ShowPerfToolWindow(ImGuiTestEngine* engine, bool* p_open);
|
||||
void ViewOnly(const char* perf_name);
|
||||
void ViewOnly(const char** perf_names);
|
||||
ImGuiPerfToolEntry* GetEntryByBatchIdx(int idx, const char* perf_name = nullptr);
|
||||
bool SaveHtmlReport(const char* file_name, const char* image_file = nullptr);
|
||||
inline bool Empty() { return _SrcData.empty(); }
|
||||
|
||||
void _Rebuild();
|
||||
bool _IsVisibleBuild(ImGuiPerfToolBatch* batch);
|
||||
bool _IsVisibleBuild(ImGuiPerfToolEntry* batch);
|
||||
bool _IsVisibleTest(const char* test_name);
|
||||
void _CalculateLegendAlignment();
|
||||
void _ShowEntriesPlot();
|
||||
void _ShowEntriesTable();
|
||||
void _SetBaseline(int batch_index);
|
||||
void _AddSettingsHandler();
|
||||
void _UnpackSortedKey(ImU64 key, int* batch_index, int* entry_index, int* monotonic_index = nullptr);
|
||||
};
|
||||
|
||||
IMGUI_API void ImGuiTestEngine_PerfToolAppendToCSV(ImGuiPerfTool* perf_log, ImGuiPerfToolEntry* entry, const char* filename = nullptr);
|
||||
25
lib/third_party/imgui/imgui_test_engine/include/imgui_te_ui.h
vendored
Normal file
25
lib/third_party/imgui/imgui_test_engine/include/imgui_te_ui.h
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// dear imgui test engine
|
||||
// (ui)
|
||||
// If you run tests in an interactive or visible application, you may want to call ImGuiTestEngine_ShowTestEngineWindows()
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
// Provide access to:
|
||||
// - "Dear ImGui Test Engine" main interface
|
||||
// - "Dear ImGui Capture Tool"
|
||||
// - "Dear ImGui Perf Tool"
|
||||
// - other core debug functions: Metrics, Debug Log
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef IMGUI_VERSION
|
||||
#include "imgui.h" // IMGUI_API
|
||||
#endif
|
||||
|
||||
// Forward declarations
|
||||
struct ImGuiTestEngine;
|
||||
|
||||
// Functions
|
||||
IMGUI_API void ImGuiTestEngine_ShowTestEngineWindows(ImGuiTestEngine* engine, bool* p_open);
|
||||
IMGUI_API void ImGuiTestEngine_OpenSourceFile(ImGuiTestEngine* engine, const char* source_filename, int source_line_no);
|
||||
213
lib/third_party/imgui/imgui_test_engine/include/imgui_te_utils.h
vendored
Normal file
213
lib/third_party/imgui/imgui_test_engine/include/imgui_te_utils.h
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
// dear imgui test engine
|
||||
// (helpers/utilities. do NOT use this as a general purpose library)
|
||||
|
||||
// This file is governed by the "Dear ImGui Test Engine License".
|
||||
// Details of the license are provided in the LICENSE.txt file in the same directory.
|
||||
|
||||
#pragma once
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Includes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <math.h> // fabsf
|
||||
#include <stdint.h> // uint64_t
|
||||
#include <stdio.h> // FILE*
|
||||
#include "imgui.h" // ImGuiID, ImGuiKey
|
||||
class Str; // Str<> from thirdparty/Str/Str.h
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hashing Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImGuiID ImHashDecoratedPath(const char* str, const char* str_end = nullptr, ImGuiID seed = 0);
|
||||
const char* ImFindNextDecoratedPartInPath(const char* str, const char* str_end = nullptr);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// File/Directory Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool ImFileExist(const char* filename);
|
||||
bool ImFileDelete(const char* filename);
|
||||
bool ImFileCreateDirectoryChain(const char* path, const char* path_end = nullptr);
|
||||
bool ImFileFindInParents(const char* sub_path, int max_parent_count, Str* output);
|
||||
bool ImFileLoadSourceBlurb(const char* filename, int line_no_start, int line_no_end, ImGuiTextBuffer* out_buf);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Path Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Those are strictly string manipulation functions
|
||||
const char* ImPathFindFilename(const char* path, const char* path_end = nullptr); // Return value always between path and path_end
|
||||
const char* ImPathFindExtension(const char* path, const char* path_end = nullptr); // Return value always between path and path_end
|
||||
void ImPathFixSeparatorsForCurrentOS(char* buf);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// String Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImStrReplace(Str* s, const char* find, const char* repl);
|
||||
const char* ImStrchrRangeWithEscaping(const char* str, const char* str_end, char find_c);
|
||||
void ImStrXmlEscape(Str* s);
|
||||
int ImStrBase64Encode(const unsigned char* src, char* dst, int length);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Parsing Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImParseExtractArgcArgvFromCommandLine(int* out_argc, char const*** out_argv, const char* cmd_line);
|
||||
bool ImParseFindIniSection(const char* ini_config, const char* header, ImVector<char>* result);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Time Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uint64_t ImTimeGetInMicroseconds();
|
||||
void ImTimestampToISO8601(uint64_t timestamp, Str* out_date);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Threading Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImThreadSleepInMilliseconds(int ms);
|
||||
void ImThreadSetCurrentThreadDescription(const char* description);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Build Info helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// All the pointers are expect to be literals/persistent
|
||||
struct ImBuildInfo
|
||||
{
|
||||
const char* Type = "";
|
||||
const char* Cpu = "";
|
||||
const char* OS = "";
|
||||
const char* Compiler = "";
|
||||
char Date[32]; // "YYYY-MM-DD"
|
||||
const char* Time = "";
|
||||
};
|
||||
|
||||
const ImBuildInfo* ImBuildGetCompilationInfo();
|
||||
bool ImBuildFindGitBranchName(const char* git_repo_path, Str* branch_name);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Operating System Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum ImOsConsoleStream
|
||||
{
|
||||
ImOsConsoleStream_StandardOutput,
|
||||
ImOsConsoleStream_StandardError,
|
||||
};
|
||||
|
||||
enum ImOsConsoleTextColor
|
||||
{
|
||||
ImOsConsoleTextColor_Black,
|
||||
ImOsConsoleTextColor_White,
|
||||
ImOsConsoleTextColor_BrightWhite,
|
||||
ImOsConsoleTextColor_BrightRed,
|
||||
ImOsConsoleTextColor_BrightGreen,
|
||||
ImOsConsoleTextColor_BrightBlue,
|
||||
ImOsConsoleTextColor_BrightYellow,
|
||||
};
|
||||
|
||||
bool ImOsCreateProcess(const char* cmd_line);
|
||||
FILE* ImOsPOpen(const char* cmd_line, const char* mode);
|
||||
void ImOsPClose(FILE* fp);
|
||||
void ImOsOpenInShell(const char* path);
|
||||
bool ImOsIsDebuggerPresent();
|
||||
void ImOsOutputDebugString(const char* message);
|
||||
void ImOsConsoleSetTextColor(ImOsConsoleStream stream, ImOsConsoleTextColor color);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Miscellaneous functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Tables functions
|
||||
struct ImGuiTable;
|
||||
ImGuiID TableGetHeaderID(ImGuiTable* table, const char* column, int instance_no = 0);
|
||||
ImGuiID TableGetHeaderID(ImGuiTable* table, int column_n, int instance_no = 0);
|
||||
void TableDiscardInstanceAndSettings(ImGuiID table_id);
|
||||
|
||||
// DrawData functions
|
||||
void DrawDataVerifyMatchingBufferCount(ImDrawData* draw_data);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper: maintain/calculate moving average
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<typename TYPE>
|
||||
struct ImMovingAverage
|
||||
{
|
||||
// Internal Fields
|
||||
ImVector<TYPE> Samples;
|
||||
TYPE Accum;
|
||||
int Idx;
|
||||
int FillAmount;
|
||||
|
||||
// Functions
|
||||
ImMovingAverage() { Accum = (TYPE)0; Idx = FillAmount = 0; }
|
||||
void Init(int count) { Samples.resize(count); memset(Samples.Data, 0, (size_t)Samples.Size * sizeof(TYPE)); Accum = (TYPE)0; Idx = FillAmount = 0; }
|
||||
void AddSample(TYPE v) { Accum += v - Samples[Idx]; Samples[Idx] = v; if (++Idx == Samples.Size) Idx = 0; if (FillAmount < Samples.Size) FillAmount++; }
|
||||
TYPE GetAverage() const { return Accum / (TYPE)FillAmount; }
|
||||
int GetSampleCount() const { return Samples.Size; }
|
||||
bool IsFull() const { return FillAmount == Samples.Size; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper: Simple/dumb CSV parser
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiCsvParser
|
||||
{
|
||||
// Public fields
|
||||
int Columns = 0; // Number of columns in CSV file.
|
||||
int Rows = 0; // Number of rows in CSV file.
|
||||
|
||||
// Internal fields
|
||||
char* _Data = nullptr; // CSV file data.
|
||||
ImVector<char*> _Index; // CSV table: _Index[row * _Columns + col].
|
||||
|
||||
// Functions
|
||||
ImGuiCsvParser(int columns = -1) { Columns = columns; }
|
||||
~ImGuiCsvParser() { Clear(); }
|
||||
bool Load(const char* file_name); // Open and parse a CSV file.
|
||||
void Clear(); // Free allocated buffers.
|
||||
const char* GetCell(int row, int col) { IM_ASSERT(0 <= row && row < Rows && 0 <= col && col < Columns); return _Index[row * Columns + col]; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Misc Dear ImGui extensions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if IMGUI_VERSION_NUM < 18924
|
||||
struct ImGuiTabBar;
|
||||
struct ImGuiTabItem;
|
||||
#endif
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
|
||||
IMGUI_API void ItemErrorFrame(ImU32 col);
|
||||
|
||||
#if IMGUI_VERSION_NUM < 18927
|
||||
ImGuiID TableGetInstanceID(ImGuiTable* table, int instance_no = 0);
|
||||
#endif
|
||||
|
||||
// Str support for InputText()
|
||||
IMGUI_API bool InputText(const char* label, Str* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
|
||||
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, Str* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
|
||||
IMGUI_API bool InputTextMultiline(const char* label, Str* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
|
||||
|
||||
// Splitter
|
||||
IMGUI_API bool Splitter(const char* id, float* value_1, float* value_2, int axis, int anchor = 0, float min_size_0 = -1.0f, float min_size_1 = -1.0f);
|
||||
|
||||
// Misc
|
||||
IMGUI_API ImFont* FindFontByPrefix(const char* name);
|
||||
|
||||
// Legacy version support
|
||||
#if IMGUI_VERSION_NUM < 18924
|
||||
IMGUI_API const char* TabBarGetTabName(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||
#endif
|
||||
|
||||
}
|
||||
7
lib/third_party/imgui/imgui_test_engine/include/thirdparty/README.md
vendored
Normal file
7
lib/third_party/imgui/imgui_test_engine/include/thirdparty/README.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
## Third party libraries used by Test Engine
|
||||
|
||||
Always used:
|
||||
- `Str/Str.h` simple string type, used by `imgui_test_engine` (Public Domain)
|
||||
|
||||
Used if `IMGUI_TEST_ENGINE_ENABLE_CAPTURE` is defined to 1 (default: 1)
|
||||
- `stb/imstb_image_write.h` image writer, used by `imgui_capture_tool` (MIT Licence OR Public Domain)
|
||||
5
lib/third_party/imgui/imgui_test_engine/include/thirdparty/Str/.editorconfig
vendored
Normal file
5
lib/third_party/imgui/imgui_test_engine/include/thirdparty/Str/.editorconfig
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
[*.{h,cpp}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
|
||||
71
lib/third_party/imgui/imgui_test_engine/include/thirdparty/Str/README.md
vendored
Normal file
71
lib/third_party/imgui/imgui_test_engine/include/thirdparty/Str/README.md
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
```
|
||||
Str
|
||||
Simple C++ string type with an optional local buffer, by Omar Cornut
|
||||
https://github.com/ocornut/str
|
||||
|
||||
LICENSE
|
||||
This software is in the public domain. Where that dedication is not
|
||||
recognized, you are granted a perpetual, irrevocable license to copy,
|
||||
distribute, and modify this file as you see fit.
|
||||
|
||||
USAGE
|
||||
Include Str.h in whatever places need to refer to it.
|
||||
In ONE .cpp file, write '#define STR_IMPLEMENTATION' before the #include.
|
||||
This expands out the actual implementation into that C/C++ file.
|
||||
|
||||
NOTES
|
||||
- This isn't a fully featured string class.
|
||||
- It is a simple, bearable replacement to std::string that isn't heap abusive nor bloated (can actually be debugged by humans!).
|
||||
- String are mutable. We don't maintain size so length() is not-constant time.
|
||||
- Maximum string size currently limited to 2 MB (we allocate 21 bits to hold capacity).
|
||||
- Local buffer size is currently limited to 1023 bytes (we allocate 10 bits to hold local buffer size).
|
||||
- We could easily raise those limits if we are ok to increase the structure overhead in 32-bits mode.
|
||||
- In "non-owned" mode for literals/reference we don't do any tracking/counting of references.
|
||||
- Overhead is 8-bytes in 32-bits, 16-bytes in 64-bits (12 + alignment).
|
||||
- I'm using this code but it hasn't been tested thoroughly.
|
||||
|
||||
The idea is that you can provide an arbitrary sized local buffer if you expect string to fit
|
||||
most of the time, and then you avoid using costly heap.
|
||||
|
||||
No local buffer, always use heap, sizeof()==8~16 (depends if your pointers are 32-bits or 64-bits)
|
||||
|
||||
Str s = "hey"; // use heap
|
||||
|
||||
With a local buffer of 16 bytes, sizeof() == 8~16 + 16 bytes.
|
||||
|
||||
Str16 s = "filename.h"; // copy into local buffer
|
||||
Str16 s = "long_filename_not_very_long_but_longer_than_expected.h"; // use heap
|
||||
|
||||
With a local buffer of 256 bytes, sizeof() == 8~16 + 256 bytes.
|
||||
|
||||
Str256 s = "long_filename_not_very_long_but_longer_than_expected.h"; // copy into local buffer
|
||||
|
||||
Common sizes are defined at the bottom of Str.h, you may define your own.
|
||||
|
||||
Functions:
|
||||
|
||||
Str256 s;
|
||||
s.set("hello sailor"); // set (copy)
|
||||
s.setf("%s/%s.tmp", folder, filename); // set (w/format)
|
||||
s.append("hello"); // append. cost a length() calculation!
|
||||
s.appendf("hello %d", 42); // append (w/format). cost a length() calculation!
|
||||
s.set_ref("Hey!"); // set (literal/reference, just copy pointer, no tracking)
|
||||
|
||||
Constructor helper for format string: add a trailing 'f' to the type. Underlying type is the same.
|
||||
|
||||
Str256f filename("%s/%s.tmp", folder, filename); // construct (w/format)
|
||||
fopen(Str256f("%s/%s.tmp, folder, filename).c_str(), "rb"); // construct (w/format), use as function param, destruct
|
||||
|
||||
Constructor helper for reference/literal:
|
||||
|
||||
StrRef ref("literal"); // copy pointer, no allocation, no string copy
|
||||
StrRef ref2(GetDebugName()); // copy pointer. no tracking of anything whatsoever, know what you are doing!
|
||||
|
||||
All StrXXX types derives from Str and instance hold the local buffer capacity.
|
||||
So you can pass e.g. Str256* to a function taking base type Str* and it will be functional!
|
||||
|
||||
void MyFunc(Str& s) { s = "Hello"; } // will use local buffer if available in Str instance
|
||||
|
||||
(Using a template e.g. Str<N> we could remove the LocalBufSize storage but it would make passing typed Str<> to functions tricky.
|
||||
Instead we don't use template so you can pass them around as the base type Str*. Also, templates are ugly.)
|
||||
```
|
||||
660
lib/third_party/imgui/imgui_test_engine/include/thirdparty/Str/Str.h
vendored
Normal file
660
lib/third_party/imgui/imgui_test_engine/include/thirdparty/Str/Str.h
vendored
Normal file
@@ -0,0 +1,660 @@
|
||||
// Str v0.33
|
||||
// Simple C++ string type with an optional local buffer, by Omar Cornut
|
||||
// https://github.com/ocornut/str
|
||||
|
||||
// LICENSE
|
||||
// This software is in the public domain. Where that dedication is not
|
||||
// recognized, you are granted a perpetual, irrevocable license to copy,
|
||||
// distribute, and modify this file as you see fit.
|
||||
|
||||
// USAGE
|
||||
// Include this file in whatever places need to refer to it.
|
||||
// In ONE .cpp file, write '#define STR_IMPLEMENTATION' before the #include of this file.
|
||||
// This expands out the actual implementation into that C/C++ file.
|
||||
|
||||
|
||||
/*
|
||||
- This isn't a fully featured string class.
|
||||
- It is a simple, bearable replacement to std::string that isn't heap abusive nor bloated (can actually be debugged by humans).
|
||||
- String are mutable. We don't maintain size so length() is not-constant time.
|
||||
- Maximum string size currently limited to 2 MB (we allocate 21 bits to hold capacity).
|
||||
- Local buffer size is currently limited to 1023 bytes (we allocate 10 bits to hold local buffer size).
|
||||
- In "non-owned" mode for literals/reference we don't do any tracking/counting of references.
|
||||
- Overhead is 8-bytes in 32-bits, 16-bytes in 64-bits (12 + alignment).
|
||||
- This code hasn't been tested very much. it is probably incomplete or broken. Made it for my own use.
|
||||
|
||||
The idea is that you can provide an arbitrary sized local buffer if you expect string to fit
|
||||
most of the time, and then you avoid using costly heap.
|
||||
|
||||
No local buffer, always use heap, sizeof()==8~16 (depends if your pointers are 32-bits or 64-bits)
|
||||
|
||||
Str s = "hey";
|
||||
|
||||
With a local buffer of 16 bytes, sizeof() == 8~16 + 16 bytes.
|
||||
|
||||
Str16 s = "filename.h"; // copy into local buffer
|
||||
Str16 s = "long_filename_not_very_long_but_longer_than_expected.h"; // use heap
|
||||
|
||||
With a local buffer of 256 bytes, sizeof() == 8~16 + 256 bytes.
|
||||
|
||||
Str256 s = "long_filename_not_very_long_but_longer_than_expected.h"; // copy into local buffer
|
||||
|
||||
Common sizes are defined at the bottom of Str.h, you may define your own.
|
||||
|
||||
Functions:
|
||||
|
||||
Str256 s;
|
||||
s.set("hello sailor"); // set (copy)
|
||||
s.setf("%s/%s.tmp", folder, filename); // set (w/format)
|
||||
s.append("hello"); // append. cost a length() calculation!
|
||||
s.appendf("hello %d", 42); // append (w/format). cost a length() calculation!
|
||||
s.set_ref("Hey!"); // set (literal/reference, just copy pointer, no tracking)
|
||||
|
||||
Constructor helper for format string: add a trailing 'f' to the type. Underlying type is the same.
|
||||
|
||||
Str256f filename("%s/%s.tmp", folder, filename); // construct (w/format)
|
||||
fopen(Str256f("%s/%s.tmp, folder, filename).c_str(), "rb"); // construct (w/format), use as function param, destruct
|
||||
|
||||
Constructor helper for reference/literal:
|
||||
|
||||
StrRef ref("literal"); // copy pointer, no allocation, no string copy
|
||||
StrRef ref2(GetDebugName()); // copy pointer. no tracking of anything whatsoever, know what you are doing!
|
||||
|
||||
All StrXXX types derives from Str and instance hold the local buffer capacity. So you can pass e.g. Str256* to a function taking base type Str* and it will be functional.
|
||||
|
||||
void MyFunc(Str& s) { s = "Hello"; } // will use local buffer if available in Str instance
|
||||
|
||||
(Using a template e.g. Str<N> we could remove the LocalBufSize storage but it would make passing typed Str<> to functions tricky.
|
||||
Instead we don't use template so you can pass them around as the base type Str*. Also, templates are ugly.)
|
||||
*/
|
||||
|
||||
/*
|
||||
CHANGELOG
|
||||
0.33 - fixed capacity() return value to match standard. e.g. a Str256's capacity() now returns 255, not 256.
|
||||
0.32 - added owned() accessor.
|
||||
0.31 - fixed various warnings.
|
||||
0.30 - turned into a single header file, removed Str.cpp.
|
||||
0.29 - fixed bug when calling reserve on non-owned strings (ie. when using StrRef or set_ref), and fixed <string> include.
|
||||
0.28 - breaking change: replaced Str32 by Str30 to avoid collision with Str32 from MacTypes.h .
|
||||
0.27 - added STR_API and basic .natvis file.
|
||||
0.26 - fixed set(cont char* src, const char* src_end) writing null terminator to the wrong position.
|
||||
0.25 - allow set(const char* NULL) or operator= NULL to clear the string. note that set() from range or other types are not allowed.
|
||||
0.24 - allow set_ref(const char* NULL) to clear the string. include fixes for linux.
|
||||
0.23 - added append(char). added append_from(int idx, XXX) functions. fixed some compilers warnings.
|
||||
0.22 - documentation improvements, comments. fixes for some compilers.
|
||||
0.21 - added StrXXXf() constructor to construct directly from a format string.
|
||||
*/
|
||||
|
||||
/*
|
||||
TODO
|
||||
- Since we lose 4-bytes of padding on 64-bits architecture, perhaps just spread the header to 8-bytes and lift size limits?
|
||||
- More functions/helpers.
|
||||
*/
|
||||
|
||||
#ifndef STR_INCLUDED
|
||||
#define STR_INCLUDED
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CONFIGURATION
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#ifndef STR_MEMALLOC
|
||||
#define STR_MEMALLOC malloc
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifndef STR_MEMFREE
|
||||
#define STR_MEMFREE free
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifndef STR_ASSERT
|
||||
#define STR_ASSERT assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#ifndef STR_API
|
||||
#define STR_API
|
||||
#endif
|
||||
#include <stdarg.h> // for va_list
|
||||
#include <string.h> // for strlen, strcmp, memcpy, etc.
|
||||
|
||||
// Configuration: #define STR_SUPPORT_STD_STRING 0 to disable setters variants using const std::string& (on by default)
|
||||
#ifndef STR_SUPPORT_STD_STRING
|
||||
#define STR_SUPPORT_STD_STRING 1
|
||||
#endif
|
||||
|
||||
// Configuration: #define STR_DEFINE_STR32 1 to keep defining Str32/Str32f, but be warned: on macOS/iOS, MacTypes.h also defines a type named Str32.
|
||||
#ifndef STR_DEFINE_STR32
|
||||
#define STR_DEFINE_STR32 0
|
||||
#endif
|
||||
|
||||
#if STR_SUPPORT_STD_STRING
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// HEADERS
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// This is the base class that you can pass around
|
||||
// Footprint is 8-bytes (32-bits arch) or 16-bytes (64-bits arch)
|
||||
class STR_API Str
|
||||
{
|
||||
char* Data; // Point to LocalBuf() or heap allocated
|
||||
int Capacity : 21; // Max 2 MB. Exclude zero terminator.
|
||||
int LocalBufSize : 10; // Max 1023 bytes
|
||||
unsigned int Owned : 1; // Set when we have ownership of the pointed data (most common, unless using set_ref() method or StrRef constructor)
|
||||
|
||||
public:
|
||||
inline char* c_str() { return Data; }
|
||||
inline const char* c_str() const { return Data; }
|
||||
inline bool empty() const { return Data[0] == 0; }
|
||||
inline int length() const { return (int)strlen(Data); } // by design, allow user to write into the buffer at any time
|
||||
inline int capacity() const { return Capacity; }
|
||||
inline bool owned() const { return Owned ? true : false; }
|
||||
|
||||
inline void set_ref(const char* src);
|
||||
int setf(const char* fmt, ...);
|
||||
int setfv(const char* fmt, va_list args);
|
||||
int setf_nogrow(const char* fmt, ...);
|
||||
int setfv_nogrow(const char* fmt, va_list args);
|
||||
int append(char c);
|
||||
int append(const char* s, const char* s_end = NULL);
|
||||
int appendf(const char* fmt, ...);
|
||||
int appendfv(const char* fmt, va_list args);
|
||||
int append_from(int idx, char c);
|
||||
int append_from(int idx, const char* s, const char* s_end = NULL); // If you know the string length or want to append from a certain point
|
||||
int appendf_from(int idx, const char* fmt, ...);
|
||||
int appendfv_from(int idx, const char* fmt, va_list args);
|
||||
|
||||
void clear();
|
||||
void reserve(int cap);
|
||||
void reserve_discard(int cap);
|
||||
void shrink_to_fit();
|
||||
|
||||
inline char& operator[](size_t i) { return Data[i]; }
|
||||
inline char operator[](size_t i) const { return Data[i]; }
|
||||
//explicit operator const char*() const{ return Data; }
|
||||
|
||||
inline Str();
|
||||
inline Str(const char* rhs);
|
||||
inline void set(const char* src);
|
||||
inline void set(const char* src, const char* src_end);
|
||||
inline Str& operator=(const char* rhs) { set(rhs); return *this; }
|
||||
inline bool operator==(const char* rhs) const { return strcmp(c_str(), rhs) == 0; }
|
||||
|
||||
inline Str(const Str& rhs);
|
||||
inline void set(const Str& src);
|
||||
inline Str& operator=(const Str& rhs) { set(rhs); return *this; }
|
||||
inline bool operator==(const Str& rhs) const { return strcmp(c_str(), rhs.c_str()) == 0; }
|
||||
|
||||
#if STR_SUPPORT_STD_STRING
|
||||
inline Str(const std::string& rhs);
|
||||
inline void set(const std::string& src);
|
||||
inline Str& operator=(const std::string& rhs) { set(rhs); return *this; }
|
||||
inline bool operator==(const std::string& rhs)const { return strcmp(c_str(), rhs.c_str()) == 0; }
|
||||
#endif
|
||||
|
||||
// Destructor for all variants
|
||||
inline ~Str()
|
||||
{
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
}
|
||||
|
||||
static char* EmptyBuffer;
|
||||
|
||||
protected:
|
||||
inline char* local_buf() { return (char*)this + sizeof(Str); }
|
||||
inline const char* local_buf() const { return (char*)this + sizeof(Str); }
|
||||
inline bool is_using_local_buf() const { return Data == local_buf() && LocalBufSize != 0; }
|
||||
|
||||
// Constructor for StrXXX variants with local buffer
|
||||
Str(unsigned short local_buf_size)
|
||||
{
|
||||
STR_ASSERT(local_buf_size < 1024);
|
||||
Data = local_buf();
|
||||
Data[0] = '\0';
|
||||
Capacity = local_buf_size ? local_buf_size - 1 : 0;
|
||||
LocalBufSize = local_buf_size;
|
||||
Owned = 1;
|
||||
}
|
||||
};
|
||||
|
||||
void Str::set(const char* src)
|
||||
{
|
||||
// We allow set(NULL) or via = operator to clear the string.
|
||||
if (src == NULL)
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
int buf_len = (int)strlen(src);
|
||||
if (Capacity < buf_len)
|
||||
reserve_discard(buf_len);
|
||||
memcpy(Data, src, (size_t)(buf_len + 1));
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
void Str::set(const char* src, const char* src_end)
|
||||
{
|
||||
STR_ASSERT(src != NULL && src_end >= src);
|
||||
int buf_len = (int)(src_end - src);
|
||||
if ((int)Capacity < buf_len)
|
||||
reserve_discard(buf_len);
|
||||
memcpy(Data, src, (size_t)buf_len);
|
||||
Data[buf_len] = 0;
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
void Str::set(const Str& src)
|
||||
{
|
||||
int buf_len = (int)strlen(src.c_str());
|
||||
if ((int)Capacity < buf_len)
|
||||
reserve_discard(buf_len);
|
||||
memcpy(Data, src.c_str(), (size_t)(buf_len + 1));
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
#if STR_SUPPORT_STD_STRING
|
||||
void Str::set(const std::string& src)
|
||||
{
|
||||
int buf_len = (int)src.length();
|
||||
if ((int)Capacity < buf_len)
|
||||
reserve_discard(buf_len);
|
||||
memcpy(Data, src.c_str(), (size_t)(buf_len + 1));
|
||||
Owned = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void Str::set_ref(const char* src)
|
||||
{
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
Data = src ? (char*)src : EmptyBuffer;
|
||||
Capacity = 0;
|
||||
Owned = 0;
|
||||
}
|
||||
|
||||
Str::Str()
|
||||
{
|
||||
Data = EmptyBuffer; // Shared READ-ONLY initial buffer for 0 capacity
|
||||
Capacity = 0;
|
||||
LocalBufSize = 0;
|
||||
Owned = 0;
|
||||
}
|
||||
|
||||
Str::Str(const Str& rhs) : Str()
|
||||
{
|
||||
set(rhs);
|
||||
}
|
||||
|
||||
Str::Str(const char* rhs) : Str()
|
||||
{
|
||||
set(rhs);
|
||||
}
|
||||
|
||||
#if STR_SUPPORT_STD_STRING
|
||||
Str::Str(const std::string& rhs) : Str()
|
||||
{
|
||||
set(rhs);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Literal/reference string
|
||||
class StrRef : public Str
|
||||
{
|
||||
public:
|
||||
StrRef(const char* s) : Str() { set_ref(s); }
|
||||
};
|
||||
|
||||
// Types embedding a local buffer
|
||||
// NB: we need to override the constructor and = operator for both Str& and TYPENAME (without the later compiler will call a default copy operator)
|
||||
#if STR_SUPPORT_STD_STRING
|
||||
|
||||
#define STR_DEFINETYPE(TYPENAME, LOCALBUFSIZE) \
|
||||
class TYPENAME : public Str \
|
||||
{ \
|
||||
char local_buf[LOCALBUFSIZE]; \
|
||||
public: \
|
||||
TYPENAME() : Str(LOCALBUFSIZE) {} \
|
||||
TYPENAME(const Str& rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME(const char* rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME(const TYPENAME& rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME(const std::string& rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME& operator=(const char* rhs) { set(rhs); return *this; } \
|
||||
TYPENAME& operator=(const Str& rhs) { set(rhs); return *this; } \
|
||||
TYPENAME& operator=(const TYPENAME& rhs) { set(rhs); return *this; } \
|
||||
TYPENAME& operator=(const std::string& rhs) { set(rhs); return *this; } \
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define STR_DEFINETYPE(TYPENAME, LOCALBUFSIZE) \
|
||||
class TYPENAME : public Str \
|
||||
{ \
|
||||
char local_buf[LOCALBUFSIZE]; \
|
||||
public: \
|
||||
TYPENAME() : Str(LOCALBUFSIZE) {} \
|
||||
TYPENAME(const Str& rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME(const char* rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME(const TYPENAME& rhs) : Str(LOCALBUFSIZE) { set(rhs); } \
|
||||
TYPENAME& operator=(const char* rhs) { set(rhs); return *this; } \
|
||||
TYPENAME& operator=(const Str& rhs) { set(rhs); return *this; } \
|
||||
TYPENAME& operator=(const TYPENAME& rhs) { set(rhs); return *this; } \
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Disable PVS-Studio warning V730: Not all members of a class are initialized inside the constructor (local_buf is not initialized and that is fine)
|
||||
// -V:STR_DEFINETYPE:730
|
||||
|
||||
// Helper to define StrXXXf constructors
|
||||
#define STR_DEFINETYPE_F(TYPENAME, TYPENAME_F) \
|
||||
class TYPENAME_F : public TYPENAME \
|
||||
{ \
|
||||
public: \
|
||||
TYPENAME_F(const char* fmt, ...) : TYPENAME() { va_list args; va_start(args, fmt); setfv(fmt, args); va_end(args); } \
|
||||
};
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field" // warning : private field 'local_buf' is not used
|
||||
#endif
|
||||
|
||||
// Declaring types for common sizes here
|
||||
STR_DEFINETYPE(Str16, 16)
|
||||
STR_DEFINETYPE(Str30, 30)
|
||||
STR_DEFINETYPE(Str64, 64)
|
||||
STR_DEFINETYPE(Str128, 128)
|
||||
STR_DEFINETYPE(Str256, 256)
|
||||
STR_DEFINETYPE(Str512, 512)
|
||||
|
||||
// Declaring helper constructors to pass in format strings in one statement
|
||||
STR_DEFINETYPE_F(Str16, Str16f)
|
||||
STR_DEFINETYPE_F(Str30, Str30f)
|
||||
STR_DEFINETYPE_F(Str64, Str64f)
|
||||
STR_DEFINETYPE_F(Str128, Str128f)
|
||||
STR_DEFINETYPE_F(Str256, Str256f)
|
||||
STR_DEFINETYPE_F(Str512, Str512f)
|
||||
|
||||
#if STR_DEFINE_STR32
|
||||
STR_DEFINETYPE(Str32, 32)
|
||||
STR_DEFINETYPE_F(Str32, Str32f)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef STR_INCLUDED
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// IMPLEMENTATION
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#ifdef STR_IMPLEMENTATION
|
||||
|
||||
#include <stdio.h> // for vsnprintf
|
||||
|
||||
// On some platform vsnprintf() takes va_list by reference and modifies it.
|
||||
// va_copy is the 'correct' way to copy a va_list but Visual Studio prior to 2013 doesn't have it.
|
||||
#ifndef va_copy
|
||||
#define va_copy(dest, src) (dest = src)
|
||||
#endif
|
||||
|
||||
// Static empty buffer we can point to for empty strings
|
||||
// Pointing to a literal increases the like-hood of getting a crash if someone attempts to write in the empty string buffer.
|
||||
char* Str::EmptyBuffer = (char*)"\0NULL";
|
||||
|
||||
// Clear
|
||||
void Str::clear()
|
||||
{
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
if (LocalBufSize)
|
||||
{
|
||||
Data = local_buf();
|
||||
Data[0] = '\0';
|
||||
Capacity = LocalBufSize - 1;
|
||||
Owned = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Data = EmptyBuffer;
|
||||
Capacity = 0;
|
||||
Owned = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Reserve memory, preserving the current of the buffer
|
||||
// Capacity doesn't include the zero terminator, so reserve(5) is enough to store "hello".
|
||||
void Str::reserve(int new_capacity)
|
||||
{
|
||||
if (new_capacity <= Capacity)
|
||||
return;
|
||||
|
||||
char* new_data;
|
||||
if (new_capacity <= LocalBufSize - 1)
|
||||
{
|
||||
// Disowned -> LocalBuf
|
||||
new_data = local_buf();
|
||||
new_capacity = LocalBufSize - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disowned or LocalBuf -> Heap
|
||||
new_data = (char*)STR_MEMALLOC((size_t)(new_capacity + 1) * sizeof(char));
|
||||
}
|
||||
|
||||
// string in Data might be longer than new_capacity if it wasn't owned, don't copy too much
|
||||
#ifdef _MSC_VER
|
||||
strncpy_s(new_data, (size_t)new_capacity + 1, Data, (size_t)new_capacity);
|
||||
#else
|
||||
strncpy(new_data, Data, (size_t)new_capacity);
|
||||
#endif
|
||||
new_data[new_capacity] = 0;
|
||||
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
|
||||
Data = new_data;
|
||||
Capacity = new_capacity;
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
// Reserve memory, discarding the current of the buffer (if we expect to be fully rewritten)
|
||||
void Str::reserve_discard(int new_capacity)
|
||||
{
|
||||
if (new_capacity <= Capacity)
|
||||
return;
|
||||
|
||||
if (Owned && !is_using_local_buf())
|
||||
STR_MEMFREE(Data);
|
||||
|
||||
if (new_capacity <= LocalBufSize - 1)
|
||||
{
|
||||
// Disowned -> LocalBuf
|
||||
Data = local_buf();
|
||||
Capacity = LocalBufSize - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disowned or LocalBuf -> Heap
|
||||
Data = (char*)STR_MEMALLOC((size_t)(new_capacity + 1) * sizeof(char));
|
||||
Capacity = new_capacity;
|
||||
}
|
||||
Owned = 1;
|
||||
}
|
||||
|
||||
void Str::shrink_to_fit()
|
||||
{
|
||||
if (!Owned || is_using_local_buf())
|
||||
return;
|
||||
int new_capacity = length();
|
||||
if (Capacity <= new_capacity)
|
||||
return;
|
||||
|
||||
char* new_data = (char*)STR_MEMALLOC((size_t)(new_capacity + 1) * sizeof(char));
|
||||
memcpy(new_data, Data, (size_t)(new_capacity + 1));
|
||||
STR_MEMFREE(Data);
|
||||
Data = new_data;
|
||||
Capacity = new_capacity;
|
||||
}
|
||||
|
||||
// FIXME: merge setfv() and appendfv()?
|
||||
int Str::setfv(const char* fmt, va_list args)
|
||||
{
|
||||
// Needed for portability on platforms where va_list are passed by reference and modified by functions
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
|
||||
// MSVC returns -1 on overflow when writing, which forces us to do two passes
|
||||
// FIXME-OPT: Find a way around that.
|
||||
#ifdef _MSC_VER
|
||||
int len = vsnprintf(NULL, 0, fmt, args);
|
||||
STR_ASSERT(len >= 0);
|
||||
|
||||
if (Capacity < len)
|
||||
reserve_discard(len);
|
||||
len = vsnprintf(Data, (size_t)len + 1, fmt, args2);
|
||||
#else
|
||||
// First try
|
||||
int len = vsnprintf(Owned ? Data : NULL, Owned ? (size_t)(Capacity + 1): 0, fmt, args);
|
||||
STR_ASSERT(len >= 0);
|
||||
|
||||
if (Capacity < len)
|
||||
{
|
||||
reserve_discard(len);
|
||||
len = vsnprintf(Data, (size_t)len + 1, fmt, args2);
|
||||
}
|
||||
#endif
|
||||
|
||||
STR_ASSERT(Owned);
|
||||
return len;
|
||||
}
|
||||
|
||||
int Str::setf(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = setfv(fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
int Str::setfv_nogrow(const char* fmt, va_list args)
|
||||
{
|
||||
STR_ASSERT(Owned);
|
||||
|
||||
if (Capacity == 0)
|
||||
return 0;
|
||||
|
||||
int w = vsnprintf(Data, (size_t)(Capacity + 1), fmt, args);
|
||||
Data[Capacity] = 0;
|
||||
Owned = 1;
|
||||
return (w == -1) ? Capacity : w;
|
||||
}
|
||||
|
||||
int Str::setf_nogrow(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = setfv_nogrow(fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
int Str::append_from(int idx, char c)
|
||||
{
|
||||
int add_len = 1;
|
||||
if (Capacity < idx + add_len)
|
||||
reserve(idx + add_len);
|
||||
Data[idx] = c;
|
||||
Data[idx + add_len] = 0;
|
||||
STR_ASSERT(Owned);
|
||||
return add_len;
|
||||
}
|
||||
|
||||
int Str::append_from(int idx, const char* s, const char* s_end)
|
||||
{
|
||||
if (!s_end)
|
||||
s_end = s + strlen(s);
|
||||
int add_len = (int)(s_end - s);
|
||||
if (Capacity < idx + add_len)
|
||||
reserve(idx + add_len);
|
||||
memcpy(Data + idx, (const void*)s, (size_t)add_len);
|
||||
Data[idx + add_len] = 0; // Our source data isn't necessarily zero terminated
|
||||
STR_ASSERT(Owned);
|
||||
return add_len;
|
||||
}
|
||||
|
||||
// FIXME: merge setfv() and appendfv()?
|
||||
int Str::appendfv_from(int idx, const char* fmt, va_list args)
|
||||
{
|
||||
// Needed for portability on platforms where va_list are passed by reference and modified by functions
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
|
||||
// MSVC returns -1 on overflow when writing, which forces us to do two passes
|
||||
// FIXME-OPT: Find a way around that.
|
||||
#ifdef _MSC_VER
|
||||
int add_len = vsnprintf(NULL, 0, fmt, args);
|
||||
STR_ASSERT(add_len >= 0);
|
||||
|
||||
if (Capacity < idx + add_len)
|
||||
reserve(idx + add_len);
|
||||
add_len = vsnprintf(Data + idx, add_len + 1, fmt, args2);
|
||||
#else
|
||||
// First try
|
||||
int add_len = vsnprintf(Owned ? Data + idx : NULL, Owned ? (size_t)(Capacity + 1 - idx) : 0, fmt, args);
|
||||
STR_ASSERT(add_len >= 0);
|
||||
|
||||
if (Capacity < idx + add_len)
|
||||
{
|
||||
reserve(idx + add_len);
|
||||
add_len = vsnprintf(Data + idx, (size_t)add_len + 1, fmt, args2);
|
||||
}
|
||||
#endif
|
||||
|
||||
STR_ASSERT(Owned);
|
||||
return add_len;
|
||||
}
|
||||
|
||||
int Str::appendf_from(int idx, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = appendfv_from(idx, fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
int Str::append(char c)
|
||||
{
|
||||
int cur_len = length();
|
||||
return append_from(cur_len, c);
|
||||
}
|
||||
|
||||
int Str::append(const char* s, const char* s_end)
|
||||
{
|
||||
int cur_len = length();
|
||||
return append_from(cur_len, s, s_end);
|
||||
}
|
||||
|
||||
int Str::appendfv(const char* fmt, va_list args)
|
||||
{
|
||||
int cur_len = length();
|
||||
return appendfv_from(cur_len, fmt, args);
|
||||
}
|
||||
|
||||
int Str::appendf(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = appendfv(fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif // #define STR_IMPLEMENTATION
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
14
lib/third_party/imgui/imgui_test_engine/include/thirdparty/Str/Str.natvis
vendored
Normal file
14
lib/third_party/imgui/imgui_test_engine/include/thirdparty/Str/Str.natvis
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
|
||||
<Type Name="Str">
|
||||
<DisplayString>{ Data, na }</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="Data">Data, na</Item>
|
||||
<Item Name="Size">strlen(Data)</Item>
|
||||
<Item Name="Capacity">Capacity</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
</AutoVisualizer>
|
||||
1617
lib/third_party/imgui/imgui_test_engine/include/thirdparty/stb/imstb_image_write.h
vendored
Normal file
1617
lib/third_party/imgui/imgui_test_engine/include/thirdparty/stb/imstb_image_write.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user