5ffdd75a2aeda2a71ca5ef44ec4763272296086c
[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          this = container;
159       }
160       else
161       {
162          this = null;
163       }
164    }
165
166    virtual IteratorPointer Find(D value)
167    {
168       IteratorPointer i;
169       Class Dclass = class(D);
170       if((Dclass.type == systemClass || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass))
171       {
172          for(i = GetFirst(); i; i = GetNext(i))
173          {
174             D data = GetData(i);
175             int result = ((int (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnCompare])(Dclass, &value,&data);
176             if(!result)
177                return i;
178          }
179       }
180       else
181       {
182          for(i = GetFirst(); i; i = GetNext(i))
183          {
184             D data = GetData(i);
185             int result = ((int (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnCompare])(Dclass, (void *)value, (void *)data);
186             if(!result)
187                return i;
188          }
189       }
190       return null;
191    }
192
193    virtual void FreeIterator(IteratorPointer it);
194    
195    virtual int GetCount()
196    {
197       int count = 0;
198       IteratorPointer i;
199       for(i = GetFirst(); i; i = GetNext(i)) count++;
200       return count;
201    }
202
203    virtual void Free()
204    {
205       IteratorPointer i;
206       while(i = GetFirst())
207          Delete(i);
208    }
209
210    virtual void Delete(IteratorPointer i)
211    {
212       D data = GetData(i);
213       delete data;
214       Remove(i);
215    }
216
217    char * OnGetString(char * tempString, void * fieldData, bool * needClass)
218    {
219       if(this)
220       {
221          char itemString[4096];//1024];
222          bool first = true;
223          IteratorPointer i;
224          tempString[0] = '\0';
225          for(i = GetFirst(); i; i = GetNext(i))
226          {
227             Class Dclass = class(D);
228             D data = GetData(i);
229             char * result;
230
231             itemString[0] = '\0';
232             
233             result = ((char *(*)(void *, void *, char *, void *, bool *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnGetString])(Dclass,
234                (Dclass.type == systemClass || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass) ? &data : (void *)data, itemString, null, null);
235             if(!first) strcat(tempString, ", ");
236
237             strcat(tempString, result);         
238             first = false;
239          }
240       }
241       else
242          tempString[0] = 0;
243       return tempString;
244    }
245
246    void TakeOut(D d)
247    {
248       IteratorPointer i = Find(d);
249       if(i) Remove(i);
250    }
251
252    ~Container()
253    {
254       RemoveAll();
255    }
256
257    void OnSerialize(IOChannel channel)
258    {
259       uint count = GetCount();
260       IteratorPointer i;
261       Class Dclass = class(D);
262
263       channel.Put(count);
264       for(i = GetFirst(); i; i = GetNext(i))
265       {
266          D data = GetData(i);
267          ((void (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnSerialize])(Dclass, 
268             (Dclass.type == systemClass || Dclass.type == bitClass || Dclass.type == enumClass || Dclass.type == unitClass) ? &data : (void *)data, channel);
269       }
270    }
271
272    void OnUnserialize(IOChannel channel)
273    {
274       Container container = eInstance_New(_class.fullName);
275       uint count, c;
276       Class Dclass = class(D);
277       D data;
278
279       channel.Get(count);
280       if(Dclass.type == structClass)
281          data = (D)(new byte[Dclass.structSize]);
282       for(c = 0; c < count; c++)
283       {
284          ((void (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnUnserialize])
285             (Dclass, (Dclass.type == structClass) ? (void *)data : &data, channel);
286          container.Add(data);
287       }
288       if(Dclass.type == structClass)
289          delete data;
290       this = container;
291    }
292 }