git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@236 05563f52-14a8-4384-a975-3d1654cca0fa
177 lines
4.1 KiB
C
177 lines
4.1 KiB
C
/* -----------------------------------------------------------------------------
|
|
* 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 <stdbool.h>
|
|
|
|
/* -------------------------------*
|
|
* 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;
|
|
}
|