diff options
| author | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-09-12 16:35:40 +0200 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-09-12 16:35:40 +0200 |
| commit | abf01f657d068aa6b22ab962cbe01b88f3b5f7ea (patch) | |
| tree | 2a354a6112ef0b9ef6975613f12865831f5d4a69 | |
| parent | d174d803de2296061731c3698980a6a51e6fc3ef (diff) | |
event logging
| -rw-r--r-- | docs/README.rst | 3 | ||||
| -rw-r--r-- | include/log.hpp | 7 | ||||
| -rw-r--r-- | include/ui.hpp | 1 | ||||
| -rw-r--r-- | libs/timer_lib/.gitattributes | 22 | ||||
| -rw-r--r-- | libs/timer_lib/.gitignore | 163 | ||||
| -rw-r--r-- | libs/timer_lib/Makefile | 23 | ||||
| -rw-r--r-- | libs/timer_lib/README | 37 | ||||
| -rw-r--r-- | libs/timer_lib/test.vcxproj | 169 | ||||
| -rw-r--r-- | libs/timer_lib/timer.c | 174 | ||||
| -rw-r--r-- | libs/timer_lib/timer.h | 77 | ||||
| -rw-r--r-- | libs/timer_lib/timer.sln | 36 | ||||
| -rw-r--r-- | libs/timer_lib/timer.vcxproj | 225 | ||||
| -rw-r--r-- | run.bat | 3 | ||||
| -rw-r--r-- | src/administration.cpp | 11 | ||||
| -rw-r--r-- | src/administration_writer.cpp | 24 | ||||
| -rw-r--r-- | src/log.cpp | 33 | ||||
| -rw-r--r-- | src/main.cpp | 4 | ||||
| -rw-r--r-- | src/ui/ui_expenses.cpp | 10 | ||||
| -rw-r--r-- | src/ui/ui_invoices.cpp | 9 | ||||
| -rw-r--r-- | src/ui/ui_log.cpp | 20 | ||||
| -rw-r--r-- | src/ui/ui_main.cpp | 11 |
21 files changed, 1047 insertions, 15 deletions
diff --git a/docs/README.rst b/docs/README.rst index 4436a53..e8aab29 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -43,4 +43,5 @@ This section lists all supported countries. If the country you operate from is n - ImGuiDatePicker (https://github.com/DnA-IntRicate/ImGuiDatePicker) - tinyfiledialogs (https://sourceforge.net/projects/tinyfiledialogs/) - xml.c (https://github.com/ooxi/xml.c) -- zip (https://github.com/kuba--/zip)
\ No newline at end of file +- zip (https://github.com/kuba--/zip) +- timer_lib (https://github.com/mjansson/timer_lib)
\ No newline at end of file diff --git a/include/log.hpp b/include/log.hpp index dcb2987..f34cc27 100644 --- a/include/log.hpp +++ b/include/log.hpp @@ -1,5 +1,6 @@ #pragma once +#include "timer.h" #include "imgui.h" #include "config.hpp" @@ -12,4 +13,8 @@ typedef struct { char history[MAX_LEN_LOG_HISTORY][MAX_LEN_LOG_TXT]; } log; -void log_add(double timestamp, const char* fmt, ...) IM_FMTARGS(2);
\ No newline at end of file +#define STOPWATCH_START tick_t timestamp_start = timer_current(); +#define STOPWATCH_TIME (timer_elapsed(timestamp_start)*1000.0f) + +log* get_log(); +void log_add(const char* fmt, ...) IM_FMTARGS(2);
\ No newline at end of file diff --git a/include/ui.hpp b/include/ui.hpp index ddfb824..7bbdd5a 100644 --- a/include/ui.hpp +++ b/include/ui.hpp @@ -46,6 +46,7 @@ void ui_draw_invoices(); void ui_draw_settings(); void ui_draw_expenses(); void ui_draw_earnings(); +void ui_draw_log(); void ui_setup_invoices(); void ui_setup_contacts(); diff --git a/libs/timer_lib/.gitattributes b/libs/timer_lib/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/libs/timer_lib/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/libs/timer_lib/.gitignore b/libs/timer_lib/.gitignore new file mode 100644 index 0000000..5ebd21a --- /dev/null +++ b/libs/timer_lib/.gitignore @@ -0,0 +1,163 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +*.dotCover + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store diff --git a/libs/timer_lib/Makefile b/libs/timer_lib/Makefile new file mode 100644 index 0000000..3edaf73 --- /dev/null +++ b/libs/timer_lib/Makefile @@ -0,0 +1,23 @@ +SRC = timer.c +OBJ = $(SRC:.c=.o) +OUT = libtimer.a +TST = timertest +TSR = test.c +TOB = $(TSR:.c=.o) + +CFLAGS = -O3 +LDFLAGS = + +default: $(OUT) $(TST) + +.c.o: + gcc $(CFLAGS) -c $< -o $@ + +$(OUT): $(OBJ) + ar rcs $(OUT) $(OBJ) + +$(TST): $(OUT) $(TOB) + gcc $(CFLAGS) $(LDFLAGS) -o $(TST) $(TOB) $(OUT) -lrt + +clean: + rm -f $(OBJ) $(OUT) $(TOB) $(TST) diff --git a/libs/timer_lib/README b/libs/timer_lib/README new file mode 100644 index 0000000..16f604b --- /dev/null +++ b/libs/timer_lib/README @@ -0,0 +1,37 @@ +timer_lib - v1.0 - Public Domain - 2011 Mattias Jansson + +This library provides a cross-platform interface to measure +elapsed time with (at least) millisecond accuracy. The latest +source code is always available at + +https://github.com/mjansson/timer_lib + +This library is put in the public domain; you can redistribute +it and/or modify it without any restrictions. + +For a complete cross-platform application framework, look at +the foundation library available at + +https://github.com/mjansson/foundation_lib + + +VERSION HISTORY + + 0.1 (2011-03-15) Initial release + 0.2 (2011-03-20) Removed timer type (always high precision) + Fixed timer_ticks_per_second declaration + Added test application + 0.3 (2011-03-22) Removed unused error checks in POSIX code + Made timeGetTime fallback optional in Windows code (define USE_FALLBACK to 1) + Fixed check of QPC weirdness (signed issue) + 0.4 (2011-03-23) timer_lib_initialize() returns non-zero if failed (no high precision timer available) + Changed POSIX path to use CLOCK_MONOTONIC + POSIX timer_system use CLOCK_REALTIME for actual timestamp + Addded Mach-O path for MacOS X + Changed POSIX path to use nanosecond frequency as returned by clock_gettime + 0.5 (2012-10-01) Merged (cleaned up) MacOSX build fixes from Nicolas Léveillé + 0.6 (2013-01-11) Simplified API, only using tick_t type as timestamp and removing custom timer struct + Removed old legacy fallback code for Windows platform + 0.7 (2013-01-11) Using platform_lib for platform and compiler abstraction + 0.8 (2013-07-30) Made library standalone with no deps (not using deprecated platform_lib) + 1.0 (2021-12-15) Updated and cleaned up for clang 10+ and Visual Studio 2022 diff --git a/libs/timer_lib/test.vcxproj b/libs/timer_lib/test.vcxproj new file mode 100644 index 0000000..468b70e --- /dev/null +++ b/libs/timer_lib/test.vcxproj @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{54E95B82-7759-4825-9478-91E76F1C1C89}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>build\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir> + <IntDir>build\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>build\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir> + <IntDir>build\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../platform_lib</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../platform_lib</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../platform_lib</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../platform_lib</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="test.c" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="timer.vcxproj"> + <Project>{321bab92-2ede-4b3b-939d-bd0be0248c8f}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/libs/timer_lib/timer.c b/libs/timer_lib/timer.c new file mode 100644 index 0000000..dd6434c --- /dev/null +++ b/libs/timer_lib/timer.c @@ -0,0 +1,174 @@ +/* timer.h - Cross-platform timer library - Public Domain - 2011 Mattias Jansson / Rampant Pixels + * + * This library provides a cross-platform interface to measure + * elapsed time with (at least) millisecond accuracy. + * + * This library is put in the public domain; you can redistribute + * it and/or modify it without any restrictions. + * + */ + +#include "timer.h" + +#define TIMER_PLATFORM_WINDOWS 0 +#define TIMER_PLATFORM_APPLE 0 +#define TIMER_PLATFORM_POSIX 0 + +#if defined( _WIN32 ) || defined( _WIN64 ) +# undef TIMER_PLATFORM_WINDOWS +# define TIMER_PLATFORM_WINDOWS 1 +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +#elif defined( __APPLE__ ) +# undef TIMER_PLATFORM_APPLE +# define TIMER_PLATFORM_APPLE 1 +# include <mach/mach_time.h> +# include <string.h> +static mach_timebase_info_data_t timerlib_info; +static void absolutetime_to_nanoseconds (uint64_t mach_time, uint64_t* clock ) { *clock = mach_time * timerlib_info.numer / timerlib_info.denom; } +#else +# undef TIMER_PLATFORM_POSIX +# define TIMER_PLATFORM_POSIX 1 +# include <unistd.h> +# include <time.h> +# include <string.h> +#endif + +static tick_t timerlib_freq = 0; +static double timerlib_oofreq = 0; + + +int timer_lib_initialize( void ) +{ +#if TIMER_PLATFORM_WINDOWS + tick_t unused; + if( !QueryPerformanceFrequency( (LARGE_INTEGER*)&timerlib_freq ) || + !QueryPerformanceCounter( (LARGE_INTEGER*)&unused ) ) + return -1; +#elif TIMER_PLATFORM_APPLE + if( mach_timebase_info( &timerlib_info ) ) + return -1; + timerlib_freq = 1000000000ULL; +#elif TIMER_PLATFORM_POSIX + struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; + if( clock_gettime( CLOCK_MONOTONIC, &ts ) ) + return -1; + timerlib_freq = 1000000000ULL; +#endif + + timerlib_oofreq = 1.0 / (double)timerlib_freq; + + return 0; +} + + +void timer_lib_shutdown( void ) +{ +} + + +tick_t timer_current( void ) +{ +#if TIMER_PLATFORM_WINDOWS + + tick_t curclock; + QueryPerformanceCounter( (LARGE_INTEGER*)&curclock ); + return curclock; + +#elif TIMER_PLATFORM_APPLE + + tick_t curclock = 0; + absolutetime_to_nanoseconds( mach_absolute_time(), &curclock ); + return curclock; + +#elif TIMER_PLATFORM_POSIX + + struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; + clock_gettime( CLOCK_MONOTONIC, &ts ); + return ( (uint64_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec; + +#endif +} + + +tick_t timer_ticks_per_second( void ) +{ + return timerlib_freq; +} + + +deltatime_t timer_elapsed( const tick_t t ) +{ + return (deltatime_t)( (double)timer_elapsed_ticks( t ) * timerlib_oofreq ); +} + + +tick_t timer_elapsed_ticks( const tick_t t ) +{ + tick_t dt = 0; + +#if TIMER_PLATFORM_WINDOWS + + tick_t curclock = t; + QueryPerformanceCounter( (LARGE_INTEGER*)&curclock ); + dt = curclock - t; + +#elif TIMER_PLATFORM_APPLE + + tick_t curclock = t; + absolutetime_to_nanoseconds( mach_absolute_time(), &curclock ); + dt = curclock - t; + +#elif TIMER_PLATFORM_POSIX + + tick_t curclock; + struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; + clock_gettime( CLOCK_MONOTONIC, &ts ); + + curclock = ( (tick_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec; + dt = curclock - t; + +#endif + + return dt; +} + + +deltatime_t timer_ticks_to_seconds( const tick_t dt ) +{ + return (deltatime_t)( (double)dt * timerlib_oofreq ); +} + + +#if TIMER_PLATFORM_WINDOWS +struct __timeb64 { + __time64_t time; + unsigned short millitm; + short timezone; + short dstflag; + }; +_CRTIMP errno_t __cdecl _ftime64_s(_Out_ struct __timeb64 * _Time); +#endif + +tick_t timer_system( void ) +{ +#if TIMER_PLATFORM_WINDOWS + + struct __timeb64 tb; + _ftime64_s( &tb ); + return ( (tick_t)tb.time * 1000ULL ) + (tick_t)tb.millitm; + +#elif TIMER_PLATFORM_APPLE + + tick_t curclock = 0; + absolutetime_to_nanoseconds( mach_absolute_time(), &curclock ); + return ( curclock / 1000000ULL ); + +#elif TIMER_PLATFORM_POSIX + + struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; + clock_gettime( CLOCK_REALTIME, &ts ); + return ( (uint64_t)ts.tv_sec * 1000ULL ) + ( ts.tv_nsec / 1000000ULL ); + +#endif +} diff --git a/libs/timer_lib/timer.h b/libs/timer_lib/timer.h new file mode 100644 index 0000000..c7d8bba --- /dev/null +++ b/libs/timer_lib/timer.h @@ -0,0 +1,77 @@ +/* timer.h - Cross-platform timer library - Public Domain - 2011 Mattias Jansson / Rampant Pixels + * + * This library provides a cross-platform interface to measure + * elapsed time with (at least) millisecond accuracy. + * + * This library is put in the public domain; you can redistribute + * it and/or modify it without any restrictions. + * + */ + +#pragma once + +/*! \file timer.h + Time measurements */ + +#if TIMER_COMPILE +#define TIMER_API +#else +#if __cplusplus +#define TIMER_API extern "C" +#else +#define TIMER_API extern +#endif +#endif + +#if defined( _WIN32 ) || defined( _WIN64 ) + +//! Tick type +typedef unsigned __int64 tick_t; + +#else + +#include <stdint.h> +//! Tick type +typedef uint64_t tick_t; + +#endif + +//! Deltatime type (float or double) +//typedef float deltatime_t; +typedef double deltatime_t; + + +/*! Initialize timer library */ +TIMER_API int timer_lib_initialize( void ); + +/*! Shutdown timer library */ +TIMER_API void timer_lib_shutdown( void ); + +/*! Get current timestamp, in ticks of system-specific frequency (queryable with timer_ticks_per_second), measured from some system-specific base timestamp + and not in sync with other timestamps + \return Current timestamp */ +TIMER_API tick_t timer_current( void ); + +/*! Get elapsed time since given timestamp + \param t Timestamp + \return Number of seconds elapsed */ +TIMER_API deltatime_t timer_elapsed( const tick_t t ); + +/*! Get elapsed ticks since given timestamp + \param t Timestamp + \return Number of ticks elapsed */ +TIMER_API tick_t timer_elapsed_ticks( const tick_t t ); + +/*! Get timer frequency, as number of ticks per second + \return Ticks per second */ +TIMER_API tick_t timer_ticks_per_second( void ); + +/*! Get ticks as seconds (effectively calculating ticks/timer_ticks_per_second()) + \param dt Deltatime in ticks + \return Deltatime in seconds */ +TIMER_API deltatime_t timer_ticks_to_seconds( const tick_t dt ); + +/*! Get system time, in milliseconds since the epoch (UNIX time) + \return Current timestamp, in milliseconds */ +TIMER_API tick_t timer_system( void ); + diff --git a/libs/timer_lib/timer.sln b/libs/timer_lib/timer.sln new file mode 100644 index 0000000..0146411 --- /dev/null +++ b/libs/timer_lib/timer.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timer", "timer.vcxproj", "{321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{54E95B82-7759-4825-9478-91E76F1C1C89}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}.Debug|Win32.ActiveCfg = Debug|Win32 + {321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}.Debug|Win32.Build.0 = Debug|Win32 + {321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}.Debug|x64.ActiveCfg = Debug|x64 + {321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}.Debug|x64.Build.0 = Debug|x64 + {321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}.Release|Win32.ActiveCfg = Release|Win32 + {321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}.Release|Win32.Build.0 = Release|Win32 + {321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}.Release|x64.ActiveCfg = Release|x64 + {321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}.Release|x64.Build.0 = Release|x64 + {54E95B82-7759-4825-9478-91E76F1C1C89}.Debug|Win32.ActiveCfg = Debug|Win32 + {54E95B82-7759-4825-9478-91E76F1C1C89}.Debug|Win32.Build.0 = Debug|Win32 + {54E95B82-7759-4825-9478-91E76F1C1C89}.Debug|x64.ActiveCfg = Debug|x64 + {54E95B82-7759-4825-9478-91E76F1C1C89}.Debug|x64.Build.0 = Debug|x64 + {54E95B82-7759-4825-9478-91E76F1C1C89}.Release|Win32.ActiveCfg = Release|Win32 + {54E95B82-7759-4825-9478-91E76F1C1C89}.Release|Win32.Build.0 = Release|Win32 + {54E95B82-7759-4825-9478-91E76F1C1C89}.Release|x64.ActiveCfg = Release|x64 + {54E95B82-7759-4825-9478-91E76F1C1C89}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libs/timer_lib/timer.vcxproj b/libs/timer_lib/timer.vcxproj new file mode 100644 index 0000000..83e5ded --- /dev/null +++ b/libs/timer_lib/timer.vcxproj @@ -0,0 +1,225 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="timer.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="timer.h" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{321BAB92-2EDE-4B3B-939D-BD0BE0248C8F}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>timer</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + <TargetName>$(ProjectName)32d</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)</OutDir> + <IntDir>build\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> + <TargetName>$(ProjectName)64d</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + <TargetName>$(ProjectName)32</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)</OutDir> + <IntDir>build\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> + <TargetName>$(ProjectName)64</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>TIMER_COMPILE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAsManaged>false</CompileAsManaged> + <MultiProcessorCompilation>false</MultiProcessorCompilation> + <OmitFramePointers>false</OmitFramePointers> + <StringPooling>false</StringPooling> + <MinimalRebuild>false</MinimalRebuild> + <ExceptionHandling>false</ExceptionHandling> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <FunctionLevelLinking>false</FunctionLevelLinking> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <RuntimeTypeInfo>false</RuntimeTypeInfo> + <OpenMPSupport>false</OpenMPSupport> + <AdditionalIncludeDirectories> + </AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>TIMER_COMPILE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAsManaged>false</CompileAsManaged> + <MultiProcessorCompilation>false</MultiProcessorCompilation> + <OmitFramePointers>false</OmitFramePointers> + <StringPooling>false</StringPooling> + <MinimalRebuild>false</MinimalRebuild> + <ExceptionHandling>false</ExceptionHandling> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <FunctionLevelLinking>false</FunctionLevelLinking> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <RuntimeTypeInfo>false</RuntimeTypeInfo> + <OpenMPSupport>false</OpenMPSupport> + <AdditionalIncludeDirectories> + </AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>false</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>TIMER_COMPILE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAsManaged>false</CompileAsManaged> + <MultiProcessorCompilation>false</MultiProcessorCompilation> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>false</OmitFramePointers> + <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <RuntimeTypeInfo>false</RuntimeTypeInfo> + <OpenMPSupport>false</OpenMPSupport> + <AdditionalIncludeDirectories> + </AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>false</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>TIMER_COMPILE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAsManaged>false</CompileAsManaged> + <MultiProcessorCompilation>false</MultiProcessorCompilation> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>false</OmitFramePointers> + <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <RuntimeTypeInfo>false</RuntimeTypeInfo> + <OpenMPSupport>false</OpenMPSupport> + <AdditionalIncludeDirectories> + </AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file @@ -24,11 +24,12 @@ set LIB_SOURCES=libs\imgui-1.92.1\backends\imgui_impl_dx11.cpp^ libs\ImGuiDatePicker\*.cpp^ libs\zip\src\*.c^ libs\xml.c\src\*.c^ + libs\timer_lib\*.c^ libs\tinyfiledialogs\tinyfiledialogs.c @set SOURCES= src\*.cpp src\ui\*.cpp src\locales\*.cpp @set LIBS=opengl32.lib Advapi32.lib Shell32.lib Ole32.lib User32.lib Pathcch.lib D3D11.lib Comdlg32.lib Kernel32.lib @set FLAGS=/nologo /Ob0 /MD /Oy- /Zi /FS /W4 /EHsc /utf-8 -@set INCLUDE_DIRS=/I"libs/imgui-1.92.1" /I"libs/imgui-1.92.1/backends" /I"/" /I"libs/simclist-1.5" /I"libs/tinyfiledialogs" /I"libs/zip/src" /I"libs/xml.c/src" /I"libs/" /Iinclude +@set INCLUDE_DIRS=/I"libs/imgui-1.92.1" /I"libs/imgui-1.92.1/backends" /I"/" /I"libs/timer_lib" /I"libs/simclist-1.5" /I"libs/tinyfiledialogs" /I"libs/zip/src" /I"libs/xml.c/src" /I"libs/" /Iinclude cl %FLAGS% %INCLUDE_DIRS% %SOURCES% %LIB_SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fd%OUT_DIR%/vc140.pdb /Fo%OUT_DIR%/ /link %LIBS% if "%1"=="-r" call "%OUT_DIR%/%OUT_EXE%.exe" diff --git a/src/administration.cpp b/src/administration.cpp index bbc9a65..ab72647 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -6,6 +6,7 @@ #include <time.h> #include <stdio.h> +#include "log.hpp" #include "strops.hpp" #include "administration.hpp" #include "administration_writer.hpp" @@ -395,6 +396,8 @@ static s32 administration_create_sequence_number() // ======================= void administration_create() { + STOPWATCH_START; + g_administration.next_id = 1; g_administration.next_sequence_number = 1; @@ -412,8 +415,8 @@ void administration_create() administration_create_debug_data(); //administration_writer_save_all_async(); - income_statement* statement = (income_statement*)malloc(sizeof(income_statement)); - administration_create_income_statement(statement); + + log_add("Setup took %.3fms.", STOPWATCH_TIME); } static void administration_destroy_list(list_t *list) @@ -520,6 +523,8 @@ static void administration_debug_print_income_statement(income_statement* statem void administration_create_income_statement(income_statement* statement) { + STOPWATCH_START; + assert(statement); statement->quarter_count = 0; @@ -702,6 +707,8 @@ void administration_create_income_statement(income_statement* statement) //administration_debug_print_income_statement(statement); free(invoice_buffer); + + log_add("Created income statement in %.3fms.", STOPWATCH_TIME); } char* administration_file_path_get() diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index c97a828..6a0aba3 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -170,6 +170,8 @@ static char* administration_writer_get_eas_scheme_for_address(address addr) bool administration_writer_save_invoice_blocking(invoice inv) { + STOPWATCH_START; + bool result = 1; int buf_length = 150000; // Ballpark file content size. char* file_content = (char*)malloc(buf_length); @@ -312,8 +314,7 @@ bool administration_writer_save_invoice_blocking(invoice inv) free(file_content); - log_add(ImGui::GetTime(), "Saved file."); - + log_add("Saved invoice '%s' in %.3fms.", inv.sequential_number, STOPWATCH_TIME); return result; } @@ -339,6 +340,8 @@ static bool administration_writer_save_all_invoices_blocking() ///////////////////////////// bool administration_writer_save_project_blocking(project project) { + STOPWATCH_START; + bool result = 1; int buf_length = 0; char* file_content = administration_writer_copy_template(project_save_template, &buf_length); @@ -358,6 +361,8 @@ bool administration_writer_save_project_blocking(project project) else if (!administration_writer_write_to_zip(final_path, file_content, final_length)) result = 0; free(file_content); + + log_add("Saved project '%s' in %.3fms.", project.description, STOPWATCH_TIME); return result; } @@ -383,6 +388,8 @@ static bool administration_writer_save_all_projects_blocking() ///////////////////////////// bool administration_writer_save_cost_center_blocking(cost_center cost) { + STOPWATCH_START; + bool result = 1; int buf_length = 0; char* file_content = administration_writer_copy_template(costcenter_save_template, &buf_length); @@ -400,6 +407,8 @@ bool administration_writer_save_cost_center_blocking(cost_center cost) else if (!administration_writer_write_to_zip(final_path, file_content, final_length)) result = 0; free(file_content); + + log_add("Saved cost center '%s' in %.3fms.", cost.code, STOPWATCH_TIME); return result; } @@ -425,6 +434,8 @@ static bool administration_writer_save_all_cost_centers_blocking() ///////////////////////////// bool administration_writer_save_tax_bracket_blocking(country_tax_bracket bracket) { + STOPWATCH_START; + bool result = 1; int buf_length = 0; char* file_content = administration_writer_copy_template(taxbracket_save_template, &buf_length); @@ -443,6 +454,8 @@ bool administration_writer_save_tax_bracket_blocking(country_tax_bracket bracket else if (!administration_writer_write_to_zip(final_path, file_content, final_length)) result = 0; free(file_content); + + log_add("Saved tax bracket '%s/%.1f' in %.3fms.", bracket.country_code, bracket.rate, STOPWATCH_TIME); return result; } @@ -470,6 +483,8 @@ static bool administration_writer_save_all_tax_brackets_blocking() ///////////////////////////// bool administration_writer_save_contact_blocking(contact c) { + STOPWATCH_START; + bool result = 1; int buf_length = 0; char* file_content = administration_writer_copy_template(contact_save_template, &buf_length); @@ -497,6 +512,8 @@ bool administration_writer_save_contact_blocking(contact c) else if (!administration_writer_write_to_zip(final_path, file_content, final_length)) result = 0; free(file_content); + + log_add("Saved contact '%s' in %.3fms.", c.name, STOPWATCH_TIME); return result; } @@ -528,6 +545,8 @@ static bool administration_writer_save_all_contacts_blocking() ///////////////////////////// bool administration_writer_save_all_administration_info_blocking() { + STOPWATCH_START; + bool result = 1; int buf_length = 0; char* file_content = administration_writer_copy_template(administration_save_template, &buf_length); @@ -543,6 +562,7 @@ bool administration_writer_save_all_administration_info_blocking() free(file_content); + log_add("Saved administration info in %.3fms.", STOPWATCH_TIME); return result; } diff --git a/src/log.cpp b/src/log.cpp index 960ee85..058b594 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -1,24 +1,47 @@ #include <stdio.h> #include <stdarg.h> - +#include <time.h> +#include "timer.h" #include "log.hpp" log g_log = {0}; -void log_add(double timestamp, const char* fmt, ...) +log* get_log() +{ + return &g_log; +} + +void log_add(const char* fmt, ...) { va_list args; va_start(args, fmt); vsnprintf(g_log.history[g_log.write_cursor], MAX_LEN_LOG_TXT, fmt, args); va_end(args); + tick_t ms_since_epoch = timer_system(); + char time_buf[50]; + time_t seconds = (time_t)(ms_since_epoch / 1000); + int milliseconds = (int)(ms_since_epoch % 1000); + + // Convert to local time + struct tm tm_time; + #if defined(_WIN32) + localtime_s(&tm_time, &seconds); + #else + localtime_r(&seconds, &tm_time); + #endif + + snprintf(time_buf, 50, "%02d:%02d %02d.%03d", + tm_time.tm_hour, + tm_time.tm_min, + tm_time.tm_sec, + milliseconds); + char tmp[MAX_LEN_LOG_TXT]; - snprintf(tmp, MAX_LEN_LOG_TXT, "[%.3f] %s", timestamp, g_log.history[g_log.write_cursor]); + snprintf(tmp, MAX_LEN_LOG_TXT, "[%s] %s", time_buf, g_log.history[g_log.write_cursor]); tmp[MAX_LEN_LOG_TXT-1] = 0; memcpy(g_log.history[g_log.write_cursor], tmp, MAX_LEN_LOG_TXT); - printf(g_log.history[g_log.write_cursor]); - g_log.write_cursor++; if (g_log.write_cursor >= MAX_LEN_LOG_HISTORY) g_log.write_cursor = 0; diff --git a/src/main.cpp b/src/main.cpp index 289ca57..d579a19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,7 @@ #include "imgui_impl_dx11.h" #include <d3d11.h> #include <tchar.h> - +#include "timer.h" #include "ui.hpp" #include "administration.hpp" #include "administration_writer.hpp" @@ -89,6 +89,7 @@ int main() ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + timer_lib_initialize(); administration_writer_create(); administration_create(); @@ -148,6 +149,7 @@ int main() administration_destroy(); administration_writer_destroy(); + timer_lib_shutdown(); // Cleanup ImGui_ImplDX11_Shutdown(); diff --git a/src/ui/ui_expenses.cpp b/src/ui/ui_expenses.cpp index eb8d8c1..bb23ba9 100644 --- a/src/ui/ui_expenses.cpp +++ b/src/ui/ui_expenses.cpp @@ -438,7 +438,15 @@ static void ui_draw_expenses_list() ImGui::Separator(); if (ImGui::Button(localize("form.yes"), ImVec2(120, 0))) { - administration_invoice_remove(&selected_for_removal); + if (administration_invoice_remove(&selected_for_removal)) { + if (administration_writer_delete_entry(selected_for_removal.id)) { + ui_set_status(localize("status.saved")); + } + else { + ui_set_status_error(localize("status.saveFailed")); + } + } + ImGui::CloseCurrentPopup(); } ImGui::SameLine(); diff --git a/src/ui/ui_invoices.cpp b/src/ui/ui_invoices.cpp index fd748c8..d64147f 100644 --- a/src/ui/ui_invoices.cpp +++ b/src/ui/ui_invoices.cpp @@ -471,7 +471,14 @@ static void ui_draw_invoices_list() ImGui::Separator(); if (ImGui::Button(localize("form.yes"), ImVec2(120, 0))) { - administration_invoice_remove(&selected_for_removal); + if (administration_invoice_remove(&selected_for_removal)) { + if (administration_writer_delete_entry(selected_for_removal.id)) { + ui_set_status(localize("status.saved")); + } + else { + ui_set_status_error(localize("status.saveFailed")); + } + } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); diff --git a/src/ui/ui_log.cpp b/src/ui/ui_log.cpp new file mode 100644 index 0000000..08a0a72 --- /dev/null +++ b/src/ui/ui_log.cpp @@ -0,0 +1,20 @@ +#include <stdio.h> + +#include "ui.hpp" +#include "imgui.h" +#include "log.hpp" +#include "locales.hpp" + +void ui_draw_log() +{ + log* l = get_log(); + + for (int i = (int)l->history_length-1; i >= 0; i--) + { + u32 cursor = l->write_cursor - l->history_length + i; + if (cursor < 0) { + cursor = (l->write_cursor + i) % MAX_LEN_LOG_HISTORY; + } + ImGui::Text(l->history[cursor]); + } +}
\ No newline at end of file diff --git a/src/ui/ui_main.cpp b/src/ui/ui_main.cpp index 9ff965d..61c4784 100644 --- a/src/ui/ui_main.cpp +++ b/src/ui/ui_main.cpp @@ -12,6 +12,7 @@ typedef enum REPORT_TAX = 4, PROJECTS = 5, SETTINGS = 6, + LOG = 7, END } dashboard_view_state; @@ -25,6 +26,7 @@ void (*drawcalls[dashboard_view_state::END])(void) = { 0, ui_draw_projects, ui_draw_settings, + ui_draw_log, }; void (*setupcalls[dashboard_view_state::END])(void) = { @@ -35,6 +37,7 @@ void (*setupcalls[dashboard_view_state::END])(void) = { 0, ui_setup_projects, ui_setup_settings, + 0, }; void (*destroycalls[dashboard_view_state::END])(void) = { @@ -45,6 +48,7 @@ void (*destroycalls[dashboard_view_state::END])(void) = { 0, 0, ui_destroy_settings, + 0, }; static void set_dashboard_state(dashboard_view_state state) @@ -68,6 +72,13 @@ void ui_draw_main() ImGui::EndMenu(); } + + if (ImGui::BeginMenu("Help")) + { + if (ImGui::MenuItem("Event Log")) { set_dashboard_state(dashboard_view_state::LOG); } + + ImGui::EndMenu(); + } ImGui::EndMainMenuBar(); } |
