diff --git a/include/drawtypes/animation.hpp b/include/drawtypes/animation.hpp index faaf9fc3..843f9729 100644 --- a/include/drawtypes/animation.hpp +++ b/include/drawtypes/animation.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "common.hpp" @@ -14,32 +15,33 @@ namespace chrono = std::chrono; namespace drawtypes { class animation : public non_copyable_mixin { public: - explicit animation(int framerate_ms) : m_framerate_ms(framerate_ms) {} + explicit animation(unsigned int framerate_ms) : m_framerate_ms(framerate_ms) {} explicit animation(vector&& frames, int framerate_ms) - : m_frames(forward(frames)) + : m_frames(move(frames)) , m_framerate_ms(framerate_ms) , m_framecount(m_frames.size()) - , m_lastupdate(chrono::system_clock::now()) {} + , m_frame(m_frames.size() - 1) {} void add(label_t&& frame); - label_t get(); - int framerate(); - operator bool(); + void increment(); + + label_t get() const; + unsigned int framerate() const; + + explicit operator bool() const; protected: - void tick(); - vector m_frames; - int m_framerate_ms = 1000; - int m_frame = 0; - int m_framecount = 0; - chrono::system_clock::time_point m_lastupdate; + + unsigned int m_framerate_ms = 1000; + size_t m_framecount = 0; + std::atomic_size_t m_frame{0_z}; }; using animation_t = shared_ptr; animation_t load_animation( const config& conf, const string& section, string name = "animation", bool required = true); -} +} // namespace drawtypes POLYBAR_NS_END diff --git a/src/drawtypes/animation.cpp b/src/drawtypes/animation.cpp index 04e9cd98..a65fafb3 100644 --- a/src/drawtypes/animation.cpp +++ b/src/drawtypes/animation.cpp @@ -8,33 +8,27 @@ namespace drawtypes { void animation::add(label_t&& frame) { m_frames.emplace_back(forward(frame)); m_framecount = m_frames.size(); + m_frame = m_framecount - 1; } - label_t animation::get() { - tick(); + label_t animation::get() const { return m_frames[m_frame]; } - int animation::framerate() { + unsigned int animation::framerate() const { return m_framerate_ms; } - animation::operator bool() { + animation::operator bool() const { return !m_frames.empty(); } - void animation::tick() { - auto now = chrono::system_clock::now(); - auto diff = chrono::duration_cast(now - m_lastupdate); + void animation::increment() { + auto tmp = m_frame.load(); + ++tmp; + tmp %= m_framecount; - if (diff.count() < m_framerate_ms) { - return; - } - if (++m_frame >= m_framecount) { - m_frame = 0; - } - - m_lastupdate = now; + m_frame = tmp; } /** @@ -64,6 +58,6 @@ namespace drawtypes { return factory_util::shared(move(vec), framerate); } -} +} // namespace drawtypes POLYBAR_NS_END diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index f2563820..36af8a80 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -345,19 +345,25 @@ namespace modules { m_log.trace("%s: Start of subthread", name()); while (running()) { - int framerate = 1000; // milliseconds + auto now = chrono::system_clock::now(); + auto framerate = 1000U; // milliseconds if (m_state == battery_module::state::CHARGING) { + m_animation_charging->increment(); broadcast(); framerate = m_animation_charging->framerate(); } else if (m_state == battery_module::state::DISCHARGING) { + m_animation_discharging->increment(); broadcast(); framerate = m_animation_discharging->framerate(); } - this_thread::sleep_for(std::chrono::milliseconds(framerate)); + + // We don't count the the first part of the loop to be as close as possible to the framerate. + now += chrono::milliseconds(framerate); + this_thread::sleep_until(now); } m_log.trace("%s: End of subthread", name()); } -} +} // namespace modules POLYBAR_NS_END diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 3c8774fe..e845dd4f 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -174,13 +174,16 @@ namespace modules { void network_module::subthread_routine() { const chrono::milliseconds framerate{m_animation_packetloss->framerate()}; - const auto dur = chrono::duration(framerate); while (running()) { + auto now = chrono::system_clock::now(); if (m_connected && m_packetloss) { + m_animation_packetloss->increment(); broadcast(); } - sleep(dur); + + now += framerate; + this_thread::sleep_until(now); } m_log.trace("%s: Reached end of network subthread", name());