source: cpp/frams/param/param.h @ 144

Last change on this file since 144 was 144, checked in by sz, 6 years ago

Param and ExtValue? improvements (better control on conversions, "load" returns the number of loaded fields)

  • Property svn:eol-style set to native
File size: 11.4 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 2002-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#ifndef _PARAM_H_
6#define _PARAM_H_
7
8#include <stdio.h>
9#include <frams/util/sstring.h>
10#include <frams/util/list.h>
11#include <frams/util/statrick.h>
12#include <frams/virtfile/virtfile.h>
13#include <common/framsg.h>
14
15class ExtValue;
16class ExtObject;
17
18// ParamInterface flags:
19#define PARAM_READONLY  1
20#define PARAM_DONTSAVE  2
21#define PARAM_SETLEVEL(x) (((x)&3)<<2)
22#define PARAM_LEVEL(x) (((x)>>2)&3)
23#define PARAM_USERREADONLY 16
24#define PARAM_USERHIDDEN 32
25// for mutableparam (private!)
26#define MUTPARAM_ALLOCENTRY 64
27#define MUTPARAM_ALLOCDATA 128
28#define PARAM_NOSTATIC 256
29#define PARAM_CONST 512
30#define PARAM_CANOMITNAME 1024
31#define PARAM_DONTLOAD  2048
32#define PARAM_NOISOLATION       4096
33#define PARAM_DEPRECATED        8192
34
35// wynik z param::set() to kombinacja bitow:
36
37#define PSET_RONLY      1
38// oznacza,ze nie mozna zmienic
39
40#define PSET_CHANGED    2
41// zaawansowane: wartosc zostala zmieniona
42
43#define PSET_HITMIN     4
44#define PSET_HITMAX     8
45// wartosc zostala dopasowana do min lub max
46
47#define PSET_WARN (PSET_RONLY | PSET_HITMIN | PSET_HITMAX)
48// pozyteczna kombinacja - oznacza, ze nalezy pobrac i wyswietlic
49// wartosc, zeby uzytkownik wiedzial, ze jego propozycja jest odrzucona
50
51#define PSET_NOPROPERTY 16
52
53struct ParamEntry;
54
55/** Property get/set interface - runtime access to named properties */
56class ParamInterface
57{
58public:
59virtual int getGroupCount()=0; ///< @return number of property groups
60virtual int getPropCount()=0; ///< @return number of properties
61
62virtual const char* getName()=0;
63virtual const char* getDescription() {return 0;}
64virtual ParamEntry *getParamTab() const {return NULL;}
65
66int findId(const char *n);      ///< find id number for internal name
67int findIdn(const char *naz,int n);
68
69virtual const char *id(int i)=0;        ///< get internal name
70virtual const char *name(int i)=0;      ///< get human readable name
71
72/** get type description.
73    first character defines basic datatype:
74    - d = integer
75    - f = floating point
76    - s = string
77    - o = ExtObject
78    - x = ExtValue (universal datatype)
79 */
80virtual const char *type(int i)=0;     
81
82virtual const char *help(int i)=0;      ///< get long description (tooltip)
83
84virtual int flags(int i)=0;             ///< get flags
85
86virtual int group(int i)=0;             ///< get group id for a property
87virtual const char *grname(int gi)=0;   ///< get group name
88virtual int grmember(int gi,int n)=0;   ///< get property id for n'th member of group "gi"
89
90virtual void call(int i,ExtValue* args,ExtValue *ret)=0;
91
92void get(int,ExtValue &retval); ///< most universal get, can be used for every datatype
93
94virtual SString getString(int)=0;       ///< get string value, you can only use this for "s" type property
95virtual long getInt(int)=0;     ///< get long value, you can only use this for "d" type property
96virtual double getDouble(int)=0;        ///< get double value, you can only use this for "f" type property
97virtual ExtObject getObject(int)=0;     ///< get object reference, you can only use this for "o" type property
98virtual ExtValue getExtValue(int)=0;    ///< get extvalue object, you can only use this for "x" type property
99
100SString get(int);               ///< old style get, can convert long or double to string
101SString getText(int);           ///< like getString, returns enumeration label for subtype "d 0 n ~enum1~enum2...
102
103SString getStringById(const char*prop);  ///< get string value, you can only use this for "s" type property
104long getIntById(const char* prop);    ///< get long value, you can only use this for "d" type property
105double getDoubleById(const char* prop);///< get double value, you can only use this for "f" type property
106ExtObject getObjectById(const char* prop);///< get object reference, you can only use this for "o" type property
107ExtValue getExtValueById(const char* prop);///< get extvalue object, you can only use this for "x" type property
108ExtValue getById(const char* prop);
109
110int setInt(int i,const char* str);
111int setDouble(int i,const char* str);
112virtual int setInt(int,long)=0;         ///< set long value, you can only use this for "d" type prop
113virtual int setDouble(int,double)=0;    ///< set double value, you can only use this for "f" type prop
114virtual int setString(int,const SString &)=0;   ///< set string value, you can only use this for "s" type prop
115virtual int setObject(int,const ExtObject &)=0;         ///< set object reference, you can only use this for "o" type prop
116virtual int setExtValue(int,const ExtValue &)=0;        ///< 4 in 1
117
118int set(int,const ExtValue &);///< most universal set, can be used for every datatype
119
120int set(int,const char*);               ///< oldstyle set, can convert string to long or double
121
122int setIntById(const char* prop,long);///< set long value, you can only use this for "d" type prop
123int setDoubleById(const char* prop,double);///< set double value, you can only use this for "f" type prop
124int setStringById(const char* prop,const SString &);///< set string value, you can only use this for "s" type prop
125int setObjectById(const char* prop,const ExtObject &);///< set object reference, you can only use this for "o" type prop
126int setExtValueById(const char* prop,const ExtValue &); ///< for ExtValue types only
127int setById(const char* prop,const ExtValue &);///< can be used for all property types
128
129/** get valid minimum, maximum and default value for property 'prop'
130    @return 0 if min/max/def information is not available */
131int getMinMax(int prop,long& minumum,long& maximum,long& def);
132/** get valid minimum, maximum and default value for property 'prop'
133    @return 0 if min/max/def information is not available */
134int getMinMax(int prop,double& minumum,double& maximum,double& def);
135
136virtual void setDefault(bool numericonly=false);
137virtual void setDefault(int i,bool numericonly=false);
138void setMin();
139void setMax();
140void setMin(int i);
141void setMax(int i);
142
143/** copy all property values from other ParamInterface object */
144void 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    - any two Param objects having common paramtab
150    - any ParamInterface object and the Param with paramtab constructed by ParamObject::makeParamTab
151 */
152void quickCopyFrom(ParamInterface *src);
153
154int save(VirtFILE*,const char* altname=NULL,bool force=0);
155int saveprop(VirtFILE*,int i,const char* p,bool force=0);
156int load(VirtFILE*);///< @return number of fields loaded
157int load2(const SString &,int &);///< @return number of fields loaded
158
159static const char* SERIALIZATION_PREFIX;
160};
161
162// implementations:
163
164extern char MakeCodeGuardHappy;
165
166#define PROCOFFSET(_proc_) ( (void (*)(void*,ExtValue*,ExtValue*)) &(FIELDSTRUCT :: _proc_ ## _statrick))
167#define STATICPROCOFFSET(_proc_) ( (void (*)(void*,ExtValue*,ExtValue*)) &(FIELDSTRUCT :: _proc_))
168#define GETOFFSET(_proc_) ( (void (*)(void*,ExtValue*)) &(FIELDSTRUCT :: _proc_ ## _statrick))
169#define SETOFFSET(_proc_) ( (int (*)(void*,const ExtValue*)) &(FIELDSTRUCT :: _proc_ ## _statrick))
170
171#define FIELDOFFSET(_fld_) ((long)((char*)(&((FIELDSTRUCT*)&MakeCodeGuardHappy)->_fld_)-((char*)((FIELDSTRUCT*)&MakeCodeGuardHappy))))
172
173#define FIELD(_fld_) FIELDOFFSET(_fld_),0,0
174#define LONGOFFSET(_o_) (_o_),0,0
175#define PROCEDURE(_proc_) 0,(void*)PROCOFFSET(_proc_),0
176#define STATICPROCEDURE(_proc_) 0,(void*)STATICPROCOFFSET(_proc_),0
177#define GETSET(_proc_) 0,(void*)GETOFFSET(get_ ## _proc_),(void*)SETOFFSET(set_ ## _proc_)
178#define GETFIELD(_proc_) FIELDOFFSET(_proc_),(void*)GETOFFSET(get_ ## _proc_),0
179#define SETFIELD(_proc_) FIELDOFFSET(_proc_),0,(void*)SETOFFSET(set_ ## _proc_)
180#define GETONLY(_proc_) 0,(void*)GETOFFSET(get_ ## _proc_),0
181#define SETONLY(_proc_) 0,0,(void*)SETOFFSET(set_ ## _proc_)
182
183#define PARAMPROCARGS ExtValue* args,ExtValue* ret
184#define PARAMSETARGS const ExtValue* arg
185#define PARAMGETARGS ExtValue* ret
186
187#define PARAMPROCDEF(name) STATRICKDEF2(name,ExtValue*,ExtValue*)
188#define PARAMGETDEF(name) STATRICKDEF1(get_ ## name,ExtValue*)
189#define PARAMSETDEF(name) STATRICKRDEF1(int,set_ ## name,const ExtValue*)
190
191///////////////////////////////
192
193struct ParamEntry
194{
195const char *id;
196short group,flags;
197const char *name,*type;
198long offset;
199void *fun1; ///< procedure or get
200void *fun2; ///< set
201const char *help;
202};
203
204struct ParamEntryConstructor: public ParamEntry
205{
206public:
207ParamEntryConstructor(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
211class SimpleAbstractParam: public virtual ParamInterface
212{
213protected:
214virtual void *getTarget(int i);
215virtual ParamEntry *entry(int i)=0;
216const char* myname;
217bool dontcheckchanges;
218
219public:
220void *object;
221
222const char* getName() {return myname;}
223void setName(const char* n) {myname=n;}
224
225/**
226        @param t ParamEntry table
227        @param o controlled object
228        @param n Param's name
229*/
230SimpleAbstractParam(void* o=0,const char*n=0):myname(n),dontcheckchanges(0),object(o) {}
231void setDontCheckChanges(bool x) {dontcheckchanges=x;}
232
233void select(void *o) {object=o;}
234void* getSelected() {return object;}
235
236const char *id(int i) {return (i>=getPropCount())?0:entry(i)->id;}
237const char *name(int i) {return entry(i)->name;}
238const char *type(int i) {return entry(i)->type;}
239const char *help(int i) {return entry(i)->help;}
240int flags(int i) {return entry(i)->flags;}
241int group(int i) {return entry(i)->group;}
242void call(int i,ExtValue* args,ExtValue *ret);
243
244SString getString(int);
245long getInt(int);
246double getDouble(int);
247ExtObject getObject(int);
248ExtValue getExtValue(int);
249
250template<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
251{
252        if (setflags & (PSET_HITMIN | PSET_HITMAX))
253    {
254        SString svaluetoset=SString::valueOf(valuetoset); //converts any type to SString
255        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
261int setInt(int,long);
262int setDouble(int,double);
263int setString(int,const SString &);
264int setObject(int,const ExtObject &);
265int setExtValue(int,const ExtValue &);
266
267int isequal(int i,void* defdata);
268void save2(SString&,void *defdata,bool addcr=true,bool all_names=true);
269
270virtual void setDefault(bool numericonly=false);
271virtual void setDefault(int i,bool numericonly=false);
272};
273
274class Param: public SimpleAbstractParam
275{
276protected:
277ParamEntry *entry(int i) {return tab+tab[0].group+i;}
278public:
279ParamEntry *tab;
280/**
281        @param t ParamEntry table
282        @param o controlled object
283        @param n Param's name
284*/
285
286Param(ParamEntry *t=0,void* o=0,const char*n=0):SimpleAbstractParam(o,n),tab(t)
287{if (!n&&tab) myname=tab[0].name;}
288
289Param(const Param& p):SimpleAbstractParam(p.object,p.myname),tab(p.tab) {}
290void operator=(const Param&p) {object=p.object; myname=p.myname; tab=p.tab;}
291
292const char* getDescription() {return tab[0].type;}
293
294int getGroupCount() {return tab[0].group;}
295int getPropCount() {return tab[0].flags;}
296const char *grname(int i) {return (i<getGroupCount())?tab[i].id:0;}
297int grmember(int,int);
298void setParamTab(ParamEntry *t,int dontupdatename=0) {tab=t; if ((!dontupdatename)&&tab) myname=tab[0].name; }
299ParamEntry *getParamTab() const {return tab;}
300};
301
302extern ParamEntry empty_paramtab[];
303
304#endif
Note: See TracBrowser for help on using the repository browser.