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

Last change on this file since 332 was 319, checked in by Maciej Komosinski, 10 years ago

Fixed compilation warnings

  • Property svn:eol-style set to native
File size: 12.8 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#ifndef _PARAM_H_
6#define _PARAM_H_
7
8#include <stdio.h>
9#include <stdint.h>
10#include <frams/util/sstring.h>
11#include <frams/util/list.h>
12#include <frams/util/statrick.h>
13#include <frams/virtfile/virtfile.h>
14#include <common/framsg.h>
15
16class ExtValue;
17class ExtObject;
18
19// ParamInterface flags:
20#define PARAM_READONLY       1  //< Param is not able to change this member
21#define PARAM_DONTSAVE       2  //< Param will not save this member
22#define PARAM_SETLEVEL(x) (((x)&3)<<2)  //< internal use
23#define PARAM_LEVEL(x)    (((x)>>2)&3)  //< internal use
24#define PARAM_USERREADONLY  16  //< GUI should not change this member (even if Param can)
25#define PARAM_USERHIDDEN    32  //< GUI should not display this member
26#define MUTPARAM_ALLOCENTRY 64  //< for mutableparam (private!)
27#define MUTPARAM_ALLOCDATA 128  //< for mutableparam (private!)
28#define PARAM_NOSTATIC  256     //< (FramScript) don't access this member in a static object (ClassName.field)
29#define PARAM_CONST     512     //< (FramScript) constant value
30#define PARAM_CANOMITNAME 1024  //< affects Param::save2()/load2() - for example one-liners in f0 genetic encoding
31#define PARAM_DONTLOAD    2048  //< Param::load() skips this field
32#define PARAM_NOISOLATION 4096  //< don't use proxy object in master/slave interactions
33#define PARAM_DEPRECATED  8192  //< this member is deprecated
34
35typedef int32_t paInt;
36#define PA_INT_SCANF "%d"
37#define PA_INT_SCANF_X "%x"
38
39// the result of param::set() is a combination of bits:
40
41// read-only: cannot modify
42#define PSET_RONLY      1
43
44// value has been modified
45#define PSET_CHANGED    2
46
47//value has been adjusted because it tried to exceed min or max
48#define PSET_HITMIN     4
49#define PSET_HITMAX     8
50
51// 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
52#define PSET_WARN (PSET_RONLY | PSET_HITMIN | PSET_HITMAX)
53
54#define PSET_NOPROPERTY 16
55
56struct ParamEntry;
57
58/** Property get/set interface - runtime access to named properties */
59class ParamInterface
60{
61public:
62        virtual ~ParamInterface() {}
63
64        virtual int getGroupCount() = 0; ///< @return the number of property groups
65        virtual int getPropCount() = 0; ///< @return the number of properties
66
67        virtual const char* getName() = 0;
68        virtual const char* getDescription() { return 0; }
69        virtual ParamEntry *getParamTab() const { return NULL; }
70
71        int findId(const char *n);      ///< find id number for internal name
72        int findIdn(const char *naz, int n);
73
74        virtual const char *id(int i) = 0;      ///< get internal name
75        virtual const char *name(int i) = 0;    ///< get the human-readable name
76
77        /** get type description.
78                first character defines basic datatype:
79                - d = integer
80                - f = floating point
81                - s = string
82                - o = ExtObject
83                - x = ExtValue (universal datatype)
84                */
85        virtual const char *type(int i) = 0;
86
87        virtual const char *help(int i) = 0;    ///< get long description (tooltip)
88
89        virtual int flags(int i) = 0;           ///< get flags
90
91        virtual int group(int i) = 0;           ///< get group id for a property
92        virtual const char *grname(int gi) = 0; ///< get group name
93        virtual int grmember(int gi, int n) = 0;        ///< get property id for n'th member of group "gi"
94
95        virtual void call(int i, ExtValue* args, ExtValue *ret) = 0;
96
97        void get(int, ExtValue &retval);        ///< most universal get, can be used for every datatype
98
99        virtual SString getString(int) = 0;     ///< get string value, you can only use this for "s" type property
100        virtual paInt getInt(int) = 0;  ///< get long value, you can only use this for "d" type property
101        virtual double getDouble(int) = 0;      ///< get double value, you can only use this for "f" type property
102        virtual ExtObject getObject(int) = 0;   ///< get object reference, you can only use this for "o" type property
103        virtual ExtValue getExtValue(int) = 0;  ///< get extvalue object, you can only use this for "x" type property
104
105        SString get(int);               ///< old style get, can convert long or double to string
106        SString getText(int);           ///< like getString, returns enumeration label for subtype "d 0 n ~enum1~enum2...
107
108        SString getStringById(const char*prop);  ///< get string value, you can only use this for "s" type property
109        paInt getIntById(const char* prop);    ///< get long value, you can only use this for "d" type property
110        double getDoubleById(const char* prop);///< get double value, you can only use this for "f" type property
111        ExtObject getObjectById(const char* prop);///< get object reference, you can only use this for "o" type property
112        ExtValue getExtValueById(const char* prop);///< get extvalue object, you can only use this for "x" type property
113        ExtValue getById(const char* prop);
114
115        int setInt(int i, const char* str);
116        int setDouble(int i, const char* str);
117        virtual int setInt(int, paInt) = 0;             ///< set long value, you can only use this for "d" type prop
118        virtual int setDouble(int, double) = 0; ///< set double value, you can only use this for "f" type prop
119        virtual int setString(int, const SString &) = 0;        ///< set string value, you can only use this for "s" type prop
120        virtual int setObject(int, const ExtObject &) = 0;      ///< set object reference, you can only use this for "o" type prop
121        virtual int setExtValue(int, const ExtValue &) = 0;     ///< 4 in 1
122
123        int set(int, const ExtValue &);///< most universal set, can be used for every datatype
124
125        int set(int, const char*);              ///< oldstyle set, can convert string to long or double
126
127        int setIntById(const char* prop, paInt);///< set long value, you can only use this for "d" type prop
128        int setDoubleById(const char* prop, double);///< set double value, you can only use this for "f" type prop
129        int setStringById(const char* prop, const SString &);///< set string value, you can only use this for "s" type prop
130        int setObjectById(const char* prop, const ExtObject &);///< set object reference, you can only use this for "o" type prop
131        int setExtValueById(const char* prop, const ExtValue &); ///< for ExtValue types only
132        int setById(const char* prop, const ExtValue &);///< can be used for all property types
133
134        /** get valid minimum, maximum and default value for property 'prop'
135                @return 0 if min/max/def information is not available */
136        int getMinMax(int prop, paInt& minumum, paInt& maximum, paInt& def);
137        /** get valid minimum, maximum and default value for property 'prop'
138                @return 0 if min/max/def information is not available */
139        int getMinMax(int prop, double& minumum, double& maximum, double& def);
140        int getMinMax(int prop, int& minumum, int& maximum, SString& def);
141
142        virtual void setDefault();
143        virtual void setDefault(int i);
144        void setMin();
145        void setMax();
146        void setMin(int i);
147        void setMax(int i);
148
149        /** copy all property values from other ParamInterface object */
150        void copyFrom(ParamInterface *src);
151
152        /** Copy all property values from compatible ParamInterface object.
153                This method is more efficient than copyFrom,
154                but can be used only if the other object has the same properties sequence, e.g.:
155                - any two Param objects having common paramtab
156                - any ParamInterface object and the Param with paramtab constructed by ParamObject::makeParamTab
157                */
158        void quickCopyFrom(ParamInterface *src);
159
160        int save(VirtFILE*, const char* altname = NULL, bool force = 0);
161        int saveprop(VirtFILE*, int i, const char* p, bool force = 0);
162        int load(VirtFILE*,bool warn_unknown_fields=true,bool *abortable=NULL);///< @return the number of fields loaded
163        int load2(const SString &, int &);///< @return the number of fields loaded
164
165        static const char* SERIALIZATION_PREFIX;
166
167#ifdef DEBUG
168        virtual void sanityCheck(int i) {}
169#endif
170};
171
172// implementations:
173
174extern char MakeCodeGuardHappy;
175
176#define PROCOFFSET(_proc_) ( (void (*)(void*,ExtValue*,ExtValue*)) &(FIELDSTRUCT :: _proc_ ## _statrick))
177#define STATICPROCOFFSET(_proc_) ( (void (*)(void*,ExtValue*,ExtValue*)) &(FIELDSTRUCT :: _proc_))
178#define GETOFFSET(_proc_) ( (void (*)(void*,ExtValue*)) &(FIELDSTRUCT :: _proc_ ## _statrick))
179#define SETOFFSET(_proc_) ( (int (*)(void*,const ExtValue*)) &(FIELDSTRUCT :: _proc_ ## _statrick))
180
181#define FIELDOFFSET(_fld_) ((intptr_t)((char*)(&((FIELDSTRUCT*)&MakeCodeGuardHappy)->_fld_)-((char*)((FIELDSTRUCT*)&MakeCodeGuardHappy))))
182
183#ifdef DEBUG
184#define PARAM_ILLEGAL_OFFSET ((intptr_t)0xdeadbeef)
185#else
186#define PARAM_ILLEGAL_OFFSET 0
187#endif
188
189#define FIELD(_fld_) FIELDOFFSET(_fld_),0,0
190#define LONGOFFSET(_o_) (_o_),0,0
191#define PROCEDURE(_proc_) PARAM_ILLEGAL_OFFSET,(void*)PROCOFFSET(_proc_),0
192#define STATICPROCEDURE(_proc_) PARAM_ILLEGAL_OFFSET,(void*)STATICPROCOFFSET(_proc_),0
193#define GETSET(_proc_) PARAM_ILLEGAL_OFFSET,(void*)GETOFFSET(get_ ## _proc_),(void*)SETOFFSET(set_ ## _proc_)
194#define GETFIELD(_proc_) FIELDOFFSET(_proc_),(void*)GETOFFSET(get_ ## _proc_),0
195#define SETFIELD(_proc_) FIELDOFFSET(_proc_),0,(void*)SETOFFSET(set_ ## _proc_)
196#define GETONLY(_proc_) PARAM_ILLEGAL_OFFSET,(void*)GETOFFSET(get_ ## _proc_),0
197#define SETONLY(_proc_) PARAM_ILLEGAL_OFFSET,0,(void*)SETOFFSET(set_ ## _proc_)
198
199#define PARAMPROCARGS ExtValue* args,ExtValue* ret
200#define PARAMSETARGS const ExtValue* arg
201#define PARAMGETARGS ExtValue* ret
202
203#define PARAMPROCDEF(name) STATRICKDEF2(name,ExtValue*,ExtValue*)
204#define PARAMGETDEF(name) STATRICKDEF1(get_ ## name,ExtValue*)
205#define PARAMSETDEF(name) STATRICKRDEF1(int,set_ ## name,const ExtValue*)
206
207///////////////////////////////
208
209struct ParamEntry
210{
211        const char *id;
212        short group, flags;
213        const char *name, *type;
214        intptr_t offset;
215        void *fun1; ///< procedure or get
216        void *fun2; ///< set
217        const char *help;
218};
219
220struct ParamEntryConstructor : public ParamEntry
221{
222public:
223        ParamEntryConstructor(const char *_id, short _group = 0, short _flags = 0, const char *_name = 0, const char *_type = 0, intptr_t _offset = 0, void *_fun1 = 0, void *_fun2 = 0, const char *_help = 0)
224        {
225                id = _id; group = _group; flags = _flags; name = _name; type = _type; offset = _offset; fun1 = _fun1; fun2 = _fun2; help = _help;
226        }
227};
228
229class SimpleAbstractParam : public virtual ParamInterface
230{
231protected:
232        virtual void *getTarget(int i);
233        const char* myname;
234        bool dontcheckchanges;
235
236public:
237        void *object;
238
239        const char* getName() { return myname; }
240        void setName(const char* n) { myname = n; }
241
242        /**
243                @param t ParamEntry table
244                @param o controlled object
245                @param n Param's name
246                */
247        SimpleAbstractParam(void* o = 0, const char*n = 0) :myname(n), dontcheckchanges(0), object(o) {}
248        void setDontCheckChanges(bool x) { dontcheckchanges = x; }
249
250        void select(void *o) { object = o; }
251        void* getSelected() { return object; }
252
253        virtual ParamEntry *entry(int i) = 0;
254        const char *id(int i) { return (i >= getPropCount()) ? 0 : entry(i)->id; }
255        const char *name(int i) { return entry(i)->name; }
256        const char *type(int i) { return entry(i)->type; }
257        const char *help(int i) { return entry(i)->help; }
258        int flags(int i) { return entry(i)->flags; }
259        int group(int i) { return entry(i)->group; }
260        void call(int i, ExtValue* args, ExtValue *ret);
261
262        SString getString(int);
263        paInt getInt(int);
264        double getDouble(int);
265        ExtObject getObject(int);
266        ExtValue getExtValue(int);
267
268        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
269        {
270                if (setflags & (PSET_HITMIN | PSET_HITMAX))
271                {
272                        SString svaluetoset = SString::valueOf(valuetoset); //converts any type to SString
273                        SString actual = get(i);
274                        FMprintf("Param", "set", FMLV_WARN, "Setting '%s.%s = %s' exceeded allowed range (too %s). Adjusted to %s.",
275                                getName(), id(i), (const char*)svaluetoset, (setflags&PSET_HITMAX) ? "big" : "small", (const char*)actual);
276                }
277        }
278
279        int setInt(int, paInt);
280        int setDouble(int, double);
281        int setString(int, const SString &);
282        int setObject(int, const ExtObject &);
283        int setExtValue(int, const ExtValue &);
284
285        int isequal(int i, void* defdata);
286        void save2(SString&, void *defdata, bool addcr = true, bool all_names = true);
287
288        virtual void setDefault();
289        virtual void setDefault(int i);
290
291#ifdef DEBUG
292        void sanityCheck(int i);
293#endif
294};
295
296class Param : public SimpleAbstractParam
297{
298protected:
299        ParamEntry *entry(int i) { return tab + tab[0].group + i; }
300public:
301        ParamEntry *tab;
302        /**
303                @param t ParamEntry table
304                @param o controlled object
305                @param n Param's name
306                */
307
308        Param(ParamEntry *t = 0, void* o = 0, const char*n = 0) :SimpleAbstractParam(o, n), tab(t)
309        {
310                if (!n&&tab) myname = tab[0].name;
311        }
312
313        Param(const Param& p) :SimpleAbstractParam(p.object, p.myname), tab(p.tab) {}
314        void operator=(const Param&p) { object = p.object; myname = p.myname; tab = p.tab; }
315
316        const char* getDescription() { return tab[0].type; }
317
318        int getGroupCount() { return tab[0].group; }
319        int getPropCount() { return tab[0].flags; }
320        const char *grname(int i) { return (i < getGroupCount()) ? tab[i].id : 0; }
321        int grmember(int, int);
322        void setParamTab(ParamEntry *t, int dontupdatename = 0) { tab = t; if ((!dontupdatename) && tab) myname = tab[0].name; }
323        ParamEntry *getParamTab() const { return tab; }
324};
325
326extern ParamEntry empty_paramtab[];
327
328#endif
Note: See TracBrowser for help on using the repository browser.