1 #pragma once
2 
3 #include "common.hpp"
4 #include "modules/meta/inotify_module.hpp"
5 
6 POLYBAR_NS
7 
8 namespace modules {
9   class battery_module : public inotify_module<battery_module> {
10    public:
11     enum class state {
12       NONE = 0,
13       CHARGING,
14       DISCHARGING,
15       FULL,
16     };
17 
18     enum class value {
19       NONE = 0,
20       ADAPTER,
21       CAPACITY,
22       CAPACITY_MAX,
23       VOLTAGE,
24       RATE,
25     };
26 
27     template <typename ReturnType>
28     struct value_reader {
29       using return_type = ReturnType;
30 
31       explicit value_reader() = default;
value_readermodules::battery_module::value_reader32       explicit value_reader(function<ReturnType()>&& fn) : m_fn(forward<decltype(fn)>(fn)) {}
33 
readmodules::battery_module::value_reader34       ReturnType read() const {
35         return m_fn();
36       }
37 
38      private:
39       const function<ReturnType()> m_fn;
40     };
41 
42     using state_reader = mutex_wrapper<value_reader<bool /* is_charging */>>;
43     using capacity_reader = mutex_wrapper<value_reader<int /* percentage */>>;
44     using rate_reader = mutex_wrapper<value_reader<unsigned long /* seconds */>>;
45     using consumption_reader = mutex_wrapper<value_reader<string /* watts */>>;
46 
47    public:
48     explicit battery_module(const bar_settings&, string);
49 
50     void start();
51     void teardown();
52     void idle();
53     bool on_event(inotify_event* event);
54     string get_format() const;
55     bool build(builder* builder, const string& tag) const;
56 
57     static constexpr auto TYPE = "internal/battery";
58 
59    protected:
60     state current_state();
61     int current_percentage();
62     int clamp_percentage(int percentage, state state) const;
63     string current_time();
64     string current_consumption();
65     void subthread();
66 
67    private:
68     static constexpr const char* FORMAT_CHARGING{"format-charging"};
69     static constexpr const char* FORMAT_DISCHARGING{"format-discharging"};
70     static constexpr const char* FORMAT_FULL{"format-full"};
71 
72     static constexpr const char* TAG_ANIMATION_CHARGING{"<animation-charging>"};
73     static constexpr const char* TAG_ANIMATION_DISCHARGING{"<animation-discharging>"};
74     static constexpr const char* TAG_BAR_CAPACITY{"<bar-capacity>"};
75     static constexpr const char* TAG_RAMP_CAPACITY{"<ramp-capacity>"};
76     static constexpr const char* TAG_LABEL_CHARGING{"<label-charging>"};
77     static constexpr const char* TAG_LABEL_DISCHARGING{"<label-discharging>"};
78     static constexpr const char* TAG_LABEL_FULL{"<label-full>"};
79 
80     static const size_t SKIP_N_UNCHANGED{3_z};
81 
82     unique_ptr<state_reader> m_state_reader;
83     unique_ptr<capacity_reader> m_capacity_reader;
84     unique_ptr<rate_reader> m_rate_reader;
85     unique_ptr<consumption_reader> m_consumption_reader;
86 
87     label_t m_label_charging;
88     label_t m_label_discharging;
89     label_t m_label_full;
90     animation_t m_animation_charging;
91     animation_t m_animation_discharging;
92     progressbar_t m_bar_capacity;
93     ramp_t m_ramp_capacity;
94 
95     string m_fstate;
96     string m_fcapnow;
97     string m_fcapfull;
98     string m_frate;
99     string m_fvoltage;
100 
101     state m_state{state::DISCHARGING};
102     int m_percentage{0};
103 
104     int m_fullat{100};
105     string m_timeformat;
106     size_t m_unchanged{SKIP_N_UNCHANGED};
107     chrono::duration<double> m_interval{};
108     chrono::system_clock::time_point m_lastpoll;
109     thread m_subthread;
110   };
111 }  // namespace modules
112 
113 POLYBAR_NS_END
114