ecere: Fix for BitmapResource objects in Menu items/Tool tips; X11: Fix for icons...
[sdk] / ecere / src / com / containers / Container.ec
1 namespace com;
2
3 import "BuiltInContainer"
4
5 default:
6
7 static void UnusedFunction()
8 {
9    int a;
10    a.OnCompare(null);
11    a.OnCopy(null);
12    a.OnGetString(null, null, null);
13    a.OnSerialize(null);
14    a.OnUnserialize(null);
15 }
16
17 extern int __ecereVMethodID_class_OnCompare;
18 extern int __ecereVMethodID_class_OnGetString;
19 extern int __ecereVMethodID_class_OnSerialize;
20 extern int __ecereVMethodID_class_OnUnserialize;
21 private:
22
23 // CAUSES PROBLEM WHEN AFTER
24 public struct Iterator<class T, class IT = int>
25 {
26    Container<T, IT> container;
27 // private:
28    IteratorPointer pointer;
29
30 public:
31    property T data
32    {
33       get { return container.GetData(pointer); }
34       set { container.SetData(pointer, value); }
35    }
36
37    bool Prev()
38    {
39       if(pointer && container)
40          pointer = container.GetPrev(pointer);
41       else if(container)
42          pointer = container.GetLast();
43       return pointer != null;
44    }
45
46    bool Next()
47    {
48       if(pointer && container)
49          pointer = container.GetNext(pointer);
50       else if(container)
51          pointer = container.GetFirst();
52       return pointer != null;
53    }
54
55    T GetData()
56    {
57       return container.GetData(pointer);
58    }
59
60    bool SetData(T value)
61    {
62       return container.SetData(pointer, value);
63    };
64
65    bool Find(T value)
66    {
67       if(container)
68       {
69          Free();
70          pointer = container.Find(value);
71       }
72       return pointer != null;
73    }
74
75    void Remove()
76    {
77       if(container)
78          container.Remove(pointer);
79       pointer = null;
80    }
81
82    void Free()
83    {
84       if(container)
85          container.FreeIterator(pointer);
86    }
87
88    bool Index(IT index, bool create)
89    {
90       if(container)
91       {
92          Free();
93          pointer = container.GetAtPosition(index, create);
94          return pointer != null;
95       }
96       return false;
97    }
98 };
99
100 public class Container<class T, class I = int, class D = T>
101 {
102 public:
103    class_fixed
104    public property Container<T> copySrc { set { Copy(value); } }
105    property Iterator<T> firstIterator { get { value = { (Container<T>)this, pointer = GetFirst() }; } }
106    property Iterator<T> lastIterator  { get { value = { (Container<T>)this, pointer = GetLast() }; } }
107
108    virtual IteratorPointer GetFirst() { return null; }
109    virtual IteratorPointer GetLast()  { return null; }
110    virtual IteratorPointer GetPrev(IteratorPointer pointer) { return null; }
111    virtual IteratorPointer GetNext(IteratorPointer pointer) { return null; }
112    virtual D GetData(IteratorPointer pointer) { return (D)0; }
113    virtual bool SetData(IteratorPointer pointer, D data);
114    virtual IteratorPointer GetAtPosition(I pos, bool create) { return null; }
115
116    virtual IteratorPointer Insert(IteratorPointer after, T value);
117    virtual IteratorPointer Add(T value);
118    virtual void Remove(IteratorPointer it);
119    virtual void Move(IteratorPointer it, IteratorPointer after);
120
121    virtual void RemoveAll()
122    {
123       IteratorPointer i, next;
124       for(i = GetFirst(), next = i ? GetNext(i) : null; i; i = next, next = i ? GetNext(i) : null)
125          Remove(i);
126    }
127
128    virtual void Copy(Container<T> source)
129    {
130       IteratorPointer i;
131       RemoveAll();
132       for(i = source.GetFirst(); i; i = source.GetNext(i))
133       {
134          D data = source.GetData(i);
135          // WARNING: This doesn't make a new copy of the elements it adds
136          Add(data);
137       }
138    }
139
140    void OnFree()
141    {
142       if(this)
143       {
144          Free();
145          delete this;
146       }
147    }
148    
149    void OnCopy(Container<T> source)
150    {
151       if(source)
152       {
153          // BUG IN this = SYNTAX
154          Container<T> container = eInstance_New(source._class);
155          // See WARNING in Copy()
156          container.Copy(source);
157          *(void **)this = container;
158       }
159       else
160       {
161          *(void **)this = null;
162       }
163    }
164
165    virtual IteratorPointer Find(D value)
166    {
167       IteratorPointer i;
168       Class Dclass = class(D);
169       if((Dclass.type == systemClass || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass))
170       {
171          for(i = GetFirst(); i; i = GetNext(i))
172          {
173             D data = GetData(i);
174             int result = ((int (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnCompare])(Dclass, &value,&data);
175             if(!result)
176                return i;
177          }
178       }
179       else
180       {
181          for(i = GetFirst(); i; i = GetNext(i))
182          {
183             D data = GetData(i);
184             int result = ((int (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnCompare])(Dclass, (void *)value, (void *)data);
185             if(!result)
186                return i;
187          }
188       }
189       return null;
190    }
191
192    virtual void FreeIterator(IteratorPointer it);
193    
194    virtual int GetCount()
195    {
196       int count = 0;
197       IteratorPointer i;
198       for(i = GetFirst(); i; i = GetNext(i)) count++;
199       return count;
200    }
201
202    virtual void Free()
203    {
204       IteratorPointer i;
205       while(i = GetFirst())
206          Delete(i);
207    }
208
209    virtual void Delete(IteratorPointer i)
210    {
211       D data = GetData(i);
212       delete data;
213       Remove(i);
214    }
215
216    char * OnGetString(char * tempString, void * fieldData, bool * needClass)
217    {
218       if(this)
219       {
220          char itemString[4096];//1024];
221          bool first = true;
222          IteratorPointer i;
223          tempString[0] = '\0';
224          for(i = GetFirst(); i; i = GetNext(i))
225          {
226             Class Dclass = class(D);
227             D data = GetData(i);
228             char * result;
229
230             itemString[0] = '\0';
231             
232             result = ((char *(*)(void *, void *, char *, void *, bool *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnGetString])(Dclass,
233                (Dclass.type == systemClass || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass) ? &data : (void *)data, itemString, null, null);
234             if(!first) strcat(tempString, ", ");
235
236             strcat(tempString, result);         
237             first = false;
238          }
239       }
240       else
241          tempString[0] = 0;
242       return tempString;
243    }
244
245    void TakeOut(D d)
246    {
247       IteratorPointer i = Find(d);
248       if(i) Remove(i);
249    }
250
251    ~Container()
252    {
253       RemoveAll();
254    }
255
256    void OnSerialize(IOChannel channel)
257    {
258       uint count = GetCount();
259       IteratorPointer i;
260       Class Dclass = class(D);
261
262       channel.Put(count);
263       for(i = GetFirst(); i; i = GetNext(i))
264       {
265          D data = GetData(i);
266          Dclass._vTbl[__ecereVMethodID_class_OnSerialize](Dclass, 
267             (Dclass.type == systemClass || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass) ? &data : (void *)data, channel);
268       }
269    }
270
271    void OnUnserialize(IOChannel channel)
272    {
273       Container container = eInstance_New(_class.fullName);
274       uint count, c;
275       Class Dclass = class(D);
276
277       channel.Get(count);
278       for(c = 0; c < count; c++)
279       {
280          D data;
281          Dclass._vTbl[__ecereVMethodID_class_OnUnserialize](Dclass, &data, channel);
282          container.Add(data);
283       }
284       this = container;
285    }
286 }