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> | ||