-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathpin.hpp
More file actions
127 lines (97 loc) · 3.57 KB
/
pin.hpp
File metadata and controls
127 lines (97 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017 Dimitry Ishenko
// Contact: dimitry (dot) ishenko (at) (gee) mail (dot) com
//
// Distributed under the GNU GPL license. See the LICENSE.md file for details.
////////////////////////////////////////////////////////////////////////////////
#ifndef FIRMATA_PIN_HPP
#define FIRMATA_PIN_HPP
////////////////////////////////////////////////////////////////////////////////
#include "firmata/call_chain.hpp"
#include "firmata/types.hpp"
#include <map>
#include <set>
#include <utility>
////////////////////////////////////////////////////////////////////////////////
namespace firmata
{
////////////////////////////////////////////////////////////////////////////////
// Firmata pin
//
class pin
{
public:
////////////////////
pin() noexcept = default;
pin(const pin&) = delete;
pin(pin&& rhs) noexcept { swap(rhs); }
pin& operator=(const pin&) = delete;
pin& operator=(pin&& rhs) noexcept { swap(rhs); return *this; }
void swap(pin&) noexcept;
////////////////////
bool valid() const noexcept { return pos_ != npos; }
explicit operator bool() const noexcept { return valid(); }
////////////////////
// pin position (number)
auto pos() const noexcept { return pos_; }
// analong position
auto analog() const noexcept { return analog_; }
// supported modes
auto const& modes() const noexcept { return modes_; }
bool supports(firmata::mode mode) const noexcept { return modes_.count(mode); }
// current mode
auto mode() const noexcept { return mode_; }
// set new mode
void mode(firmata::mode);
// current mode res (in bits)
auto res() const noexcept { return reses_.at(mode_); }
// current value
auto value() const noexcept { return value_; }
// set new value
void value(int);
// current state
auto state() const noexcept { return state_; }
////////////////////
using int_call = call<void(int)>;
using void_call = call<void()>;
// install state changed/low/high callback
cid on_state_changed(int_call);
cid on_state_low(void_call);
cid on_state_high(void_call);
// remove callback
bool remove_call(cid);
private:
////////////////////
firmata::pos pos_ = npos, analog_ = npos;
std::set<firmata::mode> modes_;
std::map<firmata::mode, firmata::res> reses_; // res (bits) for each mode
firmata::mode mode_; // current mode
int value_ = 0; // current value
int state_ = 0; // current state
// state changed/low/high call chains
call_chain< int_call> changed_ { 0 };
call_chain<void_call> low_ { 1 };
call_chain<void_call> high_ { 2 };
// set new state
void state(int);
////////////////////
// delegate for setting new mode/value
struct delegate
{
call<void(firmata::pos, bool)> report_digital;
call<void(firmata::pos, bool)> report_analog;
call<void(firmata::pos, bool)> digital_value;
call<void(firmata::pos, int)> analog_value;
call<void(firmata::pos, firmata::mode)> pin_mode;
};
delegate* delegate_ = nullptr;
////////////////////
pin(firmata::pos pos, delegate* del) : pos_(pos), delegate_(del) { }
friend class client;
};
////////////////////////////////////////////////////////////////////////////////
inline void swap(pin& lhs, pin& rhs) noexcept { lhs.swap(rhs); }
////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
#endif