#include #include // Allgemein template class GetMemFunWrapper; template class GetMemFunWrapper { public: static Ret function (Args... args, void* userData) { return (static_cast (userData)->*MemFun) (static_cast (args)...); } }; template static constexpr auto wrapMemFun = &GetMemFunWrapper< MemFun>::function; // Button-Spezifisch static constexpr std::size_t maxCallbacks = 4; class Button { public: using ClickCallback = bool (*) (int, void*); using DoubleClickCallback = int (*) (short, long, void*); Button () : numClickCallbacks (0), numDoubleClickCallbacks(0) {} void addClickCallback (ClickCallback cb, void *userData) { if (numClickCallbacks >= maxCallbacks) abort (); clickUserData [numClickCallbacks] = userData; clickCallbacks [numClickCallbacks++] = cb; } void addDoubleClickCallback (DoubleClickCallback cb, void *userData) { if (numDoubleClickCallbacks >= maxCallbacks) abort (); doubleClickUserData [numDoubleClickCallbacks] = userData; doubleClickCallbacks [numDoubleClickCallbacks++] = cb; } bool onClick (int x) { // Beispiel: Iteriere solange die Observer bis einer "true" zurück gibt for (std::size_t i = 0; i < numClickCallbacks; ++i) { if (clickCallbacks [i] (x, clickUserData [i])) return true; } return false; } int onDoubleClick (short x, long y) { // Beispiel: Summiere die Rückgabewerte der Observer int sum = 0; for (std::size_t i = 0; i < numClickCallbacks; ++i) { sum += doubleClickCallbacks [i] (x, y, doubleClickUserData [i]); } return sum; } private: ClickCallback clickCallbacks [maxCallbacks]; DoubleClickCallback doubleClickCallbacks [maxCallbacks]; void* clickUserData [maxCallbacks]; void* doubleClickUserData [maxCallbacks]; std::size_t numClickCallbacks, numDoubleClickCallbacks; }; // Screen-Spezifisch class Screen { public: Screen () { btn0.addClickCallback (wrapMemFun<&Screen::onButton0Click>, this); btn0.addDoubleClickCallback (wrapMemFun<&Screen::onButton0DoubleClick>, this); btn1.addClickCallback (wrapMemFun<&Screen::onButton1Click>, this); btn1.addDoubleClickCallback (wrapMemFun<&Screen::onButton1DoubleClick>, this); } bool onButton0Click (int x) { std::cout << "Button 0 Click(" << x << ")" << std::endl; return true; } int onButton0DoubleClick (short x, long y) { std::cout << "Button 0 DoubleClick(" << x << ", " << y << ")" << std::endl; return 0; } bool onButton1Click (int x) { std::cout << "Button 1 Click(" << x << ")" << std::endl; return true; } int onButton1DoubleClick (short x, long y) { std::cout << "Button 1 DoubleClick(" << x << ", " << y << ")" << std::endl; return 0; } Button btn0, btn1; }; int main () { Screen s; s.btn0.onClick (42); s.btn0.onDoubleClick (12, 3456); s.btn1.onClick (1); s.btn1.onDoubleClick (2, 3); }