1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 1 июн. 2017 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef UI_TK_LSPTIMER_H_
23 #define UI_TK_LSPTIMER_H_
24 
25 namespace lsp
26 {
27     namespace tk
28     {
29         class LSPDisplay;
30 
31         /** Simple timer interface to launch scheduled or periodic tasks
32          *
33          */
34         class LSPTimer
35         {
36             protected:
37                 enum flags_t
38                 {
39                     TF_INFINITE     = 1 << 0,
40                     TF_LAUNCHED     = 1 << 1,
41                     TF_ERROR        = 1 << 2,
42                     TF_STOP_ON_ERR  = 1 << 3,
43                     TF_COMPLETED    = 1 << 4,
44 
45                     TF_DEFAULT      = 0
46                 };
47 
48             protected:
49                 IDisplay           *pDisplay;
50                 task_handler_t      pHandler;
51                 void               *pArguments;
52                 size_t              nRepeatInterval;
53                 ssize_t             nRepeatCount;
54                 size_t              nFlags;
55                 status_t            nErrorCode;
56                 taskid_t            nTaskID;
57 
58             protected:
59                 static  status_t    execute(timestamp_t time, void *arg);
60                 status_t            execute_task(timestamp_t time, void *arg);
61 
62                 status_t            submit_task(timestamp_t at);
63 
64             public:
65                 /** Constructor
66                  *
67                  */
68                 explicit LSPTimer();
69 
70                 /** Destructor
71                  *
72                  */
73                 virtual ~LSPTimer();
74 
75             public:
76                 /** Bind timer to the display
77                  *
78                  * @param dpy native display
79                  */
80                 void    bind(IDisplay *dpy);
81 
82                 /** Bind timer to the display
83                  *
84                  * @param dpy LSP display
85                  */
86                 void    bind(LSPDisplay *dpy);
87 
88                 /** Cancel the previous execution and start the timer
89                  *
90                  * @param count number of repeats, negative or zero value for infinite
91                  * @param interval the interval in milliseconds between repeats
92                  * @param delay the relative to the current time delay to trigger first tick, 0 if immediate
93                  * @return status of operation
94                  */
95                 status_t    launch(ssize_t count = 1, size_t interval = 1000, timestamp_t delay = 0);
96 
97                 /** Set handler, cancels previously used handler,
98                  * does not drop argument
99                  *
100                  * @param handler timer handler
101                  */
102                 void    set_handler(task_handler_t handler);
103 
104                 /** Set handler, cancels previously used handler,
105                  * overrides arguments
106                  *
107                  * @param handler timer handler
108                  * @param args argument passed to the handler
109                  */
110                 void    set_handler(task_handler_t handler, void *args);
111 
112                 /** Set argument to pass to the handler, do not cancel previously used handler
113                  *
114                  * @param args argument to pass to the handler
115                  */
116                 void    set_argument(void *args);
117 
118                 /** Cancel timer
119                  *
120                  */
121                 status_t    cancel();
122 
123                 /** Stop timer on error
124                  *
125                  */
126                 void set_stop_on_error(bool stop = true);
127 
128                 /** Get timer error handling status
129                  *
130                  * @return true if timer will be stopped on error
131                  */
get_stop_on_error()132                 inline bool get_stop_on_error() const { return nFlags & TF_STOP_ON_ERR; }
133 
134                 /** Check if there is pending error
135                  *
136                  * @return true if there is pending error
137                  */
has_error()138                 inline bool has_error() const { return nFlags & TF_ERROR; }
139 
140                 /** Check if timer has finished and will never execute more
141                  *
142                  * @return true if timer has finished
143                  */
has_finished()144                 inline bool has_finished() const { return nFlags & TF_COMPLETED; }
145 
146                 /** Clear error state and resume the timer
147                  *
148                  */
149                 status_t resume();
150 
151                 /** Get last execution error code
152                  *
153                  * @return last execution error code
154                  */
get_last_error()155                 inline status_t get_last_error() const { return nErrorCode; };
156 
157                 /** Check if timer runs in infinite repeat mode
158                  *
159                  * @return true if timer runs in infinite repeat mode
160                  */
is_infinite()161                 inline bool is_infinite() const { return nFlags & TF_INFINITE; };
162 
163                 /** Check if timer runs in finite repeat mode
164                  *
165                  * @return true if timer runs in finite repeat mode
166                  */
is_finite()167                 inline bool is_finite() const { return !(nFlags & TF_INFINITE); };
168 
169                 /** Check whether the timer is in launched state
170                  *
171                  * @return true if timer is in launched state
172                  */
is_launched()173                 inline bool is_launched() const { return nFlags & TF_LAUNCHED; }
174 
175                 /** Get number of repeats left before timer enters finished state
176                  *
177                  * @return number of repeats left, valid only for finite timers
178                  */
repeats_left()179                 inline ssize_t repeats_left() const { return nRepeatCount; }
180 
181             public:
182                 /** This method can be overridden to handle timer events,
183                  * this method will be executed even if set_handler() method was issued
184                  *
185                  * @param time time at whic the timer was executed
186                  * @param args argument passed to the handler
187                  */
188                 virtual status_t    run(timestamp_t time, void *args);
189         };
190     }
191 } /* namespace lsp */
192 
193 #endif /* UI_TK_LSPTIMER_H_ */
194