#pragma once
#include<cstdint>
#include<chrono>
#include<algorithm>#include"internal/dev_env.hpp"namespaceuni{structtimer{usingtime_point=std::chrono::milliseconds::rep;usingprogress_type=longdouble;private:time_point_time_limit=0;progress_typeprogress_duration=0;std::chrono::system_clock::time_pointclock_start,clock_end;public:timer()noexcept=default;explicittimer(consttime_pointtime_limit)noexcept(NO_EXCEPT){this->reset(time_limit);}inlinetime_pointlimit()noexcept(NO_EXCEPT){returnthis->_time_limit;}inlinetimer&reset()noexcept(NO_EXCEPT){this->clock_start=std::chrono::system_clock::now();this->clock_end=clock_start+std::chrono::milliseconds(this->_time_limit);return*this;}inlinetimer&reset(consttime_pointtime_limit)noexcept(NO_EXCEPT){this->_time_limit=time_limit;this->progress_duration=static_cast<progress_type>(std::chrono::duration_cast<std::chrono::system_clock::duration>(std::chrono::milliseconds(time_limit)).count());returnthis->reset();}inlinetime_pointelapsed()constnoexcept(NO_EXCEPT){returnstd::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()-this->clock_start).count();}inlinetime_pointremaining()constnoexcept(NO_EXCEPT){return_time_limit-this->elapsed();}inlineboolexpired()constnoexcept(NO_EXCEPT){returnthis->elapsed()>=_time_limit;}inlineprogress_typeprogress()constnoexcept(NO_EXCEPT){returnstd::clamp<progress_type>((std::chrono::system_clock::now()-this->clock_start).count()/this->progress_duration,0,1);}};}// namespace uni