mbed library sources. Supersedes mbed-src.
Fork of mbed-dev by
Diff: common/CallChain.cpp
- Revision:
- 144:ef7eb2e8f9f7
- Parent:
- 0:9b334a45a8ff
--- a/common/CallChain.cpp Tue Aug 02 14:07:36 2016 +0000 +++ b/common/CallChain.cpp Fri Sep 02 15:07:44 2016 +0100 @@ -1,90 +1,116 @@ -#include "CallChain.h" -#include "cmsis.h" - -namespace mbed { - -CallChain::CallChain(int size) : _chain(), _size(size), _elements(0) { - _chain = new pFunctionPointer_t[size](); -} - -CallChain::~CallChain() { - clear(); - delete _chain; -} - -pFunctionPointer_t CallChain::add(void (*function)(void)) { - return common_add(new FunctionPointer(function)); -} - -pFunctionPointer_t CallChain::add_front(void (*function)(void)) { - return common_add_front(new FunctionPointer(function)); -} - -int CallChain::size() const { - return _elements; -} - -pFunctionPointer_t CallChain::get(int i) const { - if (i < 0 || i >= _elements) - return NULL; - return _chain[i]; -} - -int CallChain::find(pFunctionPointer_t f) const { - for (int i = 0; i < _elements; i++) - if (f == _chain[i]) - return i; - return -1; -} - -void CallChain::clear() { - for(int i = 0; i < _elements; i ++) { - delete _chain[i]; - _chain[i] = NULL; - } - _elements = 0; -} - -bool CallChain::remove(pFunctionPointer_t f) { - int i; - - if ((i = find(f)) == -1) - return false; - if (i != _elements - 1) - memmove(_chain + i, _chain + i + 1, (_elements - i - 1) * sizeof(pFunctionPointer_t)); - delete f; - _elements --; - return true; -} - -void CallChain::call() { - for(int i = 0; i < _elements; i++) - _chain[i]->call(); -} - -void CallChain::_check_size() { - if (_elements < _size) - return; - _size = (_size < 4) ? 4 : _size + 4; - pFunctionPointer_t* new_chain = new pFunctionPointer_t[_size](); - memcpy(new_chain, _chain, _elements * sizeof(pFunctionPointer_t)); - delete _chain; - _chain = new_chain; -} - -pFunctionPointer_t CallChain::common_add(pFunctionPointer_t pf) { - _check_size(); - _chain[_elements] = pf; - _elements ++; - return pf; -} - -pFunctionPointer_t CallChain::common_add_front(pFunctionPointer_t pf) { - _check_size(); - memmove(_chain + 1, _chain, _elements * sizeof(pFunctionPointer_t)); - _chain[0] = pf; - _elements ++; - return pf; -} - -} // namespace mbed +#include "CallChain.h" +#include "cmsis.h" +#include "critical.h" + +namespace mbed { + +class CallChainLink { +public: + CallChainLink(): cb(), next(NULL) { + // No work to do + } + + CallChainLink(Callback<void()> &callback): cb(callback), next(NULL) { + // No work to do + } + Callback<void()> cb; + CallChainLink * next; +}; + +CallChain::CallChain(int size) : _chain(NULL) { + // No work to do +} + +CallChain::~CallChain() { + clear(); +} + +pFunctionPointer_t CallChain::add(Callback<void()> func) { + CallChainLink *new_link = new CallChainLink(func); + if (NULL == _chain) { + _chain = new_link; + return &new_link->cb; + } + + CallChainLink *link = _chain; + while (true) { + if (NULL == link->next) { + link->next = new_link; + return &new_link->cb; + } + link = link->next; + } +} + +pFunctionPointer_t CallChain::add_front(Callback<void()> func) { + CallChainLink *link = new CallChainLink(func); + link->next = _chain; + _chain = link->next; + return &link->cb; +} + +int CallChain::size() const { + CallChainLink *link = _chain; + int elements = 0; + while (link != NULL) { + elements++; + link = link->next; + } + return elements; +} + +pFunctionPointer_t CallChain::get(int idx) const { + CallChainLink *link = _chain; + for (int i = 0; i < idx; i++) { + if (NULL == link) { + break; + } + link = link->next; + } + return &link->cb; +} + +int CallChain::find(pFunctionPointer_t f) const { + CallChainLink *link = _chain; + int i = 0; + while (link != NULL) { + if (f == &link->cb) { + return i; + } + i++; + link = link->next; + } + return -1; +} + +void CallChain::clear() { + CallChainLink *link = _chain; + _chain = NULL; + while (link != NULL) { + CallChainLink *temp = link->next; + delete link; + link = temp; + } +} + +bool CallChain::remove(pFunctionPointer_t f) { + CallChainLink *link = _chain; + while (link != NULL) { + if (f == &link->cb) { + delete link; + return true; + } + link = link->next; + } + return false; +} + +void CallChain::call() { + CallChainLink *link = _chain; + while (link != NULL) { + link->cb.call(); + link = link->next; + } +} + +} // namespace mbed