/* ----------------------------------------------------------------------------- * Observable.c (c) 2013 Micro-Key bv * ----------------------------------------------------------------------------- * Micro-Key bv * Industrieweg 28, 9804 TG Noordhorn * Postbus 92, 9800 AB Zuidhorn * The Netherlands * Tel: +31 594 503020 * Fax: +31 594 505825 * Email: support@microkey.nl * Web: www.microkey.nl * ----------------------------------------------------------------------------- * Description: Observer design pattern * ----------------------------------------------------------------------------- * $Id$ * ----------------------------------------------------------------------------- */ /* --------------* * Include files * * --------------* */ #define CLASS_INTERNAL_INCLUDE #include "Observable.h" #include "Logger.h" #include /* -------------------------------* * Constant and macro definitions * * -------------------------------* */ #define OBSERVER_NOT_FOUND (-1) /* ----------------------* * Function declarations * * ----------------------* */ // Searches for the specified observer in the observer list and returns the index on self->observers[] if found. // If not found, the index returned is OBSERVER_NOT_FOUND. static int indexOfObserverInList(const struct Observable* self, const Observer observer); /* ---------------------* * Function definitions * * ---------------------* */ void Observable_initialize(struct Observable* self) { Observable_deleteObservers(self); } void Observable_terminate(struct Observable* self) { Observable_deleteObservers(self); } ErrorStatus Observable_addObserver(struct Observable* self, const Observer observer) { ErrorStatus errorStatus = SUCCESS; // Only add Observer if it hasn't been added before if(indexOfObserverInList(self, observer) == OBSERVER_NOT_FOUND) { if(self->nrOfObservers < (int)sizeof(self->observers) / (int)sizeof(self->observers[0])) { self->observers[self->nrOfObservers] = observer; ++self->nrOfObservers; } else { LOGGER_ERROR("No space left to store a new observer"); errorStatus = ERROR; } } return errorStatus; } ErrorStatus Observable_addObserverAtFront(struct Observable* self, const Observer observer) { ErrorStatus errorStatus = SUCCESS; int observerIndex; // Search for this Observer in the list observerIndex = indexOfObserverInList(self, observer); // Only add Observer if it hasn't been added before if(observerIndex == OBSERVER_NOT_FOUND) { if(self->nrOfObservers < (int)sizeof(self->observers) / (int)sizeof(self->observers[0])) { // Move all entries one down int i; for(i = self->nrOfObservers - 1; i >= 0; --i) { self->observers[i + 1] = self->observers[i]; } self->observers[0] = observer; ++self->nrOfObservers; } else { LOGGER_ERROR("No space left to store a new observer"); errorStatus = ERROR; } } return errorStatus; } ErrorStatus Observable_notifyObservers(const struct Observable* self, const void* const data) { ErrorStatus errorStatus = SUCCESS; int i; for(i = 0; i < self->nrOfObservers; ++i) { errorStatus &= self->observers[i](data); } return errorStatus; } void Observable_deleteObserver(struct Observable* self, const Observer observer) { int observerIndex; // Search for this Observer in the list observerIndex = indexOfObserverInList(self, observer); // If found, move all remaining entries one up if(observerIndex != OBSERVER_NOT_FOUND) { int i; for(i = observerIndex; i < self->nrOfObservers - 1; ++i) { self->observers[i] = self->observers[i + 1]; } --self->nrOfObservers; } } void Observable_deleteObservers(struct Observable* self) { self->nrOfObservers = 0; } int Observable_nrOfObservers(struct Observable* self) { return self->nrOfObservers; } static int indexOfObserverInList(const struct Observable* self, const Observer observer) { int observerIndex = OBSERVER_NOT_FOUND; int i; // Search for this Observer in the list for(i = 0; i < self->nrOfObservers; ++i) { if(self->observers[i] == observer) { observerIndex = i; break; } } return observerIndex; }