source: cpp/gdk/param.h @ 104

Last change on this file since 104 was 104, checked in by sz, 11 years ago

introducing object de/serialization - see serialtest.cpp
the core GDK classes can be now used in multiple threads (ifdef MULTITHREADED)

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