- Timestamp:
- 03/01/14 22:25:20 (11 years ago)
- Location:
- cpp/frams
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/param/param.cpp
r144 r154 17 17 char MakeCodeGuardHappy; 18 18 19 ParamEntry empty_paramtab[] =20 { { "Empty",1,0,"Empty",}, {0,0,0,}, };21 22 static void czytdotyldy(VirtFILE *f, SString &s)23 { 24 SString temp;25 int z;26 char last_char=0;27 while((z=fgetc(f))!=EOF)28 { 29 if (z=='~')30 if (last_char!='\\') break;31 last_char=(char)z;32 temp+=last_char;33 } 34 s=temp;35 } 36 37 static const char *strchrlimit(const char *t, int ch,const char *limit)38 { 39 int n=limit-t;40 for (;(n>0)&&*t;t++,n--)41 if (*t==ch) return t;42 return 0;19 ParamEntry empty_paramtab[] = 20 { { "Empty", 1, 0, "Empty", }, { 0, 0, 0, }, }; 21 22 static void czytdotyldy(VirtFILE *f, SString &s) 23 { 24 SString temp; 25 int z; 26 char last_char = 0; 27 while ((z = fgetc(f)) != EOF) 28 { 29 if (z == '~') 30 if (last_char != '\\') break; 31 last_char = (char)z; 32 temp += last_char; 33 } 34 s = temp; 35 } 36 37 static const char *strchrlimit(const char *t, int ch, const char *limit) 38 { 39 int n = limit - t; 40 for (; (n > 0) && *t; t++, n--) 41 if (*t == ch) return t; 42 return 0; 43 43 } 44 44 45 45 void ParamInterface::copyFrom(ParamInterface *src) 46 46 { 47 int n=getPropCount();48 ExtValue v;49 int j;50 for(int i=0;i<n;i++)51 52 && (*type(i)!='p'))53 {54 j=src->findId(id(i));55 if (j<0) continue;56 src->get(j,v);57 set(i,v);58 }47 int n = getPropCount(); 48 ExtValue v; 49 int j; 50 for (int i = 0; i < n; i++) 51 if ((!(flags(i)&PARAM_READONLY)) 52 && (*type(i) != 'p')) 53 { 54 j = src->findId(id(i)); 55 if (j < 0) continue; 56 src->get(j, v); 57 set(i, v); 58 } 59 59 } 60 60 61 61 void ParamInterface::quickCopyFrom(ParamInterface *src) 62 62 { 63 int n=getPropCount();64 ExtValue v;65 for(int i=0;i<n;i++)66 67 && (*type(i)!='p'))68 69 src->get(i,v);70 set(i,v);71 72 } 73 74 int ParamInterface::getMinMax(int prop, long& minumum,long& maximum,long &def)75 { 76 const char* t=type(prop)+1;77 while(*t) if (*t==' ') break; else t++;78 return sscanf(t,"%ld %ld %ld",&minumum,&maximum,&def);79 } 80 81 int ParamInterface::getMinMax(int prop, double& minumum,double& maximum,double& def)82 { 83 const char* t=type(prop)+1;84 while(*t) if (*t==' ') break; else t++;85 return sscanf(t,"%lg %lg %lg",&minumum,&maximum,&def);63 int n = getPropCount(); 64 ExtValue v; 65 for (int i = 0; i < n; i++) 66 if ((!(flags(i)&PARAM_READONLY)) 67 && (*type(i) != 'p')) 68 { 69 src->get(i, v); 70 set(i, v); 71 } 72 } 73 74 int ParamInterface::getMinMax(int prop, long& minumum, long& maximum, long &def) 75 { 76 const char* t = type(prop) + 1; 77 while (*t) if (*t == ' ') break; else t++; 78 return sscanf(t, "%ld %ld %ld", &minumum, &maximum, &def); 79 } 80 81 int ParamInterface::getMinMax(int prop, double& minumum, double& maximum, double& def) 82 { 83 const char* t = type(prop) + 1; 84 while (*t) if (*t == ' ') break; else t++; 85 return sscanf(t, "%lg %lg %lg", &minumum, &maximum, &def); 86 86 } 87 87 88 88 void ParamInterface::setDefault(bool numericonly) 89 89 { 90 int n=getPropCount();91 for(int i=0;i<n;i++)92 setDefault(i,numericonly);90 int n = getPropCount(); 91 for (int i = 0; i < n; i++) 92 setDefault(i, numericonly); 93 93 } 94 94 95 95 void ParamInterface::setMin() 96 96 { 97 int n=getPropCount();98 for(int i=0;i<n;i++)99 setMin(i);97 int n = getPropCount(); 98 for (int i = 0; i < n; i++) 99 setMin(i); 100 100 } 101 101 102 102 void ParamInterface::setMax() 103 103 { 104 int n=getPropCount();105 for(int i=0;i<n;i++)106 setMax(i);107 } 108 109 void ParamInterface::setDefault(int i, bool numericonly)110 { 111 const char *t=type(i);112 switch(*t)104 int n = getPropCount(); 105 for (int i = 0; i < n; i++) 106 setMax(i); 107 } 108 109 void ParamInterface::setDefault(int i, bool numericonly) 110 { 111 const char *t = type(i); 112 switch (*t) 113 113 { 114 114 case 'f': 115 115 { 116 double a=0,b=0,c=0;117 if (getMinMax(i,a,b,c)<3) c=a;118 setDouble(i,c);119 } 120 break;116 double a = 0, b = 0, c = 0; 117 if (getMinMax(i, a, b, c) < 3) c = a; 118 setDouble(i, c); 119 } 120 break; 121 121 case 'd': 122 122 { 123 long a=0,b=0,c=0;124 if (getMinMax(i,a,b,c)<3) c=a;125 setInt(i,c);126 } 127 break;128 default: if (!numericonly) set(i, "");123 long a = 0, b = 0, c = 0; 124 if (getMinMax(i, a, b, c) < 3) c = a; 125 setInt(i, c); 126 } 127 break; 128 default: if (!numericonly) set(i, ""); 129 129 } 130 130 } … … 132 132 void ParamInterface::setMin(int i) 133 133 { 134 const char *t=type(i);135 switch(*t)134 const char *t = type(i); 135 switch (*t) 136 136 { 137 137 case 'f': 138 138 { 139 double a=0,b=0,c=0;140 getMinMax(i,a,b,c);141 setDouble(i,a);142 } 143 break;139 double a = 0, b = 0, c = 0; 140 getMinMax(i, a, b, c); 141 setDouble(i, a); 142 } 143 break; 144 144 case 'd': 145 145 { 146 long a=0,b=0,c=0;147 getMinMax(i,a,b,c);148 setInt(i,a);149 } 150 break;151 default: set(i, "");146 long a = 0, b = 0, c = 0; 147 getMinMax(i, a, b, c); 148 setInt(i, a); 149 } 150 break; 151 default: set(i, ""); 152 152 } 153 153 } … … 155 155 void ParamInterface::setMax(int i) 156 156 { 157 const char *t=type(i);158 switch(*t)157 const char *t = type(i); 158 switch (*t) 159 159 { 160 160 case 'f': 161 161 { 162 double a=0,b=0,c=0;163 getMinMax(i,a,b,c);164 setDouble(i,b);165 } 166 break;162 double a = 0, b = 0, c = 0; 163 getMinMax(i, a, b, c); 164 setDouble(i, b); 165 } 166 break; 167 167 case 'd': 168 168 { 169 long a=0,b=0,c=0;170 getMinMax(i,a,b,c);171 setInt(i,b);172 } 173 break;174 default: set(i, "");169 long a = 0, b = 0, c = 0; 170 getMinMax(i, a, b, c); 171 setInt(i, b); 172 } 173 break; 174 default: set(i, ""); 175 175 } 176 176 } … … 200 200 {int i=findId(prop); if (i>=0) return set(i,v); else return PSET_NOPROPERTY;} 201 201 202 int ParamInterface::save(VirtFILE* f, const char* altname,bool force)203 { 204 const char *p;205 SString ws;206 int err=0,i;207 bool withname=false;208 if ((altname==NULL)||(altname[0]!=0))209 { 210 err|=(fputs(altname?altname:getName(),f)==EOF);211 err|=(fputs(":\n",f)==EOF);212 withname=true;213 } 214 for (i=0;p=id(i);i++)215 err|=saveprop(f,i,p,force);216 if (withname)217 err|=(fputs("\n",f)==EOF);218 return err;219 } 220 221 const char* ParamInterface::SERIALIZATION_PREFIX ="@Serialized:";222 223 int ParamInterface::saveprop(VirtFILE* f, int i,const char* p,bool force)224 { 225 if ((flags(i)&PARAM_DONTSAVE)&&(!force)) return 0;226 const char *typ=type(i);227 if ((*typ=='p')||(*typ=='o')) return 0;228 229 const char *t,*w;230 SString ws;231 int err=0,cr;232 233 err|=(fputs(p,f)==EOF); fputc(':',f);234 cr=0;235 if (*typ=='x')236 { 237 ExtValue ex;238 get(i,ex);239 ws=SString(SERIALIZATION_PREFIX)+ex.serialize();240 } 241 else242 ws=get(i);243 quoteTilde(ws);244 w=ws;245 if (ws.len()>50) cr=1;246 else for (t=w;*t;t++) if ((*t==10)||(*t==13)) {cr=1; break;}247 if (cr) fputs("~\n",f);248 err|=(fputs(w,f)==EOF);249 err|=(fputs(cr ? "~\n" : "\n",f)==EOF);250 return err;251 } 252 253 254 int SimpleAbstractParam::isequal(int i, void* defdata)202 int ParamInterface::save(VirtFILE* f, const char* altname, bool force) 203 { 204 const char *p; 205 SString ws; 206 int err = 0, i; 207 bool withname = false; 208 if ((altname == NULL) || (altname[0] != 0)) 209 { 210 err |= (fputs(altname ? altname : getName(), f) == EOF); 211 err |= (fputs(":\n", f) == EOF); 212 withname = true; 213 } 214 for (i = 0; p = id(i); i++) 215 err |= saveprop(f, i, p, force); 216 if (withname) 217 err |= (fputs("\n", f) == EOF); 218 return err; 219 } 220 221 const char* ParamInterface::SERIALIZATION_PREFIX = "@Serialized:"; 222 223 int ParamInterface::saveprop(VirtFILE* f, int i, const char* p, bool force) 224 { 225 if ((flags(i)&PARAM_DONTSAVE) && (!force)) return 0; 226 const char *typ = type(i); 227 if ((*typ == 'p') || (*typ == 'o')) return 0; 228 229 const char *t, *w; 230 SString ws; 231 int err = 0, cr; 232 233 err |= (fputs(p, f) == EOF); fputc(':', f); 234 cr = 0; 235 if (*typ == 'x') 236 { 237 ExtValue ex; 238 get(i, ex); 239 ws = SString(SERIALIZATION_PREFIX) + ex.serialize(); 240 } 241 else 242 ws = get(i); 243 quoteTilde(ws); 244 w = ws; 245 if (ws.len() > 50) cr = 1; 246 else for (t = w; *t; t++) if ((*t == 10) || (*t == 13)) { cr = 1; break; } 247 if (cr) fputs("~\n", f); 248 err |= (fputs(w, f) == EOF); 249 err |= (fputs(cr ? "~\n" : "\n", f) == EOF); 250 return err; 251 } 252 253 254 int SimpleAbstractParam::isequal(int i, void* defdata) 255 255 { // defdata->member == object->member ? 256 void *backup=object;257 switch(type(i)[0])256 void *backup = object; 257 switch (type(i)[0]) 258 258 { 259 259 case 'd': 260 260 { 261 261 select(defdata); 262 long x =getInt(i);262 long x = getInt(i); 263 263 select(backup); 264 return x ==getInt(i);265 264 return x == getInt(i); 265 } 266 266 case 'f': 267 267 { 268 268 select(defdata); 269 double x =getDouble(i);269 double x = getDouble(i); 270 270 select(backup); 271 return x ==getDouble(i);272 271 return x == getDouble(i); 272 } 273 273 case 's': 274 274 { 275 275 select(defdata); 276 SString x =getString(i);276 SString x = getString(i); 277 277 select(backup); 278 return x ==getString(i);279 280 } 281 return 1;282 } 283 284 void SimpleAbstractParam::save2(SString& f, void *defdata,bool addcr,bool all_names)285 { // defdata!=NULL -> nie zapisuje wartosci domyslnych286 const char *p;287 int i;288 int needlabel=0;289 int first=1;290 SString val;291 SString t;292 int fl;293 // t+=SString(getName()); t+=':';294 for (i=0;p=id(i);i++)295 if (!((fl=flags(i))&PARAM_DONTSAVE))296 {297 if (defdata && isequal(i,defdata))298 needlabel=1;299 else300 {301 if (!first) t+=", ";278 return x == getString(i); 279 } 280 } 281 return 1; 282 } 283 284 void SimpleAbstractParam::save2(SString& f, void *defdata, bool addcr, bool all_names) 285 { // defdata!=NULL -> does not save default values 286 const char *p; 287 int i; 288 int needlabel = 0; 289 int first = 1; 290 SString val; 291 SString t; 292 int fl; 293 // t+=SString(getName()); t+=':'; 294 for (i = 0; p = id(i); i++) 295 if (!((fl = flags(i))&PARAM_DONTSAVE)) 296 { 297 if (defdata && isequal(i, defdata)) 298 needlabel = 1; 299 else 300 { 301 if (!first) t += ", "; 302 302 #ifndef SAVE_ALL_NAMES 303 303 #ifdef SAVE_SELECTED_NAMES 304 if (needlabel || all_names || !(fl & PARAM_CANOMITNAME))304 if (needlabel || all_names || !(fl & PARAM_CANOMITNAME)) 305 305 #else 306 if (needlabel)306 if (needlabel) 307 307 #endif 308 308 #endif 309 { t+=p; t+="="; needlabel=0; }310 if (type(i)[0]=='s')311 { // string - special case312 SString str=getString(i);313 if (strContainsOneOf(str,", \\\n\r\t\""))314 309 { 315 t+="\""; 316 sstringQuote(str); 317 t+=str; 318 t+="\""; 310 t += p; t += "="; needlabel = 0; 319 311 } 312 if (type(i)[0] == 's') 313 { // string - special case 314 SString str = getString(i); 315 if (strContainsOneOf(str, ", \\\n\r\t\"")) 316 { 317 t += "\""; 318 sstringQuote(str); 319 t += str; 320 t += "\""; 321 } 322 else 323 t += str; 324 } 325 else 326 t += get(i); 327 first = 0; 328 } 329 } 330 if (addcr) 331 t += "\n"; 332 f += t; 333 } 334 335 int ParamInterface::load(VirtFILE* f) 336 { 337 SString buf; 338 int i; 339 const char *p, *p0; 340 int p_len; 341 bool loaded; 342 int fields_loaded = 0; 343 while (loadSStringLine(f, buf)) 344 { 345 const char* t = (const char*)buf; 346 p0 = t; while ((*p0 == ' ') || (*p0 == '\t')) p0++; 347 if (!*p0) break; 348 p = strchr(p0, ':'); if (!p) continue; 349 p_len = p - p0; 350 loaded = false; 351 if (p_len && ((i = findIdn(p0, p_len)) >= 0) && (!(flags(i)&PARAM_DONTLOAD))) 352 { 353 if (p0[p_len + 1] == '~') 354 { 355 SString s; 356 czytdotyldy(f, s); 357 removeCR(s); 358 int ch; while ((ch = fgetc(f)) != EOF) if (ch == '\n') break; 359 unquoteTilde(s); 360 set(i, (const char*)s); 361 } 320 362 else 321 t+=str; 363 { 364 set(i, p0 + p_len + 1); 322 365 } 323 else 324 t+=get(i); 325 first=0; 326 } 327 } 328 if (addcr) 329 t+="\n"; 330 f+=t; 331 } 332 333 int ParamInterface::load(VirtFILE* f) 334 { 335 SString buf; 336 int i; 337 const char *p,*p0; 338 int p_len; 339 bool loaded; 340 int fields_loaded=0; 341 while(loadSStringLine(f,buf)) 342 { 343 const char* t=(const char*)buf; 344 p0=t; while ((*p0==' ')||(*p0=='\t')) p0++; 345 if (!*p0) break; 346 p=strchr(p0,':'); if (!p) continue; 347 p_len=p-p0; 348 loaded=false; 349 if (p_len&&((i=findIdn(p0,p_len))>=0)&&(!(flags(i)&PARAM_DONTLOAD))) 350 { 351 if (p0[p_len+1]=='~') 352 { 366 fields_loaded++; 367 loaded = true; 368 } 369 if ((!loaded) && (p0[p_len + 1] == '~')) 370 { // eat unrecognized multiline field 353 371 SString s; 354 czytdotyldy(f,s); 355 removeCR(s); 356 int ch; while((ch=fgetc(f))!=EOF) if (ch=='\n') break; 357 unquoteTilde(s); 358 set(i,(const char*)s); 359 } 360 else 361 { 362 set(i,p0+p_len+1); 363 } 364 fields_loaded++; 365 loaded=true; 366 } 367 if ((!loaded) && (p0[p_len+1]=='~')) 368 { // eat unrecognized multiline field 369 SString s; 370 czytdotyldy(f,s); 371 int ch; while((ch=fgetc(f))!=EOF) if (ch=='\n') break; 372 } 373 } 374 return fields_loaded; 372 czytdotyldy(f, s); 373 int ch; while ((ch = fgetc(f)) != EOF) if (ch == '\n') break; 374 } 375 } 376 return fields_loaded; 375 377 } 376 378 … … 403 405 int ParamInterface::findId(const char* n) 404 406 { 405 int i; const char *p;406 for (i =0;p=id(i);i++) if (!strcmp(n,p)) return i;407 return -1;408 } 409 410 int ParamInterface::findIdn(const char* naz, int n)411 { 412 int i; const char *p;413 for (i =0;p=id(i);i++) if ((!strncmp(naz,p,n))&&(!p[n])) return i;414 return -1;415 } 416 417 void ParamInterface::get(int i, ExtValue &ret)418 { 419 switch(type(i)[0])407 int i; const char *p; 408 for (i = 0; p = id(i); i++) if (!strcmp(n, p)) return i; 409 return -1; 410 } 411 412 int ParamInterface::findIdn(const char* naz, int n) 413 { 414 int i; const char *p; 415 for (i = 0; p = id(i); i++) if ((!strncmp(naz, p, n)) && (!p[n])) return i; 416 return -1; 417 } 418 419 void ParamInterface::get(int i, ExtValue &ret) 420 { 421 switch (type(i)[0]) 420 422 { 421 423 case 'd': ret.setInt(getInt(i)); break; … … 423 425 case 's': ret.setString(getString(i)); break; 424 426 case 'o': ret.setObject(getObject(i)); break; 425 case 'x': ret =getExtValue(i); break;426 default: FMprintf("ParamInterface", "get",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));427 case 'x': ret = getExtValue(i); break; 428 default: FMprintf("ParamInterface", "get", FMLV_ERROR, "'%s.%s' is not a field", getName(), id(i)); 427 429 } 428 430 } … … 430 432 static bool stringIsNumeric(const char* str) 431 433 {// /-?.?[0-9]+/ 432 if (!str) return false;433 if (*str=='-') str++;434 if (*str=='.') str++;435 return isdigit(*str)!=0;436 } 437 438 int ParamInterface::setInt(int i, const char* str)439 { 440 if (!stringIsNumeric(str))441 { 442 long a,b,c;443 if (getMinMax(i,a,b,c)>=3)444 return setInt(i,c);445 else446 return setInt(i,(long)0);447 } 448 else449 return setInt(i,ExtValue::getInt(str));450 } 451 452 int ParamInterface::setDouble(int i, const char* str)453 { 454 if (!stringIsNumeric(str))455 { 456 double a,b,c;457 if (getMinMax(i,a,b,c)>=3)458 return setDouble(i,c);459 else460 return setDouble(i,(double)0);461 } 462 else463 return setDouble(i,ExtValue::getDouble(str));464 } 465 466 int ParamInterface::set(int i, const ExtValue &v)467 { 468 switch(type(i)[0])434 if (!str) return false; 435 if (*str == '-') str++; 436 if (*str == '.') str++; 437 return isdigit(*str) != 0; 438 } 439 440 int ParamInterface::setInt(int i, const char* str) 441 { 442 if (!stringIsNumeric(str)) 443 { 444 long a, b, c; 445 if (getMinMax(i, a, b, c) >= 3) 446 return setInt(i, c); 447 else 448 return setInt(i, (long)0); 449 } 450 else 451 return setInt(i, ExtValue::getInt(str)); 452 } 453 454 int ParamInterface::setDouble(int i, const char* str) 455 { 456 if (!stringIsNumeric(str)) 457 { 458 double a, b, c; 459 if (getMinMax(i, a, b, c) >= 3) 460 return setDouble(i, c); 461 else 462 return setDouble(i, (double)0); 463 } 464 else 465 return setDouble(i, ExtValue::getDouble(str)); 466 } 467 468 int ParamInterface::set(int i, const ExtValue &v) 469 { 470 switch (type(i)[0]) 469 471 { 470 472 case 'd': 471 if ((v.type ==TInt)||(v.type==TDouble)) return setInt(i,v.getInt());473 if ((v.type == TInt) || (v.type == TDouble)) return setInt(i, v.getInt()); 472 474 else 473 474 if (v.type ==TObj)475 FMprintf("ParamInterface", "set",FMLV_WARN,"Getting integer value from object reference (%s)",(const char*)v.getString());476 return setInt(i, (const char*)v.getString());477 475 { 476 if (v.type == TObj) 477 FMprintf("ParamInterface", "set", FMLV_WARN, "Getting integer value from object reference (%s)", (const char*)v.getString()); 478 return setInt(i, (const char*)v.getString()); 479 } 478 480 case 'f': 479 if ((v.type ==TInt)||(v.type==TDouble)) return setDouble(i,v.getDouble());481 if ((v.type == TInt) || (v.type == TDouble)) return setDouble(i, v.getDouble()); 480 482 else 481 482 if (v.type ==TObj)483 FMprintf("ParamInterface", "set",FMLV_WARN,"Getting floating point value from object reference (%s)",(const char*)v.getString());484 return setDouble(i, (const char*)v.getString());485 486 case 's': { SString t =v.getString(); return setString(i,t); }487 case 'o': return setObject(i, v.getObject());488 case 'x': return setExtValue(i, v);489 default: FMprintf("ParamInterface", "set",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));490 } 491 return 0;492 } 493 494 int ParamInterface::set(int i, const char *v)495 { 496 switch(type(i)[0])497 { 498 case 'd': return setInt(i, v);499 case 'f': return setDouble(i, v);500 case 's': { SString t(v); return setString(i, t); }483 { 484 if (v.type == TObj) 485 FMprintf("ParamInterface", "set", FMLV_WARN, "Getting floating point value from object reference (%s)", (const char*)v.getString()); 486 return setDouble(i, (const char*)v.getString()); 487 } 488 case 's': { SString t = v.getString(); return setString(i, t); } 489 case 'o': return setObject(i, v.getObject()); 490 case 'x': return setExtValue(i, v); 491 default: FMprintf("ParamInterface", "set", FMLV_ERROR, "'%s.%s' is not a field", getName(), id(i)); 492 } 493 return 0; 494 } 495 496 int ParamInterface::set(int i, const char *v) 497 { 498 switch (type(i)[0]) 499 { 500 case 'd': return setInt(i, v); 501 case 'f': return setDouble(i, v); 502 case 's': { SString t(v); return setString(i, t); } 501 503 case 'x': 502 504 { 503 ExtValue e;504 const char* after;505 if (!strncmp(v,SERIALIZATION_PREFIX,strlen(SERIALIZATION_PREFIX)))506 { 507 after=e.deserialize(v+strlen(SERIALIZATION_PREFIX));508 if ((after==NULL)||(*after))509 FMprintf("ParamInterface","set",FMLV_WARN,"serialization format mismatch in %s.%s",(getName()?getName():"<Unknown>"),id(i));510 } 511 else if ((after=e.parseNumber(v))&&(*after==0)) //consumed the whole string512 { 513 //OK!514 } 515 else516 { 517 e.setString(SString(v));518 } 519 return setExtValue(i,e);520 } 521 } 522 return 0;505 ExtValue e; 506 const char* after; 507 if (!strncmp(v, SERIALIZATION_PREFIX, strlen(SERIALIZATION_PREFIX))) 508 { 509 after = e.deserialize(v + strlen(SERIALIZATION_PREFIX)); 510 if ((after == NULL) || (*after)) 511 FMprintf("ParamInterface", "set", FMLV_WARN, "serialization format mismatch in %s.%s", (getName() ? getName() : "<Unknown>"), id(i)); 512 } 513 else if ((after = e.parseNumber(v)) && (*after == 0)) //consumed the whole string 514 { 515 //OK! 516 } 517 else 518 { 519 e.setString(SString(v)); 520 } 521 return setExtValue(i, e); 522 } 523 } 524 return 0; 523 525 } 524 526 525 527 SString ParamInterface::getText(int i) 526 528 { 527 const char *t;528 if ((*(t=type(i)))=='d')529 { 530 for (int j=getInt(i);j>=0;j--) if (t) t=strchr(t+1,'~');531 if (t)532 { 533 t++;534 const char *t2=strchr(t,'~');535 if (!t2) t2=t+strlen(t);536 return SString(t,t2-t);537 } 538 } 539 return get(i);529 const char *t; 530 if ((*(t = type(i))) == 'd') 531 { 532 for (int j = getInt(i); j >= 0; j--) if (t) t = strchr(t + 1, '~'); 533 if (t) 534 { 535 t++; 536 const char *t2 = strchr(t, '~'); 537 if (!t2) t2 = t + strlen(t); 538 return SString(t, t2 - t); 539 } 540 } 541 return get(i); 540 542 } 541 543 542 544 SString ParamInterface::get(int i) 543 545 { 544 switch(type(i)[0])546 switch (type(i)[0]) 545 547 { 546 548 case 'd': return SString::valueOf(getInt(i)); … … 548 550 case 's': return getString(i); 549 551 } 550 ExtValue v;551 get(i,v);552 return v.getString();552 ExtValue v; 553 get(i, v); 554 return v.getString(); 553 555 } 554 556 … … 558 560 void *SimpleAbstractParam::getTarget(int i) 559 561 { 560 return (void*)(((char*)object)+entry(i)->offset);561 //return &(object->*(entry(i)->fldptr));562 return (void*)(((char*)object) + entry(i)->offset); 563 //return &(object->*(entry(i)->fldptr)); 562 564 } 563 565 … … 566 568 long SimpleAbstractParam::getInt(int i) 567 569 { 568 ExtValue v;569 ParamEntry *pe=entry(i);570 if (pe->fun1)571 { 572 (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);573 return v.getInt();574 } 575 else576 { 577 void *target=getTarget(i);578 return *((long*)target);570 ExtValue v; 571 ParamEntry *pe = entry(i); 572 if (pe->fun1) 573 { 574 (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v); 575 return v.getInt(); 576 } 577 else 578 { 579 void *target = getTarget(i); 580 return *((long*)target); 579 581 } 580 582 } … … 582 584 double SimpleAbstractParam::getDouble(int i) 583 585 { 584 ExtValue v;585 ParamEntry *pe=entry(i);586 if (pe->fun1)587 { 588 (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);589 return v.getDouble();590 } 591 else592 { 593 void *target=getTarget(i);594 return *((double*)target);586 ExtValue v; 587 ParamEntry *pe = entry(i); 588 if (pe->fun1) 589 { 590 (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v); 591 return v.getDouble(); 592 } 593 else 594 { 595 void *target = getTarget(i); 596 return *((double*)target); 595 597 } 596 598 } … … 598 600 SString SimpleAbstractParam::getString(int i) 599 601 { 600 ExtValue v;601 ParamEntry *pe=entry(i);602 if (pe->fun1)603 { 604 (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);605 return v.getString();606 } 607 else608 { 609 void *target=getTarget(i);610 return *((SString*)target);602 ExtValue v; 603 ParamEntry *pe = entry(i); 604 if (pe->fun1) 605 { 606 (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v); 607 return v.getString(); 608 } 609 else 610 { 611 void *target = getTarget(i); 612 return *((SString*)target); 611 613 } 612 614 } … … 614 616 ExtObject SimpleAbstractParam::getObject(int i) 615 617 { 616 ExtValue v;617 ParamEntry *pe=entry(i);618 if (pe->fun1)619 { 620 (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);621 return v.getObject();622 } 623 else624 { 625 void *target=getTarget(i);626 return *((ExtObject*)target);618 ExtValue v; 619 ParamEntry *pe = entry(i); 620 if (pe->fun1) 621 { 622 (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v); 623 return v.getObject(); 624 } 625 else 626 { 627 void *target = getTarget(i); 628 return *((ExtObject*)target); 627 629 } 628 630 } … … 630 632 ExtValue SimpleAbstractParam::getExtValue(int i) 631 633 { 632 ExtValue v;633 ParamEntry *pe=entry(i);634 if (pe->fun1)635 { 636 (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);637 return v;638 } 639 else640 { 641 void *target=getTarget(i);642 return *((ExtValue*)target);634 ExtValue v; 635 ParamEntry *pe = entry(i); 636 if (pe->fun1) 637 { 638 (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v); 639 return v; 640 } 641 else 642 { 643 void *target = getTarget(i); 644 return *((ExtValue*)target); 643 645 } 644 646 } … … 647 649 //////// set 648 650 649 int SimpleAbstractParam::setInt(int i,long x) 650 { 651 ExtValue v; 652 ParamEntry *pe=entry(i); 653 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 654 long xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 655 long a=0,b=0; 656 int result=0; 657 const char* t=pe->type+1; 658 while(*t) if (*t==' ') break; else t++; 659 if (sscanf(t,"%ld %ld",&a,&b)==2) 660 if (a<=b) // jezeli max<min to znaczy ze min/max nie obowiazuje 661 { 662 if (x<a) {x=a; result=PSET_HITMIN;} 663 else if (x>b) {x=b; result=PSET_HITMAX;} 664 } 665 666 if (pe->fun2) 667 { 668 v.setInt(x); 669 result |= (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v); 670 } 671 else 672 { 673 void *target=getTarget(i); 674 if (dontcheckchanges || (*((long*)target)!=x)) 651 int SimpleAbstractParam::setInt(int i, long x) 652 { 653 ExtValue v; 654 ParamEntry *pe = entry(i); 655 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 656 long xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 657 long a = 0, b = 0; 658 int result = 0; 659 const char* t = pe->type + 1; 660 while (*t) if (*t == ' ') break; else t++; 661 if (sscanf(t, "%ld %ld", &a, &b) == 2) 662 if (a <= b) // if max<min then the min/max constraint check is not supported 663 { 664 if (x<a) { x = a; result = PSET_HITMIN; } 665 else if (x>b) { x = b; result = PSET_HITMAX; } 666 } 667 668 if (pe->fun2) 669 { 670 v.setInt(x); 671 result |= (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &v); 672 } 673 else 674 { 675 void *target = getTarget(i); 676 if (dontcheckchanges || (*((long*)target) != x)) 677 { 678 result |= PSET_CHANGED; 679 *((long*)target) = x; 680 } 681 } 682 messageOnExceedRange(i, result, xcopy); 683 return result; 684 } 685 686 int SimpleAbstractParam::setDouble(int i, double x) 687 { 688 ExtValue v; 689 ParamEntry *pe = entry(i); 690 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 691 double xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 692 double a = 0, b = 0; 693 int result = 0; 694 const char* t = pe->type + 1; 695 while (*t) if (*t == ' ') break; else t++; 696 if (sscanf(t, "%lg %lg", &a, &b) == 2) 697 if (a <= b) // if max<min then the min/max constraint check is not supported 698 { 699 if (x<a) { x = a; result = PSET_HITMIN; } 700 else if (x>b) { x = b; result = PSET_HITMAX; } 701 } 702 703 if (pe->fun2) 704 { 705 v.setDouble(x); 706 result |= (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &v); 707 } 708 else 709 { 710 void *target = getTarget(i); 711 if (dontcheckchanges || (*((double*)target) != x)) 712 { 713 result |= PSET_CHANGED; 714 *((double*)target) = x; 715 } 716 } 717 messageOnExceedRange(i, result, xcopy); 718 return result; 719 } 720 721 int SimpleAbstractParam::setString(int i, const SString& x) 722 { 723 ExtValue v; 724 SString vs; 725 const SString *xx = &x; 726 ParamEntry *pe = entry(i); 727 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 728 SString xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 729 const char* t = pe->type + 1; 730 while (*t) if (*t == ' ') break; else t++; 731 long a = 0, b = 0; 732 int result = 0; 733 if (sscanf(t, "%ld %ld", &a, &b) == 2) 734 { 735 if ((x.len() > b) && (b > 0)) 736 { 737 vs = x.substr(0, b); 738 xx = &vs; 739 result |= PSET_HITMAX; 740 } 741 } 742 743 if (pe->fun2) 744 { 745 v.setString(*xx); 746 result |= (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &v); 747 } 748 else 749 { 750 void *target = getTarget(i); 751 if (dontcheckchanges || (!(*((SString*)target) == *xx))) 752 { 753 result |= PSET_CHANGED; 754 *((SString*)target) = x; 755 } 756 } 757 messageOnExceedRange(i, result, xcopy); 758 return result; 759 } 760 761 int SimpleAbstractParam::setObject(int i, const ExtObject& x) 762 { 763 ExtValue v; 764 ParamEntry *pe = entry(i); 765 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 766 ExtObject xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 767 if (pe->fun2) 768 { 769 v.setObject(x); 770 int result = (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &v); 771 messageOnExceedRange(i, result, xcopy); 772 return result; 773 } 774 else 775 { 776 void *target = getTarget(i); 777 *((ExtObject*)target) = x; 778 return PSET_CHANGED; 779 } 780 } 781 782 int SimpleAbstractParam::setExtValue(int i, const ExtValue& x) 783 { 784 ParamEntry *pe = entry(i); 785 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 786 ExtValue xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 787 if (pe->fun2) 788 { 789 int result = (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &x); 790 messageOnExceedRange(i, result, xcopy); 791 return result; 792 } 793 else 794 { 795 void *target = getTarget(i); 796 *((ExtValue*)target) = x; 797 return PSET_CHANGED; 798 } 799 } 800 801 void SimpleAbstractParam::call(int i, ExtValue *args, ExtValue *ret) 802 { 803 ParamEntry *pe = entry(i); 804 if (!pe) return; 805 if (pe->fun1 && (pe->type[0] == 'p')) 806 (*(void(*)(void*, ExtValue*, ExtValue*))pe->fun1)(object, args, ret); 807 else 808 { 809 FMprintf("SimpleAbstractParam", "call", FMLV_ERROR, 810 (*pe->type != 'p') ? "'%s.%s' is not a function" : "Internal error - undefined function pointer for '%s.%s'", getName(), pe->id); 811 } 812 } 813 814 void SimpleAbstractParam::setDefault(bool numericonly) 815 { 816 bool save = dontcheckchanges; 817 dontcheckchanges = 1; 818 ParamInterface::setDefault(numericonly); 819 dontcheckchanges = save; 820 } 821 822 void SimpleAbstractParam::setDefault(int i, bool numericonly) 823 { 824 bool save = dontcheckchanges; 825 dontcheckchanges = 1; 826 ParamInterface::setDefault(i, numericonly); 827 dontcheckchanges = save; 828 } 829 830 // Returns the address of the beginning of the line. 831 // len = line length (without \n). 832 // 0 may mean the line with length=0 or the end of the SString. 833 // poz is advanced to the beginning of the next line. 834 // A typical loop: for(poz=0;poz<s.d;) {line=getline(s,poz,len);... 835 static const char *getline(const SString &s, int &poz, int &len) 836 { 837 const char *beg = (const char*)s + poz; 838 if (poz >= s.len()) { poz = s.len(); len = 0; return (const char*)s + s.len(); } 839 const char *lf = strchr(beg, '\n'); 840 if (!lf) { lf = (const char*)s + s.len() - 1; poz = s.len(); } 841 else { poz = (lf - (const char*)s) + 1; if (poz > s.len()) poz = s.len(); } 842 while (lf >= beg) if ((*lf == '\n') || (*lf == '\r')) lf--; else break; 843 len = lf - beg + 1; 844 return beg; 845 } 846 847 int ParamInterface::load2(const SString &s, int &poz) 848 { 849 int i; // the index number of the parameter 850 int tmpi; 851 int len; 852 int ret; 853 int fields_loaded = 0; 854 const char *t, *lin, *end; 855 const char *equals_sign, *comma_sign; 856 char remember; 857 const char *quote, *quote2; 858 const char *value, *valstop; 859 SString tmpvalue; 860 if (poz >= s.len()) return fields_loaded; 861 t = (const char*)s + poz; 862 863 lin = getline(s, poz, len); // all fields must be encoded in a single line 864 if (!len) return fields_loaded; // empty line = end 865 i = 0; 866 end = lin + len; 867 while (t < end) 868 { 869 // processing a single field 870 while (strchr(" \n\r\t", *t)) if (t<end) t++; else return fields_loaded; 871 872 comma_sign = strchrlimit(t, ',', end); if (!comma_sign) comma_sign = end; 873 quote = strchrlimit(t, '\"', comma_sign); 874 if (quote) 875 { 876 quote2 = skipQuoteString(quote + 1, end); 877 if (quote2>comma_sign) 675 878 { 676 result |= PSET_CHANGED;677 *((long*)target)=x;879 comma_sign = strchrlimit(quote2 + 1, ',', end); 880 if (!comma_sign) comma_sign = end; 678 881 } 679 } 680 messageOnExceedRange(i,result,xcopy); 681 return result; 682 } 683 684 int SimpleAbstractParam::setDouble(int i,double x) 685 { 686 ExtValue v; 687 ParamEntry *pe=entry(i); 688 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 689 double xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 690 double a=0,b=0; 691 int result=0; 692 const char* t=pe->type+1; 693 while(*t) if (*t==' ') break; else t++; 694 if (sscanf(t,"%lg %lg",&a,&b)==2) 695 if (a<=b) // jezeli max<min to znaczy ze min/max nie obowiazuje 696 { 697 if (x<a) {x=a; result=PSET_HITMIN;} 698 else if (x>b) {x=b; result=PSET_HITMAX;} 699 } 700 701 if (pe->fun2) 702 { 703 v.setDouble(x); 704 result |= (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v); 705 } 706 else 707 { 708 void *target=getTarget(i); 709 if (dontcheckchanges || (*((double*)target)!=x)) 710 { 711 result|=PSET_CHANGED; 712 *((double*)target)=x; 713 } 714 } 715 messageOnExceedRange(i,result,xcopy); 716 return result; 717 } 718 719 int SimpleAbstractParam::setString(int i,const SString& x) 720 { 721 ExtValue v; 722 SString vs; 723 const SString *xx=&x; 724 ParamEntry *pe=entry(i); 725 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 726 SString xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 727 const char* t=pe->type+1; 728 while(*t) if (*t==' ') break; else t++; 729 long a=0,b=0; 730 int result=0; 731 if (sscanf(t,"%ld %ld",&a,&b)==2) 732 { 733 if ((x.len()>b)&&(b>0)) 734 { 735 vs=x.substr(0,b); 736 xx=&vs; 737 result|=PSET_HITMAX; 738 } 739 } 740 741 if (pe->fun2) 742 { 743 v.setString(*xx); 744 result |= (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v); 745 } 746 else 747 { 748 void *target=getTarget(i); 749 if (dontcheckchanges || (!(*((SString*)target) == *xx))) 750 { 751 result|=PSET_CHANGED; 752 *((SString*)target)=x; 753 } 754 } 755 messageOnExceedRange(i,result,xcopy); 756 return result; 757 } 758 759 int SimpleAbstractParam::setObject(int i,const ExtObject& x) 760 { 761 ExtValue v; 762 ParamEntry *pe=entry(i); 763 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 764 ExtObject xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 765 if (pe->fun2) 766 { 767 v.setObject(x); 768 int result=(*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v); 769 messageOnExceedRange(i,result,xcopy); 770 return result; 771 } 772 else 773 { 774 void *target=getTarget(i); 775 *((ExtObject*)target)=x; 776 return PSET_CHANGED; 777 } 778 } 779 780 int SimpleAbstractParam::setExtValue(int i,const ExtValue& x) 781 { 782 ParamEntry *pe=entry(i); 783 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 784 ExtValue xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 785 if (pe->fun2) 786 { 787 int result=(*(int(*)(void*,const ExtValue*))pe->fun2)(object,&x); 788 messageOnExceedRange(i,result,xcopy); 789 return result; 790 } 791 else 792 { 793 void *target=getTarget(i); 794 *((ExtValue*)target)=x; 795 return PSET_CHANGED; 796 } 797 } 798 799 void SimpleAbstractParam::call(int i,ExtValue *args,ExtValue *ret) 800 { 801 ParamEntry *pe=entry(i); 802 if (!pe) return; 803 if (pe->fun1 && (pe->type[0]=='p')) 804 (*(void(*)(void*,ExtValue*,ExtValue*))pe->fun1)(object,args,ret); 805 else 806 { 807 FMprintf("SimpleAbstractParam","call",FMLV_ERROR, 808 (*pe->type!='p')?"'%s.%s' is not a function":"Internal error - undefined function pointer for '%s.%s'",getName(),pe->id); 809 } 810 } 811 812 void SimpleAbstractParam::setDefault(bool numericonly) 813 { 814 bool save=dontcheckchanges; 815 dontcheckchanges=1; 816 ParamInterface::setDefault(numericonly); 817 dontcheckchanges=save; 818 } 819 820 void SimpleAbstractParam::setDefault(int i,bool numericonly) 821 { 822 bool save=dontcheckchanges; 823 dontcheckchanges=1; 824 ParamInterface::setDefault(i,numericonly); 825 dontcheckchanges=save; 826 } 827 828 // zwraca adres poczatku linii 829 // len = dlugosc linii (bez \n) 830 // 0 moze oznaczac linie dlugosci 0 lub koniec SStringa 831 // poz jest przesuwane na poczatek nastepnej linii 832 // typowa petla: for(poz=0;poz<s.d;) {line=getline(s,poz,len);... 833 static const char *getline(const SString &s,int &poz,int &len) 834 { 835 const char *beg=(const char*)s+poz; 836 if (poz>=s.len()) {poz=s.len(); len=0; return (const char*)s+s.len();} 837 const char *lf=strchr(beg,'\n'); 838 if (!lf) { lf=(const char*)s+s.len()-1; poz=s.len(); } 839 else {poz=(lf-(const char*)s)+1; if (poz>s.len()) poz=s.len();} 840 while (lf>=beg) if ((*lf=='\n')||(*lf=='\r')) lf--; else break; 841 len=lf-beg+1; 842 return beg; 843 } 844 845 int ParamInterface::load2(const SString &s,int &poz) 846 { 847 int i; // numer akt. parametru 848 int tmpi; 849 int len; 850 int ret; 851 int fields_loaded=0; 852 const char *t,*lin,*end; 853 const char *rownasie,*przecinek; 854 char remember; 855 const char *quote,*quote2; 856 const char *value,*valstop; 857 SString tmpvalue; 858 if (poz>=s.len()) return fields_loaded; 859 t=(const char*)s+poz; 860 861 // na razie wszystko musi byc w jednej linii... 862 lin=getline(s,poz,len); 863 if (!len) return fields_loaded; // pusta linia = koniec 864 i=0; 865 end=lin+len; 866 while(t<end) 867 { 868 // przetwarzanie jednego par 869 while (strchr(" \n\r\t",*t)) if (t<end) t++; else return fields_loaded; 870 871 przecinek=strchrlimit(t,',',end); if (!przecinek) przecinek=end; 872 quote=strchrlimit(t,'\"',przecinek); 873 if (quote) 874 { 875 quote2=skipQuoteString(quote+1,end); 876 if (quote2>przecinek) 877 { 878 przecinek=strchrlimit(quote2+1,',',end); 879 if (!przecinek) przecinek=end; 880 } 881 rownasie=strchrlimit(t,'=',quote); 882 } 883 else 884 { 885 rownasie=strchrlimit(t,'=',przecinek); 886 quote2=0; 887 } 888 if (rownasie==t) { t++; rownasie=0; } 889 if (przecinek==t) // skip empty value 890 { 891 t++; i++; 892 continue; 893 } 894 if (rownasie) // have parameter name 895 { 896 tmpi=findIdn(t,rownasie-t); 897 i=tmpi; 898 if (tmpi<0) 899 FMprintf("Param","load2",FMLV_WARN,"Unknown property name for '%s' (ignored)",getName()); 900 t=rownasie+1; // t=value 901 } 882 equals_sign = strchrlimit(t, '=', quote); 883 } 884 else 885 { 886 equals_sign = strchrlimit(t, '=', comma_sign); 887 quote2 = 0; 888 } 889 if (equals_sign == t) { t++; equals_sign = 0; } 890 if (comma_sign == t) // skip empty value 891 { 892 t++; i++; 893 continue; 894 } 895 if (equals_sign) // have parameter name 896 { 897 tmpi = findIdn(t, equals_sign - t); 898 i = tmpi; 899 if (tmpi < 0) 900 FMprintf("Param", "load2", FMLV_WARN, "Unknown property name for '%s' (ignored)", getName()); 901 t = equals_sign + 1; // t=value 902 } 902 903 #ifdef WARN_MISSING_NAME 903 else904 else 904 905 #ifdef SAVE_SELECTED_NAMES 905 if (!(flags(i)&PARAM_CANOMITNAME))906 if (!(flags(i)&PARAM_CANOMITNAME)) 906 907 #endif 907 {908 FMprintf("Param","load2",FMLV_WARN,"Missing property name in '%s' (assuming '%s')",909 getName(),id(i)?id(i):"unknown property?");910 }908 { 909 FMprintf("Param", "load2", FMLV_WARN, "Missing property name in '%s' (assuming '%s')", 910 getName(), id(i) ? id(i) : "unknown property?"); 911 } 911 912 #endif 912 if ((i>=0)&&id(i))913 {914 value=t;915 if (quote)916 {917 tmpvalue.copyFrom(quote+1,quote2-quote-1);918 sstringUnquote(tmpvalue);919 value=tmpvalue;920 valstop=quote2;921 }922 else923 if (przecinek<end) valstop=przecinek; else valstop=end;924 925 remember=*valstop;926 *(char*)valstop=0;927 ret=set(i,value);928 fields_loaded++;929 if (ret&(PSET_HITMAX|PSET_HITMIN))930 FMprintf("Param","load2",FMLV_WARN,"Adjusted '%s' in '%s' (was too %s)",931 id(i),getName(),(ret&PSET_HITMAX)?"big":"small");932 *(char*)valstop=remember;933 }934 935 if (i>=0) i++;913 if ((i >= 0) && id(i)) 914 { 915 value = t; 916 if (quote) 917 { 918 tmpvalue.copyFrom(quote + 1, quote2 - quote - 1); 919 sstringUnquote(tmpvalue); 920 value = tmpvalue; 921 valstop = quote2; 922 } 923 else 924 if (comma_sign < end) valstop = comma_sign; else valstop = end; 925 926 remember = *valstop; 927 *(char*)valstop = 0; 928 ret = set(i, value); 929 fields_loaded++; 930 if (ret&(PSET_HITMAX | PSET_HITMIN)) 931 FMprintf("Param", "load2", FMLV_WARN, "Adjusted '%s' in '%s' (was too %s)", 932 id(i), getName(), (ret&PSET_HITMAX) ? "big" : "small"); 933 *(char*)valstop = remember; 934 } 935 936 if (i >= 0) i++; 936 937 #ifdef __CODEGUARD__ 937 if (przecinek<end-1) t=przecinek+1; else return fields_loaded;938 if (comma_sign<end-1) t=comma_sign+1; else return fields_loaded; 938 939 #else 939 t=przecinek+1;940 t = comma_sign + 1; 940 941 #endif 941 } 942 return fields_loaded; 943 } 944 945 int Param::grmember(int g,int a) 946 { 947 if ((getGroupCount()<2)&&(!g)) 948 return (a<getPropCount())?a:-9999; 949 950 ParamEntry *e=entry(0); 951 int x=0,i=0; 952 for (;e->id;i++,e++) 953 { 954 if (e->group==g) 955 if (a==x) return i; else x++; 956 } 957 return -9999; 958 } 959 942 } 943 return fields_loaded; 944 } 945 946 int Param::grmember(int g, int a) 947 { 948 if ((getGroupCount() < 2) && (!g)) 949 return (a < getPropCount()) ? a : -9999; 950 951 ParamEntry *e = entry(0); 952 int x = 0, i = 0; 953 for (; e->id; i++, e++) 954 { 955 if (e->group == g) 956 if (a == x) return i; else x++; 957 } 958 return -9999; 959 } -
cpp/frams/param/param.h
r144 r154 33 33 #define PARAM_DEPRECATED 8192 34 34 35 // wynik z param::set() to kombinacja bitow: 36 35 // the result of param::set() is a combination of bits: 36 37 // read-only: cannot modify 37 38 #define PSET_RONLY 1 38 // oznacza,ze nie mozna zmienic 39 39 40 // value has been modified 40 41 #define PSET_CHANGED 2 41 // zaawansowane: wartosc zostala zmieniona 42 42 43 //value has been adjusted because it tried to exceed min or max 43 44 #define PSET_HITMIN 4 44 45 #define PSET_HITMAX 8 45 // wartosc zostala dopasowana do min lub max 46 46 47 // useful combination: need to get and display the value so that a user knows that the value they tried to set has been rejected or changed 47 48 #define PSET_WARN (PSET_RONLY | PSET_HITMIN | PSET_HITMAX) 48 // pozyteczna kombinacja - oznacza, ze nalezy pobrac i wyswietlic49 // wartosc, zeby uzytkownik wiedzial, ze jego propozycja jest odrzucona50 49 51 50 #define PSET_NOPROPERTY 16 … … 57 56 { 58 57 public: 59 virtual int getGroupCount()=0; ///< @returnnumber of property groups60 virtual int getPropCount()=0; ///< @returnnumber of properties61 62 virtual const char* getName()=0;63 virtual const char* getDescription() {return 0;}64 virtual ParamEntry *getParamTab() const {return NULL;}65 66 int findId(const char *n); ///< find id number for internal name67 int findIdn(const char *naz,int n);68 69 virtual const char *id(int i)=0; ///< get internal name70 virtual const char *name(int i)=0; ///< get humanreadable name71 72 /** get type description.73 74 75 76 77 78 79 80 virtual const char *type(int i)=0; 81 82 virtual const char *help(int i)=0; ///< get long description (tooltip)83 84 virtual int flags(int i)=0; ///< get flags85 86 virtual int group(int i)=0; ///< get group id for a property87 virtual const char *grname(int gi)=0; ///< get group name88 virtual int grmember(int gi,int n)=0; ///< get property id for n'th member of group "gi"89 90 virtual void call(int i,ExtValue* args,ExtValue *ret)=0;91 92 void get(int,ExtValue &retval); ///< most universal get, can be used for every datatype93 94 virtual SString getString(int)=0; ///< get string value, you can only use this for "s" type property95 virtual long getInt(int)=0; ///< get long value, you can only use this for "d" type property96 virtual double getDouble(int)=0; ///< get double value, you can only use this for "f" type property97 virtual ExtObject getObject(int)=0; ///< get object reference, you can only use this for "o" type property98 virtual ExtValue getExtValue(int)=0; ///< get extvalue object, you can only use this for "x" type property99 100 SString get(int); ///< old style get, can convert long or double to string101 SString getText(int); ///< like getString, returns enumeration label for subtype "d 0 n ~enum1~enum2...102 103 SString getStringById(const char*prop); ///< get string value, you can only use this for "s" type property104 long getIntById(const char* prop); ///< get long value, you can only use this for "d" type property105 double getDoubleById(const char* prop);///< get double value, you can only use this for "f" type property106 ExtObject getObjectById(const char* prop);///< get object reference, you can only use this for "o" type property107 ExtValue getExtValueById(const char* prop);///< get extvalue object, you can only use this for "x" type property108 ExtValue getById(const char* prop);109 110 int setInt(int i,const char* str);111 int setDouble(int i,const char* str);112 virtual int setInt(int,long)=0; ///< set long value, you can only use this for "d" type prop113 virtual int setDouble(int,double)=0; ///< set double value, you can only use this for "f" type prop114 virtual int setString(int,const SString &)=0; ///< set string value, you can only use this for "s" type prop115 virtual int setObject(int,const ExtObject &)=0; ///< set object reference, you can only use this for "o" type prop116 virtual int setExtValue(int,const ExtValue &)=0; ///< 4 in 1117 118 int set(int,const ExtValue &);///< most universal set, can be used for every datatype119 120 int set(int,const char*); ///< oldstyle set, can convert string to long or double121 122 int setIntById(const char* prop,long);///< set long value, you can only use this for "d" type prop123 int setDoubleById(const char* prop,double);///< set double value, you can only use this for "f" type prop124 int setStringById(const char* prop,const SString &);///< set string value, you can only use this for "s" type prop125 int setObjectById(const char* prop,const ExtObject &);///< set object reference, you can only use this for "o" type prop126 int setExtValueById(const char* prop,const ExtValue &);///< for ExtValue types only127 int setById(const char* prop,const ExtValue &);///< can be used for all property types128 129 /** get valid minimum, maximum and default value for property 'prop'130 131 int getMinMax(int prop,long& minumum,long& maximum,long& def);132 /** get valid minimum, maximum and default value for property 'prop'133 134 int getMinMax(int prop,double& minumum,double& maximum,double& def);135 136 virtual void setDefault(bool numericonly=false);137 virtual void setDefault(int i,bool numericonly=false);138 void setMin();139 void setMax();140 void setMin(int i);141 void setMax(int i);142 143 /** copy all property values from other ParamInterface object */144 void copyFrom(ParamInterface *src);145 146 /** copy all property values from compatible ParamInterface object.147 this method is more efficient than copyFrom,148 but can be used only if the other object has the same properties sequence, eg:149 150 151 152 void quickCopyFrom(ParamInterface *src);153 154 int save(VirtFILE*,const char* altname=NULL,bool force=0);155 int saveprop(VirtFILE*,int i,const char* p,bool force=0);156 int load(VirtFILE*);///< @returnnumber of fields loaded157 int load2(const SString &,int &);///< @returnnumber of fields loaded158 159 static const char* SERIALIZATION_PREFIX;58 virtual int getGroupCount() = 0; ///< @return the number of property groups 59 virtual int getPropCount() = 0; ///< @return the number of properties 60 61 virtual const char* getName() = 0; 62 virtual const char* getDescription() { return 0; } 63 virtual ParamEntry *getParamTab() const { return NULL; } 64 65 int findId(const char *n); ///< find id number for internal name 66 int findIdn(const char *naz, int n); 67 68 virtual const char *id(int i) = 0; ///< get internal name 69 virtual const char *name(int i) = 0; ///< get the human-readable name 70 71 /** get type description. 72 first character defines basic datatype: 73 - d = integer 74 - f = floating point 75 - s = string 76 - o = ExtObject 77 - x = ExtValue (universal datatype) 78 */ 79 virtual const char *type(int i) = 0; 80 81 virtual const char *help(int i) = 0; ///< get long description (tooltip) 82 83 virtual int flags(int i) = 0; ///< get flags 84 85 virtual int group(int i) = 0; ///< get group id for a property 86 virtual const char *grname(int gi) = 0; ///< get group name 87 virtual int grmember(int gi, int n) = 0; ///< get property id for n'th member of group "gi" 88 89 virtual void call(int i, ExtValue* args, ExtValue *ret) = 0; 90 91 void get(int, ExtValue &retval); ///< most universal get, can be used for every datatype 92 93 virtual SString getString(int) = 0; ///< get string value, you can only use this for "s" type property 94 virtual long getInt(int) = 0; ///< get long value, you can only use this for "d" type property 95 virtual double getDouble(int) = 0; ///< get double value, you can only use this for "f" type property 96 virtual ExtObject getObject(int) = 0; ///< get object reference, you can only use this for "o" type property 97 virtual ExtValue getExtValue(int) = 0; ///< get extvalue object, you can only use this for "x" type property 98 99 SString get(int); ///< old style get, can convert long or double to string 100 SString getText(int); ///< like getString, returns enumeration label for subtype "d 0 n ~enum1~enum2... 101 102 SString getStringById(const char*prop); ///< get string value, you can only use this for "s" type property 103 long getIntById(const char* prop); ///< get long value, you can only use this for "d" type property 104 double getDoubleById(const char* prop);///< get double value, you can only use this for "f" type property 105 ExtObject getObjectById(const char* prop);///< get object reference, you can only use this for "o" type property 106 ExtValue getExtValueById(const char* prop);///< get extvalue object, you can only use this for "x" type property 107 ExtValue getById(const char* prop); 108 109 int setInt(int i, const char* str); 110 int setDouble(int i, const char* str); 111 virtual int setInt(int, long) = 0; ///< set long value, you can only use this for "d" type prop 112 virtual int setDouble(int, double) = 0; ///< set double value, you can only use this for "f" type prop 113 virtual int setString(int, const SString &) = 0; ///< set string value, you can only use this for "s" type prop 114 virtual int setObject(int, const ExtObject &) = 0; ///< set object reference, you can only use this for "o" type prop 115 virtual int setExtValue(int, const ExtValue &) = 0; ///< 4 in 1 116 117 int set(int, const ExtValue &);///< most universal set, can be used for every datatype 118 119 int set(int, const char*); ///< oldstyle set, can convert string to long or double 120 121 int setIntById(const char* prop, long);///< set long value, you can only use this for "d" type prop 122 int setDoubleById(const char* prop, double);///< set double value, you can only use this for "f" type prop 123 int setStringById(const char* prop, const SString &);///< set string value, you can only use this for "s" type prop 124 int setObjectById(const char* prop, const ExtObject &);///< set object reference, you can only use this for "o" type prop 125 int setExtValueById(const char* prop, const ExtValue &); ///< for ExtValue types only 126 int setById(const char* prop, const ExtValue &);///< can be used for all property types 127 128 /** get valid minimum, maximum and default value for property 'prop' 129 @return 0 if min/max/def information is not available */ 130 int getMinMax(int prop, long& minumum, long& maximum, long& def); 131 /** get valid minimum, maximum and default value for property 'prop' 132 @return 0 if min/max/def information is not available */ 133 int getMinMax(int prop, double& minumum, double& maximum, double& def); 134 135 virtual void setDefault(bool numericonly = false); 136 virtual void setDefault(int i, bool numericonly = false); 137 void setMin(); 138 void setMax(); 139 void setMin(int i); 140 void setMax(int i); 141 142 /** copy all property values from other ParamInterface object */ 143 void copyFrom(ParamInterface *src); 144 145 /** Copy all property values from compatible ParamInterface object. 146 This method is more efficient than copyFrom, 147 but can be used only if the other object has the same properties sequence, e.g.: 148 - any two Param objects having common paramtab 149 - any ParamInterface object and the Param with paramtab constructed by ParamObject::makeParamTab 150 */ 151 void quickCopyFrom(ParamInterface *src); 152 153 int save(VirtFILE*, const char* altname = NULL, bool force = 0); 154 int saveprop(VirtFILE*, int i, const char* p, bool force = 0); 155 int load(VirtFILE*);///< @return the number of fields loaded 156 int load2(const SString &, int &);///< @return the number of fields loaded 157 158 static const char* SERIALIZATION_PREFIX; 160 159 }; 161 160 … … 193 192 struct ParamEntry 194 193 { 195 const char *id;196 short group,flags;197 const char *name,*type;198 long offset;199 void *fun1; ///< procedure or get200 void *fun2; ///< set201 const char *help;202 }; 203 204 struct ParamEntryConstructor : public ParamEntry194 const char *id; 195 short group, flags; 196 const char *name, *type; 197 long offset; 198 void *fun1; ///< procedure or get 199 void *fun2; ///< set 200 const char *help; 201 }; 202 203 struct ParamEntryConstructor : public ParamEntry 205 204 { 206 205 public: 207 ParamEntryConstructor(const char *_id,short _group=0,short _flags=0,const char *_name=0,const char *_type=0,long _offset=0,void *_fun1=0, void *_fun2=0, const char *_help=0) 208 {id=_id;group=_group;flags=_flags;name=_name;type=_type;offset=_offset;fun1=_fun1;fun2=_fun2;help=_help;} 209 }; 210 211 class SimpleAbstractParam: public virtual ParamInterface 206 ParamEntryConstructor(const char *_id, short _group = 0, short _flags = 0, const char *_name = 0, const char *_type = 0, long _offset = 0, void *_fun1 = 0, void *_fun2 = 0, const char *_help = 0) 207 { 208 id = _id; group = _group; flags = _flags; name = _name; type = _type; offset = _offset; fun1 = _fun1; fun2 = _fun2; help = _help; 209 } 210 }; 211 212 class SimpleAbstractParam : public virtual ParamInterface 212 213 { 213 214 protected: 214 virtual void *getTarget(int i);215 virtual ParamEntry *entry(int i)=0;216 const char* myname;217 bool dontcheckchanges;215 virtual void *getTarget(int i); 216 virtual ParamEntry *entry(int i) = 0; 217 const char* myname; 218 bool dontcheckchanges; 218 219 219 220 public: 220 void *object;221 222 const char* getName() {return myname;}223 void setName(const char* n) {myname=n;}224 225 /**226 @param t ParamEntry table227 @param o controlled object228 @param n Param's name229 */230 SimpleAbstractParam(void* o=0,const char*n=0):myname(n),dontcheckchanges(0),object(o) {}231 void setDontCheckChanges(bool x) {dontcheckchanges=x;}232 233 void select(void *o) {object=o;}234 void* getSelected() {return object;}235 236 const char *id(int i) {return (i>=getPropCount())?0:entry(i)->id;}237 const char *name(int i) {return entry(i)->name;}238 const char *type(int i) {return entry(i)->type;}239 const char *help(int i) {return entry(i)->help;}240 int flags(int i) {return entry(i)->flags;}241 int group(int i) {return entry(i)->group;}242 void call(int i,ExtValue* args,ExtValue *ret);243 244 SString getString(int);245 long getInt(int);246 double getDouble(int);247 ExtObject getObject(int);248 ExtValue getExtValue(int);249 250 template<typename T> void messageOnExceedRange(int i,int setflags, T valuetoset) ///< prints a warning when setflags indicates that allowed param range has been exceeded during set251 {252 if (setflags & (PSET_HITMIN | PSET_HITMAX))253 254 SString svaluetoset=SString::valueOf(valuetoset); //converts any type to SString255 SString actual=get(i);256 FMprintf("Param","set",FMLV_WARN,"Setting '%s.%s = %s' exceeded allowed range (too %s). Adjusted to %s.",257 getName(),id(i),(const char*)svaluetoset,(setflags&PSET_HITMAX)?"big":"small",(const char*)actual);258 259 } 260 261 int setInt(int,long);262 int setDouble(int,double);263 int setString(int,const SString &);264 int setObject(int,const ExtObject &);265 int setExtValue(int,const ExtValue &);266 267 int isequal(int i,void* defdata);268 void save2(SString&,void *defdata,bool addcr=true,bool all_names=true);269 270 virtual void setDefault(bool numericonly=false);271 virtual void setDefault(int i,bool numericonly=false);272 }; 273 274 class Param : public SimpleAbstractParam221 void *object; 222 223 const char* getName() { return myname; } 224 void setName(const char* n) { myname = n; } 225 226 /** 227 @param t ParamEntry table 228 @param o controlled object 229 @param n Param's name 230 */ 231 SimpleAbstractParam(void* o = 0, const char*n = 0) :myname(n), dontcheckchanges(0), object(o) {} 232 void setDontCheckChanges(bool x) { dontcheckchanges = x; } 233 234 void select(void *o) { object = o; } 235 void* getSelected() { return object; } 236 237 const char *id(int i) { return (i >= getPropCount()) ? 0 : entry(i)->id; } 238 const char *name(int i) { return entry(i)->name; } 239 const char *type(int i) { return entry(i)->type; } 240 const char *help(int i) { return entry(i)->help; } 241 int flags(int i) { return entry(i)->flags; } 242 int group(int i) { return entry(i)->group; } 243 void call(int i, ExtValue* args, ExtValue *ret); 244 245 SString getString(int); 246 long getInt(int); 247 double getDouble(int); 248 ExtObject getObject(int); 249 ExtValue getExtValue(int); 250 251 template<typename T> void messageOnExceedRange(int i, int setflags, T valuetoset) ///< prints a warning when setflags indicates that allowed param range has been exceeded during set 252 { 253 if (setflags & (PSET_HITMIN | PSET_HITMAX)) 254 { 255 SString svaluetoset = SString::valueOf(valuetoset); //converts any type to SString 256 SString actual = get(i); 257 FMprintf("Param", "set", FMLV_WARN, "Setting '%s.%s = %s' exceeded allowed range (too %s). Adjusted to %s.", 258 getName(), id(i), (const char*)svaluetoset, (setflags&PSET_HITMAX) ? "big" : "small", (const char*)actual); 259 } 260 } 261 262 int setInt(int, long); 263 int setDouble(int, double); 264 int setString(int, const SString &); 265 int setObject(int, const ExtObject &); 266 int setExtValue(int, const ExtValue &); 267 268 int isequal(int i, void* defdata); 269 void save2(SString&, void *defdata, bool addcr = true, bool all_names = true); 270 271 virtual void setDefault(bool numericonly = false); 272 virtual void setDefault(int i, bool numericonly = false); 273 }; 274 275 class Param : public SimpleAbstractParam 275 276 { 276 277 protected: 277 ParamEntry *entry(int i) {return tab+tab[0].group+i;}278 ParamEntry *entry(int i) { return tab + tab[0].group + i; } 278 279 public: 279 ParamEntry *tab; 280 /** 281 @param t ParamEntry table 282 @param o controlled object 283 @param n Param's name 284 */ 285 286 Param(ParamEntry *t=0,void* o=0,const char*n=0):SimpleAbstractParam(o,n),tab(t) 287 {if (!n&&tab) myname=tab[0].name;} 288 289 Param(const Param& p):SimpleAbstractParam(p.object,p.myname),tab(p.tab) {} 290 void operator=(const Param&p) {object=p.object; myname=p.myname; tab=p.tab;} 291 292 const char* getDescription() {return tab[0].type;} 293 294 int getGroupCount() {return tab[0].group;} 295 int getPropCount() {return tab[0].flags;} 296 const char *grname(int i) {return (i<getGroupCount())?tab[i].id:0;} 297 int grmember(int,int); 298 void setParamTab(ParamEntry *t,int dontupdatename=0) {tab=t; if ((!dontupdatename)&&tab) myname=tab[0].name; } 299 ParamEntry *getParamTab() const {return tab;} 280 ParamEntry *tab; 281 /** 282 @param t ParamEntry table 283 @param o controlled object 284 @param n Param's name 285 */ 286 287 Param(ParamEntry *t = 0, void* o = 0, const char*n = 0) :SimpleAbstractParam(o, n), tab(t) 288 { 289 if (!n&&tab) myname = tab[0].name; 290 } 291 292 Param(const Param& p) :SimpleAbstractParam(p.object, p.myname), tab(p.tab) {} 293 void operator=(const Param&p) { object = p.object; myname = p.myname; tab = p.tab; } 294 295 const char* getDescription() { return tab[0].type; } 296 297 int getGroupCount() { return tab[0].group; } 298 int getPropCount() { return tab[0].flags; } 299 const char *grname(int i) { return (i < getGroupCount()) ? tab[i].id : 0; } 300 int grmember(int, int); 301 void setParamTab(ParamEntry *t, int dontupdatename = 0) { tab = t; if ((!dontupdatename) && tab) myname = tab[0].name; } 302 ParamEntry *getParamTab() const { return tab; } 300 303 }; 301 304 -
cpp/frams/util/rndutil.cpp
r121 r154 9 9 unsigned short pseudornd(short x) 10 10 { 11 static long seed=0;12 long y;13 if (x<=0) {seed=-x; return 0;}14 seed=(y=(3677*seed+3680)&0x7fffffff)-1;15 return (unsigned short)(((unsigned short)y)%(x));//rzutowanie y->unsigned short to pewnie blad bo zmniejsza wartosc ktorej sie potem robi modulo, ale pseudornd sluzy chyba tylko do generowania randomowych world map? i modulo i tak jest tam bardzo male, lepiej niczego nie zmieniac bo po co maja pliki z ustawieniami zmienic swoje przypadkowe znaczenie11 static long seed = 0; 12 long y; 13 if (x <= 0) { seed = -x; return 0; } 14 seed = (y = (3677 * seed + 3680) & 0x7fffffff) - 1; 15 return (unsigned short)(((unsigned short)y) % (x)); //rzutowanie y->unsigned short to pewnie blad bo zmniejsza wartosc ktorej sie potem robi modulo, ale pseudornd sluzy chyba tylko do generowania randomowych world map? i modulo i tak jest tam bardzo male, lepiej niczego nie zmieniac bo po co maja pliki z ustawieniami zmienic swoje przypadkowe znaczenie 16 16 } 17 17 18 18 double CustomRnd(double *tab) 19 19 { 20 double *range=tab+1+2*randomN((int)(0.5+tab[0]));21 return range[0]+rnd0N(range[1]-range[0]);20 double *range = tab + 1 + 2 * randomN((int)(0.5 + tab[0])); 21 return range[0] + rnd0N(range[1] - range[0]); 22 22 } 23 23 24 24 double RandomGener::Uni(double begin, double end) 25 25 { 26 return begin+rnd01*(end-begin);26 return begin + rnd01*(end - begin); 27 27 } 28 28 29 29 double RandomGener::GaussStd() 30 30 { 31 if (isNextGauss) {isNextGauss=0; return nextGauss;}32 double v1,v2,s;33 do {34 v1=2*rnd01-1; //-1..135 v2=2*rnd01-1; //-1..136 s=v1*v1+v2*v2;37 } while (s>=1);38 double mult=sqrt(-2*log(s)/s);39 nextGauss=v2*mult;40 isNextGauss=1;41 return v1*mult;31 if (isNextGauss) { isNextGauss = 0; return nextGauss; } 32 double v1, v2, s; 33 do { 34 v1 = 2 * rnd01 - 1; //-1..1 35 v2 = 2 * rnd01 - 1; //-1..1 36 s = v1*v1 + v2*v2; 37 } while (s >= 1); 38 double mult = sqrt(-2 * log(s) / s); 39 nextGauss = v2*mult; 40 isNextGauss = 1; 41 return v1*mult; 42 42 } 43 43 44 double RandomGener::Gauss(double m,double s) 45 {return m+s*GaussStd();} 44 double RandomGener::Gauss(double m, double s) 45 { 46 return m + s*GaussStd(); 47 } 46 48 47 49 RandomGener RndGen;
Note: See TracChangeset
for help on using the changeset viewer.