1 | // This file is a part of the Framsticks GDK library.
|
---|
2 | // Copyright (C) 2002-2011 Szymon Ulatowski. See LICENSE.txt for details.
|
---|
3 | // Refer to http://www.framsticks.com/ for further information.
|
---|
4 |
|
---|
5 | #include "collectionobj.h"
|
---|
6 | #include <math.h> //sqrt in borland
|
---|
7 | #include "stderrors.h"
|
---|
8 |
|
---|
9 | #define FIELDSTRUCT VectorObject
|
---|
10 | ParamEntry vector_paramtab[]=
|
---|
11 | {
|
---|
12 | {"Vector",1,11,"Vector","Vector is 1-dimensional array, indexed by integer value (starting from 0). "
|
---|
13 | "Multidimensional arrays can be simulated by putting other Vector objects into the Vector.\n"
|
---|
14 | "Example:\nvar v=Vector.new();\nv.add(123); v.add(\"string\");",},
|
---|
15 | {"clear",0,PARAM_NOSTATIC,"clear data","p()",PROCEDURE(p_clear),},
|
---|
16 | {"size",0,PARAM_READONLY+PARAM_NOSTATIC,"element count","d",GETONLY(size),},
|
---|
17 | {"remove",0,PARAM_NOSTATIC,"remove at position","p(d position)",PROCEDURE(p_remove),},
|
---|
18 | {"get",0,PARAM_NOSTATIC,"get value at position","p x(d position)",PROCEDURE(p_get),},
|
---|
19 | {"set",0,PARAM_NOSTATIC,"set value at position","p(d position,x value)",PROCEDURE(p_set),},
|
---|
20 | {"add",0,PARAM_NOSTATIC,"append at the end","p(x value)",PROCEDURE(p_add),},
|
---|
21 | {"find",0,PARAM_NOSTATIC,"find","p d(x value)",PROCEDURE(p_find),"returns the element index or -1 if not found"},
|
---|
22 | {"avg",0,PARAM_READONLY+PARAM_NOSTATIC,"average","f",GETONLY(avg)},
|
---|
23 | {"stdev",0,PARAM_READONLY+PARAM_NOSTATIC,"standard deviation","f",GETONLY(stdev),"=sqrt(sum((element[i]-avg)^2)/(size-1)) which is estimated population std.dev. from sample std.dev."},
|
---|
24 | {"toString",0,PARAM_READONLY+PARAM_NOSTATIC,"textual form","s",GETONLY(toString),},
|
---|
25 | {"new",0,0,"create new Vector","p oVector()",STATICPROCEDURE(p_new),},
|
---|
26 | {0,0,0,},
|
---|
27 | };
|
---|
28 | #undef FIELDSTRUCT
|
---|
29 |
|
---|
30 | #define FIELDSTRUCT DictionaryObject
|
---|
31 | ParamEntry dictionary_paramtab[]=
|
---|
32 | {
|
---|
33 | {"Dictionary",1,9,"Dictionary","Dictionary associates stored values with string keys "
|
---|
34 | "(\"key\" is the first argument in get/set/remove functions). Integer \"key\" can be "
|
---|
35 | "used to enumerate all elements. The sequence of elements is not preserved.\n"
|
---|
36 | "Example: var d=Dictionary.new(); d.set(\"name\",\"John\"); d.set(\"age\",44);\n"
|
---|
37 | "var i,element; for(i=0;i<d.size;i++) CLI.println(d.getKey(i)+\" is \"+d.get(i));",},
|
---|
38 | {"clear",0,PARAM_NOSTATIC,"clear data","p()",PROCEDURE(p_clear),},
|
---|
39 | {"size",0,PARAM_NOSTATIC,"element count","d",GETONLY(size),},
|
---|
40 | {"remove",0,PARAM_NOSTATIC,"remove named or indexed element","p(x key)",PROCEDURE(p_remove),},
|
---|
41 | {"get",0,PARAM_NOSTATIC,"get named or indexed element","p x(x key)",PROCEDURE(p_get),},
|
---|
42 | {"getKey",0,PARAM_NOSTATIC,"get a key of the indexed element","p s(d index)",PROCEDURE(p_getKey),},
|
---|
43 | {"set",0,PARAM_NOSTATIC,"set named or indexed element","p(x key,x value)",PROCEDURE(p_set),},
|
---|
44 | {"find",0,PARAM_NOSTATIC,"find","p s(x value)",PROCEDURE(p_find),"returns the element key or null if not found"},
|
---|
45 | {"new",0,0,"create new Dictionary","p oDictionary()",STATICPROCEDURE(p_new),},
|
---|
46 | {"toString",0,PARAM_READONLY+PARAM_NOSTATIC,"textual form","s",GETONLY(toString),},
|
---|
47 | {0,0,0,},
|
---|
48 | };
|
---|
49 | #undef FIELDSTRUCT
|
---|
50 |
|
---|
51 | Param VectorObject::par(vector_paramtab);
|
---|
52 | Param DictionaryObject::par(dictionary_paramtab);
|
---|
53 |
|
---|
54 | /////////////////////////////////////////
|
---|
55 |
|
---|
56 | VectorObject::VectorObject(Pt3D &pt)
|
---|
57 | :readonly(0),owndata(1)
|
---|
58 | {
|
---|
59 | set(0,ExtValue(pt.x));
|
---|
60 | set(1,ExtValue(pt.y));
|
---|
61 | set(2,ExtValue(pt.z));
|
---|
62 | }
|
---|
63 |
|
---|
64 | void VectorObject::clear()
|
---|
65 | {
|
---|
66 | if (owndata)
|
---|
67 | for(int i=data.size()-1;i>=0;i--)
|
---|
68 | {
|
---|
69 | ExtValue *v=(ExtValue*)data.get(i);
|
---|
70 | if (v) delete v;
|
---|
71 | }
|
---|
72 | //nie tak spektakularny jak rasowe bugi roku ale tez idiotyczny :>
|
---|
73 | //wszystko przez to ze poczatkowo bylo tylko uzywane w destruktorze...
|
---|
74 | data.clear();
|
---|
75 | }
|
---|
76 |
|
---|
77 | void VectorObject::p_remove(PARAMPROCARGS)
|
---|
78 | {
|
---|
79 | if (readonly) return;
|
---|
80 | int i=args->getInt();
|
---|
81 | if ((i<0)||(i>=data.size())) return;
|
---|
82 | ExtValue *v=(ExtValue*)data.get(i);
|
---|
83 | if (v) delete v;
|
---|
84 | data-=i;
|
---|
85 | }
|
---|
86 |
|
---|
87 | void VectorObject::set(int i,const ExtValue& val)
|
---|
88 | {
|
---|
89 | int oldsize=data.size();
|
---|
90 | if (i<0) return;
|
---|
91 | ExtValue *v=(ExtValue*)data.get(i);
|
---|
92 | if (v) delete v;
|
---|
93 | data.set(i,new ExtValue(val));
|
---|
94 | i--;
|
---|
95 | while(i>=oldsize)
|
---|
96 | {
|
---|
97 | data.set(i,0);
|
---|
98 | i--;
|
---|
99 | }
|
---|
100 | }
|
---|
101 |
|
---|
102 | void VectorObject::p_get(PARAMPROCARGS)
|
---|
103 | {
|
---|
104 | int i=args->getInt();
|
---|
105 | if (listIndexCheck(&data,i,"VectorObject","get",""))
|
---|
106 | {
|
---|
107 | ExtValue *v=get(i);
|
---|
108 | if (v)
|
---|
109 | {
|
---|
110 | *ret=*v;
|
---|
111 | return;
|
---|
112 | }
|
---|
113 | }
|
---|
114 | *ret=ExtValue();
|
---|
115 | }
|
---|
116 |
|
---|
117 | void VectorObject::get_avg(ExtValue* ret)
|
---|
118 | {
|
---|
119 | if (!data.size()) {ret->setEmpty(); return;}
|
---|
120 | double s=0.0;
|
---|
121 | for(int i=data.size()-1;i>=0;i--)
|
---|
122 | s+=((ExtValue*)data.get(i))->getDouble();
|
---|
123 | s/=data.size();
|
---|
124 | ret->setDouble(s);
|
---|
125 | }
|
---|
126 |
|
---|
127 | void VectorObject::get_toString(ExtValue* ret)
|
---|
128 | {
|
---|
129 | SString out="[";
|
---|
130 | static SListTempl<VectorObject*> trace;
|
---|
131 | if (trace.find(this)>=0)
|
---|
132 | out+="...";
|
---|
133 | else
|
---|
134 | {
|
---|
135 | trace+=this;
|
---|
136 | for(int i=0;i<data.size();i++)
|
---|
137 | {
|
---|
138 | ExtValue* v=(ExtValue*)data.get(i);
|
---|
139 | if (i) out+=",";
|
---|
140 | if (v)
|
---|
141 | out+=v->getString();
|
---|
142 | else
|
---|
143 | out+="null";
|
---|
144 | }
|
---|
145 | trace-=this;
|
---|
146 | }
|
---|
147 | out+="]";
|
---|
148 | ret->setString(out);
|
---|
149 | }
|
---|
150 |
|
---|
151 | void VectorObject::get_stdev(ExtValue* ret)
|
---|
152 | {
|
---|
153 | if (!data.size()) {ret->setEmpty(); return;}
|
---|
154 | get_avg(ret);
|
---|
155 | double a=ret->getDouble();
|
---|
156 | double s=0.0;
|
---|
157 | for(int i=data.size()-1;i>=0;i--)
|
---|
158 | {
|
---|
159 | double d=a-((ExtValue*)data.get(i))->getDouble();
|
---|
160 | s+=d*d;
|
---|
161 | }
|
---|
162 | ret->setDouble(sqrt(s/max(1,data.size()-1)));
|
---|
163 | }
|
---|
164 |
|
---|
165 | void VectorObject::p_find(PARAMPROCARGS)
|
---|
166 | {
|
---|
167 | short i;
|
---|
168 | for(i=0;i<data.size();i++)
|
---|
169 | {
|
---|
170 | if ((*args)==(*get(i)))
|
---|
171 | {ret->setInt(i);return;}
|
---|
172 | }
|
---|
173 | ret->setInt(-1);
|
---|
174 | }
|
---|
175 |
|
---|
176 | /////////////////////////////
|
---|
177 |
|
---|
178 | void DictionaryObject::clear()
|
---|
179 | {
|
---|
180 | for(HashEntryIterator it(hash);it.isValid();)
|
---|
181 | {
|
---|
182 | ExtValue *v=(ExtValue*)hash.remove(it);
|
---|
183 | if (v) delete v;
|
---|
184 | }
|
---|
185 | hash.clear();
|
---|
186 | hash.init();
|
---|
187 | }
|
---|
188 |
|
---|
189 | void DictionaryObject::p_find(PARAMPROCARGS)
|
---|
190 | {
|
---|
191 | for(HashEntryIterator it(hash);it.isValid();it++)
|
---|
192 | {
|
---|
193 | if ((*args)==(*((ExtValue*)it->value)))
|
---|
194 | {
|
---|
195 | ret->setString(it->key);
|
---|
196 | return;
|
---|
197 | }
|
---|
198 | }
|
---|
199 | ret->setEmpty();
|
---|
200 | }
|
---|
201 |
|
---|
202 | HashEntryIterator* DictionaryObject::getIndexIterator(int i)
|
---|
203 | {
|
---|
204 | if (i<0) return 0;
|
---|
205 | if (i>=hash.getSize()) return 0;
|
---|
206 |
|
---|
207 | if ((!it.isValid())||(it_index>i))
|
---|
208 | {
|
---|
209 | it=HashEntryIterator(hash);
|
---|
210 | it_index=0;
|
---|
211 | }
|
---|
212 | while(it.isValid())
|
---|
213 | {
|
---|
214 | if (it_index==i)
|
---|
215 | return ⁢
|
---|
216 | it_index++;
|
---|
217 | it++;
|
---|
218 | }
|
---|
219 | return 0;
|
---|
220 | }
|
---|
221 |
|
---|
222 | void DictionaryObject::p_remove(PARAMPROCARGS)
|
---|
223 | {
|
---|
224 | if ((args->type==TInt)||(args->type==TDouble))
|
---|
225 | {
|
---|
226 | HashEntryIterator* iter=getIndexIterator(args->getInt());
|
---|
227 | if (iter)
|
---|
228 | {
|
---|
229 | ExtValue *oldval=(ExtValue*)hash.remove(*iter);
|
---|
230 | if (oldval) {*ret=*oldval; delete oldval;} else *ret=ExtValue();
|
---|
231 | }
|
---|
232 | }
|
---|
233 | else
|
---|
234 | {
|
---|
235 | ExtValue *oldval=(ExtValue*)hash.remove(args[0].getString());
|
---|
236 | if (oldval) {*ret=*oldval; delete oldval;} else *ret=ExtValue();
|
---|
237 | }
|
---|
238 | }
|
---|
239 |
|
---|
240 | void DictionaryObject::p_get(PARAMPROCARGS)
|
---|
241 | {
|
---|
242 | if ((args->type==TInt)||(args->type==TDouble))
|
---|
243 | {
|
---|
244 | HashEntryIterator* iter=getIndexIterator(args->getInt());
|
---|
245 | if (iter && (*iter)->value)
|
---|
246 | {
|
---|
247 | *ret=*((ExtValue*)(*iter)->value);
|
---|
248 | return;
|
---|
249 | }
|
---|
250 | }
|
---|
251 | else
|
---|
252 | {
|
---|
253 | ExtValue *val=(ExtValue*)hash.get(args[0].getString());
|
---|
254 | if (val)
|
---|
255 | {
|
---|
256 | *ret=*val;
|
---|
257 | return;
|
---|
258 | }
|
---|
259 | }
|
---|
260 | *ret=ExtValue();
|
---|
261 | }
|
---|
262 |
|
---|
263 | void DictionaryObject::p_getKey(PARAMPROCARGS)
|
---|
264 | {
|
---|
265 | HashEntryIterator* iter=getIndexIterator(args->getInt());
|
---|
266 | if (iter)
|
---|
267 | {
|
---|
268 | *ret=(*iter)->key;
|
---|
269 | return;
|
---|
270 | }
|
---|
271 | *ret=ExtValue();
|
---|
272 | }
|
---|
273 |
|
---|
274 | void DictionaryObject::p_set(PARAMPROCARGS)
|
---|
275 | {
|
---|
276 | ExtValue *newval=(args[0].getType()==TUnknown)?0:new ExtValue(args[0]);
|
---|
277 | ExtValue *oldval=(ExtValue*)hash.put(args[1].getString(),newval);
|
---|
278 | if (oldval) {*ret=*oldval; delete oldval;} else *ret=ExtValue();
|
---|
279 | }
|
---|
280 |
|
---|
281 | void DictionaryObject::get_toString(ExtValue* ret)
|
---|
282 | {
|
---|
283 | SString out="[";
|
---|
284 | static SListTempl<DictionaryObject*> trace;
|
---|
285 | if (trace.find(this)>=0)
|
---|
286 | out+="...";
|
---|
287 | else
|
---|
288 | {
|
---|
289 | trace+=this;
|
---|
290 | for(HashEntryIterator it(hash);it.isValid();)
|
---|
291 | {
|
---|
292 | out+=it->key;
|
---|
293 | out+="=";
|
---|
294 | out+=((ExtValue*)it->value)->getString();
|
---|
295 | it++;
|
---|
296 | if (it.isValid()) out+=",";
|
---|
297 | }
|
---|
298 | trace-=this;
|
---|
299 | }
|
---|
300 | out+="]";
|
---|
301 | ret->setString(out);
|
---|
302 | }
|
---|