1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
| #ifndef _SimpleLink_h
#define _SimpleLink_h
#include <Pool.h>
#include <map>
// this template class is used for bidirectionnal linking.
// When 2 instances of two different classes link each other, each side have a SimpleLink class with both classes as template arguments (in this order : Src, Dst)
template <class T0, class T> void Nothing(T0* A,T* B) {};
template <class T0, class T>
class SimpleLink
{
protected:
T0* _Owner;
// Destination reference pool
Pool<T>* _ReferencePool;
// Main data structure : map class permit multiple links as well as simple ones
std::map<int,T*> _Data;
// Link callbacks declaration as static members
static void (*_LinkCallBack)(T0*,T*) ;
static void (*_UnlinkCallBack)(T0*,T*) ;
public:
SimpleLink(T0* Owner, Pool<T>* ReferencePool);
virtual ~SimpleLink();
void Set(int Id); // Set a link (remove former ones, add just one)
void Add(int Id); // Add a link (add one more, without coping with former ones)
void Delete(int Id=NULL); // Delete a specified link or all if NULL is passed
T* get(); // Returns the destination objet (works only for simple links)
T* operator->() { return get();}; // shortcut to get()
T* IterateValues(T* Element); // Iterators : see Pool.h for similar behaviours
int IterateKeys(int Element);
static void setLinkCallBack(void (*CallBack)(T0*,T*)) { _LinkCallBack = CallBack;};
static void setUnlinkCallBack(void (*CallBack)(T0*,T*)) { _UnlinkCallBack = CallBack;};
};
// Initialisation to default callbacks
template <class T0, class T> void (*SimpleLink<T0,T>::_LinkCallBack)(T0*,T*) = Nothing; //-> C'EST ICI QU'APPARAIT L'ERREUR
template <class T0, class T> void (*SimpleLink<T0,T>::_UnlinkCallBack)(T0*,T*) = Nothing; //-> ET ICI AUSSI
template <class T0, class T> SimpleLink<T0,T>::SimpleLink(T0* Owner, Pool<T>* ReferencePool)
{
_Owner = Owner;
_ReferencePool = ReferencePool;
}
template <class T0, class T> SimpleLink<T0,T>::~SimpleLink()
{
if (_Data.size())
{
// Should never be here, unlink macro must be called before deleting the object....
int foo=0;
}
}
template <class T0, class T> void SimpleLink<T0,T>::Set(int Id)
{
Delete();
Add(Id);
}
template <class T0, class T> void SimpleLink<T0,T>::Add(int Id)
{
T* temp = _ReferencePool->Find(Id);
_Data[Id] = temp;
(*_LinkCallBack)(_Owner,temp);
}
template <class T0, class T> void SimpleLink<T0,T>::Delete(int Id)
{
std::map<int,T*>::iterator temp;
if (Id)
{
temp = _Data.find(Id);
(*_UnlinkCallBack)(_Owner,temp->second);
_Data.erase(temp);
}
else
{
for (temp = _Data.begin(); temp != _Data.end(); temp++)
{
(*_UnlinkCallBack)(_Owner,temp->second);
}
_Data.clear();
}
}
template <class T0, class T> T* SimpleLink<T0,T>::get()
{
if (!(_Data.size()))
return NULL;
else
return _Data.begin()->second;
}
template <class T0, class T> T* SimpleLink<T0,T>::IterateValues(T* Element)
{
static std::map<int,T*>::iterator Cursor;
if (Element == NULL) // If null given, we start from the begining
{
Cursor = _Data.begin();
if (Cursor == end())
return NULL;
else
return Cursor->second;
}
else
{
if (Element == Cursor->second) // If it isn't given back next one, must find it first
{
Cursor = _Data.begin();
while ((Cursor != _Data.end()) && (Cursor->second != Element))
Cursor++;
if (Cursor == end())
return NULL;
}
if ((++Cursor) == _Data.end())
{
return NULL;
}
else
{
return Cursor->second;
}
}
}
template <class T0, class T> int SimpleLink<T0,T>::IterateKeys(int Element)
{
static std::map<int,T*>::iterator Cursor;
if (Element == 0) // If null given, we start from the begining
{
Cursor = _Data.begin();
if (Cursor == _Data.end())
return NULL;
else
return Cursor->first;
}
else
{
if (Element == Cursor->first) // If it isn't given back next one, must find it first
{
Cursor = _Data.find(Element);
if (Cursor == _Data.end())
return NULL;
}
if ((++Cursor) == _Data.end())
{
return NULL;
}
else
{
return Cursor->first;
}
}
}
#endif |