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

Last change on this file since 316 was 316, checked in by Maciej Komosinski, 9 years ago

Improved documentation (for Param flags in particular)

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