Libmacro  0.2
Libmacro is an extensible macro and hotkey library.
macro.h
Go to the documentation of this file.
1 /* Libmacro - A multi-platform, extendable macro and hotkey C library
2  Copyright (C) 2013 Jonathan Pelletier, New Paradigm Software
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
22 #ifndef MCR_EXTRAS_MACRO_H_
23 #define MCR_EXTRAS_MACRO_H_
24 
25 #include "mcr/extras/wrappers.h"
26 
27 namespace mcr
28 {
30 class MacroPrivate;
38 class MCR_API Macro
39 {
40  friend class MacroPrivate;
41 public:
43  enum Interrupt {
45  CONTINUE = 0,
55  DISABLE
56  };
57 
58  static inline bool receive(struct mcr_DispatchReceiver *dispPt,
59  struct mcr_Signal *, unsigned int)
60  {
61  mcr_throwif(!dispPt || !dispPt->receiver, EFAULT);
62  return reference<Macro>(dispPt->receiver)();
63  }
64  static inline bool trigger(struct mcr_Trigger *trigPt, struct mcr_Signal *,
65  unsigned int)
66  {
67  mcr_throwif(!trigPt || !trigPt->actor, EFAULT);
68  return reference<Macro>(trigPt->actor)();
69  }
70 
71  Macro(Libmacro *context = nullptr, bool blocking = false,
72  bool sticky = false, unsigned int threadMax = 1,
73  bool enable = false);
74  Macro(const Macro &copytron);
75  virtual ~Macro();
76  inline Macro &operator =(const Macro &copytron)
77  {
78  copy(copytron);
79  return *this;
80  }
81 
82  inline bool operator()()
83  {
84  start();
85  return blocking();
86  }
87 
88  /* Properties changed */
89  typedef void (*propertyChanged)(void *);
90 
91  void *propertyReceiver = nullptr;
92  propertyChanged blockingChanged = nullptr;
93  propertyChanged enabledChanged = nullptr;
94  propertyChanged interruptorChanged = nullptr;
95  propertyChanged nameChanged = nullptr;
96  propertyChanged stickyChanged = nullptr;
97  propertyChanged threadMaxChanged = nullptr;
98  /* arrays */
99  propertyChanged activatorsChanged = nullptr;
100  propertyChanged signalsChanged = nullptr;
101  propertyChanged triggersChanged = nullptr;
102  /* read-only */
103  propertyChanged threadCountChanged = nullptr;
104  propertyChanged queuedChanged = nullptr;
105 
106  inline void callProperty(propertyChanged propertyFn)
107  {
108  // safety
109  if (_threadMax > MCR_THREAD_MAX)
110  _threadMax = MCR_THREAD_MAX;
111  mcr_throwif(_threadCount > MCR_THREAD_MAX, -1);
112  if (_queued > _threadMax)
113  _queued = 0;
114  if (propertyFn)
115  propertyFn(propertyReceiver);
116  }
117  virtual inline void objectChanged()
118  {
119  /* When everything is changed always notify lists and read-only
120  * properties */
121  callProperty(activatorsChanged);
122  callProperty(signalsChanged);
123  callProperty(triggersChanged);
124  callProperty(threadCountChanged);
125  callProperty(queuedChanged);
126  }
127 
128  inline Libmacro &context() const
129  {
130  return *_context;
131  }
132 
133  inline bool blocking() const
134  {
135  return _blocking;
136  }
137  void setBlocking(bool val);
138 
139  inline bool enabled() const
140  {
141  return _interruptor != DISABLE;
142  }
143  void setEnabled(bool val)
144  {
145  setInterruptor(val ? CONTINUE : DISABLE);
146  }
147 
148  inline Interrupt interruptor() const
149  {
150  return _interruptor;
151  }
152  void setInterruptor(Interrupt val);
153 
154  const char *name() const;
155  void setName(const char *val);
156 
157  inline bool sticky() const
158  {
159  return _sticky;
160  }
161  void setSticky(bool val);
162 
163  inline unsigned int threadMax() const
164  {
165  return _threadMax;
166  }
167  void setThreadMax(unsigned int val);
168 
169  void setActivators(const Signal *array, size_t count);
171  template<class T>
172  inline void setActivators(const T &vals)
173  {
174  setActivators(&vals.front(), vals.size());
175  }
176  inline void clearActivators()
177  {
178  setActivators(NULL, 0);
179  }
180 
182  void setSignals(const Signal *array, size_t count);
184  template<class T>
185  inline void setSignals(const T &vals)
186  {
187  setSignals(&vals.front(), vals.size());
188  }
189  inline void clearSignals()
190  {
191  setSignals(NULL, 0);
192  }
193 
194  void setTriggers(const Trigger *array, size_t count);
196  template<class T>
197  inline void setTriggers(const T &vals)
198  {
199  setTriggers(&vals.front(), vals.size());
200  }
201  inline void clearTriggers()
202  {
203  setTriggers(NULL, 0);
204  }
205 
206  /* Read-only */
207  inline int threadCount() const
208  {
209  return _threadCount;
210  }
211  inline unsigned queued() const
212  {
213  return _queued;
214  }
215 
216  inline void clearAll()
217  {
218  clearActivators();
219  clearSignals();
220  clearTriggers();
221  }
222 
224  virtual void start();
226  virtual void run();
227  inline bool running()
228  {
229  return _threadCount;
230  }
231  virtual void copy(const Macro &copytron);
232 
233  inline void triggerMe(mcr_Trigger *trigPt)
234  {
235  mcr_throwif(!trigPt, EFAULT);
236  triggerMe(*trigPt);
237  }
238  inline void triggerMe(mcr_Trigger &trigger)
239  {
240  trigger.actor = this;
241  trigger.trigger = Macro::trigger;
242  }
243 
245  void applyDispatch();
250  void addDispatch();
252  void removeDispatch();
253  // Maybe needs to be private
255  void addDispatch(Signal &sigPt);
257  void addDispatch(Trigger &trigPt);
259  void addDispatch(Signal &sigPt, Trigger &trigPt);
260 
261 protected:
262  inline unsigned int decQueued()
263  {
264  if (_queued > 0) {
265  --_queued;
266  callProperty(queuedChanged);
267  }
268  return _queued;
269  }
270  inline unsigned int incQueued()
271  {
272  if (_queued < _threadMax) {
273  ++_queued;
274  callProperty(queuedChanged);
275  }
276  return _queued;
277  }
278  // \todo threadMax, interruptor, and enabled changed property
280  inline void dequeue(Interrupt val)
281  {
282  _queued = 0;
283  _interruptor = val;
284  }
286  inline void limitMaxThreads()
287  {
288  if (!_threadMax) {
289  _threadMax = 1;
290  } else if (_threadMax > MCR_THREAD_MAX) {
291  _threadMax = MCR_THREAD_MAX;
292  }
293  }
294 
297  int waitThreadsChanged();
299  void notifyThreadsChanged();
300 
301 private:
302  Libmacro *_context;
303 
304  bool _blocking;
305  Interrupt _interruptor;
306  bool _sticky;
307  unsigned int _threadCount;
308  unsigned int _threadMax;
309  unsigned int _queued;
310  /* non-export */
311  MacroPrivate *_private;
312 
314  void ctor(bool blocking = false, bool sticky = false, unsigned int threadMax = 1);
315 
316  void disableEverything();
324  void clearThreads(Interrupt clearType, bool stickyInterrupt);
325 
327  void resetThread();
328  inline void onCanPause()
329  {
330  if (interruptor() == PAUSE)
331  pauseLoop();
332  }
335  void pauseLoop();
336  void onRunComplete();
337 };
338 }
339 #endif
#define mcr_throwif(condition, errorNumber)
Definition: defines.h:415
Interrupt
Definition: macro.h:43
void dequeue(Interrupt val)
Definition: macro.h:280
void setSignals(const T &vals)
Definition: macro.h:185
#define ctor
Definition: defines.h:85
void setTriggers(const T &vals)
Definition: macro.h:197
void limitMaxThreads()
Definition: macro.h:286
mcr_Trigger_receive_fnc trigger
Definition: trigger.h:49
void * receiver
Definition: types.h:64
void * actor
Definition: trigger.h:51
C++ wrappers and extensions of C types.
Libmacro, by Jonathan Pelletier, New Paradigm Software. Alpha version.
Definition: classes.h:31
#define MCR_THREAD_MAX
Definition: defines.h:387
void setActivators(const T &vals)
Definition: macro.h:172