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

Last change on this file since 743 was 743, checked in by Maciej Komosinski, 6 years ago

Introduced different function names in C++ instead of overloading (with the same number of arguments) so that javascript is able to discriminate them

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