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

Last change on this file since 1155 was 1155, checked in by Maciej Komosinski, 12 months ago

Added ParamInterface::findGroupId(const char* name)

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