File: StateDatabase.h

package info (click to toggle)
bzflag 2.4.30-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 26,488 kB
  • sloc: cpp: 150,376; ansic: 3,463; sh: 2,535; makefile: 2,194; perl: 486; python: 260; objc: 246; php: 206
file content (453 lines) | stat: -rw-r--r-- 17,389 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
/* bzflag
 * Copyright (c) 1993-2025 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef BZF_STATE_DATABASE_H
#define BZF_STATE_DATABASE_H

// common header first
#include "common.h"

// system headers
#include <vector>
#include <map>
#include <iostream>
#include <string>

// implementation headers
#include "CallbackList.h"
#include "bzfio.h"
#include "Singleton.h"

/** BZDB is the generic name:value pair database within bzflag and bzfs. Its
 * useful for data that can be serialized to a string that needs to be
 * accessible to many areas of the code. It also provides facilities for
 * saving persistent pairs to the config file and downloading variables from
 * the server.
 *
 * BZDB is not an object broker, and isn't meant to be. If you have data
 * within an object that needs to be accessible from a number of places, but
 * don't want to pass the object around, you could store that data within BZDB
 * (if accessed often, such as game variables like gravity, you will need a
 * cached version anyway to avoid the overhead of lookup). Using BZDB adds
 * unnecessary overhead if objects generally keep their data hidden without
 * needing persistent state.
 *
 * Basically, if your data can be serialized to a string, and it makes sense
 * to do so (eg: config file option, game variable downloaded from server), use
 * BZDB. If you wanted an object broker, use a freakin' global.
 */
class StateDatabase : public Singleton<StateDatabase>
{
public:

    typedef void (*Callback)(const std::string& name, void* userData);
    enum Permission
    {
        // permission levels
        ReadWrite,
        Locked,
        ReadOnly,

        // access levels
        User   = ReadWrite,
        Server = Locked,
        Client = ReadOnly
    };

    /** set a name/value pair.  if access is less than the permission
     *level of the name then this has no effect.
     */
    void              set(const std::string& name,
                          const std::string& value,
                          Permission access = Client);

    void               setInt(const std::string& name,
                              const int& value,
                              Permission access = Client);

    void              setBool(const std::string& name,
                              const bool& value,
                              Permission access = Client);

    void             setFloat(const std::string& name,
                              const float& value,
                              Permission access = Client);
    /** allow setting name/pointer pairs.  this allows simple object
     * pointer storage into the bzdb via pointer address serialization.
     */
    void              setPointer(const std::string& name,
                                 const void *value,
                                 Permission access = Client);

    /** unset a name if access is not less than the permission level
     * of the name.
     */
    void              unset(const std::string& name,
                            Permission access = Client);

    /** simulate a change to a value (i.e. invoke the callbacks on it)
     */
    void              touch(const std::string& name,
                            Permission access = Client);

    /** mark a value as persistent (i.e. to be saved) or volatile.
     * this state is stored independently of the existence of a value
     * with the given name.  that is, adding or removing the name
     * will not affect persistence of the name.  the default is
     * volatile.
     */
    void              setPersistent(const std::string& name,
                                    bool = true);

    /** set the default value for a name.  if the default value is set
     * then the value will not be written by write() if the current
     * value is equal to the default value.
     */
    void              setDefault(const std::string& name,
                                 const std::string& value);

    /** set the permission level of a name.  like persistence, this is
     * stored independently of a value with the name.  the default
     * permission is ReadWrite (i.e. full access).
     */
    void              setPermission(const std::string& name,
                                    Permission);

    /** add/remove a callback to/from a name.  all callbacks on a name are
     * invoked when the value changes (either by being set or unset).
     * each name can have any number of callbacks but any given callback
     * function/userData pair on a name can only be registered once (i.e.
     * multiple adds have the same effect as a single add).
     */
    void              addCallback(const std::string& name,
                                  Callback, void* userData);
    void              removeCallback(const std::string& name,
                                     Callback, void* userData);

    /** add/remove a global callback for all values. invoked when any value
    * changes (either by being set or unset). each function/userData pair can
    * only be registered once (i.e. multiple adds have the same effect as a
    * single add).
    */
    void addGlobalCallback(Callback, void* userData);
    void removeGlobalCallback(Callback, void* userData);

    /** test if a name is set or not
     */
    bool              isSet(const std::string& name) const;

    /** get the value associated with a name.  returns the empty string
     * if the name isn't set.
     */
    std::string           get(const std::string& name) const;

    /** get the INT value associated with a name. Clamp value within range.
     *  Returns 0 (or min) if value is not set.
     */
    int   getIntClamped(const std::string& name, const int min, const int max) const;

    /** returns the pointer stored with a name.  returns NULL if the
     * name isn't set.
     */
    void *            getPointer(const std::string& name) const;

    /** get the value as a floating point number. this will evaluate
     * the string as an expression
     */
    float             eval(const std::string& name);
    int               evalInt(const std::string& name);
    bool              evalTriplet(const std::string& name, float data[3]);
    bool              evalPair(const std::string& name, float data[2]);

    /** return true if the value associated with a name indicates
     * logical true, which is when the value is not empty and not
     * "0" and not "false" and not "no".
     */
    bool              isTrue(const std::string& name) const;

    /** test if a name is empty or not.  a name is empty if it's
     * not set or it's set to the empty string.
     */
    bool              isEmpty(const std::string& name) const;

    /** get the persistence, permission, and default for an entry
     */
    bool              isPersistent(const std::string& name) const;
    std::string           getDefault(const std::string& name) const;
    Permission            getPermission(const std::string& name) const;

    /** invoke the callback for each entry
     */
    void              iterate(Callback, void* userData) const;

    /** invoke the callback for each entry that should be written (i.e.
     * is set, persistent, and not the default).
     */
    void              write(Callback, void* userData) const;

    /** tell the state database whether it should print debug info to stdout
     * now and then.
     */
    void              setDebug(bool print);

    /** do we want debug output?
     */
    bool              getDebug() const;

// true if we are in a mode where we are setting values that are to be defaults ( config and world time )
    void              setSaveDefault(bool save);
    bool              getSaveDefault() const;

    static const std::string  BZDB_AGILITYADVEL;
    static const std::string  BZDB_AGILITYTIMEWINDOW;
    static const std::string  BZDB_AGILITYVELDELTA;
    static const std::string  BZDB_AMBIENTLIGHT;
    static const std::string  BZDB_ANGLETOLERANCE;
    static const std::string  BZDB_ANGULARAD;
    static const std::string  BZDB_AVENUESIZE;
    static const std::string  BZDB_BASESIZE;
    static const std::string  BZDB_BOXBASE;
    static const std::string  BZDB_BOXHEIGHT;
    static const std::string  BZDB_BURROWDEPTH;
    static const std::string  BZDB_BURROWSPEEDAD;
    static const std::string  BZDB_BURROWANGULARAD;
    static const std::string  BZDB_COLDETDEPTH;
    static const std::string  BZDB_COLDETELEMENTS;
    static const std::string  BZDB_COUNTDOWNRESDELAY;
    static const std::string  BZDB_CULLDEPTH;
    static const std::string  BZDB_CULLELEMENTS;
    static const std::string  BZDB_CULLOCCLUDERS;
    static const std::string  BZDB_DISABLEBOTS;
    static const std::string  BZDB_DRAWCELESTIAL;
    static const std::string  BZDB_DRAWCLOUDS;
    static const std::string  BZDB_DRAWGROUND;
    static const std::string  BZDB_DRAWGROUNDLIGHTS;
    static const std::string  BZDB_DRAWMOUNTAINS;
    static const std::string  BZDB_DRAWSKY;
    static const std::string  BZDB_ENDSHOTDETECTION;
    static const std::string  BZDB_EXPLODETIME;
    static const std::string  BZDB_FLAGALTITUDE;
    static const std::string  BZDB_FLAGEFFECTTIME;
    static const std::string  BZDB_FLAGHEIGHT;
    static const std::string  BZDB_FLAGPOLEWIDTH;
    static const std::string  BZDB_FLAGPOLESIZE;
    static const std::string  BZDB_FLAGRADIUS;
    static const std::string  BZDB_FOGMODE;
    static const std::string  BZDB_FOGDENSITY;
    static const std::string  BZDB_FOGSTART;
    static const std::string  BZDB_FOGEND;
    static const std::string  BZDB_FOGCOLOR;
    static const std::string  BZDB_GMACTIVATIONTIME;
    static const std::string  BZDB_GMADLIFE;
    static const std::string  BZDB_GMSIZE;
    static const std::string  BZDB_GMTURNANGLE;
    static const std::string  BZDB_GRAVITY;
    static const std::string  BZDB_FRICTION;
    static const std::string  BZDB_HANDICAPSCOREDIFF;
    static const std::string  BZDB_HANDICAPVELAD;
    static const std::string  BZDB_HANDICAPANGAD;
    static const std::string  BZDB_HANDICAPSHOTAD;
    static const std::string  BZDB_HIDEFLAGSONRADAR;
    static const std::string  BZDB_HIDETEAMFLAGSONRADAR;
    static const std::string  BZDB_IDENTIFYRANGE;
    static const std::string  BZDB_JUMPVELOCITY;
    static const std::string  BZDB_LASERADVEL;
    static const std::string  BZDB_LASERADRATE;
    static const std::string  BZDB_LASERADLIFE;
    static const std::string  BZDB_LATITUDE;
    static const std::string  BZDB_LOCKONANGLE;
    static const std::string  BZDB_TARGETINGANGLE;
    static const std::string  BZDB_TARGETINGDISTANCE;
    static const std::string  BZDB_LONGITUDE;
    static const std::string  BZDB_LRADRATE;
    static const std::string  BZDB_MAXBUMPHEIGHT;
    static const std::string  BZDB_MAXFLAGGRABS;
    static const std::string  BZDB_MAXLOD;
    static const std::string  BZDB_MIRROR;
    static const std::string  BZDB_MOMENTUMLINACC;
    static const std::string  BZDB_MOMENTUMANGACC;
    static const std::string  BZDB_MOMENTUMFRICTION;
    static const std::string  BZDB_MGUNADVEL;
    static const std::string  BZDB_MGUNADRATE;
    static const std::string  BZDB_MGUNADLIFE;
    static const std::string  BZDB_MUZZLEFRONT;
    static const std::string  BZDB_MUZZLEHEIGHT;
    static const std::string  BZDB_NOCLIMB;
    static const std::string  BZDB_NOSHADOWS;
    static const std::string  BZDB_NOSMALLPACKETS;
    static const std::string  BZDB_NOTRESPONDINGTIME;
    static const std::string  BZDB_OBESEFACTOR;
    static const std::string  BZDB_PAUSEDROPTIME;
    static const std::string  BZDB_POSITIONTOLERANCE;
    static const std::string  BZDB_PYRBASE;
    static const std::string  BZDB_PYRHEIGHT;
    static const std::string  BZDB_RADARLIMIT;
    static const std::string  BZDB_REJOINTIME;
    static const std::string  BZDB_RELOADTIME;
    static const std::string  BZDB_RFIREADVEL;
    static const std::string  BZDB_RFIREADRATE;
    static const std::string  BZDB_RFIREADLIFE;
    static const std::string  BZDB_SHIELDFLIGHT;
    static const std::string  BZDB_SHOCKADLIFE;
    static const std::string  BZDB_SHOCKINRADIUS;
    static const std::string  BZDB_SHOCKOUTRADIUS;
    static const std::string  BZDB_SHOTSPEED;
    static const std::string  BZDB_SHOTRADIUS;
    static const std::string  BZDB_SHOTRANGE;
    static const std::string  BZDB_SHOTTAILLENGTH;
    static const std::string  BZDB_SHOTSKEEPVERTICALV;
    static const std::string  BZDB_SQUISHFACTOR;
    static const std::string  BZDB_SQUISHTIME;
    static const std::string  BZDB_SPEEDCHECKSLOGONLY;
    static const std::string  BZDB_SRRADIUSMULT;
    static const std::string  BZDB_SYNCLOCATION;
    static const std::string  BZDB_SYNCTIME;
    static const std::string  BZDB_TANKANGVEL;
    static const std::string  BZDB_TANKEXPLOSIONSIZE;
    static const std::string  BZDB_TANKLENGTH;
    static const std::string  BZDB_TANKWIDTH;
    static const std::string  BZDB_TANKHEIGHT;
    static const std::string  BZDB_TANKSPEED;
    static const std::string  BZDB_TANKRADIUS;
    static const std::string  BZDB_TELEBREADTH;
    static const std::string  BZDB_TELEHEIGHT;
    static const std::string  BZDB_TELEPORTTIME;
    static const std::string  BZDB_TELEWIDTH;
    static const std::string  BZDB_THIEFVELAD;
    static const std::string  BZDB_THIEFTINYFACTOR;
    static const std::string  BZDB_THIEFADSHOTVEL;
    static const std::string  BZDB_THIEFADRATE;
    static const std::string  BZDB_THIEFADLIFE;
    static const std::string  BZDB_THIEFDROPTIME;
    static const std::string  BZDB_TINYFACTOR;
    static const std::string  BZDB_TRACKFADE;
    static const std::string  BZDB_UPDATETHROTTLERATE;
    static const std::string  BZDB_VELOCITYAD;
    static const std::string  BZDB_WALLHEIGHT;
    static const std::string  BZDB_WEAPONS;
    static const std::string  BZDB_WIDEANGLEANG;
    static const std::string  BZDB_WINGSGRAVITY;
    static const std::string  BZDB_WINGSJUMPCOUNT;
    static const std::string  BZDB_WINGSJUMPVELOCITY;
    static const std::string  BZDB_WINGSSLIDETIME;
    static const std::string  BZDB_WORLDSIZE;


protected:
    friend class Singleton<StateDatabase>;

private:

    StateDatabase();
    ~StateDatabase();

    static bool           onCallback(Callback, void* userData,
                                     void* iterateData);

    struct Item
    {
    public:
        Item();

    public:
        std::string         value;
        std::string         defValue;
        bool            isSet;
        bool            isTrue;
        bool            save;
        Permission          permission;
        CallbackList<Callback>  callbacks;
    };
    typedef std::map<std::string, Item> Map;

    Map::iterator         lookup(const std::string&);
    void              notify(Map::iterator);

private:
    Map               items;

public:
    class ExpressionToken
    {
    public:
        enum Type { Oper, Number, Variable };
        enum Operator { add, subtract, multiply, divide, power, lparen, rparen, none };
        struct Contents
        {
        public:
            double number;
            std::string variable;
            Operator oper;
        };

        ExpressionToken();
        ExpressionToken(Type _tokenType);
        ExpressionToken(Type _tokenType, Contents _tokenContents);

        void            setType(Type _tokenType);
        void            setContents(Contents _tokenContents);
        void            setNumber(double number);
        void            setVariable(std::string variable);
        void            setOper(Operator oper);

        Type            getTokenType() const;
        Contents            getTokenContents() const;
        double          getNumber() const;
        std::string         getVariable() const;
        Operator            getOperator() const;

        int             getPrecedence() const;

    private:
        Type tokenType;
        Contents tokenContents;
    };

    typedef std::vector<ExpressionToken> Expression;

private:
    static Expression     infixToPrefix(const Expression &infix);
    float             evaluate(Expression e) const;
    typedef std::map<std::string,float> EvalMap;
    EvalMap           evalCache;
    bool              debug;
    bool              saveDefault;
    CallbackList<Callback>    globalCallbacks;
};

inline bool StateDatabase::getDebug() const
{
    return debug;
}

inline bool StateDatabase::getSaveDefault() const
{
    return saveDefault;
}


std::istream& operator>>(std::istream& src, StateDatabase::Expression& dst);
std::string& operator>>(std::string& src, StateDatabase::Expression& dst);
std::ostream& operator<<(std::ostream& dst, const StateDatabase::Expression& src);

#define BZDB (StateDatabase::instance())


#endif // BZF_STATE_DATABASE_H

// Local Variables: ***
// mode: C++ ***
// tab-width: 4 ***
// c-basic-offset: 4 ***
// indent-tabs-mode: nil ***
// End: ***
// ex: shiftwidth=4 tabstop=4