diff --git a/cores/esp8266/CallBackList.h b/cores/esp8266/CallBackList.h new file mode 100644 index 0000000000..187c86c2ad --- /dev/null +++ b/cores/esp8266/CallBackList.h @@ -0,0 +1,84 @@ +#ifndef __CALLBACKLIST_H__ +#define __CALLBACKLIST_H__ + + +/* + CallBackList, An implemention for handling callback execution + + Copyright (c) 2019 Herman Reintke. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +namespace experimental +{ +namespace CBListImplentation +{ + +template +class CallBackList +{ +public: + CallBackList (){}; + + struct CallBackInfo + { + CallBackInfo(cbFunctionT f) : cbFunction(f, true){}; + CallBackInfo(cbFunctionT f, bool ar) : cbFunction(f), _allowRemove(ar) {}; + cbFunctionT cbFunction; + bool _allowRemove = true; + bool allowRemove() + { + return _allowRemove; + } + }; + using CallBackHandler = std::shared_ptr ; + std::list callBackEventList; + + CallBackHandler add(cbFunctionT af, bool ad = true) { + CallBackHandler handler = std::make_shared(CallBackInfo(af,ad)); + callBackEventList.emplace_back(handler); + return handler; + } + + void remove(CallBackHandler& dh) { + callBackEventList.remove(dh); + } + + template + void execute(Args... params) { + for(auto it = std::begin(callBackEventList); it != std::end(callBackEventList); ) { + CallBackHandler &handler = *it; + if (handler->allowRemove() && handler.unique()) { + it = callBackEventList.erase(it); + } + else { + handler->cbFunction(params...); + ++it; + } + } + } +}; + +} //CBListImplementation +}//experimental + +#endif // __CALLBACKLIST_H__ diff --git a/libraries/esp8266/examples/CallBackList/CallBackGeneric.ino b/libraries/esp8266/examples/CallBackList/CallBackGeneric.ino new file mode 100644 index 0000000000..ce4dac2470 --- /dev/null +++ b/libraries/esp8266/examples/CallBackList/CallBackGeneric.ino @@ -0,0 +1,64 @@ +#include +#include +#include "CallBackList.h" + +using namespace experimental::CBListImplentation; + +class exampleClass { + public: + exampleClass() {}; + + using exCallBack = std::function; + using exHandler = CallBackList::CallBackHandler; + + CallBackList myHandlers; + + exHandler setHandler(exCallBack cb) { + return myHandlers.add(cb); + } + + void removeHandler(exHandler hnd) { + myHandlers.remove(hnd); + } + + void trigger(int t) { + myHandlers.execute(t); + } +}; + +exampleClass myExample; + +void cb1(int in) { + Serial.printf("Callback 1, in = %d\n", in); +} + +void cb2(int in) { + Serial.printf("Callback 2, in = %d\n", in); +} + +void cb3(int in, int s) { + Serial.printf("Callback 3, in = %d, s = %d\n", in, s); +} + +Ticker tk, tk2, tk3; +exampleClass::exHandler e1 = myExample.setHandler(cb1); +exampleClass::exHandler e2 = myExample.setHandler(cb2); +exampleClass::exHandler e3 = myExample.setHandler(std::bind(cb3, std::placeholders::_1, 10)); + +void setup() { + Serial.begin(115200); + + tk.attach_ms(2000, []() { + Serial.printf("trigger %d\n", (uint32_t)millis()); + myExample.trigger(millis()); + }); + tk2.once_ms(10000, []() { + myExample.removeHandler(e2); + }); + tk3.once_ms(20000, []() { + e3.reset(); + }); +} + +void loop() { +}