This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
in202:seance_6:jalon_4 [2021/05/02 20:49] bmonsuez [Question n°2] |
in202:seance_6:jalon_4 [2022/11/18 10:47] (current) |
||
---|---|---|---|
Line 54: | Line 54: | ||
<code cpp> | <code cpp> | ||
- | template<int First, int... _Rest> class _ButtonEvents | + | template<int First, int... _Rest> |
class _ButtonEvents <First, _Rest...> : private _ButtonEvents <_Rest...> | class _ButtonEvents <First, _Rest...> : private _ButtonEvents <_Rest...> | ||
{ | { | ||
Line 107: | Line 107: | ||
Pour récupérer les fonctions, nous allons définir les fonctions suivantes : | Pour récupérer les fonctions, nous allons définir les fonctions suivantes : | ||
+ | <code cpp> | ||
+ | template<int First, int... _Rest> | ||
class _ButtonEvents <First, _Rest...> : private _ButtonEvents <_Rest...> | class _ButtonEvents <First, _Rest...> : private _ButtonEvents <_Rest...> | ||
{ | { | ||
Line 143: | Line 145: | ||
Pour ce faire, il suffit de définit une fonction ''SetupButton(int thePort, Button* theButton)'' comme suit : | Pour ce faire, il suffit de définit une fonction ''SetupButton(int thePort, Button* theButton)'' comme suit : | ||
+ | <code cpp> | ||
+ | template<int First, int... _Rest> | ||
class _ButtonEvents <First, _Rest...> : private _ButtonEvents <_Rest...> | class _ButtonEvents <First, _Rest...> : private _ButtonEvents <_Rest...> | ||
{ | { | ||
Line 220: | Line 224: | ||
</code> | </code> | ||
- | * Définir les méthodes ''Pressed'', ''Released'' et ''OnChanged'' de la classe ''__ButtonEvents''. Ces méthodes devront être définies après la définition de la classe ''Button''. | + | * Définir les méthodes ''Pressed'', ''Released'' et ''OnChanged'' de la classe ''_ButtonEvents''. Ces méthodes devront être définies après la définition de la classe ''Button''. |
<code cpp> | <code cpp> | ||
template<int First, int... _Rest> | template<int First, int... _Rest> | ||
- | void _ButtonEvents<First, _Rest...>::Pressed() { if(mButton != NULL) mButton->OnPressed(); } | + | void _ButtonEvents<First, _Rest...>::Pressed() |
+ | { if(mButton != NULL) mButton->OnPressed(); } | ||
template <int First, int... _Rest> | template <int First, int... _Rest> | ||
- | void _ButtonEvents<First, _Rest...>::Released() { if(mButton != NULL) mButton->OnReleased(); } | + | void _ButtonEvents<First, _Rest...>::Released() |
+ | { if(mButton != NULL) mButton->OnReleased(); } | ||
template <int First, int... _Rest> | template <int First, int... _Rest> | ||
- | void _ButtonEvents<First, _Rest...>::Changed() { if(mButton != NULL) mButton->OnChanged(); } | + | void _ButtonEvents<First, _Rest...>::Changed() |
+ | { if(mButton != NULL) mButton->OnChanged(); } | ||
</code> | </code> | ||
Line 268: | Line 275: | ||
} | } | ||
} | } | ||
+ | </code> | ||
+ | |||
+ | ===== Code correspondant à la classe Button ===== | ||
+ | |||
+ | <code cpp> | ||
+ | |||
+ | #ifndef buttonHPP | ||
+ | #define buttonHPP | ||
+ | #include"Component.hpp" | ||
+ | |||
+ | enum ButtonEvent { PRESSED = 0x1, RELEASED = 0x2 }; | ||
+ | |||
+ | typedef void (*interrupt_type)(); | ||
+ | |||
+ | class Button; | ||
+ | |||
+ | template <int... _Is> | ||
+ | class _ButtonEvents; | ||
+ | template <> | ||
+ | class _ButtonEvents<> { | ||
+ | public: | ||
+ | static interrupt_type GetPressed(int thePort) { return NULL; } | ||
+ | static interrupt_type GetReleased(int thePort) { return NULL; } | ||
+ | static interrupt_type GetChanged(int thePort) { return NULL; } | ||
+ | static void SetButton(int thePort, Button* theButton) {} | ||
+ | }; // Empty events | ||
+ | template <int First, int... _Rest> | ||
+ | class _ButtonEvents<First, _Rest...> : private _ButtonEvents<_Rest...> | ||
+ | { | ||
+ | private: | ||
+ | static const int mPortNumber = First; | ||
+ | static Button* mButton; | ||
+ | static void Pressed(); | ||
+ | static void Released(); | ||
+ | static void Changed(); | ||
+ | public: | ||
+ | static interrupt_type GetPressed(int thePort) { return thePort == mPortNumber ? Pressed : _ButtonEvents<_Rest...>::GetPressed(thePort); } | ||
+ | static interrupt_type GetReleased(int thePort) { return thePort == mPortNumber ? Released : _ButtonEvents<_Rest...>::GetReleased(thePort); } | ||
+ | static interrupt_type GetChanged(int thePort){ return thePort == mPortNumber ? Changed : _ButtonEvents<_Rest...>::GetChanged(thePort); } | ||
+ | static void SetButton(int thePort, Button* theButton); | ||
+ | }; | ||
+ | |||
+ | typedef _ButtonEvents<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13> ButtonEvents; | ||
+ | |||
+ | class Button: public Component | ||
+ | { | ||
+ | private: | ||
+ | uint32_t m_PortNumber; | ||
+ | public: | ||
+ | Button(uint32_t thePortNumber, const char* theName, bool isDebug = false): | ||
+ | m_PortNumber(thePortNumber), Component(theName, isDebug) | ||
+ | { | ||
+ | pinMode(m_PortNumber, INPUT); | ||
+ | ButtonEvents::SetButton(m_PortNumber, this); | ||
+ | } | ||
+ | void MonitorEvents(ButtonEvent anEvent) | ||
+ | { | ||
+ | if(anEvent == (PRESSED | RELEASED)) | ||
+ | attachInterrupt(digitalPinToInterrupt(m_PortNumber), | ||
+ | ButtonEvents::GetChanged(m_PortNumber), CHANGE); | ||
+ | else if(anEvent == PRESSED) | ||
+ | { | ||
+ | attachInterrupt(digitalPinToInterrupt(m_PortNumber), | ||
+ | ButtonEvents::GetPressed(m_PortNumber), RISING); | ||
+ | } | ||
+ | else if(anEvent == RELEASED) | ||
+ | attachInterrupt(digitalPinToInterrupt(m_PortNumber), | ||
+ | ButtonEvents::GetReleased(m_PortNumber), FALLING); | ||
+ | } | ||
+ | bool IsPressed() { return digitalRead(m_PortNumber) == HIGH; } | ||
+ | virtual void OnPressed() | ||
+ | { | ||
+ | if(IsDebug()) | ||
+ | Serial << name() << "Button is pressed\n"; | ||
+ | } | ||
+ | virtual void OnReleased() | ||
+ | { | ||
+ | if(IsDebug()) | ||
+ | Serial << name() << "Button is released\n"; | ||
+ | } | ||
+ | virtual void OnChanged() | ||
+ | { | ||
+ | if(IsDebug()) | ||
+ | Serial << name() << "Button state has changed\n"; | ||
+ | } | ||
+ | }; | ||
+ | template<int First, int... _Rest> | ||
+ | Button* _ButtonEvents<First, _Rest...>::mButton = NULL; | ||
+ | template<int First, int... _Rest> | ||
+ | void _ButtonEvents<First, _Rest...>::Pressed() | ||
+ | { if(mButton != NULL) mButton->OnPressed(); } | ||
+ | template <int First, int... _Rest> | ||
+ | void _ButtonEvents<First, _Rest...>::Released() | ||
+ | { if(mButton != NULL) mButton->OnReleased(); } | ||
+ | template <int First, int... _Rest> | ||
+ | void _ButtonEvents<First, _Rest...>::Changed() | ||
+ | { if(mButton != NULL) mButton->OnChanged(); } | ||
+ | |||
+ | template <int First, int... _Rest> | ||
+ | void _ButtonEvents<First, _Rest...>::SetButton(int thePort, Button* theButton) | ||
+ | { | ||
+ | if(thePort == mPortNumber) | ||
+ | mButton = theButton; | ||
+ | else | ||
+ | _ButtonEvents<_Rest...>::SetButton(thePort, theButton); | ||
+ | } | ||
+ | |||
+ | #endif | ||
+ | |||
</code> | </code> | ||