Program Listing for File managers.hpp
↰ Return to documentation for file (/tmp/ws/src/ecl_lite/ecl_sigslots_lite/include/ecl/sigslots_lite/managers.hpp
)
/*****************************************************************************
** Ifdefs
*****************************************************************************/
#ifndef ECL_SIGSLOTS_LITE_MANAGERS_HPP_
#define ECL_SIGSLOTS_LITE_MANAGERS_HPP_
/*****************************************************************************
** Includes
*****************************************************************************/
#include "slot.hpp"
/*****************************************************************************
** Namespaces
*****************************************************************************/
namespace ecl {
namespace lite {
/*****************************************************************************
** Forward Declarations
*****************************************************************************/
template <typename Data, unsigned int Capacity> class Signal;
/*****************************************************************************
** Managers
*****************************************************************************/
namespace sigslots {
template <typename Data, typename FunctionClass>
class MemberSlotsBase {
public:
virtual unsigned int stored() const { return 0; }
virtual unsigned int capacity() const { return 0; }
virtual sigslots::MemberSlot<Data,FunctionClass>* addSlot(void (FunctionClass::*func)(Data), FunctionClass &instance) = 0;
};
template <typename FunctionClass>
class MemberSlotsBase<void,FunctionClass> {
public:
virtual unsigned int stored() const { return 0; }
virtual unsigned int capacity() const { return 0; }
virtual sigslots::MemberSlot<void,FunctionClass>* addSlot(void (FunctionClass::*func)(), FunctionClass &instance) = 0;
};
} // namespace sigslots
/******************************************
** Member Manager
*******************************************/
template <typename Data, typename FunctionClass, unsigned int Capacity = 1>
class MemberSlots : public sigslots::MemberSlotsBase<Data,FunctionClass> {
public:
/*********************
** Friends
**********************/
// allow connect to use addSlot
template <typename Data_, unsigned int Capacity_, typename FunctionClass_>
friend sigslots::Error connect(Signal<Data_,Capacity_> &signal, void(FunctionClass_::*f)(Data_), FunctionClass_ &o);
// needs access to stored()
template <typename Data_, typename FunctionClass_>
friend unsigned int member_slots_stored(const FunctionClass_ &object);
// needs access to capacity()
template <typename Data_, typename FunctionClass_>
friend unsigned int member_slots_capacity(const FunctionClass_ &object);
protected:
MemberSlots() : size(0) {};
private:
unsigned int stored() const { return size; }
unsigned int capacity() const { return Capacity; }
sigslots::MemberSlot<Data,FunctionClass>* addSlot(void (FunctionClass::*func)(Data), FunctionClass &instance) {
for ( unsigned int i = 0; i < size; ++i ) {
if ( func == slots[i].member_function ) {
return &(slots[i]);
}
}
if ( size < Capacity ) {
slots[size] = sigslots::MemberSlot<Data,FunctionClass>(func,instance);
++size;
return &(slots[size-1]);
} else {
return NULL;
}
}
unsigned int size;
sigslots::MemberSlot<Data,FunctionClass> slots[Capacity];
};
/******************************************
** Global Manager
*******************************************/
template <typename Data, typename Dummy = int>
class GlobalSlots {
public:
static const unsigned int capacity;
/*********************
** Friends
**********************/
// needs access to addSlot()
template <typename Data_, unsigned int Capacity_>
friend sigslots::Error connect(Signal<Data_, Capacity_> &signal, void (*function)(Data_));
// needs access to stored()
template <typename Data_>
friend unsigned int global_slots_stored();
private:
static unsigned int stored(const bool increment = false) {
static unsigned int stored_slots = 0;
if ( increment ) { ++stored_slots; }
return stored_slots;
}
static sigslots::GlobalSlot<Data>* addSlot(void (*func)(Data)) {
unsigned int size = stored();
static sigslots::GlobalSlot<Data> slots[capacity];
for ( unsigned int i = 0; i < size; ++i ) {
if ( func == slots[i].global_function ) {
return &(slots[i]);
}
}
if ( size < capacity ) {
slots[size] = sigslots::GlobalSlot<Data>(func);
bool inc = true;
stored(inc); // increment the number of stored slots variable
return &(slots[size]);
} else {
return NULL;
}
}
};
/*****************************************************************************
** Specialisations
*****************************************************************************/
template <typename FunctionClass, unsigned int Capacity>
class MemberSlots<void, FunctionClass, Capacity> : public sigslots::MemberSlotsBase<void,FunctionClass> {
public:
/*********************
** Friends
**********************/
// allow connect to use addSlot
template <unsigned int Capacity_, typename FunctionClass_>
friend sigslots::Error connect(Signal<void,Capacity_> &signal, void(FunctionClass_::*f)(void), FunctionClass_ &o);
// needs access to stored()
template <typename Data_, typename FunctionClass_>
friend unsigned int member_slots_stored(const FunctionClass_ &object);
// needs access to capacity()
template <typename Data_, typename FunctionClass_>
friend unsigned int member_slots_capacity(const FunctionClass_ &object);
protected:
MemberSlots() : size(0) {};
private:
unsigned int stored() const { return size; }
unsigned int capacity() const { return Capacity; }
sigslots::MemberSlot<void,FunctionClass>* addSlot(void (FunctionClass::*func)(void), FunctionClass &instance) {
for ( unsigned int i = 0; i < size; ++i ) {
if ( func == slots[i].member_function ) {
return &(slots[i]);
}
}
if ( size < Capacity ) {
slots[size] = sigslots::MemberSlot<void,FunctionClass>(func,instance);
++size;
return &(slots[size-1]);
} else {
return NULL;
}
}
unsigned int size;
sigslots::MemberSlot<void,FunctionClass> slots[Capacity];
};
template <typename Dummy>
class GlobalSlots<void, Dummy> {
public:
static const unsigned int capacity;
/*********************
** Friends
**********************/
// needs access to addSlot()
template <unsigned int Capacity_>
friend sigslots::Error connect(Signal<void,Capacity_> &signal, void (*function)(void));
// needs access to stored()
template <typename Data> friend unsigned int global_slots_stored();
private:
static unsigned int stored(const bool increment = false) {
static unsigned int stored_slots = 0;
if ( increment ) { ++stored_slots; }
return stored_slots;
}
static sigslots::GlobalSlot<void>* addSlot(void (*func)(void)) {
unsigned int size = stored();
static sigslots::GlobalSlot<void> slots[capacity];
for ( unsigned int i = 0; i < size; ++i ) {
if ( func == slots[i].global_function ) {
return &(slots[i]);
}
}
if ( size < capacity ) {
slots[size] = sigslots::GlobalSlot<void>(func);
bool inc = true;
stored(inc); // increment the number of stored slots variable
return &(slots[size]);
} else {
return NULL;
}
}
};
} // namespace lite
} // namespace ecl
#endif /* ECL_SIGSLOTS_LITE_MANAGERS_HPP_ */